Welcome, Guest. Register Now!
   
Mark Forums Read Mark Forums Read Mark Forums Read


Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 09-14-2008, 06:52 PM
pm7 pm7 is offline
Member
 
Join Date: Aug 2008
Posts: 65
Default Streaming audio class

Here I'm.

I tried to adapt a code available in the SDK for OSX (some adaptations exist on the web, which helped much): afsclient

Here is the code.

Player: h file
Code:
#import <AudioToolbox/AudioQueue.h>
#import <AudioToolbox/AudioFileStream.h>


#define kNumAQBufs	3			// number of audio queue buffers we allocate
#define kAQMaxPacketDescs   128
#define kAQBufSize			1 * 1024

typedef enum {
	EAudioStateClosed,
	EAudioStateStopped,
	EAudioStatePlaying,
	EAudioStatePaused,
	EAudioStateSeeking
} EAudioState;


@interface MEPlayer : NSObject
{
	AudioFileStreamID				audioFileStream;
	AudioQueueRef					audioQueue;
	AudioQueueBufferRef				audioQueueBuffer[kNumAQBufs];
	AudioStreamPacketDescription	packetDescs[kAQMaxPacketDescs];
	
	NSURLConnection					*connection;
	NSURLRequest					*request;
	
	UInt64							fillBufferIndex;
	UInt32							bytesFilled;	
	UInt32							packetsFilled;
	
	UInt64							packetIndex;
	UInt32							numPacketsToRead;
	
	BOOL							inuse[kNumAQBufs];	
	BOOL							started;			
	BOOL							failed;	
	BOOL							repeat;
	BOOL							trackClosed;
	
	EAudioState						audioState;
}

- (void)init;
- (void)playUrl:(NSString*)url;
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data;
- (void)propertyChanged:(AudioFileStreamPropertyID)propertyID flags:(UInt32*)flags;
- (void)packetData:(const void*)data
   numberOfPackets:(UInt32)numPackets
	 numberOfBytes:(UInt32)numBytes
packetDescriptions:(AudioStreamPacketDescription*)packetDescriptions;

- (void)enqueueBuffer;
- (int)findQueueBuffer:(AudioQueueBufferRef)inBuffer;
- (void)outputCallbackWithBufferReference:(AudioQueueBufferRef)buffer;
- (void)close;
- (void)dealloc;

@end
Player: m file
Code:
#import "AudioClass.h"

void MyPropertyListenerProc(void *inClientData, AudioFileStreamID inAudioFileStream,AudioFileStreamPropertyID	inPropertyID, UInt32 * ioFlags)
{
	MEPlayer *player = (MEPlayer*)inClientData;
	[player propertyChanged:inPropertyID flags:ioFlags];
}

void MyPacketsProc(void *inClientData, UInt32 inNumberBytes, UInt32 inNumberPackets, const void * inInputData, AudioStreamPacketDescription	*inPacketDescriptions)
{
	MEPlayer *player = (MEPlayer*)inClientData;
	[player packetData:inInputData  numberOfPackets:inNumberPackets numberOfBytes:inNumberBytes packetDescriptions:inPacketDescriptions];
}

void MyAudioQueueOutputCallback(void *inClientData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
{
	MEPlayer *player = (MEPlayer*)inClientData;
	[player outputCallbackWithBufferReference:inBuffer];
}


@implementation MEPlayer

- (void)init {
	
	audioState	= EAudioStateStopped;
}

- (void)playUrl:(NSString*)url
{
	
	NSLog(@"playUrl");
	OSStatus err = AudioFileStreamOpen(self, MyPropertyListenerProc, MyPacketsProc, 0, &audioFileStream);
	if (!err) NSLog(@"AudioFileStreamOpen ok");
	else NSLog(@"AudioFileStreamOpen nok");
	
	request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
	connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
	
	if (connection)
		NSLog(@"connection created");
	else
		NSLog(@"connection failed");
}

- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
	OSStatus err = AudioFileStreamParseBytes(audioFileStream, [data length], [data bytes], 0);
	if (err) NSLog(@"AudioFileStreamParseBytes failed");
}

