录制后ios 4.3.x和5.0中的声音噪音

时间:2011-11-15 04:33:00

标签: iphone ios core-audio audio

我有一个应用程序,我使用Core Audio进行录音。声音由某些声部组成,然后必须保存到设备中。它工作正常,但在一些新的ios版本中,我在输出文件中有一个噪音,如失真。可能的原因是什么? ExtAudioFileCreateWithURL用于创建输出文件,ExtAudioFileSetProperty用于设置其属性。 任何帮助将不胜感激。

此代码是由另一位目前无法使用的程序员创建的,因此我不知道为何会实施此类攻击。

为不同版本的ios创建声音缓冲区的方式:

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);
    }
}

保存记录:

 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

2 个答案:

答案 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;
}

答案 1 :(得分:0)

oops ..应该是反馈。抱歉..

您发布的代码的主要区别在于格式设置 sizeof(mOutputFormat),&amp; mOutputFormat 其中mOutputFormat未指定其设置方式。

与设置的旧版本的dst格式进行比较。

设置“错误”格式通常会产生不良声音: - )