The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
question about SDL_audio
jeroen.clarysse


Joined: 22 Feb 2010
Posts: 69
i’ve been looking at the loopwave sample, but can find out where the actual LOOPING happens…

there is a call to LoadWav to fill the SDL_AudioSpec structure, then a call to SDL_OpenAudio to open the audio device, and then SDL_PauseAudio(0) to start playing

the callback fillerup does the actuall buffer filling:


fillerup(void *unused, Uint8 * stream, int len)
{
Uint8 *waveptr;
int waveleft;

/* Set up the pointers */
waveptr = wave.sound + wave.soundpos;
waveleft = wave.soundlen - wave.soundpos;

/* Go! */
while (waveleft <= len) {
SDL_memcpy(stream, waveptr, waveleft);
stream += waveleft;
len -= waveleft;
waveptr = wave.sound;
waveleft = wave.soundlen;
wave.soundpos = 0;
}
SDL_memcpy(stream, waveptr, len);
wave.soundpos += len;
}

the first two lines are just declarations
the next two lines determine where to start filling and how much there will be left of the data after filling
then there is a loop until we reached the passed amount (len)

where is the actual repeating of the sound done ?


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
David Olofson
Guest

On Tue, Apr 19, 2016 at 12:03 PM, jeroen clarysse
wrote:
[...]
Quote:
fillerup(void *unused, Uint8 * stream, int len)
{
Uint8 *waveptr;
int waveleft;

/* Set up the pointers */
waveptr = wave.sound + wave.soundpos;
waveleft = wave.soundlen - wave.soundpos;

/* Go! */
while (waveleft <= len) {
SDL_memcpy(stream, waveptr, waveleft);
stream += waveleft;
len -= waveleft;
waveptr = wave.sound;
waveleft = wave.soundlen;
wave.soundpos = 0;
}
SDL_memcpy(stream, waveptr, len);
wave.soundpos += len;
}
[...]
Quote:
where is the actual repeating of the sound done ?

It's a bit "backwards," as the looping is in terms of the source index
(wave.soundpos) rather than the write index. :-)

What happens is, if there's less than a full output buffer's worth of
wave data left, the while() loop is entered, takes care of that,
resets the index, and then the final SDL_memcpy() takes care of any
remaining samples.

The reason it's while() and not if() is that the output buffer may be
larger than the wave. Typically, it'll be the other way around, so the
while() will only be entered when the loop point falls within the
current output buffer.


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
jeroen.clarysse


Joined: 22 Feb 2010
Posts: 69
aha… that explains it a bit… but where do I turn off the looping ? I just want to play the sound ONCE...

Quote:
On Tue, Apr 19, 2016 at 12:03 PM, jeroen clarysse
wrote:
[...]
Quote:
fillerup(void *unused, Uint8 * stream, int len)
{
Uint8 *waveptr;
int waveleft;

/* Set up the pointers */
waveptr = wave.sound + wave.soundpos;
waveleft = wave.soundlen - wave.soundpos;

/* Go! */
while (waveleft <= len) {
SDL_memcpy(stream, waveptr, waveleft);
stream += waveleft;
len -= waveleft;
waveptr = wave.sound;
waveleft = wave.soundlen;
wave.soundpos = 0;
}
SDL_memcpy(stream, waveptr, len);
wave.soundpos += len;
}
[...]
Quote:
where is the actual repeating of the sound done ?

It's a bit "backwards," as the looping is in terms of the source index
(wave.soundpos) rather than the write index. :-)

What happens is, if there's less than a full output buffer's worth of
wave data left, the while() loop is entered, takes care of that,
resets the index, and then the final SDL_memcpy() takes care of any
remaining samples.

The reason it's while() and not if() is that the output buffer may be
larger than the wave. Typically, it'll be the other way around, so the
while() will only be entered when the loop point falls within the
current output buffer.


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
David Olofson
Guest

On Tue, Apr 19, 2016 at 12:57 PM, jeroen clarysse
wrote:
Quote:
aha… that explains it a bit… but where do I turn off the looping ? I just want to play the sound ONCE...

Well, the "wave.soundpos = 0;" line is where the wave is looped.
Remove that, replace the final SDL_memcpy() with an SDL_memset() or
something (in SDL2, buffer contents is undefined when the callback is
entered!), and remove the final "wave.soundpos += len;", so it just
sits there outputting silence after the end of the wave. Something
like that. I leave it as an exercise for the reader to implement and
debug the logic. ;-)


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
jeroen.clarysse


