Sound step control with ActionScript 3.0?

after looking at the documentation for sound classes, there seems to be no way to control the sound step using ActionScript 3.0. there is only the ability to control the volume and pan. why is there no step property? Is this the only property of sound that is missing for the ability to create a fully functional sound engine in ActionScript?

Hope I'm misinformed, but in case I don't have alternatives / workarounds for step management in AS3?

+4
source share
2 answers

Andre Michelle has an excellent article on Pitch control with actionscript 3.0

For reference, here is a sample Andre code:

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 ( andre.michelle@gmail.com ) */ 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; } } } 

The main use would look something like this:

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

Extract bytearray from the sound object, and then manipulate byte data, returning a new bytearray.

Here is an example from the 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; } 
0
source

Source: https://habr.com/ru/post/1302552/


All Articles