Beispiel #1
0
func (vis *basic) Push(samples []float32) {
	po := &spectral.PwelchOptions{
		NFFT: 64,
	}
	powers, _ := spectral.Pwelch(float32To64(samples), vis.freq, po)
	vis.Set(float64ToInt(powers, 10))
}
Beispiel #2
0
func findNextCandidate(samples []float64, sampleRate, min, max float64, c0 int) int {
	sr := int(sampleRate)

	for c := 0; c+sr < len(samples); c += sr {
		pxx, freqs := spectral.Pwelch(samples[c:c+sr], sampleRate, pwOpts)
		globalPeakPower, globalPeakFreq := findPeak(pxx, freqs, 32, 880)
		localPeakPower, localPeakFreq := findPeak(pxx, freqs, min, max)

		if !dsputils.Float64Equal(globalPeakPower, localPeakPower) {
			if globalPeakFreq < localPeakFreq || !areHarmonic(globalPeakFreq, localPeakFreq) {
				continue
			}
		}

		if localPeakPower < purrMinPower {
			continue
		}

		fmt.Printf("Candidate at %v (local peak: %f Hz (%.2f), global peak: %f Hz (%.2f))\n", fmtSeconds(float64(c+c0)/sampleRate), localPeakFreq, localPeakPower, globalPeakFreq, globalPeakPower)
		findRepeats(samples[c:], sampleRate, localPeakFreq, true, true)

		return c + c0
	}

	return -1
}
Beispiel #3
0
func findRepeats(samples []float64, sampleRate, baseFreq float64, lookBelow, lookAbove bool) {
	if !lookBelow && !lookAbove {
		fmt.Println("findRepeats: both lookBelow and lookAbove are false.")
	}

	win0 := int(2.9 * sampleRate)

	if win0 >= len(samples) {
		fmt.Println("findRepeats: reached the end of the samples.")
		return
	}

	win1 := minInt(int(6.1*sampleRate), len(samples))

	if win1-win0 < int(sampleRate) {
		fmt.Println("findRepeats: reached near the end of the samples.")
		return
	}

	freqBelow := baseFreq / 1.5
	freqAbove := baseFreq * 1.5

	pxx, freqs := spectral.Pwelch(samples[win0:win1], sampleRate, pwOpts)
	peakPowerBelow, peakFreqBelow := findPeak(pxx, freqs, freqBelow/1.1, freqBelow*1.1)
	peakPowerAbove, peakFreqAbove := findPeak(pxx, freqs, freqAbove/1.1, freqAbove*1.1)

	var repeatPower float64 = 0
	var repeatFreq float64 = 0
	foundBelow := false
	foundAbove := false

	if lookBelow {
		if lookAbove {
			if peakPowerBelow > peakPowerAbove {
				repeatPower = peakPowerBelow
				repeatFreq = peakFreqBelow
				foundBelow = true
			} else {
				repeatPower = peakPowerAbove
				repeatFreq = peakFreqAbove
				foundAbove = true
			}
		} else {
			repeatPower = peakPowerBelow
			repeatFreq = peakFreqBelow
			foundBelow = true
		}
	} else {
		repeatPower = peakPowerAbove
		repeatFreq = peakFreqAbove
		foundAbove = true
	}

	if repeatPower >= purrMinPower {
		fmt.Printf("Repeat candidate: %f Hz (%.2f)\n", repeatFreq, repeatPower)
		findRepeats(samples[int(4*sampleRate):], sampleRate, baseFreq, lookBelow && foundBelow, lookAbove && foundAbove)
	} else {
		fmt.Println("No further repeat candidates found.")
	}
}
Beispiel #4
0
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
}