从Springboard返回后导致通用跳过的AudioUnit

时间:2011-05-25 20:25:28

标签: iphone objective-c ios audiounit

我在使用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做错了什么,那将会非常有帮助。

编辑: 上传完整的来源。 Here

  1. 按Play Sound(可能需要耳机)
  2. 按RestartAudioUnit
  3. 返回跳板
  4. 重新输入TestAudioUnit app
  5. 音频将跳过

2 个答案:

答案 0 :(得分:1)

重新初始化应用时,您正在调用AudioUnitInitialize(),这不太好。您的应用启动时只需拨打一次AudioUnitInitialize(),每次应用进入前台时都不需要构建整个AU图。

答案 1 :(得分:0)

切换到使用AUGraph来设置我的音频单元路径,我运气更好。