Add equal-power-panning details
authorcrogers
Fri, 15 Jun 2012 17:35:27 -0700
changeset 86 ef06854badfb
parent 85 f415796410bf
child 87 2bc1c74be387
Add equal-power-panning details
webaudio/specification.html
--- a/webaudio/specification.html	Thu Jun 14 17:31:16 2012 -0700
+++ b/webaudio/specification.html	Fri Jun 15 17:35:27 2012 -0700
@@ -3655,14 +3655,99 @@
 
 <h3 id="Spatialization-panning-algorithm">Panning Algorithm</h3>
 
-<p>The following algorithms can be implemented: </p>
+<p>
+<em>mono->stereo</em> and <em>stereo->stereo</em>  panning must be supported.
+<em>mono->stereo</em> processing is used when all connections to the input are mono.
+Otherwise <em>stereo->stereo</em> processing is used.</p>
+<p>
+
+<p>The following algorithms must be implemented: </p>
 <ul>
   <li>Equal-power (Vector-based) panning 
     <p>This is a simple and relatively inexpensive algorithm which provides
-    basic, but reasonable results. </p>
-  </li>
-  <li>Sound-field (<a href="http://www.ambisonic.net/">Ambisonics</a>) 
-    <p>Attempts to recreate the acoustic field.</p>
+    basic, but reasonable results.  It is commonly used when panning musical sources.
+    </p>
+    The <em>elevation</em> value is ignored in this panning algorithm.
+
+    <p>
+    The following steps are used for processing:
+    </p>
+    
+    <ol>
+
+    <li>
+    </p>
+    The <em>azimuth</em> value is first contained to be within the range -90 <= <em>azimuth</em> <= +90 according to:
+    </p>
+    <pre>
+    // Clamp azimuth to allowed range of -180 -> +180.
+    azimuth = max(-180.0, azimuth);
+    azimuth = min(180.0, azimuth);
+
+    // Now wrap to range -90 -> +90.
+    if (azimuth < -90)
+        azimuth = -180 - azimuth;
+    else if (azimuth > 90)
+        azimuth = 180 - azimuth;
+    </pre>
+    </li>
+    
+    <li>
+    <p>
+    A 0 -> 1 normalized value <em>x</em> is calculated from <em>azimuth</em> for <em>mono->stereo</em> as:
+    </p>
+    <pre>
+    x = (azimuth + 90) / 180    
+    </pre>
+
+    <p>
+    Or for <em>stereo->stereo</em> as:
+    </p>
+    <pre>
+    if (azimuth <= 0) { // from -90 -> 0
+        // inputL -> outputL and "equal-power pan" inputR as in mono case
+        // by transforming the "azimuth" value from -90 -> 0 degrees into the range -90 -> +90.
+        x = (azimuth + 90) / 90;
+    } else { // from 0 -> +90
+        // inputR -> outputR and "equal-power pan" inputL as in mono case
+        // by transforming the "azimuth" value from 0 -> +90 degrees into the range -90 -> +90.
+        x = azimuth / 90;
+    }
+    </pre>
+    </li>
+    
+    <li>
+    <p>
+    Left and right gain values are then calculated:
+    </p>
+    <pre>
+    gainL = cos(0.5 * PI * x);
+    gainR = sin(0.5 * PI * x);    
+    </pre>
+    </li>
+    
+    <li>
+    <p>For <em>mono->stereo</em>, the output is calculated as:</p>
+    <pre>
+    outputL = input * gainL
+    outputR = input * gainR
+    </pre>
+    <p>Else for <em>stereo->stereo</em>, the output is calculated as:</p>
+    <pre>
+    if (azimuth <= 0) { // from -90 -> 0
+        outputL = inputL + inputR * gainL;
+        outputR = inputR * gainR;
+    } else { // from 0 -> +90
+        outputL = inputL * gainL;
+        outputR = inputR + inputL * gainR;
+    }
+    </pre>
+    </li>
+    
+    </ol>
+    
+    
+    
   </li>
   <li><a
     href="http://en.wikipedia.org/wiki/Head-related_transfer_function">HRTF</a>