SDL_audio code..no need for function parame ters? Help please

----In the code below, I’m wondering why the function fillerup can be called
like this ONLY:

wave.spec.callback = fillerup;

----When the function itself takes the form:

void SDLCALL fillerup(void *unused, Uint8 *stream, int len)

Doesn’t it need parameters or arguments???-----------------------------------------------------------------------------

/* Program to load a wave file and loop playing it using SDL sound */

/* loopwaves.c is much more robust in handling WAVE files –
This is only for simple WAVEs
*/
#include “SDL_config.h”

#include <stdio.h>
#include <stdlib.h>

#if HAVE_SIGNAL_H
#include <signal.h>
#endif

#include “SDL.h”
#include “SDL_audio.h”

static double volume = 1.0f;
struct {
SDL_AudioSpec spec;
Uint8 sound; / Pointer to wave data /
Uint32 soundlen; /
Length of wave data /
int soundpos; /
Current play position */
} wave;

static int done = 0;
void poked(int sig)
{
done = 1;
}

/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
static void quit(int rc)
{
SDL_Quit();
exit(rc);
}

/* Process the audio buffer, here only adjust the volume. */
void process_audio(Uint8 *audio_buf, int buf_size) {
int i;
switch (wave.spec.format) {
case AUDIO_U8: {
// unsigned 8-bit sample
Uint8 *ptr = (Uint8 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Uint8)) {
double tmp = (*ptr) * volume;
tmp = tmp > 255.0 ? 255.0 : tmp;
*ptr = (Uint8)tmp;
ptr++;
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Uint8)*2) {
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 255.0 ? 255.0 : tmp;
*ptr = (Uint8)tmp;
ptr++;

            // process right channel
            tmp = (*ptr) * volume;
            tmp = tmp > 255.0 ? 255.0 : tmp;
            *ptr = (Uint8)tmp;
            ptr++;
        }
    } else {
        fprintf(stderr, "Doesn't support more than 2 channels!\n");
        exit(1);
    }
    break; }
case AUDIO_S8: {
    // signed 8-bit sample
    Sint8 *ptr = (Sint8 *)audio_buf;
    if (wave.spec.channels == 1) {
        // process mono audio
        for (i=0; i<buf_size; i += sizeof(Sint8)) {
            double tmp = (*ptr) * volume;
            tmp = tmp > 127.0 ? 127.0 : tmp;
            tmp = tmp < -128.0 ? -128.0 : tmp;
            *ptr = (Sint8)tmp;
            ptr++; // note here ptr will move to 8 bits higher
        }
    } else if (wave.spec.channels == 2) {
        // process stero audio
        for (i=0; i<buf_size; i += sizeof(Uint8)*2) {
            // process left channel
            double tmp = (*ptr) * volume;
            tmp = tmp > 127.0 ? 127.0 : tmp;
            tmp = tmp < -128.0 ? -128.0 : tmp;
            *ptr = (Sint8)tmp;
            ptr++;
            
            // process right channel
            tmp = (*ptr) * volume;
            tmp = tmp > 127.0 ? 127.0 : tmp;
            tmp = tmp < -128.0 ? -128.0 : tmp;
            *ptr = (Sint8)tmp;
            ptr++;
        }
    } else {
        fprintf(stderr, "Doesn't support more than 2 channels!\n");
        exit(1);
    }
    break; }
