Subversion Repositories Kolibri OS

Rev

Rev 300 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 300 Rev 333
Line 15... Line 15...
15
// for more details.
15
// for more details.
16
//
16
//
17
// $Log:$
17
// $Log:$
18
//
18
//
19
// DESCRIPTION:
19
// DESCRIPTION:
20
//	System interface for sound.
20
//      System interface for sound.
21
//
21
//
22
//-----------------------------------------------------------------------------
22
//-----------------------------------------------------------------------------
Line 23... Line 23...
23
 
23
 
24
static const char
24
static const char
Line 53... Line 53...
53
//  the size of the 16bit, 2 hardware channel (stereo)
53
//  the size of the 16bit, 2 hardware channel (stereo)
54
//  mixing buffer, and the samplerate of the raw data.
54
//  mixing buffer, and the samplerate of the raw data.
Line 55... Line 55...
55
 
55
 
56
 
56
 
57
// Needed for calling the actual sound output.
57
// Needed for calling the actual sound output.
58
#define SAMPLECOUNT		512
58
#define SAMPLECOUNT             512
59
#define NUM_CHANNELS	16
59
#define NUM_CHANNELS    16
60
// It is 2 for 16bit, and 2 for two channels.
60
// It is 2 for 16bit, and 2 for two channels.
Line 61... Line 61...
61
#define BUFMUL                  4
61
#define BUFMUL                  4
62
#define MIXBUFFERSIZE		(SAMPLECOUNT*BUFMUL)
62
#define MIXBUFFERSIZE           (SAMPLECOUNT*BUFMUL)
Line 63... Line 63...
63
 
63
 
64
#define SAMPLERATE		11025	// Hz
64
#define SAMPLERATE              11025   // Hz
Line 65... Line 65...
65
#define SAMPLESIZE		2   	// 16bit
65
#define SAMPLESIZE              2       // 16bit
66
 
66
 
Line 67... Line 67...
67
// The actual lengths of all sound effects.
67
// The actual lengths of all sound effects.
68
int 		lengths[NUMSFX];
68
int             lengths[NUMSFX];
69
 
69
 
70
// The actual output device.
70
// The actual output device.
71
int	audio_fd;
71
int     audio_fd;
Line 72... Line 72...
72
 
72
 
73
// The global mixing buffer.
73
// The global mixing buffer.
74
// Basically, samples from all active internal channels
74
// Basically, samples from all active internal channels
75
//  are modifed and added, and stored in the buffer
75
//  are modifed and added, and stored in the buffer
Line 76... Line 76...
76
//  that is submitted to the audio device.
76
//  that is submitted to the audio device.
77
signed short	mixbuffer[MIXBUFFERSIZE];
77
signed short    mixbuffer[MIXBUFFERSIZE];
78
 
78
 
Line 79... Line 79...
79
 
79
 
80
// The channel step amount...
80
// The channel step amount...
81
unsigned int	channelstep[NUM_CHANNELS];
81
unsigned int    channelstep[NUM_CHANNELS];
82
// ... and a 0.16 bit remainder of last step.
82
// ... and a 0.16 bit remainder of last step.
83
unsigned int	channelstepremainder[NUM_CHANNELS];
83
unsigned int    channelstepremainder[NUM_CHANNELS];
84
 
84
 
Line 85... Line 85...
85
 
85
 
86
// The channel data pointers, start and end.
86
// The channel data pointers, start and end.
87
unsigned char*	channels[NUM_CHANNELS];
87
unsigned char*  channels[NUM_CHANNELS];
88
unsigned char*	channelsend[NUM_CHANNELS];
88
unsigned char*  channelsend[NUM_CHANNELS];
89
 
89
 
Line 90... Line 90...
90
 
90
 
91
// Time/gametic that the channel started playing,
91
// Time/gametic that the channel started playing,
92
//  used to determine oldest, which automatically
92
//  used to determine oldest, which automatically
Line 93... Line 93...
93
//  has lowest priority.
93
//  has lowest priority.
94
// In case number of active sounds exceeds
94
// In case number of active sounds exceeds
Line 95... Line 95...
95
//  available channels.
95
//  available channels.
96
int		channelstart[NUM_CHANNELS];
96
int             channelstart[NUM_CHANNELS];
Line 97... Line 97...
97
 
