57 lines
1.2 KiB
Go
57 lines
1.2 KiB
Go
package extractfreq
|
|
|
|
import (
|
|
"math"
|
|
|
|
"git.crumpington.com/public/jlaudio/lib/util"
|
|
"gonum.org/v1/gonum/stat"
|
|
)
|
|
|
|
type HarmonicWindow struct {
|
|
TargetFreq float64
|
|
Amps []float64
|
|
Freqs []float64
|
|
Idx0 int
|
|
IdxPeak int
|
|
IdxPeakInterp float64
|
|
FreqPeakInterp float64
|
|
AmpPeak float64
|
|
AmpMean float64
|
|
AmpStd float64
|
|
}
|
|
|
|
// Construct a window around the harmonic peak with a width of 100 cents.
|
|
func NewHarmonicWindow(
|
|
amps []float64,
|
|
freqs []float64,
|
|
targetFreq float64,
|
|
idxPeak int,
|
|
) *HarmonicWindow {
|
|
deltaF := freqs[1] - freqs[0] // Size of frequency bins.
|
|
fCenter := freqs[idxPeak] // Center frequency.
|
|
|
|
// Create a window approximately 200 cents in width.
|
|
deltaIdx := int(math.Round(deltaF / (100 * util.CentDeltaFreq(fCenter))))
|
|
idxMin := idxPeak - deltaIdx
|
|
idxMax := idxPeak + deltaIdx
|
|
|
|
if idxMin < 0 {
|
|
idxMin = 0
|
|
}
|
|
|
|
if idxMax > len(freqs) {
|
|
idxMax = len(freqs)
|
|
}
|
|
|
|
hw := &HarmonicWindow{
|
|
TargetFreq: targetFreq,
|
|
Amps: amps[idxMin:idxMax],
|
|
Freqs: freqs[idxMin:idxMax],
|
|
IdxPeak: idxPeak,
|
|
AmpPeak: amps[idxPeak],
|
|
}
|
|
|
|
hw.AmpMean, hw.AmpStd = stat.MeanStdDev(hw.Amps, nil)
|
|
return hw
|
|
}
|