rip out digiobj stuff, use d2src system for persistent sounds. Untested, of course.
authorBradley Bell <btb@icculus.org>
Fri, 25 Feb 2005 10:49:48 +0000 (10:49 +0000)
committerBradley Bell <btb@icculus.org>
Fri, 25 Feb 2005 10:49:48 +0000 (10:49 +0000)
ChangeLog
arch/dos/digi.c
arch/dos/digiallg.c
arch/dos/digimm.c
arch/linux/alsadigi.c
arch/win32/digi.c

index 2b6bd0a..f2091cc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-02-25  Bradley Bell  <btb@icculus.org>
+
+       * 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  <tmassey@obscorp.com>
 
        * main/inferno.c: allow -notitles to work in shareware [and
index de558b2..4a35044 100644 (file)
@@ -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<MAX_SOUND_SLOTS; i++)
- {
-  if (!SoundSlots[i].playing) return i;
- }
- return -1;
-}
-
-int digi_start_sound(int soundnum, fix volume, fix pan, int unknown1, int unknown2, int unknown3, int unknown4)
-{
- int ntries;
- int slot;
-
- if (!digi_initialised) return -1;
-
- //added on 980905 by adb from original source to add sound kill system
- // play at most digi_max_channel samples, if possible kill sample with low volume
- ntries = 0;
-
-TryNextChannel:
- if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing)  )
- {
-  if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
-  {
-   //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
-   next_handle++;
-   if ( next_handle >= 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<digi_max_channels; i++)
-  if (SampleHandles[i] == channel)
-   SampleHandles[i] = -1;
-}
-//end edit by adb
-
-int digi_start_sound_object(int obj)
-{
- int slot;
-
- if (!digi_initialised) return -1;
- slot = get_free_slot();
-
- if (slot<0) return -1;
-
-
- SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
- SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
- SoundSlots[slot].length = GameSounds[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;
-
- SoundObjects[obj].signature = next_signature++;
- SoundObjects[obj].handle = slot;
+       int i;
 
- 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;
+       for (i = 0; i < MAX_SOUND_SLOTS; i++)
+               digi_stop_sound(i);
 }
 
 
-// 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
-       soundno = digi_xlat_sound(soundno);
-
-       if (!digi_initialised) return;
-
-       if (soundno < 0 ) return;
-
-       digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
-}
+extern void digi_end_soundobj(int channel);    
+extern int SoundQ_channel;
+extern void SoundQ_end();
+int verify_sound_channel_free(int channel);
 
-// Play the given sound number. If the sound is already playing,
-// restart it.
-void digi_play_sample_once( int soundno, fix max_volume )
+// 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 i;
-
-#ifdef NEWDEMO
-       if ( Newdemo_state == ND_STATE_RECORDING )
-               newdemo_record_sound( soundno );
-#endif
-       soundno = digi_xlat_sound(soundno);
-
-       if (!digi_initialised) return;
+       int i, starting_channel;
 
-       if (soundno < 0 ) return;
+       if (!digi_initialised) return -1;
 
-        for (i=0; i < MAX_SOUND_SLOTS; i++)
-          if (SoundSlots[i].soundno == soundno)
-            SoundSlots[i].playing = 0;
-       digi_start_sound(soundno, max_volume, F0_5, 0, 0, 0, 0);
+       if (soundnum < 0) return -1;
 
-}
+       Assert(GameSounds[soundnum].data != (void *)-1);
 
-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
-       soundno = digi_xlat_sound(soundno);
+       starting_channel = next_channel;
 
-       if (!digi_initialised) return;
-       if (soundno < 0 ) return;
+       while(1)
+       {
+               if (!SoundSlots[next_channel].playing)
+                       break;
 
-       if (volume < MIN_VOLUME ) return;
-       digi_start_sound(soundno, volume, angle, 0, 0, 0, 0);
-}
+               if (!SoundSlots[next_channel].persistent)
+                       break;  // use this channel!    
 
-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;
-                       }
+               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; 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;
-       }
+#ifndef NDEBUG
+       verify_sound_channel_free(next_channel);
+#endif
 
