diff --git a/CHANGELOG.txt b/CHANGELOG.txt index e7e68c4a5..0c6319e65 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D2X-Rebirth Changelog +20110530 +-------- +arch/include/digi_audio.h, arch/include/digi_mixer.h, arch/sdl/digi.c, arch/sdl/digi_mixer.c, main/digi.h, main/digiobj.c: Added own channel management to SDL_mixer sound interface since the builtin channel management of this lib cannot handle our needs; Little code cleanup + 20110528 -------- main/net_ipx.c, main/net_udp.c: Made netgame setup menu more flexible towards (constant or temporary) changes in available game modes diff --git a/arch/include/digi_audio.h b/arch/include/digi_audio.h index 73745ae52..1b501ff67 100644 --- a/arch/include/digi_audio.h +++ b/arch/include/digi_audio.h @@ -8,7 +8,6 @@ void digi_audio_reset(); void digi_audio_close(); void digi_audio_stop_all_channels(); int digi_audio_start_sound(short, fix, int, int, int, int, int ); -int digi_audio_find_channel(int ); int digi_audio_is_sound_playing(int ); int digi_audio_is_channel_playing(int ); void digi_audio_set_channel_volume(int, int ); diff --git a/arch/include/digi_mixer.h b/arch/include/digi_mixer.h index 336315450..6a12f591a 100644 --- a/arch/include/digi_mixer.h +++ b/arch/include/digi_mixer.h @@ -10,7 +10,6 @@ void digi_mixer_set_channel_volume(int, int); void digi_mixer_set_channel_pan(int, int); void digi_mixer_stop_sound(int); void digi_mixer_end_sound(int); -int digi_mixer_find_channel(int); int digi_mixer_is_sound_playing(int); int digi_mixer_is_channel_playing(int); void digi_mixer_reset(); diff --git a/arch/sdl/digi.c b/arch/sdl/digi.c index 8d505b888..c64215e87 100644 --- a/arch/sdl/digi.c +++ b/arch/sdl/digi.c @@ -43,7 +43,6 @@ int (*fptr_start_sound)(short, fix, int, int, int, int, int) = NULL; void (*fptr_stop_sound)(int) = NULL; void (*fptr_end_sound)(int) = NULL; -int (*fptr_find_channel)(int) = NULL; int (*fptr_is_sound_playing)(int) = NULL; int (*fptr_is_channel_playing)(int) = NULL; void (*fptr_stop_all_channels)() = NULL; @@ -62,7 +61,6 @@ void digi_select_system(int n) { fptr_start_sound = digi_mixer_start_sound; fptr_stop_sound = digi_mixer_stop_sound; fptr_end_sound = digi_mixer_end_sound; - fptr_find_channel = digi_mixer_find_channel; fptr_is_sound_playing = digi_mixer_is_sound_playing; fptr_is_channel_playing = digi_mixer_is_channel_playing; fptr_stop_all_channels = digi_mixer_stop_all_channels; @@ -80,7 +78,6 @@ void digi_select_system(int n) { fptr_start_sound = digi_audio_start_sound; fptr_stop_sound = digi_audio_stop_sound; fptr_end_sound = digi_audio_end_sound; - fptr_find_channel = digi_audio_find_channel; fptr_is_sound_playing = digi_audio_is_sound_playing; fptr_is_channel_playing = digi_audio_is_channel_playing; fptr_stop_all_channels = digi_audio_stop_all_channels; @@ -121,7 +118,6 @@ int digi_start_sound(short soundnum, fix volume, int pan, int looping, int loop void digi_stop_sound(int channel) { fptr_stop_sound(channel); } void digi_end_sound(int channel) { fptr_end_sound(channel); } -int digi_find_channel(int soundno) { return fptr_find_channel(soundno); } int digi_is_sound_playing(int soundno) { return fptr_is_sound_playing(soundno); } int digi_is_channel_playing(int channel) { return fptr_is_channel_playing(channel); } void digi_stop_all_channels() { fptr_stop_all_channels(); } diff --git a/arch/sdl/digi_mixer.c b/arch/sdl/digi_mixer.c index 408605369..1b5621b0f 100644 --- a/arch/sdl/digi_mixer.c +++ b/arch/sdl/digi_mixer.c @@ -49,134 +49,163 @@ static int digi_initialised = 0; static int digi_max_channels = MAX_SOUND_SLOTS; inline int fix2byte(fix f) { return (f / 256) % 256; } Mix_Chunk SoundChunks[MAX_SOUNDS]; +ubyte channels[MAX_SOUND_SLOTS]; /* Initialise audio */ -int digi_mixer_init() { - if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"digi_init %d (SDL_Mixer)\n", MAX_SOUNDS); - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) Error("SDL audio initialisation failed: %s.", SDL_GetError()); +int digi_mixer_init() +{ + if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"digi_init %d (SDL_Mixer)\n", MAX_SOUNDS); + if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) Error("SDL audio initialisation failed: %s.", SDL_GetError()); - if (Mix_OpenAudio(SAMPLE_RATE_44K, MIX_OUTPUT_FORMAT, MIX_OUTPUT_CHANNELS, SOUND_BUFFER_SIZE)) { - //edited on 10/05/98 by Matt Mueller - should keep running, just with no sound. - con_printf(CON_URGENT,"\nError: Couldn't open audio: %s\n", SDL_GetError()); - GameArg.SndNoSound = 1; - return 1; - } + if (Mix_OpenAudio(SAMPLE_RATE_44K, MIX_OUTPUT_FORMAT, MIX_OUTPUT_CHANNELS, SOUND_BUFFER_SIZE)) + { + //edited on 10/05/98 by Matt Mueller - should keep running, just with no sound. + con_printf(CON_URGENT,"\nError: Couldn't open audio: %s\n", SDL_GetError()); + GameArg.SndNoSound = 1; + return 1; + } - Mix_AllocateChannels(digi_max_channels); - Mix_Pause(0); + digi_max_channels = Mix_AllocateChannels(digi_max_channels); + memset(channels, 0, MAX_SOUND_SLOTS); + Mix_Pause(0); - digi_initialised = 1; + digi_initialised = 1; - digi_mixer_set_digi_volume( (GameCfg.DigiVolume*32768)/8 ); + digi_mixer_set_digi_volume( (GameCfg.DigiVolume*32768)/8 ); - return 0; + return 0; } /* Shut down audio */ void digi_mixer_close() { - if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"digi_close (SDL_Mixer)\n"); - if (!digi_initialised) return; - digi_initialised = 0; - Mix_CloseAudio(); + if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"digi_close (SDL_Mixer)\n"); + if (!digi_initialised) return; + digi_initialised = 0; + Mix_CloseAudio(); +} + +/* channel management */ +int digi_mixer_find_channel() +{ + int i; + for (i = 0; i < digi_max_channels; i++) + if (channels[i] == 0) + return i; + return -1; +} + +void digi_mixer_free_channel(int channel_num) +{ + channels[channel_num] = 0; } /* * Play-time conversion. Performs output conversion only once per sound effect used. * Once the sound sample has been converted, it is cached in SoundChunks[] */ -void mixdigi_convert_sound(int i) { +void mixdigi_convert_sound(int i) +{ + SDL_AudioCVT cvt; + Uint8 *data = GameSounds[i].data; + Uint32 dlen = GameSounds[i].length; + int out_freq; + Uint16 out_format; + int out_channels; - SDL_AudioCVT cvt; - Uint8 *data = GameSounds[i].data; - Uint32 dlen = GameSounds[i].length; - int out_freq; - Uint16 out_format; - int out_channels; + Mix_QuerySpec(&out_freq, &out_format, &out_channels); // get current output settings - Mix_QuerySpec(&out_freq, &out_format, &out_channels); // get current output settings + if (SoundChunks[i].abuf) return; //proceed only if not converted yet - if (SoundChunks[i].abuf) return; //proceed only if not converted yet + if (data) + { + if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"converting %d (%d)\n", i, dlen); + SDL_BuildAudioCVT(&cvt, AUDIO_U8, 1, GameArg.SndDigiSampleRate, out_format, out_channels, out_freq); - if (data) { - if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"converting %d (%d)\n", i, dlen); - SDL_BuildAudioCVT(&cvt, AUDIO_U8, 1, GameArg.SndDigiSampleRate, out_format, out_channels, out_freq); + cvt.buf = malloc(dlen * cvt.len_mult); + cvt.len = dlen; + memcpy(cvt.buf, data, dlen); + if (SDL_ConvertAudio(&cvt)) con_printf(CON_DEBUG,"conversion of %d failed\n", i); - cvt.buf = malloc(dlen * cvt.len_mult); - cvt.len = dlen; - memcpy(cvt.buf, data, dlen); - if (SDL_ConvertAudio(&cvt)) con_printf(CON_DEBUG,"conversion of %d failed\n", i); - - SoundChunks[i].abuf = cvt.buf; - SoundChunks[i].alen = dlen * cvt.len_mult; - SoundChunks[i].allocated = 1; - SoundChunks[i].volume = 128; // Max volume = 128 - } + SoundChunks[i].abuf = cvt.buf; + SoundChunks[i].alen = dlen * cvt.len_mult; + SoundChunks[i].allocated = 1; + SoundChunks[i].volume = 128; // Max volume = 128 + } } // Volume 0-F1_0 int digi_mixer_start_sound(short soundnum, fix volume, int pan, int looping, int loop_start, int loop_end, int soundobj) { - int mix_vol = fix2byte(fixmul(digi_volume, volume)); - int mix_pan = fix2byte(pan); - int mix_loop = looping * -1; - int channel; + int mix_vol = fix2byte(fixmul(digi_volume, volume)); + int mix_pan = fix2byte(pan); + int mix_loop = looping * -1; + int channel; - if (!digi_initialised) return -1; - Assert(GameSounds[soundnum].data != (void *)-1); + if (!digi_initialised) return -1; + Assert(GameSounds[soundnum].data != (void *)-1); - mixdigi_convert_sound(soundnum); + mixdigi_convert_sound(soundnum); - if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"digi_start_sound %d, volume %d, pan %d (start=%d, end=%d)\n", soundnum, mix_vol, mix_pan, loop_start, loop_end); + if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"digi_start_sound %d, volume %d, pan %d (start=%d, end=%d)\n", soundnum, mix_vol, mix_pan, loop_start, loop_end); + + channel = digi_mixer_find_channel(); - channel = Mix_PlayChannel(-1, &(SoundChunks[soundnum]), mix_loop); - Mix_SetPanning(channel, 255-mix_pan, mix_pan); - if (volume > F1_0) - Mix_SetDistance(channel, 0); - else - Mix_SetDistance(channel, 255-mix_vol); + Mix_PlayChannel(channel, &(SoundChunks[soundnum]), mix_loop); + Mix_SetPanning(channel, 255-mix_pan, mix_pan); + if (volume > F1_0) + Mix_SetDistance(channel, 0); + else + Mix_SetDistance(channel, 255-mix_vol); + channels[channel] = 1; + Mix_ChannelFinished(digi_mixer_free_channel); - return channel; + return channel; } -void digi_mixer_set_channel_volume(int channel, int volume) { - int mix_vol = fix2byte(volume); - if (!digi_initialised) return; - Mix_SetDistance(channel, 255-mix_vol); +void digi_mixer_set_channel_volume(int channel, int volume) +{ + int mix_vol = fix2byte(volume); + if (!digi_initialised) return; + Mix_SetDistance(channel, 255-mix_vol); } -void digi_mixer_set_channel_pan(int channel, int pan) { - int mix_pan = fix2byte(pan); - Mix_SetPanning(channel, 255-mix_pan, mix_pan); +void digi_mixer_set_channel_pan(int channel, int pan) +{ + int mix_pan = fix2byte(pan); + Mix_SetPanning(channel, 255-mix_pan, mix_pan); } void digi_mixer_stop_sound(int channel) { - if (!digi_initialised) return; - if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"digi_stop_sound %d\n", channel); - Mix_HaltChannel(channel); + if (!digi_initialised) return; + if (MIX_DIGI_DEBUG) con_printf(CON_DEBUG,"digi_stop_sound %d\n", channel); + Mix_HaltChannel(channel); + channels[channel] = 0; } -void digi_mixer_end_sound(int channel) { - digi_mixer_stop_sound(channel); +void digi_mixer_end_sound(int channel) +{ + digi_mixer_stop_sound(channel); + channels[channel] = 0; } void digi_mixer_set_digi_volume( int dvolume ) { - digi_volume = dvolume; - if (!digi_initialised) return; - Mix_Volume(-1, fix2byte(dvolume)); + digi_volume = dvolume; + if (!digi_initialised) return; + Mix_Volume(-1, fix2byte(dvolume)); } -int digi_mixer_find_channel(int soundno) { return 0; } int digi_mixer_is_sound_playing(int soundno) { return 0; } int digi_mixer_is_channel_playing(int channel) { return 0; } void digi_mixer_reset() {} -void digi_mixer_stop_all_channels() { +void digi_mixer_stop_all_channels() +{ Mix_HaltChannel(-1); + memset(channels, 0, MAX_SOUND_SLOTS); } extern void digi_end_soundobj(int channel); -int verify_sound_channel_free(int channel); //added on 980905 by adb to make sound channel setting work void digi_mixer_set_max_channels(int n) { } diff --git a/main/digi.h b/main/digi.h index a1c5f7c96..bc5f75a99 100644 --- a/main/digi.h +++ b/main/digi.h @@ -71,10 +71,6 @@ extern int digi_xlat_sound(int soundno); extern void digi_stop_sound( int channel ); -// Returns the channel a sound number is playing on, or -// -1 if none. -extern int digi_find_channel(int soundno); - // Volume 0-F1_0 extern int digi_start_sound(short soundnum, fix volume, int pan, int looping, int loop_start, int loop_end, int soundobj); diff --git a/main/digiobj.c b/main/digiobj.c index bead0dcc7..2fef307ce 100644 --- a/main/digiobj.c +++ b/main/digiobj.c @@ -149,8 +149,6 @@ void digi_get_sound_loc( vms_matrix * listener, vms_vector * listener_pos, int l void digi_play_sample_once( int soundno, fix max_volume ) { - int channel; - if ( Newdemo_state == ND_STATE_RECORDING ) newdemo_record_sound( soundno ); @@ -158,10 +156,6 @@ void digi_play_sample_once( int soundno, fix max_volume ) if (soundno < 0 ) return; - channel=digi_find_channel(soundno); - if ( channel > -1 ) - digi_stop_sound( channel ); - // start the sample playing digi_start_sound( soundno, max_volume, 0xffff/2, 0, -1, -1, -1 ); }