• 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: Chris Reed <email@hidden>
  • Date: Wed, 4 Jun 2003 15:48:25 -0500

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.
_______________________________________________
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.

  • Follow-Ups:
    • Re: Playing PCM buffers
      • From: Sean Harding <email@hidden>
References: 
 >Playing PCM buffers (From: Sean Harding <email@hidden>)

  • Prev by Date: Re: How To Give Idle Time From The AU To The Host ?
  • Next by Date: Re: Playing PCM buffers
  • Previous by thread: Playing PCM buffers
  • Next by thread: Re: Playing PCM buffers
  • Index(es):
    • Date
    • Thread