Callback issue

All,
Can someone verify if the following behaviour is correct (and if so why) regarding audio output.

I have opened the audio device with following params:
frequency=8000
samples=256
channels=1
format=AUDIO_S16SYS

The audio callback routine I have assigned fires ok but the length parameter passed to it is not 512 as I would expect, instead it is 340…!?

The way I understand this is that I have asked SDL to allow me to feed in 256 16 bit samples (512 bytes) every time the callback fires.

Is this correct or am I missing something - It is possible that my DSP has developed a problem as I have noticed odd crackles occasionally in the speaker.
The OS is 2.6.18 custom on a DELL inspiron 6000

Any help is appreciated as usual.
-Chris

Futher update on this:
I tried it on another linux box and guess what ? yep, I get 512 passed in as the length as expected.
Guess this means there is something not right with the other box, anyone got and ideas what it could be. I am running with SDL1.2 in tandem with the SDL_AudioIn project to provide microphone input.
Strange thing is I have looke thru some old logs and it definitley used to behave correctly so unless I have installed something that’s upset the sound layer or worse the dsp is shot.

-Chris----- Original Message -----
From: Chris Dobbs
To: sdl at lists.libsdl.org
Sent: Saturday, April 28, 2007 4:28 PM
Subject: [SDL] callback issue

All,
Can someone verify if the following behaviour is correct (and if so why) regarding audio output.

I have opened the audio device with following params:
frequency=8000
samples=256
channels=1
format=AUDIO_S16SYS

The audio callback routine I have assigned fires ok but the length parameter passed to it is not 512 as I would expect, instead it is 340…!?

The way I understand this is that I have asked SDL to allow me to feed in 256 16 bit samples (512 bytes) every time the callback fires.

Is this correct or am I missing something - It is possible that my DSP has developed a problem as I have noticed odd crackles occasionally in the speaker.
The OS is 2.6.18 custom on a DELL inspiron 6000

Any help is appreciated as usual.
-Chris



SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

As far as I’m aware, the audio hardware on different systems will ask
for different amounts of audio data each callback, so your
responsibility is to provide it with however much data it asks for.
Often (for me, at least) this has meant playing through the end of
one sample/source and starting the next one just a little bit before
the next callback. It’s not clean, but the result sounds nice anyway.

– ScottOn Apr 28, 2007, at 10:25 AM, Chris Dobbs wrote:

Futher update on this:
I tried it on another linux box and guess what ? yep, I get 512
passed in as the length as expected.
Guess this means there is something not right with the other box,
anyone got and ideas what it could be. I am running with SDL1.2 in
tandem with the SDL_AudioIn project to provide microphone input.
Strange thing is I have looke thru some old logs and it definitley
used to behave correctly so unless I have installed something
that’s upset the sound layer or worse the dsp is shot.

-Chris
----- Original Message -----
From: Chris Dobbs
To: sdl at lists.libsdl.org
Sent: Saturday, April 28, 2007 4:28 PM
Subject: [SDL] callback issue

All,
Can someone verify if the following behaviour is correct (and if so
why) regarding audio output.

I have opened the audio device with following params:
frequency=8000
samples=256
channels=1
format=AUDIO_S16SYS

The audio callback routine I have assigned fires ok but the length
parameter passed to it is not 512 as I would expect, instead it is
340…!?

The way I understand this is that I have asked SDL to allow me to
feed in 256 16 bit samples (512 bytes) every time the callback fires.

Is this correct or am I missing something - It is possible that my
DSP has developed a problem as I have noticed odd crackles
occasionally in the speaker.
The OS is 2.6.18 custom on a DELL inspiron 6000

Any help is appreciated as usual.
-Chris


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

The audio callback routine I have assigned fires ok but the length
parameter passed to it is not 512 as I would expect, instead it is 340…!?

SDL is probably converting to whatever format the audio hardware can
handle behind the scenes, which means it needs less samples from you
each callback.

You can’t count on the callback to ask for a specific amount of data.

–ryan.

Futher update on this:
I tried it on another linux box and guess what ? yep, I get 512 passed in as the length as expected.
Guess this means there is something not right with the other box, anyone got and ideas what it could be. I am running with SDL1.2 in tandem with the SDL_AudioIn project to provide microphone input.
Strange thing is I have looke thru some old logs and it definitley used to behave correctly so unless I have installed something that’s upset the sound layer or worse the dsp is shot.

