1

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

编辑:上传完整的源代码。这里

  1. 按播放声音(可能需要耳机)
  2. 按重启AudioUnit
  3. 返回跳板
  4. 重新进入 TestAudioUnit 应用程序

音频将跳过

4

2 回答 2

1

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

于 2011-06-03T09:39:28.460 回答
0

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

于 2011-11-01T16:11:49.337 回答