G.711 Audio Compression for Telephony

Flash Player 11 includes support for the G.711 codec for audio. G.711 is actually a rather old – actually formally standardized in 1972 as “Pulse Code Modulation (PCM) of voice frequencies”. There are two compression algorithm variants of G.711, both of which can be used in Flash Player:

SoundCodec.PCMA

Specifies the G.711 A-law codec (used in Europe and the rest of the world).

SoundCodec.PCMU

Specifies the G.711 µ-law codec (used in North America and Japan).

Note

G.711 is primarily used in telephony and SIP (Session Initiation Protocol) based applications. It is tailored specifically for voice communications and supported on innumerable systems.

We can accomplish this through use of the flash.media.SoundCodec class within our audio project. Upon configuration of our Microphone object, we can assign the codec property to the SoundCodec.PCMU or SoundCodec.PCMA constant. This will ensure that any audio from that source is processed as G.711.

package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.SampleDataEvent;
    import flash.filters.BlurFilter;
    import flash.geom.Point;
    import flash.media.Microphone;
    import flash.media.SoundCodec;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.utils.ByteArray;

    [SWF(width="600", height="500", backgroundColor="#CCCCCC")]

    public class G711Telephony extends Sprite {

        private const SPECTRUM_COLOR:uint = 0x24ff00;

        private var traceField:TextField;
        private var microphone:Microphone;
        private var audioBlur:BlurFilter;
        private var audioBitmapData:BitmapData;
        private var audioBitmap:Bitmap;
        private var soundDisplay:Sprite;
        private var soundActivity:Sprite;

        public function G711Telephony() {
            generateTextFields();
            spectrumSetup();
            performOperations();
        }

        protected function generateTextFields():void {
            var defaultFormat:TextFormat = new TextFormat();
            defaultFormat.font = "Arial";
            defaultFormat.size = 24;
            defaultFormat.color = 0xFFFFFF;

            traceField = new TextField();
            traceField.width = stage.stageWidth;
            traceField.height = stage.stageHeight;
            traceField.backgroundColor = 0x000000;
            traceField.alpha = 0.7;
            traceField.multiline = true;
            traceField.wordWrap = true;
            traceField.background = true;
            traceField.defaultTextFormat = defaultFormat;
            addChild(traceField);
        }

        protected function spectrumSetup():void {
            audioBitmapData = new BitmapData(stage.stageWidth, stage.stageWidth, true, 0x000000);
            audioBitmap = new Bitmap(audioBitmapData);

            audioBlur = new BlurFilter(2, 12, 2);

            soundActivity = new Sprite();
            soundDisplay = new Sprite();
            soundActivity.addChild(soundDisplay);
            soundActivity.addChild(audioBitmap);
            addChild(soundActivity);
        }

        protected function performOperations():void {
            if(Microphone.isSupported){
                microphone = Microphone.getMicrophone(0);
                microphone.codec = SoundCodec.PCMU;
                microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, microphoneDataSample);
            }
        }

        protected function microphoneDataSample(e:SampleDataEvent):void {
            var soundBytes:ByteArray = new ByteArray();
            soundBytes = e.data;

            traceField.text = "Microphone: " + e.target.name + "\n\n";
            traceField.appendText("activityLevel: " + e.target.activityLevel + "\n");
            traceField.appendText("bytesAvailable: " + soundBytes.bytesAvailable + "\n");
            traceField.appendText("codec: " + e.target.codec);

            drawSpectrum(e.data);
        }

        protected function drawSpectrum(d:ByteArray):void {
            var ba:ByteArray = new ByteArray();
            ba = d;
            var a:Number = 0;
            var n:Number = 0;
            var i:uint = 0;
            soundDisplay.graphics.clear();
            soundDisplay.graphics.lineStyle(2, SPECTRUM_COLOR, 0.8, false);
            soundDisplay.graphics.moveTo(0, (n/2)+(stage.stageHeight/2+100));
            for(i=0; i<=ba.bytesAvailable; i++) {
                a = ba.readFloat();
                n = a*soundActivity.height;
                soundDisplay.graphics.lineTo(i*(stage.stageWidth/ba.bytesAvailable), (n/2)+(stage.stageHeight/2+100));
            }
            soundDisplay.graphics.endFill();
            audioBitmapData.draw(soundDisplay);
            audioBitmapData.applyFilter(audioBitmapData, audioBitmapData.rect, new Point(0,0), audioBlur);
        }
    }
}

The result of running this class can be seen in Figure 4-3.

G.711 µ-law (PCMU) encoded audio data

Figure 4-3. G.711 µ-law (PCMU) encoded audio data

Get What's New in Flash Player 11 now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.