Subversion Repositories Kolibri OS

Rev

Rev 374 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 374 Rev 376
1
// Emacs style mode select   -*- C++ -*- 
1
// Emacs style mode select   -*- C++ -*- 
2
//-----------------------------------------------------------------------------
2
//-----------------------------------------------------------------------------
3
//
3
//
4
// $Id:$
4
// $Id:$
5
//
5
//
6
// Copyright (C) 1993-1996 by id Software, Inc.
6
// Copyright (C) 1993-1996 by id Software, Inc.
7
//
7
//
8
// This source is available for distribution and/or modification
8
// This source is available for distribution and/or modification
9
// only under the terms of the DOOM Source Code License as
9
// only under the terms of the DOOM Source Code License as
10
// published by id Software. All rights reserved.
10
// published by id Software. All rights reserved.
11
//
11
//
12
// The source is distributed in the hope that it will be useful,
12
// The source is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
14
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
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
//-----------------------------------------------------------------------------
23
 
23
 
24
static const char
24
static const char
25
rcsid[] = "$Id: i_unix.c,v 1.5 1997/02/03 22:45:10 b1 Exp $";
25
rcsid[] = "$Id: i_unix.c,v 1.5 1997/02/03 22:45:10 b1 Exp $";
26
 
26
 
27
#include 
27
#include 
28
#include 
28
#include 
29
#include 
29
#include 
30
 
30
 
31
#include 
31
#include 
32
 
32
 
33
#include 
33
#include 
34
 
34
 
35
#include 
35
#include 
36
 
36
 
37
// Timer stuff. Experimental.
37
// Timer stuff. Experimental.
38
#include 
38
#include 
39
#include 
39
#include 
40
 
40
 
41
#include "z_zone.h"
41
#include "z_zone.h"
42
 
42
 
43
#include "i_system.h"
43
#include "i_system.h"
44
#include "i_sound.h"
44
#include "i_sound.h"
45
#include "m_argv.h"
45
#include "m_argv.h"
46
#include "m_misc.h"
46
#include "m_misc.h"
47
#include "w_wad.h"
47
#include "w_wad.h"
48
 
48
 
49
#include "doomdef.h"
49
#include "doomdef.h"
50
 
50
 
51
#include "kolibri.h"
51
#include "kolibri.h"
52
#include "sound.h"
52
#include "sound.h"
53
 
53
 
54
// The number of internal mixing channels,
54
// The number of internal mixing channels,
55
//  the samples calculated for each mixing step,
55
//  the samples calculated for each mixing step,
56
//  the size of the 16bit, 2 hardware channel (stereo)
56
//  the size of the 16bit, 2 hardware channel (stereo)
57
//  mixing buffer, and the samplerate of the raw data.
57
//  mixing buffer, and the samplerate of the raw data.
58
 
58
 
59
 
59
 
60
// Needed for calling the actual sound output.
60
// Needed for calling the actual sound output.
61
#define SAMPLECOUNT     1024
61
#define SAMPLECOUNT     1024
62
#define NUM_CHANNELS    16
62
#define NUM_CHANNELS    16
63
// It is 2 for 16bit, and 2 for two channels.
63
// It is 2 for 16bit, and 2 for two channels.
64
//#define BUFMUL          4
64
//#define BUFMUL          4
65
//#define MIXBUFFERSIZE           (SAMPLECOUNT*BUFMUL)
65
//#define MIXBUFFERSIZE           (SAMPLECOUNT*BUFMUL)
66
 
66
 
67
#define SAMPLERATE      11025   // Hz
67
#define SAMPLERATE      11025   // Hz
68
#define SAMPLESIZE      2       // 16bit
68
#define SAMPLESIZE      2       // 16bit
69
 
69
 
70
// The actual lengths of all sound effects.
70
// The actual lengths of all sound effects.
71
int             lengths[NUMSFX];
71
int             lengths[NUMSFX];
72
 
72
 
73
// The actual output device.
73
// The actual output device.
74
int     audio_fd;
74
int     audio_fd;
75
 
75
 
76
// The global mixing buffer.
76
// The global mixing buffer.
77
// Basically, samples from all active internal channels
77
// Basically, samples from all active internal channels
78
//  are modifed and added, and stored in the buffer
78
//  are modifed and added, and stored in the buffer
79
//  that is submitted to the audio device.
79
//  that is submitted to the audio device.
80
signed short    *mixbuffer;
80
signed short    *mixbuffer;
81
 
81
 
82
// The channel step amount...
82
// The channel step amount...
83
unsigned int    channelstep[NUM_CHANNELS];
83
unsigned int    channelstep[NUM_CHANNELS];
84
// ... and a 0.16 bit remainder of last step.
84
// ... and a 0.16 bit remainder of last step.
85
unsigned int    channelstepremainder[NUM_CHANNELS];
85
unsigned int    channelstepremainder[NUM_CHANNELS];
86
 
86
 
87
 
87
 
88
// The channel data pointers, start and end.
88
// The channel data pointers, start and end.
89
unsigned char*  channels[NUM_CHANNELS];
89
unsigned char*  channels[NUM_CHANNELS];
90
unsigned char*  channelsend[NUM_CHANNELS];
90
unsigned char*  channelsend[NUM_CHANNELS];
91
 
