Actionscript 3 AS3:提取的sampledata循环永远是最后一个块

Actionscript 3 AS3:提取的sampledata循环永远是最后一个块,actionscript-3,audio,bytearray,sample-data,Actionscript 3,Audio,Bytearray,Sample Data,我正在开发一个虚拟钢琴键盘,可以处理导入的mp3声音样本。我已经找到了一个问题的解决方案,但当我运行下面的测试代码时,声音将永远循环每个声源的最后一个数据块,显然,我希望它在提取的声音数据结束时停止。任何提取的样本数据也会发生同样的情况,我甚至不必混合它。我添加了一个动态绘制的图形波形,以便您可以直观地检查发生了什么。这是我第一次使用ByteArray类,所以我不知道如何解决这个问题 import flash.media.Sound; import flash.utils.ByteArray;

我正在开发一个虚拟钢琴键盘,可以处理导入的mp3声音样本。我已经找到了一个问题的解决方案,但当我运行下面的测试代码时,声音将永远循环每个声源的最后一个数据块,显然,我希望它在提取的声音数据结束时停止。任何提取的样本数据也会发生同样的情况,我甚至不必混合它。我添加了一个动态绘制的图形波形,以便您可以直观地检查发生了什么。这是我第一次使用ByteArray类,所以我不知道如何解决这个问题

import flash.media.Sound;
import flash.utils.ByteArray;
import flash.geom.Point;
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.events.MouseEvent;

var t0:Sound = new Sound(new URLRequest("5_C.mp3")); //sound imported
var t1:Sound = new Sound(new URLRequest("5_E.mp3")); //other sound imported
//var t0:Sound = new C4(); //sound in library
//var t1:Sound = new E4(); //other sound in library
var t0p:Point = new Point();
var t1p:Point = new Point();
var t0a:ByteArray = new ByteArray();
var t1a:ByteArray = new ByteArray();
var mix:Sound = new Sound();

var spr:Sprite = new Sprite();
addChild(spr);
spr.y = 10;
var lx:Number = 0;
var ly:Number = 0;
spr.graphics.lineStyle(1,0,1,true);

mix.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);

stage.addEventListener(MouseEvent.CLICK, mce);
function mce(e:MouseEvent) {
    mix.play();
}

function onSampleData(e:SampleDataEvent):void {

    t0a.position = 0;
    t1a.position = 0;

    t0.extract(t0a, 3072);
    t1.extract(t1a, 3072);

    t0a.position = 0;
    t1a.position = 0;

    for(var i:int = 0; i < 3072; i++) {

        t0p.x = t0a.readFloat();
        t0p.y = t0a.readFloat();
        t1p.x = t1a.readFloat();
        t1p.y = t1a.readFloat();

        var tmp:Point = new Point(Math.max(Math.min(t0p.x + t1p.x, 1), -1), Math.max(Math.min(t0p.y + t1p.y, 1), -1));

        e.data.writeFloat(tmp.x); // left
        e.data.writeFloat(tmp.y); // right

        if (lx > 549) {
            lx = 0;
            ly += 10;
            if (ly > 399) {
                spr.graphics.clear();
                ly = 0;
                spr.graphics.lineStyle(1,0,1,true);
            }
            spr.graphics.moveTo(lx, (tmp.x + tmp.y) * 4 + ly);
        } else {
            spr.graphics.lineTo(lx, (tmp.x + tmp.y) * 4 + ly);
        }
        lx += 0.05;

    }
}
导入flash.media.Sound;
导入flash.utils.ByteArray;
导入flash.geom.Point;
导入flash.display.Sprite;
导入flash.net.URLRequest;
导入flash.events.MouseEvent;
var t0:Sound=新声音(新的URL请求(“5_C.mp3”)//进口声音
变量t1:Sound=新声音(新的URL请求(“5_E.mp3”)//其他进口声音
//变量t0:声音=新的C4()//图书馆的声音
//变量t1:Sound=newe4()//图书馆中的其他声音
var t0p:Point=新点();
var t1p:Point=新点();
var t0a:ByteArray=新的ByteArray();
var t1a:ByteArray=新的ByteArray();
var mix:Sound=新声音();
var spr:Sprite=新Sprite();
addChild(spr);
spr.y=10;
变量lx:Number=0;
变量ly:数值=0;
spr.图形线样式(1,0,1,真);
mix.addEventListener(SampleDataEvent.SAMPLE_数据,onSampleData);
stage.addEventListener(MouseEvent.CLICK,mce);
功能mce(e:MouseeEvent){
mix.play();
}
函数onSampleData(e:SampleDataEvent):void{
t0a.position=0;
t1a.位置=0;
t0.提取物(t0a,3072);
t1.提取物(t1a,3072);
t0a.position=0;
t1a.位置=0;
对于(变量i:int=0;i<3072;i++){
t0p.x=t0a.readFloat();
t0p.y=t0a.readFloat();
t1p.x=t1a.readFloat();
t1p.y=t1a.readFloat();
var tmp:Point=新点(数学最大值(数学最小值(t0p.x+t1p.x,1),-1),数学最大值(数学最小值(t0p.y+t1p.y,1),-1));
e、 data.writeFloat(tmp.x);//左
e、 data.writeFloat(tmp.y);//对
如果(lx>549){
lx=0;
ly+=10;
如果(ly>399){
spr.graphics.clear();
ly=0;
spr.图形线样式(1,0,1,真);
}
spr.graphics.moveTo(lx,(tmp.x+tmp.y)*4+ly);
}否则{
spr.graphics.lineTo(lx,(tmp.x+tmp.y)*4+ly);
}
lx+=0.05;
}
}

必须有一个非常简单的解决方案,我只是没有处理原始数据的经验,所以如果您能帮我解决任何问题,我将非常感谢。

好的,几天前我提出了一个解决方案,我只是没有时间在这里发布

计算声音的ByteArray采样长度的一种简单方法是
samplesLength=sound.length*44.1

这是因为声音以毫秒为单位显示其长度,即每秒1000个立体声采样对,而flash中声音的采样分辨率为44100 Hz(也是每秒采样对),因此在短毫秒内渲染44.1个采样对

另外,一个样本是一个32位浮点值,一个样本对是64位(8字节)长,所以如果我是正确的,那么它是
samplesLength=soundExtract.length/8