Как выполнить простую линейную повторную выборку с помощью ScriptProcessorNode? - PullRequest
0 голосов
/ 01 апреля 2020

В настоящее время я пытаюсь динамически замедлить скорость воспроизведения с помощью 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. Почему это так? Неужели я слишком наивен, думая, что я могу замедлить звуковой сигнал, просто линейно интерполируя между сигналами?

Вот скрипка: https://jsfiddle.net/6Le7aq42/

1 Ответ

1 голос
/ 01 апреля 2020

Понял, ошибка была написана (completion - 1) вместо (1 - completion).

...