Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!spool.mu.edu!cs.umn.edu!lindner From: lindner@cs.umn.edu (Paul Lindner) Newsgroups: comp.sys.next Subject: Re: Showing off the sounds Keywords: hacking, playing, wasting time... :-) Message-ID: <1991May25.081857.27167@cs.umn.edu> Date: 25 May 91 08:18:57 GMT Article-I.D.: cs.1991May25.081857.27167 References: <1991May24.230242.22506@cs.mcgill.ca> Organization: University of Minnesota, Minneapolis, CSci dept. Lines: 269 In <1991May24.230242.22506@cs.mcgill.ca> peterd@cs.mcgill.ca (Peter Deutsch) writes: >So, I hope this puts a few ideas in people's heads. I'm >going to keep playing and would be interested in hearing >from others working along simliar lines. >---------------------------------------------------------------------- >#import >#import >main (int argc, char *argv[]) [.... code deleted...] Ha! I've already beat ya to it! I hacked the same examples and came up with with commands that play from stdin and record to stdout for the NeXT. The problem around here is really sh**ty radio reception. I swear that our Csci building is just one big Focault cage. However my office is in another building, where I've set up an antenna. Thus I set up a little server on the next cube here in my office connected to the radio, that's connected to the mongo antenna. My little server sits at port 7000 and waits for connections. When it receives one it starts the record process and starts spewing forth sound data across the socket. The client receives this and pipes it into the speaker on the local machine. Essentially I now have KJJO and KFAI gateways. I also pop a CD in my Sun CD-ROM, start up a sound server on it, and then I run x_cdplayer remotely. I can change tracks on the client machine and actually hear my changes. (Just don't press the eject button, or else you'll have a long run on your hands.) In fact I had it running for three days straight once. (That's about 2.1 gig of sound transferred) I also have digitized some of my favorite tunes to Optical Disk. I'm up to about 40 megs of sampled songs! This fits in quite well with this distributed database project of mine that utilizes the full text indexing of the Next. The sound server is patched into this database. You can choose from a menu/directory tree for the songs you want to hear. The only thing it doesn't have is a quarter slot on the side! (Though if ASCAP or BMI finds out, I may have to do that!) So for all of you NeXT people, here's the play and record that work flawlessly on pipes. If anyone is interested in the server and clients for sound (I call them radiod and radio), drop me a line. It's pretty cool. -------------------- play.c ------------------------------------------ /* derived from * recordchaintest.c - this test shows how to chain small recordings * and append them to a soundfile. * * Play sound from a pipe. An ugly hack by Paul Lindner * */ #import #import #define NUM_BUFFERS 2 #define BUF_SIZE 8192 #define SECONDS 10000.0 static SNDSoundStruct *buffers[NUM_BUFFERS]; static int requestedDataSize, recordedDataSize = 0; static int lastBufNum; static void playit(int tag); /* * Called before the sample is played */ static int beforePlay(SNDSoundStruct *s, int tag, int err) { if (err) fprintf(stderr, "beforePlay: %s\n", SNDSoundError(err)); if (fread((void*)((char*)s + s->dataLocation), 1, s->dataSize, stdin) != s->dataSize) fprintf(stderr, "playDone: could not read data to soundfile\n"); } static int playDone(SNDSoundStruct *s, int tag, int err) /* * Called when a buffer has been played. */ { playit((lastBufNum + 1) % NUM_BUFFERS); return 0; } static void playit(int bufNum) /* * Initiates playing into a buffers[bufNum]. */ { int err; static int tag = 1; lastBufNum = bufNum; if (err = SNDStartPlaying(buffers[bufNum], tag++, 0, 0, beforePlay, playDone)) fprintf(stderr, "record: %s\n", SNDSoundError(err)); } /* * Allocate n sound buffers. */ static void init(int n, int size) { int i, err; SNDSoundStruct s; for (i = 0; i < n; i++) if (err = SNDAlloc(&buffers[i], size, SND_FORMAT_MULAW_8, SND_RATE_CODEC, 1, 4)) fprintf(stderr, "init: %s\n", SNDSoundError(err)); } static void startup(void) /* * Read the soundfile header. */ { SNDSoundStruct s; s.magic = SND_MAGIC; s.dataLocation = sizeof(SNDSoundStruct); s.dataSize = recordedDataSize; s.dataFormat = SND_FORMAT_MULAW_8; s.samplingRate = SND_RATE_CODEC; s.channelCount = 1; if (fread((void *)&s, sizeof(SNDSoundStruct), 1, stdin) != 1) fprintf(stderr, "cleanup: could not read header\n"); /* if (s.magic != SND_MAGIC) fprintf(stderr, "Not a valid sound file....\n"), exit(-1); */ } main(int argc, char *argv[]) { int i; requestedDataSize = SECONDS * SND_RATE_CODEC; startup(); init(NUM_BUFFERS, BUF_SIZE); for (i=0; i to output * sound to a pipe instead of a file. */ #import #import #define NUM_BUFFERS 2 #define BUF_SIZE 8192 #define SECONDS 10000.0 static SNDSoundStruct *buffers[NUM_BUFFERS]; static FILE *sfp; static int requestedDataSize, recordedDataSize = 0; static int lastBufNum; static void record(int tag); static int recordDone(SNDSoundStruct *s, int tag, int err) /* * Called when a buffer has been recorded. * Appends the buffer to the soundfile and initiates recording into it again. */ { if (recordedDataSize >= requestedDataSize) return 0; if (err) fprintf(stderr, "recordDone: %s\n", SNDSoundError(err)); if (fwrite((void*)((char*)s + s->dataLocation), 1, s->dataSize, stdout) != s->dataSize) fprintf(stderr, "recordDone: could not write data to soundfile\n"); recordedDataSize += s->dataSize; record((lastBufNum + 1) % NUM_BUFFERS); return 0; } static void record(int bufNum) /* * Initiates recording into a buffers[bufNum]. */ { int err; static int tag = 1; lastBufNum = bufNum; if (err = SNDStartRecording(buffers[bufNum], tag++, 0, 0, SND_NULL_FUN, recordDone)) fprintf(stderr, "record: %s\n", SNDSoundError(err)); } static void init(int n, int size) /* * Allocate n sound buffers. * Creates the soundfile. */ { int i, err; SNDSoundStruct s; for (i = 0; i < n; i++) if (err = SNDAlloc(&buffers[i], size, SND_FORMAT_MULAW_8, SND_RATE_CODEC, 1, 4)) fprintf(stderr, "init: %s\n", SNDSoundError(err)); if (fwrite((void *)&s, sizeof(SNDSoundStruct), 1, stdout) != 1) fprintf(stderr, "init: could not write dummy header to soundfile\n"); } static void cleanup(void) /* * Write the soundfile header. */ { SNDSoundStruct s; s.magic = SND_MAGIC; s.dataLocation = sizeof(SNDSoundStruct); s.dataSize = recordedDataSize; s.dataFormat = SND_FORMAT_MULAW_8; s.samplingRate = SND_RATE_CODEC; s.channelCount = 1; if (fwrite((void *)&s, sizeof(SNDSoundStruct), 1, stdout) != 1) fprintf(stderr, "cleanup: could not write header to soundfile\n"); } main(int argc, char *argv[]) { int i; requestedDataSize = SECONDS * SND_RATE_CODEC; cleanup(); init(NUM_BUFFERS, BUF_SIZE); for (i=0; i