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