开发者

Help needed with AS3 Sound.extract()

开发者 https://www.devze.com 2023-01-07 10:28 出处:网络
I\'m trying to create a parametric equalizer in Flash. I\'ve been looking for a way to read audio data and mess around with the samples before Flash plays them on the fly. Loading a sound in one Sound

I'm trying to create a parametric equalizer in Flash. I've been looking for a way to read audio data and mess around with the samples before Flash plays them on the fly. Loading a sound in one Sound object and using Sound.extract() to read the data, processing it, then play a second second empty Sound object and writing the data to its samp开发者_开发技巧leData event seems to be the way to do it (please correct me if I am wrong or there is a better way).

Is there a way to use Sound.extract() while the Sound object is still loading a sound file? I don't want to have to wait for the entire sound file to load before it plays. Unfortunately, whenever I use Sound.extract() while the Sound object is still loading, it returns a zero-length byte array.

Is there a way to wait for enough samples to load first before playing? I imagine I'd have the same problem again when the Flash movie eats through all the loaded samples while the sound file is still loading.

Here's a simplified version of my code. It's working so far, but only when I wait for the Sound object to fire an Event.COMPLETE event.

var inputSound:Sound = new Sound();
inputSound.load("somefile.mp3");
inputSound.addEventListener(Event.COMPLETE, loadComplete);

var outputSound:Sound = new Sound();
outputSound.addEventListener(SampleDataEvent.SAMPLE_DATA, processSamples);
var sc:SoundChannel;

/*if I called ouputSound.play() right now, it wouldn't work.*/

function loadComplete(e:Event) : void
{
    sc = outputSound.play();
}

function processSamples(e:SampleDataEvent) : void
{
    var samples:ByteArray = new ByteArray();
    var len:int = snd.extract(samples, 8192);
    var sample:Number;
    var i:int = 0;

    trace(len.toString());

    samples.position = 0;

    //TODO: Sound Processing here

    //The following code plays a sine wave over the input sound as a test

    while (samples.bytesAvailable)
    {
        i++;
        sample = samples.readFloat();
        sample += Math.sin(i * Math.PI / 256) * 0.5;
        e.data.writeFloat(sample);
        sample = samples.readFloat();
        sample += Math.sin(i * Math.PI / 256) * 0.5;
        e.data.writeFloat(sample);
    }
}

EDIT: If I try using the PROGRESS event, I'm going to need to do a lot more low level stuff to implement buffering and whatnot (anything else I need to account for?). Could someone help me out with that? Also, is there a way to tell the position of a sample in milliseconds? Do I have to assume that all sound files are 44.1 kHz stereo (they may not be), or is there a better way?


check out the solution in this post here

How to compute viewport from scrollbar?

You don't need to extract the entire track into a bytearray. You only really need to get what you need when you need it.

If you really want to extract the track in one go you can use

sound.extract(yourbytearray,sound.lenght*44.1)

// lenght *44.1 gives you the number of samples if the mp3 is encoded at 44100

one you have all your pcm data, in your processsamples handler instead of calling sound extract you would do something like

if(yourbytearray.bytesAvailable==0)
{
  yourbytearray.position==0
}

var left:Number = youbytearray.readFloat

var right:Number = youbytearray.readFloat

//process the left with eq

//process the right with eq

event.data.writeFloat(left);
event.data.writeFloat(right);

Extracting all the audio at once would probably be the easiest but you'll run into memory problem for mp3s longer than about 8 minutes.

On the whole samples milliseconds thing.....

bytearray.position / bytearray.lenght gives you where in the song you are.

Divide that by 44100 and it will give you the number of milliseconds.

Ask more questions if you need me to clear anything up

0

精彩评论

暂无评论...
验证码 换一张
取 消