Chris@4
|
1 #include "portaudiocpp/System.hxx"
|
Chris@4
|
2
|
Chris@4
|
3 #include <cstddef>
|
Chris@4
|
4 #include <cassert>
|
Chris@4
|
5
|
Chris@4
|
6 #include "portaudiocpp/HostApi.hxx"
|
Chris@4
|
7 #include "portaudiocpp/Device.hxx"
|
Chris@4
|
8 #include "portaudiocpp/Stream.hxx"
|
Chris@4
|
9 #include "portaudiocpp/Exception.hxx"
|
Chris@4
|
10 #include "portaudiocpp/SystemHostApiIterator.hxx"
|
Chris@4
|
11 #include "portaudiocpp/SystemDeviceIterator.hxx"
|
Chris@4
|
12
|
Chris@4
|
13 namespace portaudio
|
Chris@4
|
14 {
|
Chris@4
|
15 // -----------------------------------------------------------------------------------
|
Chris@4
|
16
|
Chris@4
|
17 // Static members:
|
Chris@4
|
18 System *System::instance_ = NULL;
|
Chris@4
|
19 int System::initCount_ = 0;
|
Chris@4
|
20 HostApi **System::hostApis_ = NULL;
|
Chris@4
|
21 Device **System::devices_ = NULL;
|
Chris@4
|
22 Device *System::nullDevice_ = NULL;
|
Chris@4
|
23
|
Chris@4
|
24 // -----------------------------------------------------------------------------------
|
Chris@4
|
25
|
Chris@4
|
26 int System::version()
|
Chris@4
|
27 {
|
Chris@4
|
28 return Pa_GetVersion();
|
Chris@4
|
29 }
|
Chris@4
|
30
|
Chris@4
|
31 const char *System::versionText()
|
Chris@4
|
32 {
|
Chris@4
|
33 return Pa_GetVersionText();
|
Chris@4
|
34 }
|
Chris@4
|
35
|
Chris@4
|
36 void System::initialize()
|
Chris@4
|
37 {
|
Chris@4
|
38 ++initCount_;
|
Chris@4
|
39
|
Chris@4
|
40 if (initCount_ == 1)
|
Chris@4
|
41 {
|
Chris@4
|
42 // Create singleton:
|
Chris@4
|
43 assert(instance_ == NULL);
|
Chris@4
|
44 instance_ = new System();
|
Chris@4
|
45
|
Chris@4
|
46 // Initialize the PortAudio system:
|
Chris@4
|
47 {
|
Chris@4
|
48 PaError err = Pa_Initialize();
|
Chris@4
|
49
|
Chris@4
|
50 if (err != paNoError)
|
Chris@4
|
51 throw PaException(err);
|
Chris@4
|
52 }
|
Chris@4
|
53
|
Chris@4
|
54 // Create and populate device array:
|
Chris@4
|
55 {
|
Chris@4
|
56 int numDevices = instance().deviceCount();
|
Chris@4
|
57
|
Chris@4
|
58 devices_ = new Device*[numDevices];
|
Chris@4
|
59
|
Chris@4
|
60 for (int i = 0; i < numDevices; ++i)
|
Chris@4
|
61 devices_[i] = new Device(i);
|
Chris@4
|
62 }
|
Chris@4
|
63
|
Chris@4
|
64 // Create and populate host api array:
|
Chris@4
|
65 {
|
Chris@4
|
66 int numHostApis = instance().hostApiCount();
|
Chris@4
|
67
|
Chris@4
|
68 hostApis_ = new HostApi*[numHostApis];
|
Chris@4
|
69
|
Chris@4
|
70 for (int i = 0; i < numHostApis; ++i)
|
Chris@4
|
71 hostApis_[i] = new HostApi(i);
|
Chris@4
|
72 }
|
Chris@4
|
73
|
Chris@4
|
74 // Create null device:
|
Chris@4
|
75 nullDevice_ = new Device(paNoDevice);
|
Chris@4
|
76 }
|
Chris@4
|
77 }
|
Chris@4
|
78
|
Chris@4
|
79 void System::terminate()
|
Chris@4
|
80 {
|
Chris@4
|
81 PaError err = paNoError;
|
Chris@4
|
82
|
Chris@4
|
83 if (initCount_ == 1)
|
Chris@4
|
84 {
|
Chris@4
|
85 // Destroy null device:
|
Chris@4
|
86 delete nullDevice_;
|
Chris@4
|
87
|
Chris@4
|
88 // Destroy host api array:
|
Chris@4
|
89 {
|
Chris@4
|
90 if (hostApis_ != NULL)
|
Chris@4
|
91 {
|
Chris@4
|
92 int numHostApis = instance().hostApiCount();
|
Chris@4
|
93
|
Chris@4
|
94 for (int i = 0; i < numHostApis; ++i)
|
Chris@4
|
95 delete hostApis_[i];
|
Chris@4
|
96
|
Chris@4
|
97 delete[] hostApis_;
|
Chris@4
|
98 hostApis_ = NULL;
|
Chris@4
|
99 }
|
Chris@4
|
100 }
|
Chris@4
|
101
|
Chris@4
|
102 // Destroy device array:
|
Chris@4
|
103 {
|
Chris@4
|
104 if (devices_ != NULL)
|
Chris@4
|
105 {
|
Chris@4
|
106 int numDevices = instance().deviceCount();
|
Chris@4
|
107
|
Chris@4
|
108 for (int i = 0; i < numDevices; ++i)
|
Chris@4
|
109 delete devices_[i];
|
Chris@4
|
110
|
Chris@4
|
111 delete[] devices_;
|
Chris@4
|
112 devices_ = NULL;
|
Chris@4
|
113 }
|
Chris@4
|
114 }
|
Chris@4
|
115
|
Chris@4
|
116 // Terminate the PortAudio system:
|
Chris@4
|
117 assert(instance_ != NULL);
|
Chris@4
|
118 err = Pa_Terminate();
|
Chris@4
|
119
|
Chris@4
|
120 // Destroy singleton:
|
Chris@4
|
121 delete instance_;
|
Chris@4
|
122 instance_ = NULL;
|
Chris@4
|
123 }
|
Chris@4
|
124
|
Chris@4
|
125 if (initCount_ > 0)
|
Chris@4
|
126 --initCount_;
|
Chris@4
|
127
|
Chris@4
|
128 if (err != paNoError)
|
Chris@4
|
129 throw PaException(err);
|
Chris@4
|
130 }
|
Chris@4
|
131
|
Chris@4
|
132
|
Chris@4
|
133 System &System::instance()
|
Chris@4
|
134 {
|
Chris@4
|
135 assert(exists());
|
Chris@4
|
136
|
Chris@4
|
137 return *instance_;
|
Chris@4
|
138 }
|
Chris@4
|
139
|
Chris@4
|
140 bool System::exists()
|
Chris@4
|
141 {
|
Chris@4
|
142 return (instance_ != NULL);
|
Chris@4
|
143 }
|
Chris@4
|
144
|
Chris@4
|
145 // -----------------------------------------------------------------------------------
|
Chris@4
|
146
|
Chris@4
|
147 System::HostApiIterator System::hostApisBegin()
|
Chris@4
|
148 {
|
Chris@4
|
149 System::HostApiIterator tmp;
|
Chris@4
|
150 tmp.ptr_ = &hostApis_[0]; // begin (first element)
|
Chris@4
|
151 return tmp;
|
Chris@4
|
152 }
|
Chris@4
|
153
|
Chris@4
|
154 System::HostApiIterator System::hostApisEnd()
|
Chris@4
|
155 {
|
Chris@4
|
156 int count = hostApiCount();
|
Chris@4
|
157
|
Chris@4
|
158 System::HostApiIterator tmp;
|
Chris@4
|
159 tmp.ptr_ = &hostApis_[count]; // end (one past last element)
|
Chris@4
|
160 return tmp;
|
Chris@4
|
161 }
|
Chris@4
|
162
|
Chris@4
|
163 HostApi &System::defaultHostApi()
|
Chris@4
|
164 {
|
Chris@4
|
165 PaHostApiIndex defaultHostApi = Pa_GetDefaultHostApi();
|
Chris@4
|
166
|
Chris@4
|
167 if (defaultHostApi < 0)
|
Chris@4
|
168 throw PaException(defaultHostApi);
|
Chris@4
|
169
|
Chris@4
|
170 return *hostApis_[defaultHostApi];
|
Chris@4
|
171 }
|
Chris@4
|
172
|
Chris@4
|
173 HostApi &System::hostApiByTypeId(PaHostApiTypeId type)
|
Chris@4
|
174 {
|
Chris@4
|
175 PaHostApiIndex index = Pa_HostApiTypeIdToHostApiIndex(type);
|
Chris@4
|
176
|
Chris@4
|
177 if (index < 0)
|
Chris@4
|
178 throw PaException(index);
|
Chris@4
|
179
|
Chris@4
|
180 return *hostApis_[index];
|
Chris@4
|
181 }
|
Chris@4
|
182
|
Chris@4
|
183 HostApi &System::hostApiByIndex(PaHostApiIndex index)
|
Chris@4
|
184 {
|
Chris@4
|
185 if (index < 0 || index >= hostApiCount())
|
Chris@4
|
186 throw PaException(paInternalError);
|
Chris@4
|
187
|
Chris@4
|
188 return *hostApis_[index];
|
Chris@4
|
189 }
|
Chris@4
|
190
|
Chris@4
|
191 int System::hostApiCount()
|
Chris@4
|
192 {
|
Chris@4
|
193 PaHostApiIndex count = Pa_GetHostApiCount();
|
Chris@4
|
194
|
Chris@4
|
195 if (count < 0)
|
Chris@4
|
196 throw PaException(count);
|
Chris@4
|
197
|
Chris@4
|
198 return count;
|
Chris@4
|
199 }
|
Chris@4
|
200
|
Chris@4
|
201 // -----------------------------------------------------------------------------------
|
Chris@4
|
202
|
Chris@4
|
203 System::DeviceIterator System::devicesBegin()
|
Chris@4
|
204 {
|
Chris@4
|
205 DeviceIterator tmp;
|
Chris@4
|
206 tmp.ptr_ = &devices_[0];
|
Chris@4
|
207
|
Chris@4
|
208 return tmp;
|
Chris@4
|
209 }
|
Chris@4
|
210
|
Chris@4
|
211 System::DeviceIterator System::devicesEnd()
|
Chris@4
|
212 {
|
Chris@4
|
213 int count = deviceCount();
|
Chris@4
|
214
|
Chris@4
|
215 DeviceIterator tmp;
|
Chris@4
|
216 tmp.ptr_ = &devices_[count];
|
Chris@4
|
217
|
Chris@4
|
218 return tmp;
|
Chris@4
|
219 }
|
Chris@4
|
220
|
Chris@4
|
221 //////
|
Chris@4
|
222 /// Returns the System's default input Device, or the null Device if none
|
Chris@4
|
223 /// was available.
|
Chris@4
|
224 //////
|
Chris@4
|
225 Device &System::defaultInputDevice()
|
Chris@4
|
226 {
|
Chris@4
|
227 PaDeviceIndex index = Pa_GetDefaultInputDevice();
|
Chris@4
|
228 return deviceByIndex(index);
|
Chris@4
|
229 }
|
Chris@4
|
230
|
Chris@4
|
231 //////
|
Chris@4
|
232 /// Returns the System's default output Device, or the null Device if none
|
Chris@4
|
233 /// was available.
|
Chris@4
|
234 //////
|
Chris@4
|
235 Device &System::defaultOutputDevice()
|
Chris@4
|
236 {
|
Chris@4
|
237 PaDeviceIndex index = Pa_GetDefaultOutputDevice();
|
Chris@4
|
238 return deviceByIndex(index);
|
Chris@4
|
239 }
|
Chris@4
|
240
|
Chris@4
|
241 //////
|
Chris@4
|
242 /// Returns the Device for the given index.
|
Chris@4
|
243 /// Will throw a paInternalError equivalent PaException if the given index
|
Chris@4
|
244 /// is out of range.
|
Chris@4
|
245 //////
|
Chris@4
|
246 Device &System::deviceByIndex(PaDeviceIndex index)
|
Chris@4
|
247 {
|
Chris@4
|
248 if (index < -1 || index >= deviceCount())
|
Chris@4
|
249 {
|
Chris@4
|
250 throw PaException(paInternalError);
|
Chris@4
|
251 }
|
Chris@4
|
252
|
Chris@4
|
253 if (index == -1)
|
Chris@4
|
254 return System::instance().nullDevice();
|
Chris@4
|
255
|
Chris@4
|
256 return *devices_[index];
|
Chris@4
|
257 }
|
Chris@4
|
258
|
Chris@4
|
259 int System::deviceCount()
|
Chris@4
|
260 {
|
Chris@4
|
261 PaDeviceIndex count = Pa_GetDeviceCount();
|
Chris@4
|
262
|
Chris@4
|
263 if (count < 0)
|
Chris@4
|
264 throw PaException(count);
|
Chris@4
|
265
|
Chris@4
|
266 return count;
|
Chris@4
|
267 }
|
Chris@4
|
268
|
Chris@4
|
269 Device &System::nullDevice()
|
Chris@4
|
270 {
|
Chris@4
|
271 return *nullDevice_;
|
Chris@4
|
272 }
|
Chris@4
|
273
|
Chris@4
|
274 // -----------------------------------------------------------------------------------
|
Chris@4
|
275
|
Chris@4
|
276 void System::sleep(long msec)
|
Chris@4
|
277 {
|
Chris@4
|
278 Pa_Sleep(msec);
|
Chris@4
|
279 }
|
Chris@4
|
280
|
Chris@4
|
281 int System::sizeOfSample(PaSampleFormat format)
|
Chris@4
|
282 {
|
Chris@4
|
283 PaError err = Pa_GetSampleSize(format);
|
Chris@4
|
284 if (err < 0)
|
Chris@4
|
285 {
|
Chris@4
|
286 throw PaException(err);
|
Chris@4
|
287 return 0;
|
Chris@4
|
288 }
|
Chris@4
|
289
|
Chris@4
|
290 return err;
|
Chris@4
|
291 }
|
Chris@4
|
292
|
Chris@4
|
293 // -----------------------------------------------------------------------------------
|
Chris@4
|
294
|
Chris@4
|
295 System::System()
|
Chris@4
|
296 {
|
Chris@4
|
297 // (left blank intentionally)
|
Chris@4
|
298 }
|
Chris@4
|
299
|
Chris@4
|
300 System::~System()
|
Chris@4
|
301 {
|
Chris@4
|
302 // (left blank intentionally)
|
Chris@4
|
303 }
|
Chris@4
|
304
|
Chris@4
|
305 // -----------------------------------------------------------------------------------
|
Chris@4
|
306
|
Chris@4
|
307 } // namespace portaudio
|
Chris@4
|
308
|