18 Replies Latest reply on Mar 1, 2007 10:03 AM by vectorg6

    Control Volume of All Sounds

    ser_g
      Hello Guys,
      How can I do that simple task?

      --
      se
        • 1. Re: Control Volume of All Sounds
          dishmael Level 1
          How about a global integer for all SoundChannels using the SoundTransform object:

          http://livedocs.macromedia.com/flex/2/langref/flash/media/SoundTransform.html#includeExamp lesSummary
          • 2. Re: Control Volume of All Sounds
            ser_g Level 1
            Yes, but how to bind that global integer to ALL SoundChannels with single piece of code?
            I have effects, classes, media displays…

            ?
            • 3. Re: Control Volume of All Sounds
              dishmael Level 1
              How about a singleton class? Going from memory here so mileage may vary:

              class VolumeControl {

              private function VolumeControl() {}

              private var _instance:VolumeControl;
              private var _volume:Number = 0;

              public function getInstance():VolumeControl {

              if ( _instance == undefined ) {

              _instance = new VolumeControl();

              }

              return _instance;

              }

              public function setVolume(number:Number):void {

              _volume = number;

              }

              public function getVolume():Number {

              return _volume;

              }

              }

              Then you can set the volume for all your SoundChannels via the SoundTransform object:

              VolumeControl vc = VolumeControl.getInstance();

              var transform:SoundTransform = channel.soundTransform;
              transform.volume = vc.getVolume();

              To update the sound for all your channels, call vc.setVolume(<number>);

              Disclaimer: I have not tested any of this code, I'm at work and don't have access to my system to actually test this.

              Note: Here's some docs on the singleton pattern for AS:

              http://www.playfool.com/patterns/singleton/Singleton.pdf
              • 4. Re: Control Volume of All Sounds
                ser_g Level 1
                Darren, Thank you!
                I'll try this.
                • 5. Re: Control Volume of All Sounds
                  dishmael Level 1
                  lol, its David and your welcome. If it works, let us know, it might be useful to others.
                  • 6. Re: Control Volume of All Sounds
                    ser_g Level 1
                    Oh sorry I thought that was your PDF and your name in it :-)

                    By the way can it be somehow done thruogh the prototype property?
                    something like mx.core.SoundAsset.prototype.SoundTransform.volume = bindableVar;

                    in a manner of AS2
                    ?
                    • 7. Re: Control Volume of All Sounds
                      dishmael Level 1
                      Hrm, not sure ... you might have to play around with it to see. I imagine you'll definitely want the variable in the class to be bindable so that changes to the volume are detected (again, you may have to play around with it to get it working). Wish I could be more help, I've never tried controlling all sounds through a single volume control. I'd really be interested in knowing how you finally get it working (I'm sure it will come up again) so please let us know the final solution.
                      • 8. Control Volume of All Sounds
                        ser_g Level 1
                        Here is th Class that works:

                        package components.sounds
                        {
                        public class VolumeControl {
                        public function VolumeControl() {}
                        static private var _instance:VolumeControl;
                        static private var _volume:Number = 1;

                        public function getInstance():VolumeControl {
                        if ( _instance == null) {
                        _instance = new VolumeControl();
                        }
                        return _instance;
                        }

                        public function setVolume(number:Number):void {
                        _volume = number;
                        }

                        public function getVolume():Number {
                        return _volume;
                        }
                        }
                        }

                        (the vars shold be static)


                        ======

                        MXML

                        ======
                        <mx:VSlider minimum="0" maximum="100" change="myVC.setVolume(event.value/100); Alert.show(' ' + myVC.getVolume());" />
                        ======

                        But it requres calling getVolume() in every instance.
                        :-(


                        Now plaing with a proto... with not much hope :-(
                        • 9. Re: Control Volume of All Sounds
                          ser_g Level 1
                          flash.media.SoundTransform.prototype.volume = 0;
                          Doesn't throw an error but has no effect eather.

                          The HOW is now how to to make flash.media.SoundTransform volume property static for the class?
                          • 10. Re: Control Volume of All Sounds
                            dishmael Level 1
                            I had a few minutes today to play around with this and here's what I've found.

                            1. I set both the internal property (_volume) and the actual object for VolumeControl as bindable but the SoundTransform object did not recognize changes to the volume so that approach didn't quite work out

                            2. I changed the VolumeControl so that it had an event (volumeChanged) which was dispatched whenever the volume was changed, I then created an event handler in each class so that the volume could be set

                            This second approach yielded what I think you wanted:

                            - The VolumeControl is a singleton so it can be instantiated across all of my classes, where each class has access to the same volume value

                            - The SoundTransform must be called by the event handler of the VolumeControl, so each class that has a sound needs to implement a handler for the event so that the volume can be set

                            This may not be exactly what you're looking for; perhaps someone else might have a better solution. Here's the VolumeControl class:

                            import flash.events.Event;
                            import flash.display.Sprite;

                            public class VolumeControl extends Sprite {

                            [Event(name="volumeChanged", type="flash.events.Event")]

                            private var _instance:VolumeControl;
                            private var _volume:Number = 50;

                            public function VolumeControl() {}

                            public function getInstance():VolumeControl {
                            if ( _instance == null ) {
                            _instance = new VolumeControl();
                            }

                            return _instance;
                            }

                            public function setVolume(number:Number):void {
                            _volume = number;

                            // Dispatch volumeChange event
                            dispatchEvent( new Event("volumeChanged") );
                            }

                            public function getVolume():Number {
                            return _volume;
                            }
                            And here's the MXML application:

                            <mx:Script>
                            <![CDATA[
                            import com.windwardcg.testing.VolumeControl;

                            [Bindable]private var vc:VolumeControl;
                            private var file:String = "Test.mp3";
                            private var song:SoundChannel;

                            private function init():void {
                            vc = new VolumeControl().getInstance();
                            vc.addEventListener( "volumeChanged", volumeChangeHandler );

                            SoundExample();
                            }

                            public function SoundExample():void {
                            var request:URLRequest = new URLRequest(file);
                            var soundFactory:Sound = new Sound();
                            soundFactory.addEventListener(Event.COMPLETE, completeHandler);
                            soundFactory.addEventListener(Event.ID3, id3Handler);
                            soundFactory.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
                            soundFactory.addEventListener(ProgressEvent.PROGRESS, progressHandler);
                            soundFactory.load(request);
                            song = soundFactory.play();

                            // Set the initial volume
                            var transform:SoundTransform = song.soundTransform;
                            transform.volume = vc.getVolume();
                            song.soundTransform = transform;
                            }

                            private function volumeChangeHandler(event:Event):void {

                            vSetting.text = vSlider.value.toString();

                            var transform:SoundTransform = song.soundTransform;
                            transform.volume = vc.getVolume();
                            song.soundTransform = transform;
                            }

                            private function completeHandler(event:Event):void {
                            trace("completeHandler: " + event);
                            }

                            private function id3Handler(event:Event):void {
                            trace("id3Handler: " + event);
                            }

                            private function ioErrorHandler(event:Event):void {
                            trace("ioErrorHandler: " + event);
                            }

                            private function progressHandler(event:ProgressEvent):void {
                            trace("progressHandler: " + event);
                            }


                            ]]>
                            </mx:Script>
                            <mx:HSlider x="29" y="37" maximum="100" minimum="0" id="vSlider" value="50" change="volumeChangedHander(event)" snapInterval="1"/>
                            <mx:Label x="198" y="39" text="50" id="vSetting"/>
                            • 11. Re: Control Volume of All Sounds
                              vectorg6
                              I tried this I get the error :
                              Call to a possibly undefined method volumeChangeHandler .

                              Am I missing something

                              ????
                              • 12. Re: Control Volume of All Sounds
                                dishmael Level 1
                                Post your code, its saying you didn't define the volumeChangeHandler method.
                                • 13. Re: Control Volume of All Sounds
                                  vectorg6 Level 1
                                  Thanks ...Tried a few other things but still end up with the same error?

                                  package VC
                                  {
                                  import flash.events.Event;
                                  import flash.display.Sprite;

                                  public class VolumeControl extends Sprite {

                                  [Event(name="volumeChanged", type="flash.events.Event")]

                                  private var _instance:VolumeControl;
                                  private var _volume:Number = 50;

                                  public function VolumeControl() {}

                                  public function getInstance():VolumeControl {
                                  if ( _instance == null ) {
                                  _instance = new VolumeControl();
                                  }

                                  return _instance;
                                  }

                                  public function setVolume(number:Number):void {
                                  _volume = number;

                                  // Dispatch volumeChange event
                                  dispatchEvent( new Event("volumeChanged") );
                                  }

                                  public function getVolume():Number {
                                  return _volume;
                                  }
                                  }
                                  }



                                  <?xml version="1.0" encoding="utf-8"?>
                                  <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute">


                                  <mx:Script>
                                  <![CDATA[
                                  import VC.VolumeControl;

                                  [Bindable]private var vc:VolumeControl;
                                  private var file:String = "Test.mp3";
                                  private var song:SoundChannel;

                                  private function init():void {
                                  vc = new VolumeControl().getInstance();
                                  vc.addEventListener( "volumeChanged", volumeChangeHandler );

                                  SoundExample();
                                  }

                                  public function SoundExample():void {
                                  var request:URLRequest = new URLRequest(file);
                                  var soundFactory:Sound = new Sound();
                                  soundFactory.addEventListener(Event.COMPLETE, completeHandler);
                                  soundFactory.addEventListener(Event.ID3, id3Handler);
                                  soundFactory.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
                                  soundFactory.addEventListener(ProgressEvent.PROGRESS, progressHandler);
                                  soundFactory.load(request);
                                  song = soundFactory.play();

                                  // Set the initial volume
                                  var transform:SoundTransform = song.soundTransform;
                                  transform.volume = vc.getVolume();
                                  song.soundTransform = transform;
                                  }

                                  private function volumeChangeHandler(event:Event):void {

                                  vSetting.text = vSlider.value.toString();

                                  var transform:SoundTransform = song.soundTransform;
                                  transform.volume = vc.getVolume();
                                  song.soundTransform = transform;
                                  }

                                  private function completeHandler(event:Event):void {
                                  trace("completeHandler: " + event);
                                  }

                                  private function id3Handler(event:Event):void {
                                  trace("id3Handler: " + event);
                                  }

                                  private function ioErrorHandler(event:Event):void {
                                  trace("ioErrorHandler: " + event);
                                  }

                                  private function progressHandler(event:ProgressEvent):void {
                                  trace("progressHandler: " + event);
                                  }


                                  ]]>
                                  </mx:Script>
                                  <mx:HSlider x="29" y="37" maximum="100" minimum="0" id="vSlider" value="50" change="volumeChangedHander(event)" snapInterval="1"/>
                                  <mx:Label x="198" y="39" text="50" id="vSetting"/>


                                  </mx:Application>
                                  • 14. Re: Control Volume of All Sounds
                                    dishmael Level 1
                                    In your AS code, you have this defined:

                                    private function volumeChangeHandler(event:Event):void {

                                    but in your MXML application your calling volumeChange dHandler:

                                    change="volumeChangedHander(event)"
                                    • 15. Re: Control Volume of All Sounds
                                      vectorg6 Level 1
                                      Great!!!! Im closer to having this global volume slider. Thanks for your help dishmael.

                                      Here is my latest error. After looking it up from what I can understand it means I am not using something that is there or I dont have something that I need.

                                      TypeError: Error #1009: Cannot access a property or method of a null object reference.
                                      at volumeslider/::volumeChangedHandler()
                                      at volumeslider/__vSlider_change()
                                      at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
                                      at flash.events::EventDispatcher/dispatchEvent()
                                      at mx.core::UIComponent/dispatchEvent()
                                      at mx.controls.sliderClasses::Slider/::setValueAt()
                                      at mx.controls.sliderClasses::Slider/::setValueFromPos()
                                      at mx.controls.sliderClasses::Slider/ http://www.adobe.com/2006/flex/mx/internal::onThumbRelease()
                                      at mx.controls.sliderClasses::SliderThumb/ http://www.adobe.com/2006/flex/mx/internal::buttonReleased()
                                      at mx.controls::Button/::systemManager_mouseUpHandler()


                                      The updated code is //

                                      package VX
                                      {
                                      import flash.events.Event;
                                      import flash.display.Sprite;

                                      public class VolumeControl extends Sprite {

                                      [Event(name="volumeChanged", type="flash.events.Event")]

                                      private var _instance:VolumeControl;
                                      private var _volume:Number = 50;

                                      public function VolumeControl() {}

                                      public function getInstance():VolumeControl {
                                      if ( _instance == null ) {
                                      _instance = new VolumeControl();
                                      }

                                      return _instance;
                                      }

                                      public function setVolume(number:Number):void {
                                      _volume = number;

                                      // Dispatch volumeChange event
                                      dispatchEvent( new Event("volumeChanged") );
                                      }

                                      public function getVolume():Number {
                                      return _volume;
                                      }
                                      }
                                      }


                                      <?xml version="1.0" encoding="utf-8"?>
                                      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute">


                                      <mx:Script>
                                      <![CDATA[
                                      import VX.VolumeControl;

                                      [Bindable]private var vc:VolumeControl;
                                      private var file:String = "test.mp3";
                                      private var song:SoundChannel;

                                      private function init():void {
                                      vc = new VolumeControl().getInstance();
                                      vc.addEventListener( "volumeChanged", volumeChangedHandler );

                                      SoundExample();
                                      }

                                      public function SoundExample():void {
                                      var request:URLRequest = new URLRequest(file);
                                      var soundFactory:Sound = new Sound();
                                      soundFactory.addEventListener(Event.COMPLETE, completeHandler);
                                      soundFactory.addEventListener(Event.ID3, id3Handler);
                                      soundFactory.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
                                      soundFactory.addEventListener(ProgressEvent.PROGRESS, progressHandler);
                                      soundFactory.load(request);
                                      song = soundFactory.play();

                                      // Set the initial volume
                                      var transform:SoundTransform = song.soundTransform;
                                      transform.volume = vc.getVolume();
                                      song.soundTransform = transform;
                                      }

                                      private function volumeChangedHandler(event:Event):void {

                                      vSetting.text = vSlider.value.toString();

                                      var transform:SoundTransform = song.soundTransform;
                                      transform.volume = vc.getVolume();
                                      song.soundTransform = transform;
                                      }

                                      private function completeHandler(event:Event):void {
                                      trace("completeHandler: " + event);
                                      }

                                      private function id3Handler(event:Event):void {
                                      trace("id3Handler: " + event);
                                      }

                                      private function ioErrorHandler(event:Event):void {
                                      trace("ioErrorHandler: " + event);
                                      }

                                      private function progressHandler(event:ProgressEvent):void {
                                      trace("progressHandler: " + event);
                                      }


                                      ]]>
                                      </mx:Script>
                                      <mx:HSlider x="29" y="37" maximum="100" minimum="0" id="vSlider" value="50" change="volumeChangedHandler(event)" snapInterval="1"/>
                                      <mx:Label x="198" y="39" text="50" id="vSetting"/>


                                      </mx:Application>
                                      • 16. Re: Control Volume of All Sounds
                                        dishmael Level 1
                                        You didn't initialize your application. The init() method should be called using the application
                                        creationComplete:

                                        <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
                                        • 17. Re: Control Volume of All Sounds
                                          vectorg6 Level 1
                                          That worked but not really. The mp3 played but the slider did not change the volume at all? Thanks for your help I will try to work with this or find another solution. Did you get this to work and change the volume in your project?

                                          VG6
                                          • 18. Control Volume of All Sounds
                                            vectorg6 Level 1
                                            Does anyone have an example of how to use the hslider to control the volume of a loaded swf. Or a global volume example. I have still not found a solution and I know this is so easy but I just cant figure it out. I cant even figure out how to control any volume using the hslider.