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