case AUDIO_U16LSB: {
    // unsigned 16-bit sample, little-endian
    Uint16 *ptr = (Uint16 *)audio_buf;
    if (wave.spec.channels == 1) {
        // process mono audio
        for (i=0; i<buf_size; i += sizeof(Uint16)) {

#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
Uint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
swap = (Uint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++; // note here ptr will move to 16 bits higher
#else
double tmp = (*ptr) * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
*ptr = (Uint16)tmp;
ptr++;
#endif
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Uint16)*2) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
// process left channel
Uint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
swap = (Uint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;

            // process right channel
            swap = SDL_Swap16(*ptr);
            tmp = swap * volume;
            tmp = tmp > 65535.0 ? 65535.0 : tmp;
            swap = (Uint16)tmp;
            *ptr = SDL_Swap16(swap);
            ptr++;

#else
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
*ptr = (Uint16)tmp;
ptr++;

            // process right channel
            tmp = (*ptr) * volume;
            tmp = tmp > 65535.0 ? 65535.0 : tmp;
            *ptr = (Uint16)tmp;
            ptr++;

#endif
}
} else {
fprintf(stderr, “Doesn’t support more than 2 channels!\n”);
exit(1);
}
break; }
case AUDIO_S16LSB: {
// signed 16-bit sample, little-endian
Sint16 *ptr = (Sint16 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Sint16)) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
Sint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
swap = (Sint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;
#else
double tmp = (*ptr) * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
*ptr = (Sint16)tmp;
ptr++;
#endif
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Sint16)*2) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
// process left channel
Sint16 swap = SDL_Swap(*ptr);
double tmp = swap * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
swap = (Sint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;

            // process right channel
            swap = SDL_Swap(*ptr);
            tmp = swap * volume;
            tmp = tmp > 32767.0 ? 32767.0 : tmp;
            tmp = tmp < -32768.0 ? -32768.0 : tmp;
            swap = (Sint16)tmp;
            *ptr = SDL_Swap16(swap);
            ptr++;

#else
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
*ptr = (Sint16)tmp;
ptr++;

            // process right channel
            tmp = (*ptr) * volume;
            tmp = tmp > 32767.0 ? 32767.0 : tmp;
            tmp = tmp < -32768.0 ? -32768.0 : tmp;
            *ptr = (Sint16)tmp;
            ptr++;

#endif
}
} else {
fprintf(stderr, “Doesn’t support more than 2 channels!\n”);
exit(1);
}
break; }
case AUDIO_U16MSB: {
// unsigned 16-bit sample, big-endian
Uint16 *ptr = (Uint16 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Uint16)) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
Uint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
swap = (Uint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++; // note here ptr will move to 16 bits higher
#else
double tmp = (*ptr) * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
*ptr = (Uint16)tmp;
ptr++;
#endif
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Uint16)*2) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
// process left channel
Uint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
swap = (Uint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;

            // process right channel
            swap = SDL_Swap16(*ptr);
            tmp = swap * volume;
            tmp = tmp > 65535.0 ? 65535.0 : tmp;
            swap = (Uint16)tmp;
            *ptr = SDL_Swap16(swap);
            ptr++;

#else
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
*ptr = (Uint16)tmp;
ptr++;

            // process right channel
            tmp = (*ptr) * volume;
            tmp = tmp > 65535.0 ? 65535.0 : tmp;
            *ptr = (Uint16)tmp;
            ptr++;

#endif
}
} else {
fprintf(stderr, “Doesn’t support more than 2 channels!\n”);
exit(1);
}
break; }
case AUDIO_S16MSB: {
// signed 16-bit sample, big-endian
Sint16 *ptr = (Sint16 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Sint16)) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
Sint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
swap = (Sint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;
#else
double tmp = (*ptr) * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
*ptr = (Sint16)tmp;
ptr++;
#endif
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Sint16)*2) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
// process left channel
Sint16 swap = SDL_Swap(*ptr);
double tmp = swap * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
swap = (Sint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;

            // process right channel
            swap = SDL_Swap(*ptr);
            tmp = swap * volume;
            tmp = tmp > 32767.0 ? 32767.0 : tmp;
            tmp = tmp < -32768.0 ? -32768.0 : tmp;
            swap = (Sint16)tmp;
            *ptr = SDL_Swap16(swap);
            ptr++;

#else
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
*ptr = (Sint16)tmp;
ptr++;

            // process right channel
            tmp = (*ptr) * volume;
            tmp = tmp > 32767.0 ? 32767.0 : tmp;
            tmp = tmp < -32768.0 ? -32768.0 : tmp;
            *ptr = (Sint16)tmp;
            ptr++;

#endif
}
} else {
fprintf(stderr, “Doesn’t support more than 2 channels!\n”);
exit(1);
}
break; }
}
}

