AudioUnits causing universal skipping after returning from Springboard

巧了我就是萌 提交于 2019-11-28 10:59:15

问题


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

  1. Press Play Sound (may need headphones)
  2. Press RestartAudioUnit
  3. Return to Springboard
  4. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!