Version 3.0.2
[rtaudio.git] / tests / play_saw.cpp
1 /******************************************/
2 /*
3   play_saw.c
4   by Gary P. Scavone, 2001
5
6   Play sawtooth waveforms of distinct frequency.
7   Takes number of channels and sample rate as
8   input arguments.  Uses blocking functionality.
9 */
10 /******************************************/
11
12 #include "RtAudio.h"
13 #include <iostream>
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   4.0
45
46 void usage(void) {
47   // Error function in case of incorrect command-line
48   // argument specifications.
49   std::cout << "\nuseage: play_saw N fs <device>\n";
50   std::cout << "    where N = number of channels,\n";
51   std::cout << "    fs = the sample rate,\n";
52   std::cout << "    and device = the device to use (default = 0).\n\n";
53   exit(0);
54 }
55
56 int main(int argc, char *argv[])
57 {
58   int chans, fs, buffer_size, device = 0;
59   long frames, counter = 0, i, j;
60   MY_TYPE *buffer;
61   RtAudio *audio = 0;
62   double *data = 0;
63
64   // minimal command-line checking
65   if (argc != 3 && argc != 4 ) usage();
66
67   chans = (int) atoi(argv[1]);
68   fs = (int) atoi(argv[2]);
69   if ( argc == 4 )
70     device = (int) atoi(argv[3]);
71
72   // Open the realtime output device
73   buffer_size = 512;
74   try {
75     audio = new RtAudio(device, chans, 0, 0,
76                         FORMAT, fs, &buffer_size, 4);
77   }
78   catch (RtError &error) {
79     error.printMessage();
80     exit(EXIT_FAILURE);
81   }
82
83   frames = (long) (fs * TIME);
84   data = (double *) calloc(chans, sizeof(double));
85
86   try {
87     buffer = (MY_TYPE *) audio->getStreamBuffer();
88     audio->startStream();
89   }
90   catch (RtError &error) {
91     error.printMessage();
92     goto cleanup;
93   }
94
95   std::cout << "\nPlaying for " << TIME << " seconds ... buffer size = " << buffer_size << "." << std::endl;
96   while (counter < frames) {
97     for (i=0; i<buffer_size; i++) {
98       for (j=0; j<chans; j++) {
99         buffer[i*chans+j] = (MY_TYPE) (data[j] * SCALE);
100         data[j] += BASE_RATE * (j+1+(j*0.1));
101         if (data[j] >= 1.0) data[j] -= 2.0;
102       }
103     }
104
105     try {
106       audio->tickStream();
107     }
108     catch (RtError &error) {
109       error.printMessage();
110       goto cleanup;
111     }
112
113     counter += buffer_size;
114   }
115
116   try {
117     audio->stopStream();
118   }
119   catch (RtError &error) {
120     error.printMessage();
121   }
122
123  cleanup:
124   audio->closeStream();
125   delete audio;
126   if (data) free(data);
127
128   return 0;
129 }