AS3 sound.extract()用于波形

时间:2011-05-29 13:44:42

标签: flash actionscript-3 audio mp3 flashdevelop

早上好!

我正在尝试为MP3创建可视波形。我所包含的代码是在成功加载MP3时调用的。我打算从声音中提取一些重要的样本来创建波形,而不是将整个声音提取到一个bytearray中。即使在一台好机器上,提取整首歌曲也会导致闪光灯冻结3-5秒(或更长时间!)。就我的目的而言,这是不可行的。

不幸的是,我在下面的代码未能生成任何数字。如果我提取整个歌曲它的功能,但提取关键点并没有给我什么。执行提取是否会使声音对象的其余部分对将来的提取无效?如果是这样,有什么方法可以在提取过程中长时间不冻结闪光?

其余代码中的一些重要变量:

waveFormWidth:波形精灵的静态宽度 waveFormHeight:波形精灵的静态高度 song:我将用来创建波形的声音对象。

    public function mapWaveForm(e:Event = null):void
    {

        // Clear the wave form sprite
        waveForm.graphics.clear();
        waveForm.graphics.lineStyle(0, 0x000000, 1);

        // Storage for the wave form bit data
        var byteOutput:ByteArray;
        var leftPeakSize:Number;
        var rightPeakSize:Number;
        var songTotalSamples:int;
        var thisSample:int;

        byteOutput = new ByteArray();

        // How many samples?
        songTotalSamples = (song.length * 44.1);

        // Loop for the wave form width
        for (var peakCount:int = 0; (peakCount < waveFormWidth); peakCount++)
        {

            // Get info at each peak.
            thisSample = Math.floor(songTotalSamples * (peakCount / waveFormWidth));
            song.extract(byteOutput, 1, thisSample);
            byteOutput.position = 0;
            trace(thisSample, byteOutput.readFloat());

            leftPeakSize = byteOutput.readFloat() / 1.27;
            rightPeakSize = byteOutput.readFloat() / 1.27;

            // Turn those peaks into something usable.
            leftPeakSize = leftPeakSize * (waveFormHeight * .5);
            rightPeakSize = rightPeakSize * (waveFormHeight * .5);

            // Make the left channel line
            waveForm.graphics.moveTo(peakCount, (waveFormHeight * .5));
            waveForm.graphics.lineTo(peakCount, (waveFormHeight * .5) - leftPeakSize);

            // Make the right channel line
            waveForm.graphics.moveTo(peakCount, (waveFormHeight * .5));
            waveForm.graphics.lineTo(peakCount, (waveFormHeight * .5) + rightPeakSize);


        }

    }

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

对于它的价值,我只是在研究完全相同的东西,我只是在经过一些研究后才开始工作。我似乎无法使用WAV文件,但这与所有类型的MP3文件兼容。这就是我最终的结果:

var IMAGE_SIZE:int = new int(600); // Final width of image
var IMAGE_DEPTH:int = new int(5); // How many passes per pixel of image
var RESOLUTION:int = new int(IMAGE_SIZE * IMAGE_DEPTH);
var DRAW_AMPLITUDE:int = new int(150); // pixel height of max volume line

var waveForm:Shape = new Shape();

var mp3File:Sound = new Sound();
mp3File.load(new URLRequest("audio.mp3"));
mp3File.addEventListener(Event.COMPLETE, parseSound);

function parseSound(e:Event):void {
    var soundBytes:ByteArray = new ByteArray();
    for (var i:int=0; i<RESOLUTION; i++) {
        mp3File.extract(soundBytes, 1, Math.floor((mp3File.length*44.1)*(i/RESOLUTION)));
        soundBytes.position = 0;
        while (soundBytes.bytesAvailable > 0) {
            var tmpNum:Number = new Number();
            tmpNum += soundBytes.readFloat();
        }
        drawWave(i, tmpNum);
        soundBytes.clear();
    }
    this.addChild(waveForm);
    trace("--DONE--");
}

function drawWave(i:Number, amp:Number):void {
    var pixX:Number = new Number(Math.floor(i/IMAGE_DEPTH));
    var pixY:Number = new Number((amp*DRAW_AMPLITUDE)/2);
    waveForm.graphics.lineStyle(1, 0x0, (1.2/IMAGE_DEPTH));
    waveForm.graphics.moveTo(pixX, ((DRAW_AMPLITUDE/2)-pixY));
    waveForm.graphics.lineTo(pixX, ((DRAW_AMPLITUDE/2)+pixY));
}

答案 1 :(得分:1)

这是一篇旧帖子,也许我不能正确理解你的问题,但是提取方法允许你指定样本的长度,以及开始的位置。

"public function extract(target:ByteArray, length:Number, startPosition:Number = -1):Number"

length是要提取的样本数,startPosition是byteArray中要开始的位置。

请参阅http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/Sound.html#extract%28%29

答案 2 :(得分:0)

使用此课程:

http://www.bytearray.org/?p=329

我还把这个结合到了一个非常糟糕,半生不熟的实验中,我开始做一个混音器。你也可以在这里获得源代码:

http://code.google.com/p/ascensionsystems/downloads/list