我在使用 AudioUnits 的应用程序中遇到问题。所有应用程序的音频(包括未通过 AudioUnits 播放的音频)将在退出 Springboard 并返回应用程序后开始跳过。
我将问题分解为一个新的单独测试应用程序。以下是重复它的步骤:
- 使用 AVAudioPlayer 开始播放音频文件。
- 创建、删除,然后再创建一个 AudioUnit
- 退出跳板
- 返回应用程序
- 来自 AvAudioPlayer 的音频将开始跳过
这是我使用的一些代码:
- (IBAction)restartAudioUnit {
MySoundStream* audioUnitClass;
audioUnitClass = Load();
[audioUnitClass release];
audioUnitClass = Load();
}
请原谅冗长的代码转储,但 AudioUnits 很复杂,我很确定我只是设置它们或不正确地删除它们。
MySoundStream 类:
OSStatus UnitRenderCB(void* pRefCon, AudioUnitRenderActionFlags* flags, const AudioTimeStamp* timeStamp, UInt32 busNum, UInt32 numFrames, AudioBufferList* pData){
OSStatus tErr = noErr;
//Do Nothing
return tErr;
}
@implementation MySoundStream
-(void) dealloc {
[self Unload];
[super dealloc];
}
-(void) Unload {
OSStatus tErr = noErr;
tErr = AudioUnitUninitialize(OutUnit);
}
@end
MySoundStream* Load()
{
OSStatus tErr = noErr;
AudioComponentInstance tRIO;
AudioComponentDescription tRIOCD;
AURenderCallbackStruct tRIOCB;
AudioStreamBasicDescription tAUF;
tRIOCD.componentType = kAudioUnitType_Output;
tRIOCD.componentSubType = kAudioUnitSubType_RemoteIO;
tRIOCD.componentManufacturer = kAudioUnitManufacturer_Apple;
tRIOCD.componentFlags = 0;
tRIOCD.componentFlagsMask = 0;
AudioComponent tRIOC = AudioComponentFindNext(NULL, &tRIOCD);
tErr = AudioComponentInstanceNew(tRIOC, &tRIO);
if (tErr != noErr) return NULL;
int tOutEnable = 1;
tErr = AudioUnitSetProperty(tRIO, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &tOutEnable, sizeof(tOutEnable));
if (tErr != noErr) return NULL;
tAUF.mSampleRate = 44100.00;
tAUF.mFormatID = kAudioFormatLinearPCM;
tAUF.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
tAUF.mFramesPerPacket = 1;
tAUF.mChannelsPerFrame = 2;
tAUF.mBitsPerChannel = 16;
tAUF.mBytesPerPacket = 4;
tAUF.mBytesPerFrame = 4;
tErr = AudioUnitSetProperty(tRIO, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &tAUF, sizeof(tAUF));
if (tErr != noErr) return false;
MySoundStream* pRet = [MySoundStream alloc];
tRIOCB.inputProc = UnitRenderCB;
tRIOCB.inputProcRefCon = pRet;
tErr = AudioUnitSetProperty(tRIO, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &tRIOCB, sizeof(tRIOCB));
if (tErr != noErr){ delete pRet; return NULL; }
tErr = AudioUnitInitialize(tRIO);
if (tErr != noErr){ delete pRet; return NULL; }
pRet->OutUnit = tRIO;
return pRet;
}
如果有人能看到我对这个 AudioUnit 做错了什么,那将非常有帮助。
编辑:上传完整的源代码。这里
- 按播放声音(可能需要耳机)
- 按重启AudioUnit
- 返回跳板
- 重新进入 TestAudioUnit 应用程序
音频将跳过