如何使用 ScriptProcessorNode 执行简单的线性重采样?
How do I perform simple linear resampling using a ScriptProcessorNode?
我目前正在尝试使用 ScriptProcessorNode 动态降低播放速度。这是我到目前为止一起破解的代码(只处理左声道):
let processor = audioContext.createScriptProcessor(2**14);
let stored = [];
let currIndex = 0;
let playbackRate = 0.666;
processor.onaudioprocess = (e) => {
let leftChannel = e.inputBuffer.getChannelData(0);
for (let i = 0; i < leftChannel.length; i++) stored.push(leftChannel[i]);
let outputLeft = e.outputBuffer.getChannelData(0);
for (let i = 0; i < outputLeft.length; i++) {
let otherIndex = currIndex + i * playbackRate;
let completion = otherIndex % 1;
let otherSampleLow = stored[Math.floor(otherIndex)];
let otherSampleHigh = stored[Math.ceil(otherIndex)];
let val = (completion-1)*otherSampleLow + completion*otherSampleHigh;
outputLeft[i] = val;
}
currIndex += Math.floor(leftChannel.length * playbackRate);
};
let osc = audioContext.createOscillator();
osc.frequency.value = 440;
osc.connect(processor);
osc.start();
然而,对于任何小于 1 的播放速率,这听起来都像是垃圾。这是为什么呢?我是不是太天真了,以为我可以通过在信号之间进行线性插值来减慢音频信号的速度?
这里是 fiddle:https://jsfiddle.net/6Le7aq42/
知道了,错误是 (completion - 1)
而不是 (1 - completion)
。
我目前正在尝试使用 ScriptProcessorNode 动态降低播放速度。这是我到目前为止一起破解的代码(只处理左声道):
let processor = audioContext.createScriptProcessor(2**14);
let stored = [];
let currIndex = 0;
let playbackRate = 0.666;
processor.onaudioprocess = (e) => {
let leftChannel = e.inputBuffer.getChannelData(0);
for (let i = 0; i < leftChannel.length; i++) stored.push(leftChannel[i]);
let outputLeft = e.outputBuffer.getChannelData(0);
for (let i = 0; i < outputLeft.length; i++) {
let otherIndex = currIndex + i * playbackRate;
let completion = otherIndex % 1;
let otherSampleLow = stored[Math.floor(otherIndex)];
let otherSampleHigh = stored[Math.ceil(otherIndex)];
let val = (completion-1)*otherSampleLow + completion*otherSampleHigh;
outputLeft[i] = val;
}
currIndex += Math.floor(leftChannel.length * playbackRate);
};
let osc = audioContext.createOscillator();
osc.frequency.value = 440;
osc.connect(processor);
osc.start();
然而,对于任何小于 1 的播放速率,这听起来都像是垃圾。这是为什么呢?我是不是太天真了,以为我可以通过在信号之间进行线性插值来减慢音频信号的速度?
这里是 fiddle:https://jsfiddle.net/6Le7aq42/
知道了,错误是 (completion - 1)
而不是 (1 - completion)
。