- (void)propertyChanged:(AudioFileStreamPropertyID)propertyID flags:(UInt32*)flags
{
	NSLog(@"found property '%c%c%c%c'\n", (propertyID>>24)&255, (propertyID>>16)&255, (propertyID>>8)&255, propertyID&255);
	
	OSStatus err = noErr;
	
	switch (propertyID)
	{
		case kAudioFileStreamProperty_ReadyToProducePackets:
		{
			AudioStreamBasicDescription asbd;
			UInt32 asbdSize = sizeof(asbd);
			
			err = AudioFileStreamGetProperty(audioFileStream,  kAudioFileStreamProperty_DataFormat, &asbdSize, &asbd);
			if (err) NSLog(@"get kAudioFileStreamProperty_DataFormat failed");
			
			err = AudioQueueNewOutput(&asbd, MyAudioQueueOutputCallback, self, NULL, NULL, 0, &audioQueue);
			if (err) NSLog(@"AudioQueueNewOutput failed");
			
			for (unsigned int i = 0; i < kNumAQBufs; i++)
				err = AudioQueueAllocateBuffer(audioQueue, kAQBufSize, &audioQueueBuffer[i]);
			break;
		}
	}
}

- (void)packetData:(const void*)data numberOfPackets:(UInt32)numPackets numberOfBytes:(UInt32)numBytes packetDescriptions:(AudioStreamPacketDescription*)packetDescriptions
{
	//NSLog(@"got data. bytes: %d, packets: %d", numBytes, numPackets);
	
	for (int i = 0; i < numPackets; i++)
	{
		SInt64 packetOffset = packetDescriptions[i].mStartOffset;
		SInt64 packetSize = packetDescriptions[i].mDataByteSize;
		
		size_t bufSpaceRemaining = kAQBufSize - bytesFilled;
		if (bufSpaceRemaining < packetSize) [self enqueueBuffer];
		
		AudioQueueBufferRef fillBuf = audioQueueBuffer[fillBufferIndex];
		memcpy((char*)fillBuf->mAudioData + bytesFilled, (const char*)data + packetOffset, packetSize);
		packetDescs[packetsFilled] = packetDescriptions[i];
		packetDescs[packetsFilled].mStartOffset = bytesFilled;
		bytesFilled += packetSize;
		packetsFilled += 1;
		
		size_t packetsDescsRemaining = kAQMaxPacketDescs - packetsFilled;
		if (packetsDescsRemaining == 0) [self enqueueBuffer];
	}
}

- (void)enqueueBuffer
{
	OSStatus err = noErr;
	inuse[fillBufferIndex] = true;
	
	AudioQueueBufferRef fillBuf = audioQueueBuffer[fillBufferIndex];
	fillBuf->mAudioDataByteSize = bytesFilled;
	err = AudioQueueEnqueueBuffer(audioQueue, fillBuf, packetsFilled, packetDescs);
	if (err) NSLog(@"AudioQueueEnqueueBuffer failed");
	
	if (!started)
	{
		err = AudioQueueStart(audioQueue, NULL);
		if (err) NSLog(@"AudioQueueStart failed");
		started = true;
		NSLog(@"started.");
		audioState	= EAudioStatePlaying;
	}
	
	if (++fillBufferIndex >= kNumAQBufs) fillBufferIndex = 0;
	bytesFilled = 0;
	packetsFilled = 0;
	
	NSLog(@"lock.");
	while (inuse[fillBufferIndex])
		NSLog(@"wait...");
	NSLog(@"unlock.");

	}

- (int)findQueueBuffer:(AudioQueueBufferRef)inBuffer
{
	for (unsigned int i = 0; i < kNumAQBufs; i++)
	{
		if (inBuffer == audioQueueBuffer[i]) return i;
	}
	return -1;
}

- (void)outputCallbackWithBufferReference:(AudioQueueBufferRef)buffer
{
	unsigned int bufIndex = [self findQueueBuffer:buffer];
	
	inuse[bufIndex] = false;
}

- (void)close
{
	// it is preferrable to call close first, before dealloc if there is a problem waiting for an autorelease
	audioState	= EAudioStateClosed;
	
	if (trackClosed) return;
	
	trackClosed = YES;
	AudioQueueStop(audioQueue, YES);
	AudioQueueDispose(audioQueue, YES);
	AudioFileStreamClose(audioFileStream);
	free(packetDescs);
	//packetDescs = nil;
}

