Skip to content

Instantly share code, notes, and snippets.

@wesmaldonado
Created January 23, 2011 00:42
Show Gist options
  • Save wesmaldonado/791676 to your computer and use it in GitHub Desktop.
Save wesmaldonado/791676 to your computer and use it in GitHub Desktop.
def goertzel(block_size,samples)
freq = 500 # from demorse.h AUDIO_FREQ
s = 0.0
s_prev1 = 0.0
s_prev2 = 0.0;
coeff = 2.0 * Math.cos(2.0 * Math::PI* freq);
samples.map do |sv|
s = sv + (coeff * s_prev1) - s_prev2;
s_prev2 = s_prev1;
s_prev1 = s;
end
# Normalize over block size
s_prev1 = s_prev1 / block_size
s_prev2 = s_prev2 / block_size
return (s_prev1 * s_prev1) + (s_prev2 * s_prev2)
- (s_prev1 * s_prev2 * coeff);
end
data = ARGF.read
keys = %w[id totallength wavefmt format
pcm channels frequency bytes_per_second
bytes_by_capture bits_per_sample
data bytes_in_data sum
]
values = data.unpack 'Z4 i Z8 i s s i i s s Z4 i s*'
sum = values.drop(12).map(&:abs).inject(:+)
keys.zip(values.take(12) << sum) {|k, v|
puts "#{k.ljust 17}: #{v}"
}
sound_data = values.drop(12)
# Block of frequency over 48 samples
block_size = 20
freq_blocks = []
sound_data.each_slice(block_size) do |slice|
freq_blocks << goertzel(block_size, slice)
end
puts freq_blocks.map{|f| sprintf("%d", f/1000000)}.join("\n")
exit
up_steps = 0
down_steps = 0
freq_blocks.each_with_index do |f, i|
thresh = 60 # constant
t1 = f
t2 = freq_blocks[i+1] || t1 # same if end of input
unit_elem = 160
puts "#{t1.inspect}\t #{t2.inspect}"
if thresh * t1 < 100 * t2
up_steps = up_steps +1
elsif 100 * t1 > thresh *t2
down_steps = down_steps +1
end
if 100 * up_steps > (60 * unit_elem - 1)
puts "TONE"
elsif 100 * down_steps > (60 * unit_elem - 1)
puts "CLEAR TONE"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment