Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
298 serge 1
// Emacs style mode select   -*- C++ -*-
2
//-----------------------------------------------------------------------------
3
//
4
// $Id:$
5
//
6
// Copyright (C) 1993-1996 by id Software, Inc.
7
//
8
// This source is available for distribution and/or modification
9
// only under the terms of the DOOM Source Code License as
10
// published by id Software. All rights reserved.
11
//
12
// The source is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15
// for more details.
16
//
17
// $Log:$
18
//
19
// DESCRIPTION:
20
//	System interface for sound.
21
//
22
//-----------------------------------------------------------------------------
23
 
24
static const char
25
rcsid[] = "$Id: i_unix.c,v 1.5 1997/02/03 22:45:10 b1 Exp $";
26
 
27
#include 
28
#include 
29
#include 
30
 
31
#include 
32
 
33
#include 
34
#include 
35
 
36
//#ifndef LINUX
37
//#include 
38
//#endif
39
 
40
#include 
41
#include 
42
//#include 
43
//#include 
44
 
45
// Linux voxware output.
46
//#include 
47
 
48
// Timer stuff. Experimental.
49
#include 
50
#include 
51
 
52
#include "z_zone.h"
53
 
54
#include "i_system.h"
55
#include "i_sound.h"
56
#include "m_argv.h"
57
#include "m_misc.h"
58
#include "w_wad.h"
59
 
60
#include "doomdef.h"
61
 
62
typedef unsigned int DWORD;
63
 
64
////////////////////////////////////////////////////////////////////////////
65
// WinDoom - DirectSound
66
////////////////////////////////////////////////////////////////////////////
67
 
68
#define NUM_SOUND_FX 128
69
#define SB_SIZE      20480
70
 
71
void CreateSoundBuffer(int Channel, int length, unsigned char *data);
72
void I_PlaySoundEffect(int sfxid, int Channel, int volume, int pan);
73
 
74
#define NUM_DSBUFFERS 256
75
 
76
typedef enum { dsb_perm, dsb_temp } dsb_type;
77
 
78
typedef struct
79
   {
80
    void   *origin;
81
    int     dsb_type;
82
    int     sfxid;
83
   }DSBControl_t;
84
 
85
DSBControl_t DSBControl[NUM_DSBUFFERS];
86
 
87
extern int swap_stereo;
88
 
89
////////////////////////////////////////////////////////////////////////////
90
 
91
// UNIX hack, to be removed.
92
#ifdef SNDSERV
93
// Separate sound server process.
94
FILE*	sndserver=0;
95
char*	sndserver_filename = "./sndserver ";
96
#elif SNDINTR
97
 
98
// Update all 30 millisecs, approx. 30fps synchronized.
99
// Linux resolution is allegedly 10 millisecs,
100
//  scale is microseconds.
101
#define SOUND_INTERVAL     500
102
 
103
// Get the interrupt. Set duration in millisecs.
104
int I_SoundSetTimer( int duration_of_tick );
105
void I_SoundDelTimer( void );
106
#else
107
// None?
108
#endif
109
 
110
 
111
// A quick hack to establish a protocol between
112
// synchronous mix buffer updates and asynchronous
113
// audio writes. Probably redundant with gametic.
114
static int flag = 0;
115
 
116
// The number of internal mixing channels,
117
//  the samples calculated for each mixing step,
118
//  the size of the 16bit, 2 hardware channel (stereo)
119
//  mixing buffer, and the samplerate of the raw data.
120
 
121
 
122
// Needed for calling the actual sound output.
123
#define SAMPLECOUNT		512
124
#define NUM_CHANNELS		16
125
// It is 2 for 16bit, and 2 for two channels.
126
#define BUFMUL                  4
127
#define MIXBUFFERSIZE		(SAMPLECOUNT*BUFMUL)
128
 
129
#define SAMPLERATE		11025	// Hz
130
#define SAMPLESIZE		2   	// 16bit
131
 
132
// The actual lengths of all sound effects.
133
int 		lengths[NUMSFX];
134
 
135
// The actual output device.
136
//int	audio_fd;
137
 
138
// The global mixing buffer.
139
// Basically, samples from all active internal channels
140
//  are modifed and added, and stored in the buffer
141
//  that is submitted to the audio device.
142
signed short	mixbuffer[MIXBUFFERSIZE];
143
 
144
 
145
// The channel step amount...
146
unsigned int	channelstep[NUM_CHANNELS];
147
// ... and a 0.16 bit remainder of last step.
148
unsigned int	channelstepremainder[NUM_CHANNELS];
149
 
150
 
151
// The channel data pointers, start and end.
152
unsigned char*	channels[NUM_CHANNELS];
153
unsigned char*	channelsend[NUM_CHANNELS];
154
 
155
 
156
// Time/gametic that the channel started playing,
157
//  used to determine oldest, which automatically
158
//  has lowest priority.
159
// In case number of active sounds exceeds
160
//  available channels.
161
int		channelstart[NUM_CHANNELS];
162
 
163
// The sound in channel handles,
164
//  determined on registration,
165
//  might be used to unregister/stop/modify,
166
//  currently unused.
167
int 		channelhandles[NUM_CHANNELS];
168
 
169
// SFX id of the playing sound effect.
170
// Used to catch duplicates (like chainsaw).
171
int		channelids[NUM_DSBUFFERS];
172
 
173
// Pitch to stepping lookup, unused.
174
int		steptable[256];
175
 
176
// Volume lookups.
177
int		vol_lookup[128*256];
178
 
179
// Hardware left and right channel volume lookup.
180
int*		channelleftvol_lookup[NUM_CHANNELS];
181
int*		channelrightvol_lookup[NUM_CHANNELS];
182
 
183
 
184
//
185
// Safe ioctl, convenience.
186
//
187
void
188
myioctl
189
( int	fd,
190
  int	command,
191
  int*	arg )
192
{
193
// FIXME
194
/*
195
    int		rc;
196
    extern int	errno;
197
 
198
    rc = ioctl(fd, command, arg);
199
    if (rc < 0)
200
    {
201
	fprintf(stderr, "ioctl(dsp,%d,arg) failed\n", command);
202
	fprintf(stderr, "errno=%d\n", errno);
203
	exit(-1);
204
    }
205
*/
206
}
207
 
208
 
209
 
210
 
211
 
212
//
213
// This function loads the sound data from the WAD lump,
214
//  for single sound.
215
//
216
void *getsfx( char *sfxname, int *len )
217
   {
218
    unsigned char*      sfx;
219
    unsigned char*      paddedsfx;
220
    int                 i;
221
    int                 size;
222
    int                 paddedsize;
223
    char                name[20];
224
    int                 sfxlump;
225
 
226
 
227
    sprintf(name, "ds%s", sfxname);
228
 
229
    // Get the sound data from the WAD, allocate lump
230
    //  in zone memory.
231
    // Now, there is a severe problem with the
232
    //  sound handling, in it is not (yet/anymore)
233
    //  gamemode aware. That means, sounds from
234
    //  DOOM II will be requested even with DOOM
235
    //  shareware.
236
    // The sound list is wired into sounds.c,
237
    //  which sets the external variable.
238
    // I do not do runtime patches to that
239
    //  variable. Instead, we will use a
240
    //  default sound for replacement.
241
 
242
    if ( W_CheckNumForName(name) == -1 )
243
      sfxlump = W_GetNumForName("dspistol");
244
    else
245
      sfxlump = W_GetNumForName(name);
246
 
247
    size = W_LumpLength( sfxlump );
248
 
249
	// sprintf(MsgText, "Getting sound effect : %s - %d\n", name, size);
250
    // WriteDebug(MsgText);
251
 
252
    // Debug.
253
    // fprintf( stderr, "." );
254
    //fprintf( stderr, " -loading  %s (lump %d, %d bytes)\n",
255
    //	     sfxname, sfxlump, size );
256
    //fflush( stderr );
257
 
258
    sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC );
259
 
260
    // Pads the sound effect out to the mixing buffer size.
261
    // The original realloc would interfere with zone memory.
262
    paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT;
263
 
264
    // Allocate from zone memory.
265
    paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 );
266
    // ddt: (unsigned char *) realloc(sfx, paddedsize+8);
267
    // This should interfere with zone memory handling,
268
    //  which does not kick in in the soundserver.
269
 
270
    // Now copy and pad.
271
    memcpy(  paddedsfx, sfx, size );
272
    for (i = size; i < paddedsize+8; i++)
273
        paddedsfx[i] = 128;
274
 
275
    // Remove the cached lump.
276
    Z_Free( sfx );
277
 
278
    // Preserve padded length.
279
    *len = paddedsize;
280
 
281
    // Return allocated padded data.
282
    return (void *) (paddedsfx + 8);
283
   }
284
 
285
 
286
 
287
/*
288
 
289
//
290
// This function adds a sound to the
291
//  list of currently active sounds,
292
//  which is maintained as a given number
293
//  (eight, usually) of internal channels.
294
// Returns a handle.
295
//
296
int addsfx( int sfxid, int volume, int step, int seperation )
297
   {
298
    static unsigned short	handlenums = 0;
299
 
300
    int		i;
301
    int		rc = -1;
302
 
303
    int		oldest = gametic;
304
    int		oldestnum = 0;
305
    int		slot;
306
 
307
    int		rightvol;
308
    int		leftvol;
309
 
310
    int     iVolume, iPan;
311
 
312
    // Chainsaw troubles.
313
    // Play these sound effects only one at a time.
314
    if ( sfxid == sfx_sawup || sfxid == sfx_sawidl || sfxid == sfx_sawful ||
315
         sfxid == sfx_sawhit || sfxid == sfx_stnmov || sfxid == sfx_pistol )
316
       {
317
        // Loop all channels, check.
318
        for (i = 0; i < NUM_CHANNELS; i++)
319
           {
320
            // Active, and using the same SFX?
321
            if ( (channels[i]) && (channelids[i] == sfxid) )
322
               {
323
                // Reset.
324
                channels[i] = 0;
325
                // We are sure that iff, there will only be one.
326
                break;
327
               }
328
           }
329
       }
330
 
331
    // Loop all channels to find oldest SFX.
332
    for (i = 0; (i
333
        {
334
         if (channelstart[i] < oldest)
335
            {
336
             oldestnum = i;
337
             oldest = channelstart[i];
338
            }
339
        }
340
 
341
    // Tales from the cryptic.
342
    // If we found a channel, fine.
343
    // If not, we simply overwrite the first one, 0.
344
    // Probably only happens at startup.
345
    if (i == NUM_CHANNELS)
346
        slot = oldestnum;
347
    else
348
        slot = i;
349
 
350
    // Okay, in the less recent channel,
351
    //  we will handle the new SFX.
352
    // Set pointer to raw data.
353
    channels[slot] = (unsigned char *) S_sfx[sfxid].data;
354
    // Set pointer to end of raw data.
355
    channelsend[slot] = channels[slot] + lengths[sfxid];
356
 
357
    // Reset current handle number, limited to 0..100.
358
    if (!handlenums)
359
        handlenums = 100;
360
 
361
    // Assign current handle number.
362
    // Preserved so sounds could be stopped (unused).
363
    channelhandles[slot] = rc = handlenums++;
364
 
365
    // Set stepping???
366
    // Kinda getting the impression this is never used.
367
    channelstep[slot] = step;
368
    // ???
369
    channelstepremainder[slot] = 0;
370
    // Should be gametic, I presume.
371
    channelstart[slot] = gametic;
372
 
373
    iVolume = 0-(128*(15-volume));
374
    if (iVolume < -10000)
375
       iVolume == -10000;
376
    iPan = (seperation-128)*20;
377
    if (iPan < -10000)
378
       iPan = -10000;
379
    if (iPan > 10000)
380
       iPan = 10000;
381
 
382
    if (swap_stereo == TRUE)
383
       iPan *= -1;
384
 
385
    // Separation, that is, orientation/stereo.
386
    //  range is: 1 - 256
387
 
388
    seperation += 1;
389
 
390
    // Per left/right channel.
391
    //  x^2 seperation,
392
    //  adjust volume properly.
393
    leftvol = volume - ((volume*seperation*seperation) >> 16); //(256*256);
394
    seperation = seperation - 257;
395
    rightvol = volume - ((volume*seperation*seperation) >> 16);
396
 
397
    // Sanity check, clamp volume.
398
    if (rightvol < 0 || rightvol > 127)
399
        I_Error("rightvol out of bounds");
400
 
401
    if (leftvol < 0 || leftvol > 127)
402
        I_Error("leftvol out of bounds");
403
 
404
    // Get the proper lookup table piece
405
    //  for this volume level???
406
    channelleftvol_lookup[slot] = &vol_lookup[leftvol*256];
407
    channelrightvol_lookup[slot] = &vol_lookup[rightvol*256];
408
 
409
    // Preserve sound SFX id,
410
    //  e.g. for avoiding duplicates of chainsaw.
411
    channelids[slot] = sfxid;
412
 
413
    I_PlaySoundEffect(sfxid, iVolume, iPan);
414
 
415
    // You tell me.
416
    //return rc;
417
    return sfxid;
418
   }
419
 
420
*/
421
//
422
// This function adds a sound to the
423
//  list of currently active sounds,
424
//  which is maintained as a given number
425
//  (eight, usually) of internal channels.
426
// Returns a handle.
427
//
428
 
