From 530dd11e645ca8eb502561b6843ec5e8537efc35 Mon Sep 17 00:00:00 2001 From: Bradley Bell Date: Fri, 25 Feb 2005 10:49:48 +0000 Subject: [PATCH] rip out digiobj stuff, use d2src system for persistent sounds. Untested, of course. --- ChangeLog | 6 + arch/dos/digi.c | 662 ++++++++++------------------------------ arch/dos/digiallg.c | 612 +++++-------------------------------- arch/dos/digimm.c | 684 ++++++++---------------------------------- arch/linux/alsadigi.c | 683 +++++++++-------------------------------- arch/win32/digi.c | 616 +++++++------------------------------ 6 files changed, 610 insertions(+), 2653 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b6bd0ab..f2091cce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-02-25 Bradley Bell + + * arch/dos/digi.c, arch/dos/digiallg.c, arch/dos/digimm.c, + arch/linux/alsadigi, arch/win32/digi.c: rip out digiobj stuff, use + d2src system for persistent sounds. Untested, of course. + 2005-02-24 Tim Massey * main/inferno.c: allow -notitles to work in shareware [and diff --git a/arch/dos/digi.c b/arch/dos/digi.c index de558b2d..4a350447 100644 --- a/arch/dos/digi.c +++ b/arch/dos/digi.c @@ -1,12 +1,15 @@ /* * $Source: /cvs/cvsroot/d2x/arch/dos/digi.c,v $ - * $Revision: 1.3 $ - * $Author: bradleyb $ - * $Date: 2001-10-25 08:25:33 $ + * $Revision: 1.4 $ + * $Author: btb $ + * $Date: 2005-02-25 10:49:48 $ * * DOS digital audio support * * $Log: not supported by cvs2svn $ + * Revision 1.3 2001/10/25 08:25:33 bradleyb + * Finished moving stuff to arch/blah. I know, it's ugly, but It'll be easier to sync with d1x. + * * Revision 1.3 2001/01/31 14:04:45 bradleyb * Fix compiler warnings * @@ -36,7 +39,7 @@ #include "newdemo.h" #include "kconfig.h" -int digi_sample_rate=11025; +int digi_sample_rate = SAMPLE_RATE_11K; int digi_timer_rate = 9943; // rate for the timer to go off to handle the driver system (120 Hz) //edited 05/17/99 Matt Mueller - added ifndef NO_ASM @@ -119,43 +122,6 @@ static const unsigned char mix8[] = 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; -#define SOF_USED 1 // Set if this sample is used -#define SOF_PLAYING 2 // Set if this sample is playing on a channel -#define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits. -#define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos -#define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once - -typedef struct sound_object { - short signature; // A unique signature to this sound - ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long. - fix max_volume; // Max volume that this sound is playing at - fix max_distance; // The max distance that this sound can be heard at... - int volume; // Volume that this sound is playing at - int pan; // Pan value that this sound is playing at - int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set. - short soundnum; // The sound number that is playing - union { - struct { - short segnum; // Used if SOF_LINK_TO_POS field is used - short sidenum; - vms_vector position; - }pos; - struct { - short objnum; // Used if SOF_LINK_TO_OBJ field is used - short objsignature; - }obj; - }link; -} sound_object; -#define lp_segnum link.pos.segnum -#define lp_sidenum link.pos.sidenum -#define lp_position link.pos.position - -#define lo_objnum link.obj.objnum -#define lo_objsignature link.obj.objsignature - -#define MAX_SOUND_OBJECTS 16 -sound_object SoundObjects[MAX_SOUND_OBJECTS]; -short next_signature=0; //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2 #define SOUND_MAX_VOLUME (F1_0 / 2) @@ -163,8 +129,6 @@ short next_signature=0; int digi_volume = SOUND_MAX_VOLUME; //end edit by adb -int digi_lomem = 0; - static int digi_initialised = 0; struct sound_slot { @@ -178,18 +142,13 @@ struct sound_slot { //end changes by adb unsigned int length; // Length of the sample unsigned int position; // Position we are at at the moment. + int soundobj; // Which soundobject is on this channel + int persistent; // This can't be pre-empted } SoundSlots[MAX_SOUND_SLOTS]; -static int digi_sounds_initialized = 0; - -//added on 980905 by adb to add rotating/volume based sound kill system static int digi_max_channels = 16; -static int next_handle = 0; -int SampleHandles[32]; -void reset_sounds_on_channel(int channel); -//end edit by adb -void digi_reset_digi_sounds(void); +static int next_channel = 0; /* Audio mixing callback */ //changed on 980905 by adb to cleanup, add pan support and optimize mixer @@ -262,489 +221,107 @@ void digi_close() digi_initialised = 0; } -/* Find the sound which actually equates to a sound number */ -int digi_xlat_sound(int soundno) +void digi_stop_all_channels() { - if ( soundno < 0 ) return -1; - - if ( digi_lomem ) { - soundno = AltSounds[soundno]; - if ( soundno == 255 ) return -1; - } - return Sounds[soundno]; -} - -static int get_free_slot() -{ - int i; - for (i=0; i= 0) && (SoundSlots[SampleHandles[next_handle]].playing) ) - { - if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries= digi_max_channels ) - next_handle = 0; - ntries++; - goto TryNextChannel; - } - //mprintf(( 0, "[SS:%d]", next_handle )); - SoundSlots[SampleHandles[next_handle]].playing = 0; - SampleHandles[next_handle] = -1; - } - //end edit by adb - - slot = get_free_slot(); - if (slot<0) return -1; - - SoundSlots[slot].soundno = soundnum; - SoundSlots[slot].samples = GameSounds[soundnum].data; - SoundSlots[slot].length = GameSounds[soundnum].length; - SoundSlots[slot].volume = fixmul(digi_volume, volume); - SoundSlots[slot].pan = pan; - SoundSlots[slot].position = 0; - SoundSlots[slot].looped = 0; - SoundSlots[slot].playing = 1; - - //added on 980905 by adb to add sound kill system from original sos digi.c - reset_sounds_on_channel(slot); - SampleHandles[next_handle] = slot; - next_handle++; - if ( next_handle >= digi_max_channels ) - next_handle = 0; - //end edit by adb - - return slot; -} - - //added on 980905 by adb to add sound kill system from original sos digi.c -void reset_sounds_on_channel( int channel ) -{ - int i; - - for (i=0; i -1 ) { - *volume = max_volume - fixdiv(path_distance,max_distance); - //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume )); - if (*volume > 0 ) { - angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec); - fix_sincos(angle_from_ear,&sinang,&cosang); - //mprintf( (0, "volume is %.2f\n", f2fl(*volume) )); - if (Config_channels_reversed) cosang *= -1; - *pan = (cosang + F1_0)/2; - } else { - *volume = 0; - } + next_channel++; + if (next_channel >= digi_max_channels) + next_channel = 0; + if (next_channel == starting_channel) + { + mprintf((1, "OUT OF SOUND CHANNELS!!!\n")); + return -1; } - } -} - -int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance ) -{ - int i,volume,pan; - object * objp; - int soundnum; - - soundnum = digi_xlat_sound(org_soundnum); - - if ( max_volume < 0 ) return -1; -// if ( max_volume > F1_0 ) max_volume = F1_0; - - if (!digi_initialised) return -1; - if (soundnum < 0 ) return -1; - if (GameSounds[soundnum].data==NULL) { - Int3(); - return -1; } - if ((objnum<0)||(objnum>Highest_object_index)) - return -1; - - if ( !forever ) { - // Hack to keep sounds from building up... - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance ); - digi_play_sample_3d( org_soundnum, pan, volume, 0 ); - return -1; + if (SoundSlots[next_channel].playing) + { + SoundSlots[next_channel].playing = 0; + if (SoundSlots[next_channel].soundobj > -1) + { + digi_end_soundobj(SoundSlots[next_channel].soundobj); + } + if (SoundQ_channel == next_channel) + SoundQ_end(); } - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; + SoundSlots[next_channel].soundno = soundnum; + SoundSlots[next_channel].samples = GameSounds[soundnum].data; + SoundSlots[next_channel].length = GameSounds[soundnum].length; + SoundSlots[next_channel].volume = fixmul(digi_volume, volume); + SoundSlots[next_channel].pan = pan; + SoundSlots[next_channel].position = 0; + SoundSlots[next_channel].looped = looping; + SoundSlots[next_channel].playing = 1; + SoundSlots[next_channel].soundobj = soundobj; + SoundSlots[next_channel].persistent = 0; + if ((soundobj > -1) || (looping) || (volume > F1_0)) + SoundSlots[next_channel].persistent = 1; + + i = next_channel; + next_channel++; + if (next_channel >= digi_max_channels) + next_channel = 0; + + return i; } -int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume ) -{ return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); } -int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance ) +// Returns the channel a sound number is playing on, or +// -1 if none. +int digi_find_channel(int soundno) { - int i, volume, pan; - int soundnum; - - soundnum = digi_xlat_sound(org_soundnum); - - if ( max_volume < 0 ) return -1; -// if ( max_volume > F1_0 ) max_volume = F1_0; - - if (!digi_initialised) return -1; - if (soundnum < 0 ) return -1; - if (GameSounds[soundnum].data==NULL) { - Int3(); + if (!digi_initialised) return -1; - } - if ((segnum<0)||(segnum>Highest_segment_index)) + if (soundno < 0 ) return -1; - if ( !forever ) { - // Hack to keep sounds from building up... - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance ); - digi_play_sample_3d( org_soundnum, pan, volume, 0 ); - return -1; - } - - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; -} - -int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume ) -{ - return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 ); -} - -void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum ) -{ - int i,killed; - - soundnum = digi_xlat_sound(soundnum); - - if (!digi_initialised) return; - - killed = 0; - - for (i=0; i 1 ) { - mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum )); - } -} - -void digi_kill_sound_linked_to_object( int objnum ) -{ - int i,killed; - - if (!digi_initialised) return; - - killed = 0; - - for (i=0; i 1 ) { - mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum )); - } -} - -void digi_sync_sounds() -{ - int i; - int oldvolume, oldpan; - - if (!digi_initialised) return; - - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) { - object * objp; - - objp = &Objects[SoundObjects[i].lo_objnum]; - - if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) { - // The object that this is linked to is dead, so just end this sound if it is looping. - if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - SoundSlots[SoundObjects[i].handle].playing = 0; - } - SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound - continue; // Go on to next sound... - } else { - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - } - } - - if (oldvolume != SoundObjects[i].volume) { - if ( SoundObjects[i].volume < MIN_VOLUME ) { - // Sound is too far away, so stop it from playing. - if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - SoundSlots[SoundObjects[i].handle].playing = 0; - SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing - } - } else { - if (!(SoundObjects[i].flags & SOF_PLAYING)) { - digi_start_sound_object(i); - } else { - SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0); - } - } - } - - if (oldpan != SoundObjects[i].pan) { - if (SoundObjects[i].flags & SOF_PLAYING) - SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan; - } - } - } + //FIXME: not implemented + return -1; } -void digi_init_sounds() -{ - int i; - - if (!digi_initialised) return; - - digi_reset_digi_sounds(); - - for (i=0; i (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) ) - digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS); + if (digi_max_channels > MAX_SOUND_SLOTS) + digi_max_channels = MAX_SOUND_SLOTS; if ( !digi_initialised ) return; - digi_reset_digi_sounds(); + digi_stop_all_channels(); } int digi_get_max_channels() { @@ -803,6 +376,55 @@ int digi_get_max_channels() { } // end edit by adb +int digi_is_channel_playing(int channel) +{ + if (!digi_initialised) + return 0; + + return SoundSlots[channel].playing; +} + +void digi_set_channel_volume(int channel, int volume) +{ + if (!digi_initialised) + return; + + if (!SoundSlots[channel].playing) + return; + + SoundSlots[channel].volume = fixmuldiv(volume, digi_volume, F1_0); +} + +void digi_set_channel_pan(int channel, int pan) +{ + if (!digi_initialised) + return; + + if (!SoundSlots[channel].playing) + return; + + SoundSlots[channel].pan = pan; +} + +void digi_stop_sound(int channel) +{ + SoundSlots[channel].playing = 0; + SoundSlots[channel].soundobj = -1; + SoundSlots[channel].persistent = 0; +} + +void digi_end_sound(int channel) +{ + if (!digi_initialised) + return; + + if (!SoundSlots[channel].playing) + return; + + SoundSlots[channel].soundobj = -1; + SoundSlots[channel].persistent = 0; +} + void digi_reset_digi_sounds() { int i; @@ -829,4 +451,26 @@ void digi_reset_digi_sounds() { // send_ipc(buf); //#endif //} +//void digi_pause_midi() {} +//void digi_resume_midi() {} //end this section kill - MM + +#ifndef NDEBUG +void digi_debug() +{ + int i; + int n_voices = 0; + + if (!digi_initialised) + return; + + for (i = 0; i < digi_max_channels; i++) + { + if (digi_is_channel_playing(i)) + n_voices++; + } + + mprintf_at((0, 2, 0, "DIGI: Active Sound Channels: %d/%d (HMI says %d/32) ", n_voices, digi_max_channels, -1)); + //mprintf_at((0, 3, 0, "DIGI: Number locked sounds: %d ", digi_total_locks )); +} +#endif diff --git a/arch/dos/digiallg.c b/arch/dos/digiallg.c index b0e8efeb..7edd5b1c 100644 --- a/arch/dos/digiallg.c +++ b/arch/dos/digiallg.c @@ -61,7 +61,6 @@ static int digi_max_channels = 8; //static int digi_driver_rate = 11025; // rate to use driver at //static int digi_dma_buffersize = 4096; // size of the dma buffer to use (4k) int digi_timer_rate = 9943; // rate for the timer to go off to handle the driver system (120 Hz) -int digi_lomem = 0; static int digi_volume = _DIGI_MAX_VOLUME; // Max volume //static int midi_volume = 128/2; // Max volume //static int midi_system_initialized = 0; @@ -83,48 +82,6 @@ extern int midi_volume; // handle for the initialized MIDI song //MIDI *SongHandle = NULL; -#define SOF_USED 1 // Set if this sample is used -#define SOF_PLAYING 2 // Set if this sample is playing on a channel -#define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits. -#define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos -#define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once - -typedef int WORD; - -typedef struct sound_object { - short signature; // A unique signature to this sound - ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long. - fix max_volume; // Max volume that this sound is playing at - fix max_distance; // The max distance that this sound can be heard at... - int volume; // Volume that this sound is playing at - int pan; // Pan value that this sound is playing at - WORD handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set. - short soundnum; // The sound number that is playing - union { - struct { - short segnum; // Used if SOF_LINK_TO_POS field is used - short sidenum; - vms_vector position; - }pos; - struct { - short objnum; // Used if SOF_LINK_TO_OBJ field is used - short objsignature; - }obj; - }link; -} sound_object; -#define lp_segnum link.pos.segnum -#define lp_sidenum link.pos.sidenum -#define lp_position link.pos.position - -#define lo_objnum link.obj.objnum -#define lo_objsignature link.obj.objsignature - -#define MAX_SOUND_OBJECTS 16 -sound_object SoundObjects[MAX_SOUND_OBJECTS]; -short next_signature=0; - -int digi_sounds_initialized=0; - // a channel (voice) id is an int in Allegro typedef int CHANNEL; @@ -153,17 +110,6 @@ static uint SoundVolumes[DIGI_SLOTS] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, void digi_reset_digi_sounds(); int verify_channel_not_used_by_soundobjects( int channel ); -int digi_xlat_sound(int soundno) -{ - if ( soundno < 0 ) return -1; - - if ( digi_lomem ) { - soundno = AltSounds[soundno]; - if ( soundno == 255 ) return -1; - } - return Sounds[soundno]; -} - void digi_close() { if (!Digi_initialized) return; @@ -284,23 +230,6 @@ void digi_reset_digi_sounds() { } } -void reset_slots_on_channel( int channel ) { - int i; - - if ( !Digi_initialized ) return; - if ( digi_driver_board <= 0 ) return; - - for (i=0; i -1 ) { - *volume = max_volume - fixdiv(path_distance,max_distance); - //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume )); - if (*volume > 0 ) { - angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec); - fix_sincos(angle_from_ear,&sinang,&cosang); - //mprintf( (0, "volume is %.2f\n", f2fl(*volume) )); - if (Config_channels_reversed) cosang *= -1; - *pan = (cosang + F1_0)/2; - } else { - *volume = 0; - } - } - } -} - -void digi_init_sounds() -{ - int i; - - if (!Digi_initialized) return; - if (digi_driver_board<1) return; - - digi_reset_digi_sounds(); - - for (i=0; i> 8, /* 0-255 */ - 1000, - (SoundObjects[i].flags & SOF_PLAY_FOREVER) ? 1 : 0 - ); - if (SoundObjects[i].handle < 0) { - mprintf(( 1, "NOT ENOUGH SOUND SLOTS!!! (SoundObject)\n" )); - //digi_unlock_sound(SoundObjects[i].soundnum); //never unlocked... - } else { - SoundObjects[i].flags |= SOF_PLAYING; - reset_slots_on_channel( SoundObjects[i].handle ); - } -} - -int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance ) -{ - int i,volume,pan; - object * objp; - int soundnum; - - soundnum = digi_xlat_sound(org_soundnum); - if ( max_volume < 0 ) return -1; -// if ( max_volume > F1_0 ) max_volume = F1_0; - - if (!Digi_initialized) return -1; - if (soundnum < 0 ) return -1; - if (GameSounds[soundnum].data==NULL) { - Int3(); - return -1; - } - if ((objnum<0)||(objnum>Highest_object_index)) - return -1; - if (digi_driver_board<1) return -1; - - if ( !forever ) { - // Hack to keep sounds from building up... - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance ); - digi_play_sample_3d( org_soundnum, pan, volume, 0 ); - return -1; - } - - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; -} - -int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume ) -{ // 10 segs away - return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0 ); -} - -int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance ) -{ - int i, volume, pan; - int soundnum; - - soundnum = digi_xlat_sound(org_soundnum); - - if ( max_volume < 0 ) return -1; -// if ( max_volume > F1_0 ) max_volume = F1_0; - - if (!Digi_initialized) return -1; - if (soundnum < 0 ) return -1; - if (GameSounds[soundnum].data==NULL) { - Int3(); - return -1; - } - if (digi_driver_board<1) return -1; - - if ((segnum<0)||(segnum>Highest_segment_index)) - return -1; - - if ( !forever ) { - // Hack to keep sounds from building up... - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance ); - digi_play_sample_3d( org_soundnum, pan, volume, 0 ); - return -1; - } - - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; -} - -int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume ) -{ - return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 ); -} - -void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum ) -{ - int i,killed; - - soundnum = digi_xlat_sound(soundnum); - - if (!Digi_initialized) return; - if (digi_driver_board<1) return; - - killed = 0; - - for (i=0; i 1 ) { - mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum )); - } -} - -void digi_kill_sound_linked_to_object( int objnum ) -{ - int i,killed; - - if (!Digi_initialized) return; - if (digi_driver_board<1) return; - - killed = 0; - - for (i=0; i 1 ) { - mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum )); - } -} - -void digi_sync_sounds() -{ - int i; - int oldvolume, oldpan; - - if (!Digi_initialized) return; - if (digi_driver_board<1) return; - - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) { - object * objp; - - objp = &Objects[SoundObjects[i].lo_objnum]; - - if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) { - // The object that this is linked to is dead, so just end this sound if it is looping. - if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - deallocate_voice(SoundObjects[i].handle); - } - SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound - continue; // Go on to next sound... - } else { - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - } - } - - if (oldvolume != SoundObjects[i].volume) { - if ( SoundObjects[i].volume < MIN_VOLUME ) { - // Sound is too far away, so stop it from playing. - if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - deallocate_voice(SoundObjects[i].handle); - SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing - } - } else { - if (!(SoundObjects[i].flags & SOF_PLAYING)) { - digi_start_sound_object(i); - } else { - voice_set_volume(SoundObjects[i].handle, fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0)); - } - } - } - - if (oldpan != SoundObjects[i].pan) { - if (SoundObjects[i].flags & SOF_PLAYING) - voice_set_pan(SoundObjects[i].handle, SoundObjects[i].pan >> 8); - } - } - } -} - -int sound_paused = 0; - -void digi_pause_all() +#ifndef NDEBUG +void digi_debug() { int i; + int n_voices = 0; - if (!Digi_initialized) return; - - if (sound_paused==0) { -// if ( digi_midi_type > 0 ) { -// if (SongHandle) -// midi_pause(); -// } - digi_midi_pause(); - if (digi_driver_board>0) { - for (i=0; i 0 ); + if (!digi_initialised) + return; - if (sound_paused==1) { - // resume sound here -// if ( digi_midi_type > 0 ) { -// if (SongHandle) -// midi_resume(); -// } - digi_midi_resume(); + for (i = 0; i < digi_max_channels; i++) + { + if (digi_is_channel_playing(i)) + n_voices++; } - sound_paused--; -} - -void digi_stop_all() -{ - int i; - - if (!Digi_initialized) return; -// if ( digi_midi_type > 0 ) { -// if (SongHandle) { -// destroy_midi(SongHandle); -// SongHandle = NULL; -// } -// } - digi_midi_stop(); - - if (digi_driver_board>0) { - for (i=0; i= 0) && (SoundSlots[SampleHandles[next_handle]].playing) ) - { - if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries= digi_max_channels ) - next_handle = 0; - ntries++; - goto TryNextChannel; - } - //mprintf(( 0, "[SS:%d]", next_handle )); - SoundSlots[SampleHandles[next_handle]].playing = 0; - SampleHandles[next_handle] = -1; - } - //end edit by adb - - slot = get_free_slot(); - if (slot<0) return -1; - - if (volume > F2_0) - volume = F2_0; - SoundSlots[slot].soundno = soundnum; - SoundSlots[slot].samples = GameSounds[soundnum].data; - SoundSlots[slot].length = GameSounds[soundnum].length; - SoundSlots[slot].volume = fixmul(digi_volume, volume); - SoundSlots[slot].pan = pan; - SoundSlots[slot].position = 0; - SoundSlots[slot].looped = 0; - SoundSlots[slot].playing = 1; - - //added on 980905 by adb to add sound kill system from original sos digi.c - reset_sounds_on_channel(slot); - SampleHandles[next_handle] = slot; - next_handle++; - if ( next_handle >= digi_max_channels ) - next_handle = 0; - //end edit by adb - - return slot; -} - - //added on 980905 by adb to add sound kill system from original sos digi.c -void reset_sounds_on_channel( int channel ) -{ - int i; - - for (i=0; i -1 ) { - *volume = max_volume - fixdiv(path_distance,max_distance); - //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume )); - if (*volume > 0 ) { - angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec); - fix_sincos(angle_from_ear,&sinang,&cosang); - //mprintf( (0, "volume is %.2f\n", f2fl(*volume) )); - if (Config_channels_reversed) cosang *= -1; - *pan = (cosang + F1_0)/2; - } else { - *volume = 0; - } + next_channel++; + if (next_channel >= digi_max_channels) + next_channel = 0; + if (next_channel == starting_channel) + { + mprintf((1, "OUT OF SOUND CHANNELS!!!\n")); + return -1; } - } -} - -int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance ) -{ - int i,volume,pan; - object * objp; - int soundnum; - - soundnum = digi_xlat_sound(org_soundnum); - - if ( max_volume < 0 ) return -1; -// if ( max_volume > F1_0 ) max_volume = F1_0; - - if (!digi_initialised) return -1; - if (soundnum < 0 ) return -1; - if (GameSounds[soundnum].data==NULL) { - Int3(); - return -1; } - if ((objnum<0)||(objnum>Highest_object_index)) - return -1; - - if ( !forever ) { - // Hack to keep sounds from building up... - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance ); - digi_play_sample_3d( org_soundnum, pan, volume, 0 ); - return -1; + if (SoundSlots[next_channel].playing) + { + SoundSlots[next_channel].playing = 0; + if (SoundSlots[next_channel].soundobj > -1) + { + digi_end_soundobj(SoundSlots[next_channel].soundobj); + } + if (SoundQ_channel == next_channel) + SoundQ_end(); } - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; + SoundSlots[next_channel].soundno = soundnum; + SoundSlots[next_channel].samples = GameSounds[soundnum].data; + SoundSlots[next_channel].length = GameSounds[soundnum].length; + SoundSlots[next_channel].volume = fixmul(digi_volume, volume); + SoundSlots[next_channel].pan = pan; + SoundSlots[next_channel].position = 0; + SoundSlots[next_channel].looped = looping; + SoundSlots[next_channel].playing = 1; + SoundSlots[next_channel].soundobj = soundobj; + SoundSlots[next_channel].persistent = 0; + if ((soundobj > -1) || (looping) || (volume > F1_0)) + SoundSlots[next_channel].persistent = 1; + + i = next_channel; + next_channel++; + if (next_channel >= digi_max_channels) + next_channel = 0; + + return i; } -int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume ) -{ return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); } - -int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance ) +// Returns the channel a sound number is playing on, or +// -1 if none. +int digi_find_channel(int soundno) { - int i, volume, pan; - int soundnum; - - soundnum = digi_xlat_sound(org_soundnum); - - if ( max_volume < 0 ) return -1; -// if ( max_volume > F1_0 ) max_volume = F1_0; - - if (!digi_initialised) return -1; - if (soundnum < 0 ) return -1; - if (GameSounds[soundnum].data==NULL) { - Int3(); + if (!digi_initialised) return -1; - } - if ((segnum<0)||(segnum>Highest_segment_index)) + if (soundno < 0 ) return -1; - if ( !forever ) { - // Hack to keep sounds from building up... - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance ); - digi_play_sample_3d( org_soundnum, pan, volume, 0 ); - return -1; - } - - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; -} - -int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume ) -{ - return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 ); -} - -void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum ) -{ - int i,killed; - - soundnum = digi_xlat_sound(soundnum); - - if (!digi_initialised) return; - - killed = 0; - - for (i=0; i 1 ) { - mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum )); - } -} - -void digi_kill_sound_linked_to_object( int objnum ) -{ - int i,killed; - - if (!digi_initialised) return; - - killed = 0; - - for (i=0; i 1 ) { - mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum )); - } -} - -void digi_sync_sounds() -{ - int i; - int oldvolume, oldpan; - - if (!digi_initialised) return; - - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) { - object * objp; - - objp = &Objects[SoundObjects[i].lo_objnum]; - - if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) { - // The object that this is linked to is dead, so just end this sound if it is looping. - if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - SoundSlots[SoundObjects[i].handle].playing = 0; - } - SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound - continue; // Go on to next sound... - } else { - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - } - } - - if (oldvolume != SoundObjects[i].volume) { - if ( SoundObjects[i].volume < MIN_VOLUME ) { - // Sound is too far away, so stop it from playing. - if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - SoundSlots[SoundObjects[i].handle].playing = 0; - SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing - } - } else { - if (!(SoundObjects[i].flags & SOF_PLAYING)) { - digi_start_sound_object(i); - } else { - SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0); - } - } - } - - if (oldpan != SoundObjects[i].pan) { - if (SoundObjects[i].flags & SOF_PLAYING) - SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan; - } - } - } -} - -void digi_stop_soundobjects() { - int i; - - for (i=0; i (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) ) - digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS); + if (digi_max_channels > MAX_SOUND_SLOTS) + digi_max_channels = MAX_SOUND_SLOTS; if ( !digi_initialised ) return; - digi_reset_digi_sounds(); + digi_stop_all_channels(); } int digi_get_max_channels() { @@ -912,51 +460,75 @@ int digi_get_max_channels() { } // end edit by adb -void digi_reset_digi_sounds() +int digi_is_channel_playing(int channel) { - int i; - - for (i=0; i< MAX_SOUND_SLOTS; i++) - SoundSlots[i].playing=0; - - //added on 980905 by adb to reset sound kill system - memset(SampleHandles, 255, sizeof(SampleHandles)); - next_handle = 0; - //end edit by adb + if (!digi_initialised) + return 0; + + return SoundSlots[channel].playing; } -int sound_paused = 0; +void digi_set_channel_volume(int channel, int volume) +{ + if (!digi_initialised) + return; + + if (!SoundSlots[channel].playing) + return; -void digi_pause_all() + SoundSlots[channel].volume = fixmuldiv(volume, digi_volume, F1_0); +} + +void digi_set_channel_pan(int channel, int pan) { - if (!digi_initialised) return; - if (sound_paused==0) { - digi_midi_pause(); - digi_stop_soundobjects(); - } - sound_paused++; + if (!digi_initialised) + return; + + if (!SoundSlots[channel].playing) + return; + + SoundSlots[channel].pan = pan; } -void digi_resume_all() +void digi_stop_sound(int channel) { - if (!digi_initialised) return; + SoundSlots[channel].playing=0; + SoundSlots[channel].soundobj = -1; + SoundSlots[channel].persistent = 0; +} + +void digi_end_sound(int channel) +{ + if (!digi_initialised) + return; - Assert( sound_paused > 0 ); + if (!SoundSlots[channel].playing) + return; - if (sound_paused==1) { - digi_midi_resume(); - } - sound_paused--; + SoundSlots[channel].soundobj = -1; + SoundSlots[channel].persistent = 0; } -void digi_stop_all() +#ifndef NDEBUG +void digi_debug() { - if (!digi_initialised) return; + int i; + int n_voices = 0; - digi_midi_stop(); + if (!digi_initialised) + return; - digi_stop_soundobjects(); + for (i = 0; i < digi_max_channels; i++) + { + if (digi_is_channel_playing(i)) + n_voices++; + } + + mprintf_at((0, 2, 0, "DIGI: Active Sound Channels: %d/%d (HMI says %d/32) ", n_voices, digi_max_channels, -1)); + //mprintf_at((0, 3, 0, "DIGI: Number locked sounds: %d ", digi_total_locks )); } +#endif + // mikmod stubs... BOOL VC_Init(void) { return 1; } diff --git a/arch/linux/alsadigi.c b/arch/linux/alsadigi.c index 61c95722..bb3c1e33 100644 --- a/arch/linux/alsadigi.c +++ b/arch/linux/alsadigi.c @@ -1,4 +1,4 @@ -/* $Id: alsadigi.c,v 1.3 2005-02-25 07:02:46 btb Exp $ */ +/* $Id: alsadigi.c,v 1.4 2005-02-25 10:49:48 btb Exp $ */ /* * * ALSA digital audio support @@ -103,52 +103,12 @@ static const ubyte mix8[] = 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; -#define SOF_USED 1 // Set if this sample is used -#define SOF_PLAYING 2 // Set if this sample is playing on a channel -#define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits. -#define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos -#define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once - -typedef struct sound_object { - short signature; // A unique signature to this sound - ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long. - fix max_volume; // Max volume that this sound is playing at - fix max_distance; // The max distance that this sound can be heard at... - int volume; // Volume that this sound is playing at - int pan; // Pan value that this sound is playing at - int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set. - short soundnum; // The sound number that is playing - union { - struct { - short segnum; // Used if SOF_LINK_TO_POS field is used - short sidenum; - vms_vector position; - }pos; - struct { - short objnum; // Used if SOF_LINK_TO_OBJ field is used - short objsignature; - }obj; - }link; -} sound_object; -#define lp_segnum link.pos.segnum -#define lp_sidenum link.pos.sidenum -#define lp_position link.pos.position - -#define lo_objnum link.obj.objnum -#define lo_objsignature link.obj.objsignature - -#define MAX_SOUND_OBJECTS 16 -sound_object SoundObjects[MAX_SOUND_OBJECTS]; -short next_signature=0; - //added/changed on 980905 by adb to make sfx volume work, on 990221 by adb changed F1_0 to F1_0 / 2 #define SOUND_MAX_VOLUME (F1_0 / 2) int digi_volume = SOUND_MAX_VOLUME; //end edit by adb -int digi_lomem = 0; - static int digi_initialised = 0; struct sound_slot { @@ -162,16 +122,13 @@ struct sound_slot { //end changes by adb unsigned int length; // Length of the sample unsigned int position; // Position we are at at the moment. + int soundobj; // Which soundobject is on this channel + int persistent; // This can't be pre-empted } SoundSlots[MAX_SOUND_SLOTS]; -static int digi_sounds_initialized = 0; - -//added on 980905 by adb to add rotating/volume based sound kill system static int digi_max_channels = 16; -static int next_handle = 0; -int SampleHandles[32]; -void reset_sounds_on_channel(int channel); -//end edit by adb + +static int next_channel = 0; /* Threading/ALSA stuff */ #define LOCK() pthread_mutex_lock(&mutex) @@ -181,9 +138,6 @@ pthread_t thread_id; pthread_mutex_t mutex; -void digi_reset_digi_sounds(void); - - /* Audio mixing callback */ //changed on 980905 by adb to cleanup, add pan support and optimize mixer static void audio_mixcallback(void *userdata, ubyte *stream, int len) @@ -374,511 +328,109 @@ void digi_close() snd_pcm_close(snd_devhandle); } -/* Find the sound which actually equates to a sound number */ -int digi_xlat_sound(int soundno) -{ - if ( soundno < 0 ) return -1; - - if ( digi_lomem ) { - soundno = AltSounds[soundno]; - if ( soundno == 255 ) return -1; - } - return Sounds[soundno]; -} - -static int get_free_slot() +void digi_stop_all_channels() { - int i; - for (i=0; i= 0) && (SoundSlots[SampleHandles[next_handle]].playing) ) - { - if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries= digi_max_channels ) - next_handle = 0; - ntries++; - goto TryNextChannel; - } - //mprintf(( 0, "[SS:%d]", next_handle )); - SoundSlots[SampleHandles[next_handle]].playing = 0; - SampleHandles[next_handle] = -1; - } - //end edit by adb - - slot = get_free_slot(); - if (slot<0) return -1; - - SoundSlots[slot].soundno = soundnum; - SoundSlots[slot].samples = GameSounds[soundnum].data; - SoundSlots[slot].length = GameSounds[soundnum].length; - SoundSlots[slot].volume = fixmul(digi_volume, volume); - SoundSlots[slot].pan = pan; - SoundSlots[slot].position = 0; - SoundSlots[slot].looped = 0; - SoundSlots[slot].playing = 1; - - //added on 980905 by adb to add sound kill system from original sos digi.c - reset_sounds_on_channel(slot); - SampleHandles[next_handle] = slot; - next_handle++; - if ( next_handle >= digi_max_channels ) - next_handle = 0; - //end edit by adb - UNLOCK(); - return slot; -} - - //added on 980905 by adb to add sound kill system from original sos digi.c -void reset_sounds_on_channel( int channel ) -{ - int i; + int i; - for (i=0; i -1 ) { - *volume = max_volume - fixdiv(path_distance,max_distance); - //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume )); - if (*volume > 0 ) { - angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec); - fix_sincos(angle_from_ear,&sinang,&cosang); - //mprintf( (0, "volume is %.2f\n", f2fl(*volume) )); - if (Config_channels_reversed) cosang *= -1; - *pan = (cosang + F1_0)/2; - } else { - *volume = 0; - } + next_channel++; + if (next_channel >= digi_max_channels) + next_channel = 0; + if (next_channel == starting_channel) + { + mprintf((1, "OUT OF SOUND CHANNELS!!!\n")); + UNLOCK(); + return -1; } - } -} - -int digi_link_sound_to_object2( int org_soundnum, short objnum, int forever, fix max_volume, fix max_distance ) -{ - int i,volume,pan; - object * objp; - int soundnum; - - soundnum = digi_xlat_sound(org_soundnum); - - if ( max_volume < 0 ) return -1; -// if ( max_volume > F1_0 ) max_volume = F1_0; - - if (!digi_initialised) return -1; - if (soundnum < 0 ) return -1; - if (GameSounds[soundnum].data==NULL) { - Int3(); - return -1; } - if ((objnum<0)||(objnum>Highest_object_index)) - return -1; - - if ( !forever ) { - // Hack to keep sounds from building up... - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume,&volume, &pan, max_distance ); - digi_play_sample_3d( org_soundnum, pan, volume, 0 ); - return -1; + if (SoundSlots[next_channel].playing) + { + SoundSlots[next_channel].playing = 0; + if (SoundSlots[next_channel].soundobj > -1) + { + digi_end_soundobj(SoundSlots[next_channel].soundobj); + } + if (SoundQ_channel == next_channel) + SoundQ_end(); } - for (i=0; i -1) || (looping) || (volume > F1_0)) + SoundSlots[next_channel].persistent = 1; + + i = next_channel; + next_channel++; + if (next_channel >= digi_max_channels) + next_channel = 0; + UNLOCK(); - SoundObjects[i].signature=next_signature++; - SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ; - if ( forever ) - SoundObjects[i].flags |= SOF_PLAY_FOREVER; - SoundObjects[i].lo_objnum = objnum; - SoundObjects[i].lo_objsignature = Objects[objnum].signature; - SoundObjects[i].max_volume = max_volume; - SoundObjects[i].max_distance = max_distance; - SoundObjects[i].volume = 0; - SoundObjects[i].pan = 0; - SoundObjects[i].soundnum = soundnum; - - objp = &Objects[SoundObjects[i].lo_objnum]; - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; + return i; } -int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume ) -{ return digi_link_sound_to_object2( soundnum, objnum, forever, max_volume, 256*F1_0); } - -int digi_link_sound_to_pos2( int org_soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance ) +// Returns the channel a sound number is playing on, or +// -1 if none. +int digi_find_channel(int soundno) { - int i, volume, pan; - //int soundnum; - - soundnum = digi_xlat_sound(org_soundnum); - - if ( max_volume < 0 ) return -1; -// if ( max_volume > F1_0 ) max_volume = F1_0; - - if (!digi_initialised) return -1; - if (soundnum < 0 ) return -1; - if (GameSounds[soundnum].data==NULL) { - Int3(); - return -1; - } - - if ((segnum<0)||(segnum>Highest_segment_index)) + if (!digi_initialised) return -1; - if ( !forever ) { - // Hack to keep sounds from building up... - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance ); - digi_play_sample_3d( org_soundnum, pan, volume, 0 ); + if (soundno < 0 ) return -1; - } - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; + //FIXME: not implemented + return -1; } -int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume ) -{ - return digi_link_sound_to_pos2( soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256 ); -} - -void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum ) -{ - int i,killed; - - soundnum = digi_xlat_sound(soundnum); - - if (!digi_initialised) return; - - killed = 0; - - for (i=0; i 1 ) { - mprintf( (1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum )); - } -} - -void digi_kill_sound_linked_to_object( int objnum ) -{ - int i,killed; - - if (!digi_initialised) return; - - killed = 0; - - for (i=0; i 1 ) { - mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum )); - } -} - -void digi_sync_sounds() -{ - int i; - int oldvolume, oldpan; - - if (!digi_initialised) return; - - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) { - object * objp; - - objp = &Objects[SoundObjects[i].lo_objnum]; - - if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) { - // The object that this is linked to is dead, so just end this sound if it is looping. - if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - LOCK(); - SoundSlots[SoundObjects[i].handle].playing = 0; - UNLOCK(); - } - SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound - continue; // Go on to next sound... - } else { - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - } - } - - if (oldvolume != SoundObjects[i].volume) { - if ( SoundObjects[i].volume < MIN_VOLUME ) { - // Sound is too far away, so stop it from playing. - if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - LOCK(); - SoundSlots[SoundObjects[i].handle].playing = 0; - UNLOCK(); - SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing - } - } else { - if (!(SoundObjects[i].flags & SOF_PLAYING)) { - digi_start_sound_object(i); - } else { - LOCK(); - SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0); - UNLOCK(); - } - } - } - - if (oldpan != SoundObjects[i].pan) { - if (SoundObjects[i].flags & SOF_PLAYING) { - LOCK(); - SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan; - UNLOCK(); - } - } - } - } -} - -void digi_init_sounds() -{ - int i; - - if (!digi_initialised) return; - - digi_reset_digi_sounds(); - - for (i=0; i (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) ) - digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS); + if (digi_max_channels > MAX_SOUND_SLOTS) + digi_max_channels = MAX_SOUND_SLOTS; if ( !digi_initialised ) return; - digi_reset_digi_sounds(); + digi_stop_all_channels(); } int digi_get_max_channels() { @@ -939,18 +492,64 @@ int digi_get_max_channels() { } // end edit by adb -void digi_reset_digi_sounds() { - int i; +int digi_is_channel_playing(int channel) +{ + if (!digi_initialised) + return 0; - LOCK(); - for (i=0; i< MAX_SOUND_SLOTS; i++) - SoundSlots[i].playing=0; - UNLOCK(); - - //added on 980905 by adb to reset sound kill system - memset(SampleHandles, 255, sizeof(SampleHandles)); - next_handle = 0; - //end edit by adb + LOCK(); + if (SoundSlots[channel].playing) + { + UNLOCK(); + return 1; + } + UNLOCK(); + return 0; +} + +void digi_set_channel_volume(int channel, int volume) +{ + if (!digi_initialised) + return; + + LOCK(); + if (SoundSlots[channel].playing) + SoundSlots[channel].volume = fixmuldiv(volume, digi_volume, F1_0); + UNLOCK(); +} + +void digi_set_channel_pan(int channel, int pan) +{ + if (!digi_initialised) + return; + + LOCK(); + if (SoundSlots[channel].playing) + SoundSlots[channel].pan = pan; + UNLOCK(); +} + +void digi_stop_sound(int channel) +{ + LOCK(); + SoundSlots[channel].playing = 0; + SoundSlots[channel].soundobj = -1; + SoundSlots[channel].persistent = 0; + UNLOCK(); +} + +void digi_end_sound(int channel) +{ + if (!digi_initialised) + return; + + LOCK(); + if (SoundSlots[channel].playing) + { + SoundSlots[channel].soundobj = -1; + SoundSlots[channel].persistent = 0; + } + UNLOCK(); } diff --git a/arch/win32/digi.c b/arch/win32/digi.c index 4ceb426b..5d449352 100644 --- a/arch/win32/digi.c +++ b/arch/win32/digi.c @@ -1,4 +1,4 @@ -/* $Id: digi.c,v 1.11 2004-05-22 23:01:20 btb Exp $ */ +/* $Id: digi.c,v 1.12 2005-02-25 10:49:48 btb Exp $ */ #define DIGI_SOUND #define MIDI_SOUND @@ -34,45 +34,6 @@ hmp_file *hmp = NULL; #define MIN_VOLUME 10 -#define SOF_USED 1 // Set if this sample is used -#define SOF_PLAYING 2 // Set if this sample is playing on a channel -#define SOF_LINK_TO_OBJ 4 // Sound is linked to a moving object. If object dies, then finishes play and quits. -#define SOF_LINK_TO_POS 8 // Sound is linked to segment, pos -#define SOF_PLAY_FOREVER 16 // Play forever (or until level is stopped), otherwise plays once - -typedef struct sound_object { - short signature; // A unique signature to this sound - ubyte flags; // Used to tell if this slot is used and/or currently playing, and how long. - fix max_volume; // Max volume that this sound is playing at - fix max_distance; // The max distance that this sound can be heard at... - int volume; // Volume that this sound is playing at - int pan; // Pan value that this sound is playing at - int handle; // What handle this sound is playing on. Valid only if SOF_PLAYING is set. - short soundnum; // The sound number that is playing - union { - struct { - short segnum; // Used if SOF_LINK_TO_POS field is used - short sidenum; - vms_vector position; - }pos; - struct { - short objnum; // Used if SOF_LINK_TO_OBJ field is used - short objsignature; - }obj; - }link; -} sound_object; -#define lp_segnum link.pos.segnum -#define lp_sidenum link.pos.sidenum -#define lp_position link.pos.position - -#define lo_objnum link.obj.objnum -#define lo_objsignature link.obj.objsignature - -#define MAX_SOUND_OBJECTS 16 -sound_object SoundObjects[MAX_SOUND_OBJECTS]; -short next_signature=0; - - //added/changed on 980905 by adb to make sfx volume work #define SOUND_MAX_VOLUME F1_0 int digi_volume = SOUND_MAX_VOLUME; @@ -99,7 +60,6 @@ struct sound_slot { } SoundSlots[MAX_SOUND_SLOTS]; -int digi_lomem = 0; int midi_volume = 255; int digi_midi_song_playing = 0; int digi_last_midi_song = 0; @@ -108,8 +68,6 @@ int digi_last_midi_song_loop = 0; static int digi_initialised = 0; static int digi_atexit_initialised=0; -static int digi_sounds_initialized = 0; - //added on 980905 by adb to add rotating/volume based sound kill system static int digi_max_channels = 16; static int next_handle = 0; @@ -195,6 +153,15 @@ static int DS_release_slot(int slot, int kill) return 1; } +void digi_stop_all_channels() +{ + int i; + + for (i = 0; i < MAX_SOUND_SLOTS; i++) + digi_stop_sound(i); +} + + static int get_free_slot() { int i; @@ -219,7 +186,8 @@ int D1vol2DSvol(fix d1v){ return log(f2fl(d1v))/log(2)*1000.0; } -int digi_start_sound(int soundnum, fix volume, fix pan) +// Volume 0-F1_0 +int digi_start_sound(short soundnum, fix volume, int pan, int looping, int loop_start, int loop_end, int soundobj) { int ntries; int slot; @@ -309,465 +277,36 @@ TryNextChannel: return slot; } - //added on 980905 by adb to add sound kill system from original sos digi.c -void reset_sounds_on_channel( int channel ) +// Returns the channel a sound number is playing on, or +// -1 if none. +int digi_find_channel(int soundno) { - int i; - - for (i=0; idata; - SoundSlots[slot].length = Sounddat(SoundObjects[obj].soundnum).length; - SoundSlots[slot].volume = fixmul(digi_volume, SoundObjects[obj].volume); - SoundSlots[slot].pan = SoundObjects[obj].pan; - SoundSlots[slot].position = 0; - SoundSlots[slot].looped = (SoundObjects[obj].flags & SOF_PLAY_FOREVER); - SoundSlots[slot].playing = 1; - - memset(&waveformat, 0, sizeof(waveformat)); - waveformat.wFormatTag = WAVE_FORMAT_PCM; - waveformat.wBitsPerSample = Sounddat(SoundObjects[obj].soundnum)->bits; - waveformat.nChannels = 1; - waveformat.nSamplesPerSec = Sounddat(SoundObjects[obj].soundnum)->freq; //digi_sample_rate; - waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample / 8); - waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; - - memset(&dsbd, 0, sizeof(dsbd)); - dsbd.dwSize = sizeof(dsbd); - dsbd.dwFlags = DSBCAPS_CTRLDEFAULT | DSBCAPS_GETCURRENTPOSITION2; - dsbd.dwReserved = 0; - dsbd.dwBufferBytes = SoundSlots[slot].length; - dsbd.lpwfxFormat = &waveformat; - - hr = IDirectSound_CreateSoundBuffer(lpds, &dsbd, &SoundSlots[slot].lpsb, NULL); - if (hr != DS_OK) - { - abort(); - } - - { - void *ptr1, *ptr2; - DWORD len1, len2; - - IDirectSoundBuffer_Lock(SoundSlots[slot].lpsb, 0, SoundSlots[slot].length, - &ptr1, &len1, &ptr2, &len2, 0); - memcpy(ptr1, SoundSlots[slot].samples, MIN(len1, (int)SoundSlots[slot].length)); - IDirectSoundBuffer_Unlock(SoundSlots[slot].lpsb, ptr1, len1, ptr2, len2); - } - IDirectSoundBuffer_SetPan(SoundSlots[slot].lpsb, ((int)(f2fl(SoundSlots[slot].pan) * 20000)) - 10000); - IDirectSoundBuffer_SetVolume(SoundSlots[slot].lpsb, D1vol2DSvol(SoundSlots[slot].volume)); - IDirectSoundBuffer_Play(SoundSlots[slot].lpsb, 0, 0, SoundSlots[slot].looped ? DSBPLAY_LOOPING : 0); - - SoundObjects[obj].signature = next_signature++; - SoundObjects[obj].handle = slot; - - SoundObjects[obj].flags |= SOF_PLAYING; - // added on 980905 by adb to add sound kill system from original sos digi.c - reset_sounds_on_channel(slot); - // end edit by adb - - return 0; -} - - -// Play the given sound number. -// Volume is max at F1_0. -void digi_play_sample( int soundno, fix max_volume ) -{ -#ifdef NEWDEMO - if (Newdemo_state == ND_STATE_RECORDING) - newdemo_record_sound(soundno); -#endif - if (!digi_initialised) - return; - if (digi_xlat_sound(soundno) < 0) - return; - - if (soundno < 0 ) return; - - digi_start_sound(soundno, max_volume, F0_5); -} - -// Play the given sound number. If the sound is already playing, -// restart it. -void digi_play_sample_once( int soundno, fix max_volume ) -{ - int i; - -#ifdef NEWDEMO - if (Newdemo_state == ND_STATE_RECORDING) - newdemo_record_sound(soundno); -#endif - if (!digi_initialised) - return; - if(digi_xlat_sound(soundno) < 0) - return; - - for (i = 0; i < MAX_SOUND_SLOTS; i++) - if (SoundSlots[i].soundno == soundno) - { - DS_release_slot(i, 1); - } - - digi_start_sound(soundno, max_volume, F0_5); -} - -void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) // Volume from 0-0x7fff -{ - no_dups = 1; - -#ifdef NEWDEMO - if (Newdemo_state == ND_STATE_RECORDING) - { - if (no_dups) - newdemo_record_sound_3d_once(soundno, angle, volume); - else - newdemo_record_sound_3d(soundno, angle, volume); - } -#endif - if (!digi_initialised) - return; - if (digi_xlat_sound(soundno) < 0) - return; - if (volume < MIN_VOLUME) - return; - - digi_start_sound(soundno, volume, angle); -} - -void digi_get_sound_loc( vms_matrix * listener, vms_vector * listener_pos, int listener_seg, vms_vector * sound_pos, int sound_seg, fix max_volume, int *volume, int *pan, fix max_distance ) -{ - vms_vector vector_to_sound; - fix angle_from_ear, cosang,sinang; - fix distance; - fix path_distance; - - *volume = 0; - *pan = 0; - - max_distance = (max_distance * 5) / 4; // Make all sounds travel 1.25 times as far. - - // Warning: Made the vm_vec_normalized_dir be vm_vec_normalized_dir_quick and got illegal values to acos in the fang computation. - distance = vm_vec_normalized_dir_quick( &vector_to_sound, sound_pos, listener_pos ); - - if (distance < max_distance ) { - int num_search_segs = f2i(max_distance/20); - if ( num_search_segs < 1 ) num_search_segs = 1; - - path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG ); - if ( path_distance > -1 ) { - *volume = max_volume - fixdiv(path_distance,max_distance); - //mprintf( (0, "Sound path distance %.2f, volume is %d / %d\n", f2fl(distance), *volume, max_volume )); - if (*volume > 0 ) { - angle_from_ear = vm_vec_delta_ang_norm(&listener->rvec,&vector_to_sound,&listener->uvec); - fix_sincos(angle_from_ear,&sinang,&cosang); - //mprintf( (0, "volume is %.2f\n", f2fl(*volume) )); - if (Config_channels_reversed) cosang *= -1; - *pan = (cosang + F1_0)/2; - } else { - *volume = 0; - } - } - } -} - -int digi_link_sound_to_object2(int soundnum, short objnum, int forever, fix max_volume, fix max_distance) -{ - int i, volume, pan; - object *objp; - - if (max_volume < 0) - return -1; - if (!digi_initialised) - return -1; - if (digi_xlat_sound(soundnum) < 0) - return -1; - if (Sounddat(soundnum)->data == NULL) + if (GameSounds[soundno].data == NULL) { Int3(); return -1; } - if ((objnum < 0) || (objnum > Highest_object_index)) - return -1; - - if (!forever) - { - // Hack to keep sounds from building up... - digi_get_sound_loc(&Viewer->orient, &Viewer->pos, Viewer->segnum, &Objects[objnum].pos, Objects[objnum].segnum, max_volume, &volume, &pan, max_distance); - digi_play_sample_3d(soundnum, pan, volume, 0); - return -1; - } - - for (i = 0; i < MAX_SOUND_OBJECTS; i++) - if (SoundObjects[i].flags == 0) - break; - if (i == MAX_SOUND_OBJECTS) - { - mprintf((1, "Too many sound objects!\n")); - return -1; - } - - SoundObjects[i].signature = next_signature++; - SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_OBJ; - if (forever) - SoundObjects[i].flags |= SOF_PLAY_FOREVER; - SoundObjects[i].lo_objnum = objnum; - SoundObjects[i].lo_objsignature = Objects[objnum].signature; - SoundObjects[i].max_volume = max_volume; - SoundObjects[i].max_distance = max_distance; - SoundObjects[i].volume = 0; - SoundObjects[i].pan = 0; - SoundObjects[i].soundnum = soundnum; - objp = &Objects[SoundObjects[i].lo_objnum]; - digi_get_sound_loc(&Viewer->orient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; -} - -int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume ) -{ - return digi_link_sound_to_object2(soundnum, objnum, forever, max_volume, 256 * F1_0); + //FIXME: not implemented + return -1; } -int digi_link_sound_to_pos2(int soundnum, short segnum, short sidenum, vms_vector *pos, int forever, fix max_volume, fix max_distance) -{ - int i, volume, pan; - - if (max_volume < 0 ) - return -1; - if (!digi_initialised) - return -1; - if (digi_xlat_sound(soundnum) < 0) - return -1; - if (Sounddat(soundnum)->data == NULL) - { - Int3(); - return -1; - } - - if (!forever) - { - // Hack to keep sounds from building up... - digi_get_sound_loc(&Viewer->orient, &Viewer->pos, Viewer->segnum, pos, segnum, max_volume, &volume, &pan, max_distance); - digi_play_sample_3d(org_soundnum, pan, volume, 0); - return -1; - } - - for (i = 0; i < MAX_SOUND_OBJECTS; i++) - if (SoundObjects[i].flags == 0) - break; - - if (i == MAX_SOUND_OBJECTS) - { - mprintf((1, "Too many sound objects!\n")); - return -1; - } - - - SoundObjects[i].signature = next_signature++; - SoundObjects[i].flags = SOF_USED | SOF_LINK_TO_POS; - if (forever) - SoundObjects[i].flags |= SOF_PLAY_FOREVER; - SoundObjects[i].lp_segnum = segnum; - SoundObjects[i].lp_sidenum = sidenum; - SoundObjects[i].lp_position = *pos; - SoundObjects[i].soundnum = soundnum; - SoundObjects[i].max_volume = max_volume; - SoundObjects[i].max_distance = max_distance; - SoundObjects[i].volume = 0; - SoundObjects[i].pan = 0; - digi_get_sound_loc(&Viewer->orient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance); - - if (!forever || SoundObjects[i].volume >= MIN_VOLUME) - digi_start_sound_object(i); - - return SoundObjects[i].signature; -} - -int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume ) -{ - return digi_link_sound_to_pos2(soundnum, segnum, sidenum, pos, forever, max_volume, F1_0 * 256); -} - -void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum ) -{ - int i, killed; - - if (!digi_initialised) - return; - - killed = 0; - - for (i = 0; i < MAX_SOUND_OBJECTS; i++) - if ((SoundObjects[i].flags & SOF_USED) && - (SoundObjects[i].flags & SOF_LINK_TO_POS) && - (SoundObjects[i].lp_segnum == segnum) && - (SoundObjects[i].soundnum == soundnum) && - (SoundObjects[i].lp_sidenum==sidenum)) - { - if (SoundObjects[i].flags & SOF_PLAYING) - { - DS_release_slot(SoundObjects[i].handle, 1); - } - SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound - killed++; - } - - // If this assert happens, it means that there were 2 sounds - // that got deleted. Weird, get John. - if (killed > 1) - { - mprintf((1, "ERROR: More than 1 sounds were deleted from seg %d\n", segnum)); - } -} - -void digi_kill_sound_linked_to_object( int objnum ) -{ - int i, killed; - - if (!digi_initialised) return; - - killed = 0; - - for (i=0; i 1 ) { - mprintf( (1, "ERROR: More than 1 sounds were deleted from object %d\n", objnum )); - } -} - -void digi_sync_sounds() -{ - int i; - int oldvolume, oldpan; - - if (!digi_initialised) return; - - for (i=0; iorient, &Viewer->pos, Viewer->segnum, - &SoundObjects[i].lp_position, SoundObjects[i].lp_segnum, - SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - - } else if ( SoundObjects[i].flags & SOF_LINK_TO_OBJ ) { - object * objp; - - objp = &Objects[SoundObjects[i].lo_objnum]; - - if ((objp->type==OBJ_NONE) || (objp->signature!=SoundObjects[i].lo_objsignature)) { - // The object that this is linked to is dead, so just end this sound if it is looping. - if ( (SoundObjects[i].flags & SOF_PLAYING) && (SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - DS_release_slot(SoundObjects[i].handle, 1); - } - SoundObjects[i].flags = 0; // Mark as dead, so some other sound can use this sound - continue; // Go on to next sound... - } else { - digi_get_sound_loc( &Viewer->orient, &Viewer->pos, Viewer->segnum, - &objp->pos, objp->segnum, SoundObjects[i].max_volume, - &SoundObjects[i].volume, &SoundObjects[i].pan, SoundObjects[i].max_distance ); - } - } - - if (oldvolume != SoundObjects[i].volume) { - if ( SoundObjects[i].volume < MIN_VOLUME ) { - // Sound is too far away, so stop it from playing. - if ((SoundObjects[i].flags & SOF_PLAYING)&&(SoundObjects[i].flags & SOF_PLAY_FOREVER)) { - DS_release_slot(SoundObjects[i].handle, 1); - SoundObjects[i].flags &= ~SOF_PLAYING; // Mark sound as not playing - } - } else { - if (!(SoundObjects[i].flags & SOF_PLAYING)) { - digi_start_sound_object(i); - } else { - SoundSlots[SoundObjects[i].handle].volume = fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0); - IDirectSoundBuffer_SetVolume(SoundSlots[SoundObjects[i].handle].lpsb, D1vol2DSvol(SoundSlots[SoundObjects[i].handle].volume)); - } - } - } - - if (oldpan != SoundObjects[i].pan) { - if (SoundObjects[i].flags & SOF_PLAYING) - { - SoundSlots[SoundObjects[i].handle].pan = SoundObjects[i].pan; - IDirectSoundBuffer_SetPan(SoundSlots[SoundObjects[i].handle].lpsb, ((int)(f2fl(SoundObjects[i].pan) * 20000.0)) - 10000); - } - } - } - } -} - -void digi_init_sounds() + //added on 980905 by adb to add sound kill system from original sos digi.c +void reset_sounds_on_channel( int channel ) { - int i; - - if (!digi_initialised) return; - - digi_reset_digi_sounds(); + int i; - for (i=0; i (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS) ) - digi_max_channels = (MAX_SOUND_SLOTS-MAX_SOUND_OBJECTS); + if (digi_max_channels > MAX_SOUND_SLOTS) + digi_max_channels = MAX_SOUND_SLOTS; if ( !digi_initialised ) return; @@ -842,8 +377,57 @@ void digi_reset_digi_sounds() { next_handle = 0; //end edit by adb } + +int digi_is_channel_playing(int channel) +{ + if (!digi_initialised) + return 0; + + return SoundSlots[channel].playing; +} + +void digi_set_channel_volume(int channel, int volume) +{ + if (!digi_initialised) + return; + + if (!SoundSlots[channel].playing) + return; + + SoundSlots[channel].volume = fixmuldiv(volume, digi_volume, F1_0); +} + +void digi_set_channel_pan(int channel, int pan) +{ + if (!digi_initialised) + return; + + if (!SoundSlots[channel].playing) + return; + + SoundSlots[channel].pan = pan; +} + +void digi_stop_sound(int channel) +{ + SoundSlots[channel].playing=0; + SoundSlots[channel].soundobj = -1; + SoundSlots[channel].persistent = 0; +} + +void digi_end_sound(int channel) +{ + if (!digi_initialised) + return; + + if (!SoundSlots[channel].playing) + return; + + SoundSlots[channel].soundobj = -1; + SoundSlots[channel].persistent = 0; +} + #else -int digi_lomem = 0; int digi_midi_song_playing = 0; static int digi_initialised = 0; int midi_volume = 255; @@ -853,30 +437,11 @@ int digi_init() { digi_initialised = 1; return 0; } void digi_reset() {} void digi_close() {} -void digi_play_sample( int sndnum, fix max_volume ) {} -void digi_play_sample_once( int sndnum, fix max_volume ) {} -int digi_link_sound_to_object( int soundnum, short objnum, int forever, fix max_volume ) { return 0; } -int digi_link_sound_to_pos( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume ) { return 0; } -// Same as above, but you pass the max distance sound can be heard. The old way uses f1_0*256 for max_distance. -int digi_link_sound_to_object2( int soundnum, short objnum, int forever, fix max_volume, fix max_distance ) { return 0; } -int digi_link_sound_to_pos2( int soundnum, short segnum, short sidenum, vms_vector * pos, int forever, fix max_volume, fix max_distance ) { return 0; } - -void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups ) {} // Volume from 0-0x7fff - -void digi_init_sounds() {} -void digi_sync_sounds() {} -void digi_kill_sound_linked_to_segment( int segnum, int sidenum, int soundnum ) {} -void digi_kill_sound_linked_to_object( int objnum ) {} - void digi_set_digi_volume( int dvolume ) {} void digi_set_volume( int dvolume, int mvolume ) {} int digi_is_sound_playing(int soundno) { return 0; } -void digi_pause_all() {} -void digi_resume_all() {} -void digi_stop_all() {} - void digi_set_max_channels(int n) {} int digi_get_max_channels() { return 0; } @@ -932,8 +497,33 @@ void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank else printf("hmp_open failed\n"); } +void digi_pause_midi() {} +void digi_resume_midi() {} + #else void digi_stop_current_song() {} void digi_set_midi_volume( int n ) {} void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop ) {} +void digi_pause_midi() {} +void digi_resume_midi() {} +#endif + +#ifndef NDEBUG +void digi_debug() +{ + int i; + int n_voices = 0; + + if (!digi_initialised) + return; + + for (i = 0; i < digi_max_channels; i++) + { + if (digi_is_channel_playing(i)) + n_voices++; + } + + mprintf_at((0, 2, 0, "DIGI: Active Sound Channels: %d/%d (HMI says %d/32) ", n_voices, digi_max_channels, -1)); + //mprintf_at((0, 3, 0, "DIGI: Number locked sounds: %d ", digi_total_locks )); +} #endif -- 2.39.2