iOS: Playing PCM buffers from a stream

10,540

Solution 1

You need to use some type of buffer to hold your incoming UDP data. This is an easy and good circular buffer that I have used.

Then to play back data from the buffer, you can use Audio Unit framework. Here is a good example project.

Note: The first link also shows you how to playback using Audio Unit.

Solution 2

You could use audioQueue services as well, make sure your doing some kind of packet re-ordering, if your using ffmpeg to decode the streams there is an option for this.

otherwise audio queues are easy to set up.

https://github.com/mooncatventures-group/iFrameExtractor/blob/master/Classes/AudioController.m

You could also use AudioUnits, a bit more complicated though.

Share:
10,540
Sergio Morales
Author by

Sergio Morales

Costa Rican CS student and embedded software engineer; if not programming and listening to music, it's just the music.

Updated on June 04, 2022

Comments

  • Sergio Morales
    Sergio Morales almost 2 years

    I'm receiving a series of UDP packets from a socket containing encoded PCM buffers. After decoding them, I'm left with an int16 * audio buffer, which I'd like to immediately play back.

    The intended logic goes something like this:

    init(){
       initTrack(track, output, channels, sample_rate, ...);
    }
    
    onReceiveBufferFromSocket(NSData data){
       //Decode the buffer
       int16 * buf = handle_data(data);
    
       //Play data
       write_to_track(track, buf, length_of_buf, etc);
    }
    

    I'm not sure about everything that has to do with playing back the buffers though. On Android, I'm able to achieve this by creating an AudioTrack object, setting it up by specifying a sample rate, a format, channels, etc... and then just calling the "write" method with the buffer (like I wish I could in my pseudo-code above) but on iOS I'm coming up short.

    I tried using the Audio File Stream Services, but I'm guessing I'm doing something wrong since no sound ever comes out and I feel like those functions by themselves don't actually do any playback. I also attempted to understand the Audio Queue Services (which I think might be close to what I want), however I was unable to find any simple code samples for its usage.

    Any help would be greatly appreciated, specially in the form of example code.

  • Sergio Morales
    Sergio Morales over 11 years
    I'm still a bit clueless about how to do it. I have a reception callback function from the UDP socket. I fetch the PCM frames there, so what you're saying is I should have a circular buffer so that function can put the frames it fetches there, and another callback (which I'm not too sure how to make) checks the buffer and submits the frames for playback using the audiounit service? But what calls the second callback? It doesn't seem like I get to decide when the audio plays, is that correct?
  • user523234
    user523234 over 11 years
    If you look at the example in the my first link, there is a function called: audioOutputCallback. It shows you how to copy data from the circular buffer into the Audio Unit playback. I just made a copy of that function above.
  • DURGESH
    DURGESH almost 7 years
    please share your implementation part