Audio Queues

Nibbie
Posts: 2
Joined: 2009.04
Post: #106
hi folks,

i have a lot of short mp3 files in my app and i am using the GBMusicTrack for playing them (i want to develop for 2.0 and 2.1 as well, so i cant use AVAudioPlayer)

the code works most of the time but sometimes suddenly it crashes and a track stays in the memory and stays there until i "reboot" the device.
it happens really seldom (1:100) but i cant leave it like this anyway...

---------------------------
my steps in the code:
i am loading a mp3 file like this...
_BackgroundTrack = [[GBMusicTrack alloc] initWithPath:[[NSBundle mainBundle] pathForResource:filename ofType:@"mp3"]];

then i am playing it:
[_BackgroundTrack play];

and finally i close it:
[_BackgroundTrack close];

before i open the next mp3 and play it
---------------------------------

i also put a...
[_BackgroundTrack dealloc];
to the
- (void) dealloc - function of my App

are there any known problems with NSTimer?
i mean i can't even listen to audio files in the iPod App after it crashes... so it really stay in the memory and i have to reboot the device.

please help!!!! i have to get rid of this problem.

thx a lot
zreak
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #107
You really should be developing for the latest OS. Audio is notoriously buggy on earlier versions. I don't even know if Apple will allow you to release for earlier versions.

There are no known problems in relation to NSTimer.

Also, you should do:

[_BackgroundTrack close];

then:

[_BackgroundTrack release];
Quote this message in a reply
Nibbie
Posts: 2
Joined: 2009.04
Post: #108
but if i am developing on the newest OS, people who just have OS 2.0 on their device can't use my app, or am i wrong?
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #109
That is correct. My standard policy is to simply recommend users upgrade -- it's FREE.
Quote this message in a reply
Nibbie
Posts: 3
Joined: 2009.04
Post: #110
Hi Jake,

Great work on audio queuing made my life easier. I was wondering if you added any type of audio sessions code to the GMmusicTrack. I've been trying to add it in, but my AudioQueuePrime keeps messing up with after a phonecall, alarm. I am able to play the first track, I then remove the instance and play another mp3. It works fine until the phonecall or alarm goes off. Then I am able to play one more track, then silence. I am not able to use AVMediaPlayer as the company I'm developing for wants it to work off 2.1 only. Any help would be appreciated thank you.
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #111
It's up to you to set the audio session before using GBMusicTrack (and it is highly recommended that you do!). When you initialize the audio session (which you must do before calling any audio session routines), you'll probably want to register an interruption listener callback and pause everything when interrupted. Audio is pretty tough to get everything working just right with calls and iPod app and sleep, etc., and it was even tougher before 2.2.

Here's what you might do when setting up your audio session:

Code:
void interruptionListenerCallback(void *inUserData, UInt32 interruptionState)
{
    if (interruptionState == kAudioSessionBeginInterruption)
    {
        // Audio is my custom audio class which handles both Audio Queues and OpenAL
        [[Audio sharedAudio] suspend];
    }
    else if (interruptionState == kAudioSessionEndInterruption)
    {
        [[Audio sharedAudio] resume];
    }
}