void SDLCALL 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 ) {
	/* Process samples */
	Uint8 process_buf[waveleft];
	SDL_memcpy(process_buf, waveptr, waveleft);
	process_audio(process_buf, waveleft);

	// play the end of the audio
	SDL_memcpy(stream, process_buf, waveleft);
	stream += waveleft;
	len -= waveleft;

	// ready to repeat play the audio
	waveptr = wave.sound;
	waveleft = wave.soundlen;
	wave.soundpos = 0;
}

/* Process samples */
Uint8 process_buf[len];
SDL_memcpy(process_buf, waveptr, len);
process_audio(process_buf, len);

// play the processed samples
SDL_memcpy(stream, process_buf, len);
wave.soundpos += len;

}

static const int SCR_WIDTH = 240;
static const int SCR_HEIGHT = 180;
int main(int argc, char *argv[])
{
char name[32];
SDL_Event event;
Uint8 *keys;
SDL_Surface *screen;

/* Load the SDL library */
if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 ) {
	fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
	return(1);
}
if ( argv[1] == NULL ) {
	argv[1] = "sample.wav";
}

// Make a screen to put our video

#ifndef DARWIN
screen = SDL_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, 0, 0);
#else
screen = SDL_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, 24, 0);
#endif

if (!screen) {
    fprintf(stderr, "SDL: could not set video mode - exiting\n");
    quit(1);
}

/* Load the wave file into memory */
if ( SDL_LoadWAV(argv[1],
		&wave.spec, &wave.sound, &wave.soundlen) == NULL ) {
	fprintf(stderr, "Couldn't load %s: %s\n",
					argv[1], SDL_GetError());
	quit(1);
}

wave.spec.callback = fillerup;

#if HAVE_SIGNAL_H
/* Set the signals /
#ifdef SIGHUP
signal(SIGHUP, poked);
#endif
signal(SIGINT, poked);
#ifdef SIGQUIT
signal(SIGQUIT, poked);
#endif
signal(SIGTERM, poked);
#endif /
HAVE_SIGNAL_H */

/* Initialize fillerup() variables */
if ( SDL_OpenAudio(&wave.spec, NULL) < 0 ) {
	fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
	SDL_FreeWAV(wave.sound);
	quit(2);
}
// start playing
SDL_PauseAudio(0);

/* Let the audio run */
printf("Using audio driver: %s\n", SDL_AudioDriverName(name, 32));
while ( ! done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING) ) {
    // Poll input queue, run keyboard loop
    while ( SDL_PollEvent(&event) ) {
        if ( event.type == SDL_QUIT )
            done = 1;
    }
    keys = SDL_GetKeyState(NULL);
    if (keys[SDLK_q]) {
        done = 1;
    } else if (keys[SDLK_MINUS]) {
		volume /= 2.0f;
	} else if (keys[SDLK_EQUALS]) {
		volume *= 2.0f;
	}
	
	
	SDL_Delay(100);
}

/* Clean up on signal */
SDL_CloseAudio();
SDL_FreeWAV(wave.sound);
SDL_Quit();
return(0);

}

Hello,

That line of code does not call the audio callback function. What the
line of code DOES do is that it sets the audio callback function to
the fillerup function. Later on when SDL (periodically) needs more
audio data, SDL asks, hey what is my callback function, and finds that
it has been set to fillerup. SDL then calls the fillerup function so
obtain the needed audio data.

From your query it sounds like you might not be familiar with
function pointers (wave.spec.callback is a function pointer), so here
is a reference:
http://www.newty.de/fpt/index.html

  • HolmesOn Oct 17, 2008, at 11:21 AM, Anonymous wrote:

----In the code below, I’m wondering why the function fillerup can
be called
like this ONLY:

wave.spec.callback = fillerup;

----When the function itself takes the form:

void SDLCALL fillerup(void *unused, Uint8 *stream, int len)

