2010-02-27 5 views
4

après avoir parcouru la documentation pour les classes de sons, il semble qu'il n'y ait aucun moyen de contrôler la hauteur du son avec Actionscript 3.0. il n'y a que la possibilité de contrôler le volume et le panoramique. Pourquoi n'y a-t-il pas de propriété de hauteur? c'est la seule propriété sonore manquante pour la possibilité de créer un moteur de son complet dans Actionscript?Contrôler le son avec ActionScript 3.0?

J'espère que je suis mal informé, mais au cas où je ne suis pas existe-t-il des alternatives/solutions de contournement pour contrôler la hauteur dans AS3?

Répondre

7

Andre Michelle a un grand article on Pitch contrôle avec actionscript 3.0

Pour référence, voici le code exemple d'André:

package components 
{ 
    import flash.events.Event; 
    import flash.events.SampleDataEvent; 
    import flash.media.Sound; 
    import flash.net.URLRequest; 
    import flash.utils.ByteArray; 

    /** 
    * @author Andre Michelle ([email protected]) 
    */ 
    public class MP3Pitch 
    { 
     private const BLOCK_SIZE: int = 3072; 

     private var _mp3: Sound; 
     private var _sound: Sound; 

     private var _target: ByteArray; 

     private var _position: Number; 
     private var _rate: Number; 

     public function MP3Pitch(url: String) 
     { 
      _target = new ByteArray(); 

      _mp3 = new Sound(); 
      _mp3.addEventListener(Event.COMPLETE, complete); 
      _mp3.load(new URLRequest(url)); 

      _position = 0.0; 
      _rate = 1.0; 

      _sound = new Sound(); 
      _sound.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleData); 
     } 

     public function get rate(): Number 
     { 
      return _rate; 
     } 

     public function set rate(value: Number): void 
     { 
      if(value < 0.0) 
       value = 0; 

      _rate = value; 
     } 

     private function complete(event: Event): void 
     { 
      _sound.play(); 
     } 

     private function sampleData(event: SampleDataEvent): void 
     { 
      //-- REUSE INSTEAD OF RECREATION 
      _target.position = 0; 

      //-- SHORTCUT 
      var data: ByteArray = event.data; 

      var scaledBlockSize: Number = BLOCK_SIZE * _rate; 
      var positionInt: int = _position; 
      var alpha: Number = _position - positionInt; 

      var positionTargetNum: Number = alpha; 
      var positionTargetInt: int = -1; 

      //-- COMPUTE NUMBER OF SAMPLES NEED TO PROCESS BLOCK (+2 FOR INTERPOLATION) 
      var need: int = Math.ceil(scaledBlockSize) + 2; 

      //-- EXTRACT SAMPLES 
      var read: int = _mp3.extract(_target, need, positionInt); 

      var n: int = read == need ? BLOCK_SIZE : read/_rate; 

      var l0: Number; 
      var r0: Number; 
      var l1: Number; 
      var r1: Number; 

      for(var i: int = 0 ; i < n ; ++i) 
      { 
       //-- AVOID READING EQUAL SAMPLES, IF RATE < 1.0 
       if(int(positionTargetNum) != positionTargetInt) 
       { 
        positionTargetInt = positionTargetNum; 

        //-- SET TARGET READ POSITION 
        _target.position = positionTargetInt << 3; 

        //-- READ TWO STEREO SAMPLES FOR LINEAR INTERPOLATION 
        l0 = _target.readFloat(); 
        r0 = _target.readFloat(); 

        l1 = _target.readFloat(); 
        r1 = _target.readFloat(); 
       } 

       //-- WRITE INTERPOLATED AMPLITUDES INTO STREAM 
       data.writeFloat(l0 + alpha * (l1 - l0)); 
       data.writeFloat(r0 + alpha * (r1 - r0)); 

       //-- INCREASE TARGET POSITION 
       positionTargetNum += _rate; 

       //-- INCREASE FRACTION AND CLAMP BETWEEN 0 AND 1 
       alpha += _rate; 
       while(alpha >= 1.0) --alpha; 
      } 

      //-- FILL REST OF STREAM WITH ZEROs 
      if(i < BLOCK_SIZE) 
      { 
       while(i < BLOCK_SIZE) 
       { 
        data.writeFloat(0.0); 
        data.writeFloat(0.0); 

        ++i; 
       } 
      } 

      //-- INCREASE SOUND POSITION 
      _position += scaledBlockSize; 
     } 
    } 
} 

utilisation de base serait quelque chose comme:

//create an MP3Pitch instance and load a sound 
var mp3:MP3Pitch = new MP3Pitch("/path/to/your/file.mp3"); 
//change the pitch via rate setter 
mp3.rate += 0.5 
+0

incroyable! merci de m'avoir indiqué cela! – TheDarkIn1978

+0

content que ça aide. Initialement, Lee Brimelow (http://theflashblog.com/?p=1129) avait un article à ce sujet, mais Sound est le domaine d'expertise d'André Michelle. –

+0

-1 parce que les articles sont des liens brisés. Ainsi, nous voyons l'importance d'au moins mettre un peu de réponse comme votre «réponse», pas seulement des liens. –

0

Extrait un bytearray à partir de l'objet sonore, puis manipuler les données de l'octet, en retournant un nouveau bytearray.

Voici l'exemple réel de la API Reference Doc

var sourceSnd:Sound = new Sound(); 
var outputSnd:Sound = new Sound(); 
var urlReq:URLRequest = new URLRequest("test.mp3"); 

sourceSnd.load(urlReq); sourceSnd.addEventListener(Event.COMPLETE, loaded); 

function loaded(event:Event):void { 
    outputSnd.addEventListener(SampleDataEvent.SAMPLE_DATA, processSound); 
    outputSnd.play(); } 

function processSound(event:SampleDataEvent):void { 
    var bytes:ByteArray = new ByteArray(); 
    sourceSnd.extract(bytes, 4096); 
    event.data.writeBytes(upOctave(bytes)); } 

function upOctave(bytes:ByteArray):ByteArray { 
    var returnBytes:ByteArray = new ByteArray(); 
    bytes.position = 0; 
    while(bytes.bytesAvailable > 0) 
    { 
     returnBytes.writeFloat(bytes.readFloat()); 
     returnBytes.writeFloat(bytes.readFloat()); 
     if (bytes.bytesAvailable > 0) 
     { 
      bytes.position += 8; 
     } 
    } 
    return returnBytes; 
}