The sdl audio callback has a length argument which leaves
open the possibility that you will be asked for more or
even less sound than you specified in SDL_OpenAudio.
I don’t know why SDL_OpenAudio asks what buffer size you
want if it’s just going to ignore it, but anyway. Some
driver/os/hardware combinations honour it and some don’t,
so you always have to put something sensible there.

So, you need to spoon out the audio data in chunk sizes that
SDL asks for:

while(len > 0) {
if(nbytes_in_buffer == 0) generate_more_audio();
int n = min(nbytes_in_buffer, len);
memcpy(dst, snd_buf, n);
len -= n;
nbytes_in_buffer -= n;
}

I’ve run into this prob on 2 different hp laptops,
one running xp, and the other some linux.

RF> From: “Chris Dobbs” <chris_dobbs at dobbscr.karoo.co.uk>

Ok, thanks that kindof makes sense to me. Currently I do this in my
callback routine

void audio_out(void *userdata, Uint8 *stream, int len)
{

Lock internal data queue
Pull off queue len bytes of PCM data into data_p pointer
Call SDL_MixAudio(stream, (const Uint8*)data_p, len, SDL_MIX_MAXVOLUME)
Unlock internal data queue

}

My internal data queue is populated by another thread which receives AMR
data via network, decodes it to PCM and stuffs onto queue ready for this
callback to playback.

Are you saying that I need to get the callback to play slightly before
the start of the next queue block retreived?

Many thanks for your help by the way!

-Chris> ----- Original Message -----

From: sdl-bounces@lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org]
On Behalf Of Scott Harper
Sent: 28 April 2007 18:25
To: A list for developers using the SDL library. (includes SDL-announce)
Subject: Re: [SDL] callback issue

As far as I’m aware, the audio hardware on different systems will ask
for different amounts of audio data each callback, so your
responsibility is to provide it with however much data it asks for.
Often (for me, at least) this has meant playing through the end of one
sample/source and starting the next one just a little bit before the
next callback. It’s not clean, but the result sounds nice anyway.

– Scott

On Apr 28, 2007, at 10:25 AM, Chris Dobbs wrote:

Futher update on this:
I tried it on another linux box and guess what ? yep, I get 512 passed

in as the length as expected.
Guess this means there is something not right with the other box,
anyone got and ideas what it could be. I am running with SDL1.2 in
tandem with the SDL_AudioIn project to provide microphone input.
Strange thing is I have looke thru some old logs and it definitley
used to behave correctly so unless I have installed something that’s
upset the sound layer or worse the dsp is shot.

-Chris
----- Original Message -----
From: Chris Dobbs
To: sdl at lists.libsdl.org
Sent: Saturday, April 28, 2007 4:28 PM
Subject: [SDL] callback issue

All,
Can someone verify if the following behaviour is correct (and if so
why) regarding audio output.

I have opened the audio device with following params:
frequency=8000
samples=256
channels=1
format=AUDIO_S16SYS

The audio callback routine I have assigned fires ok but the length
parameter passed to it is not 512 as I would expect, instead it is
340…!?

The way I understand this is that I have asked SDL to allow me to feed

in 256 16 bit samples (512 bytes) every time the callback fires.

Is this correct or am I missing something - It is possible that my DSP

has developed a problem as I have noticed odd crackles occasionally in

the speaker.
The OS is 2.6.18 custom on a DELL inspiron 6000

Any help is appreciated as usual.
-Chris


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Call SDL_MixAudio(stream, (const Uint8*)data_p, len, SDL_MIX_MAXVOLUME)

Don’t do that…currently the stream is always silence (so you don’t
have to mix against it, just memcpy), but since you’re expected to
completely fill the stream (with silence if nothing else), we’re
probably going to stop initializing the buffer before calling your
callback…in which case you’d be mixing against random noise.

–ryan.

What I do is (I have a video editor I’m making) I have a thread grab
and decode audio samples, and then I have a loop which keeps track of
the current audio sample and has a marker for the first unwritten
sample, then I write as much as I can of that sample to the audio
buffer and update the marker. If the marker is the same as the
length of the sample, then I’ve written everything in the sample, and
I grab the next sample from the thread, and continue writing to the
audio buffer if necessary.

