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