429
//
430
// SFX API
431
// Note: this was called by S_Init.
432
// However, whatever they did in the
433
// old DPMS based DOS version, this
434
// were simply dummies in the Linux
435
// version.
436
// See soundserver initdata().
437
//
438
void I_SetChannels()
439
{
440
  // Init internal lookups (raw data, mixing buffer, channels).
441
  // This function sets up internal lookups used during
442
  //  the mixing process.
443
  int		i;
444
  int		j;
445
 
446
  int*	steptablemid = steptable + 128;
447
 
448
  // Okay, reset internal mixing channels to zero.
449
  for (i=0; i
450
  {
451
    channels[i] = 0;
452
  }
453
 
454
  // This table provides step widths for pitch parameters.
455
  // I fail to see that this is currently used.
456
  for (i=-128 ; i<128 ; i++)
457
    steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0);
458
 
459
 
460
  // Generates volume lookup tables
461
  //  which also turn the unsigned samples
462
  //  into signed samples.
463
  for (i=0 ; i<128 ; i++)
464
    for (j=0 ; j<256 ; j++)
465
      vol_lookup[i*256+j] = (i*(j-128)*256)/127;
466
}
467
 
468
 
469
void I_SetSfxVolume(int volume)
470
{
471
  // Identical to DOS.
472
  // Basically, this should propagate
473
  //  the menu/config file setting
474
  //  to the state variable used in
475
  //  the mixing.
476
  snd_SfxVolume = volume;
477
}
478
 
479
// MUSIC API - dummy. Some code from DOS version.
480
void I_SetMusicVolume(int volume)
481
{
482
  // Internal state variable.
483
  snd_MusicVolume = volume;
484
  // Now set volume on output device.
485
  // Whatever( snd_MusciVolume );
486
}
487
 
488
 
489
//
490
// Retrieve the raw data lump index
491
//  for a given SFX name.
492
//
493
int I_GetSfxLumpNum(sfxinfo_t* sfx)
494
{
495
    char namebuf[9];
496
    sprintf(namebuf, "ds%s", sfx->name);
497
    return W_GetNumForName(namebuf);
498
}
499
 