91
 
92
 
92
 
93
// Time/gametic that the channel started playing,
93
// Time/gametic that the channel started playing,
94
//  used to determine oldest, which automatically
94
//  used to determine oldest, which automatically
95
//  has lowest priority.
95
//  has lowest priority.
96
// In case number of active sounds exceeds
96
// In case number of active sounds exceeds
97
//  available channels.
97
//  available channels.
98
int             channelstart[NUM_CHANNELS];
98
int             channelstart[NUM_CHANNELS];
99
 
99
 
100
// The sound in channel handles,
100
// The sound in channel handles,
101
//  determined on registration,
101
//  determined on registration,
102
//  might be used to unregister/stop/modify,
102
//  might be used to unregister/stop/modify,
103
//  currently unused.
103
//  currently unused.
104
int             channelhandles[NUM_CHANNELS];
104
int             channelhandles[NUM_CHANNELS];
105
 
105
 
106
// SFX id of the playing sound effect.
106
// SFX id of the playing sound effect.
107
// Used to catch duplicates (like chainsaw).
107
// Used to catch duplicates (like chainsaw).
108
int             channelids[NUM_CHANNELS];                       
108
int             channelids[NUM_CHANNELS];                       
109
 
109
 
110
// Pitch to stepping lookup, unused.
110
// Pitch to stepping lookup, unused.
111
int             steptable[256];
111
int             steptable[256];
112
 
112
 
113
// Volume lookups.
113
// Volume lookups.
114
int             vol_lookup[128*256];
114
int             vol_lookup[128*256];
115
 
115
 
116
// Hardware left and right channel volume lookup.
116
// Hardware left and right channel volume lookup.
117
int*            channelleftvol_lookup[NUM_CHANNELS];
117
int*            channelleftvol_lookup[NUM_CHANNELS];
118
int*            channelrightvol_lookup[NUM_CHANNELS];
118
int*            channelrightvol_lookup[NUM_CHANNELS];
119
 
119
 
120
 
120
 
121
//
121
//
122
// This function loads the sound data from the WAD lump,
122
// This function loads the sound data from the WAD lump,
123
//  for single sound.
123
//  for single sound.
124
//
124
//
125
void* getsfx (char* sfxname, int* len)
125
void* getsfx (char* sfxname, int* len)
126
{
126
{
127
  unsigned char*      sfx;
127
  unsigned char*      sfx;
128
  unsigned char*      paddedsfx;
128
  unsigned char*      paddedsfx;
129
  int                 i;
129
  int                 i;
130
  int                 size;
130
  int                 size;
131
  int                 paddedsize;
131
  int                 paddedsize;
132
  char                name[20];
132
  char                name[20];
133
  int                 sfxlump;
133
  int                 sfxlump;
134
 
134
 
135
    
135
    
136
    // Get the sound data from the WAD, allocate lump
136
    // Get the sound data from the WAD, allocate lump
137
    //  in zone memory.
137
    //  in zone memory.
138
    sprintf(name, "ds%s", sfxname);
138
    sprintf(name, "ds%s", sfxname);
139
 
139
 
140
    // Now, there is a severe problem with the
140
    // Now, there is a severe problem with the
141
    //  sound handling, in it is not (yet/anymore)
141
    //  sound handling, in it is not (yet/anymore)
142
    //  gamemode aware. That means, sounds from
142
    //  gamemode aware. That means, sounds from
143
    //  DOOM II will be requested even with DOOM
143
    //  DOOM II will be requested even with DOOM
144
    //  shareware.
144
    //  shareware.
145
    // The sound list is wired into sounds.c,
145
    // The sound list is wired into sounds.c,
146
    //  which sets the external variable.
146
    //  which sets the external variable.
147
    // I do not do runtime patches to that
147
    // I do not do runtime patches to that
148
    //  variable. Instead, we will use a
148
    //  variable. Instead, we will use a
149
    //  default sound for replacement.
149
    //  default sound for replacement.
150
    if ( W_CheckNumForName(name) == -1 )
150
    if ( W_CheckNumForName(name) == -1 )
151
      sfxlump = W_GetNumForName("dspistol");
151
      sfxlump = W_GetNumForName("dspistol");
152
    else
152
    else
153
      sfxlump = W_GetNumForName(name);
153
      sfxlump = W_GetNumForName(name);
154
    
154
    
155
    size = W_LumpLength( sfxlump );
155
    size = W_LumpLength( sfxlump );
156
 
156
 
157
    // Debug.
157
    // Debug.
158
    // fprintf( stderr, "." );
158
    // fprintf( stderr, "." );
159
    //fprintf( stderr, " -loading  %s (lump %d, %d bytes)\n",
159
    //fprintf( stderr, " -loading  %s (lump %d, %d bytes)\n",
160
    //       sfxname, sfxlump, size );
160
    //       sfxname, sfxlump, size );
161
    //fflush( stderr );
161
    //fflush( stderr );
162
    
162
    
163
    sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC );
163
    sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC );
164
 
164
 
165
    // Pads the sound effect out to the mixing buffer size.
165
    // Pads the sound effect out to the mixing buffer size.
