soundsrv.c (13245B)
1 #define LENGTH(x) (sizeof(x)/sizeof(x[0])) 2 #include <string.h> 3 #include <sys/types.h> 4 #include <stdio.h> 5 #include <fcntl.h> 6 #include <sys/ioctl.h> 7 #include <unistd.h> 8 #include <stdlib.h> 9 #include <malloc.h> 10 #include <sys/stat.h> 11 #include <sys/time.h> 12 #include "sounds.h" 13 #include "soundsrv.h" 14 15 typedef struct wadinfo_struct 16 { 17 char identification[4]; 18 int numlumps; 19 int infotableofs; 20 } wadinfo_t; 21 22 typedef struct filelump_struct 23 { 24 int filepos; 25 int size; 26 char name[8]; 27 } filelump_t; 28 29 static int mytime = 0; 30 int numsounds; 31 int longsound; 32 int lengths[NUMSFX]; 33 signed short mixbuffer[MIXBUFFERSIZE]; 34 int sfxdevice; 35 int musdevice; 36 unsigned char* channels[8]; 37 unsigned int channelstep[8]; 38 unsigned int channelstepremainder[8]; 39 unsigned char* channelsend[8]; 40 int channelstart[8]; 41 int channelhandles[8]; 42 int* channelleftvol_lookup[8]; 43 int* channelrightvol_lookup[8]; 44 int channelids[8]; 45 int snd_verbose=1; 46 int steptable[256] = { 47 16384, 16562, 16742, 16925, 17109, 17295, 17484, 17674, 17866, 18061, 18258, 18456, 18657, 18861, 19066, 19274, 19483, 19696, 19910, 20127, 20346, 20568, 20792, 21018, 21247, 21478, 21712, 21949, 22188, 22429, 22673, 22920, 23170, 23422, 23677, 23935, 24196, 24459, 24726, 24995, 25267, 25542, 25820, 26102, 26386, 26673, 26964, 27257, 27554, 27854, 28157, 28464, 28774, 29087, 29404, 29724, 30048, 30375, 30706, 31040, 31378, 31720, 32065, 32415, 32768, 33124, 33485, 33850, 34218, 34591, 34968, 35348, 35733, 36122, 36516, 36913, 37315, 37722, 38132, 38548, 38967, 39392, 39821, 40254, 40693, 41136, 41584, 42037, 42494, 42957, 43425, 43898, 44376, 44859, 45347, 45841, 46340, 46845, 47355, 47871, 48392, 48919, 49452, 49990, 50535, 51085, 51641, 52204, 52772, 53347, 53928, 54515, 55108, 55709, 56315, 56928, 57548, 58175, 58809, 59449, 60096, 60751, 61412, 62081, 62757, 63440, 64131, 64830, 65536, 66249, 66971, 67700, 68437, 69182, 69936, 70697, 71467, 72245, 73032, 73827, 74631, 75444, 76265, 77096, 77935, 78784, 79642, 80509, 81386, 82272, 83168, 84074, 84989, 85915, 86850, 87796, 88752, 89718, 90695, 91683, 92681, 93691, 94711, 95742, 96785, 97839, 98904, 99981, 101070, 102170, 103283, 104408, 105545, 106694, 107856, 109030, 110217, 111418, 112631, 113857, 115097, 116351, 117618, 118898, 120193, 121502, 122825, 124162, 125514, 126881, 128263, 129660, 131072, 132499, 133942, 135400, 136875, 138365, 139872, 141395, 142935, 144491, 146064, 147655, 149263, 150888, 152531, 154192, 155871, 157569, 159284, 161019, 162772, 164545, 166337, 168148, 169979, 171830, 173701, 175592, 177504, 179437, 181391, 183367, 185363, 187382, 189422, 191485, 193570, 195678, 197809, 199963, 202140, 204341, 206566, 208816, 211090, 213388, 215712, 218061, 220435, 222836, 225262, 227715, 230195, 232702, 235236, 237797, 240387, 243004, 245650, 248325, 251029, 253763, 256526, 259320 48 }; 49 int vol_lookup[128*256]; 50 static void derror(char* msg) 51 { 52 fprintf(stderr, "error: %s\n", msg); 53 exit(-1); 54 } 55 int mix(void) 56 { 57 register int dl; 58 register int dr; 59 register unsigned int sample; 60 signed short* leftout; 61 signed short* rightout; 62 signed short* leftend; 63 int step; 64 leftout = mixbuffer; 65 rightout = mixbuffer+1; 66 step = 2; 67 leftend = mixbuffer + SAMPLECOUNT*step; 68 while (leftout != leftend) 69 { 70 dl = 0; 71 dr = 0; 72 if (channels[0]) 73 { 74 sample = *channels[0]; 75 dl += channelleftvol_lookup[0][sample]; 76 dr += channelrightvol_lookup[0][sample]; 77 channelstepremainder[0] += channelstep[0]; 78 channels[0] += channelstepremainder[0] >> 16; 79 channelstepremainder[0] &= 65536-1; 80 if (channels[0] >= channelsend[0]) 81 channels[0] = 0; 82 } 83 if (channels[1]) 84 { 85 sample = *channels[1]; 86 dl += channelleftvol_lookup[1][sample]; 87 dr += channelrightvol_lookup[1][sample]; 88 channelstepremainder[1] += channelstep[1]; 89 channels[1] += channelstepremainder[1] >> 16; 90 channelstepremainder[1] &= 65536-1; 91 if (channels[1] >= channelsend[1]) 92 channels[1] = 0; 93 } 94 if (channels[2]) 95 { 96 sample = *channels[2]; 97 dl += channelleftvol_lookup[2][sample]; 98 dr += channelrightvol_lookup[2][sample]; 99 channelstepremainder[2] += channelstep[2]; 100 channels[2] += channelstepremainder[2] >> 16; 101 channelstepremainder[2] &= 65536-1; 102 if (channels[2] >= channelsend[2]) 103 channels[2] = 0; 104 } 105 106 if (channels[3]) 107 { 108 sample = *channels[3]; 109 dl += channelleftvol_lookup[3][sample]; 110 dr += channelrightvol_lookup[3][sample]; 111 channelstepremainder[3] += channelstep[3]; 112 channels[3] += channelstepremainder[3] >> 16; 113 channelstepremainder[3] &= 65536-1; 114 if (channels[3] >= channelsend[3]) 115 channels[3] = 0; 116 } 117 118 if (channels[4]) 119 { 120 sample = *channels[4]; 121 dl += channelleftvol_lookup[4][sample]; 122 dr += channelrightvol_lookup[4][sample]; 123 channelstepremainder[4] += channelstep[4]; 124 channels[4] += channelstepremainder[4] >> 16; 125 channelstepremainder[4] &= 65536-1; 126 if (channels[4] >= channelsend[4]) 127 channels[4] = 0; 128 } 129 130 if (channels[5]) 131 { 132 sample = *channels[5]; 133 dl += channelleftvol_lookup[5][sample]; 134 dr += channelrightvol_lookup[5][sample]; 135 channelstepremainder[5] += channelstep[5]; 136 channels[5] += channelstepremainder[5] >> 16; 137 channelstepremainder[5] &= 65536-1; 138 if (channels[5] >= channelsend[5]) 139 channels[5] = 0; 140 } 141 142 if (channels[6]) 143 { 144 sample = *channels[6]; 145 dl += channelleftvol_lookup[6][sample]; 146 dr += channelrightvol_lookup[6][sample]; 147 channelstepremainder[6] += channelstep[6]; 148 channels[6] += channelstepremainder[6] >> 16; 149 channelstepremainder[6] &= 65536-1; 150 if (channels[6] >= channelsend[6]) 151 channels[6] = 0; 152 } 153 if (channels[7]) 154 { 155 sample = *channels[7]; 156 dl += channelleftvol_lookup[7][sample]; 157 dr += channelrightvol_lookup[7][sample]; 158 channelstepremainder[7] += channelstep[7]; 159 channels[7] += channelstepremainder[7] >> 16; 160 channelstepremainder[7] &= 65536-1; 161 if (channels[7] >= channelsend[7]) 162 channels[7] = 0; 163 } 164 165 166 167 168 169 170 171 172 if (dl > 0x7fff) 173 *leftout = 0x7fff; 174 else if (dl < -0x8000) 175 *leftout = -0x8000; 176 else 177 *leftout = dl; 178 if (dr > 0x7fff) 179 *rightout = 0x7fff; 180 else if (dr < -0x8000) 181 *rightout = -0x8000; 182 else 183 *rightout = dr; 184 leftout += step; 185 rightout += step; 186 } 187 return 1; 188 } 189 void 190 grabdata 191 ( int c, 192 char** v ) 193 { 194 int i; 195 char* name; 196 char* doom1wad; 197 char* doomwad; 198 char* doomuwad; 199 char* doom2wad; 200 char* doom2fwad; 201 char* doomwaddir; 202 doomwaddir = getenv("DOOMWADDIR"); 203 if (!doomwaddir) 204 doomwaddir = "."; 205 doom1wad = malloc(strlen(doomwaddir)+1+9+1); 206 sprintf(doom1wad, "%s/doom1.wad", doomwaddir); 207 doom2wad = malloc(strlen(doomwaddir)+1+9+1); 208 sprintf(doom2wad, "%s/doom2.wad", doomwaddir); 209 doom2fwad = malloc(strlen(doomwaddir)+1+10+1); 210 sprintf(doom2fwad, "%s/doom2f.wad", doomwaddir); 211 doomuwad = malloc(strlen(doomwaddir)+1+8+1); 212 sprintf(doomuwad, "%s/doomu.wad", doomwaddir); 213 doomwad = malloc(strlen(doomwaddir)+1+8+1); 214 sprintf(doomwad, "%s/doom.wad", doomwaddir); 215 for (i=1 ; i<c ; i++) 216 { 217 if (!strcmp(v[i], "-quiet")) 218 { 219 snd_verbose = 0; 220 } 221 } 222 numsounds = NUMSFX; 223 longsound = 0; 224 if (! access(doom2fwad, R_OK) ) 225 name = doom2fwad; 226 else if (! access(doom2wad, R_OK) ) 227 name = doom2wad; 228 else if (! access(doomuwad, R_OK) ) 229 name = doomuwad; 230 else if (! access(doomwad, R_OK) ) 231 name = doomwad; 232 else if (! access(doom1wad, R_OK) ) 233 name = doom1wad; 234 else 235 { 236 fprintf(stderr, "Could not find wadfile anywhere\n"); 237 exit(-1); 238 } 239 openwad(name); 240 if (snd_verbose) 241 fprintf(stderr, "loading from [%s]\n", name); 242 for (i=1 ; i<NUMSFX ; i++) 243 { 244 if (!S_sfx[i].link) 245 { 246 S_sfx[i].data = getsfx(S_sfx[i].name, &lengths[i]); 247 if (longsound < lengths[i]) longsound = lengths[i]; 248 } else { 249 S_sfx[i].data = S_sfx[i].link->data; 250 lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(SfxInfo)]; 251 } 252 253 254 255 256 257 258 259 260 261 } 262 } 263 void updatesounds(void) 264 { 265 mix(); 266 I_SubmitOutputBuffer(mixbuffer, SAMPLECOUNT); 267 } 268 int 269 addsfx 270 ( int sfxid, 271 int volume, 272 int step, 273 int seperation ) 274 { 275 static unsigned short handlenums = 0; 276 int i; 277 int rc = -1; 278 int oldest = mytime; 279 int oldestnum = 0; 280 int slot; 281 int rightvol; 282 int leftvol; 283 if ( sfxid == sfx_sawup 284 || sfxid == sfx_sawidl 285 || sfxid == sfx_sawful 286 || sfxid == sfx_sawhit 287 || sfxid == sfx_stnmov 288 || sfxid == sfx_pistol ) 289 { 290 for (i=0 ; i<8 ; i++) 291 { 292 if (channels[i] && channelids[i] == sfxid) 293 { 294 channels[i] = 0; 295 break; 296 } 297 } 298 } 299 for (i=0 ; i<8 && channels[i] ; i++) 300 { 301 if (channelstart[i] < oldest) 302 { 303 oldestnum = i; 304 oldest = channelstart[i]; 305 } 306 } 307 if (i == 8) 308 slot = oldestnum; 309 else 310 slot = i; 311 channels[slot] = (unsigned char *) S_sfx[sfxid].data; 312 channelsend[slot] = channels[slot] + lengths[sfxid]; 313 if (!handlenums) 314 handlenums = 100; 315 channelhandles[slot] = rc = handlenums++; 316 channelstep[slot] = step; 317 channelstepremainder[slot] = 0; 318 channelstart[slot] = mytime; 319 seperation += 1; 320 leftvol = 321 volume - (volume*seperation*seperation)/(256*256); 322 seperation = seperation - 257; 323 rightvol = 324 volume - (volume*seperation*seperation)/(256*256); 325 if (rightvol < 0 || rightvol > 127) 326 derror("rightvol out of bounds"); 327 if (leftvol < 0 || leftvol > 127) 328 derror("leftvol out of bounds"); 329 channelleftvol_lookup[slot] = &vol_lookup[leftvol*256]; 330 channelrightvol_lookup[slot] = &vol_lookup[rightvol*256]; 331 channelids[slot] = sfxid; 332 return rc; 333 } 334 void outputushort(int num) 335 { 336 static unsigned char buff[5] = { 0, 0, 0, 0, '\n' }; 337 static char* badbuff = "xxxx\n"; 338 if (num < 0) 339 { 340 write(1, badbuff, 5); 341 } 342 else 343 { 344 buff[0] = num>>12; 345 buff[0] += buff[0] > 9 ? 'a'-10 : '0'; 346 buff[1] = (num>>8) & 0xf; 347 buff[1] += buff[1] > 9 ? 'a'-10 : '0'; 348 buff[2] = (num>>4) & 0xf; 349 buff[2] += buff[2] > 9 ? 'a'-10 : '0'; 350 buff[3] = num & 0xf; 351 buff[3] += buff[3] > 9 ? 'a'-10 : '0'; 352 write(1, buff, 5); 353 } 354 } 355 void initdata(void) 356 { 357 int i, j; 358 int* steptablemid; 359 steptablemid = steptable + 128; 360 for (i = 0 ; i < LENGTH(channels); ++i) 361 channels[i] = 0; 362 for (i = 0; i < 128; ++i) 363 for (j=0 ; j<256 ; j++) 364 vol_lookup[i*256+j] = (i*(j-128)*256)/127; 365 } 366 void quit(void) 367 { 368 I_ShutdownMusic(); 369 I_ShutdownSound(); 370 exit(0); 371 } 372 fd_set fdset; 373 fd_set scratchset; 374 375 int 376 main(int c, char** v) 377 { 378 int done = 0; 379 int rc; 380 int nrc; 381 int sndnum; 382 int handle = 0; 383 unsigned char commandbuf[10]; 384 struct timeval zerowait = { 0, 0 }; 385 int step; 386 int vol; 387 int sep; 388 int i; 389 int waitingtofinish=0; 390 grabdata(c, v); 391 initdata(); 392 I_InitSound(11025, 16); 393 I_InitMusic(); 394 if (snd_verbose) 395 fprintf(stderr, "ready\n"); 396 FD_ZERO(&fdset); 397 FD_SET(0, &fdset); 398 while (!done) 399 { 400 mytime++; 401 if (!waitingtofinish) 402 { 403 do { 404 scratchset = fdset; 405 rc = select(FD_SETSIZE, &scratchset, 0, 0, &zerowait); 406 if (rc > 0) 407 { 408 409 410 nrc = read(0, commandbuf, 1); 411 if (!nrc) 412 { 413 done = 1; 414 rc = 0; 415 } 416 else 417 { 418 if (snd_verbose) 419 fprintf(stderr, "cmd: %c", commandbuf[0]); 420 switch (commandbuf[0]) 421 { 422 case 'p': 423 424 read(0, commandbuf, 9); 425 if (snd_verbose) 426 { 427 commandbuf[9]=0; 428 fprintf(stderr, "%s\n", commandbuf); 429 } 430 commandbuf[0] -= 431 commandbuf[0]>='a' ? 'a'-10 : '0'; 432 commandbuf[1] -= 433 commandbuf[1]>='a' ? 'a'-10 : '0'; 434 commandbuf[2] -= 435 commandbuf[2]>='a' ? 'a'-10 : '0'; 436 commandbuf[3] -= 437 commandbuf[3]>='a' ? 'a'-10 : '0'; 438 commandbuf[4] -= 439 commandbuf[4]>='a' ? 'a'-10 : '0'; 440 commandbuf[5] -= 441 commandbuf[5]>='a' ? 'a'-10 : '0'; 442 commandbuf[6] -= 443 commandbuf[6]>='a' ? 'a'-10 : '0'; 444 commandbuf[7] -= 445 commandbuf[7]>='a' ? 'a'-10 : '0'; 446 447 sndnum = (commandbuf[0]<<4) + commandbuf[1]; 448 step = (commandbuf[2]<<4) + commandbuf[3]; 449 step = steptable[step]; 450 vol = (commandbuf[4]<<4) + commandbuf[5]; 451 sep = (commandbuf[6]<<4) + commandbuf[7]; 452 handle = addsfx(sndnum, vol, step, sep); 453 454 455 break; 456 457 case 'q': 458 read(0, commandbuf, 1); 459 waitingtofinish = 1; rc = 0; 460 break; 461 462 case 's': 463 { 464 int fd; 465 read(0, commandbuf, 3); 466 commandbuf[2] = 0; 467 fd = open((char*)commandbuf, O_CREAT|O_WRONLY, 0644); 468 commandbuf[0] -= commandbuf[0]>='a' ? 'a'-10 : '0'; 469 commandbuf[1] -= commandbuf[1]>='a' ? 'a'-10 : '0'; 470 sndnum = (commandbuf[0]<<4) + commandbuf[1]; 471 write(fd, S_sfx[sndnum].data, lengths[sndnum]); 472 close(fd); 473 } 474 break; 475 476 default: 477 fprintf(stderr, "Did not recognize command\n"); 478 break; 479 } 480 } 481 } 482 else if (rc < 0) 483 { 484 quit(); 485 } 486 } while (rc > 0); 487 } 488 updatesounds(); 489 if (waitingtofinish) 490 { 491 for(i=0 ; i<8 && !channels[i] ; i++); 492 493 if (i==8) 494 done=1; 495 } 496 } 497 quit(); 498 return 0; 499 }