c – iOS:如何在运行时使用音频单元重新采样音频(PCM数据)?
发布时间:2020-12-16 07:13:38 所属栏目:百科 来源:网络整理
导读:如何在运行时/现场使用音频单元重新采样音频(PCM数据)? 我有一个音频单元设置如下. - (void) setUpAudioUnit { OSStatus status; AudioComponentInstance audioUnit; AudioComponent inputComponent; AudioComponentDescription audioComponentDescription;
如何在运行时/现场使用音频单元重新采样音频(PCM数据)?
我有一个音频单元设置如下. - (void) setUpAudioUnit { OSStatus status; AudioComponentInstance audioUnit; AudioComponent inputComponent; AudioComponentDescription audioComponentDescription; AudioStreamBasicDescription audioStreamBasicDescription; // Describe audio component audioComponentDescription.componentType = kAudioUnitType_Output; audioComponentDescription.componentSubType = kAudioUnitSubType_VoiceProcessingIO; audioComponentDescription.componentFlags = 0; audioComponentDescription.componentFlagsMask = 0; audioComponentDescription.componentManufacturer = kAudioUnitManufacturer_Apple; // Get component inputComponent = AudioComponentFindNext(NULL,&audioComponentDescription); // Get audio units status = AudioComponentInstanceNew(inputComponent,&audioUnit); checkStatus(status); // Enable IO for recording UInt32 flag = 1; status = AudioUnitSetProperty(audioUnit,kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Input,kInputBus,&flag,sizeof(flag)); checkStatus(status); // Enable IO for playback status = AudioUnitSetProperty(audioUnit,kAudioUnitScope_Output,kOutputBus,sizeof(flag)); checkStatus(status); // Describe format audioStreamBasicDescription.mSampleRate = AUDIO_SAMPLE_RATE; audioStreamBasicDescription.mFormatID = kAudioFormatLinearPCM; audioStreamBasicDescription.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; audioStreamBasicDescription.mFramesPerPacket = AUDIO_FRAMES_PER_PACKET; audioStreamBasicDescription.mChannelsPerFrame = AUDIO_CHANNELS_PER_FRAME; audioStreamBasicDescription.mBitsPerChannel = AUDIO_BITS_PER_CHANNEL; audioStreamBasicDescription.mBytesPerPacket = AUDIO_BYTES_PER_PACKET; audioStreamBasicDescription.mBytesPerFrame = AUDIO_BYTES_PER_FRAME; // Apply format status = AudioUnitSetProperty(audioUnit,kAudioUnitProperty_StreamFormat,&audioStreamBasicDescription,sizeof(audioStreamBasicDescription)); checkStatus(status); /* Make sure we set the correct audio category before restarting */ UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; status = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,sizeof(audioCategory),&audioCategory); checkStatus(status); status = AudioUnitSetProperty(audioUnit,sizeof(audioStreamBasicDescription)); checkStatus(status); // Set input callback AURenderCallbackStruct callbackStruct; callbackStruct.inputProc = recordingCallback; callbackStruct.inputProcRefCon = (__bridge void *)(self); status = AudioUnitSetProperty(audioUnit,kAudioOutputUnitProperty_SetInputCallback,kAudioUnitScope_Global,&callbackStruct,sizeof(callbackStruct)); checkStatus(status); // Set output callback callbackStruct.inputProc = playbackCallback; callbackStruct.inputProcRefCon = (__bridge void *)(self); status = AudioUnitSetProperty(audioUnit,kAudioUnitProperty_SetRenderCallback,sizeof(callbackStruct)); checkStatus(status); // Disable buffer allocation for the recorder (optional - do this if we want to pass in our own) flag = 0; status = AudioUnitSetProperty(audioUnit,kAudioUnitProperty_ShouldAllocateBuffer,sizeof(flag)); } 音频设置如下. kOutputBus 0 kInputBus 1 AUDIO_SAMPLE_RATE 44100 AUDIO_FRAMES_PER_PACKET 1 AUDIO_CHANNELS_PER_FRAME 1 AUDIO_BITS_PER_CHANNEL 16 AUDIO_BYTES_PER_PACKET 2 AUDIO_BYTES_PER_FRAME 2 我正在接收录制回调的PCM数据 audioBufferList->mBuffers[0].mData 那么,我如何将这个PCM数据从44.1KHz重新采样到8KHz,反之亦然? 找到这些线程,但这些都没有提供明确的指示. > Which built in AudioUnit can resample audio? 任何代码示例或信息都非常受欢迎. 解决方法
转换器音频单元将处理您的采样率转换.我发现解决这个问题的最佳方法是让您的链条适应硬件本身的功能.这意味着您应该获得系统AudioStreamBasicDescription(sysASBD),然后将转换器单元放在系统和链的需要不同的部分之间.因此,对于使用8K sampleRate进行音频播放,您可以这样做:ReomoteIO(mic) – >转换器 – > your8Kprocessing – >转换器 – > RemoteIO(出来).
以下是转换器的说明. AudioComponentDescription convDesc; convDesc.componentType = kAudioUnitType_FormatConverter; convDesc.componentSubType = kAudioUnitSubType_AUConverter; convDesc.componentFlags = 0; convDesc.componentFlagsMask = 0; convDesc.componentManufacturer = kAudioUnitManufacturer_Apple; 以下是如何获得ASBDin和ASBDout系统的方法 UInt32 sizeASBD = sizeof(AudioStreamBasicDescription); AudioStreamBasicDescription ioASBDin; AudioStreamBasicDescription ioASBDout; AudioUnitGetProperty(remoteIO,1,&ioASBDin,&sizeASBD); AudioUnitGetProperty(remoteIO,&ioASBDout,&sizeASBD); 使用转换器所需要做的就是设置输入ASBD并输出ASBD到所需的格式,它完成所有工作.让你的联系和你的8K游戏. AudioStreamBasicDescription asbd8K; AudioComponentInstance converter44To8; AudioUnitSetProperty(converter44To8,& ioASBDin,sizeof(AudioStreamBasicDescription)); AudioUnitSetProperty(converter44To8,&asbd8K,sizeof(AudioStreamBasicDescription)); AudioComponentInstance converter8To44; AudioUnitSetProperty(converter8To44,sizeof(AudioStreamBasicDescription)); AudioUnitSetProperty(converter8To44,& ioASBDout,sizeof(AudioStreamBasicDescription)); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐
- ios – SKSpriteNode zrotation M_PI令人愤怒
- IT 领域特殊词汇的发音
- 由include、extend的关系联想到组合、聚合的关系
- ruby-on-rails – Rails – 如何在手动sass编译中
- xml – HttpUtility.HtmlDecode在WinRT中
- xcode – 我可以找到主动登录的GameCenter用户名
- iphone – Google Drive SDK和iOS 5.1
- xcode – OS X严重编码的应用程序仍然在没有警告
- ruby-on-rails – Rails 2.0:为什么不使用sqlit
- ORA-28000: the account is locked-的解决办法
热点阅读