Использование WebAudio для воспроизведения последовательности нот - как остановить асинхронно? - PullRequest
0 голосов
/ 01 мая 2020

Я использую WebAudio для воспроизведения последовательности нот. У меня есть функция playNote, которая работает хорошо; Я посылаю ему частоту записок и время начала и окончания каждой заметки. Генерация параметров последовательности происходит за до фактического звучания, что немного сбивает с толку. Функция просто создает осциллятор для каждой ноты. (Я пробовал другие методы, и это самый чистый).

Но я бы хотел остановить последовательность асинхронно (например, когда происходит внешнее событие). Я попытался настроить главный узел Gain, который мог бы использоваться для управления выходом, но кажется, что он должен быть «внутри» функции, поэтому им нельзя будет управлять позже. Если я попытаюсь отключить объект усиления внутри функции, тогда будет слишком поздно - потому что время запуска и остановки уже передано функции.

Вот моя функция:

function playNote(audioContext,frequency, startTime, endTime, last) {
  gainNode = audioContext.createGain(); //to get smooth rise/fall
  oscillator = audioContext.createOscillator();
  oscillator.frequency.value=frequency;
  oscillator.connect(gainNode);
  gainNode.connect(analyserScale); //analyser is global
  analyserScale.connect(audioContext.destination);
  gainNode.gain.exponentialRampToValueAtTime(toneOn,  startTime + trf);
  gainNode.gain.exponentialRampToValueAtTime(toneOff, endTime+trf);
  oscillator.start(startTime);
  oscillator.stop(endTime);
}

Любая помощь приветствуется!

1 Ответ

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

Для этого: Web Audio API: остановка воспроизведения всех запланированных звуков . Решение состоит в том, чтобы отслеживать запланированные генераторы с помощью массива.

Функция теперь становится: var oscs = []; // список генераторов

function playNote(audioContext,frequency, startTime, endTime, last, index) {
  gainNode = audioContext.createGain(); //to get smooth rise/fall

  oscillator = audioContext.createOscillator();
  oscillator.frequency.value=frequency;
  oscillator.connect(gainNode);
  //keep track of alll the oscs so that they can be switched off if scale is stopped by user
    oscs[index] = oscillator;

  gainNode.connect(analyserScale); //analyser is global
  analyserScale.connect(audioContext.destination);
  gainNode.gain.exponentialRampToValueAtTime(toneOn,  startTime + trf);
  gainNode.gain.exponentialRampToValueAtTime(toneOff, endTime+trf);
  oscillator.start(startTime);
  oscillator.stop(endTime);
}

Затем код для остановки генераторов:

for(let i=0; i<oscs.length; i++) {
    if(oscs[i]){
      oscs[i].stop(0);
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...