-       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;
+       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; i<MAX_SOUND_OBJECTS; i++ )
-               if (SoundObjects[i].flags==0)
-                       break;
-       
-       if (i==MAX_SOUND_OBJECTS) {
-               mprintf((1, "Too many sound objects!\n" ));
+       if (GameSounds[soundno].data == NULL)
+       {
+               Int3();
                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;
-
-       soundnum = digi_xlat_sound(soundnum);
-
-       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) )  {
-                       if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
-                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                       SoundSlots[SoundObjects[i].handle].playing = 0;
-                               }
-                               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<MAX_SOUND_OBJECTS; i++ )    {
-               if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
-                       if (SoundObjects[i].lo_objnum == objnum)   {
-                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                     SoundSlots[SoundObjects[i].handle].playing = 0;
-                               }
-                               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 object %d\n", objnum ));
-       }
-}
-
-void digi_sync_sounds()
-{
-       int i;
-       int oldvolume, oldpan;
-
-       if (!digi_initialised) return;
-
-       for (i=0; i<MAX_SOUND_OBJECTS; i++ )    {
-               if ( SoundObjects[i].flags & SOF_USED ) {
-                       oldvolume = SoundObjects[i].volume;
-                       oldpan = SoundObjects[i].pan;
-
-                       if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) )      {
-                               // Check if its done.
-                               if (SoundObjects[i].flags & SOF_PLAYING) {
-                                       if (!SoundSlots[SoundObjects[i].handle].playing) {
-                                               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-                                               continue;               // Go on to next sound...
-                                       }
-                               }
-                       }                       
-               
-                       if ( SoundObjects[i].flags & SOF_LINK_TO_POS )  {
-                               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 );
-
-                       } 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_OBJECTS; i++ )    {
-               if (digi_sounds_initialized) {
-                       if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                               SoundSlots[SoundObjects[i].handle].playing=0;
-                       }
-               }
-               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-       }
-       digi_sounds_initialized = 1;
-}
 
 //added on 980905 by adb from original source to make sfx volume work
 void digi_set_digi_volume( int dvolume )
@@ -780,22 +357,18 @@ int digi_is_sound_playing(int soundno)
 }
 
 
