func (f *Fseq) pdetect(af *sndfile.File, lower, upper float64, length, fftbins int) { windowWidth := SampleRate / lower t := math.Trunc(windowWidth) for index := 0; index < length; index++ { var width uint if int(math.Trunc((windowWidth-t)*10.0)) < 5 { width = uint(t) } else { width = uint(math.Ceil(windowWidth)) } full := make([]float64, int32(width*2)*af.Format.Channels) _, err := af.Seek(af.Format.Frames*int64(index)/int64(length), sndfile.Set) if err != nil { panic(err) } read, err := af.ReadFrames(full) if err != nil { panic(err) } if sumread := read; read != int64(width*2) { _, err = af.Seek(0, sndfile.Set) if err != nil { panic(err) } read, err = af.ReadFrames(full[(int32(sumread) * af.Format.Channels):]) if err != nil { panic(err) } if read+sumread != int64(width*2) { width = uint((read + sumread) / 2) } } samps := mixdown(full, int(af.Format.Channels)) bestComb := uint(0) bestPower := float64(-999999) combLow := width combHigh := uint(math.Ceil(SampleRate / upper)) for comb := combLow; comb >= combHigh; comb -= QuickCombInterval { var power float64 for w := uint(0); w < comb; w++ { power += samps[w] * samps[w+comb] } if power > bestPower { bestPower = power bestComb = comb } } f.Pitches = append(f.Pitches, SampleRate/float64(bestComb)) } }