如何消除来自使用 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 中音频单元的套接字的音频中的噪音?的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS 中同时使用两个音频单元进行 I/O 是不是安全?