Как я могу импортировать модуль в AudioWorkletProcessor, который изменен в другом месте? - PullRequest
0 голосов
/ 07 апреля 2020

Я пытаюсь изменить значение, которое используется AudioWorkletProcessor, из другого модуля, но из контекста AudioWorkletProcessor это значение не изменяется и остается неизменным. Но из модуля, который модифицирует данные, при запросе данные фактически изменились там. Это похоже на совершенно отдельный экземпляр / состояние модуля, который содержит данные (функции. js) для модификатора (main. js) и считывателя (аудио-процессор. js)

Здесь у нас есть audio-processor.js

import { sawWave } from "/src/functions.js";

var tick = 0

class AudioProcessor extends AudioWorkletProcessor {
    process(inputs, outputs, parameters) {
        const output = outputs[0]
        output.forEach(channel => {

            // emphasis on sawWave function
            var value = sawWave(tick) * 0.1;
            for (let i = 0; i < channel.length; i++) {
                channel[i] = value
            }
        });
        tick++
        return true
    }
}

registerProcessor('audio-processor', AudioProcessor)

Здесь у нас есть functions.js, который содержит sawWave (), который импортируется в audio-processor.js

let variables = {
    // emphasis on this variable
    sawWaveFrequency: 1
}

export function setSawFrequency(freq) {
    variables.sawWaveFrequency = freq
}

export function sawWave(tick) {
    console.log(variables.sawWaveFrequency)
    // this function uses the variable defined above and is imported by audio-processor.js
    // variables.sawWaveFrequency doesn't change for audio-processor.js when modified from main.js
    // so the output will will always be as if variables.sawWaveFrequency = 1
    return tick * variables.sawWaveFrequency % 10;
}

Здесь у нас есть main.js, который обрабатывает ввод со страницы HTML

import { setSawFrequency } from "/src/functions.js";

var audioContext
var whiteNoiseNode

async function init() {
    audioContext = new AudioContext()
    await audioContext.audioWorklet.addModule("/src/audio-processor.js")
    whiteNoiseNode = new AudioWorkletNode(audioContext, 'audio-processor')
}

function play() {
    whiteNoiseNode.connect(audioContext.destination)
}

function main() {
    document.querySelector("#play").onclick = play;
    document.querySelector("#init").onclick = init;

    document.querySelector("#slider-mult").oninput = function() {
        // this is supposed to change the value, but only does so in the context of main.js and not audio-processor.js
        setSawFrequency(this.value);
    }
}

main();

РЕДАКТИРОВАТЬ: я так понимаю, вы должны использовать только AudioWorkletProcessor.port и параметр parameters в функции процесса для связи с ним

Ответы [ 2 ]

0 голосов
/ 06 мая 2020

Вы также можете использовать SharedArrayBuffer

Создать объект общей памяти в одном модуле.

  const length = 100;
  const size = Int32Array.BYTES_PER_ELEMENT * length;
  this.sab = new SharedArrayBuffer(size);
  this.sharedArray = new Int32Array(this.sab);

Отправьте его на AudioWorkletProcessor

  this.worker.port.postMessage({
      sab: this.sab
  });

В AudioWorkletProcessor

this.port.onmessage = event => {
      this.sharedArray = new Int32Array(event.data.sab);
}

Теперь оба модуля совместно используют один и тот же массив (this.sharedArray) .

0 голосов
/ 07 апреля 2020

Вы уже на правильном пути. Чтобы изменить значение внутри AudioWorkletProcessor, вы можете либо использовать пользовательский AudioParam, либо отправить сообщение через MessagePort.

. Причина, по которой ваш код не работает, заключается в том, что вы технически заканчиваете с два экземпляра одного и того же модуля. AudioWorkletProcessor работает в другом потоке и не имеет доступа к модулям, загруженным в основной поток. Поэтому /src/functions.js загружается дважды. Один экземпляр живет в основном потоке, а другой - в аудиопотоке. Каждый из них не знает, что другой существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...