71
71
//e6y
72
72
#include "e6y.h"
73
73
74
+ #include "dsda/ambient.h"
74
75
#include "dsda/settings.h"
75
76
76
77
static dboolean registered_non_rw = false;
@@ -195,7 +196,7 @@ static Uint8 *ConvertAudioFormat(void **data, SDL_AudioSpec *sample, Uint32 *len
195
196
typedef struct snd_data_s
196
197
{
197
198
int sfxid ;
198
- const unsigned char * data ;
199
+ unsigned char * data ;
199
200
int samplelen ;
200
201
int samplerate ;
201
202
struct snd_data_s * next ;
@@ -264,15 +265,85 @@ static snd_data_t *GetSndData(int sfxid, const unsigned char *data, size_t len)
264
265
return target ;
265
266
}
266
267
268
+ #define FADETIME 1000 // microseconds
269
+
270
+ static void FadeInOutMono16 (short * data , int len , int rate )
271
+ {
272
+ const int fadelen = rate * FADETIME / 1000000 ;
273
+ int i ;
274
+
275
+ if (len < fadelen )
276
+ return ;
277
+
278
+ if (data [0 ] != 0 )
279
+ {
280
+ for (i = 0 ; i < fadelen ; i ++ )
281
+ {
282
+ data [i ] = data [i ] * i / fadelen ;
283
+ }
284
+ }
285
+
286
+ if (data [len - 1 ] != 0 )
287
+ {
288
+ for (i = 0 ; i < fadelen ; i ++ )
289
+ {
290
+ data [len - 1 - i ] = data [len - 1 - i ] * i / fadelen ;
291
+ }
292
+ }
293
+ }
294
+
295
+ static void FadeInOutMono8 (byte * data , int len , int rate )
296
+ {
297
+ const int fadelen = rate * FADETIME / 1000000 ;
298
+ int i ;
299
+
300
+ if (len < fadelen )
301
+ return ;
302
+
303
+ if (data [0 ] != 128 )
304
+ {
305
+ for (i = 0 ; i < fadelen ; i ++ )
306
+ {
307
+ data [i ] = (data [i ] - 128 ) * i / fadelen + 128 ;
308
+ }
309
+ }
310
+
311
+ if (data [len - 1 ] != 128 )
312
+ {
313
+ for (i = 0 ; i < fadelen ; i ++ )
314
+ {
315
+ data [len - 1 - i ] = (data [len - 1 - i ] - 128 ) * i / fadelen + 128 ;
316
+ }
317
+ }
318
+ }
319
+
267
320
#define DMXHDRSIZE 8
268
321
#define DMXPADSIZE 16
269
322
323
+ INLINE static int GetDMXSampleRate (const byte * data )
324
+ {
325
+ return ((data [3 ] << 8 ) | data [2 ]);
326
+ }
327
+
328
+ INLINE static dboolean IsValidDMXSound (int dmx_len , int len )
329
+ {
330
+ // Don't play DMX format sound lumps that think they're longer than they
331
+ // really are, only contain padding, or are shorter than the padding size.
332
+ return (dmx_len <= len - DMXHDRSIZE && dmx_len > DMXPADSIZE * 2 );
333
+ }
334
+
335
+ INLINE static int GetDMXLength (const byte * data )
336
+ {
337
+ // Read the encoded number of samples. This value includes padding.
338
+ return ((data [7 ] << 24 ) | (data [6 ] << 16 ) | (data [5 ] << 8 ) | data [4 ]);
339
+ }
340
+
270
341
INLINE static dboolean IsDMXSound (const byte * data , int len )
271
342
{
272
343
return len > DMXHDRSIZE && data [0 ] == 0x03 && data [1 ] == 0x00 ;
273
344
}
274
345
275
- static void CacheSounds (void )
346
+ void I_CacheSounds (void )
276
347
{
277
348
int id ;
278
349
for (id = 1 ; id < num_sfx ; id ++ )
@@ -283,8 +354,29 @@ static void CacheSounds(void)
283
354
const byte * data = W_LumpByNum (lump );
284
355
int len = W_LumpLength (lump );
285
356
286
- if (!IsDMXSound (data , len ))
287
- GetSndData (id , data , len );
357
+ if (IsDMXSound (data , len ))
358
+ {
359
+ int dmx_len = GetDMXLength (data );
360
+
361
+ if (IsValidDMXSound (dmx_len , len ) && !dsda_IsLoopingAmbientSFX (id ))
362
+ {
363
+ const int dmx_rate = GetDMXSampleRate (data );
364
+ byte * dmx_data = W_GetModifiableLumpData (lump );
365
+ dmx_data = & dmx_data [DMXHDRSIZE + DMXPADSIZE ];
366
+ dmx_len -= DMXPADSIZE * 2 ;
367
+ FadeInOutMono8 (dmx_data , dmx_len , dmx_rate );
368
+ }
369
+ }
370
+ else
371
+ {
372
+ snd_data_t * snd_data = GetSndData (id , data , len );
373
+
374
+ if (snd_data && !dsda_IsLoopingAmbientSFX (id ))
375
+ {
376
+ len = snd_data -> samplelen / sizeof (short );
377
+ FadeInOutMono16 ((short * )snd_data -> data , len , snd_data -> samplerate );
378
+ }
379
+ }
288
380
}
289
381
}
290
382
}
@@ -297,32 +389,16 @@ static void CacheSounds(void)
297
389
// Returns a handle.
298
390
//
299
391
300
- static int addsfx (int sfxid , int channel , const unsigned char * data , size_t len ,
301
- const snd_data_t * snd_data )
392
+ static int addsfx (int sfxid , int channel , const channel_info_t * cinfo )
302
393
{
303
394
channel_info_t * ci = channelinfo + channel ;
304
395
305
396
stopchan (channel );
306
397
307
- if (snd_data )
308
- {
309
- ci -> data = snd_data -> data ;
310
- ci -> enddata = ci -> data + snd_data -> samplelen - 1 ;
311
- ci -> samplerate = snd_data -> samplerate ;
312
- ci -> bits = 16 ;
313
- }
314
- else
315
- {
316
- ci -> data = data ;
317
- /* Set pointer to end of raw data. */
318
- ci -> enddata = ci -> data + len - 1 ;
319
- ci -> samplerate = (ci -> data [3 ] << 8 ) + ci -> data [2 ];
320
- // Skip header and padding before samples.
321
- ci -> data += DMXHDRSIZE + DMXPADSIZE ;
322
- // Skip padding after samples.
323
- ci -> enddata -= DMXPADSIZE ;
324
- ci -> bits = 8 ;
325
- }
398
+ ci -> data = cinfo -> data ;
399
+ ci -> enddata = cinfo -> enddata ;
400
+ ci -> samplerate = cinfo -> samplerate ;
401
+ ci -> bits = cinfo -> bits ;
326
402
327
403
ci -> stepremainder = 0 ;
328
404
// Should be gametic, I presume.
@@ -501,6 +577,7 @@ int I_StartSound(int id, int channel, sfx_params_t *params)
501
577
int lump ;
502
578
size_t len ;
503
579
snd_data_t * snd_data = NULL ;
580
+ channel_info_t cinfo = {0 };
504
581
505
582
if ((channel < 0 ) || (channel >= MAX_CHANNELS ))
506
583
#ifdef RANGECHECK
@@ -527,26 +604,41 @@ int I_StartSound(int id, int channel, sfx_params_t *params)
527
604
528
605
if (IsDMXSound (data , len ))
529
606
{
530
- // Read the encoded number of samples. This value includes padding.
531
- const int num_samples =
532
- (data [7 ] << 24 ) | (data [6 ] << 16 ) | (data [5 ] << 8 ) | data [4 ];
607
+ const int dmx_len = GetDMXLength (data );
533
608
534
- // Don't play DMX format sound lumps that think they're longer than they
535
- // really are, only contain padding, or are shorter than the padding size.
536
- if (num_samples > len - DMXHDRSIZE || num_samples <= DMXPADSIZE * 2 )
609
+ if (IsValidDMXSound (dmx_len , len ))
610
+ {
611
+ cinfo .data = & data [DMXHDRSIZE + DMXPADSIZE ];
612
+ cinfo .enddata = & cinfo .data [dmx_len - DMXPADSIZE * 2 - 1 ];
613
+ cinfo .samplerate = GetDMXSampleRate (data );
614
+ cinfo .bits = 8 ;
615
+ }
616
+ else
617
+ {
537
618
return -1 ;
619
+ }
538
620
}
539
621
else
540
622
{
541
623
snd_data = GetSndData (id , data , len );
542
- if (!snd_data )
624
+
625
+ if (snd_data )
626
+ {
627
+ cinfo .data = snd_data -> data ;
628
+ cinfo .enddata = & cinfo .data [snd_data -> samplelen - 1 ];
629
+ cinfo .samplerate = snd_data -> samplerate ;
630
+ cinfo .bits = 16 ;
631
+ }
632
+ else
633
+ {
543
634
return -1 ;
635
+ }
544
636
}
545
637
546
638
SDL_LockMutex (sfxmutex );
547
639
548
640
// Returns a handle (not used).
549
- addsfx (id , channel , data , len , snd_data );
641
+ addsfx (id , channel , & cinfo );
550
642
updateSoundParams (channel , params );
551
643
552
644
SDL_UnlockMutex (sfxmutex );
@@ -825,10 +917,6 @@ void I_InitSound(void)
825
917
if (!nomusicparm )
826
918
I_InitMusic ();
827
919
828
- lprintf (LO_DEBUG , " Precaching all sound effects... " );
829
- CacheSounds ();
830
- lprintf (LO_DEBUG , "done\n" );
831
-
832
920
lprintf (LO_DEBUG , "I_InitSound: sound module ready\n" );
833
921
SDL_PauseAudio (0 );
834
922
}
0 commit comments