1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
/******************************************/
/*
playraw.cpp
by Gary P. Scavone, 2007
Play a specified raw file. It is necessary
that the file be of the same data format as
defined below.
*/
/******************************************/
#include "RtAudio.h"
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <stdio.h>
/*
typedef char MY_TYPE;
#define FORMAT RTAUDIO_SINT8
#define SCALE 127.0
*/
typedef signed short MY_TYPE;
#define FORMAT RTAUDIO_SINT16
#define SCALE 32767.0
/*
typedef S24 MY_TYPE;
#define FORMAT RTAUDIO_SINT24
#define SCALE 8388607.0
typedef signed int MY_TYPE;
#define FORMAT RTAUDIO_SINT32
#define SCALE 2147483647.0
typedef float MY_TYPE;
#define FORMAT RTAUDIO_FLOAT32
#define SCALE 1.0;
typedef double MY_TYPE;
#define FORMAT RTAUDIO_FLOAT64
#define SCALE 1.0;
*/
// Platform-dependent sleep routines.
#if defined( __WINDOWS_ASIO__ ) || defined( __WINDOWS_DS__ ) || defined( __WINDOWS_WASAPI__ )
#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: playraw N fs file <device> <channelOffset>\n";
std::cout << " where N = number of channels,\n";
std::cout << " fs = the sample rate, \n";
std::cout << " file = the raw file to play,\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 OutputData {
FILE *fd;
unsigned int channels;
};
// Interleaved buffers
int output( void *outputBuffer, void * /*inputBuffer*/, unsigned int nBufferFrames,
double /*streamTime*/, RtAudioStreamStatus /*status*/, void *data )
{
OutputData *oData = (OutputData*) data;
// In general, it's not a good idea to do file input in the audio
// callback function but I'm doing it here because I don't know the
// length of the file we are reading.
unsigned int count = fread( outputBuffer, oData->channels * sizeof( MY_TYPE ), nBufferFrames, oData->fd);
if ( count < nBufferFrames ) {
unsigned int bytes = (nBufferFrames - count) * oData->channels * sizeof( MY_TYPE );
unsigned int startByte = count * oData->channels * sizeof( MY_TYPE );
memset( (char *)(outputBuffer)+startByte, 0, bytes );
return 1;
}
return 0;
}
int main( int argc, char *argv[] )
{
unsigned int channels, fs, bufferFrames, device = 0, offset = 0;
char *file;
// minimal command-line checking
if ( argc < 4 || argc > 6 ) usage();
RtAudio dac;
if ( dac.getDeviceCount() < 1 ) {
std::cout << "\nNo audio devices found!\n";
exit( 0 );
}
channels = (unsigned int) atoi( argv[1]) ;
fs = (unsigned int) atoi( argv[2] );
file = argv[3];
if ( argc > 4 )
device = (unsigned int) atoi( argv[4] );
if ( argc > 5 )
offset = (unsigned int) atoi( argv[5] );
OutputData data;
data.fd = fopen( file, "rb" );
if ( !data.fd ) {
std::cout << "Unable to find or open file!\n";
exit( 1 );
}
// Set our stream parameters for output only.
bufferFrames = 512;
RtAudio::StreamParameters oParams;
oParams.deviceId = device;
oParams.nChannels = channels;
oParams.firstChannel = offset;
if ( device == 0 )
oParams.deviceId = dac.getDefaultOutputDevice();
data.channels = channels;
try {
dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &output, (void *)&data );
dac.startStream();
}
catch ( RtAudioError& e ) {
std::cout << '\n' << e.getMessage() << '\n' << std::endl;
goto cleanup;
}
std::cout << "\nPlaying raw file " << file << " (buffer frames = " << bufferFrames << ")." << std::endl;
while ( 1 ) {
SLEEP( 100 ); // wake every 100 ms to check if we're done
if ( dac.isStreamRunning() == false ) break;
}
cleanup:
fclose( data.fd );
dac.closeStream();
return 0;
}
|