Joined: 22 Feb 2010
Posts: 69
thanks for that info !!

but I’m still a bit stuck about the whole concept of that callback :

you are provided with :
* a pointer to userdata that you can use to fetch audio from
* a stream that you need to copy audio into
* a len parameter than determines the size of stream so you don’t copy out-of-bounds

The documentation says that this callback is invoked "with some frequency”.


- will the stream always be “at the start” ? Or do I have to fill it somewhere in the middle sometimes ?
- do I have to fill the stream from 0 to len-1 ?
- why do all the sample-code tutorials use a loop to fill the stream ? Why not just fill it with ONE big SDL_memcpy of size min(len, size_of_sound_file) and then fill the rest with zeroes in one additional memcpy if size_of_sound_file < len ?? I don’t see the point of this while loop


sorry if I come over as a newbie, but the documentation is a bit fuzzy to me



Quote:
On Tue, Apr 19, 2016 at 12:57 PM, jeroen clarysse
wrote:
Quote:
aha… that explains it a bit… but where do I turn off the looping ? I just want to play the sound ONCE...

Well, the "wave.soundpos = 0;" line is where the wave is looped.
Remove that, replace the final SDL_memcpy() with an SDL_memset() or
something (in SDL2, buffer contents is undefined when the callback is
entered!), and remove the final "wave.soundpos += len;", so it just
sits there outputting silence after the end of the wave. Something
like that. I leave it as an exercise for the reader to implement and
debug the logic. ;-)


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
jeroen.clarysse


Joined: 22 Feb 2010
Posts: 69
oh, and I forgot one part that is also bothering me : if I want to play a short audio at irregular intervals, should I call SDL_OpenAudio at the moment where I want to start playing, and start SDL_PauseAudio(0)at the beginning and leave it like that throughout the whole session ? Or should I call SDL_PauseAudio(1) whenever the sound is done ?


I find it difficult to understand which calls I need to use :


- SDL_LoadWAV is used to fetch the wav file from disk
- SDL_OpenAudio is used to initialize the callback
- SDL_PauseAudio is used to start the callback-loop

can I call SDL_CloseAudio from within the callback when my sound is done, and then have it re-open at a later time, or is this a slow/stupid thing to do ? Should I call SDL_OpenAudio also at the beginning of the session ? how then can my callback know when to actually start playing ?


i’m really sorry to come over so un-educated

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
David Olofson
Guest

On Fri, Apr 22, 2016 at 11:17 AM, jeroen clarysse
wrote:
[...]
Quote:
- will the stream always be “at the start” ? Or do I have to fill it somewhere in the middle sometimes ?

It's really just a buffer from the callback's perspective.


Quote:
- do I have to fill the stream from 0 to len-1 ?

Yes.


Quote:
- why do all the sample-code tutorials use a loop to fill the stream ? Why not just fill it with ONE big SDL_memcpy of size min(len, size_of_sound_file) and then fill the rest with zeroes in one additional memcpy if size_of_sound_file < len ?? I don’t see the point of this while loop

Haven't examined the other examples closely, but I suspect the idea
for the looping one(s?) is that it's expected to do the right thing
(as in, loop seamlessly) even if the output buffer is longer than the
waveform. But if you're only ever copying one fragment of the waveform
in each callback, sure; the loop is unnecessary.


Quote:
sorry if I come over as a newbie, but the documentation is a bit fuzzy to me

Well, this is a low level API for low latency realtime audio, and it's
based on the same principles as any other audio API of this type. So,
you're not really supposed to go that low level unless you're
implementing an audio engine or similar - and if you are, you're
expected to be familiar with the relevant concepts. In short, it's an
API for weirdos like yours truly. ;-)


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
jeroen.clarysse


Joined: 22 Feb 2010
Posts: 69
awesome. Many thanks for all that info. I get one step closer to actually playing audio :-)


