/* full_duplex.c */ /* * Copyright (c) 2001 Bruce R. Montague * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF * SUCH DAMAGE. */ /* * >full_duplex record_filename play_filename {bytes} */ #include #include #include #include #include #include #define REC_BYTES 300000 #define BUF_LEN 512 void do_save_work( char *rec_filename, int record_bytes ); void do_play_work( char *play_filename ); /* Args are 0:programname 1:rec_filename 2:play_filename 3:{bytes} */ /*-------------------------------------------------------------*/ int main( int argc, char *argv[] ) { char *rec_filename; char *play_filename; int pid,child_status,record_bytes; if( argc < 3) { printf( "\n\n >full_duplex record.pcm play.pcm {record_bytes}\n\n" ); exit(1); } rec_filename = argv[1]; play_filename = argv[2]; record_bytes = REC_BYTES; if( argc >= 4 ) { record_bytes = atoi( argv[3] ); } open_au_dev( "/dev/dsp", O_RDWR, 0 ); pid = fork(); if( pid < 0 ) { printf( "\n Cant fork, err=%d.\n", pid ); exit(1); } if( !pid ) { /* Child. */ do_save_work( rec_filename, record_bytes ); close_au_dev(); exit(0); } else { do_play_work( play_filename ); /* Parent. */ wait( &child_status ); } close_au_dev(); } /*-------------------------------------------------------------*/ void do_save_work( char *rec_filename, int record_bytes ) { unsigned char *au_buf_p; int fout; int bytes, au_bytes_in, len; fout = open( rec_filename, (O_WRONLY|O_CREAT|O_TRUNC), 0740 ); if( 0 > fout ) { printf( "\n Cant open file <%s>!\n", rec_filename ); perror( "" ); exit(1); } bytes = 0; for(;;) { au_bytes_in = read_au_dev( &au_buf_p ); /* printf( "\n au_bytes=%d.\n", au_bytes_in ); */ len = write( fout, au_buf_p, au_bytes_in ); if( 0 >= len ) { printf( "\n File write err? len=%d.\n", len ); exit(1); } bytes += len; if( bytes >= record_bytes ) break; } close( fout ); } /*-------------------------------------------------------------*/ void do_play_work( char *play_filename ) { char *buf_play_p; int fin, bytes_in; buf_play_p = malloc( BUF_LEN ); if( !buf_play_p ) { printf( "\n Cant malloc play buf!\n" ); } fin = open( play_filename, O_RDONLY, 0 ); if( !fin ) { printf( "\n Cant open file <%s>\n", play_filename ); exit(1); } for(;;) { bytes_in = read( fin, buf_play_p, 512 ); if( !bytes_in ) break; write_au_dev( buf_play_p, bytes_in ); } close( fin ); }