4

I've never worked with real-time audio features. I would like to know whether there are ruby libraries out there that would allow me to create something like a guitar tuner.

soulnafein
  • 1,058
  • 1
  • 10
  • 20

1 Answers1

4

There are two orthogonal tasks: 1) read the audio, 2) process it. To get the audio you could check ruby-audio though, to be honest, I've never used it and its documentation seems scarce. Personally I'd resort to whatever your operating system provides; for example in GNU/Linux we have handy tools like bplay. The second issue is how to calculate the FFT of audio, this should be easy with FFTW3.

Here is a quick and dirty example that gets the peak point of the FFT from stdin (16 bits, mono):

require 'rubygems'
require 'fftw3'

module Tuner
  def self.peaks(input_channel, samplerate, window_size)
    Enumerator.new do |enum|
      loop do
        data = input_channel.read(window_size).unpack("s*")
        na = NArray.to_na(data)
        fft = FFTW3.fft(na).to_a[0, window_size/2]
        max_n = fft.map(&:abs).each_with_index.drop(1).max[1]
        enum.yield(max_n.to_f * samplerate / window_size)
      end
    end
  end
end

if __FILE__ == $0
  Tuner.peaks(STDIN, 8000, 1024).each { |f| puts f }
end

To be called, for example:

$ brec -s 8000 -b 16 | ruby tuner.rb
tokland
  • 66,169
  • 13
  • 144
  • 170
  • 1
    Do bear in mind though that you'll need to know a little about FFT and musical instrument spectra to get something useful as a guitar tuner. You'll need to take tokland's example and do some more processing on it -- picking the peak of the FFT won't reliably give you the pitch. See some of the other posts here about pitch detection: http://stackoverflow.com/search?q=pitch+estimation – the_mandrill Dec 22 '10 at 23:29