Changeset 908


Ignore:
Timestamp:
03/29/10 20:43:53 (3 years ago)
Author:
jeroen
Message:

added ducking to audiodescription plugin.

Location:
plugins/audiodescription/v4
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • plugins/audiodescription/v4/audiodescription.xml

    r880 r908  
    1212        <flashvars> 
    1313                <flashvar> 
     14                        <name>debug</name> 
     15                        <default>false</default> 
     16                        <description>When set to 'true', the plugin renders the waveform and ducking percentage on screen.</description> 
     17                </flashvar> 
     18                <flashvar> 
     19                        <name>ducking</name> 
     20                        <default>60</default> 
     21                        <description>The volume percentage the original audio is ducked (0 to 100).</description> 
     22                </flashvar> 
     23                <flashvar> 
    1424                        <name>file</name> 
    1525                        <default></default> 
    1626                        <description>Location of the audiodescription MP3 to play.</description> 
     27                </flashvar> 
     28                <flashvar> 
     29                        <name>gain</name> 
     30                        <default>1</default> 
     31                        <description>Gain of the audiodescription compared to the original audio. Set a value of e.g. 2 if the audiodescription is very soft.</description> 
    1732                </flashvar> 
    1833                <flashvar> 
     
    2439                        <name>volume</name> 
    2540                        <default>90</default> 
    26                         <description>Volume of the audiodescription. Crank this even more up to have the AD overrule the default sound.</description> 
     41                        <description>Start volume of both the original audio and the audiodescription. Overrides the global volume flashvar.</description> 
    2742                </flashvar> 
    2843        </flashvars> 
  • plugins/audiodescription/v4/build.sh

    r880 r908  
    55 
    66echo "Compiling with MXMLC..." 
    7 $FLEXPATH/bin/mxmlc ./com/jeroenwijering/plugins/Audiodescription.as -sp ./ -o ./audiodescription.swf -use-network=false 
     7$FLEXPATH/bin/mxmlc ./com/jeroenwijering/plugins/Audiodescription.as -sp ./ -o ./audiodescription.swf -use-network=false -target-player="10.0.0" 
  • plugins/audiodescription/v4/com/jeroenwijering/plugins/Audiodescription.as

    r814 r908  
    1212import flash.media.*; 
    1313import flash.net.*; 
     14import flash.utils.ByteArray; 
    1415 
    1516 
     
    2526        /** Reference to the dock button. **/ 
    2627        private var button:MovieClip; 
     28        /** Sound channel object. **/ 
     29        private var channel:SoundChannel; 
     30        /** Current volume. **/ 
     31        private var current:Number = -1; 
    2732        /** List with configuration settings. **/ 
    2833        public var config:Object = { 
     34                ducking:80, 
     35                debug:false, 
    2936                file:undefined, 
     37                gain:1, 
    3038                state:true, 
    3139                volume:90 
    32         } 
     40        }; 
     41        /** Array with ducking samples, used for the ducking. **/ 
     42        private var ducks:Array; 
     43        /** Reference to the icon. **/ 
     44        private var icon:Bitmap; 
     45        /** Array with waveform samples, used for the ducking. **/ 
     46        private var waves:Array; 
     47        /** A bunch of clips drawn for the debug menu. **/ 
     48        private var clips:Object; 
     49        /** sound object to be instantiated. **/ 
     50        private var sound:Sound; 
    3351        /** Reference to the MVC view. **/ 
    3452        private var view:AbstractView; 
    35         /** Reference to the icon. **/ 
    36         private var icon:Bitmap; 
    37         /** sound object to be instantiated. **/ 
    38         private var sound:Sound; 
    39         /** Sound channel object. **/ 
    40         private var channel:SoundChannel; 
     53        /** Volume of the original audio. **/ 
     54        private var original:Number; 
    4155 
    4256 
     
    5872                } 
    5973                setState(config['state']); 
     74                if(config['debug']) { 
     75                        drawClips(); 
     76                } 
    6077        }; 
    6178 
     
    6784 
    6885 
     86        /** Extract a waveform of the sound when it's completed. **/ 
     87        private function completeHandler(evt:Event):void { 
     88                var arr:ByteArray; 
     89                var bts:Number = 4410; 
     90                var pos:Number; 
     91                // load a sound sample every .1 second. 
     92                while(bts == 4410) { 
     93                        arr = new ByteArray(); 
     94                        bts = sound.extract(arr,4410); 
     95                        arr.position = 0; 
     96                        if(arr.bytesAvailable > 7) { 
     97                                waves.push(arr.readFloat()); 
     98                        } 
     99                } 
     100                if(config['debug']) { drawWave() }; 
     101                // quantify the ducking and add some margin. 
     102                var i:Number = 0; 
     103                while(i<waves.length) { 
     104                        if(waves[i] == 0) { 
     105                                ducks.push(0); 
     106                                i++; 
     107                        } else { 
     108                                ducks[i-1] = ducks[i] = 1; 
     109                                ducks.push(1,1,1); 
     110                                i += 3; 
     111                        } 
     112                } 
     113                // Smooth out the ducking. 
     114                var tmp:Array = new Array(ducks[0],ducks[1]); 
     115                for(i=2; i < ducks.length-2; i++) { 
     116                        tmp.push((ducks[i-2] + ducks[i-1] + ducks[i] + ducks[i+1] + ducks[i+2])/5); 
     117                } 
     118                ducks.push(ducks[ducks.length-2],ducks[ducks.length-1]); 
     119                ducks = tmp; 
     120                if(config['debug']) { drawDucks() }; 
     121        }; 
     122 
     123 
     124        /** Draw the overall clips. **/ 
     125        private function drawClips():void { 
     126                var back:MovieClip = new MovieClip(); 
     127                back.graphics.beginFill(0x000000,0.8); 
     128                back.graphics.drawRect(0,0,view.config['width'],100); 
     129                addChild(back); 
     130                var wave:MovieClip = new MovieClip(); 
     131                wave.y = 50; 
     132                addChild(wave); 
     133                var duck:MovieClip = new MovieClip(); 
     134                addChild(duck); 
     135                var line:MovieClip = new MovieClip(); 
     136                line.graphics.beginFill(0xFF0000); 
     137                line.graphics.drawRect(0,0,1,100); 
     138                addChild(line); 
     139                clips = {back:back,wave:wave,duck:duck,line:line}; 
     140        }; 
     141 
     142 
     143        /** Draw the audiodescription waveform. **/ 
     144        private function drawDucks():void { 
     145                clips.duck.graphics.clear(); 
     146                clips.duck.graphics.moveTo(0,0); 
     147                clips.duck.graphics.lineStyle(1,0x0000FF); 
     148                for(var i:Number=0; i<ducks.length; i++) { 
     149                        clips.duck.graphics.lineTo(i,100 - config['volume'] + ducks[i]*config['ducking']); 
     150                } 
     151                clips.duck.width = view.config['width']; 
     152        }; 
     153 
     154 
     155        /** Draw the audiodescription waveform. **/ 
     156        private function drawWave():void { 
     157                clips.wave.graphics.clear(); 
     158                clips.wave.graphics.moveTo(0,0); 
     159                clips.wave.graphics.lineStyle(1,0x00FF00); 
     160                for(var i:Number=0; i<waves.length; i++) { 
     161                        clips.wave.graphics.lineTo(i,waves[i]*50); 
     162                } 
     163                clips.wave.width = view.config['width']; 
     164        }; 
     165 
     166 
    69167        /** Check for captions with a new item. **/ 
    70168        private function itemHandler(evt:ControllerEvent=null):void { 
    71169                var file:String; 
    72                 if (view.playlist[view.config['item']]['audiodescription.file']){ 
     170                if (view.playlist[view.config['item']]['audiodescription.file']) { 
    73171                        file = view.playlist[view.config['item']]['audiodescription.file']; 
    74                 } else if (view.playlist[view.config['item']]['audiodescription']){ 
     172                } else if (view.playlist[view.config['item']]['audiodescription']) { 
    75173                        file = view.playlist[view.config['item']]['audiodescription'];  
    76174                } else if(view.config['audiodescription.file']) { 
    77175                        file = view.config['audiodescription.file']; 
    78176                } else if(view.config['audio']) { 
    79                         // Legacy support 
     177                        // Legacy support (this is how 3.x did it). 
    80178                        file = view.config['audio']; 
    81179                } 
     
    83181                        config['file'] = file; 
    84182                } 
     183                ducks = new Array(); 
     184                waves = new Array(); 
    85185        }; 
    86186 
     
    93193                cke.flush(); 
    94194                setVolume(); 
    95                 if(stt) {  
    96                         if(button) {  
    97                                 button.field.text = 'is on';  
     195                if(stt) { 
     196                        if(button) { 
     197                                button.field.text = 'is on'; 
    98198                        } else { 
    99199                                icon.alpha = 1; 
    100200                        } 
    101201                } else { 
    102                         if(button) {  
    103                                 button.field.text = 'is off';  
     202                        if(button) { 
     203                                button.field.text = 'is off'; 
    104204                        } else { 
    105205                                icon.alpha = 0.3; 
     
    111211        /** Set the volume level. **/ 
    112212        private function setVolume():void { 
    113                 var trf:SoundTransform = new SoundTransform(config['volume']/100); 
     213                var trf:SoundTransform = new SoundTransform(config['volume']*config['gain']/100); 
    114214                if(!config['state']) { trf.volume = 0; } 
    115215                if(channel) { channel.soundTransform = trf; } 
     
    131231                                        try { 
    132232                                                sound = new Sound(new URLRequest(config['file'])); 
     233                                                sound.addEventListener(Event.COMPLETE,completeHandler); 
    133234                                                channel = sound.play(); 
    134235                                                setVolume(); 
     
    150251                        setVolume(); 
    151252                } 
     253                if(ducks.length > 0 && ducks[Math.round(pos*10)] != current) { 
     254                        current = ducks[Math.round(pos*10)]; 
     255                        view.sendEvent(ViewEvent.VOLUME,config['volume']-ducks[Math.round(pos*10)]*config['ducking']); 
     256                } 
     257                if(config['debug']) {  
     258                        clips.line.x = Math.round(evt.data.position/evt.data.duration*view.config['width']); 
     259                } 
    152260        }; 
    153261 
Note: See TracChangeset for help on using the changeset viewer.