500
//
501
// Starting a sound means adding it
502
//  to the current list of active sounds
503
//  in the internal channels.
504
// As the SFX info struct contains
505
//  e.g. a pointer to the raw data,
506
//  it is ignored.
507
// As our sound handling does not handle
508
//  priority, it is ignored.
509
// Pitching (that is, increased speed of playback)
510
//  is set, but currently not used by mixing.
511
//
512
int I_StartSound( int id, int vol, int sep, int pitch, int priority, void *origin )
513
   {
514
    // UNUSED
515
    priority = 0;
516
 
517
    // Debug.
518
//    sprintf(MsgText, "starting sound %d", id );
519
//    WriteDebug(MsgText);
520
 
521
    // Returns a handle (not used).
522
    id = addsfx( id, vol, steptable[pitch], sep, origin );
523
 
524
//    sprintf(MsgText, "/handle is %d\n", id );
525
//    WriteDebug(MsgText);
526
 
527
    return id;
528
   }
529
 
530
//
531
// This function loops all active (internal) sound
532
//  channels, retrieves a given number of samples
533
//  from the raw sound data, modifies it according
534
//  to the current (internal) channel parameters,
535
//  mixes the per channel samples into the global
536
//  mixbuffer, clamping it to the allowed range,
537
//  and sets up everything for transferring the
538
//  contents of the mixbuffer to the (two)
539
//  hardware channels (left and right, that is).
540
//
541
// This function currently supports only 16bit.
542
//
543
void I_UpdateSound( void )
544
   {
545
#ifdef SNDINTR
546
  // Debug. Count buffer misses with interrupt.
547
  static int misses = 0;
548
#endif
549
 
550
 
551
    // Mix current sound data.
552
    // Data, from raw sound, for right and left.
553
    register unsigned int	sample;
554
    register int		dl;
555
    register int		dr;
556
 
557
    // Pointers in global mixbuffer, left, right, end.
558
    signed short*		leftout;
559
    signed short*		rightout;
560
    signed short*		leftend;
561
    // Step in mixbuffer, left and right, thus two.
562
    int				step;
563
 
564
    // Mixing channel index.
565
    int				chan;
566
 
567
    // Left and right channel
568
    //  are in global mixbuffer, alternating.
569
    leftout = mixbuffer;
570
    rightout = mixbuffer+1;
571
    step = 2;
572
 
573
    // Determine end, for left channel only
574
    //  (right channel is implicit).
575
    leftend = mixbuffer + SAMPLECOUNT*step;
576
 
577
    // Mix sounds into the mixing buffer.
578
    // Loop over step*SAMPLECOUNT,
579
    //  that is 512 values for two channels.
580
    while (leftout != leftend)
581
    {
582
	// Reset left/right value.
583
	dl = 0;
584
	dr = 0;
585
 
586
	// Love thy L2 chache - made this a loop.
587
	// Now more channels could be set at compile time
588
	//  as well. Thus loop those  channels.
589
	for ( chan = 0; chan < NUM_CHANNELS; chan++ )
590
	{
591
	    // Check channel, if active.
592
	    if (channels[ chan ])
593
	    {
594
		// Get the raw data from the channel.
595
		sample = *channels[ chan ];
596
		// Add left and right part
597
		//  for this channel (sound)
598
		//  to the current data.
599
		// Adjust volume accordingly.
600
		dl += channelleftvol_lookup[ chan ][sample];
601
		dr += channelrightvol_lookup[ chan ][sample];
602
		// Increment index ???
603
		channelstepremainder[ chan ] += channelstep[ chan ];
604
		// MSB is next sample???
605
		channels[ chan ] += channelstepremainder[ chan ] >> 16;
606
		// Limit to LSB???
607
		channelstepremainder[ chan ] &= 65536-1;
608
 
609
		// Check whether we are done.
610
		if (channels[ chan ] >= channelsend[ chan ])
611
		    channels[ chan ] = 0;
612
	    }
613
	}
614
 
615
	// Clamp to range. Left hardware channel.
616
	// Has been char instead of short.
617
	// if (dl > 127) *leftout = 127;
618
	// else if (dl < -128) *leftout = -128;
619
	// else *leftout = dl;
620
 
621
	if (dl > 0x7fff)
622
	    *leftout = 0x7fff;
623
	else if (dl < -0x8000)
624
	    *leftout = -0x8000;
625
	else
626
	    *leftout = dl;
627
 
628
	// Same for right hardware channel.
629
	if (dr > 0x7fff)
630
	    *rightout = 0x7fff;
631
	else if (dr < -0x8000)
632
	    *rightout = -0x8000;
633
	else
634
	    *rightout = dr;
635
 
636
	// Increment current pointers in mixbuffer.
637
	leftout += step;
638
	rightout += step;
639
    }
640
 
641
#ifdef SNDINTR
642
    // Debug check.
643
    if ( flag )
644
    {
645
      misses += flag;
646
      flag = 0;
647
    }
648
 
649
    if ( misses > 10 )
650
    {
651
      fprintf( stderr, "I_SoundUpdate: missed 10 buffer writes\n");
652
      misses = 0;
653
    }
654
 
655
    // Increment flag for update.
656
    flag++;
657
#endif
658
}
659
 
