AS3: извлеченные циклы сэмплированных данных сохраняются навсегда - PullRequest
0 голосов
/ 18 ноября 2011

Я работаю над виртуальной фортепианной клавиатурой, которая обрабатывает импортированные звуковые образцы 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;

    }
}

Должно быть очень простое решение для этого, у меня просто нет опыта работы с необработанными данными, поэтому я был бы очень благодарен, если бы вы могли помочь мне с чем-либо.

1 Ответ

1 голос
/ 25 ноября 2011

Хорошо, я придумал решение несколько дней назад, у меня просто не было времени опубликовать его здесь.

Простой способ рассчитать длину образца звука ByteArray - samplesLength = sound.length * 44.1;.

Это связано с тем, что звук отображает свою длину в миллисекундах, что составляет 1000 стерео пар сэмплов в секунду, а разрешение сэмплирования для звуков во вспышке составляет 44100 Гц (также пар сэмплов в секунду), поэтому44.1 пары сэмплов, отрисованных за короткую миллисекунду.

Кроме того, сэмпл представляет собой 32-битное значение с плавающей запятой, а пара сэмплов имеет длину 64 бита (8 байт), поэтому, если я прав,это samplesLength = soundExtract.length / 8;.

...