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