2010-02-27 5 views
4

После просмотра документации по звуковым классам, похоже, нет способа управлять звуковым шагом с помощью ActionScript 3.0. есть только возможность контролировать объем и панорамирование. почему нет свойства шага? это единственное свойство звука, отсутствующее для возможности создания полнофункционального звукового движка в ActionScript?Управление звуковой дорожкой с помощью ActionScript 3.0?

Надеюсь, что я дезинформирован, но в случае, если я не есть альтернативы/обходные пути для управления шагом в AS3?

ответ

7

Andre Michelle имеет большое article on Pitch управление с помощью ActionScript 3.0

Для справки, здесь Андре пример кода:

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; 
     } 
    } 
} 

Базовое использование было бы что-то вроде:

//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

удивительного! спасибо, что указали мне на это! – TheDarkIn1978

+0

рад, что это помогает. Поначалу Ли Бремелоу (http://theflashblog.com/?p=1129) был на этом посту, но звук - это область знаний Андре Мишель. –

+0

-1 потому, что в статьях есть неработающие ссылки. Таким образом, мы видим важность, по крайней мере, откладывания некоторого modicum ответа как вашего «ответа», а не только ссылок. –

0

Извлечение ByteArray от звукового объекта, а затем манипулировать байтовыми данными, возвращая новый bytearray.

Вот конкретный пример из 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; 
}