func readSamples() ([]float64, float64, error) { w, err := wav.New(os.Stdin) if err != nil { return nil, 0, err } log.Printf("format: %d, channels: %d, sample rate: %d, byte rate: %d, bps: %d, samples: %d, duration: %v\n", w.Header.AudioFormat, w.Header.NumChannels, w.Header.SampleRate, w.Header.ByteRate, w.Header.BitsPerSample, w.Samples, w.Duration) rawSamples, err := w.ReadFloats(w.Samples) if err != nil { return nil, 0, err } flatSamples := flattenChannels(int(w.Header.NumChannels), rawSamples) return flatSamples, float64(w.Header.SampleRate), nil }
func (w *Wav) Info() (info codec.SongInfo, err error) { var r io.ReadCloser if len(w.initbuf) != 0 { r = ioutil.NopCloser(bytes.NewBuffer(w.initbuf)) } if r == nil { r, _, err = w.Reader() if err != nil { return } } wv, err := wav.New(r) r.Close() if err != nil { return } return codec.SongInfo{ Time: wv.Duration, }, nil }
func (w *Wav) Init() (sampleRate, channels int, err error) { if w.w == nil { r, _, err := w.Reader() if err != nil { return 0, 0, err } buf := new(bytes.Buffer) defer func() { w.initbuf = buf.Bytes() }() wr, err := wav.New(io.TeeReader(r, buf)) if err != nil { r.Close() return 0, 0, err } w.r = r w.w = wr } return int(w.w.SampleRate), int(w.w.NumChannels), nil }
func getHits() ([]hit, error) { w, err := wav.New(os.Stdin) if err != nil { return nil, err } log.Printf("format: %d, channels: %d, sample rate: %d, byte rate: %d, bps: %d, samples: %d, duration: %v\n", w.Header.AudioFormat, w.Header.NumChannels, w.Header.SampleRate, w.Header.ByteRate, w.Header.BitsPerSample, w.Samples, w.Duration) winSize := int(w.Header.SampleRate * uint32(w.Header.NumChannels) / winDenom) cursor := 0 hits := make([]hit, 0) for { rawSamples, err := w.ReadFloats(winSize) if err != nil { if err == io.EOF || err == io.ErrUnexpectedEOF { break } else { return nil, err } } if len(rawSamples) < winSize { break } samples := flattenChannels(int(w.Header.NumChannels), rawSamples) pxx, freqs := spectral.Pwelch(samples, float64(w.Header.SampleRate), &spectral.PwelchOptions{NFFT: 16384, Scale_off: true}) maxPower, maxPowerFreq := findPeak(pxx, freqs, 32, 880) pMaxPower, pMaxPowerFreq := findPeak(pxx, freqs, 55, 170) harmonic := true if !dsputils.Float64Equal(maxPowerFreq, pMaxPowerFreq) { if maxPowerFreq < pMaxPowerFreq || !areHarmonic(maxPower, pMaxPower) { fmt.Printf("t = %v: %f !~ %f\n", fmtSeconds(float64(cursor)/float64(w.Header.SampleRate)), maxPowerFreq, pMaxPowerFreq) harmonic = false } } v1Freq := pMaxPowerFreq * 1.1 v1Pow := powerAtFreq(v1Freq, pxx, freqs) p1Freq := pMaxPowerFreq * 1.2 p1Pow := powerAtFreq(p1Freq, pxx, freqs) v2Freq := pMaxPowerFreq * 1.3 v2Pow := powerAtFreq(v2Freq, pxx, freqs) p2Freq := pMaxPowerFreq * 1.4 p2Pow := powerAtFreq(p2Freq, pxx, freqs) if harmonic && pMaxPower >= 0.00 && pMaxPowerFreq >= 55.0 && pMaxPowerFreq <= 160.0 && v1Pow < p1Pow && v2Pow < p2Pow { hits = append(hits, hit{t: float64(cursor) / float64(w.Header.SampleRate), freq: pMaxPowerFreq, pow: pMaxPower}) } cursor += len(rawSamples) / int(w.Header.NumChannels) } return hits, nil }