It’s a rather complex loop for what it does. If you need some
pseudocode let me know and I can do that. But I have an essay to
write now so I’m going to hold off unless you need it. :slight_smile:

– ScottOn Apr 30, 2007, at 9:07 AM, <chris.2.dobbs at bt.com> <chris. 2.dobbs at bt.com> wrote:

Ok, thanks that kindof makes sense to me. Currently I do this in my
callback routine

void audio_out(void *userdata, Uint8 *stream, int len)
{

Lock internal data queue
Pull off queue len bytes of PCM data into data_p pointer
Call SDL_MixAudio(stream, (const Uint8*)data_p, len,
SDL_MIX_MAXVOLUME)
Unlock internal data queue

}

My internal data queue is populated by another thread which
receives AMR
data via network, decodes it to PCM and stuffs onto queue ready for
this
callback to playback.

Are you saying that I need to get the callback to play slightly before
the start of the next queue block retreived?

Many thanks for your help by the way!

-Chris

-----Original Message-----
From: sdl-bounces at lists.libsdl.org [mailto:sdl-
bounces at lists.libsdl.org]
On Behalf Of Scott Harper
Sent: 28 April 2007 18:25
To: A list for developers using the SDL library. (includes SDL-
announce)
Subject: Re: [SDL] callback issue

As far as I’m aware, the audio hardware on different systems will ask
for different amounts of audio data each callback, so your
responsibility is to provide it with however much data it asks for.
Often (for me, at least) this has meant playing through the end of one
sample/source and starting the next one just a little bit before the
next callback. It’s not clean, but the result sounds nice anyway.

– Scott

Many thanks Scott,
No need for pseudo code I think I see what u mean.
-Chris> ----- Original Message -----

From: sdl-bounces@lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org]
On Behalf Of Scott Harper
Sent: 01 May 2007 04:17
To: A list for developers using the SDL library. (includes SDL-announce)
Subject: Re: [SDL] callback issue

What I do is (I have a video editor I’m making) I have a thread grab and
decode audio samples, and then I have a loop which keeps track of the
current audio sample and has a marker for the first unwritten sample,
then I write as much as I can of that sample to the audio buffer and
update the marker. If the marker is the same as the length of the
sample, then I’ve written everything in the sample, and I grab the next
sample from the thread, and continue writing to the audio buffer if
necessary.

It’s a rather complex loop for what it does. If you need some
pseudocode let me know and I can do that. But I have an essay to write
now so I’m going to hold off unless you need it. :slight_smile:

– Scott

On Apr 30, 2007, at 9:07 AM, <@chris.2.dobbs_at_bt> <chris. 2.dobbs at bt.com> wrote:

Ok, thanks that kindof makes sense to me. Currently I do this in my
callback routine

void audio_out(void *userdata, Uint8 *stream, int len) {

Lock internal data queue
Pull off queue len bytes of PCM data into data_p pointer Call
SDL_MixAudio(stream, (const Uint8*)data_p, len,
SDL_MIX_MAXVOLUME)
Unlock internal data queue

}

My internal data queue is populated by another thread which receives
AMR data via network, decodes it to PCM and stuffs onto queue ready
for this callback to playback.

Are you saying that I need to get the callback to play slightly before

the start of the next queue block retreived?

Many thanks for your help by the way!

-Chris

-----Original Message-----
From: sdl-bounces at lists.libsdl.org [mailto:sdl-
bounces at lists.libsdl.org] On Behalf Of Scott Harper
Sent: 28 April 2007 18:25
To: A list for developers using the SDL library. (includes SDL-
announce)
Subject: Re: [SDL] callback issue

As far as I’m aware, the audio hardware on different systems will ask
for different amounts of audio data each callback, so your
responsibility is to provide it with however much data it asks for.
Often (for me, at least) this has meant playing through the end of one

sample/source and starting the next one just a little bit before the
next callback. It’s not clean, but the result sounds nice anyway.

