Search code examples
javascriptnode.jswebsocketpcmaudiocontext

Half speed AudioContext from microphone when written to server


I am trying to write a microphone recording on client javascript, transfer it to server then convert it to silk. I have the audio playing back on server using the Speaker module using these settings

var speaker = new Speaker({
  channels: 1,   
  bitDepth: 16,         
  sampleRate: 44000,     
  signed: true
});

but when it gets converted to silk it sounds half speed. I believe its the conversion to silk using a C class that i didn't write that causes the slow down since it sounds fine as a pcm file. The C file has these settings

#define FRAME_LENGTH_MS 20
#define SAMPLE_RATE_KHZ 16
#define SILK_BITRATE    14000
#define FRAME_SAMPLES   (FRAME_LENGTH_MS * SAMPLE_RATE_KHZ)

I'm using BinaryJS to write the code to the server as a Int16array.

I would copy the code here but i almost copied it verbatim from this tutorial.

http://blog.groupbuddies.com/posts/39-tutorial-html-audio-capture-streaming-to-node-js-no-browser-extensions

Also would love to know what exactly im getting from audioContext in terms of bitrate, samplerate and how to downsample the samplerate if i have to for the silk codec.

EDIT:

I did (kinda) solve the half speed by modifying the on onaudioprocess where i converted the float32 to Int16 by removing half the samples.

l = buffer.length;
        point = Math.floor(l/2);
        buf = new Int16Array(Math.floor(l/2));
        for (var x = l; x > 0;) {
            var average = (buffer[x] + buffer[x-1]) / 2;
            buf[point] = Math.min(1, average)*0xFFFF;
            point -= 1;
            x -= 2;
        }

        return buf.buffer;

However, the audio pitch is still half.


Solution

  • I have a few other questions I've answered that would answer the rest of this problem, but for anyone wondering the AudioContext object does return the information on the sampling rate that I ended up using with a downsampling algorithm to dynamically adjust to any browsers sampling rate.

    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

            var session = {
                audio: true
            };
    
            navigator.getUserMedia(session, function(stream){
                audioContext = window.AudioContext;
                context = new audioContext();
                sampleRate = context.sampleRate;
                // Pass sample rate to downsample function with my arraybuffer
            },function(e){
               // error
            });