//------------------------------------------------------------------- // 1second.cpp // // This program captures input from a microphone and stores it // as a Waveform Audio File (.wav) whose filename was provided // by the user as a command-line argument. // // compile using: $ make 1second // execute using: $ 1second // // Online reference: "Audio Programming," 4Front Technologies, // // // programmer: ALLAN CRUSE // written on: 25 SEP 2005 //------------------------------------------------------------------- #include // for fprintf(), perror() #include // for open() #include // for exit() #include // for read(), write(), close() #include // for strncmp() #include // for ioctl() #include #define SAMPLE_RATE 48000 #define NUM_SECONDS 1 #define NUM_SAMPLES ( SAMPLE_RATE * NUM_SECONDS ) char devname[] = "/dev/dsp1"; unsigned char pulsecode[ NUM_SAMPLES ]; int main( int argc, char **argv ) { // check for required command-line argument if ( argc == 1 ) { fprintf( stderr, "usage: 1second \n" ); exit(1); } // setup the filename for waveform audio data char wavname[ 100 ]; strncpy( wavname, argv[ 1 ], 95 ); strtok( wavname, ". \n\t" ); strcat( wavname, ".wav" ); // check for a preexistence of this file int old = open( wavname, O_RDONLY ); if ( old != -1 ) { printf( "file \'%s\' exists ", wavname ); printf( "-- overwrite (y,n)? " ); if ( getchar() == 'y' ) close( old ); else exit(1); } // define the wave file's audio parameters short formatTag = 1; short nChannels = 1; int samplesPerSec = SAMPLE_RATE; int avBytesPerSec = samplesPerSec; short blockAlignmnt = 1; short bitsPerSample = 8; // wait till the user is ready to begin recording printf( "\nPress to begin recording " ); printf( "for %d seconds ... ", NUM_SECONDS ); fflush( stdout ); char inch[80]; read( 0, inch, sizeof( inch ) ); // open the audio device-file and set its capture parameters int bits = ( bitsPerSample == 8 ) ? AFMT_U8 : AFMT_S16_BE; int chns = ( nChannels == 1 ) ? 1 : 2; int rate = samplesPerSec; int dsp = open( devname, O_RDONLY ); if ( dsp < 0 ) { perror( devname ); exit(1); } if ( ioctl( dsp, SNDCTL_DSP_RESET, NULL ) < 0 ) { perror( "ioctl" ); exit(1); } if ( ( ioctl( dsp, SNDCTL_DSP_SETFMT, &bits ) < 0 ) ||( ioctl( dsp, SNDCTL_DSP_CHANNELS, &chns ) < 0 ) ||( ioctl( dsp, SNDCTL_DSP_SPEED, &rate ) < 0 ) ) { perror( "audio format not not supported\n" ); exit(1); } // main loop to capture the waveform audio data printf( "\nOK, ready to begin recording now... \n" ); unsigned char *data = pulsecode; int begun = 0; int bytes_to_grab = NUM_SAMPLES / 16; int bytes_to_save = NUM_SAMPLES; while ( bytes_to_save > 0 ) { int nbytes = read( dsp, data, bytes_to_grab ); if ( !begun ) { int max = 0; for (int i = 0; i < nbytes; i++) if ( data[i] > max ) max = data[i]; if ( max > 0x99 ) begun = 1; else continue; } bytes_to_save -= nbytes; data += nbytes; } close( dsp ); // open the wave file for writing int wav = open( wavname, O_WRONLY | O_CREAT | O_TRUNC, 0666 ); if ( wav < 0 ) { perror( wavname ); exit(1); } // write the RIFF chunk int dataChunkSize = NUM_SAMPLES; int fmt_ChunkSize = 16; int riffChunkSize = 4 + (8 + fmt_ChunkSize) +(8 + dataChunkSize); write( wav, "RIFF", 4 ); write( wav, &riffChunkSize, 4 ); write( wav, "WAVE", 4 ); // write the FORMAT chunk write( wav, "fmt ", 4 ); write( wav, &fmt_ChunkSize, 4 ); write( wav, &formatTag, 2 ); write( wav, &nChannels, 2 ); write( wav, &samplesPerSec, 4 ); write( wav, &avBytesPerSec, 4 ); write( wav, &blockAlignmnt, 2 ); write( wav, &bitsPerSample, 2 ); // write the DATA chunk write( wav, "data", 4 ); write( wav, &dataChunkSize, 4 ); data = pulsecode; bytes_to_save = dataChunkSize; while ( bytes_to_save > 0 ) { int nbytes = write( wav, data, bytes_to_save ); bytes_to_save -= nbytes; data += nbytes; } close( wav ); printf( "done\n\n" ); }