– Scott


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Aha…that could account for the odd crackiling I keep hearing. The
reason I started using mixaudio was because the callback I am using can
potentially playback from two separate sources (which I want to playback
simultaneously).
-Chris> ----- Original Message -----

From: sdl-bounces@lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org]
On Behalf Of Ryan C. Gordon
Sent: 30 April 2007 21:19
To: A list for developers using the SDL library. (includes SDL-announce)
Subject: Re: [SDL] callback issue

Call SDL_MixAudio(stream, (const Uint8*)data_p, len,
SDL_MIX_MAXVOLUME)

Don’t do that…currently the stream is always silence (so you don’t
have to mix against it, just memcpy), but since you’re expected to
completely fill the stream (with silence if nothing else), we’re
probably going to stop initializing the buffer before calling your
callback…in which case you’d be mixing against random noise.

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Yes, that did it, I have crystal clear playback now!
As I said earilier this callback looks in two sources for playback data,
one contains captured microphone input, the other data received via
network; Both are not present all the time so do I need to call
SDL_MixAudio() if both are present? Or just memcpy both if and when they
are present?

Like this:

Got buff_A data?
memcpy(stream…
Got buff_B data?
memcpy (stream…

Regards,
-Chris> ----- Original Message -----

From: sdl-bounces@lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org]
On Behalf Of Ryan C. Gordon
Sent: 30 April 2007 21:19
To: A list for developers using the SDL library. (includes SDL-announce)
Subject: Re: [SDL] callback issue

Call SDL_MixAudio(stream, (const Uint8*)data_p, len,
SDL_MIX_MAXVOLUME)

Don’t do that…currently the stream is always silence (so you don’t
have to mix against it, just memcpy), but since you’re expected to
completely fill the stream (with silence if nothing else), we’re
probably going to stop initializing the buffer before calling your
callback…in which case you’d be mixing against random noise.

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

network; Both are not present all the time so do I need to call
SDL_MixAudio() if both are present? Or just memcpy both if and when they
are present?

Like this:

Got buff_A data?
memcpy(stream…
Got buff_B data?
memcpy (stream…

If you memcpy() both in the same call, the second one will just
overwrite the first, of course. If you need two or more things to mix
together to be played back at the same time, you should memcpy() the
first thing and then use SDL_MixAudio() or something similar to add each
of the rest to the stream. Or memset() the stream and then mix all the
sources, if you find the code is cleaner and don’t mind the extra memory
bandwidth.

But if you just have one data stream, using SDL_MixAudio is either
wasteful (since a memcpy() will be faster when mixing against silence),
or dangerous (if the stream we pass in ceases to be initialized for you
in the future).

–ryan.

Must admit I just blindly used SDL_MixAudio() as it was in one of the
samples; as usual the devil is in the detail and lazyness has done for
me again…makes much more sense now.
Many thanks once again Ryan.

BTW do you know if there any plans to incorperate libSDL_audioin into
SDL proper? Or is it always going to be an external add on library?
-Chris> ----- Original Message -----

From: sdl-bounces@lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org]
On Behalf Of Ryan C. Gordon
Sent: 01 May 2007 09:50
To: A list for developers using the SDL library. (includes SDL-announce)
Subject: Re: [SDL] callback issue

network; Both are not present all the time so do I need to call
SDL_MixAudio() if both are present? Or just memcpy both if and when
they are present?

Like this:

Got buff_A data?
memcpy(stream…
Got buff_B data?
memcpy (stream…

If you memcpy() both in the same call, the second one will just
overwrite the first, of course. If you need two or more things to mix
together to be played back at the same time, you should memcpy() the
first thing and then use SDL_MixAudio() or something similar to add each
of the rest to the stream. Or memset() the stream and then mix all the
sources, if you find the code is cleaner and don’t mind the extra memory
bandwidth.

But if you just have one data stream, using SDL_MixAudio is either
wasteful (since a memcpy() will be faster when mixing against silence),
or dangerous (if the stream we pass in ceases to be initialized for you
in the future).

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

BTW do you know if there any plans to incorperate libSDL_audioin into
SDL proper? Or is it always going to be an external add on library?

Audio capture is going into SDL 1.3 … It’s not SDL_audioin, but it’s
similar (in that SDL_audioin is similar to the SDL 1.2 audio API).

–ryan.