97
 
98
// The sound in channel handles,
98
// The sound in channel handles,
99
//  determined on registration,
99
//  determined on registration,
Line 100... Line 100...
100
//  might be used to unregister/stop/modify,
100
//  might be used to unregister/stop/modify,
101
//  currently unused.
101
//  currently unused.
102
int 		channelhandles[NUM_CHANNELS];
102
int             channelhandles[NUM_CHANNELS];
Line 153... Line 153...
153
    size = W_LumpLength( sfxlump );
153
    size = W_LumpLength( sfxlump );
Line 154... Line 154...
154
 
154
 
155
    // Debug.
155
    // Debug.
156
    // fprintf( stderr, "." );
156
    // fprintf( stderr, "." );
157
    //fprintf( stderr, " -loading  %s (lump %d, %d bytes)\n",
157
    //fprintf( stderr, " -loading  %s (lump %d, %d bytes)\n",
158
    //	     sfxname, sfxlump, size );
158
    //       sfxname, sfxlump, size );
Line 159... Line 159...
159
    //fflush( stderr );
159
    //fflush( stderr );
Line 160... Line 160...
160
    
160
    
Line 191... Line 191...
191
//  which is maintained as a given number
191
//  which is maintained as a given number
192
//  (eight, usually) of internal channels.
192
//  (eight, usually) of internal channels.
193
// Returns a handle.
193
// Returns a handle.
194
//
194
//
Line 195... Line 195...
195
 
195
 
Line 196... Line 196...
196
static unsigned short	handlenums = 0;
196
static unsigned short   handlenums = 0;
197
 
197
 
Line 198... Line 198...
198
int addsfx(int sfxid, int volume, int step, int seperation)
198
int addsfx(int sfxid, int volume, int step, int seperation)
199
{
199
{
Line 200... Line 200...
200
 
200
 
201
    int		i;
201
    int         i;
202
    int		rc = -1;
202
    int         rc = -1;
Line 203... Line 203...
203
    
203
    
204
    int		oldest = gametic;
204
    int         oldest = gametic;
Line 205... Line 205...
205
    int		oldestnum = 0;
205
    int         oldestnum = 0;
206
    int		slot;
206
    int         slot;
207
 
207
 
208
    int		rightvol;
208
    int         rightvol;
209
    int		leftvol;
209
    int         leftvol;
210
 
210
 
211
    // Chainsaw troubles.
211
    // Chainsaw troubles.
212
    // Play these sound effects only one at a time.
212
    // Play these sound effects only one at a time.
213
    if ( sfxid == sfx_sawup
213
    if ( sfxid == sfx_sawup
214
	 || sfxid == sfx_sawidl
214
         || sfxid == sfx_sawidl
215
	 || sfxid == sfx_sawful
215
         || sfxid == sfx_sawful
216
	 || sfxid == sfx_sawhit
216
         || sfxid == sfx_sawhit
217
	 || sfxid == sfx_stnmov
217
         || sfxid == sfx_stnmov
218
	 || sfxid == sfx_pistol	 )
218
         || sfxid == sfx_pistol  )
219
    {
219
    {
220
	// Loop all channels, check.
220
        // Loop all channels, check.
221
	for (i=0 ; i
221
        for (i=0 ; i
222
	{
222
        {
223
	    // Active, and using the same SFX?
223
            // Active, and using the same SFX?
224
	    if ( (channels[i])
224
            if ( (channels[i])
225
		 && (channelids[i] == sfxid) )
225
                 && (channelids[i] == sfxid) )
226
	    {
226
            {
227
		// Reset.
227
                // Reset.
228
		channels[i] = 0;
228
                channels[i] = 0;
Line 229... Line 229...
229
		// We are sure that iff,
229
                // We are sure that iff,
230
		//  there will only be one.
230
                //  there will only be one.
231
		break;
231
                break;
232
	    }
232
            }
233
	}
233
        }
234
    }
234
    }
235
 
235
 
236
    // Loop all channels to find oldest SFX.
236
    // Loop all channels to find oldest SFX.
237
    for (i=0; (i
237
    for (i=0; (i
Line 238... Line 238...
238
    {
238
    {
239
	if (channelstart[i] < oldest)
239
        if (channelstart[i] < oldest)
240
	{
240
        {
241
	    oldestnum = i;
241
            oldestnum = i;
242
	    oldest = channelstart[i];
242
            oldest = channelstart[i];
243
	}
243
        }
244
    }
244
    }
245
 
245
 
Line 246... Line 246...
246
    // Tales from the cryptic.
246
    // Tales from the cryptic.
247
    // If we found a channel, fine.
247
    // If we found a channel, fine.
248
    // If not, we simply overwrite the first one, 0.
248
    // If not, we simply overwrite the first one, 0.
249
    // Probably only happens at startup.
249
    // Probably only happens at startup.
250
    if (i == NUM_CHANNELS)
250
    if (i == NUM_CHANNELS)
251
	slot = oldestnum;
251
        slot = oldestnum;
Line 252... Line 252...
252
    else
252
    else
253
	slot = i;
253
        slot = i;
254
 
254
 
Line 255... Line 255...
255
    // Okay, in the less recent channel,
255
    // Okay, in the less recent channel,
256
    //  we will handle the new SFX.
256
    //  we will handle the new SFX.
257
    // Set pointer to raw data.
257
    // Set pointer to raw data.
Line 280... Line 280...
280
    volume *=7; 
280
    volume *=7; 
281
    // Per left/right channel.
281
    // Per left/right channel.
282
    //  x^2 seperation,
282
    //  x^2 seperation,
283
    //  adjust volume properly.
283
    //  adjust volume properly.
284
    leftvol =
284
    leftvol =
285
	volume - ((volume*seperation*seperation) >> 16); ///(256*256);
285
        volume - ((volume*seperation*seperation) >> 16); ///(256*256);
286
    seperation = seperation - 257;
286
    seperation = seperation - 257;
287
    rightvol =
287
    rightvol =
288
	volume - ((volume*seperation*seperation) >> 16);	
288
        volume - ((volume*seperation*seperation) >> 16);        
Line 289... Line 289...
289
 
289
 
290
    // Sanity check, clamp volume.
290
    // Sanity check, clamp volume.
291
    if (rightvol < 0 || rightvol > 127)
291
    if (rightvol < 0 || rightvol > 127)
Line 292... Line 292...
292
	I_Error("rightvol out of bounds");
292
        I_Error("rightvol out of bounds");
293
    
293
    
Line 294... Line 294...
294
    if (leftvol < 0 || leftvol > 127)
294
    if (leftvol < 0 || leftvol > 127)
295
	I_Error("leftvol out of bounds");
295
        I_Error("leftvol out of bounds");
296
    
296
    
297
    // Get the proper lookup table piece
297
    // Get the proper lookup table piece
Line 319... Line 319...
319
void I_SetChannels()
319
void I_SetChannels()
320
{
320
{
321
  // Init internal lookups (raw data, mixing buffer, channels).
321
  // Init internal lookups (raw data, mixing buffer, channels).
322
  // This function sets up internal lookups used during
322
  // This function sets up internal lookups used during
323
  //  the mixing process. 
323
  //  the mixing process. 
324
  int		i;
324
  int           i;
325
  int		j;
325
  int           j;
Line 326... Line 326...
326
    
326
    
Line 327... Line 327...
327
  int*	steptablemid = steptable + 128;
327
  int*  steptablemid = steptable + 128;
328
  
328
  
329
  // Okay, reset internal mixing channels to zero.
329
  // Okay, reset internal mixing channels to zero.
330
  for (i=0; i
330
  for (i=0; i
331
  {
331
  {
Line 332... Line 332...
332
    channels[i] = 0;
332
    channels[i] = 0;
333
  }
333
  }
Line 334... Line 334...
334
 
334
 
335
  for (i=-128 ; i<128 ; i++)
335
//  for (i=-128 ; i<128 ; i++)
336
    steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0);
336
//    steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0);
337
  
337
  
338
  // Generates volume lookup tables
338
  // Generates volume lookup tables
339
  //  which also turn the unsigned samples
339
  //  which also turn the unsigned samples
340
  //  into signed samples.
340
  //  into signed samples.
Line 341... Line 341...
341
  for (i=0 ; i<128 ; i++)
341
  for (i=0 ; i<128 ; i++)
342
    for (j=0 ; j<256 ; j++)
342
    for (j=0 ; j<256 ; j++)
343
      vol_lookup[i*256+j] = (i*(j-128)*256)/127;
343
      vol_lookup[i*256+j] = (i*(j-128)*256)/127;
Line 426... Line 426...
426
void I_UpdateSound( void )
426
void I_UpdateSound( void )
427
{
427
{
Line 428... Line 428...
428
  
428
  
429
  // Mix current sound data.
429
  // Mix current sound data.
430
  // Data, from raw sound, for right and left.
430
  // Data, from raw sound, for right and left.
431
  register unsigned int	sample;
431
  register unsigned int sample;
432
  register int		dl;
432
  register int          dl;
Line 433... Line 433...
433
  register int		dr;
433
  register int          dr;
434
  
434
  
435
  // Pointers in global mixbuffer, left, right, end.
435
  // Pointers in global mixbuffer, left, right, end.
436
  signed short*		leftout;
436
  signed short*         leftout;
437
  signed short*		rightout;
437
  signed short*         rightout;
438
  signed short*		leftend;
438
  signed short*         leftend;
Line 439... Line 439...
439
  // Step in mixbuffer, left and right, thus two.
439
  // Step in mixbuffer, left and right, thus two.
440
  int				step;
440
  int                           step;
Line 441... Line 441...
441
 
441
 
442
  // Mixing channel index.
442
  // Mixing channel index.
443
  int				chan;
443
  int                           chan;
444
    
444
    
Line 455... Line 455...
455
    // Mix sounds into the mixing buffer.
455
    // Mix sounds into the mixing buffer.
456
    // Loop over step*SAMPLECOUNT,
456
    // Loop over step*SAMPLECOUNT,
457
    //  that is 512 values for two channels.
457
    //  that is 512 values for two channels.
458
    while (leftout != leftend)
458
    while (leftout != leftend)
459
    {
459
    {
460
	// Reset left/right value. 
460
        // Reset left/right value. 
461
	dl = 0;
461
        dl = 0;
462
	dr = 0;
462
        dr = 0;
463
 
463
 
464
	// Love thy L2 chache - made this a loop.
464
        // Love thy L2 chache - made this a loop.
465
	// Now more channels could be set at compile time
465
        // Now more channels could be set at compile time
466
	//  as well. Thus loop those  channels.
466
        //  as well. Thus loop those  channels.
467
	for ( chan = 0; chan < NUM_CHANNELS; chan++ )
467
        for ( chan = 0; chan < NUM_CHANNELS; chan++ )
468
	{
468
        {
469
	    // Check channel, if active.
469
            // Check channel, if active.
470
	    if (channels[ chan ])
470
            if (channels[ chan ])
471
	    {
471
            {
472
		// Get the raw data from the channel. 
472
                // Get the raw data from the channel. 
473
		sample = *channels[ chan ];
473
                sample = *channels[ chan ];
474
		// Add left and right part
474
                // Add left and right part
475
		//  for this channel (sound)
475
                //  for this channel (sound)
476
		//  to the current data.
476
                //  to the current data.
477
		// Adjust volume accordingly.
477
                // Adjust volume accordingly.
478
		dl += channelleftvol_lookup[ chan ][sample];
478
                dl += channelleftvol_lookup[ chan ][sample];
479
		dr += channelrightvol_lookup[ chan ][sample];
479
                dr += channelrightvol_lookup[ chan ][sample];
480
	
480
        
481
		channelstepremainder[ chan ] += channelstep[ chan ];
481
                channelstepremainder[ chan ] += channelstep[ chan ];
482
	
482
        
483
		channels[ chan ] += channelstepremainder[ chan ] >> 16;
483
                channels[ chan ] += channelstepremainder[ chan ] >> 16;
484
	
484
        
485
		channelstepremainder[ chan ] &= 65536-1;
485
                channelstepremainder[ chan ] &= 65536-1;
486
 
486
 
487
		// Check whether we are done.
487
                // Check whether we are done.
488
		if (channels[ chan ] >= channelsend[ chan ])
488
                if (channels[ chan ] >= channelsend[ chan ])
489
		    channels[ chan ] = 0;
489
                    channels[ chan ] = 0;
490
	    }
490
            }
491
	}
491
        }
492
	
492
        
493
	// Clamp to range. Left hardware channel.
493
        // Clamp to range. Left hardware channel.
494
	// Has been char instead of short.
494
        // Has been char instead of short.
495
	// if (dl > 127) *leftout = 127;
495
        // if (dl > 127) *leftout = 127;
496
	// else if (dl < -128) *leftout = -128;
496
        // else if (dl < -128) *leftout = -128;
497
	// else *leftout = dl;
497
        // else *leftout = dl;
498
 
498
 
499
	if (dl > 0x7fff)
499
        if (dl > 0x7fff)
500
	    *leftout = 0x7fff;
500
            *leftout = 0x7fff;
501
	else if (dl < -0x8000)
501
        else if (dl < -0x8000)
502
	    *leftout = -0x8000;
502
            *leftout = -0x8000;
503
	else
503
        else
504
	    *leftout = dl;
504
            *leftout = dl;
505
 
505
 
506
	// Same for right hardware channel.
506
        // Same for right hardware channel.
507
	if (dr > 0x7fff)
507
        if (dr > 0x7fff)
508
	    *rightout = 0x7fff;
508
            *rightout = 0x7fff;
509
	else if (dr < -0x8000)
509
        else if (dr < -0x8000)
510
	    *rightout = -0x8000;
510
            *rightout = -0x8000;
511
	else
511
        else
512
	    *rightout = dr;
512
            *rightout = dr;
513
 
513
 
514
	// Increment current pointers in mixbuffer.
514
        // Increment current pointers in mixbuffer.
515
	leftout += step;
515
        leftout += step;
516
	rightout += step;
516
        rightout += step;
517
    }
517
    }
518
    I_SubmitSound(mixbuffer);
518
 //   I_SubmitSound(mixbuffer);
519
}
519
}
Line 520... Line 520...
520
 
520
 
521
 
521
 
Line 575... Line 575...
575
    // Alias? Example is the chaingun sound linked to pistol.
575
    // Alias? Example is the chaingun sound linked to pistol.
576
    if (!S_sfx[i].link)
576
    if (!S_sfx[i].link)
577
    {
577
    {
578
      // Load data from WAD file.
578
      // Load data from WAD file.
579
      S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] );
579
      S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] );
580
    }	
580
    }   
581
    else
581
    else
582
    {
582
    {
583
      // Previously loaded already?
583
      // Previously loaded already?
584
      S_sfx[i].data = S_sfx[i].link->data;
584
      S_sfx[i].data = S_sfx[i].link->data;
585
      lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
585
      lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
Line 601... Line 601...
601
//
601
//
602
// MUSIC API.
602
// MUSIC API.
603
// Still no music done.
603
// Still no music done.
604
// Remains. Dummies.
604
// Remains. Dummies.
605
//
605
//
606
void I_InitMusic(void)		{ }
606
void I_InitMusic(void)          { }
607
void I_ShutdownMusic(void)	{ }
607
void I_ShutdownMusic(void)      { }
Line 608... Line 608...
608
 
608
 
609
static int	looping=0;
609
static int      looping=0;
Line 610... Line 610...
610
static int	musicdies=-1;
610
static int      musicdies=-1;
611
 
611
 
612
void I_PlaySong(int handle, int looping)
612
void I_PlaySong(int handle, int looping)
613
{
613
{