-void digi_pause_all() { }
-void digi_resume_all() { }
-void digi_stop_all() { }
-
  //added on 980905 by adb to make sound channel setting work
 void digi_set_max_channels(int n) { 
        digi_max_channels       = n;
 
        if ( digi_max_channels < 1 ) 
                digi_max_channels = 1;
-       if ( digi_max_channels > (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
index b0e8efe..7edd5b1 100644 (file)
@@ -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<DIGI_SLOTS; i++) {
-               if (SampleHandles[i] == channel) {
-                       SampleHandles[i] = INVALID_CHANNEL;
-                       if (SoundNums[i] != -1)   {
-                               digi_unlock_sound_data(SoundNums[i]);
-                               SoundNums[i] = -1;
-                       }
-               }
-       }
-}
-
 void digi_set_max_channels(int n) {
        digi_max_channels       = n;
 
@@ -315,6 +244,14 @@ int digi_get_max_channels()
        return digi_max_channels;
 }
 
+void digi_stop_all_channels()
+{
+       int i;
+
+       for (i = 0; i < MAX_SOUND_SLOTS; i++)
+               digi_stop_sound(i);
+}
+
 int get_free_slot() {
        int ntries = 0;
        int ret_slot;
@@ -393,75 +330,36 @@ CHANNEL digi_start_sound(int soundnum, int volume, int pan) {
        return channel;
 }
 
-int digi_is_sound_playing(int soundno)
+// Returns the channel a sound number is playing on, or
+// -1 if none.
+int digi_find_channel(int soundno)
 {
-       int i;
+       if (!digi_initialised)
+               return -1;
 
-       soundno = digi_xlat_sound(soundno);
+       if (soundno < 0 )
+               return -1;
 
-       for (i = 0; i < DIGI_VOICES; i++)
-                 if (voice_check(i) == &GameSounds[soundno])
-                       return 1;
-       return 0;
+       if (GameSounds[soundno].data == NULL)
+       {
+               Int3();
+               return -1;
+       }
+
+       //FIXME: not implemented
+       return -1;
 }
 
-void digi_play_sample_once( int soundno, fix max_volume ) {
+int digi_is_sound_playing(int soundno)
+{
        int i;
 
-#ifdef NEWDEMO
-       if ( Newdemo_state == ND_STATE_RECORDING )
-               newdemo_record_sound( soundno );
-#endif
        soundno = digi_xlat_sound(soundno);
 
-       if (!Digi_initialized) return;
-       if (digi_driver_board<1) return;
-
-       if (soundno < 0 ) return;
-
        for (i = 0; i < DIGI_VOICES; i++)
-           if (voice_check(i) == &GameSounds[soundno])
-                       deallocate_voice(i);
-
-       digi_start_sound(soundno, max_volume, F0_5);
-}
-
-void digi_play_sample( int soundno, fix max_volume ) {
-#ifdef NEWDEMO
-       if ( Newdemo_state == ND_STATE_RECORDING )
-               newdemo_record_sound( soundno );
-#endif
-       soundno = digi_xlat_sound(soundno);
-
-       if (!Digi_initialized) return;
-       if (digi_driver_board<1) return;
-
-       if (soundno < 0 ) return;
-
-       digi_start_sound(soundno, max_volume, F0_5);
-}
-
-void digi_play_sample_3d( int soundno, int angle, int volume, int no_dups )
-{
-       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
-       soundno = digi_xlat_sound(soundno);
-
-       if (!Digi_initialized) return;
-       if (digi_driver_board<1) return;
-       if (soundno < 0 ) return;
-
-       if (volume < MIN_VOLUME ) return;
-
-       digi_start_sound(soundno, volume, angle);
+                 if (voice_check(i) == &GameSounds[soundno])
+                       return 1;
+       return 0;
 }
 
 //-killed- void digi_set_midi_volume( int mvolume )
@@ -508,6 +406,46 @@ void digi_set_volume( int dvolume, int mvolume )
 //     mprintf(( 1, "Volume: 0x%x and 0x%x\n", digi_volume, midi_volume ));
 }
 
+int digi_is_channel_playing(int channel)
+{
+       int i;
+
+       if (!digi_initialised)
+               return 0;
+
+       //FIXME: not implemented
+       return 0;
+}
+
+void digi_set_channel_volume(int channel, int volume)
+{
+       if (!digi_initialised)
+               return;
+
+       //FIXME: not implemented
+}
+
+void digi_set_channel_pan(int channel, int pan)
+{
+       if (!digi_initialised)
+               return;
+
+       //FIXME: not implemented
+}
+
+void digi_stop_sound(int channel)
+{
+       //FIXME: not implemented
+}
+
+void digi_end_sound(int channel)
+{
+       if (!digi_initialised)
+               return;
+
+       //FIXME: not implemented
+}
+
 //-killed- void digi_stop_current_song()
 //-killed- {
 //-killed-         if (SongHandle) {
@@ -559,418 +497,26 @@ void digi_set_volume( int dvolume, int mvolume )
 //-killed-         }
 //-killed- }
 
-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;
-                       }
-               }
-       }                                                                                                                                                                         
-}
-
-void digi_init_sounds()
-{
-       int i;
-
-       if (!Digi_initialized) return;
-       if (digi_driver_board<1) return;
-
-       digi_reset_digi_sounds();
-
-       for (i=0; i<MAX_SOUND_OBJECTS; i++ )    {
-               if (digi_sounds_initialized) {
-                       if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                               deallocate_voice(SoundObjects[i].handle);
-                       }
-               }
-               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-       }
-       digi_sounds_initialized = 1;
-}
-
-void digi_start_sound_object(int i)
-{
-       if (!Digi_initialized) return;
-       if (digi_driver_board<1) return;
-
-       // this doesn't use digi_lock_sound because these sounds are
-       // never unlocked, so we couldn't check if we unlocked all other sounds then
-       if (!dpmi_lock_region( GameSounds[SoundObjects[i].soundnum].data, GameSounds[SoundObjects[i].soundnum].len ))
-               Error( "Error locking sound object %d\n", SoundObjects[i].soundnum );
-       
-       SoundObjects[i].signature=next_signature++;
-
-       SoundObjects[i].handle = play_sample(&GameSounds[SoundObjects[i].soundnum],
-        fixmuldiv(SoundObjects[i].volume,digi_volume,F1_0), /* 0-255 */
-        SoundObjects[i].pan >> 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; 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 )
-{                                                                                                                                                                                                      // 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; 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;
-
-       soundnum = digi_xlat_sound(soundnum);
-
-       if (!Digi_initialized) return;
-       if (digi_driver_board<1) return;
-
-       killed = 0;
-
-       for (i=0; i<MAX_SOUND_OBJECTS; i++ )    {
-               if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) )  {
-                       if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
-                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                       deallocate_voice(SoundObjects[i].handle);
-                               }
-                               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_initialized) return;
-       if (digi_driver_board<1) return;
-
-       killed = 0;
-
-       for (i=0; i<MAX_SOUND_OBJECTS; i++ )    {
-               if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
-                       if (SoundObjects[i].lo_objnum == objnum)   {
-                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                       deallocate_voice(SoundObjects[i].handle );
-                               }
-                               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 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; i<MAX_SOUND_OBJECTS; i++ )    {
-               if ( SoundObjects[i].flags & SOF_USED ) {
-                       oldvolume = SoundObjects[i].volume;
-                       oldpan = SoundObjects[i].pan;
-
-                       if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) )      {
-                               // Check if its done.
-                               if (SoundObjects[i].flags & SOF_PLAYING) {
-                                       if (voice_get_position(SoundObjects[i].handle) < 0) {
-                                               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-                                               continue;               // Go on to next sound...
-                                       }
-                               }
-                       }                       
-               
-                       if ( SoundObjects[i].flags & SOF_LINK_TO_POS )  {
-                               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 );
-
-                       } 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<MAX_SOUND_OBJECTS; i++ )    {
-                               if ( (SoundObjects[i].flags & SOF_USED) && (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
-                               }                       
-                       }
-               }
-       }
-       sound_paused++;
-}
-
-void digi_resume_all()
-{
-       if (!Digi_initialized) return;
-
-       Assert( sound_paused > 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<MAX_SOUND_OBJECTS; i++ )    {
-                       if ( SoundObjects[i].flags & SOF_USED ) {
-                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                       deallocate_voice(SoundObjects[i].handle );
-                               }
-                               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-                       }
-               }
-       }
+       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 ));
 }
 
