Проблема в обработчике onSampleData.
В вашем wav-файле амплитуды хранятся в виде шорт со знаком, то есть 16 бит целых чисел . Вы читаете их как 32-битные со знаком с плавающей точкой . Целые числа и числа с плавающей запятой по-разному представляются в двоичном формате, так что это никогда не будет работать правильно.
Теперь игрок ожидает плавания. Почему они использовали поплавки? Не знаю наверняка, но одна веская причина в том, что он позволяет игроку принимать нормализованное значение для каждого сэмпла. Таким образом, вам не нужно заботиться или знать, какой битпепт использует игрок: максимальное значение равно 1, а минимальное значение равно -1, и все.
Итак, ваша проблема в том, что вы должны преобразовать подписанный шорт в нормализованное число с плавающей запятой. Короткое замыкание занимает 16 бит, поэтому оно может хранить 2 ^ 16 (или 65 536) различных значений. Поскольку он подписан, а знак занимает один бит, максимальное значение будет 2 ^ 15. Итак, вы знаете, что ваш ввод - диапазон -32,768 ... 32,767.
Значение выборки нормализовано и должно находиться в диапазоне -1 ... 1, с другой стороны.
Итак, вы должны нормализовать ваш ввод. Это довольно просто. Просто возьмите считанное значение и разделите его на максимальное значение, и ваша входная амплитуда будет преобразована в диапазон -1 ... 1.
Примерно так:
private function onSampleData(evt:SampleDataEvent):void
{
var amplitude:int = 0;
var maxAmplitude:int = 1 << (bitsPerSample - 1); // or Math.pow(2, bitsPerSample - 1);
var sample:Number = 0;
var actualSamples:int = 8192;
var samplesPerChannel:int = actualSamples / channels;
for ( var c:int = 0; c < samplesPerChannel ; c++ ) {
var i:int = 0;
while(i < channels && data.bytesAvailable >= 2) {
amplitude = data.readShort();
sample = amplitude / maxAmplitude;
evt.data.writeFloat(sample);
i++;
}
}
}
Несколько замечаний:
maxAmplitude может (и, вероятно,
должен) рассчитываться при прочтении
Глубина Я делаю это в
метод, чтобы вы могли видеть это в
вставленный код.
Хотя maxAmplitude рассчитывается
на основе прочитанного bitdepth и, таким образом,
будет правильным для любой разрядности,
Я читаю шорты в цикле, так
если ваш WAV-файл использует
разная глубина, эта функция
не будет работать правильно. Вы могли бы
добавить переключатель и прочитать необходимые
количество данных (например, readInt, если
разрядность 32). Тем не менее, 16 бит
такой широко используемый стандарт, что я
сомневаюсь, что это практически необходимо.
Эта функция будет работать для
стерео wavs. Если вы хотите, чтобы это работало
для моно, напиши это, чтобы написать
один и тот же образец дважды. То есть для каждого
читать, вы делаете две записи (ваш вклад
моно, но игрок ожидает 2
образцы).
Я удалил EOF поймать, как вы можете
знать, достаточно ли у вас данных для чтения
из вашего буфера проверки
bytesAvailable. Достигнув конца
поток не является исключительным в любом
Кстати, ИМО, так что я бы предпочел контролировать это
случай без обработчика исключений,
но это всего лишь личное
предпочтение.