660
 
661
//
662
// This would be used to write out the mixbuffer
663
//  during each game loop update.
664
// Updates sound buffer and audio device at runtime.
665
// It is called during Timer interrupt with SNDINTR.
666
// Mixing now done synchronous, and
667
//  only output be done asynchronous?
668
//
669
//void
670
//I_SubmitSound(void)
671
//{
672
  // Write it to DSP device.
673
//  write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
674
//}
675
 
676
 
677
 
678
 
679
 
680
void I_ShutdownSound(void)
681
{
682
//#ifdef SNDSERV
683
//  if (sndserver)
684
//  {
685
//    // Send a "quit" command.
686
//    fprintf(sndserver, "q\n");
687
//    fflush(sndserver);
688
//  }
689
//#else
690
  // Wait till all pending sounds are finished.
691
  int done = 0;
692
  //int i;
693
 
694
 
695
  // FIXME (below).
696
  //fprintf( stderr, "I_ShutdownSound: NOT finishing pending sounds\n");
697
  //fflush( stderr );
698
 
699
  //while ( !done )
700
  //{
701
  //  for( i=0 ; i<8 && !channels[i] ; i++);
702
 
703
    // FIXME. No proper channel output.
704
    //if (i==8)
705
    done=1;
706
  //}
707
//#ifdef SNDINTR
708
//  I_SoundDelTimer();
709
//#endif
710
 
711
  // Cleaning up -releasing the DSP device.
712
//  close( audio_fd );
713
//#endif
714
 
715
  // Done.
716
  return;
717
}
718
 
719
void I_InitSound()
720
{
721
	int i;
722
 
723
    I_CreateSound();
724
 
725
	for (i = 1; i < NUMSFX; i++)
726
	{
727
		// Alias? Example is the chaingun sound linked to pistol.
728
		if (!S_sfx[i].link)
729
		{
730
			// Load data from WAD file.
731
			S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] );
732
		}
733
		else
734
		{
735
			// Previously loaded already?
736
			S_sfx[i].data = S_sfx[i].link->data;
737
			lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
738
		}
739
		//having to crack here cuz crashing out at sound file 86 chgun
740
		// incidentally the only 'linked' sound in the whole pile
741
		// 10.10.98 dlw  tested good.
742
		if(i==86)
743
			CreateSoundBuffer(i, lengths[1], S_sfx[1].data);
744
		else
745
			CreateSoundBuffer(i, lengths[i], S_sfx[i].data);
746
 
747
 
748
		DSBControl[i].origin = NULL;
