import PitchFinder from 'pitchfinder'
const detectPitch = PitchFinder.AMDF()
const notes = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'G', 'G#']
export default {
data () {
return {
note: 'A',
register: 4,
cents: 0
}
},
mounted () {
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
const context = new AudioContext()
const source = context.createMediaStreamSource(stream)
const processor = context.createScriptProcessor()
source.connect(processor)
processor.connect(context.destination)
processor.onaudioprocess = e => {
const hz = detectPitch(e.inputBuffer.getChannelData(0))
if (hz) {
console.log(hz)
// ¢ or c = 1200 × log2 (f2 / f1), 1 semitone = 100 cents
const semitones = 12 * (Math.log2((hz) / 440))
const cents = semitones * 100
// TODO: update component
}
}
})
.catch(e => {
// TODO: handle error
})
}
}
}
I have the above code in my Vue component (note, only some of the Vue-related code is attached for context.) I'm having an issue where the value printed to console is inaccurate. I used a drone and verified its pitch with other reputable tuners (A = 440 Hz). When printed to console with my code, the Hz is always ~404, other pitches are offset as well. Why is that? Thanks.
You have a sample rate wrong somewhere else in your code.
My guess is that you're running your audio input at 48 kHz but the pitch detector thinks the sample rate is 44.1 kHz.