]> icculus.org git repositories - btb/d2x.git/blob - main/old/windigi.c
This commit was generated by cvs2svn to compensate for changes in r2,
[btb/d2x.git] / main / old / windigi.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14
15 #pragma off (unreferenced)
16 static char rcsid[] = "$Id: windigi.c,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $";
17 #pragma on (unreferenced)
18
19 #include "desw.h"
20 #include "win\ds.h"
21 #include <mmsystem.h>
22 #include <mmreg.h>
23
24 #include<stdlib.h>
25 #include<stdio.h>
26 #include<dos.h>
27 #include<fcntl.h> 
28 #include<malloc.h> 
29 #include<bios.h>
30 #include<io.h>
31 #include<string.h>
32 #include<ctype.h>
33
34 #include "fix.h"
35 #include "object.h"
36 #include "mono.h"
37 #include "timer.h"
38 #include "joy.h"
39 #include "digi.h"
40 #include "sounds.h"
41 #include "args.h"
42 #include "key.h"
43 #include "newdemo.h"
44 #include "game.h"
45 #include "error.h"
46 #include "wall.h"
47 #include "cfile.h"
48 #include "piggy.h"
49 #include "text.h"
50
51 #pragma pack (4);                                               // Use 32-bit packing!
52 #pragma off (check_stack);                      // No stack checking!
53
54 #include "win\winmidi.h"
55 #include "config.h"
56
57 #define MAX_CHANNELS 32
58
59 typedef struct digi_channel {
60         ubyte           used;                           // Non-zero if a sound is playing on this channel 
61         int             soundnum;               // Which sound effect is on this channel, -1 if none
62         WORD            handle;                 // What SS handle this is playing on
63         int             soundobj;               // Which soundobject is on this channel
64         int             persistant;             // This can't be pre-empted
65         int             volume;                 // the volume of this channel
66 } digi_channel;
67
68
69 //      Defines
70 //      ----------------------------------------------------------------------------
71
72 #define DIGI_PAUSE_BROKEN 1             //if this is defined, don't pause MIDI songs
73 #define _DIGI_SAMPLE_FLAGS (0)
74 #define _DIGI_MAX_VOLUME (16384)
75 #define MAX_SOUND_OBJECTS 22
76
77
78
79 //      Variables
80 //      ----------------------------------------------------------------------------
81
82 int     Digi_initialized                                = 0;
83 static int      digi_atexit_called      = 0;                                            // Set to 1 if atexit(digi_close) was called
84
85 int digi_sample_rate                                    = SAMPLE_RATE_22K;      // rate to use driver at
86 int digi_max_channels           = 8;
87
88 int digi_total_locks = 0;
89
90 static int digi_volume                          = _DIGI_MAX_VOLUME;     // Max volume
91 static int digi_system_initialized              = 0;
92 static int digi_sound_locks[MAX_SOUNDS];
93 BOOL DIGIDriverInit = FALSE;
94
95
96 // MIDI stuff
97 //      ----------------------------------------------------------------------------
98 WMIDISONG WMidiSong;
99 int             WMidiHandle=0;
100 ubyte           *SongData=NULL;
101 HGLOBAL hSongData=NULL;
102 int             SongSize;
103
104 char digi_last_midi_song[16] = "";
105
106 static BOOL                                                     MIDIDriverInit  = FALSE;
107
108 static int midi_system_initialized      = 0;
109 static int midi_volume                                  = 128/2;        // Max volume
110
111 extern int Redbook_playing;
112
113
114 /* Obsolete */
115 WORD            hSOSDigiDriver = 0xffff;                                // handle for the SOS driver being used 
116 WORD            hSOSMidiDriver = 0xffff;                        // handle for the loaded MIDI driver
117 WORD            hTimerEventHandle = 0xffff;                     // handle for the timer function
118 int digi_driver_dma                                                                                     = 0;
119 int digi_driver_board                                                                           = 0;
120 int digi_driver_port                                                            = 0;
121 int digi_driver_irq                                                             = 0;
122 int digi_midi_type                                                              = 0;
123 int digi_midi_port                                                                                      = 0;
124 LPSTR digi_driver_path = NULL;
125 /* Not Obsolete */
126
127
128 //      Sound Handle stuff
129 //      ----------------------------------------------------------------------------
130 digi_channel channels[MAX_CHANNELS];
131 int next_channel = 0;
132 int channels_inited = 0;
133
134
135 //      Functions
136 //      ----------------------------------------------------------------------------
137 int verify_sound_channel_free(int channel);
138
139 void * digi_load_file( char * szFileName, HGLOBAL *hmem, int * length );
140
141
142
143 //      FUNCTIONS!!!
144 //              DIGI SYSTEM
145 //                      Initialization
146 //                      Play
147 //                      Sound System
148 //
149 //              MIDI SYSTEM
150 //      ----------------------------------------------------------------------------
151
152 int digi_init(void)
153 {
154         int i;
155
156         Digi_initialized = 1;
157
158 //      Perform MIDI Detection
159
160 // Initialize MIDI driver
161         if (! FindArg( "-nomusic" )) {
162                 midi_system_initialized = 1;
163                 if (digi_init_midi()) {
164                         mprintf((1, "Couldn't initialize MIDI system.\n"));
165                         midi_system_initialized = 0;
166                         return 1;
167                 }
168         }
169
170 // Initialize DIGI driver
171         if (! FindArg( "-nosound" )) {
172                 digi_system_initialized = 1;
173                 if (digi_init_digi()) {
174                         mprintf((1, "Couldn't initialize digital sound system.\n"));
175                         digi_close();
176                         return 2;
177                 }
178         }
179                 
180         if (!digi_atexit_called) {
181                 atexit(digi_close);
182                 digi_atexit_called = 1;
183         }
184
185 //      Miscellaneous Initialization
186         digi_init_sounds();
187
188         for (i = 0; i < MAX_SOUNDS; i++)
189                 digi_sound_locks[i] = 0;
190
191         digi_stop_all_channels();
192
193         return 0; 
194 }
195
196
197 void digi_close(void)
198 {
199
200         if (!Digi_initialized) return;
201         Digi_initialized = 0;
202
203         digi_close_midi();
204         digi_close_digi();
205
206         digi_system_initialized = 0;
207         midi_system_initialized = 0;
208 }
209
210
211 int digi_init_digi(void)
212 {
213         SSCaps sscaps;
214
215         Assert(digi_sample_rate == SAMPLE_RATE_11K || digi_sample_rate == SAMPLE_RATE_22K);
216
217         if (!digi_system_initialized) 
218                 return 1;
219
220 //      Determine board type?
221         digi_driver_board = 1;
222
223 //      Initialize Sound System
224         if (!SSInit(_hAppWnd, 32, DSSCL_NORMAL)) {
225                 DIGIDriverInit = FALSE;
226                 return 1;
227         }
228
229         SSGetCaps(&sscaps);
230         if (sscaps.sample_rate < SAMPLE_RATE_22K) 
231                 digi_sample_rate = SAMPLE_RATE_11K;
232
233 //      logentry("Detected sound card using (%d Hz).  Using (%d Hz) samples.\n", sscaps.sample_rate, digi_sample_rate);
234
235 //      Crank up the WAV volume for Wave-Table and full range of FX volumes
236         DIGIDriverInit = TRUE;
237         return 0;
238 }
239
240
241 void digi_close_digi()
242 {
243    if (DIGIDriverInit)   {
244                 SSDestroy();                                                    // resets WAV vol to SSInit value.
245                 DIGIDriverInit = FALSE;
246         }
247 }
248
249
250 int digi_init_midi(void)
251 {
252         DWORD res;
253
254 //      check to see if MIDI is going to be used.
255         if (!midi_system_initialized) 
256                 return 1;
257
258 //      Initialize MIDI system and driver
259         res = wmidi_init(MIDI_MAPPER);
260
261         if (!res) {
262                 MIDIDriverInit = FALSE;
263                 return 1;
264         }
265         else {
266 //@@            switch(sMIDICaps.wTechnology) 
267 //@@            {
268 //@@                    case MOD_SYNTH:
269 //@@                            mprintf((0, "Using SB/SYNTH for MIDI.\n"));     break;
270 //@@
271 //@@                    case MOD_FMSYNTH:
272 //@@                            mprintf((0, "Using ADLIB FM for MIDI.\n")); break;
273 //@@                    
274 //@@                    case MOD_MAPPER:
275 //@@                            mprintf((0, "Using MIDI mapping.\n")); break;
276 //@@
277 //@@                    case MOD_MIDIPORT:
278 //@@                            mprintf((0, "Using SB/External MIDI port.\n")); break;
279 //@@
280 //@@                    case MOD_SQSYNTH:
281 //@@                            mprintf((0, "Using Wave Synthesis for MIDI.\n")); break;
282 //@@
283 //@@                    default:
284 //@@                            mprintf((0, "Using another method (%d) for MIDI.\n", sMIDICaps.wMID)); break;
285 //@@            }
286
287                 digi_midi_type = 1;
288         
289                 MIDIDriverInit = TRUE;
290         }
291
292         digi_set_midi_volume(Config_midi_volume*16);
293
294         return 0;
295 }               
296
297
298 void digi_close_midi()
299 {
300         if (!midi_system_initialized) return;
301
302         if (MIDIDriverInit)   {
303       if (WMidiHandle)  {
304          // stop the last MIDI song from playing
305                         wmidi_stop();
306                         wmidi_close_song();
307          WMidiHandle = 0;
308       }
309       if (SongData)  {
310                         GlobalUnlock(SongData);
311                         GlobalFree(hSongData);
312          SongData = NULL;
313                         hSongData = NULL;
314       }
315
316                 wmidi_close();
317                 MIDIDriverInit = FALSE;
318    }
319 }
320
321
322 void digi_reset()       
323 {
324         if ( Digi_initialized ) {
325                 digi_stop_all_channels();
326                 digi_close();
327                 mprintf( (0, "Sound system DISABLED.\n" ));
328         } else {
329                 digi_init();
330                 mprintf( (0, "Sound system ENABLED.\n" ));
331         }
332 }
333
334
335 //      Channel Functions
336 //      ----------------------------------------------------------------------------
337
338 void digi_stop_all_channels()
339 {
340         int i;
341
342         for (i=0; i<MAX_CHANNELS; i++ )
343                 digi_stop_sound(i);
344
345         for (i=0; i<MAX_SOUNDS; i++ )   {
346                 Assert( digi_sound_locks[i] == 0 );
347         }
348 }
349
350 void digi_set_max_channels(int n)
351 {
352         digi_max_channels       = n;
353
354         if ( digi_max_channels < 1 ) 
355                 digi_max_channels = 1;
356         if ( digi_max_channels > 32 ) 
357                 digi_max_channels = 32;
358
359         if ( !Digi_initialized ) return;
360         if ( !DIGIDriverInit )  return;
361
362         digi_stop_all_channels();
363 }
364
365 int digi_get_max_channels()
366 {
367         return digi_max_channels;
368 }
369
370 int digi_is_channel_playing( int c )
371 {
372         if (!Digi_initialized) return 0;
373         if (!DIGIDriverInit) return 0;
374
375         if ( channels[c].used && SSChannelPlaying((int)channels[c].handle)) 
376                 return 1;
377         return 0;
378 }
379
380 void digi_set_channel_volume( int c, int volume )
381 {
382         if (!Digi_initialized) return;
383         if (!DIGIDriverInit) return;
384
385         if ( !channels[c].used ) return;
386
387         SSSetChannelVolume(channels[c].handle, (unsigned short)fixmuldiv(volume,digi_volume,F1_0));
388 }
389         
390 void digi_set_channel_pan( int c, int pan )
391 {
392         if (!Digi_initialized) return;
393         if (!DIGIDriverInit) return;
394
395         if ( !channels[c].used ) return;
396
397         SSSetChannelPan(channels[c].handle, (unsigned short)pan);
398 }
399
400 void digi_stop_sound( int c )
401 {
402         if (!Digi_initialized) return;
403         if (!DIGIDriverInit) return;
404
405         if (!channels[c].used) return;
406
407         if ( digi_is_channel_playing(c)  )              {
408                 SSStopChannel(channels[c].handle);
409         }
410         channels[c].used = 0;
411
412         channels[c].soundobj = -1;
413         channels[c].persistant = 0;
414 }
415
416 void digi_end_sound( int c )
417 {
418         if (!Digi_initialized) return;
419         if (!DIGIDriverInit) return;
420
421         if (!channels[c].used) return;
422
423         channels[c].soundobj = -1;
424         channels[c].persistant = 0;
425 }
426
427
428 // Returns the channel a sound number is playing on, or
429 // -1 if none.
430 int digi_find_channel(int soundno)
431 {
432         int i, is_playing;
433
434         if (!Digi_initialized) return -1;
435         if (!DIGIDriverInit) return -1;
436
437         if (soundno < 0 ) return -1;
438         if (GameSounds[soundno].data==NULL) {
439                 Int3();
440                 return -1;
441         }
442
443         is_playing = 0;
444         for (i=0; i<digi_max_channels; i++ )    {
445                 if ( channels[i].used && (channels[i].soundnum==soundno) )
446                         if ( digi_is_channel_playing(i) )
447                                 return i;
448         }       
449         return -1;
450 }
451
452 extern void digi_end_soundobj(int channel);     
453 extern int SoundQ_channel;
454 extern void SoundQ_end();
455
456
457 //      DIGI Start Sample function
458 //      ----------------------------------------------------------------------------
459 int digi_start_sound(short soundnum, fix volume, int pan, int looping, int loop_start, int loop_end, int soundobj)
460 {
461         int i, starting_channel;
462         int sHandle;
463         SSoundBuffer ssb;
464
465         if ( !Digi_initialized ) return -1;
466         if ( !DIGIDriverInit )  return -1;
467
468         Assert(GameSounds[soundnum].data != -1);
469
470         memset(&ssb, 0, sizeof(SSoundBuffer));
471         
472         ssb.data = (char *)GameSounds[soundnum].data;
473         ssb.length = GameSounds[soundnum].length;
474         ssb.pan = (unsigned short)pan+1;
475 //      ssb.id = soundnum;
476         ssb.vol = (unsigned short)fixmuldiv(volume, digi_volume, F1_0);
477         ssb.vol = (ssb.vol << 2);
478         ssb.rate = digi_sample_rate;
479         ssb.channels = 1;
480         ssb.bits_per_sample = 8;
481
482         if (looping) {
483                 ssb.looping = 1;
484                 ssb.loop_start = ssb.loop_end = -1;
485         }       
486         if (loop_start != -1) {
487                 Assert( loop_end != -1);
488                 ssb.loop_start = loop_start;
489                 ssb.loop_end = loop_end;
490                 ssb.loop_length = loop_end - loop_start;
491         }               
492
493         starting_channel = next_channel;
494
495         while(1)        {
496                 if ( !channels[next_channel].used ) break;
497                 
498                 if (!SSChannelPlaying((int)channels[next_channel].handle)) break;
499
500                 if ( !channels[next_channel].persistant )       {
501                         SSStopChannel(channels[next_channel].handle);
502                         break;  // use this channel!    
503                 }
504                 next_channel++;
505                 if ( next_channel >= digi_max_channels )
506                         next_channel = 0;
507                 if ( next_channel == starting_channel ) {
508                         mprintf(( 1, "OUT OF SOUND CHANNELS!!!\n" ));
509                         return -1;
510                 }
511         }
512         if ( channels[next_channel].used )      {
513                 channels[next_channel].used = 0;
514                 if ( channels[next_channel].soundobj > -1 )     {
515                         digi_end_soundobj(channels[next_channel].soundobj);     
516                 }
517                 if (SoundQ_channel==next_channel)
518                         SoundQ_end();
519         }
520
521         sHandle = SSInitChannel(&ssb);
522         if (sHandle == -1) {
523                 mprintf(( 1, "NOT ENOUGH SOUND SLOTS!!!\n" ));
524                 return -1;
525         }
526
527         #ifndef NDEBUG
528         verify_sound_channel_free(next_channel);
529         #endif
530
531         //free up any sound objects that were using this handle
532         for (i=0; i<digi_max_channels; i++ )    {
533                 if ( channels[i].used && (channels[i].handle == sHandle)  )     {
534                         channels[i].used = 0;
535                         if ( channels[i].soundobj > -1 )        {
536                                 digi_end_soundobj(channels[i].soundobj);        
537                         }
538                         if (SoundQ_channel==i)
539                                 SoundQ_end();
540                 }
541         }
542
543         channels[next_channel].used = 1;
544         channels[next_channel].soundnum = soundnum;
545         channels[next_channel].soundobj = soundobj;
546         channels[next_channel].handle = sHandle;
547         channels[next_channel].volume = volume;
548         channels[next_channel].persistant = 0;
549         if ( (soundobj > -1) || (looping) || (volume>F1_0) )
550                 channels[next_channel].persistant = 1;
551
552         i = next_channel;
553         next_channel++;
554         if ( next_channel >= digi_max_channels )
555                 next_channel = 0;
556
557         return i;
558 }
559
560
561 //      Volume Functions
562 //      ----------------------------------------------------------------------------
563 void digi_set_midi_volume( int mvolume )
564 {
565
566         int old_volume = midi_volume;
567
568         if ( mvolume > 127 )
569                 midi_volume = 127;
570         else if ( mvolume < 0 )
571                 midi_volume = 0;
572         else
573                 midi_volume = mvolume;
574
575         if ( (MIDIDriverInit) )         {
576                 if (!Redbook_playing && (old_volume < 1) && ( midi_volume > 1 ) )       {
577                         if (WMidiHandle == 0 )
578                                 digi_play_midi_song( digi_last_midi_song, NULL, NULL, 1 );
579                 }
580                 wmidi_set_volume(midi_volume);
581         }
582
583         mprintf((0, "Changing midi volume=%d.\n", midi_volume));
584 }
585
586 void digi_set_digi_volume( int dvolume )
587 {
588         dvolume = fixmuldiv( dvolume, _DIGI_MAX_VOLUME, 0x7fff);
589         if ( dvolume > _DIGI_MAX_VOLUME )
590                 digi_volume = _DIGI_MAX_VOLUME;
591         else if ( dvolume < 0 )
592                 digi_volume = 0;
593         else
594                 digi_volume = dvolume;
595
596         if ( !Digi_initialized ) return;
597         if ( !digi_system_initialized ) return;
598
599         //digi_sync_sounds();
600 }
601
602
603 // 0-0x7FFF 
604 void digi_set_volume( int dvolume, int mvolume )        
605 {
606         digi_set_midi_volume( mvolume );
607         digi_set_digi_volume( dvolume );
608         mprintf(( 1, "Volume: 0x%x and 0x%x\n", digi_volume, midi_volume ));
609 }
610
611 // allocate memory for file, load fil
612 void * digi_load_file( char * szFileName, HGLOBAL *hmem, int * length )
613 {
614    PSTR  pDataPtr;
615         CFILE * fp;
616         
617    // open file
618    fp  =  cfopen( szFileName, "rb" );
619         if ( !fp ) return NULL;
620
621    *length  =  cfilelength(fp);
622
623         *hmem = GlobalAlloc(GPTR, *length);
624         if (!(*hmem)) return NULL;
625         pDataPtr = GlobalLock(*hmem);
626
627    // read in driver
628    cfread( pDataPtr, *length, 1, fp);
629
630    // close driver file
631    cfclose( fp );
632
633    // return 
634    return( pDataPtr );
635 }
636
637
638 void digi_stop_current_song()
639 {
640         if (!Digi_initialized) return;
641
642         if ( MIDIDriverInit )   {
643                 // Stop last song...
644                 if (WMidiHandle > 0 )   {
645                    // stop the last MIDI song from playing
646                         wmidi_stop();
647                         wmidi_close_song();
648                         WMidiHandle = 0;
649                 }
650                 if (SongData)   {
651                         GlobalUnlock(SongData);
652                         GlobalFree(hSongData);
653                         SongData = NULL;
654                         hSongData = NULL;
655                 }
656         }
657 }
658
659
660 void digi_play_midi_song( char * filename, char * melodic_bank, char * drum_bank, int loop )
661 {
662         char fname[128];
663         CFILE           *fp;
664         int sl;
665
666         if (!Digi_initialized) return;
667         if ( !MIDIDriverInit )  return;
668
669         digi_stop_current_song();
670
671         if ( filename == NULL ) return;
672
673         strcpy( digi_last_midi_song, filename );
674
675         fp = NULL;
676
677         sl = strlen( filename );
678         strcpy( fname, filename );      
679         fname[sl-3] = 'm';
680         fname[sl-2] = 'i';
681         fname[sl-1] = 'd';
682
683         fp = cfopen( fname, "rb" );
684         mprintf((0, "Loading %s\n", fname));
685
686         if ( !fp  )     {
687                 mprintf( (1, "Error opening midi file, '%s'", filename ));
688                 return;
689         }
690         if ( midi_volume < 1 )          {
691                 cfclose(fp);
692                 return;                         // Don't play song if volume == 0;
693         }
694         SongSize = cfilelength( fp );
695         hSongData = GlobalAlloc(GPTR, SongSize);
696         if (hSongData==NULL)    {
697                 cfclose(fp);
698                 mprintf( (1, "Error allocating %d bytes for '%s'", SongSize, filename ));
699                 return;
700         }
701         SongData = GlobalLock(hSongData);
702         if ( cfread (  SongData, SongSize, 1, fp )!=1)  {
703                 mprintf( (1, "Error reading midi file, '%s'", filename ));
704                 cfclose(fp);
705                 GlobalUnlock(SongData);
706                 GlobalFree(hSongData);
707                 SongData=NULL;
708                 hSongData = NULL;
709                 return;
710         }
711
712         cfclose(fp);
713
714 // setup the song initialization structure
715         WMidiSong.data = SongData;
716         WMidiSong.length = SongSize;
717
718         if ( loop )
719                 WMidiSong.looping = 1;
720         else
721                 WMidiSong.looping = 0;
722
723 //      initialize the song
724         WMidiHandle = wmidi_init_song(&WMidiSong);
725         if (!WMidiHandle) {
726                 mprintf((1, "Unable to initialize MIDI song.\n"));              
727                 GlobalUnlock(SongData);
728                 GlobalFree(hSongData);
729                 SongData=NULL;
730                 hSongData = NULL;
731                 return;
732         }
733
734         Assert( WMidiHandle == 1 );
735          
736 // start the song playing
737         mprintf((0, "Playing song %x.\n", WMidiHandle));
738
739         if (!wmidi_play()) {
740                 mprintf( (1, "\nUnable to play midi song.\n"));
741                 wmidi_close_song();
742                 GlobalUnlock(SongData);
743                 GlobalFree(hSongData);
744                 SongData=NULL;
745                 hSongData = NULL;
746                 return;
747    }
748 }
749
750
751 int sound_paused = 0;
752
753 void digi_pause_midi()
754 {
755         if (!Digi_initialized) return;
756
757         if (sound_paused==0)    {
758                 if ( digi_midi_type > 0 && WMidiHandle > 0)     {
759                         // pause here
760                                 wmidi_pause();
761                 }
762         }
763         sound_paused++;
764 }
765
766
767
768 void digi_resume_midi()
769 {
770         if (!Digi_initialized) return;
771
772         Assert( sound_paused > 0 );
773
774         if (sound_paused==1)    {
775                 // resume sound here
776                 if ( digi_midi_type > 0 && WMidiHandle > 0)     {
777                         wmidi_resume();
778                 }
779         }
780         sound_paused--;
781 }
782
783
784 #ifndef NDEBUG
785 void digi_debug()
786 {
787         int i;
788         int n_voices=0;
789
790         if (!Digi_initialized) return;
791         if (!DIGIDriverInit) return;
792
793         for (i=0; i<digi_max_channels; i++ )    {
794                 if ( digi_is_channel_playing(i) )
795                         n_voices++;
796         }
797
798         mprintf_at(( 0, 2, 0, "DIGI: Active Sound Channels: %d/%d ", n_voices, digi_max_channels));
799 }
800
801
802 void digi_midi_debug()
803 {
804
805 }
806         
807 #endif
808
809
810 extern BOOL WMidi_NewStream;
811
812 void digi_midi_wait()
813 {
814         fix ftime;
815         int tech;
816
817         tech = wmidi_get_tech();
818         if (tech) return;
819         
820         ftime = timer_get_fixed_seconds() + 0x50000;
821         WMidi_NewStream = FALSE;
822         while ((WMidi_NewStream < 2 && WMidiHandle) || (timer_get_fixed_seconds() < ftime)) Sleep(0);
823 }
824
825