No loops generated sound stored in ByteArray and loaded into Sound object?

EDIT 2: This problem still exists, but it seems to be a bug. The Adobe class Sounddoes not send the value Sound.lengthafter loading a ByteArray. Here is the error report I filed (vote for it!):

https://bugbase.adobe.com/index.cfm?event=bug&id=3749649

= = = = =

The following code works to create a sound once - it plays the correct sound, but does not work. I believe that it should be so. I can not debug it

It also does not raise the SOUND_COMPLETE event. Did I miss something?

EDIT: Still broken, but I updated the code below so you can test it. Just copy the class and call testSound():

private var NUM_SAMPLES:int = 16384 * 2;
private var soundByteArray:ByteArray;
private var volume:Number = 1;
private var channel:SoundChannel = new SoundChannel();
private var RATE:int = 44100;


public function testSound():void
{
    var baseSound:Sound = new Sound(); 
    storeAudio();
    var trans:SoundTransform = new SoundTransform(volume, 0);
    SoundMixer.soundTransform = trans;

    soundByteArray.position = 0;
    baseSound.loadPCMFromByteArray(soundByteArray, NUM_SAMPLES, "float", true, RATE);
    soundByteArray.position = 0;

    baseSound.addEventListener(flash.events.Event.SOUND_COMPLETE, onPlaybackComplete);

    trace("loaded 1: " + baseSound.length);
    trace("loaded 2: " + baseSound.bytesLoaded);
    trace("loaded 3: " + baseSound.bytesTotal);

    channel = baseSound.play(0, 20, trans);
    channel.addEventListener(flash.events.Event.SOUND_COMPLETE, onPlaybackComplete);
}

protected function onPlaybackComplete(event:flash.events.Event):void
{
    trace("onPlaybackComplete" + channel.position);
}

private function storeAudio():void
{
    soundByteArray = new ByteArray();
    for (var i:Number = 0; i < NUM_SAMPLES; i++) 
    {
        soundByteArray.writeFloat( 
            Math.sin(
                ((i / RATE)) 
                * Math.PI * 2 * 440
            )
        );
        soundByteArray.writeFloat( 
            Math.sin(
                ((i / RATE)) 
                * Math.PI * 2 * 440
            )
        );
    }

    trace("storeAudio i = " + i + ", " + soundByteArray.length);
}
+4
1

. , , , . -, loadPCMFromByteArray. , Sound.Complete, , , PCM .

converting bytes length to milliseconds channel.position, , .Complete ( , ). , - , , Sound.Complete

, / Flash, , PCM. E-O-F, ByteArrays, ( ?) while loop .

:

  • .. soundByteArray.position = 0; ! channel.position Ending pos. channel = baseSound.play(0); ! channel.position pos.

  • , , looped sampleData , , , PCM setupData setup , Sound.Complete ..

, , PCMdata, , sampleData . , , PCM, , ,

