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}} |