问题
I have heard that by changing playback speed we can modify the frequency of the audio. I have tested it here : https://teropa.info/blog/2016/08/10/frequency-and-pitch.html
But the problem is that I need a recorded audio file to do that. From what I have found web audio can't change playback speed of live audio. I have been thinking that if we save the audio in buffer we can change its playback speed thus changing the frequency.
I am new to web-audio API. I have found an article that records live audio by saving it to the buffer. https://docs.sumerian.amazonaws.com/articles/webaudio-1/
What I want is :-
- Get audio from mic.
- Save it into buffer.
- Change Playback speed.
- Play on the speakers.
Demo explaining how to change playback speed of a buffernode https://mdn.github.io/webaudio-examples/decode-audio-data/
But I want live mic audio to be used in place of recorded sound.
Here is my try on fiddle
https://jsfiddle.net/5dza62b8/13/
var audioContext = new(window.AudioContext || window.webkitAudioContext)();
var streamSource, scriptNode, bufferSource, audioBuffer;
var playbackControl = document.querySelector('#playback-rate-control');
var playbackValue = document.querySelector('#playback-rate-value');
// define variables
window.start_audio = function() {
navigator.mediaDevices.getUserMedia({
audio: true
}).then((stream) => {
alert("Got audio stream from microphone!");
audioContext = new AudioContext();
// Create an AudioNode from the stream.
streamSource = audioContext.createMediaStreamSource(stream);
scriptNode = audioContext.createScriptProcessor(2048, 1, 1);
bufferSource = audioContext.createBufferSource();
// Whenever onaudioprocess event is dispatched it creates a buffer array with the length bufferLength
scriptNode.onaudioprocess = (audioProcessingEvent) => {
realtimeBuffer = audioProcessingEvent.inputBuffer.getChannelData(0);
// Create an array of buffer array
audioBuffer.push(realtimeBuffer);
}
bufferSource.buffer = audioBuffer;
bufferSource.playbackRate.value = 0.8;
streamSource.connect(scriptNode);
bufferSource.connect(audioContext.destination);
bufferSource.start();
}).catch((e) => {
alert(e.name + ". " + e.message);
});
}
// wire up buttons to stop and play audio, and range slider control
playbackControl.addEventListener('input', function() {
bufferSource.playbackRate.value = playbackControl.value;
playbackValue.innerHTML = playbackControl.value;
});
回答1:
This might be a harder problem than you think – if the playback speed is greater than 1, you'll be trying to play sounds that haven't happened yet!
In general though, you can use the web audio API to add effects to live microphone input – here's an example from the MDN documentation which adds a filter to the input: https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/createMediaStreamSource
If you want to slow the live audio down, it is possible – with some caveats. The Web Audio node which allows you to change the playback rate is a BufferSourceNode, which relies on you having loaded the buffer previously. However, you could probably work around this by using a custom AudioWorklet to incrementally put the data into a buffer and play it back using a BufferSourceNode. One thing to consider is how long you'd let this go on for – the buffer would just keep getting bigger and bigger as time went on, and sooner or later your computer would run out of memory!
This is quite involved, and might not be ideal for a first foray into Web Audio, but the best jumping-off point to learn about audio worklets is here: https://developers.google.com/web/updates/2017/12/audio-worklet
Using an audio worklet, you could also investigate some more sophisticated algorithms which would allow you to change the pitch of a sound without changing its length. https://en.wikipedia.org/wiki/Audio_time_stretching_and_pitch_scaling
If you're just getting started with web audio, my recommendation would be that you write something that lets you record a sound, then change its playback rate.
来源:https://stackoverflow.com/questions/55194007/how-to-change-playback-speed-of-live-audio-from-microphone-using-a-buffer