Как создать очень простой левый / правый панорамирование одинаковой мощности с createPanner();
Я смотрю на спецификацию веб-аудио API, и узел панорамирования использует три значения для создания трехмерного спектра для звука. Мне было интересно, если для создания базового 2D панорамы "равной мощности" программисту необходимо выполнить формульное программирование, чтобы масштабировать это... или я слишком много думаю об этом, и есть более простой способ сделать это.
РЕДАКТИРОВАТЬ
3 ответа
Я все еще могу получить эффект панорамирования, изменив только первый аргумент на setPosition() и оставив другие аргументы равными нулю.
<!DOCTYPE html>
<html>
<head>
<script>
var c = new webkitAudioContext();
var s = c.createBufferSource();
var g = c.createGainNode();
var p = c.createPanner();
s.connect(g);
g.connect(p);
p.connect(c.destination);
function play(e) {
var fr = new FileReader();
var file = document.getElementById("file").files[0];
fr.onload = function(e) {
c.decodeAudioData(e.target.result,
function (buf) {
s.buffer = buf;
g.gain.value = 0.5;
s.noteOn(0)
},
function () {
console.error('decodeAudioData failed.');
}
);
};
fr.readAsArrayBuffer(file);
}
function pan(range) {
var x = Math.sin(range.value * (Math.PI / 180));
p.setPosition(x, 0, 0);
}
</script>
</head>
<body>
Choose your MP3 file:<br>
<input type="file" id="file" name="file" /><br>
<input type="submit" id="go" onclick="play()" value="Play" /><br>
L<input type="range" min="-45" max="45" value="0" onchange="pan(this);">R
</body>
</html>
Но чтобы получить естественный эффект панорамирования, вам нужно указать и третий аргумент.
function pan(range) {
var xDeg = parseInt(range.value);
var zDeg = xDeg + 90;
if (zDeg > 90) {
zDeg = 180 - zDeg;
}
var x = Math.sin(xDeg * (Math.PI / 180));
var z = Math.sin(zDeg * (Math.PI / 180));
p.setPosition(x, 0, z);
}
Вот еще более простой (менее формальный?) способ добиться 2D панорамирования:
<input type="range" name="pan" id="pan" min="-1" max="1" step="any" />
<script>
var panner = context.createPanner();
panner.panningModel = 'equalpower';
function pan(event) {
var x = this.valueAsNumber,
y = 0,
z = 1 - Math.abs(x);
panner.setPosition(x,y,z);
}
document.getElementById('pan').addEventListener(pan);
</script>
Узел панорамирования по умолчанию имеет значение "HRTF" (Передаточная функция, связанная с головкой), которая является механизмом стерео свертки и предназначена для трехмерного звука.
Чтобы иметь базовую функциональность панорамирования и более низкое использование ресурсов, вам нужно установить атрибут panningModel равным "equalpower".
var panner = context.createPanner();
panner.panningModel = "equalpower";
panner.setPosition(1,0,0);
Проверьте документацию для более подробной информации.