Использование оболочки PortAudio в ruby ​​для записи звука в .wav

Я недавно поигрался с ruby ​​и решил начать простой проект по написанию ruby скрипт, который записывает линейный звук в файл .wav . Я обнаружил, что Ruby не обеспечивает очень хороший доступ к аппаратным устройствам (и, вероятно, не должен), но PortAudio делает, и я обнаружил отличная оболочка для PA здесь (я думаю, это не драгоценный камень, потому что он использует ruby ​​ ffi для подключения к PortAudio, а библиотека PA может быть в различных количество мест). Я копался в документации и примерах PortAudio, чтобы понять, как работает PA. Я не писал и не читал C годами.

У меня возникли трудности с тем, какие параметры следует передавать в поток во время создания и в буфер во время создания.Например, что такое кадр и как он связан с другими параметрами, такими как канал и частота дискретизации . Я совершенно новичок в звуковом программировании в целом, поэтому, если бы кто-нибудь мог указать мне на какие-то общие руководства и т.Д., Об аудио на уровне устройства, я был бы признателен.

ruby-portaudio предоставляет единственный пример, который создает поток и буфер, записывает синусоидальную волну в буфер, а затем отправляет буфер в поток для воспроизведения. Некоторые из рубинов, с которыми у меня возникли проблемы в этом примере, особенно блок цикла.

  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
задан oflannabhra 6 February 2012 в 16:25
поделиться