Waveform analysis/Doh ray me: Difference between revisions

Content added Content deleted
No edit summary
(julia example)
Line 103: Line 103:
Computed average frequency = 387.1 Hz (Soh-)
Computed average frequency = 387.1 Hz (Soh-)
Actual average frequency = 385.4 Hz (Soh-)</pre>
Actual average frequency = 385.4 Hz (Soh-)</pre>

=={{header|Julia}}==
Uses the LibSndFile library for WAV file reading and the FFTW library for FFT to try to analyze the sound for its fundamental frequency.
<lib julia>using FFTW, FileIO, LibSndFile

const soundfilename = "Cscale3octaves.wav"
const freq_to_solfa = Dict([
130.81 => "DOH"
146.83 => "RAY"
164.81 => "MEE"
174.61 => "FAH"
196.0 => "SOH"
220.0 => "LAH"
246.94 => "TEE"
261.63 => "Doh"
293.66 => "Ray"
329.63 => "Mee"
349.23 => "Fah"
392.0 => "Soh"
440.0 => "Lah"
493.88 => "Tee"
523.25 => "doh"
587.33 => "ray"
659.25 => "mee"
698.46 => "fah"
783.99 => "soh"
880.0 => "lah"
987.77 => "tee"
])
const sfreqs = sort(collect(keys(freq_to_solfa)))

function closestfreqs(samples, fs=44100.0)
pfreqs = Float64[]
for sample in samples
ff = fft(sample)
xr = div(length(sample), 2)
ffreqs = LinRange(1, fs, length(sample))
sigpow = (abs.(ff)).^2.0
fmax = ffreqs[argmax(sigpow)]
idx = argmin([abs(f - fmax) for f in sfreqs])
push!(pfreqs, sfreqs[idx])
end
return pfreqs
end

function getchunks(soundfile, channel=1, timespan=0.11)
sv = load(soundfile)
fs = LibSndFile.samplerate(sv)
samplespan, data = Int(round(timespan * fs)), view(sv, :, channel)
return (fs, [data[i:i+samplespan-1] for i in 1:samplespan:length(data)-samplespan-1])
end

function makenotelist(soundfile, fs=44100.0, repetitionsneeded=1)
changelist = String[]
fs, samples = getchunks(soundfile)
freqs = closestfreqs(samples, fs)
reps, prev = 0, ""
for freq in freqs
note = freq_to_solfa[freq]
if note != prev
prev = note
reps = 0
else
reps += 1
if reps == repetitionsneeded
push!(changelist, note)
end
end
end
return changelist
end

println(makenotelist(soundfilename))
</lang>{{out}}
<pre>
["DOH", "RAY", "MEE", "FAH", "SOH", "LAH", "TEE", "Doh", "Ray", "Mee", "Fah", "Soh", "Lah", "Lah", "Tee", "doh", "ray", "mee", "fah", "soh", "lah", "tee"]
</pre>



{{omit from|AWK}}
{{omit from|AWK}}