Check in of new version 4.0.0 distribution (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 typedef signed short  MY_TYPE;
24 #define FORMAT RTAUDIO_SINT16
25 #define SCALE  32767.0
26
27 typedef signed long  MY_TYPE;
28 #define FORMAT RTAUDIO_SINT32
29 #define SCALE  2147483647.0
30 */
31
32 typedef float  MY_TYPE;
33 #define FORMAT RTAUDIO_FLOAT32
34 #define SCALE  1.0
35
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( 0 );
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;
133   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
146   options.flags |= RTAUDIO_HOG_DEVICE;
147 #if !defined( USE_INTERLEAVED )
148   options.flags |= RTAUDIO_NONINTERLEAVED;
149 #endif
150   try {
151     dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &saw, (void *)data, &options );
152     dac.startStream();
153   }
154   catch ( RtError& e ) {
155     e.printMessage();
156     goto cleanup;
157   }
158
159   char input;
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     std::cout << "Stream latency = " << dac.getStreamLatency() << "\n" << std::endl;
166     dac.stopStream();
167   }
168   catch ( RtError& e ) {
169     e.printMessage();
170   }
171
172  cleanup:
173   if ( dac.isStreamOpen() ) dac.closeStream();
174   free( data );
175
176   return 0;
177 }