- (void)dealloc
{
	[self close];
	[super dealloc];
}

@end
use in your app (I did a simple view app, and put this following code in the applicationDidFinishLaunching):
Code:
        NSLog(@"Url Init");
	NSString *myURL1 = [[NSString alloc] initWithString:@"http://download.mp3.com/user_audio/d4/3/4/0/0/21776386.mp3 "];

	NSLog(@"Player init");
	myPlayer = [[MEPlayer alloc] init];
	NSLog(@"Starting Player process");
	[myPlayer playUrl:myURL1];

This is a start for the class I wanted to write. I read and plays the track located on the web server (hope you will like the track )

Things have to be done to have something robust.

1) It is difficult to quit the app while the file is playing... I still don't know how to stop it when I want.

2) It does not have a "track buffer" to manage playlist

3) no seek method is available (should be interesting to get the current position to add a "progress bar" in the app so that it is possible to move in the song.

4) no resume method is yet implemented (in case the connection goes down for a little)

5) no volume method is available.

6) could also be interesting to get audio data to display the wave in real time or an equalizer with the FFT.

7) no notifications are available regarding the status of the playing track: started, ended. This should be necessary for example to play a next song when the current one has ended.

So, I'd love to work with anybody to help me to improve this, seeing that a lot of people is looking for this.
Then, with your help, I'm ok to create a tutorial.

Many thanks for helping me to find a way to add the 7 points in this.

PM

Last edited by pm7; 09-14-2008 at 07:16 PM.
Reply With Quote
  #2 (permalink)  
Old 09-14-2008, 07:01 PM
pm7 pm7 is offline
Member
 
Join Date: Aug 2008
Posts: 65
Default

ps: this mp3 link is not so good, If you encounter difficulties to stream, use another link.

PM
Reply With Quote
  #3 (permalink)  
Old 09-15-2008, 07:31 PM
ToM ToM is offline
Junior Member
 
Join Date: Aug 2008
Posts: 8
Default

Wow, this is some nice code there!

When I tried to use this, I got the error that myPlayer was undefined in that function. :?
Reply With Quote
  #4 (permalink)  
Old 09-15-2008, 11:07 PM
pm7 pm7 is offline
Member
 
Join Date: Aug 2008
Posts: 65
Default

you should include the MEPlayer class in the header of the class you are using it : @class ME Player.
You should also import the MEPlayer header
You should declare an instance of the MEPlayer class in the class you are using it: MEPlayer myPlayer.
don't forget the property and synthesize.

PM
Reply With Quote
  #5 (permalink)  
Old 09-16-2008, 08:59 PM
pm7 pm7 is offline
Member
 
Join Date: Aug 2008
Posts: 65
Default

Hi again,

Bellow, I post the work that has been done until my first post.

Things that have changed:

1) It is difficult to quit the app while the file is playing... I still don't know how to stop it when I want. FIXED (thanks to go2)

2) It does not have a "track buffer" to manage playlist (NOT YET IMPLEMENTED)

3) no seek method is available (should be interesting to get the current position to add a "progress bar" in the app so that it is possible to move in the song. (NOT YET IMPLEMENTED - quite complicated)

4) no resume method is yet implemented (in case the connection goes down for a little) PAUSE ADDED, NOT YET TESTED

5) no volume method is available. FIXED

6) could also be interesting to get audio data to display the wave in real time or an equalizer with the FFT. (NOT YET IMPLEMENTED)

7) no notifications are available regarding the status of the playing track: started, ended. This should be necessary for example to play a next song when the current one has ended. (SOME ADDED)

I post the class and the call.

I now can listen to a track, detect when the track has ended playing.

