Why does this click? (version 2)

Hi again,

Here’s an even simpler example of something that clicks, which writes exactly
"len" bytes directly to the “stream” pointer passed to mix(), and is
generating audio data immediately on entry to the function. Incidentally,
the duration between the clicks is directly proportional to the value of
"desired.samples" . Is there some sort of buffering or locking thing I have
to do?

It compiles with “gcc -Wall sdlsound.c -lSDL”.-

#include <SDL/SDL.h>
#include <SDL/SDL_audio.h>

#define sinf __builtin_sinf
#define printf __builtin_printf
#define exit __builtin_exit
#define M_PI 3.14159265358979323846

#define AUDIO_FREQ 44100;

float sine_pos = 0;
float sine_speed = M_PI * 2 * 440 / AUDIO_FREQ;

void mix(void* data, Uint8* stream, int len)
{
Uint8* s_ptr;
Uint8* stream_end = stream + len;

for (s_ptr = stream; s_ptr < stream_end; s_ptr+= sizeof(Sint16)) {
    *((Sint16*) s_ptr) = (Sint16) (16000.0f * sinf(sine_pos));
    sine_pos += sine_speed;
}

}

void init()
{
SDL_AudioSpec desired;
SDL_AudioSpec obtained;

desired.freq = AUDIO_FREQ;
desired.format = AUDIO_S16SYS;
desired.channels = 1;
desired.samples = 8192;
desired.callback = mix;
desired.userdata = NULL;

if (SDL_OpenAudio(&desired, &obtained) < 0) {
printf("Failed to open audio: %s\n", SDL_GetError()); exit(1);
} else if (desired.format != AUDIO_S16SYS) {
printf("Failed to open correct audio format\n"); exit(1);        
}

}

int main(int argc, char* argv[])
{
init();
SDL_PauseAudio(0);
SDL_Delay(10000);
SDL_PauseAudio(1);

return 0;

}

Hi again,

Here’s an even simpler example of something that clicks, which writes exactly
"len" bytes directly to the “stream” pointer passed to mix(), and is
generating audio data immediately on entry to the function. Incidentally,
the duration between the clicks is directly proportional to the value of
"desired.samples" . Is there some sort of buffering or locking thing I have
to do?

Yes, the minimum buffer size depends on the operating system, drivers, and
audio frequency.

For 22050 Hz, I typically use a sample size of 1024 or 2048, scaling
appropriately if I use a different frequency.

-Sam Lantinga, Senior Software Engineer, Blizzard Entertainment

Here’s an even simpler example of something that clicks, which writes exactly
"len" bytes directly to the “stream” pointer passed to mix(), and is
generating audio data immediately on entry to the function. Incidentally,
the duration between the clicks is directly proportional to the value of
"desired.samples" . Is there some sort of buffering or locking thing I have
to do?

Although 8192 samples at 44100 should be fine. What’s your audio hardware
and driver subsystem?

-Sam Lantinga, Senior Software Engineer, Blizzard Entertainment

Tried it on a Sony laptop with a VIA soundchip, and an AMD system with a 64
channel SB Audigy card in it.

Both using ALSA. In the case of the Sony laptop, I tried it with both with
dmix enabled and disabled (dmix is enabled by default on kernels >=2.6.15).

Even ramping the samples up to 16384 didn’t stop the clicks (it just halved
the number…). It appears to click every second buffer swap.

Oh yeah - in the code, I note that I forgot to call SDL_Init(SDL_INIT_AUDIO).
I’ve now added that, but it hasn’t affected anything.

<fx: bangs head on table>

cheers for the help thus far,

GilesOn Wednesday 01 March 2006 15:31, Sam Lantinga wrote:

Here’s an even simpler example of something that clicks, which writes
exactly “len” bytes directly to the “stream” pointer passed to mix(), and
is generating audio data immediately on entry to the function.
Incidentally, the duration between the clicks is directly proportional to
the value of “desired.samples” . Is there some sort of buffering or
locking thing I have to do?

Although 8192 samples at 44100 should be fine. What’s your audio hardware
and driver subsystem?

Blah… just tried it on an ubuntu box. NO CLICKS! Tried it on a fedora box.
NO CLICKS!

It appears to be a problem with both of my gentoo boxes. I’ve filed a bug
report with gentoo development.

cheers for everyone’s help,

GilesOn Wednesday 01 March 2006 16:45, I wrote:

Tried it on a Sony laptop with a VIA soundchip, and an AMD system with a 64
channel SB Audigy card in it.