我想在不使用外部庫的情況下提高或降低音頻檔案(.wav 格式)的音高。每個人都可以向我建議一些解決方案嗎?非常感謝。
uj5u.com熱心網友回復:
除了 Phil Freihofner 的回答之外,如果您想保留時間,那么您需要將資料轉換為:
將您的 PCM 資料從時域轉換為頻域
所以取一大塊 PCM 資料(對視窗使用 2 個樣本的冪,以便使用 FFT,例如 1024 個樣本)并對其應用FFT。
改變頻率
FFT 輸出中的每個條目都代表 Niquist 頻率幅度和相位(作為復域相量),因此只需丟棄低頻并用來自較高頻率的值替換它們,其余部分則用零填充。請注意實域輸入的 FFT 結果是對稱的,這意味著“所有”點都存在兩次。
這里是一個 8 點 FFT 結果的例子:
real PCM: { 0, 1, 2, 3, 4, 5, 6, 7 } cplx DFFT { 7, 0, -1, -2.414214, -1, -1, -1, -0.4142136, -1, 0, -1, 0.4142136, -1, 1, -1, 2.414214 }7,0DFFT 結果的第一個條目 ( ) 是 DC 偏移,然后每個 niquist 頻率有 2 個鏡像:7, 0, // DC offset -1, -2.414214, // 0 -1, -1, // 1 -1, -0.4142136,// 2 -1, 0, // 3 -1, 0.4142136, // 2 -1, 1, // 1 -1, 2.414214 // 0因此,為了降低音高,將鏡子移向較低的頻率和零墊:
7, 0, // DC offset -1, -1, // 1 -1, -0.4142136,// 2 -1, 0, // 3 0, 0, // zero pad -1, 0, // 3 -1, 0.4142136, // 2 -1, 1, // 1為了增加相反方向的音高偏移以及零墊并保持最高頻率不變(應該是空的):
7, 0, // DC offset 0, 0, // zero pad -1, -2.414214, // 0 -1, -1, // 1 -1, 0, // 3 this will be probably (0,0) as while increasin grequency the original signal would lack high frequencies -1, 1, // 1 -1, 2.414214 // 0 0, 0, // zero pad通過轉換回時域來重建 PCM
因此,只需對移位的資料應用逆 FFT。這將創建您想要的 PCM。
對整個 PCM 輸入重復此操作
這不是我的一杯茶,但由于頻移,可能需要沿著各個 PCM 塊的邊界進行一些平滑處理。為避免這種情況,您可以對整個 PCM 資料執行 FFT/iFFT(如果資料太大,這可能是一個問題)或稍微重疊塊并將它們與權重圖混合在一起,但這可能會產生聲音故障。
uj5u.com熱心網友回復:
基本步驟如下:
將音頻資料轉換為 PCM(我更喜歡使用帶符號的標準化浮點數)。
創建將在 PCM 陣列中前進的游標變數。在每個游標位置,您將獲取一個 PCM 值并將其放置在一個陣列中以進行播放。
游標前進的增量將決定新的播放速率。示例:如果您簡單地遍歷 PCM 陣列,則新的 PCM 陣列將具有相同的資料并以相同的速率播放。如果增加 2,新的 PCM 陣列將有一半的資料點并以兩倍的速率播放。如果你前進 1.5,新的 PCM 陣列將比原來的快 1.5 倍。
當游標落在兩個資料點之間時使用線性插值。示例:如果您的游標增加 1.75,并且 PCM 上的前三個資料點是 0、0.2、0.4,則您的第二個“新 PCM 陣列”值將通過計算 [1] 和 [2] 之間的點得出PCM 陣列值為 0.2 和 0.4。(我將陣列計算為從 [0] 開始。)在此示例中,新的 PCM 值將如下所示:
newPCM = (PCM[round(cursor)] * (1 - decimalPartOfCursor)) PCM[round(cursor) 1] * (decimalPartOfCursor)或者
newPCM = (0.25 * 0.2) (0.75 * 0.4)將新的 PCM 陣列轉換回位元組流進行播放。
uj5u.com熱心網友回復:
您可以更快地播放它以獲得更高的音高。但是如果你想保持相同的播放速度并改變音高,這要復雜得多,你需要一個“Alvin and the Chipmunks”之類的聲音處理演算法。
https://en.wikipedia.org/wiki/Audio_time_stretching_and_pitch_scaling
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/354373.html
上一篇:通過匹配屬性值對值求和
下一篇:按隨機生成的權重對元組進行排序