- (void)AppInitialize
{
    AudioSessionInitialize(nil, nil, interruptionListenerCallback, self);
    ...
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #112
Also, you should probably check out this other thread for related issues when setting the audio session.
Quote this message in a reply
Nibbie
Posts: 3
Joined: 2009.04
Post: #113
Hi Jake,

Thank you for the quick reply. I forgot to post the code, right now I'm initializing the audio session right away in the int main();

Code:
    OSStatus result =AudioSessionInitialize(NULL, NULL,interruptionListener, NULL);

This is my code for the interruption listener

Code:
void interruptionListener(    void *    inClientData,
                          UInt32    inInterruptionState)
{
    
    GBMusicTrack* song =Antic::getsong();
    if (inInterruptionState == kAudioSessionBeginInterruption) {          // 4
        
    
        [song pause];
        
    }
    
    else if ((inInterruptionState == kAudioSessionEndInterruption) )
    {
        
        UInt32 category = kAudioSessionCategory_MediaPlayback;
        AudioSessionSetProperty ( kAudioSessionProperty_AudioCategory, sizeof (category), &category );
    
         category = kAudioSessionCategory_AmbientSound;
        AudioSessionSetProperty ( kAudioSessionProperty_AudioCategory, sizeof (category), &category );
        
        // Reactivate the current audio session
        AudioSessionSetActive(YES);
        [song play];
        
        //    [song play];
        //Antic::objc_bgMusic("play","BG_Main");    
        
    }
    
    
}

The error code that I received is from the
Code:
OSStatus result= AudioQueuePrime(queue, 1, nil);


the result code when the error runs is 560030580
It seems the buffer is not getting cleared. I tried stopping and reloading the queue. Any ideas, thx I really appreciate it since I'm on a dead line,
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #114
Hmm... I can't remember for sure if the phone ring is actually an interruption or if it generates a resignActive notification. Have you checked to see for sure that the interruption callback is indeed being called? If so, have you tried completely releasing the track and then re-initializing a new one when the interruption ends? Stopping might not be enough.

I noticed that you aren't calling AudioSessionSetActive(NO); under kAudioSessionBeginInterruption.

I don't know what the specific result codes from AudioQueuePrime mean.

If the interruption callback isn't being called, then be sure to register for UIApplicationWillResignActiveNotification and UIApplicationDidBecomeActiveNotification and handle the music and audio session stop/start there.
Quote this message in a reply
Nibbie
Posts: 3
Joined: 2009.04
Post: #115
Thank you for the help, and quick responses.. I managed to get it to work out of the blue.
The result code I gave above was for overflow.

This is what my new code looks like if anyone needs an example.


Code:
void interruptionListener(    void *    inClientData, UInt32    inInterruptionState)
{
    
    GBMusicTrack* song =Antic::getsong();
    if (inInterruptionState == kAudioSessionBeginInterruption) {          // 4
        
    
        [song pause];
        AudioSessionSetActive(NO);
        // set the current context to NULL will 'shutdown' openAL
        alcMakeContextCurrent(NULL);
        // now suspend your context to 'pause' your sound world
        alcSuspendContext(mContext);        
        
    }
    
    else if ((inInterruptionState == kAudioSessionEndInterruption) )
    {
        
        UInt32 category = kAudioSessionCategory_MediaPlayback;
        AudioSessionSetProperty ( kAudioSessionProperty_AudioCategory, sizeof (category), &category );
    
         category = kAudioSessionCategory_AmbientSound;
        AudioSessionSetProperty ( kAudioSessionProperty_AudioCategory, sizeof (category), &category );
        
        // Reactivate the current audio session
        AudioSessionSetActive(YES);
        [song play];
        
        //    [song play];
        //Antic::objc_bgMusic("play","BG_Main");    
        
        // Reset audio session
         category = kAudioSessionCategory_AmbientSound;
        AudioSessionSetProperty ( kAudioSessionProperty_AudioCategory, sizeof (category), &category );
        
        // Reactivate the current audio session
        AudioSessionSetActive(YES);
        
        // Restore open al context
        alcMakeContextCurrent(mContext);
        // 'unpause' my context
        alcProcessContext(mContext);
        
        
    }
    
    
}


I'm actually not sure if it was setting the audio session to not, or adding my openal code to it, since I did both at the same time. Stepping through with debug I did find that the alerts were getting called as interruptions.
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #116
Yeah, that looks about right. Great to see you got it fixed!

I'd generalize it a bit and put the suspend and resume stuff in two other methods though, since you'll want to use them again for app resign and become active. The interrupt callback I showed above does essentially the same thing as yours, but I packaged it up to be called in my Audio class for this purpose: iPod Touch users can double-click on the home button to bring up a dialog to play their iPod music, which can freeze the device if played at the same time as Audio Queues being in use. I think on iPhone it might bring up contacts or something else (I have an iPod Touch, not an iPhone, so I don't recall). Nasty little detail...
Quote this message in a reply
Nibbie
Posts: 2
Joined: 2009.04
Post: #117
First of all, tq for the code AnotherJake, it works like a charm. Now is that any chance you going to add feature like speed up the music track?

I'm making a game for iphone and i was hoping to do something like speed up the background music to 1.5x or 2.0x for intense atmosphere when player is losing a lot of hp and about to game over.

Im trying to write the code myself but then im a noob in programming... i can only squeeze my brain cells to understand other people's code and use them in my game.. Wacko

So if you can find in your spare time to come up with speed up feature ill be very grateful. orz
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #118
Hi teoh1979,

Unfortunately, I don't think Audio Queues was designed with that feature in mind. It's mainly just used as a simple (if you can call it that) method for playback and recording. As such, more advanced features like pitch and time shifting aren't included in the API. You'd have to look into a lower level audio API, which is more than likely even more difficult to work with than Audio Queues. If you find an easy way to do it though, please let us know! Smile
Quote this message in a reply
Nibbie
Posts: 2
Joined: 2009.04
Post: #119
/sigh

i already have a hunch that it wont happen when i read through your code.. just thought i give it try by asking.

anyway thanks for the reply so soon. and thx again for the code you done. Smile
Quote this message in a reply
Nibbie
Posts: 2
Joined: 2009.04
Post: #120
AnotherJake: Thanks so much for that GBMusicTrack code! I've been searching for a while for a comprehensible example of how to use AudioQueue, as I wasn't very successful in altering the SpeakHere example for my uses. I'm going to use your code to figure out just how this baby works. I can't stand it that I don't understand. So, this is just me expressing my gratitude. Smile
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Core Audio mutlichannel audio tachyon 2 6,338 Mar 18, 2005 01:04 AM
Last Post: tachyon