我想上傳一個8000hz,16位wav文件到AS3中的11025hz。在這一點上,我不關心應用我最終需要的低通濾波器。我是referencing this wiki page。如何上傳使用AS3的wav文件?
以下是我迄今所做的:
- 計算最小公倍數是3528000
- 計算L達到441
- 計算值M是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());
}
任何人都可以告訴我我在做什麼錯在我的代碼?這是我的第一個問題,所以如果我忘記了一些東西,或者需要提供更多信息,請告訴我。
謝謝!
更新:
我簡單化ARIC的回答,我現在使用下面的代碼成功上採樣:
/**
* 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個更好的方法來做到這一點,但爲了我所需要的,它的工作原理。再次感謝Aric的回答。
加零會無疑產生不好的數據。嘗試將它看作一個圖像,並想象如果告訴您將圖像的水平分辨率提高到四倍,並且您在每個正常像素之間添加了3個黑色像素,將會怎樣?你需要看插值。我讀過的一種更好的方法是將聲音文件轉換到其頻率域,然後將其轉換回更高的分辨率。 – 2009-12-16 22:10:16
感謝您的信息。我讀過同樣的東西。不幸的是,我對數字信號處理一無所知,並且關於FFT的閱讀(http://en.wikipedia.org/wiki/Fast_Fourier_transform)讓我更加困惑。你有什麼樣的例子/資源可以讓你瞭解DFT的基本知識,哪些不是?我理解轉換到頻域的概念,但我無法理解如何以更高的分辨率進行轉換。任何信息真的很感激。謝謝! – 2009-12-16 22:23:24
當您試圖在維基百科進行該方法時,是否通過低通濾波器運行上採樣數據?我現在正在使用Aric的方法,但我對添加零點 - 然後過濾器方法感到好奇。 – 2010-12-12 04:53:01