#include #include #include #include #include #include #include #include #include #include #include #include #include "oss_server.h" #include "oss_error.h" #include "mix_server.h" int soundhz = 44100; #define SAMPLESIZE 512 static int soundfd; static pid_t server; static int soundblksize; #define TRY(x,y) if (ioctl(soundfd, x, y) < 0) \ { error("ossSound: ioctl failed (" #x "," #y "): %s", \ strerror(errno)); close(soundfd); return 0; } void die(void) { error("died an ugly death\n"); exit(1); } static int opensound(void) { int soundstereo = 0; int soundformat = AFMT_S8; int soundfragment = 11 | (2 << 16); soundfd = open(DEVICE, O_RDWR); if (soundfd < 0) { error("cannot open sound: %s\n", strerror(errno)); return 0; } TRY(SNDCTL_DSP_SETFRAGMENT, &soundfragment); TRY(SNDCTL_DSP_RESET, 0); TRY(SNDCTL_DSP_GETBLKSIZE, &soundblksize); TRY(SNDCTL_DSP_SPEED, &soundhz); TRY(SNDCTL_DSP_STEREO, &soundstereo); TRY(SNDCTL_DSP_SETFMT, &soundformat); return 1; } /****************************/ static void handle_voice(voicePacket * vp) { mix_handle_voice(vp->channel + mix_CHN0, vp->hertz, vp->volume); } static void handle_data(dataPacket * dp, u8 * data) { switch (dp->channel) { case VP_SPEECH: mix_handle_data(mix_Speech, dp->hertz, dp->volume, dp->length, data); free(data); break; } } int main(int argc, char **argv) { char command[64]; struct timeval zerowait = { 0, 0 }; fd_set readfds, usefds; int done, mix; if (!opensound()) exit(1); seteuid(getuid()); setegid(getgid()); FD_ZERO(&readfds); FD_SET(0, &readfds); mix_init(soundhz); done = 0; mix = 0; log("OSS server waiting...\n"); do { int changed; usefds = readfds; changed = select(1, &usefds, 0, 0, &zerowait); if (changed > 0) { int len; u8 data[PACKET_MAXSIZE]; dataPacket *dp; if (!recv_packet(0, data, 1)) { done = 1; break; } switch (data[0]) { case VP_SOUNDON: mix = 1; break; case VP_SOUNDOFF: mix = 0; break; case VP_QUIT: done = 1; break; case VP_VOICE0: case VP_VOICE1: case VP_VOICE2: case VP_NOISE: { voicePacket *vp = (voicePacket *) data; if (!recv_packet(0, data + 1, sizeof(voicePacket) - 1)) done = 1; else handle_voice(vp); break; } case VP_SPEECH: { u8 *stuff; dataPacket *dp = (dataPacket *) data; if (!recv_packet(0, data + 1, sizeof(dataPacket) - 1)) done = 1; else { // fprintf(stderr,"dp->channel = %d, volume=%d, hertz=%d, length=%d\n", // dp->channel, dp->volume, dp->hertz, dp->length); stuff = (u8 *) malloc(dp->length); if (stuff == NULL) die(); if (!recv_packet(0, stuff, dp->length)) { free(stuff); stuff = NULL; done = 1; } } if (stuff) { //int i; //for (i=0; ilength; i++) fprintf(stderr,"%d ", stuff[i]); //fprintf(stderr,"\n"); handle_data(dp, stuff); } break; } default: { log("unknown packet %d\n", data[0]); len += read(0, data + 1, PACKET_MAXSIZE - 1); log("skipped %d bytes\n", len); break; } } } else { if (mix) { s8 sample[SAMPLESIZE]; mix_mixit(sample, 0, SAMPLESIZE); mix_advance(SAMPLESIZE); write(soundfd, sample, SAMPLESIZE); } } } while (!done); close(soundfd); exit(0); }