ルビーのPortAudioラッパーを使用してサウンドを.wavに録音する

私は最近ルビーで遊んでいましたが、私はラインインサウンドを .wav ファイルに記録するルビスクリプトを書くための簡単なプロジェクトを開始することに決めました。私は、ルビーがハードウェアデバイスへのアクセスを非常にうまく提供していないことを発見しましたが、PortAudioはそうしています。PAのラッパーを発見しました。ここをクリックしてください(これは宝石ではありませんが、Rubyの ffi を使ってPortAudioに接続し、PAライブラリはさまざまな場所に置くことができると思います)。私はPAの仕組みを理解するために、PortAudioのドキュメンテーションとサンプルを混乱させてきました。私は何年も前に C を書いたり読んだりしていません。

私は、作成中にストリームに渡す必要のあるパラメータと、作成中のバッファで難しかったです。たとえば、フレームとは何ですか?また、 channel sample rate などの他のパラメータとはどのように関連していますか?私は一般的なオーディオプログラミングにはまったく新しいので、誰かが私にデバイスレベルのオーディオについての一般的なチュートリアルなどを指すことができたら、私はそれを感謝します。

ruby-portaudio provides a single example that creates a stream and a buffer, writes a sin wave to the buffer, then sends the buffer to the stream to be played. Some of the ruby I'm having trouble with in the example, specifically the loop block.

  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

録音する予定の場合は、ストリームをバッファに読み込み、そのバッファを操作してファイルに書き込む必要があります。

また、私がここで間違った木を鳴らしていて、これを(ルビーで)簡単にする方法があるなら、いくらかの方向性が良いでしょう。

11
関連する(重複ではない)質問がここに表示されます。 stackoverflow。 com/questions/2716987 /&hellip;
追加された 著者 ted.strauss,

1 答え

Let's first clarify the terms you were asking about. For this purpose i will try to explain the audio pipeline in a simplified way. When you are generating a sound as in your example, your sound card periodically requests frames (= buffers = blocks) from your code, which you fill with your samples. The sampling rate defines how many samples you provide within a second and thus the speed with which your samples are played back. The frame size (= buffer size = block size) determines how many samples you provide in one request from the sound card. A buffer is typically quite small, because the buffer size directly affects the latency (large buffer => high latency) and large arrays can be slow (especially ruby arrays are slow).

サウンドカードからサウンドを録音するときも同様のことが起こります。あなたの関数はいつも呼び出され、マイクロフォンからのサンプルは、通常、関数への引数(あるいはそのようなバッファへの参照)として渡されます。これらのサンプルを処理することが期待されます。それらをディスクに書き込むことによって、

私は「Rubyですべてをやる」という考えは、それほど美しい言葉であるため、非常に魅力的であることを知っています。リアルタイムでオーディオ処理を行う予定がある場合は、コンパイルされた言語(C、C ++、Obj-C、...)に切り替えることをお勧めします。これらは、Rubyよりもハードウェアにはるかに近いため、オーディオ処理にかなりの問題となる可能性があるため、オーディオをもっとうまく処理できます。これはRubyのオーディオライブラリがあまりにも少ない理由の1つかもしれません。Rubyだけがその仕事に適したツールではないかもしれません。

ところで、私はruby-portaudio、ffi-portaudio、およびruby-audioを試してみましたが、悲しいことにMacBook(正弦波を生成しようとしました)でうまく動作していませんでした。このもの(まだ?)。

3
追加された
しかし、それは実際の合成を処理するパフォーマンスチューニングされたライブラリの周りのラッパーになるでしょう。むしろ純粋なRubyアプローチを指していました。
追加された 著者 Patrick Oscity,
はい、このようなこともやっています( gist.github.com/padde/926014)しかし、上記の質問は、ライブオーディオに関するものであり、ファイルへの録音ではありません。
追加された 著者 Patrick Oscity,
それは正しいですが、portaudioを使ったコードは、ライブオーディオソリューションを提案しています。今私はそれを考えると、オーディオがリアルタイムで生成される必要があるかどうかは本当に明確ではありません。申し訳ありませんが、あなたを怒らせることを意味しませんでした!
追加された 著者 Patrick Oscity,
あなたがguiを通してオーディオを混乱させることができるなら、あなたはスクリプト言語を通してそれを混乱させることができます。たとえば、Pure Dataは楽しいグラフィカルなオーディオプログラミング言語ですが、確かに、少なくとも1人は Rubyでドライブする。私は他のオーディオ合成環境と同様の努力があると確信しています。
追加された 著者 mgamba,
.wavに出力するRubyコードは次のとおりです。 github.com/cohena/RAFL/ blob/master/RAFL_wav.rb
追加された 著者 mgamba,
最初の文の正確な言葉遣いは、ライン入力音を.wavファイルに記録するルビースクリプトを書くことです。
追加された 著者 mgamba,
犯行はありません。あなたがコードを見ているのであれば、それは合理的な仮定です。
追加された 著者 mgamba,
ええ、それは生のオーディオ状況でした。私はライブオーディオをサンプリングし、そのサンプルをファイルに書き込んだり、サンプリングを続けながら分析を行う必要がありました。実際にObjective-Cを使って解決策を書いてしまいました。
追加された 著者 oflannabhra,