Updates to OS-X for multi-stream support (GS).
[rtaudio-cdist.git] / tests / playsaw.cpp
1 /******************************************/
2 /*
3   playsaw.cpp
4   by Gary P. Scavone, 2006
5
6   This program will output sawtooth waveforms
7   of different frequencies on each channel.
8 */
9 /******************************************/
10
11 #include "RtAudio.h"
12 #include <iostream>
13
14 /*
15 typedef signed long  MY_TYPE;
16 #define FORMAT RTAUDIO_SINT24
17 #define SCALE  2147483647.0
18
19 typedef char  MY_TYPE;
20 #define FORMAT RTAUDIO_SINT8
21 #define SCALE  127.0
22 */
23
24 typedef signed short  MY_TYPE;
25 #define FORMAT RTAUDIO_SINT16
26 #define SCALE  32767.0
27
28 /*
29 typedef signed long  MY_TYPE;
30 #define FORMAT RTAUDIO_SINT32
31 #define SCALE  2147483647.0
32
33 typedef float  MY_TYPE;
34 #define FORMAT RTAUDIO_FLOAT32
35 #define SCALE  1.0
36
37 typedef double  MY_TYPE;
38 #define FORMAT RTAUDIO_FLOAT64
39 #define SCALE  1.0
40 */
41
42 #define BASE_RATE 0.005
43 #define TIME   1.0
44
45 void usage( void ) {
46   // Error function in case of incorrect command-line
47   // argument specifications
48   std::cout << "\nuseage: playsaw N fs <device> <channelOffset>\n";
49   std::cout << "    where N = number of channels,\n";
50   std::cout << "    fs = the sample rate,\n";
51   std::cout << "    device = optional device to use (default = 0),\n";
52   std::cout << "    and channelOffset = an optional channel offset on the device (default = 0).\n\n";
53   exit( 0 );
54 }
55
56 unsigned int channels;
57 RtAudio::StreamOptions options;
58
59 //#define USE_INTERLEAVED
60 #if defined( USE_INTERLEAVED )
61
62 // Interleaved buffers
63 int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
64          double streamTime, RtAudioStreamStatus status, void *data )
65 {
66   unsigned int i, j;
67   extern unsigned int channels;
68   MY_TYPE *buffer = (MY_TYPE *) outputBuffer;
69   double *lastValues = (double *) data;
70
71   if ( status )
72     std::cout << "Stream underflow detected!" << std::endl;
73
74   for ( i=0; i<nBufferFrames; i++ ) {
75     for ( j=0; j<channels; j++ ) {
76       *buffer++ = (MY_TYPE) (lastValues[j] * SCALE);
77       lastValues[j] += BASE_RATE * (j+1+(j*0.1));
78       if ( lastValues[j] >= 1.0 ) lastValues[j] -= 2.0;
79     }
80   }
81
82   return 0;
83 }
84
85 #else // Use non-interleaved buffers
86
87 int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
88          double streamTime, RtAudioStreamStatus status, void *data )
89 {
90   unsigned int i, j;
91   extern unsigned int channels;
92   MY_TYPE *buffer = (MY_TYPE *) outputBuffer;
93   double *lastValues = (double *) data;
94
95   if ( status )
96     std::cout << "Stream underflow detected!" << std::endl;
97
98   double increment;
99   for ( j=0; j<channels; j++ ) {
100     increment = BASE_RATE * (j+1+(j*0.1));
101     for ( i=0; i<nBufferFrames; i++ ) {
102       *buffer++ = (MY_TYPE) (lastValues[j] * SCALE);
103       lastValues[j] += increment;
104       if ( lastValues[j] >= 1.0 ) lastValues[j] -= 2.0;
105     }
106   }
107
108   return 0;
109 }
110 #endif
111
112 int main( int argc, char *argv[] )
113 {
114   unsigned int bufferFrames, fs, device = 0, offset = 0;
115
116   // minimal command-line checking
117   if (argc < 3 || argc > 5 ) usage();
118
119   RtAudio dac;
120   if ( dac.getDeviceCount() < 1 ) {
121     std::cout << "\nNo audio devices found!\n";
122     exit( 1 );
123   }
124
125   channels = (unsigned int) atoi( argv[1] );
126   fs = (unsigned int) atoi( argv[2] );
127   if ( argc > 3 )
128     device = (unsigned int) atoi( argv[3] );
129   if ( argc > 4 )
130     offset = (unsigned int) atoi( argv[4] );
131
132   double *data = (double *) calloc( channels, sizeof( double ) );
133
134   // Let RtAudio print messages to stderr.
135   dac.showWarnings( true );
136
137   // Set our stream parameters for output only.
138   bufferFrames = 256;
139   RtAudio::StreamParameters oParams;
140   oParams.deviceId = device;
141   oParams.nChannels = channels;
142   oParams.firstChannel = offset;
143
144   options.flags |= RTAUDIO_HOG_DEVICE;
145 #if !defined( USE_INTERLEAVED )
146   options.flags |= RTAUDIO_NONINTERLEAVED;
147 #endif
148   try {
149     dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &saw, (void *)data, &options );
150     dac.startStream();
151   }
152   catch ( RtError& e ) {
153     e.printMessage();
154     goto cleanup;
155   }
156
157   char input;
158   //std::cout << "Stream latency = " << dac.getStreamLatency() << "\n" << std::endl;
159   std::cout << "\nPlaying ... press <enter> to quit (buffer size = " << bufferFrames << ").\n";
160   std::cin.get( input );
161
162   try {
163     // Stop the stream
164     dac.stopStream();
165   }
166   catch ( RtError& e ) {
167     e.printMessage();
168   }
169
170  cleanup:
171   if ( dac.isStreamOpen() ) dac.closeStream();
172   free( data );
173
174   return 0;
175 }