如何消除来自使用 iOS 中音频单元的套接字的音频中的噪音?

Posted

技术标签:

【中文标题】如何消除来自使用 iOS 中音频单元的套接字的音频中的噪音?【英文标题】:How to remove the noise from the audio coming from socket that uses audio unit in iOS? 【发布时间】:2016-11-21 09:46:07 【问题描述】:

我正在尝试播放来自套接字的音频。但是音频有更多的噪音(原始声音没有发出)

我正在使用单独的扬声器类,并希望过滤音频中的噪音。我的代码是

OSStatus WNSpeakerOutputProc(void* inRefCon, AudioUnitRenderActionFlags* ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList* ioData) 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    WNSpeakerAudioData speakerAudioData;
    speakerAudioData.outBuffer = ioData->mBuffers[0].mData;
    speakerAudioData.outBufferSize = ioData->mBuffers[0].mDataByteSize;


    [[(WNSpeaker *)inRefCon dataSource] supplyAudioData:&speakerAudioData];
    [pool drain];
    return noErr;


请给点建议 谢谢

【问题讨论】:

【参考方案1】:

首先我想说的是,您不能只打开一个套接字并将数据直接通过管道传输到音频渲染中。您将需要缓冲一些最少量的数据以对数据进行去抖动处理。您使用的是 TCP 还是 UDP?如果是 UDP,你如何处理丢失的数据包。 通常,您不想在音频回调中做任何缓慢的事情。我强烈建议删除 AutoReleasePool 创建和排空。

我还建议将数据从源中深度复制到函数内部的 ioData 中,而不是调用选择器 supplyAudioData。

如果您提供 WNSpeaker 的详细信息会更有帮助。它应该将数据从您的源复制到目标地址 ioData->mBuffers[0].mData 它应该根据 inNumberFrames 复制 n 个字节。

【讨论】:

【参考方案2】:

详细了解音频单元的构建代码

-(void) setupAudioUnit

    AudioComponentDescription desc;
    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;

    AudioComponent comp = AudioComponentFindNext(NULL, &desc);

    OSStatus status;

    status = AudioComponentInstanceNew(comp, &_audioUnit);

    if(status != noErr)
    
        NSLog(@"Error creating AudioUnit instance");
    

    //  Enable input and output on AURemoteIO
    //  Input is enabled on the input scope of the input element
    //  Output is enabled on the output scope of the output element

    UInt32 one = 1;

    status = AudioUnitSetProperty(_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &one, sizeof(one));


    if(status != noErr)
    
        NSLog(@"Error enableling AudioUnit output bus");
    

    // Explicitly set the input and output client formats
    // sample rate = 44100, num channels = 1, format = 16 bit int point

    AudiostreamBasicDescription audioFormat = [self getAudioDescription];

    status = AudioUnitSetProperty(_audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &audioFormat, sizeof(audioFormat));

    if(status != noErr)
    
        NSLog(@"Error setting audio format");
    

    AURenderCallbackStruct renderCallback;
    renderCallback.inputProc = OutputRenderCallback;
    renderCallback.inputProcRefCon = (__bridge void *)(self);

    status = AudioUnitSetProperty(_audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &renderCallback, sizeof(renderCallback));

    if(status != noErr)
    
        NSLog(@"Error setting rendering callback");
    

    // Initialize the AURemoteIO instance
    status = AudioUnitInitialize(_audioUnit);

    if(status != noErr)
    
        NSLog(@"Error initializing audio unit");
    


- (AudioStreamBasicDescription)getAudioDescription 
    AudioStreamBasicDescription audioDescription = 0;
    audioDescription.mFormatID          = kAudioFormatLinearPCM;
    audioDescription.mFormatFlags       = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagsNativeEndian;
    audioDescription.mChannelsPerFrame  = 1;
    audioDescription.mBytesPerPacket    = sizeof(SInt16)*audioDescription.mChannelsPerFrame;
    audioDescription.mFramesPerPacket   = 1;
    audioDescription.mBytesPerFrame     = sizeof(SInt16)*audioDescription.mChannelsPerFrame;
    audioDescription.mBitsPerChannel    = 8 * sizeof(SInt16);
    audioDescription.mSampleRate        = 8000.0;
    return audioDescription;

我使用 8000 采样率和 Voice_ProcessingIO 作为 ComponentSubType 但音频的回声(噪音)没有被取消 请检查这个。谢谢

【讨论】:

以上是关于如何消除来自使用 iOS 中音频单元的套接字的音频中的噪音?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用来自网络套接字的网络音频 API 流式传输音频块?

AEC ios 多音频单元图

在 iOS 中同时使用两个音频单元进行 I/O 是不是安全?

iOS Swift 从网络流中播放音频(aac)

如何在 iOS swift 中使用 UDP 套接字流式传输音频?

iOS 音频单元:啥时候需要使用 AUGraph?