I'd like to start playing another track once the previous has finished, but I still get an EXC_BAD_ACCESS message.
(here, during the begining of the second play
Code:
memcpy((char*)fillBuf->mAudioData + bytesFilled, (const char*)data + packetOffset, packetSize);
Any help on that issue would be REALLY BUT REALLY much appreciated.

It might be that I don't deallocate something, or might be something else, but I really don't where to have a look at...

pm

class H
Code:
#import <AudioToolbox/AudioQueue.h>
#import <AudioToolbox/AudioFile.h>
#import <AudioToolbox/AudioToolbox.h>


#define kNumAQBufs	3			// number of audio queue buffers we allocate
#define kAQMaxPacketDescs   512
#define kAQBufSize			128 * 1024

typedef enum {
	EAudioStateClosed,
	EAudioStateStopped,
	EAudioStatePlaying,
	EAudioStatePaused,
	EAudioStateSeeking
} EAudioState;


@interface Player : NSObject
{
	AudioFileStreamID				audioFileStream;
	AudioQueueRef					audioQueue;
	//AudioQueueBufferRef				audioQueueBuffer[kNumAQBufs];
	AudioQueueBufferRef				*audioQueueBuffer;
	AudioStreamPacketDescription	packetDescs[kAQMaxPacketDescs];
	
	NSURLConnection					*connection;
	NSURLRequest					*request;
	
	UInt64							fillBufferIndex;
	UInt64							fillBufferCount;
	UInt64							enqueuedBuffer;
	UInt64							emptieddBuffer;
	UInt32							bytesFilled;	
	UInt32							packetsFilled;
	
	UInt64							packetIndex;
	UInt32							numPacketsToRead;
	UInt32							ckeckIFEnded;
	
	//BOOL							inuse[kNumAQBufs];	
	BOOL							*inuse;	
	BOOL							started;			
	BOOL							failed;	
	BOOL							repeat;
	BOOL							closed;
	BOOL							ended;	

	
	EAudioState						audioState;
}



- (void)init;
- (void)LoadUrl:(NSString*)url;
- (void)stop;
- (void)pause;
- (void)setGain:(Float32)gain;
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data;
- (void)propertyChanged:(AudioFileStreamPropertyID)propertyID flags:(UInt32*)flags;
- (void)packetData:(const void*)data
   numberOfPackets:(UInt32)numPackets
	 numberOfBytes:(UInt32)numBytes
packetDescriptions:(AudioStreamPacketDescription*)packetDescriptions;
- (void)playBackIsRunningStateChanged;
- (void)enqueueBuffer;
- (int)findQueueBuffer:(AudioQueueBufferRef)inBuffer;
- (void)outputCallbackWithBufferReference:(AudioQueueBufferRef)buffer;
- (void)close;
- (void)dealloc;

@end
class M
Code:
#import "AudioClass.h"

NSString *PlayerDidStopNotification = @"PlayerDidStopNotification";
NSString *PlayerDidCloseNotification = @"PlayerDidCloseNotification";
NSString *PlayerAudioDidEndedPlayingNotification = @"PlayerAudioDidEndedPlayingNotification";
NSString *PlayerDidFinishedPlayingNotification = @"PlayerDidFinishedPlayingNotification";

void MyPropertyListenerProc(void *inClientData, AudioFileStreamID inAudioFileStream,AudioFileStreamPropertyID	inPropertyID, UInt32 * ioFlags)
{
	Player *player = (Player*)inClientData;
	//NSLog(@"MyPropertyListenerProc");
	[player propertyChanged:inPropertyID flags:ioFlags];
}

void MyPacketsProc(void *inClientData, UInt32 inNumberBytes, UInt32 inNumberPackets, const void * inInputData, AudioStreamPacketDescription	*inPacketDescriptions)
{
	Player *player = (Player*)inClientData;
	[player packetData:inInputData  numberOfPackets:inNumberPackets numberOfBytes:inNumberBytes packetDescriptions:inPacketDescriptions];
}

void MyAudioQueueOutputCallback(void *inClientData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
{
	Player *player = (Player*)inClientData;
	[player outputCallbackWithBufferReference:inBuffer];
}


@implementation Player

- (void)init {
	
	bytesFilled = 0;
	packetsFilled = 0;
	emptieddBuffer = 0;
	enqueuedBuffer = 0;
	audioQueue = 0;
	started = false;
	closed = false;
	ended = false;
	ckeckIFEnded = 0;
	
	
}

- (void)LoadUrl:(NSString*)url
{
	
	bytesFilled = 0;
	packetsFilled = 0;
	emptieddBuffer = 0;
	enqueuedBuffer = 0;
	audioQueue = 0;
	started = false;
	closed = false;
	ended = false;
	ckeckIFEnded = 0;
	
	NSLog(@"playUrl");
	OSStatus err = AudioFileStreamOpen(self, MyPropertyListenerProc, MyPacketsProc, 0, &audioFileStream);
	if (!err) NSLog(@"AudioFileStreamOpen ok");
	//else NSLog(@"AudioFileStreamOpen nok");
	
	request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
	connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
	
	if (connection)
		NSLog(@"connection created");
	else
		NSLog(@"connection failed");
	NSLog(@"address inData:%p", (void *)self);
}


- (void)pause {
	if (closed)
		return;
	AudioQueuePause(audioQueue);
}

- (void)setGain:(Float32)gain {
	if (closed)
		return;
	AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, gain);
}

- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
	OSStatus err = AudioFileStreamParseBytes(audioFileStream, [data length], [data bytes], 0);
	if (err) NSLog(@"AudioFileStreamParseBytes failed");
}