I’ve contemplated using SDL_mixer, which is probably the best thing to do, but I also want as little latency as possible : for our program, getting the sound out the speakers as fast as possible is rather crucial. I know that there are a ton of variables beyond my control (such as the operating system) so we will have to add a lot of testing to figure out how variable the actual delay between “start sound” and “hearing sound” is. I plan to loop the audio into a second computer together with a TTL signal from the first computer, which gets raised when “start sound” is issued. That should give me an idea of the latencies







Quote:
On Fri, Apr 22, 2016 at 11:17 AM, jeroen clarysse
wrote:
[...]
Quote:
- will the stream always be “at the start” ? Or do I have to fill it somewhere in the middle sometimes ?

It's really just a buffer from the callback's perspective.


Quote:
- do I have to fill the stream from 0 to len-1 ?

Yes.


Quote:
- why do all the sample-code tutorials use a loop to fill the stream ? Why not just fill it with ONE big SDL_memcpy of size min(len, size_of_sound_file) and then fill the rest with zeroes in one additional memcpy if size_of_sound_file < len ?? I don’t see the point of this while loop

Haven't examined the other examples closely, but I suspect the idea
for the looping one(s?) is that it's expected to do the right thing
(as in, loop seamlessly) even if the output buffer is longer than the
waveform. But if you're only ever copying one fragment of the waveform
in each callback, sure; the loop is unnecessary.


Quote:
sorry if I come over as a newbie, but the documentation is a bit fuzzy to me

Well, this is a low level API for low latency realtime audio, and it's
based on the same principles as any other audio API of this type. So,
you're not really supposed to go that low level unless you're
implementing an audio engine or similar - and if you are, you're
expected to be familiar with the relevant concepts. In short, it's an
API for weirdos like yours truly. ;-)


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
David Olofson
Guest

On Fri, Apr 22, 2016 at 11:25 AM, jeroen clarysse
wrote:
Quote:
oh, and I forgot one part that is also bothering me : if I want to play a short audio at irregular intervals, should I call SDL_OpenAudio at the moment where I want to start playing, and start SDL_PauseAudio(0)at the beginning and leave it like that throughout the whole session ? Or should I call SDL_PauseAudio(1) whenever the sound is done ?

The typical use of SDL_PauseAudio() is just to enable the audio
callback once, as soon as you're ready for action.

