从 Springboard 返回后导致通用跳过的 AudioUnits
Posted
技术标签:
【中文标题】从 Springboard 返回后导致通用跳过的 AudioUnits【英文标题】:AudioUnits causing universal skipping after returning from Springboard 【发布时间】:2011-05-25 20:25:28 【问题描述】:我在使用 AudioUnits 的应用程序中遇到问题。所有应用程序的音频(包括未通过 AudioUnits 播放的音频)将在退出 Springboard 并返回应用程序后开始跳过。
我将问题分解为一个新的单独测试应用程序。以下是重复它的步骤:
使用 AVAudioPlayer。 创建、删除,然后再创建一个 音频单元 退出跳板 返回应用 来自 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 做错了什么,那将非常有帮助。
编辑: 上传完整的源代码。 Here
-
按播放声音(可能需要耳机)
按重启AudioUnit
返回跳板
重新进入 TestAudioUnit 应用
音频将跳过
【问题讨论】:
【参考方案1】:当应用程序重新初始化时,您正在调用AudioUnitInitialize()
,这不好。您只需在您的应用启动时调用一次AudioUnitInitialize()
,并且您不必在每次应用进入前台时都构建整个 AU 图。
【讨论】:
对不起,如果我不清楚。我调用 AudioUnitInitialize,然后是 Uninit,然后在应用程序运行时再次调用 Init。好像我正在关闭单元,重新配置它,然后重新启动它。这是不允许的吗?然后在重新配置后我退出到 Spring 并返回,没有调用 AudioUnit 任何东西。 我可能在调查此问题时发现了我的错误。有一个我没有调用的 AudioSessionInitialize,文档说应该调用一次,然后再也不会调用,这就是你所指的吗? 在更新中添加了源,正在调用 AudioSessionInitialize。 @TurqMage 是的,您应该只在程序的初始化中调用 AudioSessionInitialize 一次。多次调用它(即,当您的应用程序进入前台或重新启动音频子系统时)并不好。在您的委托中使用didFinishLaunchingWithOptions
对其进行一次调用,而不是其他任何地方。【参考方案2】:
改用 AUGraph 来设置我的音频单元路径,我的运气更好。
【讨论】:
以上是关于从 Springboard 返回后导致通用跳过的 AudioUnits的主要内容,如果未能解决你的问题,请参考以下文章