- (void)propertyChanged:(AudioFileStreamPropertyID)propertyID flags:(UInt32*)flags {
	//NSLog(@"found property '%c%c%c%c'\n", (propertyID>>24)&255, (propertyID>>16)&255, (propertyID>>8)&255, propertyID&255);
	
	OSStatus err = noErr;
	
	switch (propertyID)
	{
		case kAudioFileStreamProperty_ReadyToProducePackets:
		{
			AudioStreamBasicDescription asbd;
			UInt32 asbdSize = sizeof(asbd);
			
			err = AudioFileStreamGetProperty(audioFileStream,  kAudioFileStreamProperty_DataFormat, &asbdSize, &asbd);
			if (err) NSLog(@"get kAudioFileStreamProperty_DataFormat failed");
			
			err = AudioQueueNewOutput(&asbd, MyAudioQueueOutputCallback, self, NULL, NULL, 0, &audioQueue);
			if (err) NSLog(@"AudioQueueNewOutput failed");
			
			/*
			for (unsigned int i = 0; i < kNumAQBufs; i++)
				err = AudioQueueAllocateBuffer(audioQueue, kAQBufSize, &audioQueueBuffer[i]);
			 */
			
			fillBufferCount = 1;
			//NSLog(@"setting fillBufferCount value:%d", fillBufferCount);
			NSLog(@"allocating audioQueueBuffer from:%p", audioQueueBuffer);
			audioQueueBuffer = (AudioQueueBufferRef*)calloc(fillBufferCount, sizeof(AudioQueueBufferRef));
			NSLog(@"allocated audioQueueBuffer to:%p", audioQueueBuffer);
			//NSLog(@"allocating inuse from:%p", inuse);
			inuse = (BOOL *)calloc(fillBufferCount, sizeof(BOOL));
			//NSLog(@"allocated inuse to:%p", inuse);
			for (unsigned int i = 0; i < fillBufferCount; i++)
			{
				//NSLog(@"allocating audioQueue");
				err = AudioQueueAllocateBuffer(audioQueue, kAQBufSize, &audioQueueBuffer[i]);
				if (err) NSLog(@"AudioQueueAllocateBuffer failed");
				inuse[i] = false;
			}
			
			break;
		}

	}
}

