/** * Callback used to provide data to the audio subsystem. * * @param userdata N/A * @param stream Output stream * @param len Length of data to be placed in the output stream */ void audioCallback (void * userdata, unsigned char * stream, int len) { (void)userdata; int count; if (!music_paused) { // Read the next portion of music into the audio stream #if defined(USE_MODPLUG) if (musicFile) ModPlug_Read(musicFile, stream, len); #elif defined(USE_XMP) if (xmp_get_player(xmpC, XMP_PLAYER_STATE) == XMP_STATE_PLAYING) xmp_play_buffer(xmpC, stream, len, 0); #endif } for (count = 0; count < 32; count++) { if (sounds[count].data && (sounds[count].position >= 0)) { // Add the next portion of the sound clip to the audio stream if (len < sounds[count].length - sounds[count].position) { // Play as much of the clip as possible SDL_MixAudio(stream, sounds[count].data + sounds[count].position, len, soundsVolume * SDL_MIX_MAXVOLUME / MAX_VOLUME); sounds[count].position += len; } else { // Play the remainder of the clip SDL_MixAudio(stream, sounds[count].data + sounds[count].position, sounds[count].length - sounds[count].position, soundsVolume * SDL_MIX_MAXVOLUME / MAX_VOLUME); sounds[count].position = -1; } } } return; }
static int S_XMP_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer) { int r; /* xmp_play_buffer() requires libxmp >= 4.1. it will write * native-endian pcm data to the buffer. if the data write * is partial, the rest of the buffer will be zero-filled. * the last param is the number that the current sequence of * the song will be looped at max. */ r = xmp_play_buffer((xmp_context)stream->priv, buffer, bytes, 1); if (r == 0) { return bytes; } if (r == -XMP_END) { Con_DPrintf("XMP EOF\n"); return 0; } return -1; }
static void fill_audio(void *udata, Uint8 *stream, int len) { if (xmp_play_buffer((xmp_context)udata, stream, len, 0) < 0) playing = 0; }