[TAAE2] Background playing of audio
Could anyone point me to the proper pattern for leveraging TAAE2 for background audio?
I was hoping to move away from AudioQueue to TAAE2 for a music app i'm refactoring, but it seems that i've lost my ability to play music in the background.
For my AudioQueue Implementation, I spawned off a separate thread to render the audio, then AudioQueue's callback mechanism would read from an array of buffers.
Do i need to do something similar with TAAE2?
FWIW, my block of code is here, in case anyone can spot what i'm doing wrong. Thanks
- (NSDictionary *) initializeSound:(NSString *)path {
if (self.modPlayer) {
[self pause];
}
else {
self.modPlayer = [[MC_OMPT alloc] init];
}
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession setPreferredIOBufferDuration:audioSession.sampleRate error:NULL];
[audioSession setActive:YES error:nil];
NSError *activationError = nil;
BOOL success = [audioSession setActive:YES error:&activationError];
if (!success) {
/* handle the error condition */
NSLog(@"Dafuq?");
}
self.modInfo = [self.modPlayer loadFile:path];
NSArray *pathParts = [path componentsSeparatedByString:@"/"];
self.loadedFileName = [pathParts objectAtIndex:[pathParts count] - 1];
AERenderer *renderer = [AERenderer new];
self.output = [[AEAudioUnitOutput alloc] initWithRenderer:renderer];
lastPattern = -1;
lastRow = -1;
renderer.block = ^(const AERenderContext * _Nonnull context) {
AEBufferStack *bufferStack = context->stack;
const AudioBufferList * bufferList = AEBufferStackPushWithChannels(bufferStack, 1, 2);
if ( !bufferList ) {
return;
}
float *leftBuffer = (float*)bufferList->mBuffers[0].mData,
*rightBuffer = (float*)bufferList->mBuffers[1].mData;
int32_t *currentStep = [self.modPlayer fillLeftBuffer:leftBuffer
withRightBuffer:rightBuffer
withNumFrames:context->frames];
int currentPattern = currentStep[1],
currentRow = currentStep[2];
if (lastPattern != currentPattern || lastRow != currentRow) {
int32_t playerState[4];
playerState[0] = currentStep[0];
playerState[1] = currentStep[1];
playerState[2] = currentStep[2];
playerState[3] = currentStep[3];
[self notifyInterface:playerState];
}
AERenderContextOutput(context, 1);
};
return self.modInfo;
}
Comments
Ugh. forgot to add:
Issue resolved.
That'll do it
For the record, if anyone else is curious: you need to make sure background audio is enabled via the Info.plist (select app target in Xcode, Capabilities tab, Background Modes, check Audio). If at some point you actually want to stop the audio, you need to stop the output when moving into the background, from either the app delegate or via a
UIApplicationWillEnterBackgroundNotification
handler.Also, in case anyone runs into this similar issue,
The "Play" button on CommandCenter won't show up when you have TAAE2 write to the sound card. So, you have to tell InfoCenter that you're playing audio.
For me, setting
MPNowPlayingInfoPropertyPlaybackRate
to@1.0f
when audio is playing worked.The solution for me was to stop TAAE before activating AVAudioSession.
I thought I could just set TAAE's
setAudioSessionCategory
toAVAudioSessionCategoryPlayback
andsetAllowMixingWithOtherApps
toNO
but that doesn't seem to be enough!