- (void)packetData:(const void*)data numberOfPackets:(UInt32)numPackets numberOfBytes:(UInt32)numBytes packetDescriptions:(AudioStreamPacketDescription*)packetDescriptions
{
	//NSLog(@"got data. bytes: %d, packets: %d", numBytes, numPackets);
	//ckeckIFEnded = 0; //if data still arrive, track is not Finished!
	//NSLog(@"bytesFilled: %d, packetsFilles: %d", bytesFilled, packetsFilled);
	
	for (int i = 0; i < numPackets; i++)
	{
		SInt64 packetOffset = packetDescriptions[i].mStartOffset;
		//NSLog(@"packetOffset in packetData:%d", packetOffset);
		SInt64 packetSize = packetDescriptions[i].mDataByteSize;
		//NSLog(@"packetSize in packetData:%d", packetSize);
		size_t bufSpaceRemaining = kAQBufSize - bytesFilled;
		//NSLog(@"bufSpaceRemaining in packetData:%d", bufSpaceRemaining);
		
		if (bufSpaceRemaining < packetSize) [self enqueueBuffer];
		
		//NSLog(@"fillBufferIndex in packetData:%d", fillBufferIndex);
		AudioQueueBufferRef fillBuf = audioQueueBuffer[fillBufferIndex];
		//NSLog(@"using fillBuf at:%x", audioQueueBuffer[fillBufferIndex]);
		
                //for debug, to display only once (in for loop)
                if(i == 0)
		{
			NSLog(@"data (const char*) is at %p", data);
			NSLog(@"fillBuf->mAudioData is at:%p", fillBuf->mAudioData);
		}

                //DURING THE SECOND PLAY, AFTER THE FIRST PLAY FINISHED, GOT AN ERROR HERE.
                //I THINK THERE IS A MISALLOCATION FOR fillBuf->mAudioData OR FOR data
                //I DON'T KNOW HOW TO FIX IT, NOT SURE ALSO IF THE ERROR COMES FROM HERE 
		memcpy((char*)fillBuf->mAudioData + bytesFilled, (const char*)data + packetOffset, packetSize);
		packetDescs[packetsFilled] = packetDescriptions[i];
		packetDescs[packetsFilled].mStartOffset = bytesFilled;
		bytesFilled += packetSize;
		packetsFilled += 1;
		
		size_t packetsDescsRemaining = kAQMaxPacketDescs - packetsFilled;
		if (packetsDescsRemaining == 0) [self enqueueBuffer];
	}
}
Reply With Quote
  #6 (permalink)  
Old 09-16-2008, 08:59 PM
pm7 pm7 is offline
Member
 
Join Date: Aug 2008
Posts: 65
Default

end of the post (size of the post was two large)

PM


Code:
- (void)enqueueBuffer
{
	enqueuedBuffer++;
	NSLog(@"enqueueBuffer:%d.", enqueuedBuffer);
	OSStatus err = noErr;
	//NSLog(@"fillBufferIndex value:%d", fillBufferIndex);
	inuse[fillBufferIndex] = true;
	//NSLog(@"inuse[%d] value:%d", fillBufferIndex, inuse[fillBufferIndex]);
	
	
	AudioQueueBufferRef fillBuf = audioQueueBuffer[fillBufferIndex];
	fillBuf->mAudioDataByteSize = bytesFilled;
	err = AudioQueueEnqueueBuffer(audioQueue, fillBuf, packetsFilled, packetDescs);
	if (err) NSLog(@"AudioQueueEnqueueBuffer failed");
	
	
	if (!started)
	{
		err = AudioQueueStart(audioQueue, NULL);
		if (err) NSLog(@"AudioQueueStart failed");
		started = true;
		NSLog(@"started.");
	}

	
	bool isone = false;
	for (unsigned int i = 0; i < fillBufferCount; i++)
	{
		//NSLog(@"fillBufferCount value:%d", fillBufferCount);
		//NSLog(@"i value:%d", i);
		//NSLog(@"inuse[%d] value:%d", i, inuse[i]);
		if (!inuse[i])
		{
			fillBufferIndex = i;
			isone = true;
			//NSLog(@"found!");
			break;
		}
	}
	
	if (!isone)
	{
		//NSLog(@"not found!");
		fillBufferCount++;
		//NSLog(@"fillBufferCount value:%d", fillBufferCount);
		fillBufferIndex = fillBufferCount - 1;
		//NSLog(@"fillBufferIndex value:%d", fillBufferIndex);
		
		audioQueueBuffer = (AudioQueueBufferRef*)realloc(audioQueueBuffer, sizeof(AudioQueueBufferRef) * fillBufferCount);
		//NSLog(@"audioQueueBuffer reallocated!");
		inuse = (BOOL *)realloc(inuse, sizeof(BOOL) * fillBufferCount);
		//NSLog(@"inuse reallocated!");
		
		err = AudioQueueAllocateBuffer(audioQueue, kAQBufSize, &audioQueueBuffer[fillBufferIndex]);
		if (err) NSLog(@"AudioQueueAllocateBuffer failed");
		////else NSLog(@"AudioQueueAllocateBuffer OK");
		
		//NSLog(@"setting inuse[%d]: value:%d",fillBufferIndex, false);
		inuse[fillBufferIndex] = false;
	}	
	
	bytesFilled = 0;
	packetsFilled = 0;
}

