summaryrefslogtreecommitdiff
path: root/tests/record.cpp
diff options
context:
space:
mode:
authorGary Scavone <gary@music.mcgill.ca>2007-08-07 14:52:05 +0000
committerStephen Sinclair <sinclair@music.mcgill.ca>2013-10-11 01:19:40 +0200
commitb0080e69d64ce69e21c8ce1b22b1bb7f888f1e58 (patch)
treeb51ebcd31a5280b4f4e9e45484f07d9b35723743 /tests/record.cpp
parent0fbcd74a04713a4725d2f346a493121b623d60ab (diff)
Check in of new version 4.0.0 distribution (GS).
Diffstat (limited to 'tests/record.cpp')
-rw-r--r--tests/record.cpp169
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;
+}