749
		DSBControl[i].sfxid = i;
750
		DSBControl[i].dsb_type = dsb_perm;
751
	}
752
	for (; i < NUM_DSBUFFERS; i++)
753
	{
754
		DSBControl[i].origin = NULL;
755
		DSBControl[i].sfxid = -1;
756
		DSBControl[i].dsb_type = dsb_temp;
757
	}
758
 
759
}
760
 
761
 
762
 
763
 
764
//
765
// MUSIC API.
766
// Still no music done.
767
// Remains. Dummies.
768
//
769
void I_InitMusic(void)		{ }
770
 
771
static int	looping=0;
772
static int	musicdies=-1;
773
 
774
 
775
 
776
// 10.12.98 dlw - cleanup the music files
777
void I_ShutdownMusic(void)
778
{
779
	int trasherror;  //self explained
780
 
781
	trasherror=unlink("doomsong.mus");
782
	trasherror=unlink("doomsong.mid");
783
	printf("I_ShutdownMusic...\n");
784
}
785
 
786
 
787
 
788
 
789
void I_PlaySong(int handle, int looping)
790
{
791
  // UNUSED.
792
  handle = looping = 0;
793
  musicdies = gametic + TICRATE*30;
794
}
795
 
796
void I_PauseSong (int handle)
797
{
798
  // UNUSED.
799
  handle = 0;
800
}
801
 
802
void I_ResumeSong (int handle)
803
{
804
  // UNUSED.
805
  handle = 0;
806
}
807
 
808
void I_StopSong(int handle)
809
{
810
  // UNUSED.
811
  handle = 0;
812
 
813
  looping = 0;
814
  musicdies = 0;
815
}
816
 
817
void I_UnRegisterSong(int handle)
818
{
819
  // UNUSED.
820
  handle = 0;
821
}
822
 
823
int I_RegisterSong(void* data)
824
{
825
  // UNUSED.
826
  data = NULL;
827
 
828
  return 1;
829
}
830
 
831
// Is the song playing?
832
int I_QrySongPlaying(int handle)
833
{
834
  // UNUSED.
835
  handle = 0;
836
  return looping || musicdies > gametic;
837
}
838
 
839
 
840
//
841
// Experimental stuff.
842
// A Linux timer interrupt, for asynchronous
843
//  sound output.
844
// I ripped this out of the Timer class in
845
//  our Difference Engine, including a few
846
//  SUN remains...
847
//
848
#ifdef sun
849
    typedef     sigset_t        tSigSet;
850
#else
851
    typedef     int             tSigSet;
852
#endif
853
 
854
 
855
// We might use SIGVTALRM and ITIMER_VIRTUAL, if the process
856
//  time independend timer happens to get lost due to heavy load.
857
// SIGALRM and ITIMER_REAL doesn't really work well.
858
// There are issues with profiling as well.
859
 
860
// FIXME
861
#define ITIMER_REAL 0
862
static int /*__itimer_which*/  itimer = ITIMER_REAL;
863
 
864
// FIXME
865
#define SIGALRM 0
866
static int sig = SIGALRM;
867
 
868
// Interrupt handler.
869
void I_HandleSoundTimer( int ignore )
870
{
871
  // Debug.
872
  //fprintf( stderr, "%c", '+' ); fflush( stderr );
873
 
874
  // Feed sound device if necesary.
875
  if ( flag )
876
  {
877
    // See I_SubmitSound().
878
    // Write it to DSP device.
879
    //write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
880
 
881
    // Reset flag counter.
882
    flag = 0;
883
  }
884
  else
885
    return;
886
 
887
  // UNUSED, but required.
888
  ignore = 0;
889
  return;
890
}
891
 
892
void I_SoundDelTimer()
893
{
894
  // Debug.
895
  //if ( I_SoundSetTimer( 0 ) == -1)
896
  //  fprintf( stderr, "I_SoundDelTimer: failed to remove interrupt. Doh!\n");
897
}
898