(An audio engine typically needs to allocate buffers, calculate filter
cores and whatnot, and you need to know the actual sample rate, buffer
size etc before you can do that. That's why audio starts paused, so
you don't have the callback firing in the middle of initialization.)


Quote:
I find it difficult to understand which calls I need to use :


- SDL_LoadWAV is used to fetch the wav file from disk

Just a utility function. If you have your own loaders, use external
file I/O libs, you don't need this.


Quote:
- SDL_OpenAudio is used to initialize the callback
- SDL_PauseAudio is used to start the callback-loop

Yep.


Quote:
can I call SDL_CloseAudio from within the callback when my sound is done, and then have it re-open at a later time, or is this a slow/stupid thing to do ?

You might get away with this in some environments, but generally
speaking, this is asking for a crash or deadlock. Don't do that! :-)

Basically, you should assume that the audio callback runs in interrupt
context (which it actually does on some old SDL 1.2 platforms!), which
means no system calls, no memory allocations, no locks, no blocking
calls etc. (This is actually a pretty hairy subject...)


Quote:
Should I call SDL_OpenAudio also at the beginning of the session ? how then can my callback know when to actually start playing ?

(That's actually related to the aforementioned hairy subject.)
Typically, you'll have an audio engine running via the callback, and
the application tells the callback what to do via some form of state
updates, messages or similar. This should preferably be lock free to
avoid priority inversion, which can result in audio glitches.

In very simple cases, you can get away with just having some atomic
values (integers typically) that the callback checks and responds to,
but this quickly becomes a lot more complicated than it sounds. (Start
by reading up on "race conditions" if you're interested in that.)

What I usually do is use a lock-free FIFO or similar construct, to
safely pass proper "commands" to the audio callback. If the
application needs to know what the audio callback is up to, you can
use another lock-free FIFO to pass messages in the other direction.
There are a few different implementations of lock-free FIFOs around.


Quote:
i’m really sorry to come over so un-educated

No worries. This subject is a lot more complicated than it may seem at
first, and that's why most people just use some existing audio engine
with a higher level API instead. :-)


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
jeroen.clarysse


Joined: 22 Feb 2010
Posts: 69
reading all this, I am reconsidering my choice to not use SDL_mixer. I guess I’m only making things harder for myself at the cost of instability


Quote:
On 22 Apr 2016, at 13:12, David Olofson wrote:

On Fri, Apr 22, 2016 at 11:25 AM, jeroen clarysse
wrote:
Quote:
oh, and I forgot one part that is also bothering me : if I want to play a short audio at irregular intervals, should I call SDL_OpenAudio at the moment where I want to start playing, and start SDL_PauseAudio(0)at the beginning and leave it like that throughout the whole session ? Or should I call SDL_PauseAudio(1) whenever the sound is done ?

The typical use of SDL_PauseAudio() is just to enable the audio
callback once, as soon as you're ready for action.

(An audio engine typically needs to allocate buffers, calculate filter
cores and whatnot, and you need to know the actual sample rate, buffer
size etc before you can do that. That's why audio starts paused, so
you don't have the callback firing in the middle of initialization.)


Quote:
I find it difficult to understand which calls I need to use :


- SDL_LoadWAV is used to fetch the wav file from disk

Just a utility function. If you have your own loaders, use external
file I/O libs, you don't need this.


Quote:
- SDL_OpenAudio is used to initialize the callback
- SDL_PauseAudio is used to start the callback-loop

Yep.


Quote:
can I call SDL_CloseAudio from within the callback when my sound is done, and then have it re-open at a later time, or is this a slow/stupid thing to do ?

You might get away with this in some environments, but generally
speaking, this is asking for a crash or deadlock. Don't do that! :-)

Basically, you should assume that the audio callback runs in interrupt
context (which it actually does on some old SDL 1.2 platforms!), which
means no system calls, no memory allocations, no locks, no blocking
calls etc. (This is actually a pretty hairy subject...)


Quote:
Should I call SDL_OpenAudio also at the beginning of the session ? how then can my callback know when to actually start playing ?

(That's actually related to the aforementioned hairy subject.)
Typically, you'll have an audio engine running via the callback, and
the application tells the callback what to do via some form of state
updates, messages or similar. This should preferably be lock free to
avoid priority inversion, which can result in audio glitches.

In very simple cases, you can get away with just having some atomic
values (integers typically) that the callback checks and responds to,
but this quickly becomes a lot more complicated than it sounds. (Start
by reading up on "race conditions" if you're interested in that.)

What I usually do is use a lock-free FIFO or similar construct, to
safely pass proper "commands" to the audio callback. If the
application needs to know what the audio callback is up to, you can
use another lock-free FIFO to pass messages in the other direction.
There are a few different implementations of lock-free FIFOs around.


Quote:
i’m really sorry to come over so un-educated

No worries. This subject is a lot more complicated than it may seem at
first, and that's why most people just use some existing audio engine
with a higher level API instead. :-)


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
David Olofson
Guest

On Fri, Apr 22, 2016 at 1:29 PM, jeroen clarysse
wrote:
Quote:
reading all this, I am reconsidering my choice to not use SDL_mixer. I guess I’m only making things harder for myself at the cost of instability
[...]
Yeah... This might not be something you want to dive into unless you
really have to, or you're really interested in learning about it.

As to SDL_mixer, AFAIK, it doesn't add any extra buffering, so it
shouldn't affect latency.

Be warned though, that it uses locking to synchronize API calls with
the audio context, which is no a great solution if you have zero
tolerance for glitches. That said, locking is probably not your
biggest issue, unless you're on a finely tuned audio workstation, an
embedded system with a Linux lowlatency kernel or similar.


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
jeroen.clarysse


Joined: 22 Feb 2010
Posts: 69
the amount of sounds played will be very small : usually only one sound and a very very short one (50 msec)

I’m in charge of writing the code for our psychology experiments where we “startle” subjects with a very short but loud “probe” (around 100dB, so very loud) and then measure their eyeblink response time.

usually, such sound probes are administered via hardware units that get triggered via a TTL signal from a PC, but i’m investigating the accuracy when using software sound via a PC.

i’m rather curious about the results :-)



Quote:
On Fri, Apr 22, 2016 at 1:29 PM, jeroen clarysse
wrote:
Quote:
reading all this, I am reconsidering my choice to not use SDL_mixer. I guess I’m only making things harder for myself at the cost of instability
[...]
Yeah... This might not be something you want to dive into unless you
really have to, or you're really interested in learning about it.

As to SDL_mixer, AFAIK, it doesn't add any extra buffering, so it
shouldn't affect latency.

Be warned though, that it uses locking to synchronize API calls with
the audio context, which is no a great solution if you have zero
tolerance for glitches. That said, locking is probably not your
biggest issue, unless you're on a finely tuned audio workstation, an
embedded system with a Linux lowlatency kernel or similar.


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
David Olofson
Guest

On Fri, Apr 22, 2016 at 2:17 PM, jeroen clarysse
wrote:
Quote:
the amount of sounds played will be very small : usually only one sound and a very very short one (50 msec)

I’m in charge of writing the code for our psychology experiments where we “startle” subjects with a very short but loud “probe” (around 100dB, so very loud) and then measure their eyeblink response time.
[...]

Doesn't that mean that controlling (or even just knowing) exactly when
the probe sound is played, is more important than "command latency?"

If so, I'm not sure using minimal buffer sizes and just trying to keep
latency low is the way to go. That only makes it harder to guarantee
stability and accuracy, especially if you're on a general purpose OS
without proper realtime scheduling. Theoretically, you could use huge
buffers and still achieve sub-sample accurate timing, but the tricky
part is keeping track of exactly when each buffer reaches the audio
outputs. Most audio APIs are severely lacking in that department, and
the best you can do is measure the latency from callback to output,
and hope that's consistent. The only way to be sure is to use
dedicated hardware. If you're writing an application that people will
run on random computers, I'm afraid things are going to have to be
configured and calibrated for each install.

Oh, and there's plenty of "fun" stuff to discover in that area, like this: ;-)

https://github.com/olofson/audiality2/issues/209

(Haven't really solved that. Just reduced the risk of running into it
by changing the default sample rate to 48 kHz, which seems to be much
more common than 44.1 kHz these days.)


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
jeroen.clarysse


Joined: 22 Feb 2010
Posts: 69
Quote:
On 22 Apr 2016, at 14:37, David Olofson wrote:

On Fri, Apr 22, 2016 at 2:17 PM, jeroen clarysse
wrote:
Quote:
the amount of sounds played will be very small : usually only one sound and a very very short one (50 msec)

I’m in charge of writing the code for our psychology experiments where we “startle” subjects with a very short but loud “probe” (around 100dB, so very loud) and then measure their eyeblink response time.
[...]

Doesn't that mean that controlling (or even just knowing) exactly when
the probe sound is played, is more important than "command latency?”

yep. Latency itself is irrelevant as long as it is low in variance and not excessive. I’d prefer to have a constant latency between 95 and 100 milliseconds over a variable latency between 20 and 50 milliseconds.


Quote:
If so, I'm not sure using minimal buffer sizes and just trying to keep
latency low is the way to go. That only makes it harder to guarantee
stability and accuracy, especially if you're on a general purpose OS
without proper realtime scheduling. Theoretically, you could use huge
buffers and still achieve sub-sample accurate timing, but the tricky
part is keeping track of exactly when each buffer reaches the audio
outputs.

hm.. and can SDL_mixer manipulate that buffer size ? I’ll build my app with configurability in mind so those settings can be read from a config file. I guess I’ll have to play with these options a bit


Quote:
Most audio APIs are severely lacking in that department, and
the best you can do is measure the latency from callback to output,
and hope that's consistent. The only way to be sure is to use
dedicated hardware. If you're writing an application that people will
run on random computers, I'm afraid things are going to have to be
configured and calibrated for each install.

yup : we will need some sort of calibration box. The biggest issue with such a box is : you need at least ONE way to communicate accurately (in terms of timing) with that box ! If the box itself has a latency when receiving the “start calibration” command, you’re still in limbo. And USB isn’t perfect on all computers either !

so far, we use TTL, but parallel ports have become obsolete, so that is an issue as well



Quote:
Oh, and there's plenty of "fun" stuff to discover in that area, like this: ;-)

https://github.com/olofson/audiality2/issues/209

(Haven't really solved that. Just reduced the risk of running into it
by changing the default sample rate to 48 kHz, which seems to be much
more common than 44.1 kHz these days.)

I couldn’t even understand half of what you were explaining :-)
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
David Olofson
Guest

On Fri, Apr 22, 2016 at 2:43 PM, jeroen clarysse
wrote:
[...]
Quote:
hm.. and can SDL_mixer manipulate that buffer size ? I’ll build my app with configurability in mind so those settings can be read from a config file. I guess I’ll have to play with these options a bit

Mix_OpenAudio[Device]() just forwards the requested buffer size to
SDL_OpenAudioDevice(), so the behavior should be the same.


Quote:
Quote:
[...audio APIs and latency management...]

yup : we will need some sort of calibration box. The biggest issue with such a box is : you need at least ONE way to communicate accurately (in terms of timing) with that box ! If the box itself has a latency when receiving the “start calibration” command, you’re still in limbo. And USB isn’t perfect on all computers either !

Yeah... The easiest "fool proof" way is usually to somehow turn the
relevant events into analog audio signals, and record all sources
using one or more channels on another sound card. (A small USB sound
interface for studio use, for example.) Any reasonably well designed
sound card should have zero phase difference between channels, so you
should get extremely accurate measurements that way, even if you use
one input for each source.


Quote:
so far, we use TTL, but parallel ports have become obsolete, so that is an issue as well

Speaking of which, this thing seems like a perfect platform for things
like this:

http://bela.io/


[...]
Quote:
Quote:
https://github.com/olofson/audiality2/issues/209
[...]
Quote:
I couldn’t even understand half of what you were explaining :-)

TL;DR: Make sure you're using the native sample rate of the hardware,
to avoid weird callback timing. :-)


