Постепенно изменить Панели API Web Audio
Я пытаюсь использовать простой ввод диапазона HTML для управления панорамированием аудио моего Web Audio API, но я могу получить только 3 "позиции" для моего аудио выхода:
-Центр
-100% влево
-100% вправо.
Я хотел бы иметь что-то среднее между позициями, например, 20% слева и 80% справа и так далее...
Код, который я использую:
//Creating the node
var pannerNode = context.createPanner();
//Getting the value from the HTML input and using it on the position X value
document.getElementById('panInput').addEventListener('change', function () {
pannerNode.setPosition(this.value, 0, 0);
});
И это относится к этому входу в моем HTML-файле:
<input id="panInput" type="range" min="-1" max="1" step="0.001" value="0"/>
Кто-нибудь знает, что я делаю не так?
3 ответа
Вам не нужно использовать два паннера - паннер стерео. Этот старый ответ - отличный ответ на этот вопрос:
Как создать очень простой левый / правый панорамирование одинаковой мощности с createPanner ();
На самом деле я обнаружил, что простое панорамирование влево / вправо довольно сложно с API Web Audio. Это действительно настроено для объемного / пространственного материала, и я, честно говоря, не очень хорошо понимаю.
Я обычно делаю панорамирование так:
var panLeft = context.createGain();
var panRight = context.createGain();
var merger = context.createMerger(2);
source.connect(panLeft);
source.connect(panRight);
panLeft.connect(merger, 0, 0);
panRight.connect(merger, 0, 1);
merger.connect(context.destination);
document.getElementById('panInput').addEventListener('change', function () {
var val = this.value;
panLeft.gain.value = ( val * -0.5 ) + 0.5;
panRight.gain.value = ( val * 0.5 ) + 0.5;
});
По сути, вы посылаете сигнал двум узлам усиления, которые собираетесь использовать в качестве левого и правого канала. Затем вы берете значение из вашего элемента range и используете его для установки усиления на каждом из узлов.
Это своего рода ленивая версия, хотя. В серьезных аудиоприложениях с панорамированием обычно немного больше математики, чтобы убедиться, что в общем уровне изменений нет - но, надеюсь, этого достаточно, чтобы начать работу.
Я совершенно уверен, что есть лучший и более простой способ сделать это, но сейчас он определенно работает для меня.
Если у кого-то есть лучший / более чистый способ сделать это, пожалуйста, поделитесь им здесь!
Спасибо Кевину Эннису за подсказку!
Файл JavaScript
//Create a splitter to "separete" the stereo audio data to two channels.
var splitter = context.createChannelSplitter(2);
//Connect your source to the splitter (usually, you will do it with the last audio node before context destination)
audioSource.connect(splitter);
//Create two gain nodes (one for each side of the stereo image)
var panLeft = context.createGain();
var panRight = context.createGain();
//Connect the splitter channels to the Gain Nodes that we've just created
splitter.connect(panRight,0);
splitter.connect(panLeft,1);
//Getting the input data from a "range" input from HTML (the code used on this range will be shown right on the end of this code)
var panPosition = document.getElementById("dispPanPositionLiveInput");
document.getElementById('panControl').addEventListener('change', function () {
var val = this.value;
panPosition.value = val;
panLeft.gain.value = ( val * -0.5 ) + 0.5;
panRight.gain.value = ( val * 0.5 ) + 0.5;
});
//Create a merger node, to get both signals back together
var merger = context.createChannelMerger(2);
//Connect both channels to the Merger
panLeft.connect(merger, 0, 0);
panRight.connect(merger, 0, 1);
//Connect the Merger Node to the final audio destination (your speakers)
merger.connect(context.destination);
HTML-файл