title: Get consistent audio quality with getUserMedia using different browsers
body: <h2>What I'm doing</h2>
  
  <p>I'm using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getUserMedia">getUserMedia API</a> to record audio in the browser and then send this audio to a websocket server. Furthermore, to test the recordings, I use <a href="https://rogueamoeba.com/freebies/soundflower/">soundflower</a> on a Mac as an input device, so I can play a wave file, instead of speaking into a microphone.</p>
  
  <p><strong>client side (JavaScript)</strong></p>
  
  <pre><code>window.AudioContext = window.AudioContext || window.webkitAudioContext;
  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
  
  var audioContext = new AudioContext();
  var wsClient = new WebSocket("ws://" + WEBSOCKET_URL + ":" + WEBSOCKET_PORT);
  
  navigator.getUserMedia({audio: true}, function (stream) {
      var input = audioContext.createMediaStreamSource(stream);
      var recordNode = audioContext.createScriptProcessor(4096);
      recordNode.onaudioprocess = recorderProcess;
      input.connect(recordNode);
      recordNode.connect(audioContext.destination);
  }, function (e) {
      console.error("No live audio input: " + e);
  });
  
  function recorderProcess(e) {
      var buffer = e.inputBuffer.getChannelData(0);
      wsClient.send(buffer);
  }
  </code></pre>
  
  <p><strong>server side (python)</strong></p>
  
  <p>On the server side, I simply write the chunks in a file:</p>
  
  <pre><code>def onMessage(self, msg, binary):
      if binary:
          with open("/tmp/test.raw", "ab") as f:
              f.write(msg)
  </code></pre>
  
  <h2>The Problem</h2>
  
  <p>The problem, I'm having, is that the audio seems to get pre-processed by the browser, so that the end result is of different quality than the original audio. The quality also depends on the browser.</p>
  
  <p>Here is an example:</p>
  
  <p><img src="https://i.stack.imgur.com/dka2T.png" alt="waveform"></p>
  
  <p>The picture show the three waveforms of the original audio, the result of recording in Chrome and the result of recording in FireFox. As you can see, the wave forms appear different. Especially in Chrome, where low amplitude often gets just converted to zero.</p>
  
  <p>An even bigger difference is visible when looking at the spectogram:</p>
  
  <p><img src="https://i.stack.imgur.com/IrgJi.png" alt="spectorgram"></p>
  
  <p>So both browsers seem to cut off higher frequencies, while FireFox is certainly more extreme.</p>
  
  <p>All of this would maybe not a big deal, since the audio files are all sounding very similar to my ears. But I'm processing and analyzing the audio on server side and the pre-processing by the browsers is giving me worse end results.</p>
  
  <h2>Question</h2>
  
  <p>So what is going on? Do these browsers have an extra step of pre-processing the audio? What kind of filters do they presumably apply? Can I avoid this somehow within the getUserMedia API? And are there any ways of having a solution, that results in a consistent good audio quality in Chrome and FireFox?</p>
  
  <p><strong><em>Disclaimer</em></strong></p>
  
  <p>I'm not an audio expert, so I can only analyze the results in a very amateur way, but I hope the graphics speak for themselves.</p>