166
    // The original realloc would interfere with zone memory.
166
    // The original realloc would interfere with zone memory.
167
    paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT;
167
    paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT;
168
 
168
 
169
    // Allocate from zone memory.
169
    // Allocate from zone memory.
170
    paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 );
170
    paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 );
171
    // ddt: (unsigned char *) realloc(sfx, paddedsize+8);
171
    // ddt: (unsigned char *) realloc(sfx, paddedsize+8);
172
    // This should interfere with zone memory handling,
172
    // This should interfere with zone memory handling,
173
    //  which does not kick in in the soundserver.
173
    //  which does not kick in in the soundserver.
174
 
174
 
175
    // Now copy and pad.
175
    // Now copy and pad.
176
    memcpy(  paddedsfx, sfx, size );
176
    memcpy(  paddedsfx, sfx, size );
177
    for (i=size ; i
177
    for (i=size ; i
178
        paddedsfx[i] = 128;
178
        paddedsfx[i] = 128;
179
 
179
 
180
    // Remove the cached lump.
180
    // Remove the cached lump.
181
    Z_Free( sfx );
181
    Z_Free( sfx );
182
    
182
    
183
    // Preserve padded length.
183
    // Preserve padded length.
184
    *len = paddedsize;
184
    *len = paddedsize;
185
 
185
 
186
    // Return allocated padded data.
186
    // Return allocated padded data.
187
    return (void *) (paddedsfx + 8);
187
    return (void *) (paddedsfx + 8);
188
}
188
}
189
 
189
 
190
//
190
//
191
// This function adds a sound to the
191
// This function adds a sound to the
192
//  list of currently active sounds,
192
//  list of currently active sounds,
193
//  which is maintained as a given number
193
//  which is maintained as a given number
194
//  (eight, usually) of internal channels.
194
//  (eight, usually) of internal channels.
195
// Returns a handle.
195
// Returns a handle.
196
//
196
//
197
 
197
 
198
static unsigned short   handlenums = 0;
198
static unsigned short   handlenums = 0;
199
 
199
 
