NOOP, remove trailing tabs/whitespace.
[ardour.git] / libs / backends / wavesaudio / wavesapi / devicemanager / WCMRAudioDeviceManager.cpp
1 //----------------------------------------------------------------------------------
2 //
3 // Copyright (c) 2008 Waves Audio Ltd. All rights reserved.
4 //
5 //! \file       WCMRAudioDeviceManager.cpp
6 //!
7 //! WCMRAudioDeviceManager and related class declarations
8 //!
9 //---------------------------------------------------------------------------------*/
10 #include <iostream>
11 #include "WCMRAudioDeviceManager.h"
12
13
14 //**********************************************************************************************
15 // WCMRAudioDevice::WCMRAudioDevice
16 //
17 //! Constructor for the audio device. The derived classes will need to do more actual work, such
18 //!             as determining supported sampling rates, buffer sizes, and channel counts. Connection
19 //!             and streaming will also be provided by the derived implementations.
20 //!
21 //! \param *pManager : The audio device manager that's managing this device.
22 //! \return Nothing.
23 //!
24 //**********************************************************************************************
25 WCMRAudioDevice::WCMRAudioDevice (WCMRAudioDeviceManager *pManager) :
26         m_pMyManager (pManager)
27         , m_ConnectionStatus (DeviceDisconnected)
28         , m_IsActive (false)
29         , m_IsStreaming (false)
30         , m_CurrentSamplingRate (-1)
31         , m_CurrentBufferSize (0)
32         , m_LeftMonitorChannel (-1)
33         , m_RightMonitorChannel (-1)
34         , m_MonitorGain (1.0f)
35 {
36         m_DeviceName = "Unknown";
37 }
38
39
40
41 //**********************************************************************************************
42 // WCMRAudioDevice::~WCMRAudioDevice
43 //
44 //! Destructor for the audio device. It release all the connections that were created.
45 //!
46 //! \param none
47 //!
48 //! \return Nothing.
49 //!
50 //**********************************************************************************************
51 WCMRAudioDevice::~WCMRAudioDevice ()
52 {
53     AUTO_FUNC_DEBUG;
54         try
55         {
56         }
57         catch (...)
58         {
59                 //destructors should absorb exceptions, no harm in logging though!!
60                 DEBUG_MSG ("Exception during destructor");
61         }
62 }
63
64
65
66
67 //**********************************************************************************************
68 // WCMRAudioDevice::DeviceName
69 //
70 //! Retrieves Device's name.
71 //!
72 //! \param none
73 //!
74 //! \return The device name.
75 //!
76 //**********************************************************************************************
77 const std::string& WCMRAudioDevice::DeviceName () const
78 {
79         return (m_DeviceName);
80
81 }
82
83
84
85 //**********************************************************************************************
86 // WCMRAudioDevice::InputChannels
87 //
88 //! Retrieves Input Channel information. Note that the list may be changed at run-time.
89 //!
90 //! \param none
91 //!
92 //! \return A vector with Input Channel Names.
93 //!
94 //**********************************************************************************************
95 const std::vector<std::string>& WCMRAudioDevice::InputChannels ()
96 {
97         return (m_InputChannels);
98
99 }
100
101
102
103 //**********************************************************************************************
104 // WCMRAudioDevice::OutputChannels
105 //
106 //! Retrieves Output Channel Information. Note that the list may be changed at run-time.
107 //!
108 //! \param none
109 //!
110 //! \return A vector with Output Channel Names.
111 //!
112 //**********************************************************************************************
113 const std::vector<std::string>& WCMRAudioDevice::OutputChannels ()
114 {
115         return (m_OutputChannels);
116 }
117
118
119
120
121 //**********************************************************************************************
122 // WCMRAudioDevice::SamplingRates
123 //
124 //! Retrieves supported sampling rate information.
125 //!
126 //! \param none
127 //!
128 //! \return A vector with supported sampling rates.
129 //!
130 //**********************************************************************************************
131 const std::vector<int>& WCMRAudioDevice::SamplingRates ()
132 {
133         return (m_SamplingRates);
134 }
135
136
137
138 //**********************************************************************************************
139 // WCMRAudioDevice::CurrentSamplingRate
140 //
141 //! The device's current sampling rate. This may be overridden, if the device needs to
142 //!             query the driver for the current rate.
143 //!
144 //! \param none
145 //!
146 //! \return The device's current sampling rate. -1 on error.
147 //!
148 //**********************************************************************************************
149 int WCMRAudioDevice::CurrentSamplingRate ()
150 {
151         return (m_CurrentSamplingRate);
152 }
153
154
155
156
157 //**********************************************************************************************
158 // WCMRAudioDevice::SetCurrentSamplingRate
159 //
160 //! Change the sampling rate to be used by the device. This will most likely be overridden,
161 //!             the base class simply updates the member variable.
162 //!
163 //! \param newRate : The rate to use (samples per sec).
164 //!
165 //! \return eNoErr always. The derived classes may return error codes.
166 //!
167 //**********************************************************************************************
168 WTErr WCMRAudioDevice::SetCurrentSamplingRate (int newRate)
169 {
170         //changes the status.
171         m_CurrentSamplingRate = newRate;
172         return (eNoErr);
173 }
174
175
176
177
178 //**********************************************************************************************
179 // WCMRAudioDevice::BufferSizes
180 //
181 //! Retrieves supported buffer size information.
182 //!
183 //! \param none
184 //!
185 //! \return A vector with supported buffer sizes.
186 //!
187 //**********************************************************************************************
188 const std::vector<int>& WCMRAudioDevice::BufferSizes ()
189 {
190         return (m_BufferSizes);
191 }
192
193
194
195 //**********************************************************************************************
196 // WCMRAudioDevice::CurrentBufferSize
197 //
198 //! The device's current buffer size in use. This may be overridden, if the device needs to
199 //!             query the driver for the current size.
200 //!
201 //! \param none
202 //!
203 //! \return The device's current buffer size. 0 on error.
204 //!
205 //**********************************************************************************************
206 int WCMRAudioDevice::CurrentBufferSize ()
207 {
208         return (m_CurrentBufferSize);
209 }
210
211 //**********************************************************************************************
212 // WCMRAudioDevice::CurrentBlockSize
213 //
214 //! Device's block size we use for holding the audio samples.
215 //! Usually this is equal to the buffer size, but in some cases the buffer size holds additional
216 //!   data other then the audio buffers, like frames info in SG, so it can be overridden
217 //!
218 //! \param none
219 //!
220 //! \return The device's current block size. 0 on error.
221 //!
222 //**********************************************************************************************
223 int WCMRAudioDevice::CurrentBlockSize()
224 {
225     // By default - return the buffer size
226     return CurrentBufferSize();
227 }
228
229
230 //**********************************************************************************************
231 // WCMRAudioDevice::SetCurrentBufferSize
232 //
233 //! Change the buffer size to be used by the device. This will most likely be overridden,
234 //!             the base class simply updates the member variable.
235 //!
236 //! \param newSize : The buffer size to use (in sample-frames)
237 //!
238 //! \return eNoErr always. The derived classes may return error codes.
239 //!
240 //**********************************************************************************************
241 WTErr WCMRAudioDevice::SetCurrentBufferSize (int newSize)
242 {
243         //This will most likely be overridden, the base class simply
244         //changes the member.
245         m_CurrentBufferSize = newSize;
246         return (eNoErr);
247 }
248
249
250
251
252 //**********************************************************************************************
253 // WCMRAudioDevice::ConnectionStatus
254 //
255 //! Retrieves the device's current connection status. This will most likely be overridden,
256 //!             in case some driver communication is required to query the status.
257 //!
258 //! \param none
259 //!
260 //! \return A ConnectionStates value.
261 //!
262 //**********************************************************************************************
263 WCMRAudioDevice::ConnectionStates WCMRAudioDevice::ConnectionStatus ()
264 {
265         return (m_ConnectionStatus);
266
267 }
268
269
270
271
272 //**********************************************************************************************
273 // WCMRAudioDevice::Active
274 //
275 //! Retrieves Device activation status.
276 //!
277 //! \param none
278 //!
279 //! \return true if device is active, false otherwise.
280 //!
281 //**********************************************************************************************
282 bool WCMRAudioDevice::Active ()
283 {
284         return (m_IsActive);
285
286 }
287
288
289
290 //**********************************************************************************************
291 // WCMRAudioDevice::SetActive
292 //
293 //! Sets the device's activation status.
294 //!
295 //! \param newState : Should be true to activate, false to deactivate. This roughly corresponds
296 //!             to opening and closing the device handle/stream/audio unit.
297 //!
298 //! \return eNoErr always, the derived classes may return appropriate error code.
299 //!
300 //**********************************************************************************************
301 WTErr WCMRAudioDevice::SetActive (bool newState)
302 {
303         //This will most likely be overridden, the base class simply
304         //changes the member.
305         m_IsActive = newState;
306         return (eNoErr);
307 }
308
309
310
311
312 //**********************************************************************************************
313 // WCMRAudioDevice::Streaming
314 //
315 //! Retrieves Device streaming status.
316 //!
317 //! \param none
318 //!
319 //! \return true if device is streaming, false otherwise.
320 //!
321 //**********************************************************************************************
322 bool WCMRAudioDevice::Streaming ()
323 {
324         return (m_IsStreaming);
325 }
326
327
328
329 //**********************************************************************************************
330 // WCMRAudioDevice::SetStreaming
331 //
332 //! Sets the device's streaming status.
333 //!
334 //! \param newState : Should be true to start streaming, false to stop streaming. This roughly
335 //!             corresponds to calling Start/Stop on the lower level interface.
336 //!
337 //! \return eNoErr always, the derived classes may return appropriate error code.
338 //!
339 //**********************************************************************************************
340 WTErr WCMRAudioDevice::SetStreaming (bool newState)
341 {
342         // We must notify angine about our intention to start streming
343         // so Engine will provide all the initializations in the first audio callback
344         if (newState) {
345                 m_pMyManager->NotifyClient (WCMRAudioDeviceManagerClient::DeviceStartsStreaming);
346         }
347
348         //This will most likely be overridden, the base class simply
349         //changes the member.
350         m_IsStreaming = newState;
351         return (eNoErr);
352 }
353
354
355 WTErr WCMRAudioDevice::ResetDevice ()
356 {
357         // Keep device sates
358         bool wasStreaming = Streaming();
359         bool wasActive = Active();
360
361         WTErr err = SetStreaming(false);
362
363         if (err == eNoErr)
364                 err = SetActive(false);
365
366         if (err == eNoErr && wasActive)
367                 err = SetActive(true);
368
369         if (err == eNoErr && wasStreaming)
370                 SetStreaming(true);
371
372         return err;
373 }
374
375
376 ///////////////////////////////////////////////////////////////////////////////////////////////////////
377 // IsProcessActive - returns true if process code is running.
378 // A normal audio device should return the Streaming() value
379 ///////////////////////////////////////////////////////////////////////////////////////////////////////
380 bool WCMRAudioDevice::IsProcessActive()
381 {
382     return Streaming();
383 }
384
385
386
387
388
389 //**********************************************************************************************
390 // WCMRAudioDevice::DoIdle
391 //
392 //! A place for doing idle time processing. The derived classes will probably do something
393 //!             meaningful.
394 //!
395 //! \param none
396 //!
397 //! \return eNoErr always.
398 //!
399 //**********************************************************************************************
400 WTErr WCMRAudioDevice::DoIdle ()
401 {
402         //We don't need to do anything here...
403         //the derived classes may want to use this however.
404         return (eNoErr);
405 }
406
407
408
409
410 //**********************************************************************************************
411 // WCMRAudioDevice::InputLevels
412 //
413 //! Retrieve current input levels.
414 //!
415 //! \param none
416 //!
417 //! \return A vector (the same size as input channels list) that contains current input levels.
418 //!
419 //**********************************************************************************************
420 const std::vector<float>& WCMRAudioDevice::InputLevels ()
421 {
422         //The derived classes may override if they need to query
423         //the driver for the levels.
424         return (m_InputLevels);
425 }
426
427
428
429 //**********************************************************************************************
430 // WCMRAudioDevice::OutputLevels
431 //
432 //! Retrieve current output levels.
433 //!
434 //! \param none
435 //!
436 //! \return A vector (the same size as output channels list) that contains current output levels.
437 //!
438 //**********************************************************************************************
439 const std::vector<float>& WCMRAudioDevice::OutputLevels ()
440 {
441         //The derived classes may override if they need to query
442         //the driver for the levels.
443         return (m_OutputLevels);
444 }
445
446
447
448 //**********************************************************************************************
449 // WCMRAudioDevice::GetMonitorInfo
450 //
451 //! Retrieves current monitoring information.
452 //!
453 //! \param *pLeftChannel : Pointer to receive left monitor channel index.
454 //! \param *pRightChannel : Pointer to receive right monitor channel index.
455 //! \param *pGain : Pointer to receive the gain (linear) to be applied.
456 //!
457 //! \return Nothing.
458 //!
459 //**********************************************************************************************
460 void WCMRAudioDevice::GetMonitorInfo (int *pLeftChannel, int *pRightChannel, float *pGain)
461 {
462         if (pLeftChannel)
463                 *pLeftChannel = m_LeftMonitorChannel;
464         if (pRightChannel)
465                 *pRightChannel = m_RightMonitorChannel;
466         if (pGain)
467                 *pGain = m_MonitorGain;
468         return;
469 }
470
471
472
473 //**********************************************************************************************
474 // WCMRAudioDevice::SetMonitorChannels
475 //
476 //! Used to set the channels to be used for monitoring.
477 //!
478 //! \param leftChannel : Left monitor channel index.
479 //! \param rightChannel : Right monitor channel index.
480 //!
481 //! \return eNoErr always, the derived classes may return appropriate errors.
482 //!
483 //**********************************************************************************************
484 WTErr WCMRAudioDevice::SetMonitorChannels (int leftChannel, int rightChannel)
485 {
486         //This will most likely be overridden, the base class simply
487         //changes the member.
488         m_LeftMonitorChannel = leftChannel;
489         m_RightMonitorChannel = rightChannel;
490         return (eNoErr);
491 }
492
493
494
495 //**********************************************************************************************
496 // WCMRAudioDevice::SetMonitorGain
497 //
498 //! Used to set monitor gain (or atten).
499 //!
500 //! \param newGain : The new gain or atten. value to use. Specified as a linear multiplier (not dB)
501 //!
502 //! \return eNoErr always, the derived classes may return appropriate errors.
503 //!
504 //**********************************************************************************************
505 WTErr WCMRAudioDevice::SetMonitorGain (float newGain)
506 {
507         //This will most likely be overridden, the base class simply
508         //changes the member.
509         m_MonitorGain = newGain;
510         return (eNoErr);
511 }
512
513
514
515
516 //**********************************************************************************************
517 // WCMRAudioDevice::ShowConfigPanel
518 //
519 //! Used to show device specific config/control panel. Some interfaces may not support it.
520 //!             Some interfaces may require the device to be active before it can display a panel.
521 //!
522 //! \param pParam : A device/interface specific parameter - optional.
523 //!
524 //! \return eNoErr always, the derived classes may return errors.
525 //!
526 //**********************************************************************************************
527 WTErr WCMRAudioDevice::ShowConfigPanel (void *WCUNUSEDPARAM(pParam))
528 {
529         //This will most likely be overridden...
530         return (eNoErr);
531 }
532
533
534 //**********************************************************************************************
535 // WCMRAudioDevice::SendCustomCommand
536 //
537 //! Used to Send a custom command to the audiodevice. Some interfaces may require the device
538 //!             to be active before it can do anything in this.
539 //!
540 //! \param customCommand : A device/interface specific command.
541 //! \param pCommandParam : A device/interface/command specific parameter - optional.
542 //!
543 //! \return eNoErr always, the derived classes may return errors.
544 //!
545 //**********************************************************************************************
546 WTErr WCMRAudioDevice::SendCustomCommand (int WCUNUSEDPARAM(customCommand), void *WCUNUSEDPARAM(pCommandParam))
547 {
548         //This will most likely be overridden...
549         return (eNoErr);
550 }
551
552 //**********************************************************************************************
553 // WCMRAudioDevice::GetLatency
554 //
555 //! Get Latency for device.
556 //!
557 //! Use 'kAudioDevicePropertyLatency' and 'kAudioDevicePropertySafetyOffset' + GetStreamLatencies
558 //!
559 //! \param isInput : Return latency for the input if isInput is true, otherwise the output latency
560 //!                  wiil be returned.
561 //! \return Latency in samples.
562 //!
563 //**********************************************************************************************
564 uint32_t WCMRAudioDevice::GetLatency (bool isInput)
565 {
566     //This will most likely be overridden...
567     return 0;
568 }
569
570
571 //**********************************************************************************************
572 // WCMRAudioDeviceManager::WCMRAudioDeviceManager
573 //
574 //! The constructuor, most of the work will be done in the derived class' constructor.
575 //!
576 //! \param *pTheClient :
577 //!
578 //! \return Nothing.
579 //!
580 //**********************************************************************************************
581 WCMRAudioDeviceManager::WCMRAudioDeviceManager(WCMRAudioDeviceManagerClient *pTheClient, eAudioDeviceFilter eCurAudioDeviceFilter)
582     : m_eAudioDeviceFilter(eCurAudioDeviceFilter)
583     , m_CurrentDevice(0)
584     , m_pTheClient (pTheClient)
585 {
586 }
587
588
589 //**********************************************************************************************
590 // WCMRAudioDeviceManager::~WCMRAudioDeviceManager
591 //
592 //! It clears the device list, releasing each of the device.
593 //!
594 //! \param none
595 //!
596 //! \return Nothing.
597 //!
598 //**********************************************************************************************
599 WCMRAudioDeviceManager::~WCMRAudioDeviceManager()
600 {
601     AUTO_FUNC_DEBUG;
602
603         std::cout << "API::Destroying AudioDeviceManager " << std::endl;
604         try
605         {
606                 // clean up device info list
607         {
608             wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
609             while( m_DeviceInfoVec.size() )
610             {
611                 DeviceInfo* devInfo = m_DeviceInfoVec.back();
612                 m_DeviceInfoVec.pop_back();
613                 delete devInfo;
614             }
615         }
616                 delete m_CurrentDevice;
617
618         }
619         catch (...)
620         {
621                 //destructors should absorb exceptions, no harm in logging though!!
622                 DEBUG_MSG ("Exception during destructor");
623         }
624 }
625
626
627 WCMRAudioDevice* WCMRAudioDeviceManager::InitNewCurrentDevice(const std::string & deviceName)
628 {
629         return initNewCurrentDeviceImpl(deviceName);
630 }
631
632
633 void WCMRAudioDeviceManager::DestroyCurrentDevice()
634 {
635         return destroyCurrentDeviceImpl();
636 }
637
638
639 const DeviceInfoVec WCMRAudioDeviceManager::DeviceInfoList() const
640 {
641     wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
642         return m_DeviceInfoVec;
643 }
644
645
646 WTErr WCMRAudioDeviceManager::GetDeviceInfoByName(const std::string & nameToMatch, DeviceInfo & devInfo) const
647 {
648     wvNS::wvThread::ThreadMutex::lock theLock(m_AudioDeviceInfoVecMutex);
649         DeviceInfoVecConstIter iter = m_DeviceInfoVec.begin();
650         for (; iter != m_DeviceInfoVec.end(); ++iter)
651         {
652                 if (nameToMatch == (*iter)->m_DeviceName)
653         {
654                         devInfo = *(*iter);
655             return eNoErr;
656         }
657         }
658
659         return eRMResNotFound;
660 }
661
662
663 WTErr WCMRAudioDeviceManager::GetDeviceSampleRates(const std::string & nameToMatch, std::vector<int>& sampleRates) const
664 {
665         return getDeviceSampleRatesImpl(nameToMatch, sampleRates);
666 }
667
668
669
670 WTErr WCMRAudioDeviceManager::GetDeviceBufferSizes(const std::string & nameToMatch, std::vector<int>& bufferSizes) const
671 {
672         return getDeviceBufferSizesImpl(nameToMatch, bufferSizes);
673 }
674
675
676 //**********************************************************************************************
677 // WCMRAudioDeviceManager::NotifyClient
678 //
679 //! A helper routine used to call the client for notification.
680 //!
681 //! \param forReason : The reason for notification.
682 //! \param *pParam : A parameter (if required) for notification.
683 //!
684 //! \return Nothing.
685 //!
686 //**********************************************************************************************
687 void WCMRAudioDeviceManager::NotifyClient (WCMRAudioDeviceManagerClient::NotificationReason forReason, void *pParam)
688 {
689         if (m_pTheClient)
690                 m_pTheClient->AudioDeviceManagerNotification (forReason, pParam);
691         return;
692 }