package extractfreq import ( "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. p, err := plot.New() if err != nil { panic(err) } log.Printf("Making points...") pts := make(plotter.XYs, len(amps)) for i := range amps { pts[i].X = freqs[i] pts[i].Y = 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...") if err := p.Save(8*vg.Inch, 8*vg.Inch, "plot.png"); err != nil { panic(err) } }