Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
834 views
in Technique[技术] by (71.8m points)

iphone - AudioUnits causing universal skipping after returning from Springboard

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...