iphone - ios 4.3.x 和 5.0 录音后声音中有噪音

标签 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

最佳答案

您可以使用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;
}

关于iphone - ios 4.3.x 和 5.0 录音后声音中有噪音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8131531/

相关文章:

ios - 如果可用,将项目添加到特定 TableView 行

ios - 从 installTapOnBus 闭包中访问类属性

iphone - 根据配置更改显示名称

iphone - 从 NSObject 类获取 NSMutableArray 到 UIViewController 类时的内存管理

iphone - 在 UITableView 之上覆盖 View

macos - 在 Catalina 上,coreaudiod 始终保持在 12.5% 左右的 CPU

macos - 核心音频 : What is "AudioBox" as contrasted to "AudioDevice"

ios - 将数据从一个 ViewController 发送到另一个。

ios - 将字符串格式化为 HH :mm in Swift

ios - 在移动到登录屏幕之前在欢迎屏幕中显示视频