200
int addsfx(int sfxid, int volume, int step, int seperation)
200
int addsfx(int sfxid, int volume, int step, int seperation)
201
{
201
{
202
 
202
 
203
    int         i;
203
    int         i;
204
    int         rc = -1;
204
    int         rc = -1;
205
    
205
    
206
    int         oldest = gametic;
206
    int         oldest = gametic;
207
    int         oldestnum = 0;
207
    int         oldestnum = 0;
208
    int         slot;
208
    int         slot;
209
 
209
 
210
    int         rightvol;
210
    int         rightvol;
211
    int         leftvol;
211
    int         leftvol;
212
 
212
 
213
    // Chainsaw troubles.
213
    // Chainsaw troubles.
214
    // Play these sound effects only one at a time.
214
    // Play these sound effects only one at a time.
215
    if ( sfxid == sfx_sawup
215
    if ( sfxid == sfx_sawup
216
         || sfxid == sfx_sawidl
216
         || sfxid == sfx_sawidl
217
         || sfxid == sfx_sawful
217
         || sfxid == sfx_sawful
218
         || sfxid == sfx_sawhit
218
         || sfxid == sfx_sawhit
219
         || sfxid == sfx_stnmov
219
         || sfxid == sfx_stnmov
220
         || sfxid == sfx_pistol  )
220
         || sfxid == sfx_pistol  )
221
    {
221
    {
222
        // Loop all channels, check.
222
        // Loop all channels, check.
223
        for (i=0 ; i
223
        for (i=0 ; i
224
        {
224
        {
225
            // Active, and using the same SFX?
225
            // Active, and using the same SFX?
226
            if ( (channels[i])
226
            if ( (channels[i])
227
                 && (channelids[i] == sfxid) )
227
                 && (channelids[i] == sfxid) )
228
            {
228
            {
229
                // Reset.
229
                // Reset.
230
                channels[i] = 0;
230
                channels[i] = 0;
231
                // We are sure that iff,
231
                // We are sure that iff,
232
                //  there will only be one.
232
                //  there will only be one.
233
                break;
233
                break;
234
            }
234
            }
235
        }
235
        }
236
    }
236
    }
237
 
237
 
238
    // Loop all channels to find oldest SFX.
238
    // Loop all channels to find oldest SFX.
239
    for (i=0; (i
239
    for (i=0; (i
240
    {
240
    {
241
        if (channelstart[i] < oldest)
241
        if (channelstart[i] < oldest)
242
        {
242
        {
243
            oldestnum = i;
243
            oldestnum = i;
244
            oldest = channelstart[i];
244
            oldest = channelstart[i];
245
        }
245
        }
246
    }
246
    }
247
 
247
 
248
    // Tales from the cryptic.
248
    // Tales from the cryptic.
249
    // If we found a channel, fine.
249
    // If we found a channel, fine.
250
    // If not, we simply overwrite the first one, 0.
250
    // If not, we simply overwrite the first one, 0.
251
    // Probably only happens at startup.
251
    // Probably only happens at startup.
252
    if (i == NUM_CHANNELS)
252
    if (i == NUM_CHANNELS)
253
        slot = oldestnum;
253
        slot = oldestnum;
254
    else
254
    else
255
        slot = i;
255
        slot = i;
256
 
256
 
257
    // Okay, in the less recent channel,
257
    // Okay, in the less recent channel,
258
    //  we will handle the new SFX.
258
    //  we will handle the new SFX.
259
    // Set pointer to raw data.
259
    // Set pointer to raw data.
260
    channels[slot] = (unsigned char *) S_sfx[sfxid].data;
260
    channels[slot] = (unsigned char *) S_sfx[sfxid].data;
261
    // Set pointer to end of raw data.
261
    // Set pointer to end of raw data.
262
    channelsend[slot] = channels[slot] + lengths[sfxid];
262
    channelsend[slot] = channels[slot] + lengths[sfxid];
263
 
263
 
264
    // Reset current handle number, limited to 0..100.
264
    // Reset current handle number, limited to 0..100.
265
    if (!handlenums)
265
    if (!handlenums)
266
        handlenums = 100;
266
        handlenums = 100;
267
 
267
 
268
    // Assign current handle number.
268
    // Assign current handle number.
269
    // Preserved so sounds could be stopped (unused).
269
    // Preserved so sounds could be stopped (unused).
270
    channelhandles[slot] = rc = handlenums++;
270
    channelhandles[slot] = rc = handlenums++;
271
 
271
 
272
    channelstep[slot] = step;
272
    channelstep[slot] = step;
273
 
273
 
274
    channelstepremainder[slot] = 0;
274
    channelstepremainder[slot] = 0;
275
    // Should be gametic, I presume.
275
    // Should be gametic, I presume.
276
    channelstart[slot] = gametic;
276
    channelstart[slot] = gametic;
277
 
277
 
278
    // Separation, that is, orientation/stereo.
278
    // Separation, that is, orientation/stereo.
279
    //  range is: 1 - 256
279
    //  range is: 1 - 256
280
    seperation += 1;
280
    seperation += 1;
281
 
281
 
282
    volume *=7; 
282
    volume *=7; 
283
    // Per left/right channel.
283
    // Per left/right channel.
284
    //  x^2 seperation,
284
    //  x^2 seperation,
285
    //  adjust volume properly.
285
    //  adjust volume properly.
286
    leftvol =
286
    leftvol =
287
        volume - ((volume*seperation*seperation) >> 16); ///(256*256);
287
        volume - ((volume*seperation*seperation) >> 16); ///(256*256);
288
    seperation = seperation - 257;
288
    seperation = seperation - 257;
289
    rightvol =
289
    rightvol =
290
        volume - ((volume*seperation*seperation) >> 16);        
290
        volume - ((volume*seperation*seperation) >> 16);        
291
 
291
 
292
    // Sanity check, clamp volume.
292
    // Sanity check, clamp volume.
293
    if (rightvol < 0 || rightvol > 127)
293
    if (rightvol < 0 || rightvol > 127)
294
    {
294
    {
295
        printf("rightvol out of bounds\n\r");
295
        printf("rightvol out of bounds\n\r");
296
        rightvol = 0;
296
        rightvol = 0;
297
 
297
 
298
    }
298
    }
299
    
299
    
300
    if (leftvol < 0 || leftvol > 127)
300
    if (leftvol < 0 || leftvol > 127)
301
    {
301
    {
302
        printf("leftvol out of bounds\n\r");
302
        printf("leftvol out of bounds\n\r");
303
        leftvol=0;
303
        leftvol=0;
304
    }
304
    }
305
    
305
    
306
    // Get the proper lookup table piece
306
    // Get the proper lookup table piece
307
    //  for this volume level???
307
    //  for this volume level???
308
    channelleftvol_lookup[slot] = &vol_lookup[leftvol*256];
308
    channelleftvol_lookup[slot] = &vol_lookup[leftvol*256];
309
    channelrightvol_lookup[slot] = &vol_lookup[rightvol*256];
309
    channelrightvol_lookup[slot] = &vol_lookup[rightvol*256];
310
 
310
 
311
    // Preserve sound SFX id,
311
    // Preserve sound SFX id,
312
    //  e.g. for avoiding duplicates of chainsaw.
312
    //  e.g. for avoiding duplicates of chainsaw.
313
    channelids[slot] = sfxid;
313
    channelids[slot] = sfxid;
314
 
314
 
315
    // You tell me.
315
    // You tell me.
316
    return rc;
316
    return rc;
317
}
317
}
318
 
318
 
319
//
319
//
320
// SFX API
320
// SFX API
321
// Note: this was called by S_Init.
321
// Note: this was called by S_Init.
322
// However, whatever they did in the
322
// However, whatever they did in the
323
// old DPMS based DOS version, this
323
// old DPMS based DOS version, this
324
// were simply dummies in the Linux
324
// were simply dummies in the Linux
325
// version.
325
// version.
326
// See soundserver initdata().
326
// See soundserver initdata().
327
//
327
//
328
void I_SetChannels()
328
void I_SetChannels()
329
{
329
{
330
  // Init internal lookups (raw data, mixing buffer, channels).
330
  // Init internal lookups (raw data, mixing buffer, channels).
331
  // This function sets up internal lookups used during
331
  // This function sets up internal lookups used during
332
  //  the mixing process. 
332
  //  the mixing process. 
333
  int           i;
333
  int           i;
334
  int           j;
334
  int           j;
335
    
335
    
336
  int*  steptablemid = steptable + 128;
336
  int*  steptablemid = steptable + 128;
337
  
337
  
338
  // Okay, reset internal mixing channels to zero.
338
  // Okay, reset internal mixing channels to zero.
339
  for (i=0; i
339
  for (i=0; i
340
  {
340
  {
341
    channels[i] = 0;
341
    channels[i] = 0;
342
  }
342
  }
343
 
343
 
344
  for (i=-128 ; i<128 ; i++)
344
  for (i=-128 ; i<128 ; i++)
345
    steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0);
345
    steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0);
346
  
346
  
347
  // Generates volume lookup tables
347
  // Generates volume lookup tables
348
  //  which also turn the unsigned samples
348
  //  which also turn the unsigned samples
349
  //  into signed samples.
349
  //  into signed samples.
350
  for (i=0 ; i<128 ; i++)
350
  for (i=0 ; i<128 ; i++)
351
    for (j=0 ; j<256 ; j++)
351
    for (j=0 ; j<256 ; j++)
352
      vol_lookup[i*256+j] = (i*(j-128)*256)/127;
352
      vol_lookup[i*256+j] = (i*(j-128)*256)/127;
353
}       
353
}       
354
 
354
 
355
 
355
 
356
void I_SetSfxVolume(int volume)
356
void I_SetSfxVolume(int volume)
357
{
357
{
358
  // Identical to DOS.
358
  // Identical to DOS.
359
  // Basically, this should propagate
359
  // Basically, this should propagate
360
  //  the menu/config file setting
360
  //  the menu/config file setting
361
  //  to the state variable used in
361
  //  to the state variable used in
362
  //  the mixing.
362
  //  the mixing.
363
  snd_SfxVolume = volume;
363
  snd_SfxVolume = volume;
364
}
364
}
365
 
365
 
366
// MUSIC API - dummy. Some code from DOS version.
366
// MUSIC API - dummy. Some code from DOS version.
367
void I_SetMusicVolume(int volume)
367
void I_SetMusicVolume(int volume)
368
{
368
{
369
  // Internal state variable.
369
  // Internal state variable.
370
  snd_MusicVolume = volume;
370
  snd_MusicVolume = volume;
371
}
371
}
372
 
372
 
373
 
373
 
374
//
374
//
375
// Retrieve the raw data lump index
375
// Retrieve the raw data lump index
376
//  for a given SFX name.
376
//  for a given SFX name.
377
//
377
//
378
int I_GetSfxLumpNum(sfxinfo_t* sfx)
378
int I_GetSfxLumpNum(sfxinfo_t* sfx)
379
{
379
{
380
    char namebuf[9];
380
    char namebuf[9];
381
    sprintf(namebuf, "ds%s", sfx->name);
381
    sprintf(namebuf, "ds%s", sfx->name);
382
    return W_GetNumForName(namebuf);
382
    return W_GetNumForName(namebuf);
383
}
383
}
384
 
384
 
385
//
385
//
386
// Starting a sound means adding it
386
// Starting a sound means adding it
387
//  to the current list of active sounds
387
//  to the current list of active sounds
388
//  in the internal channels.
388
//  in the internal channels.
389
// As the SFX info struct contains
389
// As the SFX info struct contains
390
//  e.g. a pointer to the raw data,
390
//  e.g. a pointer to the raw data,
391
//  it is ignored.
391
//  it is ignored.
392
// As our sound handling does not handle
392
// As our sound handling does not handle
393
//  priority, it is ignored.
393
//  priority, it is ignored.
394
// Pitching (that is, increased speed of playback)
394
// Pitching (that is, increased speed of playback)
395
//
395
//
396
int I_StartSound(int id, int vol, int sep,
396
int I_StartSound(int id, int vol, int sep,
397
                 int pitch, int priority )
397
                 int pitch, int priority )
398
{
398
{
399
    // Returns a handle (not used).
399
    // Returns a handle (not used).
400
    id = addsfx( id, vol, steptable[pitch], sep );
400
    id = addsfx( id, vol, steptable[pitch], sep );
401
    return id;
401
    return id;
402
}
402
}
403
 
403
 
404
void I_StopSound (int handle)
404
void I_StopSound (int handle)
405
{
405
{
406
  // You need the handle returned by StartSound.
406
  // You need the handle returned by StartSound.
407
  // Would be looping all channels,
407
  // Would be looping all channels,
408
  //  tracking down the handle,
408
  //  tracking down the handle,
409
  //  an setting the channel to zero.
409
  //  an setting the channel to zero.
410
  
410
  
411
  // UNUSED.
411
  // UNUSED.
412
  handle = 0;
412
  handle = 0;
413
}
413
}
414
 
414
 
415
 
415
 
416
int I_SoundIsPlaying(int handle)
416
int I_SoundIsPlaying(int handle)
417
{
417
{
418
    // Ouch.
418
    // Ouch.
419
    return gametic < handle;
419
    return gametic < handle;
420
}
420
}
421
 
421
 
422
//
422
//
423
// This function loops all active (internal) sound
423
// This function loops all active (internal) sound
424
//  channels, retrieves a given number of samples
424
//  channels, retrieves a given number of samples
425
//  from the raw sound data, modifies it according
425
//  from the raw sound data, modifies it according
426
//  to the current (internal) channel parameters,
426
//  to the current (internal) channel parameters,
427
//  mixes the per channel samples into the global
427
//  mixes the per channel samples into the global
428
//  mixbuffer, clamping it to the allowed range,
428
//  mixbuffer, clamping it to the allowed range,
429
//  and sets up everything for transferring the
429
//  and sets up everything for transferring the
430
//  contents of the mixbuffer to the (two)
430
//  contents of the mixbuffer to the (two)
431
//  hardware channels (left and right, that is).
431
//  hardware channels (left and right, that is).
432
//
432
//
433
// This function currently supports only 16bit.
433
// This function currently supports only 16bit.
434
//
434
//
435
 
435
 
436
extern SNDBUF hMixBuff;
436
extern SNDBUF hMixBuff;
437
extern unsigned int mix_offset;
437
extern unsigned int mix_offset;
438
extern int mix_size;
438
extern int mix_size;
439
 
439
 
440
void I_UpdateSound( void )
440
void I_UpdateSound( void )
441
{
441
{
442
  
442
  
443
  // Mix current sound data.
443
  // Mix current sound data.
444
  // Data, from raw sound, for right and left.
444
  // Data, from raw sound, for right and left.
445
  register unsigned int sample;
445
  register unsigned int sample;
446
  register int          dl;
446
  register int          dl;
447
  register int          dr;
447
  register int          dr;
448
  
448
  
449
  // Pointers in global mixbuffer, left, right, end.
449
  // Pointers in global mixbuffer, left, right, end.
450
  signed short*         leftout;
450
  signed short*         leftout;
451
  signed short*         rightout;
451
  signed short*         rightout;
452
//  signed short*         leftend;
452
//  signed short*         leftend;
453
  // Step in mixbuffer, left and right, thus two.
453
  // Step in mixbuffer, left and right, thus two.
454
  int                           step;
454
  int                           step;
455
 
455
 
456
  // Mixing channel index.
456
  // Mixing channel index.
457
  int                           chan;
457
  int                           chan;
458
  int i;
458
  int i;
459
  int flags;
-
 
460
  int size = 0;
-
 
461
    
459
    
462
    // Left and right channel
460
    // Left and right channel
463
    //  are in global mixbuffer, alternating.
461
    //  are in global mixbuffer, alternating.
464
    leftout = mixbuffer;
462
    leftout = mixbuffer;
465
    rightout = mixbuffer+1;
463
    rightout = mixbuffer+1;
466
    step = 2;
464
    step = 2;
467
 
465
 
468
    // Determine end, for left channel only
466
    // Determine end, for left channel only
469
    //  (right channel is implicit).
467
    //  (right channel is implicit).
470
  //  leftend = mixbuffer + SAMPLECOUNT*step;
468
  //  leftend = mixbuffer + SAMPLECOUNT*step;
471
 
469
 
472
    // Mix sounds into the mixing buffer.
470
    // Mix sounds into the mixing buffer.
473
    // Loop over step*SAMPLECOUNT,
471
    // Loop over step*SAMPLECOUNT,
474
    //  that is 512 values for two channels.
472
    //  that is 512 values for two channels.
475
    for (i=0; i < mix_size/4; i++)
473
    for (i=0; i < mix_size/4; i++)
476
    {
474
    {
477
        // Reset left/right value. 
475
        // Reset left/right value. 
478
        dl = 0;
476
        dl = 0;
479
        dr = 0;
477
        dr = 0;
480
 
478
 
481
        // Love thy L2 chache - made this a loop.
479
        // Love thy L2 chache - made this a loop.
482
        // Now more channels could be set at compile time
480
        // Now more channels could be set at compile time
483
        //  as well. Thus loop those  channels.
481
        //  as well. Thus loop those  channels.
484
  //      flags=0;
-
 
485
        
482
        
486
        for ( chan = 0; chan < NUM_CHANNELS; chan++ )
483
        for ( chan = 0; chan < NUM_CHANNELS; chan++ )
487
        {
484
        {
488
            // Check channel, if active.
485
            // Check channel, if active.
489
            if (channels[ chan ])
486
            if (channels[ chan ])
490
            {
487
            {
491
  //              flags=1;
-
 
492
                
-
 
493
                // Get the raw data from the channel. 
488
                // Get the raw data from the channel. 
494
                sample = *channels[ chan ];
489
                sample = *channels[ chan ];
495
                // Add left and right part
490
                // Add left and right part
496
                //  for this channel (sound)
491
                //  for this channel (sound)
497
                //  to the current data.
492
                //  to the current data.
498
                // Adjust volume accordingly.
493
                // Adjust volume accordingly.
499
                dl += channelleftvol_lookup[ chan ][sample];
494
                dl += channelleftvol_lookup[ chan ][sample];
500
                dr += channelrightvol_lookup[ chan ][sample];
495
                dr += channelrightvol_lookup[ chan ][sample];
501
        
496
        
502
                channelstepremainder[ chan ] += channelstep[ chan ];
497
                channelstepremainder[ chan ] += channelstep[ chan ];
503
        
498
        
504
                channels[ chan ] += channelstepremainder[ chan ] >> 16;
499
                channels[ chan ] += channelstepremainder[ chan ] >> 16;
505
        
500
        
506
                channelstepremainder[ chan ] &= 65536-1;
501
                channelstepremainder[ chan ] &= 65536-1;
507
 
502
 
508
                // Check whether we are done.
503
                // Check whether we are done.
509
                if (channels[ chan ] >= channelsend[ chan ])
504
                if (channels[ chan ] >= channelsend[ chan ])
510
                    channels[ chan ] = 0;
505
                    channels[ chan ] = 0;
511
            }
506
            }
512
        }
507
        }
513
        
508
        
514
        // Clamp to range. Left hardware channel.
509
        // Clamp to range. Left hardware channel.
515
        // Has been char instead of short.
510
        // Has been char instead of short.
516
        // if (dl > 127) *leftout = 127;
511
        // if (dl > 127) *leftout = 127;
517
        // else if (dl < -128) *leftout = -128;
512
        // else if (dl < -128) *leftout = -128;
518
        // else *leftout = dl;
513
        // else *leftout = dl;
519
 
514
 
520
        if (dl > 0x7fff)
515
        if (dl > 0x7fff)
521
            *leftout = 0x7fff;
516
            *leftout = 0x7fff;
522
        else if (dl < -0x8000)
517
        else if (dl < -0x8000)
523
            *leftout = -0x8000;
518
            *leftout = -0x8000;
524
        else
519
        else
525
            *leftout = dl;
520
            *leftout = dl;
526
 
521
 
527
        // Same for right hardware channel.
522
        // Same for right hardware channel.
528
        if (dr > 0x7fff)
523
        if (dr > 0x7fff)
529
            *rightout = 0x7fff;
524
            *rightout = 0x7fff;
530
        else if (dr < -0x8000)
525
        else if (dr < -0x8000)
531
            *rightout = -0x8000;
526
            *rightout = -0x8000;
532
        else
527
        else
533
            *rightout = dr;
528
            *rightout = dr;
534
 
529
 
535
        // Increment current pointers in mixbuffer.
530
        // Increment current pointers in mixbuffer.
536
        leftout += step;
531
        leftout += step;
537
        rightout += step;
532
        rightout += step;
538
//        if (flags)
-
 
539
//          size+=4;
-
 
540
    }
533
    }
541
 
534
 
542
    SetBuffer(hMixBuff,mixbuffer,mix_offset,mix_size);
535
    SetBuffer(hMixBuff,mixbuffer,mix_offset,mix_size);
543
 
-
 
544
 
-
 
545
 //   WaveOut(hMixBuff,(char*)&mixbuffer[0],4096);
-
 
546
    
-
 
547
//    if(size)
-
 
548
//    {
-
 
549
//       WaveOut(hMixBuff,(char*)&mixbuffer[0],size);
-
 
550
//       SetBufferPos(hMixBuff, 0);         
-
 
551
//        SetBuffer(hMixBuff,(char*)&mixbuffer[0],mix_offset,4096);
-
 
552
//       PlayBuffer(hMixBuff, PCM_SYNC); 
-
 
553
//    };  
-
 
554
}
536
}
555
 
537
 
556
 
538
 
557
// 
539
// 
558
// This would be used to write out the mixbuffer
540
// This would be used to write out the mixbuffer
559
//  during each game loop update.
541
//  during each game loop update.
560
// Updates sound buffer and audio device at runtime. 
542
// Updates sound buffer and audio device at runtime. 
561
// It is called during Timer interrupt with SNDINTR.
543
// It is called during Timer interrupt with SNDINTR.
562
// Mixing now done synchronous, and
544
// Mixing now done synchronous, and
563
//  only output be done asynchronous?
545
//  only output be done asynchronous?
564
//
546
//
565
//void I_SubmitSound(void)
547
//void I_SubmitSound(void)
566
//{
548
//{
567
  // Write it to DSP device.
549
  // Write it to DSP device.
568
//  write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
550
//  write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
569
//}
551
//}
570
 
552
 
571
 
553
 
572
void I_UpdateSoundParams(int handle, int vol, int sep, int pitch)
554
void I_UpdateSoundParams(int handle, int vol, int sep, int pitch)
573
{
555
{
574
  // I fail too see that this is used.
556
  // I fail too see that this is used.
575
  // Would be using the handle to identify
557
  // Would be using the handle to identify
576
  //  on which channel the sound might be active,
558
  //  on which channel the sound might be active,
577
  //  and resetting the channel parameters.
559
  //  and resetting the channel parameters.
578
 
560
 
579
  // UNUSED.
561
  // UNUSED.
580
  handle = vol = sep = pitch = 0;
562
  handle = vol = sep = pitch = 0;
581
}
563
}
582
 
564
 
583
extern volatile int sound_state;
565
extern volatile int sound_state;
584
 
566
 
585
void I_ShutdownSound(void)
567
void I_ShutdownSound(void)
586
{    
568
{    
587
  sound_state=0;
569
  sound_state=0;
588
  return;
570
  return;
589
}
571
}
590
 
572
 
591
void I_InitSound()
573
void I_InitSound()
592
{ int i;
574
{ int i;
593
 
575
 
594
  printf("I_InitSound: ");
576
  printf("I_InitSound: ");
595
  
577
  
596
  for (i=1 ; i
578
  for (i=1 ; i
597
  { 
579
  { 
598
    // Alias? Example is the chaingun sound linked to pistol.
580
    // Alias? Example is the chaingun sound linked to pistol.
599
    if (!S_sfx[i].link)
581
    if (!S_sfx[i].link)
600
    {
582
    {
601
      // Load data from WAD file.
583
      // Load data from WAD file.
602
      S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] );
584
      S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] );
603
    }   
585
    }   
604
    else
586
    else
605
    {
587
    {
606
      // Previously loaded already?
588
      // Previously loaded already?
607
      S_sfx[i].data = S_sfx[i].link->data;
589
      S_sfx[i].data = S_sfx[i].link->data;
608
      lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
590
      lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
609
    }
591
    }
610
  }
592
  }
611
 
593
 
612
  printf( " pre-cached all sound data\n");
594
  printf( " pre-cached all sound data\n");
613
  
595
  
614
  // Now initialize mixbuffer with zero.
596
  // Now initialize mixbuffer with zero.
615
//  for ( i = 0; i< MIXBUFFERSIZE; i++ )
597
//  for ( i = 0; i< MIXBUFFERSIZE; i++ )
616
 //   mixbuffer[i] = 0;
598
 //   mixbuffer[i] = 0;
617
  
599
  
618
  // Finished initialization.
600
  // Finished initialization.
619
  printf("I_InitSound: sound module ready\n");
601
  printf("I_InitSound: sound module ready\n");
620
    
602
    
621
}
603
}
622
 
604
 
623
 
605
 
624
//
606
//
625
// MUSIC API.
607
// MUSIC API.
626
// Still no music done.
608
// Still no music done.
627
// Remains. Dummies.
609
// Remains. Dummies.
628
//
610
//
629
void I_InitMusic(void)          { }
611
void I_InitMusic(void)          { }
630
void I_ShutdownMusic(void)      { }
612
void I_ShutdownMusic(void)      { }
631
 
613
 
632
static int      looping=0;
614
static int      looping=0;
633
static int      musicdies=-1;
615
static int      musicdies=-1;
634
 
616
 
635
void I_PlaySong(int handle, int looping)
617
void I_PlaySong(int handle, int looping)
636
{
618
{
637
  // UNUSED.
619
  // UNUSED.
638
  handle = looping = 0;
620
  handle = looping = 0;
639
  musicdies = gametic + TICRATE*30;
621
  musicdies = gametic + TICRATE*30;
640
}
622
}
641
 
623
 
642
void I_PauseSong (int handle)
624
void I_PauseSong (int handle)
643
{
625
{
644
  // UNUSED.
626
  // UNUSED.
645
  handle = 0;
627
  handle = 0;
646
}
628
}
647
 
629
 
648
void I_ResumeSong (int handle)
630
void I_ResumeSong (int handle)
649
{
631
{
650
  // UNUSED.
632
  // UNUSED.
651
  handle = 0;
633
  handle = 0;
652
}
634
}
653
 
635
 
654
void I_StopSong(int handle)
636
void I_StopSong(int handle)
655
{
637
{
656
  // UNUSED.
638
  // UNUSED.
657
  handle = 0;
639
  handle = 0;
658
  
640
  
659
  looping = 0;
641
  looping = 0;
660
  musicdies = 0;
642
  musicdies = 0;
661
}
643
}
662
 
644
 
663
void I_UnRegisterSong(int handle)
645
void I_UnRegisterSong(int handle)
664
{
646
{
665
  // UNUSED.
647
  // UNUSED.
666
  handle = 0;
648
  handle = 0;
667
}
649
}
668
 
650
 
669
int I_RegisterSong(void* data)
651
int I_RegisterSong(void* data)
670
{
652
{
671
  // UNUSED.
653
  // UNUSED.
672
  data = NULL;
654
  data = NULL;
673
  
655
  
674
  return 1;
656
  return 1;
675
}
657
}
676
 
658
 
677
// Is the song playing?
659
// Is the song playing?
678
int I_QrySongPlaying(int handle)
660
int I_QrySongPlaying(int handle)
679
{
661
{
680
  // UNUSED.
662
  // UNUSED.
681
  handle = 0;
663
  handle = 0;
682
  return looping || musicdies > gametic;
664
  return looping || musicdies > gametic;
683
}
665
}
684
 
666
 
685
 
667
 
686
// Interrupt handler.
668
// Interrupt handler.
687
void I_HandleSoundTimer( int ignore )
669
void I_HandleSoundTimer( int ignore )
688
{
670
{
689
   
671
   
690
  // UNUSED, but required.
672
  // UNUSED, but required.
691
  ignore = 0;
673
  ignore = 0;
692
  return;
674
  return;
693
}
675
}