JS Интерфейс AudioContext: я делаю это правильно? - PullRequest
1 голос
/ 11 февраля 2020

У меня есть следующая функция:

var PE_AudioManager_playSe = AudioManager.playSe;
AudioManager.playSe = function(se) {

    if (se.name.substring(0,5) === `data:`) {

        let audioContext = new (window.AudioContext || window.webkitAudioContext)();

        let gainNode = audioContext.createGain();
        gainNode.gain.value = (se.volume / 100) || 0;

        let panNode = audioContext.createStereoPanner();
        panNode.pan.value = (se.pan / 100) || 0;

        let source = audioContext.createBufferSource();
        audioContext.decodeAudioData(se.name.split(`,`)[1].base64ToArrayBuffer(), function(buffer) {
            source.buffer = buffer;
            source.connect(gainNode);
            source.connect(panNode);
            source.connect(audioContext.destination);
            source.detune.value = (se.pitch - 100);
            source.start(0);
         });

    } else {

        PE_AudioManager_playSe.call(this,se);
    };

};

Это псевдоним для существующей функции, которая обрабатывает воспроизведение звуковых звуковых эффектов. Этот псевдоним «перехватывает» подпрограмму и использует интерфейс AudioContext для воспроизведения звука, если свойство .name исходного объекта является URI / base64 данных, а не именем файла.

Воспроизводится звуковой эффект без проблем, кроме того, что я не думаю, что я делаю панорамирование ( .createStereoPanner ) или громкость ( .createGain ) правильно - я не думаю, что слышу разницу, если я настраиваю кастрюля или объем. Но я могу ошибаться / сойти с ума.

Этот код выглядит правильно? Кто-нибудь может указать мне правильное направление? Заранее спасибо.

1 Ответ

0 голосов
/ 11 февраля 2020

Gain- и PannerNode имеют минимальное и максимальное значения. Контролируйте свой ввод, чтобы эти диапазоны соблюдались. Но проблема кроется в другом месте.

const ctx = new AudioContext();
const gainNode = ctx.createGain();
const panNode = ctx.createStereoPanner();

console.log(gainNode.gain.minValue, gainNode.gain.maxValue);
console.log(panNode.pan.minValue, panNode.pan.maxValue);

Соединение узлов является критическим. Что помогает мне, так это смотреть на нее как на гитару (или любой другой электрический инструмент) с проводами, которые необходимо подключить. Один провод идет от гитары к педали усиления, этот провод идет к педали панорамирования, а этот провод идет к усилителю для вывода сигнала.

То же самое относится и к вашим узлам. Подключите source (гитара) к gainNode (педаль усиления), затем gainNode к panNode (педаль панорамирования) и panNode к audioContext.destination (усилитель).

audioContext.decodeAudioData(se.name.split(`,`)[1].base64ToArrayBuffer(), function(buffer) {
    source.buffer = buffer;
    source.connect(gainNode);
    gainNode.connect(panNode);
    panNode.connect(audioContext.destination);
    source.detune.value = (se.pitch - 100);
    source.start(0);
});

На самом деле попытайтесь визуализировать это так. Может быть, даже нарисовать это на бумаге, если вы сделаете это более сложным.

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

Надеюсь, это поможет. Если у вас есть какие-либо вопросы или мне неясно, пожалуйста, дайте мне знать.

...