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