I want a tone from an oscillator to play under an audio clip of a song. How do I make the tones loudness match the loudness of the sample? I want the tone to be quieter when the song is quieter, and the tone to be louder at the louder parts. I have used the createAnalyzer to detect the volume of the sample, but the code does not work.
const audioContext = new AudioContext();
const audiodiv = document.querySelector('.audiodiv')
const buffer = audioContext.createBuffer(
1,
audioContext.sampleRate * 1,
audioContext.sampleRate
);
const channelData = buffer.getChannelData(0)
for (let i = 0; i < buffer.length; i++){
channelData[i] = Math.random() * 2 - 1;
}
const primaryGainControl = audioContext.createGain()
primaryGainControl.gain.setValueAtTime(0.005, 0);
primaryGainControl.connect(audioContext.destination);
const samplebutton = document.createElement('button')
samplebutton.innerText = 'sample'
samplebutton.addEventListener('click', async () => {
let volume = 0
const response = await fetch('testsong.wav')
const soundBuffer = await response.arrayBuffer()
const sampleBuffer = await audioContext.decodeAudioData(soundBuffer)
const analyzer = audioContext.createAnalyser()
volume = analyzer.frequencyBinCount
const sampleSource = audioContext.createBufferSource()
sampleSource.buffer = sampleBuffer
sampleSource.playbackRate.setValueAtTime(1, 0)
sampleSource.connect(primaryGainControl)
sampleSource.start()
})
audiodiv.appendChild(samplebutton)
const toneButton = document.createElement('button')
toneButton.innerText = "tone"
toneButton.addEventListener("click", () => {
const toneOscillator = audioContext.createOscillator();
toneOscillator.frequency.setValueAtTime(150, 0)
toneOscillator.type = "sine"
toneOscillator.connect(oscGain);
toneOscillator.start()
toneOscillator.stop(audioContext.currentTime + 5)
const oscGain = audioContext.createGain()
oscGain.gain.value = volume
oscGain.connect(primaryGainControl)
})
audiodiv.appendChild(toneButton)