--
//David Olofson - Consultant, Developer, Artist, Open Source Advocate

.--- Games, examples, libraries, scripting, sound, music, graphics ---.
| http://consulting.olofson.net http://olofsonarcade.com |
'---------------------------------------------------------------------'
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
jeroen.clarysse


Joined: 22 Feb 2010
Posts: 69
Quote:

Yeah... The easiest "fool proof" way is usually to somehow turn the
relevant events into analog audio signals, and record all sources
using one or more channels on another sound card. (A small USB sound
interface for studio use, for example.) Any reasonably well designed
sound card should have zero phase difference between channels, so you
should get extremely accurate measurements that way, even if you use
one input for each source.


that is actually a VERY COOL idea !

Quote:
Quote:
so far, we use TTL, but parallel ports have become obsolete, so that is an issue as well

Speaking of which, this thing seems like a perfect platform for things
like this:

http://bela.io/

unfortunately that is still in kickstarter-phase… I was thinking arduino for now
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
Ryan C. Gordon
Guest

Quote:
oh, and I forgot one part that is also bothering me : if I want to play
a short audio at irregular intervals, should I call SDL_OpenAudio at
the moment where I want to start playing, and start SDL_PauseAudio(0)at
the beginning and leave it like that throughout the whole session ? Or
should I call SDL_PauseAudio(1) whenever the sound is done ?

