ecd1b05698571d45457b3d1178278a2405a5448f
[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 }