2011-11-15 112 views
0

我有一個應用程序,我使用Core Audio進行錄音。聲音是由某些部分製作的,然後必須保存到設備中。它工作正常,但在一些新的ios版本中,我在輸出文件中產生了一些噪音,如失真。可能的原因是什麼? ExtAudioFileCreateWithURL用於創建輸出文件並使用ExtAudioFileSetProperty來設置其屬性。 任何幫助將不勝感激。錄音後ios 4.3.x和5.0中的聲音噪音

此代碼由另一位當前不可用的程序員創建,所以我不知道爲什麼這樣的黑客已經實現。

static BOOL shouldFixData = NO; 
    static int checkOnce = 1; 
    if (checkOnce) { 
     checkOnce = 0; 
     if (inNumberFrames * 8 == ioData->mBuffers[0].mDataByteSize) { 
      shouldFixData = YES; 
     } 
    } 

    if (shouldFixData) { 
     AudioBufferList cutData = {0}; 
     cutData.mNumberBuffers = 1; 
     cutData.mBuffers[0].mNumberChannels = ioData->mBuffers[0].mNumberChannels; 
     cutData.mBuffers[0].mDataByteSize = ioData->mBuffers[0].mDataByteSize/2; 
     cutData.mBuffers[0].mData = malloc(cutData.mBuffers[0].mDataByteSize); 

     SInt32* oldData = (SInt32*)ioData->mBuffers[0].mData; 
     SInt32* newData = (SInt32*)cutData.mBuffers[0].mData; 
     int count = cutData.mBuffers[0].mDataByteSize/4; 
     for (int i = 0; i < count; ++i) { 
      newData[i] = oldData[i*2]; 
     } 

     ExtAudioFileWriteAsync(userData->outputFile, inNumberFrames, &cutData); 
     free(cutData.mBuffers[0].mData); 
    } else { 
     ExtAudioFileWriteAsync(userData->outputFile, inNumberFrames, ioData); 
    } 
} 

保存記錄:針對不同版本的IOS創建

方式聲音緩衝

CAStreamBasicDescription dstFormat; 
     dstFormat.mSampleRate = mOutputFormat.mSampleRate; 
     dstFormat.mFormatID = kAudioFormatLinearPCM;    
     dstFormat.mChannelsPerFrame = 2; 
     dstFormat.mBitsPerChannel = 16; 
     dstFormat.mBytesPerPacket = 2 * dstFormat.mChannelsPerFrame; 
     dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame; 
     dstFormat.mFramesPerPacket = 1; 
     dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; 

     //recordInfo.output file is ExtAudioFileRef 

     err = ExtAudioFileCreateWithURL((CFURLRef)recordFileURL, kAudioFileWAVEType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &recordInfo.outputFile); 
     if (err) { printf("ExtAudioFileCreateWithURL result %ld %08X %4.4s\n", err, (unsigned int)err, (char*)&err); return; } 

     NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 
     NSComparisonResult versionCompareRes = [currSysVer compare:@"4.3" options:NSNumericSearch]; 
     if (versionCompareRes == NSOrderedSame || versionCompareRes == NSOrderedDescending) { 
//for new versions 
      err = ExtAudioFileSetProperty(recordInfo.outputFile, kExtAudioFileProperty_ClientDataFormat, sizeof(mOutputFormat), &mOutputFormat); 
      if (err) { printf("ExtAudioFileSetProperty result %ld %08X %4.4s\n", err, (unsigned int)err, (char*)&err); return; } 
     } else { 
      //for old versions 
      err = ExtAudioFileSetProperty(recordInfo.outputFile, kExtAudioFileProperty_ClientDataFormat, sizeof(dstFormat), &dstFormat); 
      if (err) { printf("ExtAudioFileSetProperty result %ld %08X %4.4s\n", err, (unsigned int)err, (char*)&err); return; } 
     } 

樣本輸出文件: output.mp3

+0

郵政爲例剪輯。 – Brad

+0

更新了一些代碼 –

+0

發佈示例** sound **剪輯。這可能與代碼沒有任何關係,我想聽聽它的發現。 – Brad

回答

0

哎呀..應該是反饋。對不起..

在您發佈的代碼的主要區別是格式設置 的sizeof(mOutputFormat),& mOutputFormat 其中mOutputFormat沒有規定如何它集。

與設置的舊版本的dst格式相比較。

設置 「錯誤」 的格式通常給人不好的聲音:-)

+0

它已初始化,但我忘記發佈它。 'mOutputFormat.SetAUCanonical(2,false); \t \t \t \t \t \t mOutputFormat.mSampleRate = kGraphSampleRate;' 我會看這個方向發展,謝謝。 –

+0

還沒有檢查,但似乎是在正確的方向。 –

1

你可以使用SPEEX做去噪,包括speex_preprocess.h第一:

SpeexPreprocessState *_spt = speex_preprocess_state_init(NN, 16000);/NN is 320 for sampleRate 16000. 
int i=1; 
speex_preprocess_ctl(_spt, SPEEX_PREPROCESS_SET_DENOISE, &i); 

-(BOOL)doConvert:(void *)data SampleLength:(SInt64)length 
{ 
    AudioBufferList *dataBuffer = (AudioBufferList*)data; 
    AudioSampleType *samples = (AudioSampleType*)dataBuffer->mBuffers[0].mData; 

    SInt64 count = length/NN; 
    //short sample_ground[count][NN]; 

    short **sample_group; 
    sample_group = (short**)malloc(sizeof(short*)*count); 
    for (int i=0; i<count; i++) 
     sample_group[i] = (short*)malloc(sizeof(short)*NN); 

    for (int i = 0; i < count; i++) { 
     for (int j = 0 ; j < NN; j++) { 
      short value = samples[i*NN+j]; 
      sample_group[i][j] = value; 
     } 
    } 
    for (int i = 0; i < count; i++) { 
     speex_preprocess_run(_spt, sample_group[i]); 
    } 
    for (int i = 0; i < count; i++) { 
     for (int j = 0 ; j < NN; j++) { 
      samples[i*NN+j] = sample_group[i][j]; 
     } 
    } 

    for (int i=0; i<count; i++) 
     free(sample_group[i]); 
    free(sample_group); 

    return YES; 
}