title: Correct audio volume output decibels using HTML5 / javascript, turn off pre-processing
body: <p>We have observed that using javascript-based audio from a browser, the output level is not correctly linearly proportional to the input signal level on many systems.  For example, if you 'play' two sin waves with amplitude varying by 20dB, the resultant difference from different devices/settings may be markedly different from 20dB, e.g. as far off as 10dB or less.
  We need to put out simple audio signals (e.g. sin waves) at calibrated decibel levels relative to each other, for example put out one sin wave at one volume, then put out another sin wave that is 20dB quieter than the first one, and have them actually come out that way.
  We would like to do this from a browser using HTML5/javascript.<br>
  We have tried to do this in several ways, e.g. using pre-created, calibrated .mp3 files, using the Web Audio API directly to generate an oscillator with calibrated dB levels.  We have gotten (to us) very surprising and basically incorrect results.
  When we have measured the resulting sounds coming out of the device using a calibrated microphone, all kinds of weird things have been observed, indicating that audio is not just 'played' in a linear way, but complex pre-processing is being done on it before it actually gets output.  This seems to depend on all kinds of variables currently outside of our control.  It does not work the way that a 'normal' audio amplifier works, ie that a 20dB louder input produces a 20dB louder output, whatever the absolute level is set to.
  We have found that using the same javascript code produces very different results depending on all kinds of variables including the hardware (e.g. browsing on Mac vs. iPhone), the volume settings chosen (even the <em>relative</em> values not different by 20dB for 20dB difference in input when volume is at 1/2), if headphones are used, etc.</p>
  
  <p>In further testing, it appears that the primary problem is related to the use of external speakers.  When using headphones, the results look <em>much</em> better.</p>
  
  <p>The basic problem is that if you create two different signals with known differences in volume, eg 20dB, and put them both out in any of several ways, the measured difference will often not be 20dB, and is in some cases as bad as 10dB.</p>
  
  <p>Is there some way to programmatically do this?</p>
  
  <p>Is there a way to override whatever pre-processing or audio volume compression seems to be adjusting the volume (causing output that is not correctly proportional to input)?</p>
  
  <p>We need a way to do this that will work across platforms (desktop, iOS, Android, different browsers, different headphones/speakers), hence the use of HTML5.</p>
  
  <p>If it isn't possible to do this using HTML5, how can we do it using native iOS/Android code?  This appears to be more of a hardware than a software problem, but perhaps there are ways to override it.</p>
  
  <p>Thanks</p>