2013-01-17 5 views
6

Sto osservando le specifiche API audio web e il nodo panning utilizza tre valori per creare uno spettro 3D per il suono. Mi chiedevo se per poter creare un panner 2D di "potenza uguale" di base il programmatore ha bisogno di fare la programmazione formulaica per ridimensionare questo ... o se ci sto pensando troppo e c'è un modo più semplice per farlo.Come creare un panning di potenza di sinistra/destra molto semplice con createPanner();

EDIT

There is now a stereoPanner node being introduced.

+0

Sì, il nuovo metodo 'createStereoPanner' funziona magnificamente. Impostare il panning dell'altoparlante sinistro e destro usando la proprietà 'pan.value' del nodo pan. Usa qualsiasi valore compreso tra -1 (spostato completamente all'altoparlante sinistro) e 1 (spostato completamente all'altoparlante destro.) – d13

risposta

7

posso ancora ottenere un effetto panning cambiando solamente il primo argomento di setPosition() e mantenendo altri argomenti nullo.

<!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> 

Ma per ottenere un effetto di panning naturale, è necessario specificare anche il terzo argomento.

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

Quindi, in breve, stai dicendo "sì" devi aggiungere la programmazione formulaica che ho menzionato. Se è così, proverò il tuo codice e voterò tra qualche giorno se nessun altro risponde. Grazie per aver fatto tutto questo lavoro. Non me l'aspettavo. – William

+0

Se si chiama il codice sopra riportato, la risposta è "sì". Non conosco nessun altro modo più semplice, mi spiace ... – kuu

8

Ecco un modo ancora più semplice (meno stereotipata?) Per ottenere 2D panning:

(full code here)

<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> 
+0

Basta notare che il panningModel dovrebbe essere impostato su "equalpower": 'panner.panningModel =" equalpower ";' – d13

+0

alcuni trigsi sono tecnicamente necessari, ma questo farà il trucco. Il mio codice crea un triangolo attorno all'ascoltatore mentre eseguono la panoramica. Un semicerchio è ciò che dovrebbe essere creato, in modo che la sorgente sia sempre a "1" di distanza (1 unità di distanza). Nel mondo reale, però, la differenza sarebbe molto difficile da sentire –

1

panner default nodo "HRTF" (Head Related Transfer Function), che è un motore a convoluzione stereo ed è progettato per il suono 3D.

Per avere una funzionalità di panning di base e un minore utilizzo delle risorse è necessario impostare l'attributo panningModel su "equalpower".

var panner = context.createPanner(); 
panner.panningModel = "equalpower"; 
panner.setPosition(1,0,0); 

Controllare il documentation per ulteriori dettagli.

+0

Questo creerà solo un solido pan sinistra/destra, a meno che il valore z sia impostato proporzionalmente in base alla soluzione di sean9999: 'panner.setPosition (x, 0, 1- Math.abs (x));' – d13

Problemi correlati