- From: Harald Alvestrand <harald@alvestrand.no>
- Date: Wed, 11 Dec 2013 10:25:08 +0100
- To: "public-media-capture@w3.org" <public-media-capture@w3.org>
One of the irritating things in the stats and media discussion has been the question of "audio volume". There are many apps that need it, yet defining the term has proved surprisingly slippery - what is it we measure, what's the baseline, do we need psychometric shaping of the signal before measuring it, what time scale does it need to be integrated over, and so on and so forth. At the moment, there is a stat in the Chrome implementation called "audioVolume" that has no particular definition, and has proved troublesome in multiple ways (for instance, it's not available without linking the track to an active PeerConnection). The suggestion has been made to expose a property on a MediaStreamTrack instead - but that runs into all the previously mentioned issues. But there is another way: Use WebAudio. Get the samples. Let the application decide. I created a demo, which works both in Firefox and Chrome, here: https://webrtc.googlecode.com/svn/trunk/samples/js/demos/html/local-audio-volume.html The essential part of the code is reproduced below, it's not long. I believe that: - This shows that volume can be measured in an application, from a MediaStreamTrack, without any modification to any part of the Media Capture and Streams spec. - This shows that the application can control the definition of "volume" to be exactly what it wants it to be; again, without making any change to any part of the Media Capture And Streams spec. - This shows that the cost is a Javascript invocation every 50 ms, where the heaviest operation is a square root. People can test for themselves if this matters for the devices they are concerned about. Therefore, on the principle that we should not solve a problem twice, I propose that we declare the problem of "measuring the volume of an audio track" to be out of scope for the working group. Does this make sense for people? Harald // Meter class that generates a number correlated to audio volume. // The meter class itself displays nothing, but it makes the // instantaneous and time-decaying volumes available for inspection. // It also reports on the fraction of samples that were at or near // the top of the measurement range. function SoundMeter(context) { this.context = context this.volume = 0.0; this.slow_volume = 0.0; this.clip = 0.0; this.script = context.createScriptProcessor(2048, 1, 1); that = this; this.script.onaudioprocess = function(event) { var input = event.inputBuffer.getChannelData(0); var i; var sum = 0.0; var clipcount = 0; for (i = 0; i < input.length; ++i) { sum += input[i] * input[i]; if (Math.abs(input[i]) > 0.99) { clipcount += 1 } } that.volume = Math.sqrt(sum / input.length); that.slow_volume = 0.95 * that.slow_volume + 0.05 * that.volume; that.clip = clipcount / input.length; } } SoundMeter.prototype.connectToSource = function(stream) { console.log('SoundMeter connecting'); this.mic = this.context.createMediaStreamSource(stream); this.mic.connect(this.script); // Necessary to make sample run, but should not be. this.script.connect(this.context.destination); } SoundMeter.prototype.stop = function() { this.mic.disconnect(); this.script.disconnect(); } // End of SoundMeter class.
Received on Wednesday, 11 December 2013 09:25:44 UTC