1 /******************************************/
4 by Gary P. Scavone, 2007
6 This program records audio from a device and writes it to a
7 header-less binary file. Use the 'playraw', with the same
8 parameters and format settings, to playback the audio.
10 /******************************************/
17 #define FORMAT RTAUDIO_SINT8
19 typedef signed short MY_TYPE;
20 #define FORMAT RTAUDIO_SINT16
22 typedef signed long MY_TYPE;
23 #define FORMAT RTAUDIO_SINT24
25 typedef signed long MY_TYPE;
26 #define FORMAT RTAUDIO_SINT32
29 typedef float MY_TYPE;
30 #define FORMAT RTAUDIO_FLOAT32
33 typedef double MY_TYPE;
34 #define FORMAT RTAUDIO_FLOAT64
37 // Platform-dependent sleep routines.
38 #if defined( __WINDOWS_ASIO__ ) || defined( __WINDOWS_DS__ )
40 #define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds )
41 #else // Unix variants
43 #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) )
47 // Error function in case of incorrect command-line
48 // argument specifications
49 std::cout << "\nuseage: record N fs <duration> <device> <channelOffset>\n";
50 std::cout << " where N = number of channels,\n";
51 std::cout << " fs = the sample rate,\n";
52 std::cout << " duration = optional time in seconds to record (default = 2.0),\n";
53 std::cout << " device = optional device to use (default = 0),\n";
54 std::cout << " and channelOffset = an optional channel offset on the device (default = 0).\n\n";
60 unsigned long bufferBytes;
61 unsigned long totalFrames;
62 unsigned long frameCounter;
63 unsigned int channels;
66 // Interleaved buffers
67 int input( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
68 double streamTime, RtAudioStreamStatus status, void *data )
70 InputData *iData = (InputData *) data;
72 // Simply copy the data to our allocated buffer.
73 unsigned int frames = nBufferFrames;
74 if ( iData->frameCounter + nBufferFrames > iData->totalFrames ) {
75 frames = iData->totalFrames - iData->frameCounter;
76 iData->bufferBytes = frames * iData->channels * sizeof( MY_TYPE );
79 unsigned long offset = iData->frameCounter * iData->channels;
80 memcpy( iData->buffer+offset, inputBuffer, iData->bufferBytes );
81 iData->frameCounter += frames;
83 if ( iData->frameCounter >= iData->totalFrames ) return 2;
87 int main( int argc, char *argv[] )
89 unsigned int channels, fs, bufferFrames, device = 0, offset = 0;
93 // minimal command-line checking
94 if ( argc < 3 || argc > 6 ) usage();
97 if ( adc.getDeviceCount() < 1 ) {
98 std::cout << "\nNo audio devices found!\n";
102 channels = (unsigned int) atoi( argv[1] );
103 fs = (unsigned int) atoi( argv[2] );
105 time = (double) atof( argv[3] );
107 device = (unsigned int) atoi( argv[4] );
109 offset = (unsigned int) atoi( argv[5] );
111 // Let RtAudio print messages to stderr.
112 adc.showWarnings( true );
114 // Set our stream parameters for input only.
116 RtAudio::StreamParameters iParams;
117 iParams.deviceId = device;
118 iParams.nChannels = channels;
119 iParams.firstChannel = offset;
124 adc.openStream( NULL, &iParams, FORMAT, fs, &bufferFrames, &input, (void *)&data );
126 catch ( RtError& e ) {
127 std::cout << '\n' << e.getMessage() << '\n' << std::endl;
131 data.bufferBytes = bufferFrames * channels * sizeof( MY_TYPE );
132 data.totalFrames = (unsigned long) (fs * time);
133 data.frameCounter = 0;
134 data.channels = channels;
135 unsigned long totalBytes;
136 totalBytes = data.totalFrames * channels * sizeof( MY_TYPE );
138 // Allocate the entire data buffer before starting stream.
139 data.buffer = (MY_TYPE*) malloc( totalBytes );
140 if ( data.buffer == 0 ) {
141 std::cout << "Memory allocation error ... quitting!\n";
148 catch ( RtError& e ) {
149 std::cout << '\n' << e.getMessage() << '\n' << std::endl;
153 std::cout << "\nRecording for " << time << " seconds ... writing file 'record.raw' (buffer frames = " << bufferFrames << ")." << std::endl;
155 SLEEP( 100 ); // wake every 100 ms to check if we're done
156 if ( adc.isStreamRunning() == false ) break;
159 // Now write the entire data to the file.
160 fd = fopen( "record.raw", "wb" );
161 fwrite( data.buffer, sizeof( MY_TYPE ), data.totalFrames * channels, fd );
165 if ( adc.isStreamOpen() ) adc.closeStream();
166 if ( data.buffer ) free( data.buffer );