-#ifndef NDEBUG
 int verify_channel_not_used_by_soundobjects( int channel )
 {
        int i;
index 9416e3c..ca57973 100644 (file)
@@ -121,51 +121,12 @@ 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
 #define SOUND_MAX_VOLUME (F1_0/2) // don't use real max like in original
 int digi_volume = SOUND_MAX_VOLUME;
 //end edit by adb
 
-int digi_lomem = 0;
-
 static int digi_initialised = 0;
 static int timer_system_initialized = 0;
 
@@ -180,19 +141,15 @@ 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 SDL_AudioSpec WaveSpec;
-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
@@ -283,10 +240,6 @@ void mm_timer() {
 /* Initialise audio devices. */
 int digi_init()
 {
- //added on 980905 by adb to init sound kill system
- memset(SampleHandles, 255, sizeof(SampleHandles));
- //end edit by adb
-
  #if 0
  WaveSpec.freq = digi_sample_rate; //11025;
  WaveSpec.format = AUDIO_U8 | AUDIO_STEREO;
@@ -348,506 +301,106 @@ void digi_close()
  #endif
 }
 
-/* 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()
-{
- int i;
- for (i=0; i<MAX_SOUND_SLOTS; i++)
- {
-  if (!SoundSlots[i].playing) return i;
- }
- return -1;
-}
-
-int digi_start_sound(int soundnum, fix volume, fix pan)
+void digi_stop_all_channels()
 {
- int ntries;
- int slot;
-
- if (!digi_initialised) return -1;
-
- //added on 980905 by adb from original source to add sound kill system
- // play at most digi_max_channel samples, if possible kill sample with low volume
- ntries = 0;
-
-TryNextChannel:
- if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing)  )
- {
-  if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
-  {
-   //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
-   next_handle++;
-   if ( next_handle >= 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<digi_max_channels; i++)
-  if (SampleHandles[i] == channel)
-   SampleHandles[i] = -1;
-}
-//end edit by adb
-
-int digi_start_sound_object(int obj)
-{
- int slot;
-
- if (!digi_initialised) return -1;
- slot = get_free_slot();
-
- if (slot<0) return -1;
-
-
- SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
- SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
- SoundSlots[slot].length = GameSounds[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;
-
- SoundObjects[obj].signature = next_signature++;
- SoundObjects[obj].handle = slot;
+       int i;
 
- 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;
+       for (i = 0; i < MAX_SOUND_SLOTS; i++)
+               digi_stop_sound(i);
 }
 
 
-// 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
-       soundno = digi_xlat_sound(soundno);
-
-       if (!digi_initialised) return;
+extern void digi_end_soundobj(int channel);    
+extern int SoundQ_channel;
+extern void SoundQ_end();
+int verify_sound_channel_free(int channel);
 
-       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 )
+// 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 i;
+       int i, starting_channel;
 
-#ifdef NEWDEMO
-       if ( Newdemo_state == ND_STATE_RECORDING )
-               newdemo_record_sound( soundno );
-#endif
-       soundno = digi_xlat_sound(soundno);
-
-       if (!digi_initialised) return;
+       if (!digi_initialised) return -1;
 
-       if (soundno < 0 ) return;
+       if (soundnum < 0) return -1;
 
-        for (i=0; i < MAX_SOUND_SLOTS; i++)
-          if (SoundSlots[i].soundno == soundno)
-            SoundSlots[i].playing = 0;
-       digi_start_sound(soundno, max_volume, F0_5);
+       Assert(GameSounds[soundnum].data != (void *)-1);
 
-}
+       starting_channel = next_channel;
 
-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
-       soundno = digi_xlat_sound(soundno);
-
-       if (!digi_initialised) return;
-       if (soundno < 0 ) return;
+       while(1)
+       {
+               if (!SoundSlots[next_channel].playing)
+                       break;
 
-       if (volume < MIN_VOLUME ) return;
-       digi_start_sound(soundno, volume, angle);
-}
+               if (!SoundSlots[next_channel].persistent)
+                       break;  // use this channel!    
 
-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;
-                       }
+               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; 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;
-       }
+#ifndef NDEBUG
+       verify_sound_channel_free(next_channel);
+#endif
 
-       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;
+       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; i<MAX_SOUND_OBJECTS; i++ )
-               if (SoundObjects[i].flags==0)
-                       break;
-       
-       if (i==MAX_SOUND_OBJECTS) {
-               mprintf((1, "Too many sound objects!\n" ));
+       if (GameSounds[soundno].data == NULL)
+       {
+               Int3();
                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;
-
-       soundnum = digi_xlat_sound(soundnum);
-
-       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) )  {
-                       if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
-                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                       SoundSlots[SoundObjects[i].handle].playing = 0;
-                               }
-                               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<MAX_SOUND_OBJECTS; i++ )    {
-               if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
-                       if (SoundObjects[i].lo_objnum == objnum)   {
-                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                     SoundSlots[SoundObjects[i].handle].playing = 0;
-                               }
-                               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 object %d\n", objnum ));
-       }
-}
-
-void digi_sync_sounds()
-{
-       int i;
-       int oldvolume, oldpan;
-
-       if (!digi_initialised) return;
-
-       for (i=0; i<MAX_SOUND_OBJECTS; i++ )    {
-               if ( SoundObjects[i].flags & SOF_USED ) {
-                       oldvolume = SoundObjects[i].volume;
-                       oldpan = SoundObjects[i].pan;
-
-                       if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) )      {
-                               // Check if its done.
-                               if (SoundObjects[i].flags & SOF_PLAYING) {
-                                       if (!SoundSlots[SoundObjects[i].handle].playing) {
-                                               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-                                               continue;               // Go on to next sound...
-                                       }
-                               }
-                       }                       
-               
-                       if ( SoundObjects[i].flags & SOF_LINK_TO_POS )  {
-                               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 );
-
-                       } 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_OBJECTS; i++ )    {
-                if (digi_sounds_initialized) {
-                        if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                SoundSlots[SoundObjects[i].handle].playing=0;
-                        }
-                }
-                SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-        }
+       //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_OBJECTS; i++ )    {
-//                if (digi_sounds_initialized) {
-//                        if ( SoundObjects[i].flags & SOF_PLAYING )      {
-//                                SoundSlots[SoundObjects[i].handle].playing=0;
-//                        }
-//                }
-//                SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-//        }
-        digi_stop_soundobjects();
-
-        digi_sounds_initialized = 1;
-}
 
 //added on 980905 by adb from original source to make sfx volume work
 void digi_set_digi_volume( int dvolume )
@@ -866,7 +419,6 @@ void digi_set_digi_volume( int dvolume )
 }
 //end edit by adb
 
-//void digi_set_volume( int dvolume, int mvolume ) {}
 void digi_set_volume( int dvolume, int mvolume )
 {
  digi_set_midi_volume(mvolume);
@@ -889,22 +441,18 @@ int digi_is_sound_playing(int soundno)
 }
 
 
-//void digi_pause_all() { }
-//void digi_resume_all() { }
-//void digi_stop_all() { }
-
  //added on 980905 by adb to make sound channel setting work
 void digi_set_max_channels(int n) { 
        digi_max_channels       = n;
 
        if ( digi_max_channels < 1 ) 
                digi_max_channels = 1;
-       if ( digi_max_channels > (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; }
index 61c9572..bb3c1e3 100644 (file)
@@ -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<MAX_SOUND_SLOTS; i++)
- {
-  if (!SoundSlots[i].playing) return i;
- }
- return -1;
-}
-
-int digi_start_sound(int soundnum, fix volume, fix pan)
-{
- int ntries;
- int slot;
-
- if (!digi_initialised) return -1;
- LOCK();
- //added on 980905 by adb from original source to add sound kill system
- // play at most digi_max_channel samples, if possible kill sample with low volume
- ntries = 0;
-
-TryNextChannel:
- if ( (SampleHandles[next_handle] >= 0) && (SoundSlots[SampleHandles[next_handle]].playing)  )
- {
-  if ( (SoundSlots[SampleHandles[next_handle]].volume > digi_volume) && (ntries<digi_max_channels) )
-  {
-   //mprintf(( 0, "Not stopping loud sound %d.\n", next_handle ));
-   next_handle++;
-   if ( next_handle >= 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<digi_max_channels; i++)
-  if (SampleHandles[i] == channel)
-   SampleHandles[i] = -1;
+       for (i = 0; i < MAX_SOUND_SLOTS; i++)
+               digi_stop_sound(i);
 }
-//end edit by adb
-
-int digi_start_sound_object(int obj)
-{
- int slot;
 
- if (!digi_initialised) return -1;
- LOCK();
- slot = get_free_slot();
 
- if (slot<0) { UNLOCK(); return -1; }
+extern void digi_end_soundobj(int channel);    
+extern int SoundQ_channel;
+extern void SoundQ_end();
+int verify_sound_channel_free(int channel);
 
-
- SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
- SoundSlots[slot].samples = GameSounds[SoundObjects[obj].soundnum].data;
- SoundSlots[slot].length = GameSounds[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;
-
- 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
- UNLOCK();
- return 0;
-}
-
-
-// Play the given sound number.
-// Volume is max at F1_0.
-void digi_play_sample( int soundno, fix max_volume )
+// Volume 0-F1_0
+int digi_start_sound(short soundnum, fix volume, int pan, int looping, int loop_start, int loop_end, int soundobj)
 {
-#ifdef NEWDEMO
-       if ( Newdemo_state == ND_STATE_RECORDING )
-               newdemo_record_sound( soundno );
-#endif
-       soundno = digi_xlat_sound(soundno);
+       int i, starting_channel;
 
-       if (!digi_initialised) 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
-       soundno = digi_xlat_sound(soundno);
-
-       if (!digi_initialised) return;
+       if (!digi_initialised) return -1;
 
-       if (soundno < 0 ) return;
+       if (soundnum < 0) return -1;
 
        LOCK();
-        for (i=0; i < MAX_SOUND_SLOTS; i++)
-          if (SoundSlots[i].soundno == soundno)
-            SoundSlots[i].playing = 0;
-       UNLOCK();
-       digi_start_sound(soundno, max_volume, F0_5);
+       Assert(GameSounds[soundnum].data != (void *)-1);
 
-}
+       starting_channel = next_channel;
 
-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
-       soundno = digi_xlat_sound(soundno);
+       while(1)
+       {
+               if (!SoundSlots[next_channel].playing)
+                       break;
 
-       if (!digi_initialised) return;
-       if (soundno < 0 ) return;
+               if (!SoundSlots[next_channel].persistent)
+                       break;  // use this channel!    
 
-       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;
-                       }
+               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<MAX_SOUND_OBJECTS; i++ )
-               if (SoundObjects[i].flags==0)
-                  break;
+#ifndef NDEBUG
+       verify_sound_channel_free(next_channel);
+#endif
 
-       if (i==MAX_SOUND_OBJECTS) {
-               mprintf((1, "Too many sound objects!\n" ));
-               return -1;
-       }
+       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;
+       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; i<MAX_SOUND_OBJECTS; i++ )
-               if (SoundObjects[i].flags==0)
-                       break;
-       
-       if (i==MAX_SOUND_OBJECTS) {
-               mprintf((1, "Too many sound objects!\n" ));
+       if (GameSounds[soundno].data == NULL)
+       {
+               Int3();
                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;
+       //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<MAX_SOUND_OBJECTS; i++ )    {
-               if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_POS) )  {
-                       if ((SoundObjects[i].lp_segnum == segnum) && (SoundObjects[i].soundnum==soundnum ) && (SoundObjects[i].lp_sidenum==sidenum) ) {
-                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                       LOCK();
-                                       SoundSlots[SoundObjects[i].handle].playing = 0;
-                                       UNLOCK();
-                               }
-                               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<MAX_SOUND_OBJECTS; i++ )    {
-               if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
-                       if (SoundObjects[i].lo_objnum == objnum)   {
-                               if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                                    LOCK();
-                                     SoundSlots[SoundObjects[i].handle].playing = 0;
-                                    UNLOCK();
-                               }
-                               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 object %d\n", objnum ));
-       }
-}
-
-void digi_sync_sounds()
-{
-       int i;
-       int oldvolume, oldpan;
-
-       if (!digi_initialised) return;
-
-       for (i=0; i<MAX_SOUND_OBJECTS; i++ )    {
-               if ( SoundObjects[i].flags & SOF_USED ) {
-                       oldvolume = SoundObjects[i].volume;
-                       oldpan = SoundObjects[i].pan;
-
-                       if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) )      {
-                               // Check if its done.
-                               if (SoundObjects[i].flags & SOF_PLAYING) {
-                                       LOCK();
-                                       if (!SoundSlots[SoundObjects[i].handle].playing) {
-                                               UNLOCK();
-                                               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-                                               continue;               // Go on to next sound...
-                                       }
-                                       UNLOCK();
-                               }
-                       }                       
-               
-                       if ( SoundObjects[i].flags & SOF_LINK_TO_POS )  {
-                               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 );
-
-                       } 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_OBJECTS; i++ )    {
-               if (digi_sounds_initialized) {
-                       if ( SoundObjects[i].flags & SOF_PLAYING )      {
-                               LOCK();
-                               SoundSlots[SoundObjects[i].handle].playing=0;
-                               UNLOCK();
-                       }
-               }
-               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-       }
-       digi_sounds_initialized = 1;
-}
 
 //added on 980905 by adb from original source to make sfx volume work
 void digi_set_digi_volume( int dvolume )
@@ -897,7 +449,12 @@ void digi_set_digi_volume( int dvolume )
 }
 //end edit by adb
 
-void digi_set_volume( int dvolume, int mvolume ) { }
+void digi_set_volume(int dvolume, int mvolume)
+{
+       digi_set_digi_volume(dvolume);
+       digi_set_midi_volume(mvolume);
+//     mprintf(( 1, "Volume: 0x%x and 0x%x\n", digi_volume, midi_volume ));
+}
 
 int digi_is_sound_playing(int soundno)
 {
@@ -916,22 +473,18 @@ int digi_is_sound_playing(int soundno)
 }
 
 
-void digi_pause_all() { }
-void digi_resume_all() { }
-void digi_stop_all() { }
-
  //added on 980905 by adb to make sound channel setting work
 void digi_set_max_channels(int n) { 
        digi_max_channels       = n;
 
        if ( digi_max_channels < 1 ) 
                digi_max_channels = 1;
-       if ( digi_max_channels > (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();
 }
 
 
index 4ceb426..5d44935 100644 (file)
@@ -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; i<digi_max_channels; i++)
-  if (SampleHandles[i] == channel)
-   SampleHandles[i] = -1;
-}
-//end edit by adb
-
-int digi_start_sound_object(int obj)
-{
- int slot;
- HRESULT hr;
-
        if (!digi_initialised)
                return -1;
 
-       slot = get_free_slot();
-
-       if (slot < 0)
+       if (soundno < 0 )
                return -1;
 
-
-       SoundSlots[slot].soundno = SoundObjects[obj].soundnum;
-       SoundSlots[slot].samples = Sounddat(SoundObjects[obj].soundnum)->data;
-       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<MAX_SOUND_OBJECTS; i++ )    {
-               if ( (SoundObjects[i].flags & SOF_USED) && (SoundObjects[i].flags & SOF_LINK_TO_OBJ ) ) {
-                       if (SoundObjects[i].lo_objnum == objnum)   {
-                               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 object %d\n", objnum ));
-       }
-}
-
-void digi_sync_sounds()
-{
-       int i;
-       int oldvolume, oldpan;
-
-       if (!digi_initialised) return;
-
-       for (i=0; i<MAX_SOUND_OBJECTS; i++ )    {
-               if ( SoundObjects[i].flags & SOF_USED ) {
-                       oldvolume = SoundObjects[i].volume;
-                       oldpan = SoundObjects[i].pan;
-
-                       if ( !(SoundObjects[i].flags & SOF_PLAY_FOREVER) )      {
-                               // Check if its done.
-                               if (SoundObjects[i].flags & SOF_PLAYING) {
-                                       if (!SoundSlots[SoundObjects[i].handle].playing) {
-                                               SoundObjects[i].flags = 0;      // Mark as dead, so some other sound can use this sound
-                                               continue;               // Go on to next sound...
-                                       }
-                               }
-                       }                       
-               
-                       if ( SoundObjects[i].flags & SOF_LINK_TO_POS )  {
-                               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 );
-
-                       } 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_OBJECTS; i++ )    {
-               if (digi_sounds_initialized) {
-                       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
-       }
-       digi_sounds_initialized = 1;
+ for (i=0; i<digi_max_channels; i++)
+  if (SampleHandles[i] == channel)
+   SampleHandles[i] = -1;
 }
+//end edit by adb
 
 //added on 980905 by adb from original source to make sfx volume work
 void digi_set_digi_volume( int dvolume )
@@ -807,18 +346,14 @@ int digi_is_sound_playing(int soundno)
 }
 
 
-void digi_pause_all() { }
-void digi_resume_all() { }
-void digi_stop_all() { }
-
  //added on 980905 by adb to make sound channel setting work
 void digi_set_max_channels(int n) { 
        digi_max_channels       = n;
 
        if ( digi_max_channels < 1 ) 
                digi_max_channels = 1;
-       if ( digi_max_channels > (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