, hack

 package  
 {

    import flash.display.MovieClip;
    import flash.events.*;
    import flash.utils.*;
    import flash.media.*;
    import flash.text.*;

 public class testSound extends MovieClip 
 {

    private var BIT_TYPE:int = 16; //16bit audio
    private var RATE:int = 44100; 
    private var NUM_SAMPLES:int = 8192; //16384 * 2;
    private var NUM_CHANNEL:int = 2; //if stereo 
    private var NUM_TEMP:int =0; //adjustable number for test without changing others 

    public var NUM_TONE_FREQ:int = 440;

    private var soundByteArray:ByteArray;
    private var volume:Number = 1;
    private var channel:SoundChannel = new SoundChannel();


    public var final_samples:int = 0;
    public var time_total:Number; //dont use Integers here - wont always be correct
    public var time_kbps:Number; //"bytes per second" count 

    public var loop_count:int = 0;
    public var timerCount:Number = 0;
    public var timerSecs:Number = 0;
    public var timer:Timer;

    public var trans:SoundTransform;
    public var baseSound:Sound = new Sound(); 

    public var timeText:TextField;
    public var txtFormat:TextFormat;

    public function testSound():void
    {
        //correct NUM_SAMPLES helps with end-time check
        NUM_SAMPLES *= NUM_CHANNEL * BIT_TYPE;

        trans = new SoundTransform(volume, 0);
        channel.soundTransform = trans;  //SoundMixer.soundTransform = trans;

        soundByteArray = new ByteArray();
        soundByteArray.position = 0;

        //setup textField for debug feedback
        setupTextFBack();

        //generate PCM
        storeAudio();
    }

    protected function onPlaybackComplete(event:flash.events.Event):void
    {
        //only works if you are passing your PCM to sampleData events, 
        trace("onPlaybackComplete" + channel.position);
    }

    private function storeAudio():void
    {

       for (var i:Number = 0; i < NUM_SAMPLES; i++) 
        {
            soundByteArray.writeFloat
            (  Math.sin((i / RATE) * Math.PI * 2 * NUM_TONE_FREQ)  );

           soundByteArray.writeFloat
           (  Math.sin((i / RATE) * Math.PI * 2 * NUM_TONE_FREQ)  );

        }

        trace("storeAudio samples (i) = " + i + ", ByteArray length: " + soundByteArray.length);

        final_samples = i;
        playAudio();
    }

    public function playAudio():void
    {

        soundByteArray.position = 0;
        baseSound.loadPCMFromByteArray(soundByteArray, final_samples, "float", true, RATE);

        channel = baseSound.play(); //channel = baseSound.play(0, 0, trans);
        setupTimeCount(); //count when play starts

        time_kbps = (RATE *  NUM_CHANNEL * BIT_TYPE) / 4; //not /8 because time is never doubled on stereo 
        time_total = (soundByteArray.length / time_kbps);
        time_total = Math.round(time_total * 100) / 100;

        trace ("=== DEBUG INFO : (loop: "+loop_count+ ") =========================================");
        trace ("*** Playing beyond Total Time (PCM end) creates sound glitch issues ");
        trace ("*** Re-Play on a continous Tone will creates short click when it stops to replay ");
        trace ("*** If PCM was music/vocals this click might not be perceived by ear if looped right");
        trace ("====================================================================");
        trace ("Total Kb/sec : " + time_kbps + " bytes per sec");
        trace ("Total time   : " + time_total + " secs" );

        //trim Total millisecs just to avoid any glitches/clicks. Test & fine-tune
        time_total -= 0.314; //PI divided by 10. Need fine-tune? Hell Yes!

        trace ("Total (trim) : " + time_total + " secs" );
    }

    public function setupTimeCount():void
    {
        timer = new Timer(100);
        timer.addEventListener(TimerEvent.TIMER, timerHandler);
        timerCount = 0;
        timer.start();
    }

    function timerHandler(Event:TimerEvent):void
    {
        timerCount += 100;
        checkTime(timerCount);
        //trace("channel.pos = " + channel.position); //for debug only
    }

    function checkTime(miliseconds:int) : void 
    {
        timerSecs = miliseconds/1000;
        timeText.text = ("elapsed : " + timerSecs);

        //if (timerSecs >= time_total)
        if ( channel.position >= (time_total * 1000) )
        {
            reloopAudio();
        }
    }

    function reloopAudio():void
    {
            channel.stop(); //else you get stutter from going forward
            timer.stop();
            trace("attempting replay / loop..");
            loop_count += 1;
            playAudio(); //redo playing function
    }

    public function setupTextFBack():void
    {
        txtFormat = new TextFormat();
        txtFormat.size = 20; 
        txtFormat.font = "Arial"; 

        timeText = new TextField();
        timeText.defaultTextFormat = txtFormat;
        timeText.antiAliasType = AntiAliasType.ADVANCED;

        timeText.x = stage.stageWidth / 2 ;
        timeText.y = stage.stageHeight / 2 ;
        timeText.textColor = 0xFF0000;
        timeText.text = " ";
        timeText.width = 200;

        addChild(timeText);

    }

 }
 }
+1

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


All Articles