Version 2.0.1
[rtaudio-cdist.git] / tests / twostreams.cpp
1 /******************************************/
2 /*
3   twostreams.cpp
4   by Gary P. Scavone, 2001
5
6   Text executable for audio playback,
7   recording, duplex operation, stopping,
8   starting, and aborting operations.
9   Takes number of channels and sample
10   rate as input arguments.  Runs input
11   and output through two separate streams.
12   Uses blocking functionality.
13 */
14 /******************************************/
15
16 #include "RtAudio.h"
17 #include <iostream.h>
18 #include <stdio.h>
19
20 /*
21 typedef signed long  MY_TYPE;
22 #define FORMAT RtAudio::RTAUDIO_SINT24
23 #define SCALE  2147483647.0
24
25 typedef char  MY_TYPE;
26 #define FORMAT RtAudio::RTAUDIO_SINT8
27 #define SCALE  127.0
28
29 typedef signed short  MY_TYPE;
30 #define FORMAT RtAudio::RTAUDIO_SINT16
31 #define SCALE  32767.0
32
33 typedef signed long  MY_TYPE;
34 #define FORMAT RtAudio::RTAUDIO_SINT32
35 #define SCALE  2147483647.0
36
37 typedef float  MY_TYPE;
38 #define FORMAT RtAudio::RTAUDIO_FLOAT32
39 #define SCALE  1.0
40 */
41
42 typedef double  MY_TYPE;
43 #define FORMAT RtAudio::RTAUDIO_FLOAT64
44 #define SCALE  1.0
45
46 #define BASE_RATE 0.005
47 #define TIME 2.0
48
49 void usage(void) {
50   /* Error function in case of incorrect command-line
51      argument specifications
52   */
53   cout << "\nuseage: twostreams N fs\n";
54   cout << "    where N = number of channels,\n";
55   cout << "    and fs = the sample rate.\n\n";
56   exit(0);
57 }
58
59 int main(int argc, char *argv[])
60 {
61   int chans, fs, device, buffer_size, stream1, stream2;
62   long frames, counter = 0, i, j;
63   MY_TYPE *buffer1, *buffer2;
64   RtAudio *audio;
65   FILE *fd;
66   double *data;
67
68   // minimal command-line checking
69   if (argc != 3) usage();
70
71   chans = (int) atoi(argv[1]);
72   fs = (int) atoi(argv[2]);
73
74   // Open the realtime output device
75   buffer_size = 512;
76   device = 0; // default device
77   try {
78     audio = new RtAudio();
79   }
80   catch (RtError &) {
81     exit(EXIT_FAILURE);
82   }
83
84   try {
85     stream1 = audio->openStream(device, chans, 0, 0,
86                                 FORMAT, fs, &buffer_size, 8);
87     stream2 = audio->openStream(0, 0, device, chans,
88                                 FORMAT, fs, &buffer_size, 8);
89     buffer1 = (MY_TYPE *) audio->getStreamBuffer(stream1);
90     buffer2 = (MY_TYPE *) audio->getStreamBuffer(stream2);
91   }
92   catch (RtError &) {
93     goto cleanup;
94   }
95
96   frames = (long) (fs * TIME);
97   data = (double *) calloc(chans, sizeof(double));
98
99   try {
100     audio->startStream(stream1);
101   }
102   catch (RtError &) {
103     goto cleanup;
104   }
105
106   cout << "\nStarting sawtooth playback stream for " << TIME << " seconds." << endl;
107   while (counter < frames) {
108     for (i=0; i<buffer_size; i++) {
109       for (j=0; j<chans; j++) {
110         buffer1[i*chans+j] = (MY_TYPE) (data[j] * SCALE);
111         data[j] += BASE_RATE * (j+1+(j*0.1));
112         if (data[j] >= 1.0) data[j] -= 2.0;
113       }
114     }
115
116     try {
117       audio->tickStream(stream1);
118     }
119     catch (RtError &) {
120       goto cleanup;
121     }
122
123     counter += buffer_size;
124   }
125
126   cout << "\nStopping playback stream." << endl;
127   try {
128     audio->stopStream(stream1);
129     audio->startStream(stream2);
130   }
131   catch (RtError &) {
132     goto cleanup;
133   }
134
135   fd = fopen("test.raw","wb");
136
137   counter = 0;
138   cout << "\nStarting recording stream for " << TIME << " seconds." << endl;
139   while (counter < frames) {
140
141     try {
142       audio->tickStream(stream2);
143     }
144     catch (RtError &) {
145       goto cleanup;
146     }
147
148     fwrite(buffer2, sizeof(MY_TYPE), chans * buffer_size, fd);
149     counter += buffer_size;
150   }
151
152   fclose(fd);
153   cout << "\nAborting recording." << endl;
154
155   try {
156     audio->abortStream(stream2);
157     audio->startStream(stream1);
158     audio->startStream(stream2);
159   }
160   catch (RtError &) {
161     goto cleanup;
162   }
163
164   counter = 0;
165   cout << "\nStarting playback and record streams (quasi-duplex) for " << TIME << " seconds." << endl;
166   while (counter < frames) {
167
168     try {
169       audio->tickStream(stream2);
170       memcpy(buffer1, buffer2, sizeof(MY_TYPE) * chans * buffer_size);
171       audio->tickStream(stream1);
172     }
173     catch (RtError &) {
174       goto cleanup;
175     }
176
177     counter += buffer_size;
178   }
179
180   cout << "\nStopping both streams." << endl;
181   try {
182     audio->stopStream(stream1);
183     audio->stopStream(stream2);
184   }
185   catch (RtError &) {
186   }
187
188  cleanup:
189   audio->closeStream(stream1);
190   audio->closeStream(stream2);
191   delete audio;
192   if (data) free(data);
193
194   return 0;
195 }