использование WebAudio AnalyserNode.getFloatFrequencyData () для изменения высоты тона BufferSource - PullRequest
0 голосов
/ 03 августа 2020

У меня есть BufferSource, который я создаю таким образом:

const proxyUrl = location.origin == 'file://' ? 'https://cors-anywhere.herokuapp.com/' : '';
const request = new XMLHttpRequest();
request.open('GET', proxyUrl + 'http://heliosophiclabs.com/~mad/projects/mad-music/non.mp3', true);
// request.open('GET', 'non.mp3', true);
request.responseType = 'arraybuffer';
request.onload = () => {
    audioCtx.decodeAudioData(request.response, buffer => {
        buff = buffer;
    }, err => {
        console.error(err);
    });
}
request.send();

Да, обходной путь CORS - patheti c, но именно так я обнаружил, что могу работать локально без необходимости запускать HTTP-сервер. В любом случае ...

Я бы хотел изменить высоту этого буфера. Я пробовал разные формы этого:

const source = audioCtx.createBufferSource();
source.buffer = buff;

const analyser = audioCtx.createAnalyser();
analyser.connect(audioCtx.destination);
analyser.minDecibels = -140;
analyser.maxDecibels = 0;

analyser.smoothingTimeConstant = 0.8;
analyser.fftSize = 2048;
const dataArray = new Float32Array(analyser.frequencyBinCount);
source.connect(analyser);
analyser.connect(audioCtx.destination);
source.start(0);
analyser.getFloatFrequencyData(dataArray);
console.log('dataArray', dataArray);

Все безрезультатно. dataArray всегда заполнен значениями -Infinity, что бы я ни пытался.

Моя идея состоит в том, чтобы получить данные из этой частотной области, а затем переместить все частоты вверх / вниз на некоторую величину и создать новый узел осциллятора. из них вот так:

    const wave = audioCtx.createPeriodicWave(real, waveCompnents);
    oscillator.setPeriodicWave(wave);

В любом случае. Если у кого-то есть лучшее представление о том, как изменить высоту звука, я хотел бы это услышать. К сожалению, Detune и PlayRate, похоже, делают в основном одно и то же (почему есть два способа сделать одно и то же?), А именно просто ускорять или замедлять воспроизведение, так что это не так.

1 Ответ

1 голос
/ 04 августа 2020

Во-первых, есть небольшая проблема с кодом: вы дважды подключаете analyser к месту назначения. На самом деле вам вообще не нужно его подключать.

Во-вторых, я думаю, что причина, по которой вы получаете значения all -infinity, заключается в том, что вы вызываете getFloatFrequencyData сразу после запуска источника. Есть большая вероятность, что сэмплы не воспроизводились, поэтому в анализаторе есть только буферы со всеми нулями.

Вам нужно позвонить getFloatFrequencyData через некоторое время, чтобы увидеть ненулевые значения.

В-третьих, я не думаю, что это вообще сработает, даже для изменения высоты тона осциллятора. getFloatFrequencyData возвращает только информацию о величине. Вам понадобится информация о фазе гармоник, чтобы все сдвинуть правильно. В настоящее время нет возможности получить информацию о фазе.

В-четвертых, если у вас есть AudioBuffer с необходимыми данными, подумайте об использовании playbackRate для изменения высоты тона. Не уверен, что это даст нужный сдвиг.

...