Я пытаюсь увеличить частоту 16-разрядного файла WAV 8000 Гц до 11025 Гц в AS3. На данный момент меня не беспокоит применение фильтров нижних частот, которые, как я знаю, мне в конечном итоге понадобятся.
Я ссылаюсь на эту вики-страницу .
Вот что я сделал до сих пор:
- Рассчитано наименьшее общее кратное 3528000
- Расчетный L будет 441
- Рассчитано М, чтобы быть 320
- Добавлено 440 нулей между выборками
- Запись каждого 320-го семпла в новый байтовый массив
Однако, когда я играю в новый wav, это неразличимый шум. Вот мой код:
const sourceRate:uint = 8000;
const targetRate:uint = 11025;
var lcm:uint = lcm(targetRate, sourceRate); // = 3528000
var l:uint = lcm / sourceRate; // = 441
var m:uint = lcm / targetRate; // = 320
// upsample by factor of l
var upsampleData:ByteArray = new ByteArray();
upsampleData.endian = Endian.LITTLE_ENDIAN;
// originalWavData is a ByteArray of the source wav data
// fill is a ByteArray that contains 440 zeroes, written using writeShort(0x0)
while(originalWavData.bytesAvailable > 1) {
upsampleData.writeBytes(fill);
upsampleData.writeShort(originalWavData.readShort());
}
// downsample by factor of m
var downsampleData:ByteArray = new ByteArray();
downsampleData.endian = Endian.LITTLE_ENDIAN;
upsampleData.position = 0;
for(var k:uint=0; k<upsampleData.length; k++) {
upsampleData.position = k * m;
if(upsampleData.bytesAvailable < 2) break;
downsampleData.writeShort(upsampleData.readShort());
}
Может кто-нибудь показать мне, что я делаю неправильно в своем коде? Это мой первый пост с вопросом, поэтому, если я что-то забыл или мне нужно предоставить дополнительную информацию, сообщите мне.
Спасибо!
Обновление:
Я не нашел ответа Арика и теперь успешно повышаю его, используя следующий код:
/**
* Generates a ByteArray containing numSamples of
* data using linear interpolation between points
* y0 and y1.
*/
function interpolate(y0:int, y1:int, numSamples:uint):ByteArray {
var b:ByteArray = new ByteArray();
b.endian = Endian.LITTLE_ENDIAN;
var m:Number = Math.round((y1-y0)/numSamples);
for(var i:uint=0; i<numSamples; i++) {
var n:int = m * i + y0;
b.writeShort(n);
}
b.position = 0;
return 0;
}
// upsample by factor of l
var n1:int = 0;
while(originalWavData.bytesAvailable > 1) {
var sample:int = originalWavData.readShort();
upsampleData.writeBytes(interpolate(n1, sample, (l-1)));
n1 = sample;
}
// downsample by factor of m
while(upsampleData.bytesAvailable > 1) {
downsampleData.writeShort(upsampleData.readShort());
upsampleData.position += ((m-1)*2);
}
Несколько моментов, которые следует отметить в этом решении: я повышаю частоту аудио-капчи, поэтому качество звука не так уж важно. Кроме того, первые сэмплы - просто тишина, поэтому мне не нужно было вычислять значение слева от первого сэмпла. Вот почему n1 изначально равно 0. Кроме того, вместо усреднения сгенерированных сэмплов в моем даунсэмпле я просто брал каждый M-й сэмпл, и для моих целей это звучало просто отлично.
Я уверен, что есть 1000 лучших способов сделать это, но для того, что мне нужно, это работает. Еще раз спасибо Арику за его ответ.