Doesn’t it need parameters or arguments???

/* Program to load a wave file and loop playing it using SDL sound */

/* loopwaves.c is much more robust in handling WAVE files –
This is only for simple WAVEs
*/
#include “SDL_config.h”

#include <stdio.h>
#include <stdlib.h>

#if HAVE_SIGNAL_H
#include <signal.h>
#endif

#include “SDL.h”
#include “SDL_audio.h”

static double volume = 1.0f;
struct {
SDL_AudioSpec spec;
Uint8 sound; / Pointer to wave data /
Uint32 soundlen; /
Length of wave data /
int soundpos; /
Current play position */
} wave;

static int done = 0;
void poked(int sig)
{
done = 1;
}

/* Call this instead of exit(), so we can clean up SDL: atexit() is
evil. */
static void quit(int rc)
{
SDL_Quit();
exit(rc);
}

/* Process the audio buffer, here only adjust the volume. */
void process_audio(Uint8 *audio_buf, int buf_size) {
int i;
switch (wave.spec.format) {
case AUDIO_U8: {
// unsigned 8-bit sample
Uint8 *ptr = (Uint8 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Uint8)) {
double tmp = (*ptr) * volume;
tmp = tmp > 255.0 ? 255.0 : tmp;
*ptr = (Uint8)tmp;
ptr++;
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Uint8)*2) {
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 255.0 ? 255.0 : tmp;
*ptr = (Uint8)tmp;
ptr++;

           // process right channel
           tmp = (*ptr) * volume;
           tmp = tmp > 255.0 ? 255.0 : tmp;
           *ptr = (Uint8)tmp;
           ptr++;
       }
   } else {
       fprintf(stderr, "Doesn't support more than 2 channels!\n");
       exit(1);
   }
   break; }

case AUDIO_S8: {
// signed 8-bit sample
Sint8 *ptr = (Sint8 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Sint8)) {
double tmp = (*ptr) * volume;
tmp = tmp > 127.0 ? 127.0 : tmp;
tmp = tmp < -128.0 ? -128.0 : tmp;
*ptr = (Sint8)tmp;
ptr++; // note here ptr will move to 8 bits higher
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Uint8)*2) {
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 127.0 ? 127.0 : tmp;
tmp = tmp < -128.0 ? -128.0 : tmp;
*ptr = (Sint8)tmp;
ptr++;

           // process right channel
           tmp = (*ptr) * volume;
           tmp = tmp > 127.0 ? 127.0 : tmp;
           tmp = tmp < -128.0 ? -128.0 : tmp;
           *ptr = (Sint8)tmp;
           ptr++;
       }
   } else {
       fprintf(stderr, "Doesn't support more than 2 channels!\n");
       exit(1);
   }
   break; }

