I want to implement an audio player's rewind functionality so than I hear the audio playing in fast rewind while I'm holding the rewind button down.
I have an AudioBuffer
and I am reversing it, but when playing it, I can't hear anything. However, the fast forward mode I implemented does work fine:
private gainNode: GainNode = {} as GainNode;
private aCtx = new AudioContext({ sampleRate: 16000 });
private source?: AudioBufferSourceNode;
// [...]
if (this.source) {
this.source = this.aCtx.createBufferSource();
let bufferToPlay = this.speechAudioBufferService.getModifyedBuffer;
if (this.speechAudioBufferService.getModifyedBuffer && this.fastRewind) {
const actualBuffer = this.speechAudioBufferService.getModifyedBuffer;
const channels = actualBuffer.numberOfChannels;
const length = actualBuffer.length;
const reversedBuffer = this.aCtx.createBuffer(channels, length, actualBuffer.sampleRate);
for (let channel = 0; channel < channels; channel++) {
const originalData = actualBuffer.getChannelData(channel);
const reversedData = reversedBuffer.getChannelData(channel);
for (let i = 0; i < length; i++) {
reversedData[i] = originalData[length - i - 1];
}
}
bufferToPlay?.copyFromChannel(reversedBuffer.getChannelData(0), 0);
}
if (bufferToPlay) {
this.source.buffer = bufferToPlay;
}
this.source.playbackRate.value = this.playRate();
this.source
.connect(this.gainNode)
.connect(this.aCtx.destination);
this.source.start(0, this.positionAndDurationService.currentPosition);
Your code is incorrect, as you fill in reversedData
but never put that data back into reversedBuffer
:
const originalData = actualBuffer.getChannelData(channel);
const reversedData = reversedBuffer.getChannelData(channel);
for (let i = 0; i < length; i++) {
reversedData[i] = originalData[length - i - 1];
}
Where does reversedData
go now? Nowhere. So, when you run:
bufferToPlay?.copyFromChannel(reversedBuffer.getChannelData(0), 0);
You are just copying one channel from an empty buffer (reversedBuffer
) into bufferToPlay
.
Here's a simpler way to do it, copying all channels and using Float32Array
and its .revese()
method:
if (this.speechAudioBufferService.getModifyedBuffer && this.fastRewind) {
const {
numberOfChannels,
length,
sampleRate,
} = bufferToPlay.numberOfChannels;
const reversedBuffer = this.aCtx.createBuffer(
numberOfChannels,
length,
sampleRate,
);
for (let channel = 0; channel < numberOfChannels; ++channel) {
const reversedSamples = bufferToPlay.getChannelData(channel).reverse();
reversedBuffer.copyToChannel(reversedSamples, channel);
}
bufferToPlay = reversedBuffer;
}