Change sample rate of AudioContext (getUserMedia)
Asked Answered
L

7

34

Im trying to record a 48000Hz recording via getUserMedia. But without luck. The returned audio MediaStream returns 44100Hz. How can i set this to 48000Hz?

Here are snippets of my code:

var startUsermedia = this.startUsermedia;

            navigator.getUserMedia({ 
                audio: true, 
                //sampleRate: 48000 
            }, startUsermedia, function (e) {
                console.log('No live audio input: ' + e);
            });

The startUsermedia function:

startUsermedia: function (stream) {
            var input = audio_context.createMediaStreamSource(stream);
            console.log('Media stream created.');
            // Uncomment if you want the audio to feedback directly
            //input.connect(audio_context.destination);
            //__log('Input connected to audio context destination.');

            recorder = new Recorder(input);
            console.log('Recorder initialised.');
        },

I tried changing the property sampleRate of the AudioContext, but no luck.

How can i change the sampleRate to 48000Hz?

EDIT : We are also now okay with a flash solution that can record and export wav files at 48000Hz

Layer answered 4/5, 2015 at 13:35 Comment(0)
S
19

As far as I know, there is no way to change the sample rate within an audio context. The sample rate will usually be the sample rate of your recording device and will stay that way. So you will not be able to write something like this:

var input = audio_context.createMediaStreamSource(stream);
var resampler = new Resampler(44100, 48000);
input.connect(resampler);
resampler.connect(audio_context.destination);

However, if you want to take your audio stream, resample it and then send it to the backend (or do sth. else with it outside of the Web Audio API), you can use an external sample rate converter (e.g. https://github.com/taisel/XAudioJS/blob/master/resampler.js).

   var resampler = new Resampler(44100, 48000, 1, 2229);

   function startUsermedia(stream) {
        var input = audio_context.createMediaStreamSource(stream);
        console.log('Media stream created.');


        recorder = audio_context.createScriptProcessor(2048);
        recorder.onaudioprocess = recorderProcess;
        recorder.connect(audio_context.destination);
    }

    function recorderProcess(e) {
        var buffer = e.inputBuffer.getChannelData(0);
        var resampled = resampler.resampler(buffer);
        //--> do sth with the resampled data for instance send to server
    }
Shizue answered 4/5, 2015 at 14:1 Comment(6)
Thank you but sadly a resampled version of the recording wouldn't work. But this is a good answer for other people looking for a way to convert sampleRatesLayer
Ok, then just out of curiosity: what do you want to do with your audio stream? Do you want to save it somehow or what is your goal?Shizue
Sadly i can't tell you the purpose of it because of company policy. But a correct sampleRate is a must.Layer
Ok, I understand. Well if you have control over the environment (browser, OS), where your application is used, then maybe you can change the default sample rate of your audio device directly there.Shizue
The audio context adopts the sample rate of the output device rather than the input device. source.Mission
@Shizue good point. I have a similar need. In my case I send an audio recording to a server (the application is a voice-bot). In my tests I'm experiencing input audio device "supply" 32 bit / 48KHz, and I would like to reduce to 8/16 8/16Khz (enough for a voice message) to reduce useless networking bandwidth in client/server audio data exchanges (via socketio). The WEIRD behaiviour I experiencing is that getUserMedia seems not accepting any audio bit/rate constraints: #62392852Debidebilitate
S
5

It looks like there is an open bug about the inability to set the sampling rate:

https://github.com/WebAudio/web-audio-api/issues/300

There's also a Chrome issue:

https://bugs.chromium.org/p/chromium/issues/detail?id=432248

I checked the latest Chromium code and there is nothing in there that lets you set the sampling rate.

Edit: Seems like it has been implemented in Chrome, but is broken currently - see the comments in the Chromium issue.

Stewart answered 13/4, 2016 at 8:17 Comment(0)
A
4

NOTE: This answer is outdated.


You can't. The sample rate of the AudioContext is set by the browser/device and there is nothing you can do to change it. In fact, you will find that 44.1kHz on your machine might be 48kHz on mine. It varies to whatever the OS picks by default.

Also remember that not all hardware is capable of all sample rates.

Adjunct answered 4/5, 2015 at 13:58 Comment(2)
I see, thank you. Is there maybe a flash solution that does support 48kHz? (It doesn't matter if some hardware don't support it)Layer
@Layer Maybe. You should post a different question for that, since a Flash answer is completely different than the Web Audio API.Adjunct
B
4

it's been added to chrome:

var ctx = new (window.AudioContext || window.webkitAudioContext)({ sampleRate:16000});

https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/AudioContext

Bhutan answered 8/6, 2019 at 6:48 Comment(1)
It was. But it does not work on Firefox (in summer 2021)Holism
R
4
audioContext = new AudioContext({sampleRate: 48000})

Simply Set sample rate when created AudioContext object, This worked for me

Raleigh answered 17/12, 2019 at 10:43 Comment(2)
Work only if the sampleRate is already the one in parameter.Spanish
This worked for me; however, if you are using recorderjs, then you need to modify the encodeWAV function. Its header for byte_rate was hard coded. I changed it to (sampleRate * numChannels * 2).Pinard
E
2

You can use an OfflineAudioContext to essentially render your audio buffer to a different sample rate (but this is batch operation).

So you would record your recording using the normal audio context, and then use an OfflineAudioContext with a different sample rate to render your buffer. There is an example on the Mozilla page.

Energid answered 19/7, 2016 at 14:26 Comment(0)
D
0

It is now in the spec but not yet implemented in Chromium. Also in bugs.chromium.org, "Status: Available" does not mean it is implemented. It just means that nobody is working on it and that it is available for anyone who wants to work on it. So "Available" means "Not assigned".

Danczyk answered 13/7, 2017 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.