case AUDIO_U16LSB: {
// unsigned 16-bit sample, little-endian
Uint16 *ptr = (Uint16 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Uint16)) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
Uint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
swap = (Uint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++; // note here ptr will move to 16 bits higher
#else
double tmp = (*ptr) * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
*ptr = (Uint16)tmp;
ptr++;
#endif
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Uint16)*2) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
// process left channel
Uint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
swap = (Uint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;

           // process right channel
           swap = SDL_Swap16(*ptr);
           tmp = swap * volume;
           tmp = tmp > 65535.0 ? 65535.0 : tmp;
           swap = (Uint16)tmp;
           *ptr = SDL_Swap16(swap);
           ptr++;

#else
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
*ptr = (Uint16)tmp;
ptr++;

           // process right channel
           tmp = (*ptr) * volume;
           tmp = tmp > 65535.0 ? 65535.0 : tmp;
           *ptr = (Uint16)tmp;
           ptr++;

#endif
}
} else {
fprintf(stderr, “Doesn’t support more than 2 channels!\n”);
exit(1);
}
break; }
case AUDIO_S16LSB: {
// signed 16-bit sample, little-endian
Sint16 *ptr = (Sint16 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Sint16)) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
Sint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
swap = (Sint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;
#else
double tmp = (*ptr) * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
*ptr = (Sint16)tmp;
ptr++;
#endif
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Sint16)*2) {
#if (SDL_BYTE_ORDER == SDL_BIG_ENDIAN)
// process left channel
Sint16 swap = SDL_Swap(*ptr);
double tmp = swap * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
swap = (Sint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;

           // process right channel
           swap = SDL_Swap(*ptr);
           tmp = swap * volume;
           tmp = tmp > 32767.0 ? 32767.0 : tmp;
           tmp = tmp < -32768.0 ? -32768.0 : tmp;
           swap = (Sint16)tmp;
           *ptr = SDL_Swap16(swap);
           ptr++;

#else
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
*ptr = (Sint16)tmp;
ptr++;

           // process right channel
           tmp = (*ptr) * volume;
           tmp = tmp > 32767.0 ? 32767.0 : tmp;
           tmp = tmp < -32768.0 ? -32768.0 : tmp;
           *ptr = (Sint16)tmp;
           ptr++;

#endif
}
} else {
fprintf(stderr, “Doesn’t support more than 2 channels!\n”);
exit(1);
}
break; }
case AUDIO_U16MSB: {
// unsigned 16-bit sample, big-endian
Uint16 *ptr = (Uint16 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Uint16)) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
Uint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
swap = (Uint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++; // note here ptr will move to 16 bits higher
#else
double tmp = (*ptr) * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
*ptr = (Uint16)tmp;
ptr++;
#endif
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Uint16)*2) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
// process left channel
Uint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
swap = (Uint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;

           // process right channel
           swap = SDL_Swap16(*ptr);
           tmp = swap * volume;
           tmp = tmp > 65535.0 ? 65535.0 : tmp;
           swap = (Uint16)tmp;
           *ptr = SDL_Swap16(swap);
           ptr++;

#else
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 65535.0 ? 65535.0 : tmp;
*ptr = (Uint16)tmp;
ptr++;

           // process right channel
           tmp = (*ptr) * volume;
           tmp = tmp > 65535.0 ? 65535.0 : tmp;
           *ptr = (Uint16)tmp;
           ptr++;

#endif
}
} else {
fprintf(stderr, “Doesn’t support more than 2 channels!\n”);
exit(1);
}
break; }
case AUDIO_S16MSB: {
// signed 16-bit sample, big-endian
Sint16 *ptr = (Sint16 *)audio_buf;
if (wave.spec.channels == 1) {
// process mono audio
for (i=0; i<buf_size; i += sizeof(Sint16)) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
Sint16 swap = SDL_Swap16(*ptr);
double tmp = swap * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
swap = (Sint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;
#else
double tmp = (*ptr) * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
*ptr = (Sint16)tmp;
ptr++;
#endif
}
} else if (wave.spec.channels == 2) {
// process stero audio
for (i=0; i<buf_size; i += sizeof(Sint16)*2) {
#if (SDL_BYTE_ORDER == SDL_LIL_ENDIAN)
// process left channel
Sint16 swap = SDL_Swap(*ptr);
double tmp = swap * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
swap = (Sint16)tmp;
*ptr = SDL_Swap16(swap);
ptr++;

           // process right channel
           swap = SDL_Swap(*ptr);
           tmp = swap * volume;
           tmp = tmp > 32767.0 ? 32767.0 : tmp;
           tmp = tmp < -32768.0 ? -32768.0 : tmp;
           swap = (Sint16)tmp;
           *ptr = SDL_Swap16(swap);
           ptr++;

#else
// process left channel
double tmp = (*ptr) * volume;
tmp = tmp > 32767.0 ? 32767.0 : tmp;
tmp = tmp < -32768.0 ? -32768.0 : tmp;
*ptr = (Sint16)tmp;
ptr++;

           // process right channel
           tmp = (*ptr) * volume;
           tmp = tmp > 32767.0 ? 32767.0 : tmp;
           tmp = tmp < -32768.0 ? -32768.0 : tmp;
           *ptr = (Sint16)tmp;
           ptr++;

#endif
}
} else {
fprintf(stderr, “Doesn’t support more than 2 channels!\n”);
exit(1);
}
break; }
}
}