SDL_OpenAudio() tends to be an expensive call (SDL has to obtain
hardware from the operating system, things can go wrong, etc).
SDL_PauseAudio() just sets a flag and returns, so you probably want to
do that.

Once the audio is unpaused, within a few milliseconds, your callback
will start firing on a different thread.

Quote:
can I call SDL_CloseAudio from within the callback when my sound is
done, and then have it re-open at a later time, or is this a
slow/stupid thing to do ? Should I call SDL_OpenAudio also at the
beginning of the session ? how then can my callback know when to
actually start playing ?

I'm not sure it would be safe to call CloseAudio from inside the
callback. I've never tried. It's probably safe to pause the audio from
inside the callback, but:

I'd recommend you just write silence to the output stream and return
immediately in the callback if you don't have anything to play at the
moment, and leave it unpaused all the time. Open the device at program
startup, close it at shutdown. This is efficient and safe.

Quote:
i’m really sorry to come over so un-educated

No worries, the audio subsystem is sort of hard to understand at first
glance.

--ryan.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
Ryan C. Gordon
Guest

Quote:
oh, and I forgot one part that is also bothering me : if I want to play
a short audio at irregular intervals, should I call SDL_OpenAudio at
the moment where I want to start playing, and start SDL_PauseAudio(0)at
the beginning and leave it like that throughout the whole session ? Or
should I call SDL_PauseAudio(1) whenever the sound is done ?

