2014-10-20 50 views
0

因此,我正在處理Objective C中的音頻,並試圖編寫增益更改函數。目前我只能將接受的音頻格式限制爲16位AIFF文件。我使用的過程非常簡單:我從AIFF對象中獲取音頻數據,然後跳到音頻中要處理的位置(如果x1:10和x2:20的目標是更改採樣的幅度從10秒進入音頻到20秒進入),然後通過乘法應用增益變化來逐步通過樣本。問題在於,我將處理後的樣本寫入新的NSMutableData,然後使用聲音數據編寫新的AIFF文件,處理後的樣本完全混亂,音頻基本上只是噪聲。更改目標C中音頻數據的增益會導致波形混亂

-(NSMutableData *)normalizeAIFF:(AIFFAudio *)audio x1:(int)x1 x2:(int)x2{ 

    // obtain audio data bytes from AIFF object 
    SInt16 * bytes = (SInt16 *)[audio.ssndData bytes]; 
    NSUInteger length = [audio.ssndData length]/sizeof(SInt16); 

    NSMutableData *newAudio = [[NSMutableData alloc] init]; 
    int loudestSample = [self findLoudestSample:audio.ssndData]; 

    // skip offset and blocksize in SSND data and proceed to user selected point 
    // For 16 bit, 44.1 audio, each second of sound data holds 88.2 thousand samples 
    int skipTo = 4 + (x1 * 88200); 
    int processChunk = ((x2 - x1) * 88200) + skipTo; 

    for(int i = skipTo; i < processChunk; i++){ 
     // convert to float format for processing 
     Float32 sampleFloat = (Float32)bytes[i]; 
     sampleFloat = sampleFloat/32768.0; 
     // This is where I would change the amplitude of the sample 
     // sampleFloat = sampleFloat + (sampleFloat * 0.5); 

     // make sure not clipping 
     if (sampleFloat > 1.0){ 
      sampleFloat = 1.0; 
     } else if (sampleFloat < -1.0){ 
      sampleFloat = -1.0; 
     } 

     // convert back to SInt16 
     sampleFloat = sampleFloat * 32768.0; 
     if (sampleFloat > 32767.0){ 
      sampleFloat = 32767.0; 
     } else if (sampleFloat < -32768.0){ 
      sampleFloat = -32768.0; 
     } 

     bytes[i] = (SInt16)sampleFloat; 
    } 

    [newAudio appendBytes:bytes length:length]; 

    return newAudio; 

} 

在這個過程中我可能會出錯?它是從SInt16 - > float - > SInt16轉換樣本嗎?在轉換過程中和之後打印數據似乎表明這裏沒有任何問題。它似乎是在我將它打包回NSMutableData對象後,但我不太確定。

任何幫助表示讚賞。

編輯:我也想提及當我通過這個函數發送音頻,並將改變增益因子設置爲0,使得生成的波形與輸入相同時,沒有問題。波形出來看起來和聽起來完全一樣。只有當改變增益因子被設置爲實際改變樣本的值時。編輯2:我改變了代碼使用指針和類型轉換而不是memcpy()。將樣本的浮點表示乘以任何數字時,我仍然會得到奇怪的結果。當我用SInt16乘以一個整數的樣本時,我得到了正確的結果。這讓我相信我的問題在於我正在進行浮點運算的方式。有沒有人看到我用浮點等式評論過的可能導致錯誤的方程?

+0

你真的想要增加0.008 dB的增益?這不是很多。 – jaket 2014-10-20 05:29:34

+0

建議:真正重新調整代碼,可能需要三倍的語句。使用'memcpy()'不是訪問兩個字節的方式,只需要一個指針和一個轉換。更多的代碼意味着複雜。檢查數據是小的還是大的。 – zaph 2014-10-20 11:43:22

+0

增益0.008 dB的增益是任意的......我只是想要得到一個結果的任何數字,即使這個小數量導致了噪音。我已經檢查了數據的字節順序,並在編寫代碼時考慮了它。我會考慮使用一個指針和一個演員。謝謝 – 2014-10-20 12:39:03

回答

0

問題證明是Zaph暗指的排序問題。當我不在的時候,我以爲自己正在處理從大端到小端的轉換。現在,代碼如下:

-(NSMutableData *)normalizeAIFF:(AIFFAudio *)audio x1:(int)x1 x2:(int)x2{ 

    // obtain audio data bytes from AIFF object 
    SInt16 * bytes = (SInt16 *)[audio.ssndData bytes]; 
    NSUInteger length = [audio.ssndData length]; 

    NSMutableData *newAudio = [[NSMutableData alloc] init]; 

    // skip offset and blocksize in SSND data and proceed to user selected point 
    // For 16 bit, 44.1 audio, each second of sound data holds 88.2 thousand samples 
    int skipTo = 4 + (x1 * 88200); 
    int processChunk = ((x2 - x1) * 88200) + skipTo; 

    for(int i = skipTo; i < processChunk; i++){ 

     SInt16 sample = CFSwapInt16BigToHost(bytes[i]); 
     bytes[i] = CFSwapInt16HostToBig(sample * 0.5); 
    } 

    [newAudio appendBytes:bytes length:length]; 

    return newAudio; 

} 

的0.5增益的變化因素將發生改變,我仍然有關於在選擇振幅最大的樣本是否真的規範化的數據,但我有問題解決了。將新波形寫入文件時,它會聽起來像預期的那樣。