void SDLCALL 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 ) {
/
Process samples */
Uint8 process_buf[waveleft];
SDL_memcpy(process_buf, waveptr, waveleft);
process_audio(process_buf, waveleft);

  // play the end of the audio
  SDL_memcpy(stream, process_buf, waveleft);
  stream += waveleft;
  len -= waveleft;

  // ready to repeat play the audio
  waveptr = wave.sound;
  waveleft = wave.soundlen;
  wave.soundpos = 0;

}

/* Process samples */
Uint8 process_buf[len];
SDL_memcpy(process_buf, waveptr, len);
process_audio(process_buf, len);

// play the processed samples
SDL_memcpy(stream, process_buf, len);
wave.soundpos += len;
}

static const int SCR_WIDTH = 240;
static const int SCR_HEIGHT = 180;
int main(int argc, char *argv[])
{
char name[32];
SDL_Event event;
Uint8 *keys;
SDL_Surface *screen;

/* Load the SDL library */
if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 ) {
fprintf(stderr, “Couldn’t initialize SDL: %s\n”,SDL_GetError());
return(1);
}
if ( argv[1] == NULL ) {
argv[1] = “sample.wav”;
}

// Make a screen to put our video
#ifndef DARWIN
screen = SDL_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, 0, 0);
#else
screen = SDL_SetVideoMode(SCR_WIDTH, SCR_HEIGHT, 24, 0);
#endif

if (!screen) {
fprintf(stderr, “SDL: could not set video mode - exiting\n”);
quit(1);
}

/* Load the wave file into memory */
if ( SDL_LoadWAV(argv[1],
&wave.spec, &wave.sound, &wave.soundlen) == NULL ) {
fprintf(stderr, “Couldn’t load %s: %s\n”,
argv[1], SDL_GetError());
quit(1);
}

wave.spec.callback = fillerup;

#if HAVE_SIGNAL_H
/* Set the signals /
#ifdef SIGHUP
signal(SIGHUP, poked);
#endif
signal(SIGINT, poked);
#ifdef SIGQUIT
signal(SIGQUIT, poked);
#endif
signal(SIGTERM, poked);
#endif /
HAVE_SIGNAL_H */

/* Initialize fillerup() variables */
if ( SDL_OpenAudio(&wave.spec, NULL) < 0 ) {
fprintf(stderr, “Couldn’t open audio: %s\n”, SDL_GetError());
SDL_FreeWAV(wave.sound);
quit(2);
}
// start playing
SDL_PauseAudio(0);

/* Let the audio run */
printf(“Using audio driver: %s\n”, SDL_AudioDriverName(name, 32));
while ( ! done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING) ) {
// Poll input queue, run keyboard loop
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_QUIT )
done = 1;
}
keys = SDL_GetKeyState(NULL);
if (keys[SDLK_q]) {
done = 1;
} else if (keys[SDLK_MINUS]) {
volume /= 2.0f;
} else if (keys[SDLK_EQUALS]) {
volume *= 2.0f;
}

  SDL_Delay(100);

}

/* Clean up on signal */
SDL_CloseAudio();
SDL_FreeWAV(wave.sound);
SDL_Quit();
return(0);
}


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

Short version: It’s not a function call, it’s a callback function. You aren’t making a function call here, you’re giving SDL_audio a function that it can call when it needs it. So you don’t provide parameters, just the function name, which the compiler translates to a pointer to the function code’s address. Then it calls that and fills in the parameters.>----- Original Message ----

From: Anonymous <st3p4an1e.8975 at gmail.com>
Subject: [SDL] SDL_audio code…no need for function parameters??? Help please

----In the code below, I’m wondering why the function fillerup can be called
like this ONLY:

wave.spec.callback = fillerup;

----When the function itself takes the form:

void SDLCALL fillerup(void *unused, Uint8 *stream, int len)

Doesn’t it need parameters or arguments???