class AudioStream::Fx::Tuner
Constants
- FREQ_TABLE
- NOTE_TABLE
- Tune
Public Class Methods
new(soundinfo, window: nil)
click to toggle source
# File lib/audio_stream/fx/tuner.rb, line 16 def initialize(soundinfo, window: nil) @samplerate = soundinfo.samplerate.to_f @window = window || HanningWindow.instance end
Public Instance Methods
process(input)
click to toggle source
# File lib/audio_stream/fx/tuner.rb, line 21 def process(input) window_size = input.window_size # mono window input = input.mono input = @window.process(input) stream = input.streams[0] gain = stream.map(&:abs).max freq = nil if 0.01<gain # fft na = input.to_float_na fft = FFTW3.fft(na, FFTW3::FORWARD) / na.length amp = fft.map {|c| c.real**2 + c.imag**2 }.real.to_a.flatten # peak i = amp.index(amp.max) #if window_size/2<i # j = window_size - i # if (amp[i]-amp[j]).abs<=0.0000001 # i = j # end #end # freq freq_rate = @samplerate / window_size if 0<i && i<window_size-1 freq_sum = amp[i-1] * (i-1) * freq_rate freq_sum += amp[i] * i * freq_rate freq_sum += amp[i+1] * (i+1) * freq_rate amp_sum = amp[i-1] + amp[i] + amp[i+1] freq = freq_sum / amp_sum else freq = i * freq_rate end struct(freq) else Tune.new end end
struct(freq)
click to toggle source
# File lib/audio_stream/fx/tuner.rb, line 72 def struct(freq) index = FREQ_TABLE.bsearch_index {|x| x>=freq} if !index || FREQ_TABLE.length<=index+1 return Tune.new end if 0<index && freq-FREQ_TABLE[index-1] < FREQ_TABLE[index]-freq diff = (freq-FREQ_TABLE[index-1]) / (FREQ_TABLE[index]-FREQ_TABLE[index-1]) * 100 index -= 1 else diff = (freq-FREQ_TABLE[index]) / (FREQ_TABLE[index+1]-FREQ_TABLE[index]) * 100 end note_num = index + 9 note = NOTE_TABLE[index%12] octave = (index-3)/12 Tune.new( freq: freq, note_num: note_num, note: note, octave: octave, diff: diff ) end