- (int)findQueueBuffer:(AudioQueueBufferRef)inBuffer
{
	//NSLog(@"findQueueBuffer!");
	emptieddBuffer++;
	NSLog(@"emptieddBuffer:%d.", emptieddBuffer);
	//for (unsigned int i = 0; i < kNumAQBufs; i++)
	
	for (unsigned int i = 0; i < fillBufferCount; i++)
	{
		if (inBuffer == audioQueueBuffer[i]) 
		{
			//NSLog(@"inBuffer (%d) = audioQueueBuffer[%d]:",inBuffer, i);
			return i;
		}
	}
	return -1;
}

- (void)outputCallbackWithBufferReference:(AudioQueueBufferRef)buffer
{
	
	if(closed  || ended)
		return;
	
	//NSLog(@"Check if Ended or stall error: ckeckIFEnded: %d",ckeckIFEnded);
	//NSLog(@"fillBufferIndex -1: %d",fillBufferIndex-1);
	unsigned int bufIndex = [self findQueueBuffer:buffer];
	if(bufIndex != -1)
	{
		inuse[bufIndex] = false;
		//NSLog(@"bufIndex: %d",bufIndex);

		if(enqueuedBuffer == emptieddBuffer) //we are at the end of the file if the file as a length. 
		{
			//ended
			//NSLog(@"stopping AudioQueue!");
			AudioQueueStop(audioQueue, NO);
			//NSLog(@"setting ended to yes!");
			ended = YES;
			//NSLog(@"calling playBackIsRunningStateChanged!");
			[self playBackIsRunningStateChanged];
		}		
	}
	
}


- (void)postTrackFinishedPlayingNotification:(id)object
{
	[[NSNotificationCenter defaultCenter] postNotificationName:PlayerDidFinishedPlayingNotification object:self];
}

- (void)playBackIsRunningStateChanged
{
	if (ended)
	{
		// go ahead and close the track now
		closed = YES;
		AudioQueueDispose(audioQueue, YES);
		AudioFileStreamClose(audioFileStream);
		NSLog(@"audioQueueBuffer before freeing: %p",audioQueueBuffer);
		free(audioQueueBuffer);
		audioQueueBuffer = (AudioQueueBufferRef*)0x0;
		[self performSelectorOnMainThread:@selector(postTrackFinishedPlayingNotification:) withObject:nil waitUntilDone:NO];
	}
}

- (void)stop
{
	if (audioQueue != 0)
	{
		if (connection)
		{
			[connection cancel];
			[connection release];
			connection = nil;
		}
		OSStatus err = noErr;
		err = AudioQueueStop(audioQueue, true);
		if (err) NSLog(@"AudioQueueStop failed");
		err = AudioFileStreamClose(audioFileStream);
		if (err) NSLog(@"AudioFileStreamClose failed");
		err = AudioQueueDispose(audioQueue, true);
		if (err) NSLog(@"AudioQueueDispose failed");
		free(audioQueueBuffer);
		if (packetDescs != nil)
			free(packetDescs);
		[[NSNotificationCenter defaultCenter] postNotificationName:PlayerDidStopNotification object:self];
	}
}

- (void)close
{
	
	if (closed) return;
	
	if (audioQueue != 0)
	{
		if (connection)
		{
			[connection cancel];
			[connection release];
			connection = nil;
		}
		OSStatus err = noErr;
		err = AudioQueueStop(audioQueue, true);
		if (err) NSLog(@"AudioQueueStop failed");
		err = AudioFileStreamClose(audioFileStream);
		if (err) NSLog(@"AudioFileStreamClose failed");
		err = AudioQueueDispose(audioQueue, true);
		if (err) NSLog(@"AudioQueueDispose failed");
		free(audioQueueBuffer);
		[[NSNotificationCenter defaultCenter] postNotificationName:PlayerDidCloseNotification object:self];
	}
}

- (void)dealloc
{
	//free(audioQueueBuffer);
	//if (packetDescs != nil)
	//	free(packetDescs);
	[super dealloc];
}

@end

