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