SDL_OpenAudio() tends to be an expensive call (SDL has to obtain
hardware from the operating system, things can go wrong, etc).
SDL_PauseAudio() just sets a flag and returns, so you probably want to
do that.

Once the audio is unpaused, within a few milliseconds, your callback
will start firing on a different thread.

Quote:
can I call SDL_CloseAudio from within the callback when my sound is
done, and then have it re-open at a later time, or is this a
slow/stupid thing to do ? Should I call SDL_OpenAudio also at the
beginning of the session ? how then can my callback know when to
actually start playing ?

I'm not sure it would be safe to call CloseAudio from inside the
callback. I've never tried. It's probably safe to pause the audio from
inside the callback, but:

I'd recommend you just write silence to the output stream and return
immediately in the callback if you don't have anything to play at the
moment, and leave it unpaused all the time. Open the device at program
startup, close it at shutdown. This is efficient and safe.

Quote:
i’m really sorry to come over so un-educated

No worries, the audio subsystem is sort of hard to understand at first
glance.

--ryan.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
Ryan C. Gordon
Guest

Quote:
oh, and I forgot one part that is also bothering me : if I want to play
a short audio at irregular intervals, should I call SDL_OpenAudio at
the moment where I want to start playing, and start SDL_PauseAudio(0)at
the beginning and leave it like that throughout the whole session ? Or
should I call SDL_PauseAudio(1) whenever the sound is done ?

SDL_OpenAudio() tends to be an expensive call (SDL has to obtain
hardware from the operating system, things can go wrong, etc).
SDL_PauseAudio() just sets a flag and returns, so you probably want to
do that.

Once the audio is unpaused, within a few milliseconds, your callback
will start firing on a different thread.

Quote:
can I call SDL_CloseAudio from within the callback when my sound is
done, and then have it re-open at a later time, or is this a
slow/stupid thing to do ? Should I call SDL_OpenAudio also at the
beginning of the session ? how then can my callback know when to
actually start playing ?

I'm not sure it would be safe to call CloseAudio from inside the
callback. I've never tried. It's probably safe to pause the audio from
inside the callback, but:

I'd recommend you just write silence to the output stream and return
immediately in the callback if you don't have anything to play at the
moment, and leave it unpaused all the time. Open the device at program
startup, close it at shutdown. This is efficient and safe.

Quote:
i’m really sorry to come over so un-educated

No worries, the audio subsystem is sort of hard to understand at first
glance.

--ryan.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
question about SDL_audio
Ryan C. Gordon
Guest

Quote:
I'd recommend you just write silence to the output stream and return
immediately in the callback if you don't have anything to play at the
moment, and leave it unpaused all the time. Open the device at program
startup, close it at shutdown. This is efficient and safe.

Another option, if you have SDL 2.0.4, is to specify NULL for a callback
and use SDL_QueueAudio() to push more sound data when it's available and
let SDL handle the details for you.

/**
* Queue more audio on non-callback devices.
*
* SDL offers two ways to feed audio to the device: you can either
supply a
* callback that SDL triggers with some frequency to obtain more audio
* (pull method), or you can supply no callback, and then SDL will expect
* you to supply data at regular intervals (push method) with this
function.
*
* There are no limits on the amount of data you can queue, short of
* exhaustion of address space. Queued data will drain to the device as
* necessary without further intervention from you. If the device needs
* audio but there is not enough queued, it will play silence to make up
* the difference. This means you will have skips in your audio playback
* if you aren't routinely queueing sufficient data.
*
* This function copies the supplied data, so you are safe to free it when
* the function returns. This function is thread-safe, but queueing to the
* same device from two threads at once does not promise which buffer will
* be queued first.
*
* You may not queue audio on a device that is using an
application-supplied
* callback; doing so returns an error. You have to use the audio callback
* or queue audio with this function, but not both.
*
* You should not call SDL_LockAudio() on the device before queueing; SDL
* handles locking internally for this function.
*
* \param dev The device ID to which we will queue audio.
* \param data The data to queue to the device for later playback.
* \param len The number of bytes (not samples!) to which (data) points.
* \return zero on success, -1 on error.
*
* \sa SDL_GetQueuedAudioSize
* \sa SDL_ClearQueuedAudio
*/
extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const
void *data, Uint32 len);


--ryan.


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org