This repository has been archived on 2019-12-11. You can view files and clone it, but cannot push or open issues/pull-requests.
jlaudio/lib/extractfreq/wip.go

104 lines
1.9 KiB
Go

package extractfreq
import (
"fmt"
"log"
"math/cmplx"
"git.crumpington.com/public/jlaudio/lib/flac"
"gonum.org/v1/gonum/fourier"
"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/plotutil"
"gonum.org/v1/plot/vg"
)
func PlotFFT(path string, nSamples int, targetFreq float64) {
L, R, err := flac.Load(path)
if err != nil {
panic(err)
}
if nSamples < len(L) {
nSamples = len(L)
}
data := make([]float64, nSamples)
for i := range data {
data[i] = float64(L[i]) + float64(R[i])
}
fft := fourier.NewFFT(nSamples)
cCoeffs := fft.Coefficients(nil, data)
amps := make([]float64, len(cCoeffs))
freqs := make([]float64, len(cCoeffs))
ampMax := float64(0)
for i := range freqs {
amps[i] = cmplx.Abs(cCoeffs[i])
if amps[i] > ampMax {
ampMax = amps[i]
}
freqs[i] = fft.Freq(i) * 48000
}
// Normalize coefficients.
for i := range amps {
amps[i] /= ampMax
}
/*
// Use a moving window to search for local peaks.
hws := []*HarmonicWindow{}
// Bypass low-frequency samples.
i := 0
for i < len(freqs) && freqs[i] < 24 {
i++
}
iCenter := i
for iC{
}
*/
// Find frequency window around midi note.
harmonics := []float64{0.25, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
for _, harmonic := range harmonics {
hw := NewHarmonicWindow(
targetFreq,
harmonic,
amps,
freqs)
p, err := plot.New()
if err != nil {
panic(err)
}
log.Printf("Making points...")
pts := make(plotter.XYs, 0, len(hw.Amps))
for i := range hw.Amps {
pts = append(pts, plotter.XY{
X: hw.Freqs[i],
Y: hw.Amps[i],
})
}
log.Printf("Plotting...")
if err = plotutil.AddLines(p, "fft", pts); err != nil {
panic(err)
}
//p.Y.Scale = plot.LogScale{}
//p.X.Scale = plot.LogScale{}
log.Printf("Saving...")
filename := fmt.Sprintf("plot-%03.2f.png", harmonic)
if err := p.Save(8*vg.Inch, 8*vg.Inch, filename); err != nil {
panic(err)
}
}
}