Постепенно меняйте Panner API веб-аудио

Я пытаюсь использовать простой ввод диапазона HTML для управления панорамированием моего аудио Web Audio API, но я могу получить только 3 "позиции" для своего аудиовыхода:
-Center
-100% влево< br>-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"/>

Кто-нибудь знает, что я делаю неправильно?


person Oliver Drummond    schedule 04.09.2013    source источник


Ответы (3)


Вам не нужно использовать два паннера - Паннер стерео. Этот старый ответ является отличным ответом на этот вопрос:

Как создать очень простой левый/правый одинаковое панорамирование с помощью createPanner();

person cwilso    schedule 06.09.2013
comment
Ух ты. Спасибо за публикацию. Панорамирование было той частью спецификации веб-аудио, с которой мне было сложно разобраться. @oliverdrummond, ты действительно должен принять этот ответ вместо моего. Это намного, намного чище. - person Kevin Ennis; 07.09.2013
comment
Ницца! Я тоже попробую этот! Спасибо @cwilso! - person Oliver Drummond; 08.09.2013
comment
Только что попробовал! Это здорово! Просто изменил входные значения с -45 и 45 на -90 и 90, это создало большее стереоизображение. Большое спасибо! - person Oliver Drummond; 08.09.2013

На самом деле я обнаружил, что простое панорамирование влево/вправо довольно сложно с API веб-аудио. Он действительно настроен для объемного/пространственного звука, и я, честно говоря, не очень хорошо в этом разбираюсь.

Способ, которым я обычно делаю панорамирование, выглядит следующим образом:

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;
});

По сути, вы отправляете сигнал на два узла усиления, которые собираетесь использовать в качестве левого и правого каналов. Затем вы берете значение из своего элемента диапазона и используете его для установки усиления на каждом из узлов.

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

person Kevin Ennis    schedule 04.09.2013
comment
Спасибо за ответ @Kevin Ennis! Работает (с небольшими изменениями). Я опубликую окончательный код здесь! - person Oliver Drummond; 07.09.2013

Я совершенно уверен, что есть лучший и более простой способ сделать это, но на данный момент он определенно работает для меня.
Если у кого-то еще есть лучший/более чистый способ сделать это, пожалуйста, поделитесь им здесь!
Спасибо Кевину Эннису за подсказку!

Файл 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-файл

‹ input id="panControl" type="range" min="-1" max="1" step="0,001" value="0"/>

person Oliver Drummond    schedule 07.09.2013