Ecco qua:
$include "object\rapidq2.inc"
$option explicit
declare sub ExamineWav(MaxSamples as long)
declare function Goertzel(target_freq as long, N as long) as integer
declare sub vai
dim Freq as long
dim FILENAME as string
const ERR_BAD_FORMAT = 2
const FATAL_ERROR = 99
dim SampleRate as long
' create form as qform
' width = 320
' height = 250
' create txtLog as qrichedit
' top = 10
' left = 10
' height = 150
' width = 230
' end create
' CREATE StatusBar AS qlabel
' top = 10
' left = 250
' caption = "--"
' END CREATE
' create btnVai as qbutton
' top = 180
' left = 10
' caption = "VAI"
' onclick = Vai
' end create
'
' end create
'
' form.showmodal
sub PrintHelp
print
print "Frequency detector by Jumpjack 2008 - freeware"
print "----------------------------------------------"
print
print "Program looks for frequencies into a WAV file"
print
print "Syntax:"
print "leggiWav <--SamplingFreq xxxx> <--TuningFreq xxxx> <--Iterations xxxx> <--File xxxxx>
print " --SamplingFreq (-sf): Sampling frequency of the file"
print " --TuningFreq (-tf): Frequency to look for"
print " --Iterations (-i): Algorithm precision (higher=slower)"
print " --File (-f): File to process (WAV)"
print
print "All parameters are mandatory."
print
print "Example:"
print "freqdet -sf 44100 -tf 440 -i 5000 -f c:\temp\audio.wav"
print
print "See for details"
print "about algorithm used (Goertzel algorithm)."
print
print "(Thanks to Kevin Banks for his page)"
print
print "This program was written in RapidQ"
end sub
SampleRate = 44100
dim i as integer
dim Iterations as integer
if CommandCount = 0 then
printHelp
end
end if
for i = 1 to CommandCount step 2
if instr(ucase$(Command$(i)),ucase$("--SamplingFreq"))>0 or instr(ucase$(Command$(i)),ucase$("-SF")) >0 then
SampleRate = val(mid$(Command$(i+1),instr(Command$(i+1)," "), len(Command$(i+1))-instr(Command$(i+1)," ")))
end if
if instr(ucase$(Command$(i)),ucase$("--TuningFreq"))>0 or instr(ucase$(Command$(i)),ucase$("-TF")) >0 then
Freq = val(mid$(Command$(i+1),instr(Command$(i+1)," "), len(Command$(i+1))-instr(Command$(i+1)," ")))
end if
if instr(ucase$(Command$(i)),ucase$("--Iterations"))>0 or instr(ucase$(Command$(i)),ucase$("-I")) >0 then
Iterations = val(mid$(Command$(i+1),instr(Command$(i+1)," "), len(Command$(i+1))-instr(Command$(i+1)," ")))
end if
if instr(ucase$(Command$(i)),ucase$("--File"))>0 or instr(ucase$(Command$(i)),ucase$("-F")) >0 then
FileName = val(mid$(Command$(i+1),instr(Command$(i+1)," "), len(Command$(i+1))-instr(Command$(i+1)," ")))
end if
if instr(ucase$(Command$(i)),ucase$("--Help"))>0 or instr(ucase$(Command$(i)),ucase$("-H")) or instr(ucase$(Command$(i)),ucase$("-?")) >0 then
call PrintHelp
end
end if
next
if FileName = "" then
print "No file specified"
end
end if
Print "SampleRate:",SampleRate
print "Looking for frequency:",Freq
print "Iterations:",Iterations
print "(Duration:", Iterations/Samplerate," seconds)"
print
call Vai
'****************************************************************************
**
DefInt WavChannels, WavFreq,WavBytesSec,WavBytesSample,WavBitsSample
dim cosine as double
dim sine as double
dim coeff as double
dim RawData(64000) as integer
dim NumSamples as long
dim f as double
sub Vai
dim MaxSamples as long
dim G as integer
MaxSamples = Iterations
call ExamineWav(MaxSamples)
for f = Freq-12 to Freq+12 step 2
G = int(Goertzel(f,MaxSamples))
print f,": ", string$(int(G/10000000),"*")
next
end sub
function Goertzel(target_freq as double, N as long) as integer
' target_freq = frequency to look for;
' N = Number of samples to examine.
' rawdata() contains raw values of audio samples
'
' This function must be called once per each frequency to be tested.
' The more the test frequency is near to detected frequency, the
' greater is the returned value.
'
' Many thanks to Kevin Banks from
'
' Musical frequencies:
' DO - C: 262 Hz
' RE - D: 294 Hz
' MI - E: 330 Hz
' FA - F: 349 Hz
' SOL - G: 392 Hz
' LA - A: 440 Hz
' SI - B: 494 Hz
defdbl Q0, Q1, Q2
dim sample as long
defdbl realPart, imgPart, magnitudeSquared, magnitude
dim k as double
dim w as double
dim pi as double
pi = 3.141592654
k=int(0.5 + (N*target_freq/SampleRate))
w = (2*pi*k)/N
cosine = cos(w)
sine = sin(w)
coeff = 2 * cosine
q0=0
q1=0
q2=0
for sample = 1 to N
Q0 = coeff * Q1 - Q2 + rawdata(sample)
Q2 = Q1
Q1 = Q0
next
realPart = (Q1 - Q2 * cosine)
imgPart = (Q2 * sine)
magnitudeSquared = realPart*realPart + imgPart*imgPart
magnitude = sqr(magnitudeSquared)
Goertzel= magnitude
end function
sub ExamineWav(MaxSamples as long)
dim wav as qfilestream
dim i as long
dim c as long
wav.open( FILENAME ,fmOpenRead) ' Apre file WAV
c = 0
' ********* Memorizza i campioni:
for i = 45 to MaxSamples
c = c + 1
rawdata©=wav.Readnum(2) ' Memorizza campione
next
wav.close
NumSamples = c-1
end sub
Il programma va compilato usando
, per ottenere un eseguibile per WINDOWS (non per il cellulare!)
In allegato c'e' l'eseguibile.
Viene mostrato una specie di "istogramma testuale" centrato sulla frequenza che si sta cercando: se c'e' un picco, vuol dire che quella frequenza è presente nel file audio (ma potrebbero essercene altre).
Ok, ora chi lo porta in Python?