extern "C" { #include #include #include #include #include #include #include #include #include #include #include "DoomDef.h" }; #include "sndserver.h" #include "wadread.h" #define SOUNDDIR LIBDIR "/sfx/" typedef struct wadinfo_struct { char identification[4]; // should be IWAD int numlumps; int infotableofs; } wadinfo_t; typedef struct filelump_struct { int filepos; int size; char name[8]; } filelump_t; static int mytime = 0; // an internal time keeper int numsounds; // number of sound effects int longsound; // longest sound effect int lengths[NUMSFX]; // lengths of all sound effects unsigned char mixbuffer[MIXBUFFERSIZE]; // mixing buffer int sfxdevice; // file descriptor of sfx device int musdevice; // file descriptor of music device unsigned char *channels[8]; // the channel data pointers unsigned char *channelsend[8]; // the channel data end pointers int channelstart[8]; // time that the channel started playing int channelhandles[8]; // the channel handles static void derror(char *msg) { fprintf(stderr, "error: %s\n", msg); exit(-1); } int mix(void) { register int i, j, d; // if (channels[0]) fprintf(stderr, "."); // for (d=i=0 ; i<8 ; i++) // d |= (int) channels[i]; // if (!d) return 0; // mix into the mixing buffer for (i=0 ; i 127) mixbuffer[i] = 255; else if (d < -128) mixbuffer[i] = 0; else mixbuffer[i] = (unsigned char) (d+128); // if (d > 127) mixbuffer[i] = 0; // else if (d < -128) mixbuffer[i] = 255; // else mixbuffer[i] = (unsigned char) (-d+127); } // check for freed channels for (j=0 ; j<8 ; j++) { if (channels[j] == channelsend[j]) channels[j] = 0; } return 1; } void grabdata(int c, char **v) { int i; numsounds = NUMSFX; longsound = 0; openwad("../frame/doom.wad"); for (i=1 ; idata; lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(struct sfxinfo_t)]; } /* // test only { int fd; char name[10]; sprintf(name, "sfx%d", i); fd = open(name, O_WRONLY|O_CREAT, 0644); write(fd, S_sfx[i].data, lengths[i]); close(fd); } */ } } void opensfxdev(int c, char **v) { int i, rc; // open the sound device sfxdevice = open("/dev/dsp", O_WRONLY, 0); if (sfxdevice < 0) derror("Could not open /dev/dsp"); // set it up for the proper sound format i = 8; rc = ioctl(sfxdevice, SNDCTL_DSP_SAMPLESIZE, &i); if (rc < 0) fprintf(stderr, "SAMPLESIZE failed\n"); i = 11111; rc = ioctl(sfxdevice, SNDCTL_DSP_SPEED, &i); if (rc < 0) fprintf(stderr, "SPEED failed\n"); i = 0; rc = ioctl(sfxdevice, SNDCTL_DSP_STEREO, &i); if (rc < 0) fprintf(stderr, "STEREO failed\n"); // i = 2; // rc = ioctl(sfxdevice, SNDCTL_DSP_SUBDIVIDE, &i); // if (rc < 0) fprintf(stderr, "SUBDIVIDE failed\n"); } void closesfxdev(void) { close(sfxdevice); } void openmusdev(int c, char **v) { } void closemusdev(void) { } static struct timeval last={0,0}, now; static struct timezone whocares; void updatesounds(void) { int deltatime; int rc; rc = mix(); rc = ioctl(sfxdevice, SNDCTL_DSP_POST, 0); // rc = ioctl(sfxdevice, SNDCTL_DSP_SYNC, 0); if (rc < 0) fprintf(stderr, "SYNC failed?!\n"); write(sfxdevice, mixbuffer, MIXBUFFERSIZE); /* gettimeofday(&now, &whocares); deltatime = (now.tv_sec - last.tv_sec)*1000000 + now.tv_usec - last.tv_usec; deltatime = deltatime - (1 * MIXBUFFERSIZE * 1000000) / (1 * SPEED); last = now; if (deltatime < 0) usleep (-deltatime); if (rc) { write(sfxdevice, mixbuffer, MIXBUFFERSIZE); fprintf(stderr, "."); } */ } int addsfx(int sfxid, int volume) { int i; int rc = -1; static unsigned short handlenums = 0; int oldest = mytime; int oldestnum = 0; for (i=0 ; i<8 ; i++) { if (!channels[i]) { channelsend[i] = (channels[i] = (unsigned char *) S_sfx[sfxid].data) + lengths[sfxid]; if (!handlenums) handlenums = 100; channelhandles[i] = rc = handlenums++; channelstart[i] = mytime; break; } else { if (channelstart[i] < oldest) { oldestnum = i; oldest = channelstart[i]; } } } // if no channels were available, kill oldest sound and replace it if (i == 8) { channelsend[oldestnum] = (channels[oldestnum] = (unsigned char *) S_sfx[sfxid].data) + lengths[sfxid]; if (!handlenums) handlenums = 100; channelhandles[oldestnum] = rc = handlenums++; channelstart[i] = mytime; } return rc; } void outputushort(int num) { static unsigned char buff[5] = { 0, 0, 0, 0, '\n' }; static char *badbuff = "xxxx\n"; // outputs a 16-bit # in hex or "xxxx" if -1. if (num < 0) { write(1, badbuff, 5); } else { buff[0] = num>>12; buff[0] += buff[0] > 9 ? 'a'-10 : '0'; buff[1] = (num>>8) & 0xf; buff[1] += buff[1] > 9 ? 'a'-10 : '0'; buff[2] = (num>>4) & 0xf; buff[2] += buff[2] > 9 ? 'a'-10 : '0'; buff[3] = num & 0xf; buff[3] += buff[3] > 9 ? 'a'-10 : '0'; write(1, buff, 5); } } void initdata(void) { int i; for (i=0 ; i 0) { // fprintf(stderr, "select is true\n"); // got a command nrc = read(0, commandbuf, 1); if (!nrc) { done = 1; rc = 0; } else { switch (commandbuf[0]) { case 'p': // play a new sound effect read(0, commandbuf, 3); commandbuf[0] -= commandbuf[0]>='a' ? 'a'-10 : '0'; commandbuf[1] -= commandbuf[1]>='a' ? 'a'-10 : '0'; sndnum = (commandbuf[0]<<4) + commandbuf[1]; // fprintf(stderr, "cmd: play sound %d\n", sndnum); handle = addsfx(sndnum, 127); // returns the handle // outputushort(handle); break; case 'q': read(0, commandbuf, 1); done = 1; rc = 0; break; case 's': { int fd; read(0, commandbuf, 3); commandbuf[2] = 0; fd = open((char*)commandbuf, O_CREAT|O_WRONLY, 0644); commandbuf[0] -= commandbuf[0]>='a' ? 'a'-10 : '0'; commandbuf[1] -= commandbuf[1]>='a' ? 'a'-10 : '0'; sndnum = (commandbuf[0]<<4) + commandbuf[1]; write(fd, S_sfx[sndnum].data, lengths[sndnum]); close(fd); } break; default: fprintf(stderr, "Did not recognize command\n"); break; } } } } while (rc > 0); updatesounds(); } closesfxdev(); closemusdev(); }