AS3 Simulating cue points for Sound

update:
pause() method is added, example .fla file is updated.

As far as I know there is no way for adding cue points in flash Sound, but using SoundChannel.position property we can check playhead current position and simulate cue points for Sound.
So I wrote simple utility Class for simulating cue points for Sound Class In AS3.

Example:

Get Adobe Flash player

AudioCuePoint.as

Actionscript:
  1. package com.abrahamyan.util
  2. {
  3.    
  4.     /**
  5.      * ...
  6.      * @author Armen Abrahamyan
  7.      */
  8.    
  9.     import flash.events.Event;
  10.     import flash.media.Sound;
  11.     import flash.media.SoundChannel;
  12.     import flash.utils.Timer;
  13.     import flash.events.TimerEvent;
  14.     import flash.events.EventDispatcher;
  15.     public class AudioCuePoint extends EventDispatcher
  16.     {
  17.         public static const ON_CUEPOINT:String = "on_cuepoint";
  18.         private var _soundChannel:SoundChannel;
  19.         private var _audioTimer:Timer;
  20.         private var _timerInterval:Number = .1;
  21.         private var _usedCuePoints:Array;
  22.         private var _cuepoints:XMLList;
  23.         private var _cuepointTime:Number;
  24.         private var _cuepointText:String;
  25.         private var _accuracy:Number = .1;
  26.         private var _paused:Boolean = false;
  27.         public var destroyAfterComplete:Boolean = false;
  28.         /**
  29.          *
  30.          * @param   pSoundChannel
  31.          * @param   pCuepoints
  32.          */
  33.         public function AudioCuePoint(pSoundChannel:SoundChannel=null,pCuepoints:XMLList =null):void
  34.         {
  35.             _soundChannel = pSoundChannel;
  36.             _cuepoints = pCuepoints;
  37.             _usedCuePoints = [];
  38.             _usedCuePoints.length = _cuepoints.length();
  39.         }
  40.        
  41.         public function set soundChannel(pSoundChannel:SoundChannel):void
  42.         {
  43.             _soundChannel = pSoundChannel;
  44.         }
  45.         public function get soundChannel():SoundChannel
  46.         {
  47.             return _soundChannel;
  48.         }
  49.         public function set cuepoints(pCuepoints:XMLList):void
  50.         {
  51.             _cuepoints = pCuepoints;
  52.             _usedCuePoints.length = _cuepoints.length();
  53.         }
  54.         public function get cuepoints():XMLList
  55.         {
  56.             return _cuepoints;
  57.         }
  58.         public function get cuepointTime():Number
  59.         {
  60.             return _cuepointTime;
  61.         }
  62.         public function get cuepointText():String
  63.         {
  64.             return _cuepointText;
  65.         }
  66.         /**
  67.          * starts process of finding cuepoints
  68.          */
  69.         public function start():void
  70.         {
  71.             if (!_soundChannel || !_cuepoints)
  72.             {
  73.                 return;
  74.                
  75.             }
  76.             if (_paused)
  77.             {
  78.                 _paused = false;
  79.                 _audioTimer.start();
  80.                 return;
  81.             }
  82.            
  83.             _audioTimer = new Timer(_timerInterval * 1000);
  84.             _audioTimer.addEventListener(TimerEvent.TIMER, onAudioTimerHandler);
  85.             _audioTimer.start();
  86.            
  87.             if (destroyAfterComplete)
  88.             {
  89.                 _soundChannel.addEventListener(Event.SOUND_COMPLETE,onSoundComplete,false,0,true)
  90.             }
  91.            
  92.            
  93.            
  94.         }
  95.         /**
  96.          * pause
  97.          */
  98.         public function pause():void
  99.         {
  100.             if (_paused)
  101.             {
  102.                 return;
  103.             }
  104.             _paused = true;
  105.             _audioTimer.stop();
  106.         }
  107.         public function get paused():Boolean
  108.         {
  109.             return _paused;
  110.         }
  111.         /**
  112.          * when sound complete
  113.          * @param   e
  114.          */
  115.         private function onSoundComplete(e:Event):void
  116.         {
  117.             _soundChannel.removeEventListener(Event.SOUND_COMPLETE, onSoundComplete);
  118.             destroy();
  119.         }
  120.         /**
  121.          *
  122.          * @param   e
  123.          */
  124.         private function onAudioTimerHandler(e:TimerEvent):void
  125.         {
  126.             trace("tick");
  127.             var position:Number = Math.round(_soundChannel.position / 100)/10;
  128.             checkForCuePoints(position);
  129.         }
  130.         /**
  131.          * checks time with cuepoints list
  132.          * @param   pTime
  133.          */
  134.         private function checkForCuePoints(pTime:Number):void
  135.         {
  136.             var cnt:Number = cuepoints.length();
  137.             for (var i:uint = 1; i <= cnt; i++)
  138.             {
  139.                 if (pTime>= (Number(cuepoints[i - 1].@time) - _accuracy) && pTime <= (Number(cuepoints[i - 1].@time) + _accuracy) && (!_usedCuePoints[i - 1] ))
  140.                 {
  141.                     _usedCuePoints[i - 1] = true;
  142.                     _cuepointTime = pTime;
  143.                     _cuepointText = cuepoints[i - 1];
  144.                     dispatchEvent(new Event(ON_CUEPOINT));
  145.                     break;
  146.                 }
  147.            
  148.            
  149.             }
  150.         }
  151.         /**
  152.          * removes listeners/loops/onenterframes...
  153.          */
  154.         public function destroy():void
  155.         {
  156.             if (_audioTimer)
  157.             {
  158.                 _audioTimer.stop();
  159.                 _audioTimer.removeEventListener(TimerEvent.TIMER, onAudioTimerHandler);
  160.             }
  161.             if (destroyAfterComplete)
  162.             {
  163.                 _soundChannel.removeEventListener(Event.SOUND_COMPLETE, onSoundComplete);
  164.             }
  165.         }
  166.        
  167.        
  168.     }
  169.    
  170. }

