问题
I have a problem in my applications where I am using AudioUnits. All of the applications Audio (including audio not played through AudioUnits) will start skipping after exiting to Springboard and returning to the applications.
I broke out the problem into a new separate test app. Here are the steps to repeat it:
- Start an Audio file playing using an AVAudioPlayer.
- Create, Delete, then again Create an AudioUnit
- Exit to Springboard
- Return to the app
- The Audio from the AvAudioPlayer will start skipping
Here is some of the code I used:
- (IBAction)restartAudioUnit {
MySoundStream* audioUnitClass;
audioUnitClass = Load();
[audioUnitClass release];
audioUnitClass = Load();
}
Forgive the long code dump but AudioUnits are complex and I am fairly sure I am just setting them up or taking them down incorrectly.
The MySoundStream class:
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;
}
If anyone can see anything I am doing wrong with this AudioUnit, that woudl be very helpful.
Edit: Upload the complete source. Here
- Press Play Sound (may need headphones)
- Press RestartAudioUnit
- Return to Springboard
- Re-enter TestAudioUnit app
Audio will skip
回答1:
You are calling AudioUnitInitialize()
when the app is re-initialized, which is not good. You need to call AudioUnitInitialize()
only once when your app starts, and you should not have to build the entire AU graph every time your app enters the foreground.
回答2:
Switched to using an AUGraph to setups my Audio Unit path and I had better luck.
来源:https://stackoverflow.com/questions/6130443/audiounits-causing-universal-skipping-after-returning-from-springboard