• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Streaming Audio - AudioFileStream, CFReadStreamRead and AudioQueue
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Streaming Audio - AudioFileStream, CFReadStreamRead and AudioQueue


  • Subject: Streaming Audio - AudioFileStream, CFReadStreamRead and AudioQueue
  • From: "Adam Fox" <email@hidden>
  • Date: Wed, 30 Jul 2008 12:34:17 +0100

Hi guys,

I am trying to stream and play MP3 file over network.

Here is what I have got so far using AudioFileStream, CFReadStream and
AudioQueue..

I hope it helps some people start off, and I hope some people can help
me finish!

First, I define a custom data structure to hold stuff throughout..

[code]
typedef struct {
    AudioFileStreamID audioFileStream;
    AudioStreamBasicDescription *mDataFormat;
    AudioQueueRef mQueue;
    CFReadStream readStream;
    UInt32 mNumPackets;
    AudioStreamPacketDescription *mPacketDescs;
} CustomData;

CustomData customData;
[/code]

I set up an AudioFileStream..

[code]
AudioFileStreamOpen(0,
                    audioFileStream_Properties,
                    audioFileStream_Packets,
                    kAudioFileMP3Type,
                    &customData.audioFileStream);
[/code]

..this has call back functions attached when the AudioFileStream
receives either stream properties or stream packets..

I then open a data stream to a URL of an MP3 stream..

[code]
NSURL *url = [NSURL URLWithString:@"http://mp3stream.com";];
CFHTTPMessageRef message = CFHTTPMessageCreateRequest(kCFAllocatorDefault,
                                                      CFSTR("GET"),
                                                      (CFURLRef)url,
                                                      kCFHTTPVersion1_1);

customData.readStream =
CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, message);
CFOptionFlags events = kCFStreamEventHasBytesAvailable |
kCFStreamEventErrorOccured | kCFStreamEventEndEncountered;

CFStreamClientContext dataStreamContext = {0, self, NULL, NULL, NULL};

if (CFReadStreamSetClient(customData.readStream, events,
readStreamEventCallBack, &dataStreamContext)) {
 CFReadStreamScheduleWithRunLoop(customData.readStream,
CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
}

CFReadStreamOpen(customData.readStream);
[/code]

..this opens a CFReadStream with a call back function that is called
on bytes available events, error events and end events..

[code]
void readStreamEventCallBack(CFReadStreamRef stream, CFStreamEventType
eventType, void *clientcallBackInfo) {

    switch(eventType) {
        case kCFStreamEventHasBytesAvailable:
            UInt8 buf[4096];
            CFIndex bytesRead = CFReadStreamRead(stream, buf, 4096);
            if (bytesRead > 0) {
                AudioFileStreamParseBytes(customData.audioFileStream,
bytesRead, buf, 0);
            }

        case kCFStreamEventErrorOccurred:
         //do stuff
         break;

        case kCFStreamEventEndOccurred:
         //do stuff
         break;

     }


}
[/code]


So when the CFReadStream reads some bytes it passes them to the
AudioFileStream which will in turn call its callback functions when it
receives stream properties or stream packets..

In audioFileStream_Properties I attempt to get the dataFormat of the stream..
I also set up an Audio Queue....

[code]
void audioFileStream_Properties (void *inClientData,
                                 AudioFileStreamID inAudioFileStream,
                                 AudioFileStreamPropertyID inPropertyID,
                                 UInt32 *ioFlags) {

    if (inPropertyID == kAudioFileStreamProperty_ReadyToProducePackets) {

        AudioQueueNewOutput(customData.mDataFormat,
                    AudioOutputCallBack,
                    &customData,
                    NULL,
                    kCFRunLoopCommonModes,
                    0,
                    &customData.mQueue);

    } if (inPropertyID == kAudioFileStreamProperty_DataFormat) {

        UInt32 size;
        AudioFileStreamGetPropertyInfo(inAudioFileStream,
inPropertyID, &size, nil)
        AudioFileStreamGetProperty(inAudioFileStream, inPropertyID,
&size,  customData.mDataFormat);
    }
}
[/code]

Most of these function calls return an OSStatus which I check for
error (!= 0) but I have left them out for now.. I get an error setting
mDataFormat using AudioFileStreamGetProperty..

Then the AudioFileStream packets..

[code]
void audioFileStream_Packets (void *inClientData,
                              UInt32 inNumberBytes,
                              UInt32 inNumberPackets,
                              const void *inInputData,
                              AudioStreamPacketDescription *inPacketDescs) {

    customData.mNumPackets = inNumberPackets;
    customData.mPacketDescs = inPacketDescs;

    AudioQueueBufferRef outBuffer;
    AudioQueueAllocateBuffer(customData.mQueue, inNumberBytes, &outBuffer);
    AudioOutputCallBack(&customData, customData.mQueue, outBuffer);

}
[/code]

..here I try and allocate the stream packets into the an
AudioQueueBuffer and force that buffer into the AudioQueue callback..

[code]
static void AudioOutputCallBack(void *inCustomData,
                                AudioQueueRef outAQ,
                                AudioQueueBufferRef) {

    CustomData *customData = (CustomData*)inCustomData;

    AudioQueueEnqueueBuffer(customData->mQueue, outBuffer,
(customData->mPacketDescs ? customData->mNumPackets : 0),
playState->mPacketDescs);

}
[/code]

..I believe I am very close but I still have two problems...

Firstly, I think I am getting or setting mDataFormat incorrectly as I
get an error.....

Mainly, I am unsure how to proceed from here.. I am getting audio data
packets in my callback... but how do I transfer them properly to the
AudioQueue. Does anyone have some example code for doing this?

Hope this is clear enough.... and thanks in advance to anyone who can
offer assistance!

Adam

null
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: Streaming Audio - AudioFileStream, CFReadStreamRead and AudioQueue
      • From: "Adam Fox" <email@hidden>
    • Re: Streaming Audio - AudioFileStream, CFReadStreamRead and AudioQueue
      • From: Jens Alfke <email@hidden>
  • Prev by Date: Re: Adjusting AudioQueue volume
  • Next by Date: Re: Streaming Audio - AudioFileStream, CFReadStreamRead and AudioQueue
  • Previous by thread: Re: Adjusting AudioQueue volume
  • Next by thread: Re: Streaming Audio - AudioFileStream, CFReadStreamRead and AudioQueue
  • Index(es):
    • Date
    • Thread