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
|
/******************************************/
/*
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>
/*
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 signed long MY_TYPE;
#define FORMAT RTAUDIO_SINT24
#define SCALE 8388607.0
typedef signed long 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__ )
#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;
data.channels = channels;
try {
dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &output, (void *)&data );
dac.startStream();
}
catch ( RtError& 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;
}
|