• 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
Re: Playing PCM buffers
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Playing PCM buffers


  • Subject: Re: Playing PCM buffers
  • From: Sean Harding <email@hidden>
  • Date: Thu, 5 Jun 2003 11:22:42 -0700

Hi Chris. Thanks for your response. This does help. I suppose I thought it
was more of an audio problem than a general programming problem because I
expected CoreAudio to have a built-in "play buffer and return" method which
would make the solution very easy. It's not a big setback to me that it
doesn't have such a method -- now that I know, I can work on achieving the
funcionality I need via different tactics. I just felt that I was missing
something.

What you describe is fairly similar to what I've implemented so far. The
whole process is happening in a feeder thread anyway because I didn't want
the main thread bogged down with choosing characters and waiting for them to
be done playing. What I have now is working pretty well. I do have a one
character delay in changes taking effect, but I haven't been terribly
concerned about it. It's important to me that I have as close as possible
to exact timing on the length of the characters and the spaces between
them -- more important than having user changes take effect immediately.
It seemed more reliable to shove PCM data of the exact character (based
on the speed and sample rate) into a buffer and then play that than to
time it on the fly. This may be a false impression. I'll play
around with it a little bit and see if doing it on the fly causes any
problems.

Thanks again for your input.

sean

On Wed Jun 04 at 03:48:25 PM, Chris Reed wrote:

> Hi Sean,
>
> It sounds like you've got the basic idea down. It's really not much of
> an audio problem, but more of a general programming problem. It sounds
> like you've got the audio output part down fine.
>
> Basically what you want after installing your IOProc is this.
>
> The IOProc will read from (preferably non-blocking) queue of buffers.
> It copies as much data from the buffer at the head of the queue into
> the output buffer as possible. Any time it runs out, it drops the queue
> head and continues with the next queue head. If there are no items in
> the queue, it outputs silence.
>
> To be notified when a buffer (character) is finished playing, the
> IOProc will have to signal back to the main or another thread using a
> (also preferably nonblocking) signalling mechanism. If you're using
> Cocoa, you can probably get away with performSelectorOnMainThread:...
> from the IOProc. The IOProc will signal each time it finishes with the
> queue head and moves on to the next.
>
> Your character-playing loop will really be broken up into several
> functions.
>
> When it first starts, you add a buffer to the to-be-played queue that
> the IOProc is watching. Then the function or method that gets notified
> by the IOProc that a buffer is finished will add the next buffer to the
> queue.
>
> But... there are problems with this whole setup. Mostly, there will be
> a full buffer's latency for playing a new character. So you'll probably
> hear a slight, annoying delay. Reducing output buffer size will reduce
> this latency, but at the cost of increased CPU usage.
>
> Really what you want to do is synthesise the morse code either within
> the IOProc or in a feeder thread, going from characters to audio
> directly. This will let you respond immediately to changes made by the
> user to pitch or other options.
>
> Hope this helps
>
> cheers
> -chris
>
> On Tuesday, June 3, 2003, at 04:42 PM, Sean Harding wrote:
>
> >Since my last message, I still haven't really found what I'm looking
> >for
> >in the documentation. I'm sure this means I'm either not looking in the
> >right place or misunderstanding something I've read that would
> >actually help
> >me. This is the first audio-related code I've written on any platform,
> >and I
> >just recently started working with Cocoa as well, so I have much to
> >learn.
> >
> >In any case, maybe if I give a better explanation of exactly what I
> >want
> >to do, someone here can give me a nudge in the right direction. I've
> >experimented quite a bit and still have not come up with exactly the
> >results I want.
> >
> >I'm writing an application that generates morse code. It generates the
> >tones
> >in real time (a character is chosen just before the sound for it is
> >played)
> >and users can adjust parameters of that code as it is being generated.
> >
> >Here's some pseudocode for what I'd like:
> >
> >while( condition ){
> > // put PCM data for one morse character into someBuffer based
> > // on user-set params
> > bufferSize = generatePCMData(someBuffer);
> > < do some stuff >
> > // play that data
> > playPCMDataOnDefaultOutputDevice(someBuffer,bufferSize);
> >}
> >
> >
> >The key points here are that I have buffers of PCM audio data that can
> >be
> >any length (in my app, they'll range from a fraction of a second to
> >several
> >seconds) and that I don't want playPCMDataOnDefaultOutputDevice() to
> >return
> >until all of the sound in the buffer has been played. My app needs to
> >know
> >immediately when all of the buffer has been played so that it can take
> >actions based on that.
> >
> >I do have reasons to play a bunch of short buffers in succession rather
> >than putting it all into one long buffer at the beginning and playing
> >that.
> >The most important is the user interaction I mentioned earlier. Users
> >can
> >change things such as speed and pitch on the fly, so I don't know what
> >the
> >next bit of audio needs sound like until immediately before playing
> >it. Also, a full 5 or 10 minute buffer of data would use a fair amount
> >of
> >memory.
> >
> >I've been able to pretty easily play sound from a PCM buffer by just
> >doing AudioDeviceAddIOProc()/AudioDeviceStart() and having my IOProc
> >read
> >from the buffer each time around. However, this doesn't give me a
> >reliable
> >way to know immediately when the buffer has been fully played. It also
> >gives
> >me a gut feeling that it's just not the "right" way to solve the
> >problem,
> >but it's about the closest I've come so far.
> >
> >I apologize for using so many words to ask what is likely an elementary
> >question. But I've been stuck on this problem for a while and any
> >guidance
> >you can give would be greatly appreciated.
> >
> >Thanks.
> >
> >sean
> >
> >--
> >Sean Harding -- email@hidden -- http://dogcow.org/s/ -- KD7UAY
> >Seattle, WA, USA
> >_______________________________________________
> >coreaudio-api mailing list | email@hidden
> >Help/Unsubscribe/Archives:
> >http://www.lists.apple.com/mailman/listinfo/coreaudio-api
> >Do not post admin requests to the list. They will be ignored.
> >



--
Sean Harding -- email@hidden -- http://dogcow.org/s/ -- KD7UAY
Seattle, WA, USA
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.

References: 
 >Playing PCM buffers (From: Sean Harding <email@hidden>)
 >Re: Playing PCM buffers (From: Chris Reed <email@hidden>)

  • Prev by Date: Re: Playing PCM buffers
  • Next by Date: Re: Convert to float and more
  • Previous by thread: Re: Playing PCM buffers
  • Next by thread: Re: AudioConverterFillBuffer error: OSStatus = -50
  • Index(es):
    • Date
    • Thread