diff -urNp uhexen2-20080819/hexen2/host.c uhexen2/hexen2/host.c --- uhexen2-20080819/hexen2/host.c 2008-04-04 10:55:12.000000000 +0300 +++ uhexen2/hexen2/host.c 2008-09-20 16:23:53.000000000 +0300 @@ -1060,7 +1060,7 @@ void Host_Init (void) S_Init (); CDAudio_Init(); - MIDI_Init(); + MIDI_Init(NULL); CL_Init(); IN_Init(); diff -urNp uhexen2-20080819/hexen2/mididef.h uhexen2/hexen2/mididef.h --- uhexen2-20080819/hexen2/mididef.h 2007-09-21 14:05:10.000000000 +0300 +++ uhexen2/hexen2/mididef.h 2008-09-20 16:23:53.000000000 +0300 @@ -8,7 +8,7 @@ #ifndef __MIDIDEFS_H #define __MIDIDEFS_H -qboolean MIDI_Init (void); +qboolean MIDI_Init (dma_t *dma); void MIDI_Cleanup (void); void MIDI_Play (const char *Name); void MIDI_Stop (void); diff -urNp uhexen2-20080819/hexen2/midi_mac.c uhexen2/hexen2/midi_mac.c --- uhexen2-20080819/hexen2/midi_mac.c 2008-03-31 14:25:21.000000000 +0300 +++ uhexen2/hexen2/midi_mac.c 2008-09-20 16:23:53.000000000 +0300 @@ -118,7 +118,7 @@ static void MIDI_Loop_f (void) Con_Printf("MIDI music will not be looped\n"); } -qboolean MIDI_Init(void) +qboolean MIDI_Init(dma_t *dma) { OSErr theErr; diff -urNp uhexen2-20080819/hexen2/midi_sdl.c uhexen2/hexen2/midi_sdl.c --- uhexen2-20080819/hexen2/midi_sdl.c 2008-03-31 14:25:21.000000000 +0300 +++ uhexen2/hexen2/midi_sdl.c 2008-09-20 16:23:53.000000000 +0300 @@ -110,18 +110,76 @@ static void MIDI_EndMusicFinished(void) } } -qboolean MIDI_Init(void) +static int buffersize; + +static void paint_audio (void *unused, Uint8 *stream, int len) +{ + int pos, tobufend; + int len1, len2; + short *buf, *src; + + if (!shm) + { /* shouldn't happen, but just in case */ + return; + } + + pos = (shm->samplepos * (shm->samplebits / 8)); + if (pos >= buffersize) + shm->samplepos = pos = 0; + + tobufend = buffersize - pos; /* bytes to buffer's end. */ + len1 = len; + len2 = 0; + + if (len1 > tobufend) + { + len1 = tobufend; + len2 = len - len1; + } + + buf = (short *)stream; + src = (short *) (shm->buffer + pos); + len = len1; + while (len >= 0) + { + *buf++ += *src++; + len -= 2; + } + + if (len2 <= 0) + { + shm->samplepos += (len1 / (shm->samplebits / 8)); + } + else + { /* wraparound? */ + src = (short *) shm->buffer; + buf = (short *) (stream + len1); + len = len2; + while (len >= 0) + { + *buf++ += *src++; + len -= 2; + } + shm->samplepos = (len2 / (shm->samplebits / 8)); + } + + if (shm->samplepos >= buffersize) + shm->samplepos = 0; +} + +qboolean MIDI_Init(dma_t *dma) { int audio_rate = 22050; - int audio_format = AUDIO_S16SYS; + Uint16 audio_format = AUDIO_S16SYS; int audio_channels = 2; - int audio_buffers = 4096; + int audio_buffers = 512; void *selfsyms; const SDL_version *smixer_version; const SDL_version *(*Mix_Linked_Version_fp)(void) = NULL; - bMidiInited = false; + if (bMidiInited) + return true; Con_Printf("%s: ", __thisfunc__); if (safemode || COM_CheckParm("-nomidi") || COM_CheckParm("-nosound") || COM_CheckParm("-s")) @@ -129,11 +187,6 @@ qboolean MIDI_Init(void) Con_Printf("disabled by commandline\n"); return false; } - if (snd_system == S_SYS_SDL) - { - Con_Printf("SDL_mixer conflicts SDL audio.\n"); - return false; - } Con_Printf("SDL_Mixer "); // this is to avoid relocation errors with very old SDL_Mixer versions @@ -183,6 +236,19 @@ bad_version: midi_endmusicfnc = &MIDI_EndMusicFinished; if (midi_endmusicfnc) Mix_HookMusicFinished(midi_endmusicfnc); + if (dma != NULL) + { + memset ((void *) dma, 0, sizeof(dma_t)); + shm = dma; + shm->samplepos = 0; + shm->submission_chunk = 1; + Mix_QuerySpec (&dma->speed, &audio_format, &dma->channels); + shm->samplebits = audio_format & 0xFF; + shm->samples = 16384; + buffersize = shm->samples * (shm->samplebits / 8); + shm->buffer = (unsigned char *) calloc (1, buffersize); + Mix_SetPostMix(paint_audio, NULL); + } Con_Printf("MIDI music initialized.\n"); diff -urNp uhexen2-20080819/hexen2/snd_sdl2.c uhexen2/hexen2/snd_sdl2.c --- uhexen2-20080819/hexen2/snd_sdl2.c 2008-08-19 20:21:17.000000000 +0300 +++ uhexen2/hexen2/snd_sdl2.c 2008-09-20 16:27:44.000000000 +0300 @@ -54,8 +54,21 @@ static int buffersize; void S_SDL_LinkFuncs (snd_driver_t *p) { +#if defined(_MIDI_SDLMIXER) + if (safemode || COM_CheckParm("-nomidi")) + { + p->Init = S_SDL_Init; + p->Shutdown = S_SDL_Shutdown; + } + else + { + p->Init = MIDI_Init; + p->Shutdown = MIDI_Cleanup; + } +#else p->Init = S_SDL_Init; p->Shutdown = S_SDL_Shutdown; +#endif /* _MIDI_SDLMIXER */ p->GetDMAPos = S_SDL_GetDMAPos; p->LockBuffer = S_SDL_LockBuffer; p->Submit = S_SDL_Submit; diff -urNp uhexen2-20080819/hexen2/win_stuff/midi.c uhexen2/hexen2/win_stuff/midi.c --- uhexen2-20080819/hexen2/win_stuff/midi.c 2008-03-31 14:25:22.000000000 +0300 +++ uhexen2/hexen2/win_stuff/midi.c 2008-09-20 16:23:53.000000000 +0300 @@ -116,7 +116,7 @@ void MIDI_Update(void) MIDI_SetVolume (&bgmvolume); } -qboolean MIDI_Init(void) +qboolean MIDI_Init(dma_t *dma) { MMRESULT mmrRetVal; MIDIOUTCAPS midi_caps; diff -urNp uhexen2-20080819/hexenworld/Client/cl_main.c uhexen2/hexenworld/Client/cl_main.c --- uhexen2-20080819/hexenworld/Client/cl_main.c 2008-04-04 10:55:14.000000000 +0300 +++ uhexen2/hexenworld/Client/cl_main.c 2008-09-20 16:23:53.000000000 +0300 @@ -1417,7 +1417,7 @@ void Host_Init (void) S_Init (); CDAudio_Init (); - MIDI_Init (); + MIDI_Init (NULL); CL_Init (); IN_Init (); diff -urNp uhexen2-20080819/hexenworld/Client/mididef.h uhexen2/hexenworld/Client/mididef.h --- uhexen2-20080819/hexenworld/Client/mididef.h 2007-09-21 14:05:11.000000000 +0300 +++ uhexen2/hexenworld/Client/mididef.h 2008-09-20 16:23:53.000000000 +0300 @@ -8,7 +8,7 @@ #ifndef __MIDIDEFS_H #define __MIDIDEFS_H -qboolean MIDI_Init (void); +qboolean MIDI_Init (dma_t *dma); void MIDI_Cleanup (void); void MIDI_Play (const char *Name); void MIDI_Stop (void); diff -urNp uhexen2-20080819/hexenworld/Client/midi_mac.c uhexen2/hexenworld/Client/midi_mac.c --- uhexen2-20080819/hexenworld/Client/midi_mac.c 2008-03-31 14:25:22.000000000 +0300 +++ uhexen2/hexenworld/Client/midi_mac.c 2008-09-20 16:23:53.000000000 +0300 @@ -118,7 +118,7 @@ static void MIDI_Loop_f (void) Con_Printf("MIDI music will not be looped\n"); } -qboolean MIDI_Init(void) +qboolean MIDI_Init(dma_t *dma) { OSErr theErr; diff -urNp uhexen2-20080819/hexenworld/Client/midi_sdl.c uhexen2/hexenworld/Client/midi_sdl.c --- uhexen2-20080819/hexenworld/Client/midi_sdl.c 2008-03-31 14:25:22.000000000 +0300 +++ uhexen2/hexenworld/Client/midi_sdl.c 2008-09-20 16:23:53.000000000 +0300 @@ -110,18 +110,76 @@ static void MIDI_EndMusicFinished(void) } } -qboolean MIDI_Init(void) +static int buffersize; + +static void paint_audio (void *unused, Uint8 *stream, int len) +{ + int pos, tobufend; + int len1, len2; + short *buf, *src; + + if (!shm) + { /* shouldn't happen, but just in case */ + return; + } + + pos = (shm->samplepos * (shm->samplebits / 8)); + if (pos >= buffersize) + shm->samplepos = pos = 0; + + tobufend = buffersize - pos; /* bytes to buffer's end. */ + len1 = len; + len2 = 0; + + if (len1 > tobufend) + { + len1 = tobufend; + len2 = len - len1; + } + + buf = (short *)stream; + src = (short *) (shm->buffer + pos); + len = len1; + while (len >= 0) + { + *buf++ += *src++; + len -= 2; + } + + if (len2 <= 0) + { + shm->samplepos += (len1 / (shm->samplebits / 8)); + } + else + { /* wraparound? */ + src = (short *) shm->buffer; + buf = (short *) (stream + len1); + len = len2; + while (len >= 0) + { + *buf++ += *src++; + len -= 2; + } + shm->samplepos = (len2 / (shm->samplebits / 8)); + } + + if (shm->samplepos >= buffersize) + shm->samplepos = 0; +} + +qboolean MIDI_Init(dma_t *dma) { int audio_rate = 22050; - int audio_format = AUDIO_S16SYS; + Uint16 audio_format = AUDIO_S16SYS; int audio_channels = 2; - int audio_buffers = 4096; + int audio_buffers = 512; void *selfsyms; const SDL_version *smixer_version; const SDL_version *(*Mix_Linked_Version_fp)(void) = NULL; - bMidiInited = false; + if (bMidiInited) + return true; Con_Printf("%s: ", __thisfunc__); if (safemode || COM_CheckParm("-nomidi") || COM_CheckParm("-nosound") || COM_CheckParm("-s")) @@ -129,11 +187,6 @@ qboolean MIDI_Init(void) Con_Printf("disabled by commandline\n"); return false; } - if (snd_system == S_SYS_SDL) - { - Con_Printf("SDL_mixer conflicts SDL audio.\n"); - return false; - } Con_Printf("SDL_Mixer "); // this is to avoid relocation errors with very old SDL_Mixer versions @@ -183,6 +236,19 @@ bad_version: midi_endmusicfnc = &MIDI_EndMusicFinished; if (midi_endmusicfnc) Mix_HookMusicFinished(midi_endmusicfnc); + if (dma != NULL) + { + memset ((void *) dma, 0, sizeof(dma_t)); + shm = dma; + shm->samplepos = 0; + shm->submission_chunk = 1; + Mix_QuerySpec (&dma->speed, &audio_format, &dma->channels); + shm->samplebits = audio_format & 0xFF; + shm->samples = 16384; + buffersize = shm->samples * (shm->samplebits / 8); + shm->buffer = (unsigned char *) calloc (1, buffersize); + Mix_SetPostMix(paint_audio, NULL); + } Con_Printf("MIDI music initialized.\n"); diff -urNp uhexen2-20080819/hexenworld/Client/snd_sdl2.c uhexen2/hexenworld/Client/snd_sdl2.c --- uhexen2-20080819/hexenworld/Client/snd_sdl2.c 2008-08-19 20:21:18.000000000 +0300 +++ uhexen2/hexenworld/Client/snd_sdl2.c 2008-09-20 16:27:48.000000000 +0300 @@ -54,8 +54,21 @@ static int buffersize; void S_SDL_LinkFuncs (snd_driver_t *p) { +#if defined(_MIDI_SDLMIXER) + if (safemode || COM_CheckParm("-nomidi")) + { + p->Init = S_SDL_Init; + p->Shutdown = S_SDL_Shutdown; + } + else + { + p->Init = MIDI_Init; + p->Shutdown = MIDI_Cleanup; + } +#else p->Init = S_SDL_Init; p->Shutdown = S_SDL_Shutdown; +#endif /* _MIDI_SDLMIXER */ p->GetDMAPos = S_SDL_GetDMAPos; p->LockBuffer = S_SDL_LockBuffer; p->Submit = S_SDL_Submit; diff -urNp uhexen2-20080819/hexenworld/Client/win_stuff/midi.c uhexen2/hexenworld/Client/win_stuff/midi.c --- uhexen2-20080819/hexenworld/Client/win_stuff/midi.c 2008-03-31 14:25:23.000000000 +0300 +++ uhexen2/hexenworld/Client/win_stuff/midi.c 2008-09-20 16:23:53.000000000 +0300 @@ -116,7 +116,7 @@ void MIDI_Update(void) MIDI_SetVolume (&bgmvolume); } -qboolean MIDI_Init(void) +qboolean MIDI_Init(dma_t *dma) { MMRESULT mmrRetVal; MIDIOUTCAPS midi_caps;