[Summary] Audio Backend code cleanup - PORTION B
[ardour.git] / libs / backends / wavesaudio / waves_audiobackend.cc
1 /*
2     Copyright (C) 2014 Waves Audio Ltd.
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "waves_audiobackend.h"
21 #include "waves_audioport.h"
22 #include "waves_midiport.h"
23
24 using namespace ARDOUR;
25
26 #if defined __MINGW64__ || defined __MINGW32__
27         extern "C" __declspec(dllexport) ARDOUR::AudioBackendInfo* descriptor ()
28 #else
29         extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor ()
30 #endif
31 {
32     // COMMENTED DBG LOGS */ std::cout  << "waves_backend.dll : ARDOUR::AudioBackendInfo* descriptor (): " << std::endl;
33     return &WavesAudioBackend::backend_info ();
34 }
35
36 void WavesAudioBackend::AudioDeviceManagerNotification (NotificationReason reason, void* parameter)
37 {
38     switch (reason) {
39         case WCMRAudioDeviceManagerClient::DeviceDebugInfo:
40             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::DeviceDebugInfo -- " << (char*)parameter << std::endl;
41             break;
42         case WCMRAudioDeviceManagerClient::BufferSizeChanged:
43             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::BufferSizeChanged: " << *(uint32_t*)parameter << std::endl;
44                         _buffer_size_change(*(uint32_t*)parameter);
45             break;
46         case WCMRAudioDeviceManagerClient::RequestReset:
47             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::RequestReset" << std::endl;
48             engine.request_backend_reset();
49             break;
50         case WCMRAudioDeviceManagerClient::RequestResync:
51             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::RequestResync" << std::endl;
52             break;
53         case WCMRAudioDeviceManagerClient::SamplingRateChanged:
54             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::SamplingRateChanged: " << *(float*)parameter << std::endl;
55                         set_sample_rate(*(float*)parameter);
56             break;
57         case WCMRAudioDeviceManagerClient::Dropout:
58             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::Dropout: " << std::endl;
59             break;
60         case WCMRAudioDeviceManagerClient::DeviceDroppedSamples:
61             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::DeviceDroppedSamples" << std::endl;
62             break;
63         case WCMRAudioDeviceManagerClient::DeviceStoppedStreaming:
64             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::DeviceStoppedStreaming" << std::endl;
65             break;
66                 case WCMRAudioDeviceManagerClient::DeviceStartsStreaming:
67             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::DeviceStartsStreaming" << std::endl;
68                         _call_thread_init_callback = true; // streaming will be started from device side, just set thread init flag
69             break;
70         case WCMRAudioDeviceManagerClient::DeviceConnectionLost:
71             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::DeviceConnectionLost" << std::endl;
72             break;
73         case WCMRAudioDeviceManagerClient::DeviceListChanged:
74             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::DeviceListChanged" << std::endl;
75             engine.request_device_list_update();
76             break;
77         case WCMRAudioDeviceManagerClient::IODeviceDisconnected:
78             std::cout << "-------------------------------  WCMRAudioDeviceManagerClient::DeviceListChanged" << std::endl;
79             engine.request_device_list_update();
80             break;
81         case WCMRAudioDeviceManagerClient::AudioCallback:
82             if (parameter) {
83                 const AudioCallbackData* audio_callback_data = (AudioCallbackData*)parameter;
84                 _audio_device_callback (
85                     audio_callback_data->acdInputBuffer,
86                     audio_callback_data->acdOutputBuffer,
87                     audio_callback_data->acdFrames,
88                     audio_callback_data->acdSampleTime,
89                     audio_callback_data->acdCycleStartTimeNanos
90                 );
91             }
92         break;
93         
94         default:
95         break;
96     };
97 }
98
99
100 WavesAudioBackend::WavesAudioBackend (AudioEngine& e)
101     : AudioBackend (e, __backend_info)
102     , _audio_device_manager (this)
103     , _midi_device_manager (*this)
104     , _device (NULL)
105     , _sample_format (FormatFloat)
106     , _interleaved (true)
107     , _input_channels (0)
108     , _max_input_channels (0)
109     , _output_channels (0)
110     , _max_output_channels (0)
111     , _sample_rate (0)
112     , _buffer_size (0)
113     , _systemic_input_latency (0)
114     , _systemic_output_latency (0)
115     , _call_thread_init_callback (false)
116     , _use_midi (true)
117     , _sample_time_at_cycle_start (0)
118     , _freewheeling (false)
119     , _freewheel_thread_active (false)
120     , _dsp_load_accumulator (0)
121     , _audio_cycle_period_nanos (0)
122     , _dsp_load_history_length(0)
123 {
124 }
125
126
127 WavesAudioBackend::~WavesAudioBackend ()
128 {
129     
130 }
131
132 std::string
133 WavesAudioBackend::name () const
134 {
135 #ifdef __APPLE__
136     return std::string ("CoreAudio");
137 #elif PLATFORM_WINDOWS
138     return std::string ("ASIO");
139 #endif
140 }
141
142
143 bool
144 WavesAudioBackend::is_realtime () const
145 {
146     return true;
147 }
148
149
150 bool 
151 WavesAudioBackend::requires_driver_selection () const
152
153     return false; 
154 }
155
156
157 std::vector<std::string> 
158 WavesAudioBackend::enumerate_drivers () const
159
160     // this backend does not suppose driver selection
161     assert (false);
162
163     return std::vector<std::string> (); 
164 }
165
166
167 int 
168 WavesAudioBackend::set_driver (const std::string& /*drivername*/)
169 {
170     //Waves audio backend does not suppose driver selection
171     assert (false);
172
173     return -1; 
174 }
175
176
177 std::vector<AudioBackend::DeviceStatus> 
178 WavesAudioBackend::enumerate_devices () const
179 {   
180     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::enumerate_devices (): " << std::endl;
181
182     std::vector<DeviceStatus> devicesStatus;
183     const DeviceInfoVec& deviceInfoList = _audio_device_manager.DeviceInfoList(); 
184
185     for (DeviceInfoVecConstIter deviceInfoIter = deviceInfoList.begin ();  deviceInfoIter != deviceInfoList.end (); ++deviceInfoIter) {
186         // COMMENTED DBG LOGS */ std::cout << "\t Device found: " << (*deviceInfoIter)->m_DeviceName << std::endl;
187         devicesStatus.push_back (DeviceStatus ((*deviceInfoIter)->m_DeviceName, true));
188     }
189     
190     return devicesStatus;
191
192
193
194 std::vector<float> 
195 WavesAudioBackend::available_sample_rates (const std::string& device_name) const
196 {
197     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_sample_rates (): [" << device_name << "]" << std::endl;
198
199     std::vector<int> sr;
200     
201     WTErr retVal = _audio_device_manager.GetDeviceSampleRates(device_name, sr);
202     
203         if (eNoErr != retVal) {
204         std::cerr << "WavesAudioBackend::available_sample_rates (): Failed to find device [" << device_name << "]" << std::endl;
205         return std::vector<float> ();
206     }
207
208     // COMMENTED DBG LOGS */ std::cout << "\tFound " << devInfo.m_AvailableSampleRates.size () << " sample rates for " << device_name << ":";
209
210     std::vector<float> sample_rates (sr.begin (), sr.end ());
211     
212     // COMMENTED DBG LOGS */ for (std::vector<float>::iterator i = sample_rates.begin ();  i != sample_rates.end (); ++i) std::cout << " " << *i; std::cout << std::endl;
213
214     return sample_rates;
215 }
216
217
218 float WavesAudioBackend::default_sample_rate () const 
219
220     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::default_sample_rate (): " << AudioBackend::default_sample_rate () << std::endl;
221     return AudioBackend::default_sample_rate (); 
222 }
223
224 uint32_t 
225 WavesAudioBackend::default_buffer_size (const std::string& device_name) const
226 {
227 #ifdef __APPLE__
228         return AudioBackend::default_buffer_size (device_name);
229 #else
230     DeviceInfo devInfo;
231     WTErr err = _audio_device_manager.GetDeviceInfoByName(device_name, devInfo);
232
233     if (err != eNoErr) {
234         std::cerr << "WavesAudioBackend::default_buffer_size (): Failed to get buffer size for device [" << device_name << "]" << std::endl;
235         return AudioBackend::default_buffer_size (device_name);
236     }
237         
238         return devInfo.m_DefaultBufferSize; 
239 #endif
240 }
241
242 std::vector<uint32_t> 
243 WavesAudioBackend::available_buffer_sizes (const std::string& device_name) const
244 {
245     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_buffer_sizes (): [" << device_name << "]" << std::endl;
246
247         std::vector<int> bs;
248
249         WTErr retVal = _audio_device_manager.GetDeviceBufferSizes(device_name, bs);
250
251     if (retVal != eNoErr) {
252         std::cerr << "WavesAudioBackend::available_buffer_sizes (): Failed to get buffer size for device [" << device_name << "]" << std::endl;
253         return std::vector<uint32_t> ();
254     }
255
256     std::vector<uint32_t> buffer_sizes (bs.begin (), bs.end ());
257
258     // COMMENTED DBG LOGS */ std::cout << "\tFound " << buffer_sizes.size () << " buffer sizes for " << device_name << ":";
259     // COMMENTED DBG LOGS */ for (std::vector<uint32_t>::const_iterator i = buffer_sizes.begin ();  i != buffer_sizes.end (); ++i) std::cout << " " << *i; std::cout << std::endl;
260
261     return buffer_sizes;
262 }
263
264
265 uint32_t 
266 WavesAudioBackend::available_input_channel_count (const std::string& device_name) const
267 {
268     DeviceInfo devInfo;
269     WTErr err = _audio_device_manager.GetDeviceInfoByName(device_name, devInfo);
270     
271         if (eNoErr != err) {
272         std::cerr << "WavesAudioBackend::available_input_channel_count (): Failed to find device [" << device_name << "]" << std::endl;
273         return 0;
274     }
275
276     uint32_t num_of_input_channels = devInfo.m_MaxInputChannels;
277
278     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_input_channel_count (): " << num_of_input_channels << std::endl;
279     return num_of_input_channels;
280 }
281
282
283 uint32_t 
284 WavesAudioBackend::available_output_channel_count (const std::string& device_name) const
285 {
286     DeviceInfo devInfo;
287     WTErr err = _audio_device_manager.GetDeviceInfoByName(device_name, devInfo);
288     
289         if (eNoErr != err) {
290         std::cerr << "WavesAudioBackend::available_output_channel_count (): Failed to find device [" << device_name << "]" << std::endl;
291         return 0;
292     }
293
294     uint32_t num_of_output_channels = devInfo.m_MaxOutputChannels;
295
296     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::available_output_channel_count (): " << num_of_output_channels << std::endl;
297
298     return num_of_output_channels;
299 }
300
301
302 bool
303 WavesAudioBackend::can_change_sample_rate_when_running () const
304 {
305     // VERIFY IT CAREFULLY
306     return true;
307 }
308
309
310 bool
311 WavesAudioBackend::can_change_buffer_size_when_running () const
312 {
313     // VERIFY IT CAREFULLY
314     return true;
315 }
316
317
318 int
319 WavesAudioBackend::set_device_name (const std::string& device_name)
320 {
321     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_device_name (): " << device_name << std::endl;
322     
323     if (_ports.size ()) {
324         std::cerr << "WavesAudioBackend::set_device_name (): There are unregistered ports left after [" << (_device ? _device->DeviceName () : std::string ("<NULL>")) << "]!" << std::endl;
325         for (size_t i = 0; i < _ports.size (); ++i) {
326             std::cerr << "\t[" << _ports[i]->name () << "]!" << std::endl;
327         }
328         return -1;
329     }
330
331         if (_device && _device->Streaming () ) {
332                 std::cerr << "WavesAudioBackend::set_device_name (): [" << _device->DeviceName () << "] is streaming! Current device must be stopped before setting another device as current" << std::endl;
333         }
334
335         // we must have only one device initialized at a time
336         // stop current device first
337         WTErr retVal;
338     if (_device) {
339         retVal = _device->SetActive (false);
340         if (retVal != eNoErr) {
341             std::cerr << "WavesAudioBackend::set_device_name (): [" << _device->DeviceName () << "]->SetActive (false) failed!" << std::endl;
342             return -1;
343         }
344     }
345
346         // deinitialize it
347         _audio_device_manager.DestroyCurrentDevice();
348         _device = 0;
349
350     WCMRAudioDevice * device = _audio_device_manager.InitNewCurrentDevice(device_name);
351
352     if (!device) {
353         std::cerr << "WavesAudioBackend::set_device_name (): Failed to initialize device [" << device_name << "]!" << std::endl;
354         return -1;
355     }
356
357
358     retVal = device->SetActive (true);
359     if (retVal != eNoErr) {
360         std::cerr << "WavesAudioBackend::set_device_name (): [" << device->DeviceName () << "]->SetActive () failed!" << std::endl;
361         return -1;
362     }
363
364     _device = device;
365     return 0;
366 }
367
368
369 int
370 WavesAudioBackend::drop_device()
371 {
372         WTErr wtErr = 0;
373
374         if (_device)
375         {
376                 wtErr = _device->SetActive (false);
377                 if (wtErr != eNoErr) {
378                         std::cerr << "WavesAudioBackend::drop_device (): [" << _device->DeviceName () << "]->SetActive () failed!" << std::endl;
379                         return -1;
380                 }
381         }
382
383         _audio_device_manager.DestroyCurrentDevice();
384         _device = 0;
385
386         return 0;
387 }
388
389
390 int 
391 WavesAudioBackend::set_sample_rate (float sample_rate)
392 {
393     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_sample_rate (): " << sample_rate << std::endl;
394     
395     WTErr retVal = eNoErr;
396
397     if (!_device) {
398         std::cerr << "WavesAudioBackend::set_sample_rate (): No device is set!" << std::endl;
399         return -1;
400     }
401
402     
403     bool device_needs_restart = _device->Streaming ();
404     
405     if (device_needs_restart) {
406         retVal  = _device->SetStreaming (false);
407         // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->_device->SetStreaming (false);"<< std::endl;
408         if (retVal != eNoErr) {
409             std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName () << "]->SetStreaming (false) failed (" << retVal << ") !" << std::endl;
410             return -1;
411         }
412     }
413     
414     retVal = _device->SetCurrentSamplingRate ((int)sample_rate);
415     
416     if (retVal != eNoErr) {
417         std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName() << "]->SetCurrentSamplingRate ((int)" << sample_rate << ") failed (" << retVal << ") !" << std::endl;
418         return -1;
419     }
420
421         _sample_rate_change(sample_rate);
422        
423     if (device_needs_restart) {
424         // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl;
425         _call_thread_init_callback = true;
426         retVal  = _device->SetStreaming (true);
427         if (retVal != eNoErr) {
428             std::cerr << "WavesAudioBackend::set_sample_rate (): [" << _device->DeviceName () << "]->SetStreaming (true) failed (" << retVal << ") !" << std::endl;
429             return -1;
430         }
431     }
432     return 0;
433 }
434
435
436 int 
437 WavesAudioBackend::set_buffer_size (uint32_t buffer_size)
438 {
439     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_buffer_size (" << buffer_size << "):"<< std::endl;
440
441     WTErr retVal = eNoErr;
442
443     if (!_device) {
444         std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl;
445         return -1;
446     }
447
448     bool device_needs_restart = _device->Streaming ();
449     
450     if (device_needs_restart) {
451         retVal  = _device->SetStreaming (false);
452         // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (false);"<< std::endl;
453         if (retVal != eNoErr) {
454             std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName () << "]->SetStreaming (false) failed (" << retVal << ") !" << std::endl;
455             return -1;
456         }
457     }
458     
459     retVal = _device->SetCurrentBufferSize (buffer_size);
460     
461     if (retVal != eNoErr) {
462         std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName() << "]->SetCurrentBufferSize (" << buffer_size << ") failed (" << retVal << ") !" << std::endl;
463         return -1;
464     }
465     
466         // if call to set buffer is successful but device buffer size differs from the value we tried to set
467         // this means we are driven by device for buffer size
468         buffer_size = _device->CurrentBufferSize ();
469
470         _buffer_size_change(buffer_size);
471     
472     if (device_needs_restart) {
473         // COMMENTED DBG LOGS */ std::cout << "\t\t[" << _device->DeviceName() << "]->SetStreaming (true);"<< std::endl;
474         _call_thread_init_callback = true;
475         retVal  = _device->SetStreaming (true);
476         if (retVal != eNoErr) {
477             std::cerr << "WavesAudioBackend::set_buffer_size (): [" << _device->DeviceName () << "]->SetStreaming (true) failed (" << retVal << ") !" << std::endl;
478             return -1;
479         }
480     }
481     
482     return 0;
483 }
484
485
486 int 
487 WavesAudioBackend::set_sample_format (SampleFormat sample_format)
488 {
489     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_sample_format (): " << sample_format << std::endl;
490
491     _sample_format = sample_format;
492     return 0;
493 }
494
495 int 
496 WavesAudioBackend::reset_device ()
497 {
498     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_reset_device ():" << std::endl;
499
500     WTErr retVal = eNoErr;
501
502     if (!_device) {
503         std::cerr << "WavesAudioBackend::set_buffer_size (): No device is set!" << std::endl;
504         return -1;
505     }
506
507         return _device->ResetDevice();
508 }
509
510
511 int 
512 WavesAudioBackend::_buffer_size_change (uint32_t new_buffer_size)
513 {
514         _buffer_size = new_buffer_size;
515     _init_dsp_load_history();
516     return engine.buffer_size_change (new_buffer_size);
517 }
518
519
520 int 
521 WavesAudioBackend::_sample_rate_change (float new_sample_rate)
522 {
523         _sample_rate = new_sample_rate;
524     _init_dsp_load_history();
525     return engine.sample_rate_change (new_sample_rate);
526 }
527
528
529 int 
530 WavesAudioBackend::set_interleaved (bool yn)
531 {
532     /*you can ignore them totally*/
533     _interleaved = yn;
534     return 0;
535 }
536
537
538 int 
539 WavesAudioBackend::set_input_channels (uint32_t input_channels)
540 {
541     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_input_channels (): " << input_channels << std::endl;
542
543     _input_channels = input_channels;
544     return 0;
545 }
546
547
548 int 
549 WavesAudioBackend::set_output_channels (uint32_t output_channels)
550 {
551     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_output_channels (): " << output_channels << std::endl;
552
553     _output_channels = output_channels;
554     return 0;
555 }
556
557
558 std::string  
559 WavesAudioBackend::device_name () const
560 {
561     if (!_device) {
562         return "";
563     }
564     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::device_name (): " << _device->DeviceName () << std::endl;
565     
566     return _device->DeviceName ();
567 }
568
569
570 float        
571 WavesAudioBackend::sample_rate () const
572 {
573     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::sample_rate (): " << std::endl;
574
575     if (!_device) {
576         std::cerr << "WavesAudioBackend::sample_rate (): No device is set!" << std::endl;
577         return -1;
578     }
579
580     int sample_rate = _device->CurrentSamplingRate ();
581
582     // COMMENTED DBG LOGS */ std::cout << "\t[" << _device->DeviceName () << "]->CurrentSamplingRate () returned " << sample_rate << std::endl;
583
584     return (float)sample_rate;
585 }
586
587
588 uint32_t     
589 WavesAudioBackend::buffer_size () const
590 {
591
592     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::buffer_size (): " << std::endl;
593
594     if (!_device) {
595         std::cerr << "WavesAudioBackend::buffer_size (): No device is set!" << std::endl;
596         return 0;
597     }
598
599     int size = _device->CurrentBufferSize ();
600     
601     // COMMENTED DBG LOGS */ std::cout << "\t[" << _device->DeviceName () << "]->CurrentBufferSize () returned " << size << std::endl;
602
603     return (uint32_t)size;
604 }
605
606
607 SampleFormat 
608 WavesAudioBackend::sample_format () const
609 {
610     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::sample_format ()" << std::endl;
611     return _sample_format;
612 }
613
614
615 bool         
616 WavesAudioBackend::interleaved () const
617 {
618     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::interleaved ()" << std::endl;
619
620     return _interleaved;
621 }
622
623
624 uint32_t     
625 WavesAudioBackend::input_channels () const
626 {
627     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::input_channels ()" << std::endl;
628
629     return _input_channels;
630 }
631
632
633 uint32_t     
634 WavesAudioBackend::output_channels () const
635 {
636     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::output_channels ()" << std::endl;
637
638     return _output_channels;
639 }
640
641
642 std::string 
643 WavesAudioBackend::control_app_name () const
644 {
645     std::string app_name = ""; 
646
647     if (_device && !dynamic_cast<WCMRNativeAudioNoneDevice*> (_device))    {
648         app_name = "PortAudioMayKnowIt";
649     }
650
651     return app_name; 
652 }
653
654
655 void
656 WavesAudioBackend::launch_control_app ()
657 {
658     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::launch_control_app ()" << std::endl;
659     if (!_device) {
660         std::cerr << "WavesAudioBackend::launch_control_app (): No device is set!" << std::endl;
661         return;
662     }
663     
664     WTErr err = _device->ShowConfigPanel (NULL);
665     
666     if (eNoErr != err) {
667         std::cerr << "WavesAudioBackend::launch_control_app (): [" << _device->DeviceName () << "]->ShowConfigPanel () failed (" << err << ")!" << std::endl;
668     }
669
670     // COMMENTED DBG LOGS */ else std::cout << "WavesAudioBackend::launch_control_app (): [" << _device->DeviceName () << "]->ShowConfigPanel ()  successfully launched!" << std::endl;
671 }
672
673
674 int
675 WavesAudioBackend::_start (bool for_latency_measurement)
676 {
677     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_start ()" << std::endl;
678
679     if (!_device) {
680         std::cerr << "WavesAudioBackend::_start (): No device is set!" << std::endl;
681         stop();
682                 return -1;
683     }
684
685     if (_register_system_audio_ports () != 0) {
686         std::cerr << "WavesAudioBackend::_start (): _register_system_audio_ports () failed!" << std::endl;
687         stop();
688                 return -1;
689     }
690
691     if (_use_midi) {
692         if (_midi_device_manager.start () != 0) {
693             std::cerr << "WavesAudioBackend::_start (): _midi_device_manager.start () failed!" << std::endl;
694             stop();
695                         return -1;
696         }
697         if (_register_system_midi_ports () != 0) {
698             std::cerr << "WavesAudioBackend::_start (): _register_system_midi_ports () failed!" << std::endl;
699             stop();
700                         return -1;
701         }
702     }
703
704     if (engine.reestablish_ports () != 0) {
705         std::cerr << "WavesAudioBackend::_start (): engine.reestablish_ports () failed!" << std::endl;
706     }
707
708     manager.registration_callback ();
709
710     _call_thread_init_callback = true;
711     WTErr retVal  = _device->SetStreaming (true);
712     if (retVal != eNoErr) {
713         std::cerr << "WavesAudioBackend::_start (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl;
714                 stop();
715         return -1;
716     }
717
718     if (_use_midi) {
719         if (_midi_device_manager.stream (true)) {
720             std::cerr << "WavesAudioBackend::_start (): _midi_device_manager.stream (true) failed!" << std::endl;
721             stop();
722                         return -1;
723         }
724     }
725
726     return 0;
727 }
728
729
730 void
731 WavesAudioBackend::_audio_device_callback (const float* input_buffer, 
732                                            float* output_buffer, 
733                                            unsigned long nframes,
734                                            framepos_t sample_time,
735                                            uint64_t cycle_start_time_nanos)
736 {
737     uint64_t dsp_start_time_nanos = __get_time_nanos();
738     // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::_audio_device_callback ():" << _device->DeviceName () << std::endl;
739     _sample_time_at_cycle_start = sample_time;
740     _cycle_start_time_nanos = cycle_start_time_nanos;
741     
742     /* There is the possibility that the thread this runs in may change from
743      *  callback to callback, so do it every time.
744      */
745     _main_thread = pthread_self ();
746
747     if (_buffer_size != nframes) {
748         // COMMENTED DBG LOGS */ std::cout << "\tAudioEngine::thread_init_callback() buffer size and nframes are not equal: " << _buffer_size << "!=" << nframes << std::endl;
749         return;
750     }
751
752     _read_audio_data_from_device (input_buffer, nframes);
753     _read_midi_data_from_devices ();
754
755     if (_call_thread_init_callback) {
756         _call_thread_init_callback = false;
757         // COMMENTED DBG LOGS */ std::cout << "\tAudioEngine::thread_init_callback() invoked for " << std::hex << pthread_self() << std::dec << " !" << std::endl;
758         AudioEngine::thread_init_callback (this);
759     }
760
761     engine.process_callback (nframes);
762     
763     _write_audio_data_to_device (output_buffer, nframes);
764     _write_midi_data_to_devices (nframes);
765     
766     uint64_t dsp_end_time_nanos = __get_time_nanos();
767     
768     _dsp_load_accumulator -= *_dsp_load_history.begin();
769         _dsp_load_history.pop_front();
770     uint64_t dsp_load_nanos = dsp_end_time_nanos - dsp_start_time_nanos;
771     _dsp_load_accumulator += dsp_load_nanos;
772     _dsp_load_history.push_back(dsp_load_nanos);
773
774     return;
775 }
776
777
778 int
779 WavesAudioBackend::stop ()
780 {
781     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::stop ()" << std::endl;
782
783     WTErr wtErr = eNoErr;
784     int retVal = 0;
785
786     // COMMENTED DBG LOGS */ std::cout << "\t[" << _device->DeviceName () << "]" << std::endl;
787
788         if (_device) {
789                 wtErr = _device->SetStreaming (false);
790                 if (wtErr != eNoErr) {
791                         std::cerr << "WavesAudioBackend::stop (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl;
792                         retVal = -1;
793                 }
794         }
795
796         _midi_device_manager.stop ();
797     _unregister_system_audio_ports ();
798     _unregister_system_midi_ports ();
799         
800     return retVal;
801 }
802
803
804 int
805 WavesAudioBackend::freewheel (bool start_stop)
806 {
807     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::freewheel (" << start_stop << "):" << std::endl;
808
809     if (start_stop != _freewheeling) {
810         if (start_stop == true) {
811             WTErr retval = _device->SetStreaming (false);
812             if (retval != eNoErr) {
813                 std::cerr << "WavesAudioBackend::freewheel (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl;
814                 return -1;
815             }
816             _call_thread_init_callback = true;
817             _freewheel_thread ();
818             engine.freewheel_callback (start_stop);
819         }
820         else {
821             _freewheel_thread_active = false; // stop _freewheel_thread ()
822             engine.freewheel_callback (start_stop);
823             _call_thread_init_callback = true;
824             WTErr retval = _device->SetStreaming (true);
825             if (retval != eNoErr) {
826                 std::cerr << "WavesAudioBackend::freewheel (): [" << _device->DeviceName () << "]->SetStreaming () failed!" << std::endl;
827                 return -1;
828             }
829         }
830         _freewheeling = start_stop;
831     }
832     // already doing what has been asked for
833     return 0;
834 }
835
836
837 void 
838 WavesAudioBackend::_freewheel_thread ()
839 {
840     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_freewheel_thread ():" << std::endl;
841     if (!_freewheel_thread_active) { // Lets create it
842         
843         // COMMENTED DBG LOGS */ std::cout << "\tCreating the thread _freewheel_thread () . . ." << std::endl;
844         pthread_attr_t attributes;
845         pthread_t thread_id;
846
847         ThreadData* thread_data = new ThreadData (this, boost::bind (&WavesAudioBackend::_freewheel_thread, this), __thread_stack_size ());
848
849         if (pthread_attr_init (&attributes)) {
850             std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_attr_init () failed!" << std::endl;
851             return;
852         }
853    
854         if (pthread_attr_setstacksize (&attributes, __thread_stack_size ())) {
855             std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_attr_setstacksize () failed!" << std::endl;
856             return;
857         }
858
859         _freewheel_thread_active = true;
860         if ((pthread_create (&thread_id, &attributes, __start_process_thread, thread_data))) {
861             _freewheel_thread_active = false;
862             std::cerr << "WavesAudioBackend::freewheel_thread (): pthread_create () failed!" << std::endl;
863             return;
864         }
865
866         // COMMENTED DBG LOGS */ std::cout << "\t. . . _freewheel_thread () complete." << std::endl;
867         return;
868     }
869     
870     if (_call_thread_init_callback) {
871         _call_thread_init_callback = false;
872         AudioEngine::thread_init_callback (this);
873     }
874
875     while (_freewheel_thread_active) {
876         engine.process_callback (_buffer_size);
877     }
878     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::_freewheel_thread (): FINISHED" << std::endl;
879     return;
880 }
881
882
883 float
884 WavesAudioBackend::dsp_load () const
885 {
886     // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::dsp_load (): " << std::endl;
887
888     if (!_device) {
889         std::cerr << "WavesAudioBackend::cpu_load (): No device is set!" << std::endl;
890         return 0;
891     }
892
893     float average_dsp_load = (float)_dsp_load_accumulator/_dsp_load_history_length;
894     
895     return ( average_dsp_load  / _audio_cycle_period_nanos)*100.0;
896 }
897
898
899 void
900 WavesAudioBackend::_init_dsp_load_history()
901 {
902     if((_sample_rate <= 0.0) || (_buffer_size <= 0.0)) {
903         return;
904     }
905     
906     _audio_cycle_period_nanos = ((uint64_t)1000000000L * _buffer_size) / _sample_rate;
907     
908     _dsp_load_accumulator = 0;
909     
910     _dsp_load_history_length = (_sample_rate + _buffer_size - 1) / _buffer_size;
911     // COMMENTED DBG LOGS */ std::cout << "\t\t_dsp_load_history_length = " << _dsp_load_history_length << std::endl;
912     _dsp_load_history = std::list<uint64_t>(_dsp_load_history_length, 0);
913 }
914
915
916 void
917 WavesAudioBackend::transport_start ()
918 {
919     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_start (): " << std::endl;
920 }
921
922
923 void
924 WavesAudioBackend::transport_stop () 
925 {
926     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_stop (): " << std::endl;
927 }
928
929
930 TransportState
931 WavesAudioBackend::transport_state () const
932 {
933     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_state (): " << std::endl;
934     return TransportStopped; 
935 }
936
937
938 void
939 WavesAudioBackend::transport_locate (framepos_t pos)
940 {
941     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_locate (" << pos << "): " << std::endl;
942 }
943
944
945 framepos_t
946 WavesAudioBackend::transport_frame () const
947
948     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::transport_frame (): " << std::endl;
949     return 0; 
950 }
951
952
953 int
954 WavesAudioBackend::set_time_master (bool yn)
955
956     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::set_time_master (): " << yn << std::endl;
957     return 0; 
958 }
959
960
961 int
962 WavesAudioBackend::usecs_per_cycle () const
963 {
964     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::usecs_per_cycle (): " << std::endl;
965     return (1000000 * _sample_rate) / _buffer_size;
966 }
967
968
969 size_t
970 WavesAudioBackend::raw_buffer_size (DataType data_type)
971 {
972     // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::raw_buffer_size (" << data_type.to_string () << "): " << std::endl;
973     switch (data_type) {
974     case DataType::AUDIO:
975             return WavesAudioPort::MAX_BUFFER_SIZE_BYTES;
976         break;
977
978     case DataType::MIDI:
979             return WavesMidiPort::MAX_BUFFER_SIZE_BYTES;
980         break;
981
982         default:
983             std::cerr << "WavesAudioBackend::raw_buffer_size (): unexpected data type (" << (uint32_t)data_type <<")!" << std::endl;
984         break;
985     }
986     return 0;
987 }
988
989
990 framepos_t
991 WavesAudioBackend::sample_time ()
992 {
993     // WARNING: This is approximate calculation. Implementation of accurate calculation is pending.
994     // http://kokkinizita.linuxaudio.org/papers/usingdll.pdf
995     
996     return _sample_time_at_cycle_start + ((__get_time_nanos () - _cycle_start_time_nanos)*_sample_rate)/1000000000L;
997 }
998
999
1000 uint64_t
1001 WavesAudioBackend::__get_time_nanos ()
1002 {
1003 #ifdef __APPLE__
1004     // here we exploit the time counting API which is used by the WCMRCoreAudioDeviceManager. However,
1005     // the API should be a part of WCMRCoreAudioDeviceManager to give a chance of being tied to the
1006     // audio device transport timeß.
1007     return AudioConvertHostTimeToNanos (AudioGetCurrentHostTime ());
1008     
1009 #elif PLATFORM_WINDOWS
1010         LARGE_INTEGER Count;
1011     QueryPerformanceCounter (&Count);
1012     return uint64_t ((Count.QuadPart * 1000000000L / __performance_counter_frequency));
1013 #endif
1014 }
1015
1016
1017 framepos_t
1018 WavesAudioBackend::sample_time_at_cycle_start ()
1019 {
1020     // COMMENTED FREQUENT DBG LOGS */ std::cout << "WavesAudioBackend::sample_time_at_cycle_start (): " << _sample_time_at_cycle_start << std::endl;
1021     return _sample_time_at_cycle_start;
1022 }
1023
1024
1025 pframes_t
1026 WavesAudioBackend::samples_since_cycle_start ()
1027 {
1028     pframes_t diff_sample_time; 
1029     diff_sample_time = sample_time () - _sample_time_at_cycle_start;
1030     // COMMENTED DBG LOGS */ std::cout << "samples_since_cycle_start: " << diff_sample_time << std::endl;
1031
1032     return diff_sample_time;
1033 }
1034
1035
1036 bool
1037 WavesAudioBackend::get_sync_offset (pframes_t& /*offset*/) const
1038
1039     // COMMENTED DBG LOGS */ std::cout << "get_sync_offset: false" << std::endl;
1040
1041     return false; 
1042 }
1043
1044
1045 int
1046 WavesAudioBackend::create_process_thread (boost::function<void ()> func)
1047 {
1048     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::create_process_thread ():" << std::endl;
1049     int retVal;
1050     pthread_attr_t attributes;
1051     size_t stacksize_aligned;
1052     pthread_t thread_id;
1053
1054     // Align stacksize to PTHREAD_STACK_MIN.
1055     stacksize_aligned = __thread_stack_size ();
1056
1057     ThreadData* td = new ThreadData (this, func, stacksize_aligned);
1058
1059     if ((retVal = pthread_attr_init (&attributes))) {
1060         std::cerr << "Cannot set thread attr init res = " << retVal << endmsg;
1061         return -1;
1062     }
1063    
1064     if ((retVal = pthread_attr_setstacksize (&attributes, stacksize_aligned))) {
1065         std::cerr << "Cannot set thread stack size (" << stacksize_aligned << ") res = " << retVal << endmsg;
1066         return -1;
1067     }
1068
1069     if ((retVal = pthread_create (&thread_id, &attributes, __start_process_thread, td))) {
1070         std::cerr << "Cannot create thread res = " << retVal << endmsg;
1071         return -1;
1072     }
1073
1074     _backend_threads.push_back (thread_id);
1075     // COMMENTED DBG LOGS */ std::cout << "\t\t\t. . . thread " << std::hex << thread_id << std::dec << " has been created" << std::endl;
1076
1077     return 0;
1078 }
1079
1080
1081 void*
1082 WavesAudioBackend::__start_process_thread (void* arg)
1083 {
1084     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__start_process_thread ():" << std::endl;
1085     ThreadData* td = reinterpret_cast<ThreadData*> (arg);
1086     boost::function<void ()> f = td->f;
1087     delete td;
1088     f ();
1089     return 0;
1090 }
1091
1092
1093 int
1094 WavesAudioBackend::join_process_threads ()
1095 {
1096     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::join_process_thread ()" << std::endl;
1097     int ret = 0;
1098
1099     for (std::vector<pthread_t>::const_iterator i = _backend_threads.begin ();
1100          i != _backend_threads.end ();
1101          ++i) {
1102         // COMMENTED DBG LOGS */ std::cout << "\t\t\tstopping thread " << std::hex << *i << std::dec << "...\n";
1103
1104         void* status;  
1105         if (pthread_join (*i, &status) != 0) {
1106             std::cerr << "AudioEngine: cannot stop process thread !" << std::endl;
1107             ret += -1;
1108         }
1109         // COMMENTED DBG LOGS */ std::cout << "\t\t\t\t...done" << std::endl;
1110     }
1111     // COMMENTED DBG LOGS */ std::cout << "\t\t\tall threads finished..." << std::endl;
1112     _backend_threads.clear ();
1113     // COMMENTED DBG LOGS */ std::cout << "\t\t\tthread list cleared..." << std::endl;
1114
1115     return ret;
1116 }
1117
1118
1119 bool 
1120 WavesAudioBackend::in_process_thread ()
1121 {
1122     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::in_process_thread ()" << std::endl;
1123         if (pthread_equal (_main_thread, pthread_self()) != 0) {
1124                 return true;
1125         }
1126         for (std::vector<pthread_t>::const_iterator i = _backend_threads.begin ();
1127              i != _backend_threads.end (); i++) {
1128                 if (pthread_equal (*i, pthread_self ()) != 0) {
1129                         return true;
1130                 }
1131         }
1132         return false;
1133 }
1134
1135
1136 size_t
1137 WavesAudioBackend::__thread_stack_size ()
1138 {
1139     // Align stacksize to PTHREAD_STACK_MIN.
1140 #if defined (__APPLE__)
1141     return (((thread_stack_size () - 1) / PTHREAD_STACK_MIN) + 1) * PTHREAD_STACK_MIN;
1142 #elif defined (PLATFORM_WINDOWS)
1143     return thread_stack_size ();
1144 #endif
1145 }
1146
1147
1148 uint32_t 
1149 WavesAudioBackend::process_thread_count ()
1150 {
1151     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::process_thread_count (): returns " << _backend_threads.size () << std::endl;
1152     return _backend_threads.size ();
1153 }
1154
1155
1156 void
1157 WavesAudioBackend::_read_audio_data_from_device (const float* input_buffer, pframes_t nframes)
1158 {
1159 #if defined(PLATFORM_WINDOWS)
1160     const float **buffer = (const float**)input_buffer;
1161     size_t copied_bytes = nframes*sizeof(float);
1162
1163     for(std::vector<WavesAudioPort*>::iterator it = _physical_audio_inputs.begin ();
1164         it != _physical_audio_inputs.end();
1165         ++it)
1166     {
1167         memcpy((*it)->buffer(), *buffer, copied_bytes);
1168         ++buffer;
1169     }
1170 #else
1171     std::vector<WavesAudioPort*>::iterator it = _physical_audio_inputs.begin ();
1172
1173     // Well, let's de-interleave here:
1174     const Sample* source = input_buffer;
1175
1176     for (uint32_t chann_cnt = 0; (chann_cnt < _max_input_channels) && (it != _physical_audio_inputs.end ()); ++chann_cnt, ++source, ++it) {
1177         const Sample* src = source;
1178         Sample* tgt = (*it)->buffer ();
1179
1180         for (uint32_t frame = 0; frame < nframes; ++frame, src += _max_input_channels, ++tgt) {
1181             *tgt = *src;
1182         }
1183     }
1184 #endif
1185 }
1186
1187 void
1188 WavesAudioBackend::_write_audio_data_to_device (float* output_buffer, pframes_t nframes)
1189 {
1190 #if defined(_WnonononoINDOWS)
1191     float **buffer = (float**)output_buffer;
1192     size_t copied_bytes = nframes*sizeof(float);
1193     int i = 0;
1194     for(std::vector<WavesAudioPort*>::iterator it = _physical_audio_outputs.begin ();
1195         it != _physical_audio_outputs.end();
1196         ++it)
1197     {
1198         memcpy(*buffer, (*it)->buffer(), copied_bytes);
1199         //*buffer = (*it)->buffer();
1200         buffer++;
1201     }
1202 #else
1203     // Well, let's interleave here:
1204     std::vector<WavesAudioPort*>::iterator it = _physical_audio_outputs.begin ();
1205     Sample* target = output_buffer;
1206
1207     for (uint32_t chann_cnt = 0;
1208          (chann_cnt < _max_output_channels) && (it != _physical_audio_outputs.end ());
1209          ++chann_cnt, ++target, ++it) {
1210         const Sample* src = (Sample*) ((*it)->get_buffer (nframes));
1211         Sample* tgt = target;
1212         for (uint32_t frame = 0; frame < nframes; ++frame, tgt += _max_output_channels, ++src) {
1213             *tgt = *src;
1214         }
1215     }
1216 #endif
1217 }
1218
1219
1220 static boost::shared_ptr<WavesAudioBackend> __instance;
1221
1222
1223 boost::shared_ptr<AudioBackend>
1224 WavesAudioBackend::__waves_backend_factory (AudioEngine& e)
1225 {
1226     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__waves_backend_factory ():" << std::endl;
1227     if (!__instance) {
1228             __instance.reset (new WavesAudioBackend (e));
1229     }
1230     return __instance;
1231 }
1232
1233
1234 #if defined(PLATFORM_WINDOWS)
1235
1236 uint64_t WavesAudioBackend::__performance_counter_frequency;
1237
1238 #endif
1239
1240 int 
1241 WavesAudioBackend::__instantiate (const std::string& arg1, const std::string& arg2)
1242 {
1243     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__instantiate ():" << "[" << arg1 << "], [" << arg2 << "]" << std::endl;
1244     __instantiated_name = arg1;
1245 #if defined(PLATFORM_WINDOWS)
1246
1247         LARGE_INTEGER Frequency;
1248         QueryPerformanceFrequency(&Frequency);
1249         __performance_counter_frequency = Frequency.QuadPart;
1250         std::cout << "__performance_counter_frequency:" << __performance_counter_frequency << std::endl;
1251
1252 #endif
1253     return 0;
1254 }
1255
1256
1257 int 
1258 WavesAudioBackend::__deinstantiate ()
1259 {
1260     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__deinstantiate ():" << std::endl;
1261     __instance.reset ();
1262     return 0;
1263 }
1264
1265
1266 bool
1267 WavesAudioBackend::__already_configured ()
1268 {
1269     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__already_configured ():" << std::endl;
1270     return false;
1271 }
1272
1273 bool
1274 WavesAudioBackend::__available ()
1275 {
1276     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::__available ():" << std::endl;
1277     return true;
1278 }
1279
1280
1281 void*
1282 WavesAudioBackend::private_handle () const
1283 {
1284     // COMMENTED DBG LOGS */ std::cout << "WHY DO CALL IT: WavesAudioBackend::private_handle: " << std::endl;
1285     return NULL;
1286 }
1287
1288
1289 bool
1290 WavesAudioBackend::available () const
1291 {
1292     // COMMENTED SECONDARY DBG LOGS */// std::cout << "WavesAudioBackend::available: " << std::endl;
1293     return true;
1294 }
1295
1296
1297 const std::string&
1298 WavesAudioBackend::my_name () const
1299 {
1300     // COMMENTED SECONDARY DBG LOGS */// std::cout << "WavesAudioBackend::my_name: " << _port_prefix_name << std::endl;
1301     return __instantiated_name;
1302 }
1303
1304
1305 bool
1306 WavesAudioBackend::can_monitor_input () const
1307 {
1308     // COMMENTED DBG LOGS */ std::cout << "WavesAudioBackend::can_monitor_input: " << std::endl;
1309     return false;
1310 }
1311
1312 std::string WavesAudioBackend::__instantiated_name;
1313
1314 AudioBackendInfo WavesAudioBackend::__backend_info = {
1315 #ifdef __APPLE__
1316     "CoreAudio",
1317 #elif PLATFORM_WINDOWS
1318     "ASIO",
1319 #endif
1320     __instantiate,
1321     WavesAudioBackend::__deinstantiate,
1322     WavesAudioBackend::__waves_backend_factory,
1323     WavesAudioBackend::__already_configured,
1324     WavesAudioBackend::__available,
1325 };
1326
1327