Я пытаюсь создать синтезатор/секвенсор с помощью API WebAudio. В основном пытается сделать что-то, что может воспроизводить песню, состоящую из заметок и событий, таких как MIDI, для управления несколькими каналами синтезатора. Но мне все же нужно заняться аспектом синхронизации.Как работает WebAudio? Использует setInterval плохое решение?
Я читал учебники по API WebAudio, но я не совсем понимаю, как работает время/планирование/часы. Сначала я сделал polyphonic synthesizer, в котором воспроизводились ноты для нажатия клавиш, и это не требовало никакого учета времени. Затем я сделал осциллятор воспроизведением массива заметок с определенными временными интервалами, используя setInterval
. Однако я заметил в прошлом при переключении вкладок в Google Chrome скорость воспроизведения значительно замедляется, я полагаю, что она менее ресурсоемкая, но другие библиотеки синтезаторов не имели этой проблемы. Также я могу только предположить, что использование setInterval
не очень хорошо для гладкого (буферизуется правильного слова?) Воспроизведения, особенно при рассмотрении осцилляторов конвертов ADSR.
Из того, что я читаю, API WebAudio имеет постоянно увеличивающуюся переменную таймера currentTime
. Но если заметки хранятся в массиве, и я хочу его циклически с заданной скоростью, как будет обрабатываться таймер WebAudio для итерации массива по заданной скорости? Мой setInterval solution (volume warning) не учитывает таймер WebAudio вообще и просто вызывает voice()
с setInterval
, чтобы сыграть заметку, перезаписав последний голос.
Есть ли лучшие или эффективные способы воспроизведения/петли последовательности заметок, отличных от setInterval
?
Просто обновление для уточнения: Когда я писал этот вопрос, я использую setInterval
играть последовательность нот через определенные промежутки времени (например, внеплановые - постоянно запуска/остановки осцилляторы) и было интересно, о более надежных способов играть ноты. Я нашел, что лучшим решением было бы использовать setValueAtTime
на osc.frequency
, а также GainNode
. Для простого прототипа synth это работает хорошо, но более продвинутый синтезатор может использовать таймер на osc.start
и osc.stop
. Проблема петля песни. Чтобы зацикливаться, мне нужно постоянно планировать больше заметок, чтобы к концу песни оно начиналось. Я могу использовать setInterval
, чтобы запланировать весь цикл петель, , но он все равно должен поддерживать время с песней, воспроизводимой, и setInterval
(и даже вызовы onmessage
веб-работников) можно было бы замедлить, если вкладка неактивна, например. Часы setInterval даже не надежны, поэтому я просто проверяю каждые 5 мс, если (currentTime >= songTime)
и планирую, если условие выполнено. Этот метод может быть не слишком эффективным. What I have so far.
Я чувствую, что я схожу с ума. Я больше не могу вызвать проблему «setInterval». Только в Chrome это происходит редко и случайным образом, и еще хуже, даже при использовании вашего метода работы с веб-рабочим он даже замедляется. Я использовал метод URI Blob, потому что Chrome специально не может запускать Web Workers локально (Firefox может). http://output.jsbin.com/busonu – bryc
Хмм, я не могу заставить его запускать этот код. Каково ваше оборудование/ОС? – cwilso
Тестирование на _2012 Intel i7 2770/16GB RAM/Win7_ и _2015 Intel i5/8GB RAM/Win10_. Если он не может быть искусственно запущен, есть ли способ обнаружить в коде, если бы произошел «дроссель» или «desync», который не будет возникать на веб-сайте в его собственном потоке? – bryc