AppDelegate H
Code:
//
//  AudioTrialAppDelegate.h
//  AudioTrial
//
//  Created by me on 9/13/08.
//  Copyright __MyCompanyName__ 2008. All rights reserved.
//

#import <UIKit/UIKit.h>

@class AudioTrialViewController;
@class Player;

@interface AudioTrialAppDelegate : NSObject <UIApplicationDelegate> {
	IBOutlet UIWindow *window;
	IBOutlet AudioTrialViewController *viewController;
	Player *myPlayer1, *myPlayer2;
}

@property (nonatomic, retain) UIWindow *window;
@property (nonatomic, retain) AudioTrialViewController *viewController;
@property (nonatomic, retain) Player *myPlayer1;
@property (nonatomic, retain) Player *myPlayer2;

- (void)log:(NSNotificationCenter *)note;

@end
AppDelegate M
Code:
//
//  AudioTrialAppDelegate.m
//  AudioTrial
//
//  Created by me on 9/13/08.
//  Copyright __MyCompanyName__ 2008. All rights reserved.
//

#import "AudioTrialAppDelegate.h"
#import "AudioTrialViewController.h"
#import "AudioClass.h"

@implementation AudioTrialAppDelegate

@synthesize window;
@synthesize viewController, myPlayer1, myPlayer2;


- (void)applicationDidFinishLaunching:(UIApplication *)application {	
	
	// Override point for customization after app launch	
    [window addSubview:viewController.view];
	[window makeKeyAndVisible];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(log:) name:nil object:nil];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myPlayerDidFinishedPlayingNotification) name:@"PlayerDidFinishedPlayingNotification" object:nil];
	
	NSLog(@"Url Init");
	

	NSString *myURL2 = [[NSString alloc] initWithString:@"http://www.ws.com/track1.mp3"];
	
	NSLog(@"Player init");
	myPlayer1 = [Player alloc];
	myPlayer2 = [Player alloc];
	NSLog(@"Starting Player process");
	[myPlayer1 LoadUrl:myURL2];

	

}

- (void)myPlayerDidFinishedPlayingNotification{
	NSLog(@"track finished.. going to next one");
	[myPlayer1 dealloc]; //don't know if this is necessary

	NSString *myURL1 = [[NSString alloc] initWithString:@"http://www.ws.com/track2.mp3"];
	[myPlayer2 LoadUrl:myURL1];
	 
}

- (void)myPlayerDidEndedPlayingNotification{
	NSLog(@"track ended.. going to next one");
}


- (void)log:(NSNotificationCenter *)note {
	NSLog(@"note = %@", note);
}

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {	

	[myPlayer1 dealloc];
        [viewController release];
	[window release];
	[super dealloc];
	
}


- (void)dealloc {
	[myPlayer1 dealloc];
        [viewController release];
	[window release];
	[super dealloc];
}


@end
Reply With Quote
  #7 (permalink)  
Old 09-16-2008, 09:01 PM
pm7 pm7 is offline
Member
 
Join Date: Aug 2008
Posts: 65
Default

Thanks for considering some help on the problem mentioned above.

pm
Reply With Quote
  #8 (permalink)  
Old 09-17-2008, 05:00 PM
pm7 pm7 is offline
Member
 
Join Date: Aug 2008
Posts: 65
Default

anyone can help on the issue please?

PM
Reply With Quote
  #9 (permalink)  
Old 09-20-2008, 06:10 PM
pm7 pm7 is offline
Member
 
Join Date: Aug 2008
Posts: 65
Default

Could somebody consider to help on my issue?

Many thanks for that

PM
Reply With Quote
  #10 (permalink)  
Old 09-22-2008, 03:42 PM
Junior Member
 
Join Date: Sep 2008
Posts: 26
Default

Hi pm, i'm trying to run your code but still i have problem with this:
Code:
Error loading /Library/QuickTime/DivX Decoder.component/Contents/MacOS/DivX Decoder:  dlopen(/Library/QuickTime/DivX Decoder.component/Contents/MacOS/DivX Decoder, 262): Symbol not found: _SCDynamicStoreCopyConsoleUser
  Referenced from: /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LangAnalysis.framework/Versions/A/LangAnalysis
  Expected in: /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.0.sdk/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration
this error is caused by calling AudioQueueNewOutput method.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 05:43 AM.