ref: 7c1994bd809aea4c535997c09f6703675986f98e
dir: /src/audio/auserver.c/
/*************************************************************************/ /* */ /* Language Technologies Institute */ /* Carnegie Mellon University */ /* Copyright (c) 2000 */ /* All Rights Reserved. */ /* */ /* Permission is hereby granted, free of charge, to use and distribute */ /* this software and its documentation without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of this work, and to */ /* permit persons to whom this work is furnished to do so, subject to */ /* the following conditions: */ /* 1. The code must retain the above copyright notice, this list of */ /* conditions and the following disclaimer. */ /* 2. Any modifications must be clearly marked as such. */ /* 3. Original authors' names are not deleted. */ /* 4. The authors' names are not used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK */ /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */ /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */ /* SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE */ /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */ /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */ /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */ /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */ /* THIS SOFTWARE. */ /* */ /*************************************************************************/ /* Author: Alan W Black (awb@cs.cmu.edu) */ /* Date: October 2000 */ /*************************************************************************/ /* */ /* A client/server audio play program */ /* */ /* Server listens to a socket and play anything coming in (streaming) */ /* Client just sends (riff) headered waveform to named socket */ /* */ /*************************************************************************/ #include "cst_file.h" #include <stdlib.h> #include "cst_socket.h" #include "cst_string.h" #include "cst_wave.h" #include "cst_file.h" #include "cst_audio.h" #ifndef CST_NO_SOCKETS #ifdef _MSC_VER #include <io.h> #define read(fd, buffer, count) _read(fd, buffer, count) #else #include <unistd.h> #endif static int play_wave_from_socket(snd_header *header,int audiostream) { /* Read audio from stream and play it to audio device, converting */ /* it to pcm if required */ int num_samples; int sample_width; cst_audiodev *audio_device; int q,i,n,r; unsigned char bytes[CST_AUDIOBUFFSIZE]; short shorts[CST_AUDIOBUFFSIZE]; #ifdef DEBUG cst_file fff; fff = cst_fopen("/tmp/awb.wav",CST_OPEN_WRITE|CST_OPEN_BINARY); #endif if ((audio_device = audio_open(header->sample_rate,1, (header->encoding == CST_SND_SHORT) ? CST_AUDIO_LINEAR16 : CST_AUDIO_LINEAR8)) == NULL) { cst_errmsg("play_wave_from_socket: can't open audio device\n"); return -1; } if (header->encoding == CST_SND_SHORT) sample_width = 2; else sample_width = 1; num_samples = header->data_size / sample_width; /* we naively let the num_channels sort itself out */ for (i=0; i < num_samples; i += r/2) { if (num_samples > i+CST_AUDIOBUFFSIZE) n = CST_AUDIOBUFFSIZE; else n = num_samples-i; if (header->encoding == CST_SND_ULAW) { r = read(audiostream,bytes,n); for (q=0; q<r; q++) shorts[q] = cst_ulaw_to_short(bytes[q]); r *= 2; } else /* if (header->encoding == CST_SND_SHORT) */ { r = read(audiostream,shorts,n*2); if (CST_LITTLE_ENDIAN) for (q=0; q<r/2; q++) shorts[q] = SWAPSHORT(shorts[q]); } if (r <= 0) { /* I'm not getting any data from the server */ audio_close(audio_device); return CST_ERROR_FORMAT; } for (q=r; q > 0; q-=n) { n = audio_write(audio_device,shorts,q); #ifdef DEBUG cst_fwrite(fff,shorts,2,q); #endif if (n <= 0) { audio_close(audio_device); return CST_ERROR_FORMAT; } } } audio_close(audio_device); #ifdef DEBUG cst_fclose(fff); #endif return CST_OK_FORMAT; } static int auserver_process_client(int client_name, int fd) { /* Gets called for each client */ snd_header header; int r; printf("client %d connected, ",client_name); fflush(stdout); /* Get header */ r = read(fd,&header,sizeof(header)); if (r != sizeof(header)) { cst_errmsg("socket: connection didn't give a header\n"); return -1; } if (CST_LITTLE_ENDIAN) { header.magic = SWAPINT(header.magic); header.hdr_size = SWAPINT(header.hdr_size); header.data_size = SWAPINT(header.data_size); header.encoding = SWAPINT(header.encoding); header.sample_rate = SWAPINT(header.sample_rate); header.channels = SWAPINT(header.channels); } if (header.magic != CST_SND_MAGIC) { cst_errmsg("socket: client something other than snd waveform\n"); return -1; } printf("%d bytes at %d rate, ", header.data_size, header.sample_rate); fflush(stdout); if (play_wave_from_socket(&header,fd) == CST_OK_FORMAT) printf("successful\n"); else printf("unsuccessful\n"); return 0; } int auserver(int port) { return cst_socket_server("audio",port,auserver_process_client); } #endif