ofl*_*hra 11 ruby audio wav portaudio
我最近一直在玩ruby,我决定开始一个简单的项目来编写一个ruby脚本来记录.wav文件的输入声音.我发现ruby不能提供对硬件设备的非常好的访问(它可能不应该),但PortAudio确实如此,我在这里发现了一个伟大的PA包装器(它不是宝石,我想因为它使用了ruby的ffi附加到PortAudio,PA库可以在各种地方).我一直在弄乱PortAudio的文档和示例来弄清楚PA是如何工作的.多年来我没有写过或读过C.
我在创建过程中应该将哪些参数传递给流,以及创建期间的缓冲区时遇到了困难.例如,究竟是一个frame,以及它是如何与其他参数,如channel和sample rate.我对音频编程也很陌生,所以如果有人能指点我一些关于设备级音频的一般教程等,我会很感激.
ruby-portaudio提供了一个创建流和缓冲区的示例,将sin波写入缓冲区,然后将缓冲区发送到要播放的流.我在示例中遇到一些问题,特别是循环块.
PortAudio.init
block_size = 1024
sr = 44100
step = 1.0/sr
time = 0.0
stream = PortAudio::Stream.open(
:sample_rate => sr,
:frames => block_size,
:output => {
:device => PortAudio::Device.default_output,
:channels => 1,
:sample_format => :float32
})
buffer = PortAudio::SampleBuffer.new(
:format => :float32,
:channels => 1,
:frames => block_size)
playing = true
Signal.trap('INT') { playing = false }
puts "Ctrl-C to exit"
stream.start
loop do
stream << buffer.fill { |frame, channel|
time += step
Math.cos(time * 2 * Math::PI * 440.0) * Math.cos(time * 2 * Math::PI)
}
break unless playing
end
stream.stop
Run Code Online (Sandbox Code Playgroud)
如果我要录制,我应该将一个流读入缓冲区,然后操作该缓冲区并将其写入文件,对吧?
此外,如果我在这里咆哮错误的树,并且有更简单的方法(红宝石),一些方向会很好.
让我们首先澄清您所询问的术语。为此,我将尝试以简化的方式解释音频管道。当您像示例中那样生成声音时,您的声卡会定期从代码中请求帧(=缓冲区=块),并用样本填充该帧。采样率定义了您在一秒钟内提供的样本数量,从而定义了样本的播放速度。帧大小(= 缓冲区大小 = 块大小)决定了声卡在一次请求中提供的样本数量。缓冲区通常非常小,因为缓冲区大小直接影响延迟(大缓冲区 => 高延迟)并且大数组可能很慢(尤其是 ruby 数组很慢)。
当您从声卡录制声音时,也会发生类似的情况。您的函数会时不时地被调用,并且来自麦克风的样本通常作为函数的参数传递(或者甚至只是对此类缓冲区的引用)。然后您需要处理这些样本,例如将它们写入磁盘。
我知道“一切都用 Ruby 来做”的想法非常诱人,因为它是一种如此美丽的语言。当您计划进行实时音频处理时,我建议切换到编译语言(C、C++、Obj-C,...)。它们可以更好地处理音频,因为它们比 Ruby 更接近硬件,因此通常速度更快,这在音频处理中可能是一个很大的问题。这可能也是 Ruby 音频库如此之少的原因,所以也许 Ruby 并不是适合这项工作的工具。
顺便说一句,我尝试了 ruby-portaudio、ffi-portaudio 以及 ruby-audio,但它们都无法在我的 Macbook 上正常工作(试图生成正弦波),这再次令人遗憾地表明,Ruby 无法处理这个东西(还没有?)。
| 归档时间: |
|
| 查看次数: |
2229 次 |
| 最近记录: |