使用ruby-alsa

使用ruby-alsa,ruby,alsa,Ruby,Alsa,我终于拿到了密码,但我又被卡住了。最后,当从客户端调用某个操作时,我希望在服务器上播放一个音频文件。因此,我的控制器中有以下代码: File.open('./public/audio/test.wav', 'r') do |f| ALSA::PCM::Playback.open do |playback| playback.write do |length| f.read length end end end 通过阅读,我得到的印象是,我应该使用来自ALSA:

我终于拿到了密码,但我又被卡住了。最后,当从客户端调用某个操作时,我希望在服务器上播放一个音频文件。因此,我的控制器中有以下代码:

File.open('./public/audio/test.wav', 'r') do |f|
  ALSA::PCM::Playback.open do |playback|
    playback.write do |length|
      f.read length
    end
  end
end
通过阅读,我得到的印象是,我应该使用来自ALSA::PCM::Playback类的。不幸的是,我无法获得正确的语法来让这个方法工作。为了简单地验证ALSA是否正常工作,我尝试使用Playback.write方法(注意上面的代码)。上述代码在语法上是正确的;但是,它只播放一微秒的声音,然后停止。我猜请求结束得太快了,没有足够的时间播放任何可识别的内容

如前所述,我的最终目标是让最终用户调用在服务器上播放音频的操作。该文件不应该在HTTP请求结束时停止播放——它应该继续播放,直到调用另一个停止播放的操作为止。知道了这一点,有人能帮我找到正确的语法和参数来调用write_in_background方法吗?作为Ruby的一名完全的新手,我担心我现在所做的一切对我的帮助还不够

更新:如果我将上述对write方法的调用替换为对write\u to\u后台方法的调用,则会出现以下运行时错误:无法添加pcm处理程序(函数未实现)

更新2:我用不同的WAV文件和以下代码尝试了这一点,它以扭曲速度播放

File.open('./public/audio/sample.wav', 'r') do |f|
  ALSA::PCM::Playback.open do |playback|
    playback.write do |length|
      @temp = length
      f.read length
    end
    sleep 4
  end
end
看来这里可能发生了多种情况。我相信第一个是关于采样率(长度=44100,这是CD质量)。我将不得不研究如何以不同的速率播放音频文件。然而,除此之外,我仍然停留在如何让它在后台播放上。虽然睡眠证明ALSA是有效的,但在现实世界中它不会很好地工作

更新3:使采样率位工作,即使它暂时依赖于一个幻数:

File.open('./public/audio/sample.wav', 'r') do |f|
  ALSA::PCM::Playback.open "default", {:channels => 1, :sample_rate => 11025} do |playback|
    playback.write do |length|
      @temp = length
      f.read length
    end
    sleep 4
  end
end

此时,我的ruby代码通过ALSA播放音频,但我不确定如何让它在不需要睡眠的情况下在后台连续播放。

如何在自己的线程上启动它

Thread.new do
  File.open('myfile.wav', 'rb') do |f|
    ALSA::PCM::Playback.open do |playback|
      playback.write do |length|
        f.read length
     end
    end
  end
end.join
编辑: 好吧,如果这不起作用,我猜它已经开始自己的线程了。在这段时间里睡觉怎么样?第一次尝试:

  File.open('myfile.wav', 'rb') do |f|
    ALSA::PCM::Playback.open do |playback|
      playback.write do |length|
        f.read length
     end
    end
  end
  sleep 4 # seconds

不幸的是,同样的事情——它快速播放“哔哔”声,然后立即停止。我想指出的是,我根本不确定我是否正确使用了这个库。我只是用我自己的文件替换了ruby alsa主页上的示例代码,其中引用了$stdin。不是我所期望的。