source: abuse/branches/pd/macabuse/imlib/port/dos4gw/sound.c @ 636

Last change on this file since 636 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 12.8 KB
Line 
1extern "C" {
2#include "sos.h"
3#include "sosm.h"
4} ;
5
6#include "profile.h"
7#include "readwav.hpp"
8#include "jmalloc.hpp"
9#include <stdlib.h>
10#include "sound.hpp"
11#include <stdio.h>
12#include "dprint.hpp"
13#include "specs.hpp"
14#include "doscall.hpp"
15#include "specs.hpp"
16#include "macs.hpp"
17#include "timing.hpp"
18#include <dos.h>
19
20static W32      wDIGIDeviceID=-1;                            // digital device ID
21static W32      wMIDIDeviceID=-1;                            // midi device ID
22
23static uchar sos_need_uninit_midi_system=0,
24             sos_need_uninit_midi_driver=0,
25             sos_need_uninit_digi_system=0,
26             sos_need_uninit_digi_driver=0,
27             sos_need_uninit_timer=0,
28             sos_need_remove_timer_event=0;
29
30static HANDLE             hDIGIDriver;               // handle to digital driver
31static HANDLE             hMIDIDriver;               // handle to MIDI driver
32static HANDLE             hDIGITimer;                // handle to digital mixer
33static _SOS_DIGI_DRIVER   sDIGIDriver;               // digital driver structure
34static _SOS_MIDI_DRIVER   sMIDIDriver;               // midi driver structure
35static PSTR               pMelodicPatch=NULL;        // melodic FM instruments
36static PSTR               pDrumPatch=NULL;           // drum FM instruments
37static _SOS_SAMPLE        sos_sam;
38static int s_init=0;                   // flags saying what has been initalized
39
40extern void add_timer_call(void ( *fun)(), int and_call_mask);
41extern void remove_timer_call(void ( *fun)());
42
43void print_sound_options() { ; }                         // print the options avaible for sound
44void song::set_volume(int volume)  // 0..127
45{
46  if ((s_init&MUSIC_INITIALIZED) && data)
47    sosMIDISetSongVolume(song_id,volume);
48}
49
50extern void (*install_timer_handler)(void (*fun)())=NULL;   // function to install timer
51extern void (*uninstall_timer_handler)()=NULL;
52
53static HANDLE jc_timer_handle;
54extern uchar timer_installed;
55static void install_timer(void (*fun)())
56{
57  sosTIMERRegisterEvent(100,fun,&jc_timer_handle);
58}
59
60static void uninstall_timer()
61{
62  sosTIMERRemoveEvent( jc_timer_handle);
63}
64// BOOL  sosEZGetConfig( PSTR szName )
65BOOL sosEZGetConfig(char *szName )
66{
67 _INI_INSTANCE  sInstance;
68 BOOL           wError;
69 
70 // reset digital and MIDI driver structures
71 memset( &sDIGIDriver, 0, sizeof( _SOS_DIGI_DRIVER ) );
72 memset( &sMIDIDriver, 0, sizeof( _SOS_MIDI_DRIVER ));
73 
74 // open .ini file
75 if ( !hmiINIOpen( &sInstance, szName ) )
76 return( _FALSE );
77 
78 // locate section for digital settings
79 if ( !hmiINILocateSection( &sInstance, "DIGITAL" ) )
80 { 
81    // close file
82    hmiINIClose( &sInstance );
83   
84    // return error
85    return( _FALSE );
86  }
87 
88 // fetch device ID, Port, DMA, IRQ
89 wError   =  hmiINIGetItemDecimal( &sInstance, "DeviceID", &wDIGIDeviceID );
90 wError   =  hmiINIGetItemDecimal( &sInstance, "DevicePort", &sDIGIDriver.sHardware.wPort );
91 wError   =  hmiINIGetItemDecimal( &sInstance, "DeviceDMA", &sDIGIDriver.sHardware.wDMA );
92 wError   =  hmiINIGetItemDecimal( &sInstance, "DeviceIRQ", &sDIGIDriver.sHardware.wIRQ );
93 
94 // error
95 if ( !wError )
96 {
97  // close file
98  hmiINIClose( &sInstance );
99 
100  // return error
101  return( _FALSE );
102}
103 
104 // locate section for MIDI settings
105 if ( !hmiINILocateSection( &sInstance, "MIDI" ) )
106 { 
107    // close file
108    hmiINIClose( &sInstance );
109   
110    // return error
111    return( _FALSE );
112  }
113 
114 // fetch device ID, Port, DMA, IRQ
115 wError   =  hmiINIGetItemDecimal( &sInstance, "DeviceID", &wMIDIDeviceID );
116 wError   =  hmiINIGetItemDecimal( &sInstance, "DevicePort", &sMIDIDriver.sHardware.wPort );
117 
118 // error
119 if ( !wError )
120 {
121  // close file
122  hmiINIClose( &sInstance );
123 
124  // return error
125  return( _FALSE );
126}
127 
128 // close file
129 hmiINIClose( &sInstance );
130 
131 // return success
132 return( _TRUE );
133}
134
135int sosEZInitSystem2(W32 wDDeviceID, W32 wMDeviceID )
136{
137  // set up the digital driver
138  sDIGIDriver.wDriverRate       =  11025;
139  sDIGIDriver.wDMABufferSize    =  0x1000;
140
141  int inst=timer_installed;
142  if (inst)    // if a timer is already installed, uninstall and reinstall with us   
143    timer_uninit();
144
145  install_timer_handler=install_timer;
146  uninstall_timer_handler=uninstall_timer;
147 
148
149  // initialize the timer system
150  sosTIMERInitSystem( _TIMER_DOS_RATE, _SOS_DEBUG_NORMAL );
151  sos_need_uninit_timer=1;
152
153  if (inst)
154    timer_init();
155
156
157  // initialize the digital and midi systems
158  sosDIGIInitSystem( _NULL, _SOS_DEBUG_NORMAL );
159  sos_need_uninit_digi_system=1;
160
161  sosMIDIInitSystem( _NULL, _SOS_DEBUG_NORMAL );
162  sos_need_uninit_midi_system=1;
163
164  // check to see if the midi device is to be initialized
165  if ( wMDeviceID != -1 )
166  {
167    // initialize MIDI
168    sMIDIDriver.wID = wMDeviceID;
169    if ( sosMIDIInitDriver( &sMIDIDriver, &hMIDIDriver ) )
170    {
171      sound_uninit();
172      return 0;
173    } else sos_need_uninit_midi_driver=1;
174  }
175
176  // initialize the digital driver
177  if ( wDDeviceID != -1 )
178  {
179    // initialize digital
180    sDIGIDriver.wID = wDDeviceID;
181    if ( sosDIGIInitDriver( &sDIGIDriver, &hDIGIDriver ) )
182    {
183      sound_uninit();
184      return 0;
185    } else
186    {
187      sos_need_uninit_digi_driver=1;
188      s_init|=SFX_INITIALIZED;
189    }
190  }
191
192
193  // register digital timer event (mixer)
194  if ( wDDeviceID != -1  || wMDeviceID!=-1)
195  {
196    sos_need_remove_timer_event=1;
197
198    sosTIMERRegisterEvent(100, sDIGIDriver.pfnMixFunction,
199                        &hDIGITimer );
200  }
201
202
203  // check driver type, if it is an OPL2/3 driver, we
204  // need to load the patch files for the driver.
205  if (wMIDIDeviceID == _MIDI_FM || wMIDIDeviceID == _MIDI_OPL3 && wMIDIDeviceID != -1 )
206  {
207    bFILE *fp=open_file("music/melodic.bnk","rb");
208    if (fp->open_failure())
209    {
210      dprintf("Missing file music/melodic.bnk, sound disabled\n");
211      sound_uninit();
212      delete fp;
213      return 0;
214    }
215   
216    long l=fp->file_size();
217    pMelodicPatch=(PSTR)jmalloc(l,"Melodic bank");
218    fp->read(pMelodicPatch,l);
219    delete fp;
220
221
222    fp=open_file("music/drum.bnk","rb");
223    if (fp->open_failure())
224    {
225      dprintf("Missing file music/drum.bnk, sound disabled\n");
226      sound_uninit();
227      delete fp;
228      return 0;
229    }
230   
231    l=fp->file_size();
232    pDrumPatch=(PSTR)jmalloc(l,"Drum bank");
233    fp->read(pDrumPatch,l);
234    delete fp;
235
236
237    if ((sosMIDISetInsData( hMIDIDriver, (LPSTR)pMelodicPatch, 1)) ||
238        (sosMIDISetInsData( hMIDIDriver, (LPSTR)pDrumPatch, 1)))
239    {
240      sound_uninit();
241      return 0;
242    }
243    s_init|=MUSIC_INITIALIZED;
244  } else if (wMIDIDeviceID!=-1)
245     s_init|=MUSIC_INITIALIZED;
246
247
248  return s_init;
249}
250
251
252void sound_uninit()
253{
254  if (sos_need_remove_timer_event)
255  {
256    sos_need_remove_timer_event=0;
257    sosTIMERRemoveEvent( hDIGITimer );
258  }
259
260  if (sos_need_uninit_timer)
261  {
262    int inst=timer_installed;
263    if (inst)    // if a timer is already installed, uninstall and reinstall with us
264    {
265      timer_uninit();
266      install_timer_handler=NULL;
267      uninstall_timer_handler=NULL;
268    }
269
270
271    sos_need_uninit_timer=0;
272    sosTIMERUnInitSystem(0);
273
274
275    if (inst)
276    {
277      timer_init();        // reinitial timer to use old method
278    }
279  }
280
281  if (sos_need_uninit_digi_driver)
282  {
283    sos_need_uninit_digi_driver=0;
284    sosDIGIUnInitDriver( hDIGIDriver, _TRUE, _TRUE );
285    s_init&=~SFX_INITIALIZED;
286  }
287
288  if (sos_need_uninit_digi_system)
289  {
290    sos_need_uninit_digi_system=0;
291    sosDIGIUnInitSystem();
292  }
293
294
295  if (sos_need_uninit_midi_driver)
296  {
297    sos_need_uninit_midi_driver=0;
298    sosMIDIUnInitDriver( hMIDIDriver, _TRUE );
299    s_init=s_init&(~MUSIC_INITIALIZED);
300  }
301
302  if (sos_need_uninit_midi_system)
303  {
304    sos_need_uninit_midi_system=0;
305    sosMIDIUnInitSystem();
306  }
307
308
309
310  if (pDrumPatch)
311  {
312    jfree(pDrumPatch);
313    pDrumPatch=NULL;
314  }
315
316  if (pMelodicPatch)
317  {
318    jfree(pMelodicPatch);
319    pMelodicPatch=NULL;
320  }
321
322}
323
324int sound_init(int argc, char **argv)
325{
326  if (s_init!=0) sound_uninit();
327
328  atexit(sound_uninit);
329  for (int i=1;i<argc;i++)
330  {
331    if (!strcmp(argv[i],"-nosound"))
332    {
333      dprintf("sound : sound disabled (-nosound)\n");
334      wDIGIDeviceID=-1;
335      wMIDIDeviceID=-1;   
336      return 0;
337    }
338  }
339
340  if (sosEZGetConfig("sndcard.cfg")==_FALSE)
341  {
342    wDIGIDeviceID=-1;
343    wMIDIDeviceID=-1;   
344    dprintf("Sound configuration was not saved by setup program, sound disabled\n");
345    return 0;   
346  }
347
348  if (wDIGIDeviceID==-1 && wMIDIDeviceID==-1)
349    return 0;
350
351  memset(&sos_sam,0,sizeof(sos_sam));
352  sos_sam.wBitsPerSample=8;
353  sos_sam.wChannels=1;
354  sos_sam.wFormat=_PCM_UNSIGNED;
355  sos_sam.wRate=11025;
356  sos_sam.wPanPosition=_PAN_CENTER;
357
358
359  return sosEZInitSystem2(wDIGIDeviceID, wMIDIDeviceID);
360
361
362
363/*  sosTIMERInitSystem( _TIMER_DOS_RATE, _SOS_DEBUG_NORMAL );   
364  sos_need_uninit_timer=1;
365  sosDIGIInitSystem( _NULL, _SOS_DEBUG_NORMAL );
366  sos_need_uninit_digi=1;
367  sosMIDIInitSystem(_NULL,_SOS_DEBUG_NORMAL);
368  sos_need_uninit_midi=1;
369
370
371  if (wDIGIDeviceID!=-1)
372  {
373    sDIGIDriver.wDriverRate       =  11025;
374    sDIGIDriver.wDMABufferSize    =  0x1000;
375
376    sDIGIDriver.wID = wDIGIDeviceID;
377
378    if ( sosDIGIInitDriver( &sDIGIDriver, &hDIGIDriver ) )
379    {
380      sound_uninit();
381      return 0;
382    }
383    int inst=timer_installed;
384    if (inst)    // if a timer is already installed, uninstall and reinstall with us   
385      timer_uninit();
386
387    install_timer_handler=install_timer;
388    uninstall_timer_handler=uninstall_timer;
389 
390    if (inst)
391      timer_init();
392
393    sosTIMERRegisterEvent(100,sDIGIDriver.pfnMixFunction,
394                          &hDIGITimer );
395    sos_need_remove_timer_event=1;
396
397    s_init|=SFX_INITIALIZED;
398  }
399
400  if (wMIDIDeviceID!=-1)
401  {
402    sMIDIDriver.wID = wMIDIDeviceID;
403    if (sosMIDIInitDriver( &sMIDIDriver, &hMIDIDriver ))
404    {
405      sound_uninit();
406      return 0;
407    }
408  }
409
410
411
412
413
414
415
416  // check driver type, if it is an OPL2/3 driver, we
417  // need to load the patch files for the driver.
418  if (wMIDIDeviceID == _MIDI_FM || wMIDIDeviceID == _MIDI_OPL3 && wMIDIDeviceID != -1 )
419  {
420    bFILE *fp=open_file("music/melodic.bnk","rb");
421    if (fp->open_failure())
422    {
423      dprintf("Missing file music/melodic.bnk, sound disabled\n");
424      sound_uninit();
425      delete fp;
426      return 0;
427    }
428   
429    long l=fp->file_size();
430    pMelodicPatch=(PSTR)jmalloc(l,"Melodic bank");
431    fp->read(pMelodicPatch,l);
432    delete fp;
433
434
435    fp=open_file("music/drum.bnk","rb");
436    if (fp->open_failure())
437    {
438      dprintf("Missing file music/drum.bnk, sound disabled\n");
439      sound_uninit();
440      delete fp;
441      return 0;
442    }
443   
444    l=fp->file_size();
445    pDrumPatch=(PSTR)jmalloc(l,"Drum bank");
446    fp->read(pDrumPatch,l);
447    delete fp;
448
449
450    if ((sosMIDISetInsData( hMIDIDriver, (LPSTR)pMelodicPatch, 1)) ||
451        (sosMIDISetInsData( hMIDIDriver, (LPSTR)pDrumPatch, 1)))
452    {
453      sound_uninit();
454      return 0;
455    }
456    s_init|=MUSIC_INITIALIZED;
457  } else if (wMIDIDeviceID!=-1) s_init|=MUSIC_INITIALIZED;
458
459  memset(&sos_sam,0,sizeof(sos_sam));
460  sos_sam.wBitsPerSample=8;
461  sos_sam.wChannels=1;
462  sos_sam.wFormat=_PCM_UNSIGNED;
463  sos_sam.wRate=11025;
464  sos_sam.wPanPosition=_PAN_CENTER;
465
466  return s_init; */
467}
468
469sound_effect::sound_effect(char *filename)
470
471  if (s_init&SFX_INITIALIZED)
472  {
473    long sample_speed;
474    data=(void *)read_wav(filename,sample_speed,size); 
475  } else data=NULL;
476};
477
478
479
480
481void sound_effect::play(int volume, int pitch, int panpot)
482{
483  if ((s_init&SFX_INITIALIZED) && data)
484  {
485    sos_sam.pSample=(PSTR)data;
486    sos_sam.wLength=size;
487    sos_sam.wVolume=MK_VOLUME( ((volume<<8)|0xff) , ((volume<<8)|0xff));
488    sosDIGIStartSample( hDIGIDriver, &sos_sam);
489  }
490}
491
492
493sound_effect::~sound_effect()
494{
495  if (data)
496    jfree(data);       // hope it's not still playing!!! :)
497}
498
499song::song(char *filename)
500{
501  data=NULL;
502  if (s_init&MUSIC_INITIALIZED)
503  {
504    bFILE *fp=open_file(filename,"rb");
505    if (!fp->open_failure())
506    {
507      long l=fp->file_size();
508      data=(uchar *)jmalloc(l+sizeof(_SOS_MIDI_SONG),"song");
509
510      _SOS_MIDI_SONG *sSong;
511      sSong= (_SOS_MIDI_SONG *)data;
512      memset( sSong, 0, sizeof( _SOS_MIDI_SONG ) );
513      sSong->pSong =  ( PSTR )( data + sizeof( _SOS_MIDI_SONG ));
514
515      fp->read(sSong->pSong,l);
516      W32 hSong;
517      int err;
518
519
520      if (err=sosMIDIInitSong( sSong, &hSong ))
521      {
522        dprintf("Error while registering song %s\n",filename);
523        if (err==_ERR_NO_HANDLES)
524        dprintf("out of handles\n");
525        else if (err==_ERR_INVALID_DATA)
526        dprintf("invaild data in file\n");
527
528        jfree(data);
529        data=NULL;     
530      } else song_id=hSong;     
531    }
532    delete fp;
533  }
534}
535
536void song::play(unsigned char volume)
537{
538  if (s_init&MUSIC_INITIALIZED)
539  {
540    if (data)
541    {
542      sosMIDIStartSong((W32)song_id);
543      set_volume(volume);
544    }
545  }
546}
547
548
549void song::stop(long fadeout_time)
550{
551  if ((s_init&MUSIC_INITIALIZED) && data)
552    sosMIDIStopSong((W32)song_id);
553}                                        // time in ms
554
555
556int song::playing()
557{
558  if ((s_init&MUSIC_INITIALIZED) && data)
559  {
560    if (sosMIDISongDone((W32)song_id)==_FALSE)
561      return 1;
562    else return 0;
563  } else return 0;
564}
565
566
567song::~song()
568{
569  if (data)
570  {
571    if (s_init&MUSIC_INITIALIZED)
572      sosMIDIUnInitSong((W32)song_id);
573    jfree(data);
574  }
575}
576
577
578
579
580
581
582
Note: See TracBrowser for help on using the repository browser.