diff options
| author | Gary Scavone <gary@music.mcgill.ca> | 2007-08-07 14:52:05 +0000 |
|---|---|---|
| committer | Stephen Sinclair <sinclair@music.mcgill.ca> | 2013-10-11 01:19:40 +0200 |
| commit | b0080e69d64ce69e21c8ce1b22b1bb7f888f1e58 (patch) | |
| tree | b51ebcd31a5280b4f4e9e45484f07d9b35723743 /tests/record.cpp | |
| parent | 0fbcd74a04713a4725d2f346a493121b623d60ab (diff) | |
Check in of new version 4.0.0 distribution (GS).
Diffstat (limited to 'tests/record.cpp')
| -rw-r--r-- | tests/record.cpp | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/tests/record.cpp b/tests/record.cpp new file mode 100644 index 0000000..f43db19 --- /dev/null +++ b/tests/record.cpp @@ -0,0 +1,169 @@ +/******************************************/ +/* + record.cpp + by Gary P. Scavone, 2007 + + This program records audio from a device and writes it to a + header-less binary file. Use the 'playraw', with the same + parameters and format settings, to playback the audio. +*/ +/******************************************/ + +#include "RtAudio.h" +#include <iostream> + +/* +typedef char MY_TYPE; +#define FORMAT RTAUDIO_SINT8 + +typedef signed short MY_TYPE; +#define FORMAT RTAUDIO_SINT16 + +typedef signed long MY_TYPE; +#define FORMAT RTAUDIO_SINT24 + +typedef signed long MY_TYPE; +#define FORMAT RTAUDIO_SINT32 +*/ + +typedef float MY_TYPE; +#define FORMAT RTAUDIO_FLOAT32 + +/* +typedef double MY_TYPE; +#define FORMAT RTAUDIO_FLOAT64 +*/ + +// Platform-dependent sleep routines. +#if defined( __WINDOWS_ASIO__ ) || defined( __WINDOWS_DS__ ) + #include <windows.h> + #define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds ) +#else // Unix variants + #include <unistd.h> + #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) ) +#endif + +void usage( void ) { + // Error function in case of incorrect command-line + // argument specifications + std::cout << "\nuseage: record N fs <duration> <device> <channelOffset>\n"; + std::cout << " where N = number of channels,\n"; + std::cout << " fs = the sample rate,\n"; + std::cout << " duration = optional time in seconds to record (default = 2.0),\n"; + std::cout << " device = optional device to use (default = 0),\n"; + std::cout << " and channelOffset = an optional channel offset on the device (default = 0).\n\n"; + exit( 0 ); +} + +struct InputData { + MY_TYPE* buffer; + unsigned long bufferBytes; + unsigned long totalFrames; + unsigned long frameCounter; + unsigned int channels; +}; + +// Interleaved buffers +int input( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, + double streamTime, RtAudioStreamStatus status, void *data ) +{ + InputData *iData = (InputData *) data; + + // Simply copy the data to our allocated buffer. + unsigned int frames = nBufferFrames; + if ( iData->frameCounter + nBufferFrames > iData->totalFrames ) { + frames = iData->totalFrames - iData->frameCounter; + iData->bufferBytes = frames * iData->channels * sizeof( MY_TYPE ); + } + + unsigned long offset = iData->frameCounter * iData->channels; + memcpy( iData->buffer+offset, inputBuffer, iData->bufferBytes ); + iData->frameCounter += frames; + + if ( iData->frameCounter >= iData->totalFrames ) return 2; + return 0; +} + +int main( int argc, char *argv[] ) +{ + unsigned int channels, fs, bufferFrames, device = 0, offset = 0; + double time = 2.0; + FILE *fd; + + // minimal command-line checking + if ( argc < 3 || argc > 6 ) usage(); + + RtAudio adc; + if ( adc.getDeviceCount() < 1 ) { + std::cout << "\nNo audio devices found!\n"; + exit( 0 ); + } + + channels = (unsigned int) atoi( argv[1] ); + fs = (unsigned int) atoi( argv[2] ); + if ( argc > 3 ) + time = (double) atof( argv[3] ); + if ( argc > 4 ) + device = (unsigned int) atoi( argv[4] ); + if ( argc > 5 ) + offset = (unsigned int) atoi( argv[5] ); + + // Let RtAudio print messages to stderr. + adc.showWarnings( true ); + + // Set our stream parameters for input only. + bufferFrames = 512; + RtAudio::StreamParameters iParams; + iParams.deviceId = device; + iParams.nChannels = channels; + iParams.firstChannel = offset; + + InputData data; + data.buffer = 0; + try { + adc.openStream( NULL, &iParams, FORMAT, fs, &bufferFrames, &input, (void *)&data ); + } + catch ( RtError& e ) { + std::cout << '\n' << e.getMessage() << '\n' << std::endl; + goto cleanup; + } + + data.bufferBytes = bufferFrames * channels * sizeof( MY_TYPE ); + data.totalFrames = (unsigned long) (fs * time); + data.frameCounter = 0; + data.channels = channels; + unsigned long totalBytes; + totalBytes = data.totalFrames * channels * sizeof( MY_TYPE ); + + // Allocate the entire data buffer before starting stream. + data.buffer = (MY_TYPE*) malloc( totalBytes ); + if ( data.buffer == 0 ) { + std::cout << "Memory allocation error ... quitting!\n"; + goto cleanup; + } + + try { + adc.startStream(); + } + catch ( RtError& e ) { + std::cout << '\n' << e.getMessage() << '\n' << std::endl; + goto cleanup; + } + + std::cout << "\nRecording for " << time << " seconds ... writing file 'record.raw' (buffer frames = " << bufferFrames << ")." << std::endl; + while ( 1 ) { + SLEEP( 100 ); // wake every 100 ms to check if we're done + if ( adc.isStreamRunning() == false ) break; + } + + // Now write the entire data to the file. + fd = fopen( "record.raw", "wb" ); + fwrite( data.buffer, sizeof( MY_TYPE ), data.totalFrames * channels, fd ); + fclose(fd); + + cleanup: + if ( adc.isStreamOpen() ) adc.closeStream(); + if ( data.buffer ) free( data.buffer ); + + return 0; +} |