Download source files

Releated Posts


7 Responses to “AS3 Simulating cue points for Sound”


  1. 1 lunacafu

    nice Tutorial! Thanks

    I would like to use this class to control the fade in/out of movieclips on stage. How would you extend/change the XML and the onCuepointFind function to fire something like

    fadeOut = new Tween(mc, “alpha”,None.easeNone,1,0,2,true);

    Any hint appreciated.

  2. 2 lunacafu

    I solved it like this;

    XML:
    var cuepoints:XML =
    cue point 1
    cue point 2
    cue point 2

    added 2 new properties _targetObj and _tween to the Class and added the values to be dispatched with the checkForCuePoints() function.

    in the FLA I changed:

    function onCuepointFind(e:Event):void
    {
    var _time = AudioCuePoint(e.target).cuepointTime;
    var _text = AudioCuePoint(e.target).cuepointText;
    var _targetClip = AudioCuePoint(e.target).cuepointTarget;
    var _tween = AudioCuePoint(e.target).cuepointTween;
    output_txt.appendText(”cuepoint find time: ” +_time+ ” / text: “+_text+”/”+_targetClip+”–”+_tween+”\n”);
    output_txt.scrollV = output_txt.maxScrollV
    this[_tween](this[_targetClip]); //this was hardest!!
    }

    and added the methods fadedIn and fadeOut

    function fadeOut(mc:MovieClip):void
    {
    TweenLite.to(mc, 1, {alpha:0});
    }

    function fadeIn(mc:MovieClip):void
    {
    TweenLite.to(mc, 1, {alpha:1});
    }

    Works great, thanks!

  3. 3 admin

    @lunacafu.
    Well, if u are tweening something that out of Class you don’t have to add properties inside class.

    you catch the event onCuepointFind, u got the time and text, your object/movieclip that u wanna tween is out of class, just have some fucntion to show it(outside of class), and call that method inside onCuepointFind.
    Its almost the same thing you did, but not inside Class file itself.

  4. 4 shawn c

    @lunacafu.
    do you have an example of what you did online
    I would love to see it in action
    thanks both of you for the info.
    I am sure this will come in handy.

  5. 5 Tim

    Not sure yet, but this may be EXACTLY what I need!!! Thanks in advance!

  6. 6 Lasse

    This is indeed a very helpful class!

    Is it possible to add pause functionality? Meaning that when I pause my sound and then resume it, the cue point timer will also pick up where it left.

    Thanks, this is a keeper.

  7. 7 admin

    @Lasse thx for pointing.
    puase() method is added, for the resume use the same start().
    When resume, make sure to set the soundChannel property again:

    audioCuePoint.start();
    sndChannel= snd.play(sndChannel.position);
    audioCuePoint.soundChannel = sndChannel;

    source files are updated.

Leave a Reply