Include windows.h in Dummy backend for LARGE_INTEGER
[ardour.git] / libs / backends / dummy / dummy_audiobackend.cc
1 /*
2  * Copyright (C) 2014 Robin Gareus <robin@gareus.org>
3  * Copyright (C) 2013 Paul Davis
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include <sys/time.h>
21 #include <regex.h>
22 #include <stdlib.h>
23
24 #include <glibmm.h>
25
26 #ifdef PLATFORM_WINDOWS
27 #include <windows.h>
28 #endif
29
30 #include "dummy_audiobackend.h"
31 #include "dummy_midi_seq.h"
32
33 #include "pbd/error.h"
34 #include "ardour/port_manager.h"
35 #include "i18n.h"
36
37 using namespace ARDOUR;
38
39 static std::string s_instance_name;
40 size_t DummyAudioBackend::_max_buffer_size = 8192;
41 std::vector<std::string> DummyAudioBackend::_midi_options;
42 std::vector<AudioBackend::DeviceStatus> DummyAudioBackend::_device_status;
43
44 #ifdef PLATFORM_WINDOWS
45 static double _win_pc_rate = 0; // usec per tick
46 #endif
47
48 static int64_t _x_get_monotonic_usec() {
49 #ifdef PLATFORM_WINDOWS
50         if (_win_pc_rate > 0) {
51                 LARGE_INTEGER Count;
52                 // not very reliable, but the only realistic way for sub milli-seconds
53                 if (QueryPerformanceCounter (&Count)) {
54                         return (int64_t) (Count.QuadPart * _win_pc_rate);
55                 }
56                 return -1;
57         }
58 #endif
59         return g_get_monotonic_time();
60 }
61
62 DummyAudioBackend::DummyAudioBackend (AudioEngine& e, AudioBackendInfo& info)
63         : AudioBackend (e, info)
64         , _running (false)
65         , _freewheel (false)
66         , _freewheeling (false)
67         , _device ("")
68         , _samplerate (48000)
69         , _samples_per_period (1024)
70         , _dsp_load (0)
71         , _n_inputs (0)
72         , _n_outputs (0)
73         , _n_midi_inputs (0)
74         , _n_midi_outputs (0)
75         , _midi_mode (MidiNoEvents)
76         , _systemic_input_latency (0)
77         , _systemic_output_latency (0)
78         , _processed_samples (0)
79         , _port_change_flag (false)
80 {
81         _instance_name = s_instance_name;
82         _device = _("Silence");
83         pthread_mutex_init (&_port_callback_mutex, 0);
84 }
85
86 DummyAudioBackend::~DummyAudioBackend ()
87 {
88         pthread_mutex_destroy (&_port_callback_mutex);
89 }
90
91 /* AUDIOBACKEND API */
92
93 std::string
94 DummyAudioBackend::name () const
95 {
96         return X_("Dummy");
97 }
98
99 bool
100 DummyAudioBackend::is_realtime () const
101 {
102         return false;
103 }
104
105 std::vector<AudioBackend::DeviceStatus>
106 DummyAudioBackend::enumerate_devices () const
107 {
108         if (_device_status.empty()) {
109                 _device_status.push_back (DeviceStatus (_("Silence"), true));
110                 _device_status.push_back (DeviceStatus (_("Sine Wave"), true));
111                 _device_status.push_back (DeviceStatus (_("Square Wave"), true));
112                 _device_status.push_back (DeviceStatus (_("Impulses"), true));
113                 _device_status.push_back (DeviceStatus (_("Uniform White Noise"), true));
114                 _device_status.push_back (DeviceStatus (_("Gaussian White Noise"), true));
115                 _device_status.push_back (DeviceStatus (_("Pink Noise"), true));
116                 _device_status.push_back (DeviceStatus (_("Pink Noise (low CPU)"), true));
117                 _device_status.push_back (DeviceStatus (_("Sine Sweep"), true));
118                 _device_status.push_back (DeviceStatus (_("Sine Sweep Swell"), true));
119                 _device_status.push_back (DeviceStatus (_("Square Sweep"), true));
120                 _device_status.push_back (DeviceStatus (_("Square Sweep Swell"), true));
121                 _device_status.push_back (DeviceStatus (_("Loopback"), true));
122         }
123         return _device_status;
124 }
125
126 std::vector<float>
127 DummyAudioBackend::available_sample_rates (const std::string&) const
128 {
129         std::vector<float> sr;
130         sr.push_back (8000.0);
131         sr.push_back (22050.0);
132         sr.push_back (24000.0);
133         sr.push_back (44100.0);
134         sr.push_back (48000.0);
135         sr.push_back (88200.0);
136         sr.push_back (96000.0);
137         sr.push_back (176400.0);
138         sr.push_back (192000.0);
139         return sr;
140 }
141
142 std::vector<uint32_t>
143 DummyAudioBackend::available_buffer_sizes (const std::string&) const
144 {
145         std::vector<uint32_t> bs;
146         bs.push_back (4);
147         bs.push_back (8);
148         bs.push_back (16);
149         bs.push_back (32);
150         bs.push_back (64);
151         bs.push_back (128);
152         bs.push_back (256);
153         bs.push_back (512);
154         bs.push_back (1024);
155         bs.push_back (2048);
156         bs.push_back (4096);
157         bs.push_back (8192);
158         return bs;
159 }
160
161 uint32_t
162 DummyAudioBackend::available_input_channel_count (const std::string&) const
163 {
164         return 128;
165 }
166
167 uint32_t
168 DummyAudioBackend::available_output_channel_count (const std::string&) const
169 {
170         return 128;
171 }
172
173 bool
174 DummyAudioBackend::can_change_sample_rate_when_running () const
175 {
176         return true;
177 }
178
179 bool
180 DummyAudioBackend::can_change_buffer_size_when_running () const
181 {
182         return true;
183 }
184
185 int
186 DummyAudioBackend::set_device_name (const std::string& d)
187 {
188         _device = d;
189         return 0;
190 }
191
192 int
193 DummyAudioBackend::set_sample_rate (float sr)
194 {
195         if (sr <= 0) { return -1; }
196         _samplerate = sr;
197         engine.sample_rate_change (sr);
198         return 0;
199 }
200
201 int
202 DummyAudioBackend::set_buffer_size (uint32_t bs)
203 {
204         if (bs <= 0 || bs >= _max_buffer_size) {
205                 return -1;
206         }
207         _samples_per_period = bs;
208
209         /* update port latencies
210          * with 'Loopback' there is exactly once cycle latency,
211          * divide it between In + Out;
212          */
213         LatencyRange lr;
214         lr.min = lr.max = _systemic_input_latency;
215         for (std::vector<DummyAudioPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it) {
216                 set_latency_range (*it, false, lr);
217         }
218         for (std::vector<DummyMidiPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it) {
219                 set_latency_range (*it, false, lr);
220         }
221
222         lr.min = lr.max = _systemic_output_latency;
223         for (std::vector<DummyAudioPort*>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it) {
224                 set_latency_range (*it, true, lr);
225         }
226         for (std::vector<DummyMidiPort*>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it) {
227                 set_latency_range (*it, true, lr);
228         }
229
230         engine.buffer_size_change (bs);
231         return 0;
232 }
233
234 int
235 DummyAudioBackend::set_interleaved (bool yn)
236 {
237         if (!yn) { return 0; }
238         return -1;
239 }
240
241 int
242 DummyAudioBackend::set_input_channels (uint32_t cc)
243 {
244         _n_inputs = cc;
245         return 0;
246 }
247
248 int
249 DummyAudioBackend::set_output_channels (uint32_t cc)
250 {
251         _n_outputs = cc;
252         return 0;
253 }
254
255 int
256 DummyAudioBackend::set_systemic_input_latency (uint32_t sl)
257 {
258         _systemic_input_latency = sl;
259         return 0;
260 }
261
262 int
263 DummyAudioBackend::set_systemic_output_latency (uint32_t sl)
264 {
265         _systemic_output_latency = sl;
266         return 0;
267 }
268
269 /* Retrieving parameters */
270 std::string
271 DummyAudioBackend::device_name () const
272 {
273         return _device;
274 }
275
276 float
277 DummyAudioBackend::sample_rate () const
278 {
279         return _samplerate;
280 }
281
282 uint32_t
283 DummyAudioBackend::buffer_size () const
284 {
285         return _samples_per_period;
286 }
287
288 bool
289 DummyAudioBackend::interleaved () const
290 {
291         return false;
292 }
293
294 uint32_t
295 DummyAudioBackend::input_channels () const
296 {
297         return _n_inputs;
298 }
299
300 uint32_t
301 DummyAudioBackend::output_channels () const
302 {
303         return _n_outputs;
304 }
305
306 uint32_t
307 DummyAudioBackend::systemic_input_latency () const
308 {
309         return _systemic_input_latency;
310 }
311
312 uint32_t
313 DummyAudioBackend::systemic_output_latency () const
314 {
315         return _systemic_output_latency;
316 }
317
318
319 /* MIDI */
320 std::vector<std::string>
321 DummyAudioBackend::enumerate_midi_options () const
322 {
323         if (_midi_options.empty()) {
324                 _midi_options.push_back (_("1 in, 1 out, Silence"));
325                 _midi_options.push_back (_("2 in, 2 out, Silence"));
326                 _midi_options.push_back (_("8 in, 8 out, Silence"));
327                 _midi_options.push_back (_("Midi Event Generators"));
328                 _midi_options.push_back (_("8 in, 8 out, Loopback"));
329                 _midi_options.push_back (_("MIDI to Audio, Loopback"));
330                 _midi_options.push_back (_("No MIDI I/O"));
331         }
332         return _midi_options;
333 }
334
335 int
336 DummyAudioBackend::set_midi_option (const std::string& opt)
337 {
338         _midi_mode = MidiNoEvents;
339         if (opt == _("1 in, 1 out, Silence")) {
340                 _n_midi_inputs = _n_midi_outputs = 1;
341         }
342         else if (opt == _("2 in, 2 out, Silence")) {
343                 _n_midi_inputs = _n_midi_outputs = 2;
344         }
345         else if (opt == _("8 in, 8 out, Silence")) {
346                 _n_midi_inputs = _n_midi_outputs = 8;
347         }
348         else if (opt == _("Midi Event Generators")) {
349                 _n_midi_inputs = _n_midi_outputs = NUM_MIDI_EVENT_GENERATORS;
350                 _midi_mode = MidiGenerator;
351         }
352         else if (opt == _("8 in, 8 out, Loopback")) {
353                 _n_midi_inputs = _n_midi_outputs = 8;
354                 _midi_mode = MidiLoopback;
355         }
356         else if (opt == _("MIDI to Audio, Loopback")) {
357                 _n_midi_inputs = _n_midi_outputs = UINT32_MAX;
358                 _midi_mode = MidiToAudio;
359         }
360         else {
361                 _n_midi_inputs = _n_midi_outputs = 0;
362         }
363         return 0;
364 }
365
366 std::string
367 DummyAudioBackend::midi_option () const
368 {
369         return ""; // TODO
370 }
371
372 /* State Control */
373
374 static void * pthread_process (void *arg)
375 {
376         DummyAudioBackend *d = static_cast<DummyAudioBackend *>(arg);
377         d->main_process_thread ();
378         pthread_exit (0);
379         return 0;
380 }
381
382 int
383 DummyAudioBackend::_start (bool /*for_latency_measurement*/)
384 {
385         if (_running) {
386                 PBD::error << _("DummyAudioBackend: already active.") << endmsg;
387                 return -1;
388         }
389
390         if (_ports.size()) {
391                 PBD::warning << _("DummyAudioBackend: recovering from unclean shutdown, port registry is not empty.") << endmsg;
392                 for (std::vector<DummyPort*>::const_iterator it = _ports.begin (); it != _ports.end (); ++it) {
393                         PBD::info << _("DummyAudioBackend: port '") << (*it)->name () << "' exists." << endmsg;
394                 }
395                 _system_inputs.clear();
396                 _system_outputs.clear();
397                 _system_midi_in.clear();
398                 _system_midi_out.clear();
399                 _ports.clear();
400         }
401
402         if (register_system_ports()) {
403                 PBD::error << _("DummyAudioBackend: failed to register system ports.") << endmsg;
404                 return -1;
405         }
406
407         engine.sample_rate_change (_samplerate);
408         engine.buffer_size_change (_samples_per_period);
409
410         if (engine.reestablish_ports ()) {
411                 PBD::error << _("DummyAudioBackend: Could not re-establish ports.") << endmsg;
412                 stop ();
413                 return -1;
414         }
415
416         engine.reconnect_ports ();
417         _port_change_flag = false;
418
419         if (pthread_create (&_main_thread, NULL, pthread_process, this)) {
420                 PBD::error << _("DummyAudioBackend: cannot start.") << endmsg;
421         }
422
423         int timeout = 5000;
424         while (!_running && --timeout > 0) { Glib::usleep (1000); }
425
426         if (timeout == 0 || !_running) {
427                 PBD::error << _("DummyAudioBackend: failed to start process thread.") << endmsg;
428                 return -1;
429         }
430
431         return 0;
432 }
433
434 int
435 DummyAudioBackend::stop ()
436 {
437         void *status;
438         if (!_running) {
439                 return 0;
440         }
441
442         _running = false;
443         if (pthread_join (_main_thread, &status)) {
444                 PBD::error << _("DummyAudioBackend: failed to terminate.") << endmsg;
445                 return -1;
446         }
447         unregister_ports();
448         return 0;
449 }
450
451 int
452 DummyAudioBackend::freewheel (bool onoff)
453 {
454         _freewheeling = onoff;
455         return 0;
456 }
457
458 float
459 DummyAudioBackend::dsp_load () const
460 {
461         return 100.f * _dsp_load;
462 }
463
464 size_t
465 DummyAudioBackend::raw_buffer_size (DataType t)
466 {
467         switch (t) {
468                 case DataType::AUDIO:
469                         return _samples_per_period * sizeof(Sample);
470                 case DataType::MIDI:
471                         return _max_buffer_size; // XXX not really limited
472         }
473         return 0;
474 }
475
476 /* Process time */
477 framepos_t
478 DummyAudioBackend::sample_time ()
479 {
480         return _processed_samples;
481 }
482
483 framepos_t
484 DummyAudioBackend::sample_time_at_cycle_start ()
485 {
486         return _processed_samples;
487 }
488
489 pframes_t
490 DummyAudioBackend::samples_since_cycle_start ()
491 {
492         return 0;
493 }
494
495
496 void *
497 DummyAudioBackend::dummy_process_thread (void *arg)
498 {
499         ThreadData* td = reinterpret_cast<ThreadData*> (arg);
500         boost::function<void ()> f = td->f;
501         delete td;
502         f ();
503         return 0;
504 }
505
506 int
507 DummyAudioBackend::create_process_thread (boost::function<void()> func)
508 {
509         pthread_t thread_id;
510         pthread_attr_t attr;
511         size_t stacksize = 100000;
512
513         pthread_attr_init (&attr);
514         pthread_attr_setstacksize (&attr, stacksize);
515         ThreadData* td = new ThreadData (this, func, stacksize);
516
517         if (pthread_create (&thread_id, &attr, dummy_process_thread, td)) {
518                 PBD::error << _("AudioEngine: cannot create process thread.") << endmsg;
519                 pthread_attr_destroy (&attr);
520                 return -1;
521         }
522         pthread_attr_destroy (&attr);
523
524         _threads.push_back (thread_id);
525         return 0;
526 }
527
528 int
529 DummyAudioBackend::join_process_threads ()
530 {
531         int rv = 0;
532
533         for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
534         {
535                 void *status;
536                 if (pthread_join (*i, &status)) {
537                         PBD::error << _("AudioEngine: cannot terminate process thread.") << endmsg;
538                         rv -= 1;
539                 }
540         }
541         _threads.clear ();
542         return rv;
543 }
544
545 bool
546 DummyAudioBackend::in_process_thread ()
547 {
548         if (pthread_equal (_main_thread, pthread_self()) != 0) {
549                 return true;
550         }
551
552         for (std::vector<pthread_t>::const_iterator i = _threads.begin (); i != _threads.end (); ++i)
553         {
554                 if (pthread_equal (*i, pthread_self ()) != 0) {
555                         return true;
556                 }
557         }
558         return false;
559 }
560
561 uint32_t
562 DummyAudioBackend::process_thread_count ()
563 {
564         return _threads.size ();
565 }
566
567 void
568 DummyAudioBackend::update_latencies ()
569 {
570         // trigger latency callback in RT thread (locked graph)
571         port_connect_add_remove_callback();
572 }
573
574 /* PORTENGINE API */
575
576 void*
577 DummyAudioBackend::private_handle () const
578 {
579         return NULL;
580 }
581
582 const std::string&
583 DummyAudioBackend::my_name () const
584 {
585         return _instance_name;
586 }
587
588 bool
589 DummyAudioBackend::available () const
590 {
591         return true;
592 }
593
594 uint32_t
595 DummyAudioBackend::port_name_size () const
596 {
597         return 256;
598 }
599
600 int
601 DummyAudioBackend::set_port_name (PortEngine::PortHandle port, const std::string& name)
602 {
603         if (!valid_port (port)) {
604                 PBD::error << _("DummyBackend::set_port_name: Invalid Port(s)") << endmsg;
605                 return -1;
606         }
607         return static_cast<DummyPort*>(port)->set_name (_instance_name + ":" + name);
608 }
609
610 std::string
611 DummyAudioBackend::get_port_name (PortEngine::PortHandle port) const
612 {
613         if (!valid_port (port)) {
614                 PBD::error << _("DummyBackend::get_port_name: Invalid Port(s)") << endmsg;
615                 return std::string ();
616         }
617         return static_cast<DummyPort*>(port)->name ();
618 }
619
620 PortEngine::PortHandle
621 DummyAudioBackend::get_port_by_name (const std::string& name) const
622 {
623         PortHandle port = (PortHandle) find_port (name);
624         return port;
625 }
626
627 int
628 DummyAudioBackend::get_ports (
629                 const std::string& port_name_pattern,
630                 DataType type, PortFlags flags,
631                 std::vector<std::string>& port_names) const
632 {
633         int rv = 0;
634         regex_t port_regex;
635         bool use_regexp = false;
636         if (port_name_pattern.size () > 0) {
637                 if (!regcomp (&port_regex, port_name_pattern.c_str (), REG_EXTENDED|REG_NOSUB)) {
638                         use_regexp = true;
639                 }
640         }
641         for (size_t i = 0; i < _ports.size (); ++i) {
642                 DummyPort* port = _ports[i];
643                 if ((port->type () == type) && (port->flags () & flags)) {
644                         if (!use_regexp || !regexec (&port_regex, port->name ().c_str (), 0, NULL, 0)) {
645                                 port_names.push_back (port->name ());
646                                 ++rv;
647                         }
648                 }
649         }
650         if (use_regexp) {
651                 regfree (&port_regex);
652         }
653         return rv;
654 }
655
656 DataType
657 DummyAudioBackend::port_data_type (PortEngine::PortHandle port) const
658 {
659         if (!valid_port (port)) {
660                 return DataType::NIL;
661         }
662         return static_cast<DummyPort*>(port)->type ();
663 }
664
665 PortEngine::PortHandle
666 DummyAudioBackend::register_port (
667                 const std::string& name,
668                 ARDOUR::DataType type,
669                 ARDOUR::PortFlags flags)
670 {
671         if (name.size () == 0) { return 0; }
672         if (flags & IsPhysical) { return 0; }
673         if (!_running) {
674                 PBD::info << _("DummyBackend::register_port: Engine is not running.") << endmsg;
675         }
676         return add_port (_instance_name + ":" + name, type, flags);
677 }
678
679 PortEngine::PortHandle
680 DummyAudioBackend::add_port (
681                 const std::string& name,
682                 ARDOUR::DataType type,
683                 ARDOUR::PortFlags flags)
684 {
685         assert(name.size ());
686         if (find_port (name)) {
687                 PBD::error << _("DummyBackend::register_port: Port already exists:")
688                                 << " (" << name << ")" << endmsg;
689                 return 0;
690         }
691         DummyPort* port = NULL;
692         switch (type) {
693                 case DataType::AUDIO:
694                         port = new DummyAudioPort (*this, name, flags);
695                         break;
696                 case DataType::MIDI:
697                         port = new DummyMidiPort (*this, name, flags);
698                         break;
699                 default:
700                         PBD::error << _("DummyBackend::register_port: Invalid Data Type.") << endmsg;
701                         return 0;
702         }
703
704         _ports.push_back (port);
705
706         return port;
707 }
708
709 void
710 DummyAudioBackend::unregister_port (PortEngine::PortHandle port_handle)
711 {
712         if (!_running) {
713                 PBD::info << _("DummyBackend::unregister_port: Engine is not running.") << endmsg;
714                 assert (!valid_port (port_handle));
715                 return;
716         }
717         DummyPort* port = static_cast<DummyPort*>(port_handle);
718         std::vector<DummyPort*>::iterator i = std::find (_ports.begin (), _ports.end (), static_cast<DummyPort*>(port_handle));
719         if (i == _ports.end ()) {
720                 PBD::error << _("DummyBackend::unregister_port: Failed to find port") << endmsg;
721                 return;
722         }
723         disconnect_all(port_handle);
724         _ports.erase (i);
725         delete port;
726 }
727
728 int
729 DummyAudioBackend::register_system_ports()
730 {
731         LatencyRange lr;
732         enum DummyAudioPort::GeneratorType gt;
733         if (_device == _("Uniform White Noise")) {
734                 gt = DummyAudioPort::UniformWhiteNoise;
735         } else if (_device == _("Gaussian White Noise")) {
736                 gt = DummyAudioPort::GaussianWhiteNoise;
737         } else if (_device == _("Pink Noise")) {
738                 gt = DummyAudioPort::PinkNoise;
739         } else if (_device == _("Pink Noise (low CPU)")) {
740                 gt = DummyAudioPort::PonyNoise;
741         } else if (_device == _("Sine Wave")) {
742                 gt = DummyAudioPort::SineWave;
743         } else if (_device == _("Square Wave")) {
744                 gt = DummyAudioPort::SquareWave;
745         } else if (_device == _("Impulses")) {
746                 gt = DummyAudioPort::KronekerDelta;
747         } else if (_device == _("Sine Sweep")) {
748                 gt = DummyAudioPort::SineSweep;
749         } else if (_device == _("Sine Sweep Swell")) {
750                 gt = DummyAudioPort::SineSweepSwell;
751         } else if (_device == _("Square Sweep")) {
752                 gt = DummyAudioPort::SquareSweep;
753         } else if (_device == _("Square Sweep Swell")) {
754                 gt = DummyAudioPort::SquareSweepSwell;
755         } else if (_device == _("Loopback")) {
756                 gt = DummyAudioPort::Loopback;
757         } else {
758                 gt = DummyAudioPort::Silence;
759         }
760
761         if (_midi_mode == MidiToAudio) {
762                 gt = DummyAudioPort::Loopback;
763         }
764
765         const int a_ins = _n_inputs > 0 ? _n_inputs : 8;
766         const int a_out = _n_outputs > 0 ? _n_outputs : 8;
767         const int m_ins = _n_midi_inputs == UINT_MAX ? 0 : _n_midi_inputs;
768         const int m_out = _n_midi_outputs == UINT_MAX ? a_ins : _n_midi_outputs;
769
770
771         /* audio ports */
772         lr.min = lr.max = _systemic_input_latency;
773         for (int i = 1; i <= a_ins; ++i) {
774                 char tmp[64];
775                 snprintf(tmp, sizeof(tmp), "system:capture_%d", i);
776                 PortHandle p = add_port(std::string(tmp), DataType::AUDIO, static_cast<PortFlags>(IsOutput | IsPhysical | IsTerminal));
777                 if (!p) return -1;
778                 set_latency_range (p, false, lr);
779                 _system_inputs.push_back (static_cast<DummyAudioPort*>(p));
780                 static_cast<DummyAudioPort*>(p)->setup_generator (gt, _samplerate);
781         }
782
783         lr.min = lr.max = _systemic_output_latency;
784         for (int i = 1; i <= a_out; ++i) {
785                 char tmp[64];
786                 snprintf(tmp, sizeof(tmp), "system:playback_%d", i);
787                 PortHandle p = add_port(std::string(tmp), DataType::AUDIO, static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
788                 if (!p) return -1;
789                 set_latency_range (p, true, lr);
790                 _system_outputs.push_back (static_cast<DummyAudioPort*>(p));
791         }
792
793         /* midi ports */
794         lr.min = lr.max = _systemic_input_latency;
795         for (int i = 0; i < m_ins; ++i) {
796                 char tmp[64];
797                 snprintf(tmp, sizeof(tmp), "system:midi_capture_%d", i+1);
798                 PortHandle p = add_port(std::string(tmp), DataType::MIDI, static_cast<PortFlags>(IsOutput | IsPhysical | IsTerminal));
799                 if (!p) return -1;
800                 set_latency_range (p, false, lr);
801                 _system_midi_in.push_back (static_cast<DummyMidiPort*>(p));
802                 if (_midi_mode == MidiGenerator) {
803                         static_cast<DummyMidiPort*>(p)->setup_generator (i % NUM_MIDI_EVENT_GENERATORS, _samplerate);
804                 }
805         }
806
807         lr.min = lr.max = _systemic_output_latency;
808         for (int i = 1; i <= m_out; ++i) {
809                 char tmp[64];
810                 snprintf(tmp, sizeof(tmp), "system:midi_playback_%d", i);
811                 PortHandle p = add_port(std::string(tmp), DataType::MIDI, static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
812                 if (!p) return -1;
813                 set_latency_range (p, true, lr);
814                 _system_midi_out.push_back (static_cast<DummyMidiPort*>(p));
815         }
816         return 0;
817 }
818
819 void
820 DummyAudioBackend::unregister_ports (bool system_only)
821 {
822         size_t i = 0;
823         _system_inputs.clear();
824         _system_outputs.clear();
825         _system_midi_in.clear();
826         _system_midi_out.clear();
827         while (i <  _ports.size ()) {
828                 DummyPort* port = _ports[i];
829                 if (! system_only || (port->is_physical () && port->is_terminal ())) {
830                         port->disconnect_all ();
831                         delete port;
832                         _ports.erase (_ports.begin() + i);
833                 } else {
834                         ++i;
835                 }
836         }
837 }
838
839 int
840 DummyAudioBackend::connect (const std::string& src, const std::string& dst)
841 {
842         DummyPort* src_port = find_port (src);
843         DummyPort* dst_port = find_port (dst);
844
845         if (!src_port) {
846                 PBD::error << _("DummyBackend::connect: Invalid Source port:")
847                                 << " (" << src <<")" << endmsg;
848                 return -1;
849         }
850         if (!dst_port) {
851                 PBD::error << _("DummyBackend::connect: Invalid Destination port:")
852                         << " (" << dst <<")" << endmsg;
853                 return -1;
854         }
855         return src_port->connect (dst_port);
856 }
857
858 int
859 DummyAudioBackend::disconnect (const std::string& src, const std::string& dst)
860 {
861         DummyPort* src_port = find_port (src);
862         DummyPort* dst_port = find_port (dst);
863
864         if (!src_port || !dst_port) {
865                 PBD::error << _("DummyBackend::disconnect: Invalid Port(s)") << endmsg;
866                 return -1;
867         }
868         return src_port->disconnect (dst_port);
869 }
870
871 int
872 DummyAudioBackend::connect (PortEngine::PortHandle src, const std::string& dst)
873 {
874         DummyPort* dst_port = find_port (dst);
875         if (!valid_port (src)) {
876                 PBD::error << _("DummyBackend::connect: Invalid Source Port Handle") << endmsg;
877                 return -1;
878         }
879         if (!dst_port) {
880                 PBD::error << _("DummyBackend::connect: Invalid Destination Port")
881                         << " (" << dst << ")" << endmsg;
882                 return -1;
883         }
884         return static_cast<DummyPort*>(src)->connect (dst_port);
885 }
886
887 int
888 DummyAudioBackend::disconnect (PortEngine::PortHandle src, const std::string& dst)
889 {
890         DummyPort* dst_port = find_port (dst);
891         if (!valid_port (src) || !dst_port) {
892                 PBD::error << _("DummyBackend::disconnect: Invalid Port(s)") << endmsg;
893                 return -1;
894         }
895         return static_cast<DummyPort*>(src)->disconnect (dst_port);
896 }
897
898 int
899 DummyAudioBackend::disconnect_all (PortEngine::PortHandle port)
900 {
901         if (!valid_port (port)) {
902                 PBD::error << _("DummyBackend::disconnect_all: Invalid Port") << endmsg;
903                 return -1;
904         }
905         static_cast<DummyPort*>(port)->disconnect_all ();
906         return 0;
907 }
908
909 bool
910 DummyAudioBackend::connected (PortEngine::PortHandle port, bool /* process_callback_safe*/)
911 {
912         if (!valid_port (port)) {
913                 PBD::error << _("DummyBackend::disconnect_all: Invalid Port") << endmsg;
914                 return false;
915         }
916         return static_cast<DummyPort*>(port)->is_connected ();
917 }
918
919 bool
920 DummyAudioBackend::connected_to (PortEngine::PortHandle src, const std::string& dst, bool /*process_callback_safe*/)
921 {
922         DummyPort* dst_port = find_port (dst);
923         if (!valid_port (src) || !dst_port) {
924                 PBD::error << _("DummyBackend::connected_to: Invalid Port") << endmsg;
925                 return false;
926         }
927         return static_cast<DummyPort*>(src)->is_connected (dst_port);
928 }
929
930 bool
931 DummyAudioBackend::physically_connected (PortEngine::PortHandle port, bool /*process_callback_safe*/)
932 {
933         if (!valid_port (port)) {
934                 PBD::error << _("DummyBackend::physically_connected: Invalid Port") << endmsg;
935                 return false;
936         }
937         return static_cast<DummyPort*>(port)->is_physically_connected ();
938 }
939
940 int
941 DummyAudioBackend::get_connections (PortEngine::PortHandle port, std::vector<std::string>& names, bool /*process_callback_safe*/)
942 {
943         if (!valid_port (port)) {
944                 PBD::error << _("DummyBackend::get_connections: Invalid Port") << endmsg;
945                 return -1;
946         }
947
948         assert (0 == names.size ());
949
950         const std::vector<DummyPort*>& connected_ports = static_cast<DummyPort*>(port)->get_connections ();
951
952         for (std::vector<DummyPort*>::const_iterator i = connected_ports.begin (); i != connected_ports.end (); ++i) {
953                 names.push_back ((*i)->name ());
954         }
955
956         return (int)names.size ();
957 }
958
959 /* MIDI */
960 int
961 DummyAudioBackend::midi_event_get (
962                 pframes_t& timestamp,
963                 size_t& size, uint8_t** buf, void* port_buffer,
964                 uint32_t event_index)
965 {
966         assert (buf && port_buffer);
967         DummyMidiBuffer& source = * static_cast<DummyMidiBuffer*>(port_buffer);
968         if (event_index >= source.size ()) {
969                 return -1;
970         }
971         DummyMidiEvent * const event = source[event_index].get ();
972
973         timestamp = event->timestamp ();
974         size = event->size ();
975         *buf = event->data ();
976         return 0;
977 }
978
979 int
980 DummyAudioBackend::midi_event_put (
981                 void* port_buffer,
982                 pframes_t timestamp,
983                 const uint8_t* buffer, size_t size)
984 {
985         assert (buffer && port_buffer);
986         DummyMidiBuffer& dst = * static_cast<DummyMidiBuffer*>(port_buffer);
987         if (dst.size () && (pframes_t)dst.back ()->timestamp () > timestamp) {
988                 // nevermind, ::get_buffer() sorts events, but always print warning
989                 fprintf (stderr, "DummyMidiBuffer: it's too late for this event.\n");
990         }
991         dst.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (timestamp, buffer, size)));
992         return 0;
993 }
994
995 uint32_t
996 DummyAudioBackend::get_midi_event_count (void* port_buffer)
997 {
998         assert (port_buffer);
999         return static_cast<DummyMidiBuffer*>(port_buffer)->size ();
1000 }
1001
1002 void
1003 DummyAudioBackend::midi_clear (void* port_buffer)
1004 {
1005         assert (port_buffer);
1006         DummyMidiBuffer * buf = static_cast<DummyMidiBuffer*>(port_buffer);
1007         assert (buf);
1008         buf->clear ();
1009 }
1010
1011 /* Monitoring */
1012
1013 bool
1014 DummyAudioBackend::can_monitor_input () const
1015 {
1016         return false;
1017 }
1018
1019 int
1020 DummyAudioBackend::request_input_monitoring (PortEngine::PortHandle, bool)
1021 {
1022         return -1;
1023 }
1024
1025 int
1026 DummyAudioBackend::ensure_input_monitoring (PortEngine::PortHandle, bool)
1027 {
1028         return -1;
1029 }
1030
1031 bool
1032 DummyAudioBackend::monitoring_input (PortEngine::PortHandle)
1033 {
1034         return false;
1035 }
1036
1037 /* Latency management */
1038
1039 void
1040 DummyAudioBackend::set_latency_range (PortEngine::PortHandle port, bool for_playback, LatencyRange latency_range)
1041 {
1042         if (!valid_port (port)) {
1043                 PBD::error << _("DummyPort::set_latency_range (): invalid port.") << endmsg;
1044         }
1045         static_cast<DummyPort*>(port)->set_latency_range (latency_range, for_playback);
1046 }
1047
1048 LatencyRange
1049 DummyAudioBackend::get_latency_range (PortEngine::PortHandle port, bool for_playback)
1050 {
1051         LatencyRange r;
1052         if (!valid_port (port)) {
1053                 PBD::error << _("DummyPort::get_latency_range (): invalid port.") << endmsg;
1054                 r.min = 0;
1055                 r.max = 0;
1056                 return r;
1057         }
1058         DummyPort *p =  static_cast<DummyPort*>(port);
1059         assert(p);
1060
1061         r = p->latency_range (for_playback);
1062         if (p->is_physical() && p->is_terminal()) {
1063                 if (p->is_input() && for_playback) {
1064                         const size_t l_in = _samples_per_period * .25;
1065                         r.min += l_in;
1066                         r.max += l_in;
1067                 }
1068                 if (p->is_output() && !for_playback) {
1069                         /* with 'Loopback' there is exactly once cycle latency, divide it between In + Out; */
1070                         const size_t l_in = _samples_per_period * .25;
1071                         const size_t l_out = _samples_per_period - l_in;
1072                         r.min += l_out;
1073                         r.max += l_out;
1074                 }
1075         }
1076         return r;
1077 }
1078
1079 /* Discovering physical ports */
1080
1081 bool
1082 DummyAudioBackend::port_is_physical (PortEngine::PortHandle port) const
1083 {
1084         if (!valid_port (port)) {
1085                 PBD::error << _("DummyPort::port_is_physical (): invalid port.") << endmsg;
1086                 return false;
1087         }
1088         return static_cast<DummyPort*>(port)->is_physical ();
1089 }
1090
1091 void
1092 DummyAudioBackend::get_physical_outputs (DataType type, std::vector<std::string>& port_names)
1093 {
1094         for (size_t i = 0; i < _ports.size (); ++i) {
1095                 DummyPort* port = _ports[i];
1096                 if ((port->type () == type) && port->is_input () && port->is_physical ()) {
1097                         port_names.push_back (port->name ());
1098                 }
1099         }
1100 }
1101
1102 void
1103 DummyAudioBackend::get_physical_inputs (DataType type, std::vector<std::string>& port_names)
1104 {
1105         for (size_t i = 0; i < _ports.size (); ++i) {
1106                 DummyPort* port = _ports[i];
1107                 if ((port->type () == type) && port->is_output () && port->is_physical ()) {
1108                         port_names.push_back (port->name ());
1109                 }
1110         }
1111 }
1112
1113 ChanCount
1114 DummyAudioBackend::n_physical_outputs () const
1115 {
1116         int n_midi = 0;
1117         int n_audio = 0;
1118         for (size_t i = 0; i < _ports.size (); ++i) {
1119                 DummyPort* port = _ports[i];
1120                 if (port->is_output () && port->is_physical ()) {
1121                         switch (port->type ()) {
1122                                 case DataType::AUDIO: ++n_audio; break;
1123                                 case DataType::MIDI: ++n_midi; break;
1124                                 default: break;
1125                         }
1126                 }
1127         }
1128         ChanCount cc;
1129         cc.set (DataType::AUDIO, n_audio);
1130         cc.set (DataType::MIDI, n_midi);
1131         return cc;
1132 }
1133
1134 ChanCount
1135 DummyAudioBackend::n_physical_inputs () const
1136 {
1137         int n_midi = 0;
1138         int n_audio = 0;
1139         for (size_t i = 0; i < _ports.size (); ++i) {
1140                 DummyPort* port = _ports[i];
1141                 if (port->is_input () && port->is_physical ()) {
1142                         switch (port->type ()) {
1143                                 case DataType::AUDIO: ++n_audio; break;
1144                                 case DataType::MIDI: ++n_midi; break;
1145                                 default: break;
1146                         }
1147                 }
1148         }
1149         ChanCount cc;
1150         cc.set (DataType::AUDIO, n_audio);
1151         cc.set (DataType::MIDI, n_midi);
1152         return cc;
1153 }
1154
1155 /* Getting access to the data buffer for a port */
1156
1157 void*
1158 DummyAudioBackend::get_buffer (PortEngine::PortHandle port, pframes_t nframes)
1159 {
1160         assert (port);
1161         assert (valid_port (port));
1162         return static_cast<DummyPort*>(port)->get_buffer (nframes);
1163 }
1164
1165 /* Engine Process */
1166 void *
1167 DummyAudioBackend::main_process_thread ()
1168 {
1169         AudioEngine::thread_init_callback (this);
1170         _running = true;
1171         _processed_samples = 0;
1172
1173         manager.registration_callback();
1174         manager.graph_order_callback();
1175
1176         int64_t clock1, clock2;
1177         clock1 = _x_get_monotonic_usec();
1178         while (_running) {
1179
1180                 if (_freewheeling != _freewheel) {
1181                         _freewheel = _freewheeling;
1182                         engine.freewheel_callback (_freewheel);
1183                 }
1184
1185                 // re-set input buffers, generate on demand.
1186                 for (std::vector<DummyAudioPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it) {
1187                         (*it)->next_period();
1188                 }
1189                 for (std::vector<DummyMidiPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it) {
1190                         (*it)->next_period();
1191                 }
1192
1193                 if (engine.process_callback (_samples_per_period)) {
1194                         return 0;
1195                 }
1196                 _processed_samples += _samples_per_period;
1197
1198                 if (_device == _("Loopback") && _midi_mode != MidiToAudio) {
1199                         int opn = 0;
1200                         int opc = _system_outputs.size();
1201                         for (std::vector<DummyAudioPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it, ++opn) {
1202                                 DummyAudioPort* op = _system_outputs[(opn % opc)];
1203                                 (*it)->fill_wavetable ((const float*)op->get_buffer (_samples_per_period), _samples_per_period);
1204                         }
1205                 }
1206
1207                 if (_midi_mode == MidiLoopback) {
1208                         int opn = 0;
1209                         int opc = _system_midi_out.size();
1210                         for (std::vector<DummyMidiPort*>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it, ++opn) {
1211                                 DummyMidiPort* op = _system_midi_out[(opn % opc)];
1212                                 op->get_buffer(0); // mix-down
1213                                 (*it)->set_loopback (op->const_buffer());
1214                         }
1215                 }
1216                 else if (_midi_mode == MidiToAudio) {
1217                         int opn = 0;
1218                         int opc = _system_midi_out.size();
1219                         for (std::vector<DummyAudioPort*>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it, ++opn) {
1220                                 DummyMidiPort* op = _system_midi_out[(opn % opc)];
1221                                 op->get_buffer(0); // mix-down
1222                                 (*it)->midi_to_wavetable (op->const_buffer(), _samples_per_period);
1223                         }
1224                 }
1225
1226                 if (!_freewheel) {
1227                         const int64_t nomial_time = 1e6 * _samples_per_period / _samplerate;
1228                         clock2 = _x_get_monotonic_usec();
1229 #ifdef PLATFORM_WINDOWS
1230                         bool win_timers_ok = true;
1231                         /* querying the performance counter can fail occasionally (-1).
1232                          * Also on some multi-core systems, timers are CPU specific and not
1233                          * synchronized. We assume they differ more than a few milliseconds
1234                          * (4 * nominal cycle time) and simply ignore cases where the
1235                          * execution switches cores.
1236                          */
1237                         if (clock1 < 0 || clock2 < 0 || (clock1 > clock2) || (clock2 - clock1) > 4 * nomial_time) {
1238                                 clock2 = clock1 = 0;
1239                                 win_timers_ok = false;
1240                         }
1241 #endif
1242                         const int64_t elapsed_time = clock2 - clock1;
1243 #ifdef PLATFORM_WINDOWS
1244                         if (win_timers_ok)
1245 #endif
1246                         { // low pass filter
1247                                 _dsp_load = _dsp_load + .05 * ((elapsed_time / (float) nomial_time) - _dsp_load) + 1e-12;
1248                         }
1249
1250                         if (elapsed_time < nomial_time) {
1251                                 Glib::usleep (nomial_time - elapsed_time);
1252                         } else {
1253                                 Glib::usleep (100); // don't hog cpu
1254                         }
1255                 } else {
1256                         _dsp_load = 1.0f;
1257                         Glib::usleep (100); // don't hog cpu
1258                 }
1259
1260                 /* beginning of netx cycle */
1261                 clock1 = _x_get_monotonic_usec();
1262
1263                 bool connections_changed = false;
1264                 bool ports_changed = false;
1265                 if (!pthread_mutex_trylock (&_port_callback_mutex)) {
1266                         if (_port_change_flag) {
1267                                 ports_changed = true;
1268                                 _port_change_flag = false;
1269                         }
1270                         if (!_port_connection_queue.empty ()) {
1271                                 connections_changed = true;
1272                         }
1273                         while (!_port_connection_queue.empty ()) {
1274                                 PortConnectData *c = _port_connection_queue.back ();
1275                                 manager.connect_callback (c->a, c->b, c->c);
1276                                 _port_connection_queue.pop_back ();
1277                                 delete c;
1278                         }
1279                         pthread_mutex_unlock (&_port_callback_mutex);
1280                 }
1281                 if (ports_changed) {
1282                         manager.registration_callback();
1283                 }
1284                 if (connections_changed) {
1285                         manager.graph_order_callback();
1286                 }
1287                 if (connections_changed || ports_changed) {
1288                         engine.latency_callback(false);
1289                         engine.latency_callback(true);
1290                 }
1291
1292         }
1293         _running = false;
1294         return 0;
1295 }
1296
1297
1298 /******************************************************************************/
1299
1300 static boost::shared_ptr<DummyAudioBackend> _instance;
1301
1302 static boost::shared_ptr<AudioBackend> backend_factory (AudioEngine& e);
1303 static int instantiate (const std::string& arg1, const std::string& /* arg2 */);
1304 static int deinstantiate ();
1305 static bool already_configured ();
1306 static bool available ();
1307
1308 static ARDOUR::AudioBackendInfo _descriptor = {
1309         "Dummy",
1310         instantiate,
1311         deinstantiate,
1312         backend_factory,
1313         already_configured,
1314         available
1315 };
1316
1317 static boost::shared_ptr<AudioBackend>
1318 backend_factory (AudioEngine& e)
1319 {
1320         if (!_instance) {
1321                 _instance.reset (new DummyAudioBackend (e, _descriptor));
1322         }
1323         return _instance;
1324 }
1325
1326 static int
1327 instantiate (const std::string& arg1, const std::string& /* arg2 */)
1328 {
1329         s_instance_name = arg1;
1330 #ifdef PLATFORM_WINDOWS
1331         LARGE_INTEGER Frequency;
1332         if (!QueryPerformanceFrequency(&Frequency) || Frequency.QuadPart < 1) {
1333                 _win_pc_rate = 0;
1334         } else {
1335                 _win_pc_rate = 1000000.0 / Frequency.QuadPart;
1336         }
1337 #endif
1338         return 0;
1339 }
1340
1341 static int
1342 deinstantiate ()
1343 {
1344         _instance.reset ();
1345         return 0;
1346 }
1347
1348 static bool
1349 already_configured ()
1350 {
1351         if (_instance) {
1352                 return _instance->is_running();
1353         }
1354         return false;
1355 }
1356
1357 static bool
1358 available ()
1359 {
1360         return true;
1361 }
1362
1363 extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor ()
1364 {
1365         return &_descriptor;
1366 }
1367
1368
1369 /******************************************************************************/
1370 DummyPort::DummyPort (DummyAudioBackend &b, const std::string& name, PortFlags flags)
1371         : _dummy_backend (b)
1372         , _name  (name)
1373         , _flags (flags)
1374         , _rseed (0)
1375         , _gen_cycle (false)
1376 {
1377         _capture_latency_range.min = 0;
1378         _capture_latency_range.max = 0;
1379         _playback_latency_range.min = 0;
1380         _playback_latency_range.max = 0;
1381         _dummy_backend.port_connect_add_remove_callback();
1382 }
1383
1384 DummyPort::~DummyPort () {
1385         disconnect_all ();
1386         _dummy_backend.port_connect_add_remove_callback();
1387 }
1388
1389
1390 int DummyPort::connect (DummyPort *port)
1391 {
1392         if (!port) {
1393                 PBD::error << _("DummyPort::connect (): invalid (null) port") << endmsg;
1394                 return -1;
1395         }
1396
1397         if (type () != port->type ()) {
1398                 PBD::error << _("DummyPort::connect (): wrong port-type") << endmsg;
1399                 return -1;
1400         }
1401
1402         if (is_output () && port->is_output ()) {
1403                 PBD::error << _("DummyPort::connect (): cannot inter-connect output ports.") << endmsg;
1404                 return -1;
1405         }
1406
1407         if (is_input () && port->is_input ()) {
1408                 PBD::error << _("DummyPort::connect (): cannot inter-connect input ports.") << endmsg;
1409                 return -1;
1410         }
1411
1412         if (this == port) {
1413                 PBD::error << _("DummyPort::connect (): cannot self-connect ports.") << endmsg;
1414                 return -1;
1415         }
1416
1417         if (is_connected (port)) {
1418 #if 0 // don't bother to warn about this for now. just ignore it
1419                 PBD::error << _("DummyPort::connect (): ports are already connected:")
1420                         << " (" << name () << ") -> (" << port->name () << ")"
1421                         << endmsg;
1422 #endif
1423                 return -1;
1424         }
1425
1426         _connect (port, true);
1427         return 0;
1428 }
1429
1430
1431 void DummyPort::_connect (DummyPort *port, bool callback)
1432 {
1433         _connections.push_back (port);
1434         if (callback) {
1435                 port->_connect (this, false);
1436                 _dummy_backend.port_connect_callback (name(),  port->name(), true);
1437         }
1438 }
1439
1440 int DummyPort::disconnect (DummyPort *port)
1441 {
1442         if (!port) {
1443                 PBD::error << _("DummyPort::disconnect (): invalid (null) port") << endmsg;
1444                 return -1;
1445         }
1446
1447         if (!is_connected (port)) {
1448                 PBD::error << _("DummyPort::disconnect (): ports are not connected:")
1449                         << " (" << name () << ") -> (" << port->name () << ")"
1450                         << endmsg;
1451                 return -1;
1452         }
1453         _disconnect (port, true);
1454         return 0;
1455 }
1456
1457 void DummyPort::_disconnect (DummyPort *port, bool callback)
1458 {
1459         std::vector<DummyPort*>::iterator it = std::find (_connections.begin (), _connections.end (), port);
1460
1461         assert (it != _connections.end ());
1462
1463         _connections.erase (it);
1464
1465         if (callback) {
1466                 port->_disconnect (this, false);
1467                 _dummy_backend.port_connect_callback (name(),  port->name(), false);
1468         }
1469 }
1470
1471
1472 void DummyPort::disconnect_all ()
1473 {
1474         while (!_connections.empty ()) {
1475                 _connections.back ()->_disconnect (this, false);
1476                 _dummy_backend.port_connect_callback (name(),  _connections.back ()->name(), false);
1477                 _connections.pop_back ();
1478         }
1479 }
1480
1481 bool
1482 DummyPort::is_connected (const DummyPort *port) const
1483 {
1484         return std::find (_connections.begin (), _connections.end (), port) != _connections.end ();
1485 }
1486
1487 bool DummyPort::is_physically_connected () const
1488 {
1489         for (std::vector<DummyPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
1490                 if ((*it)->is_physical ()) {
1491                         return true;
1492                 }
1493         }
1494         return false;
1495 }
1496
1497 void DummyPort::setup_random_number_generator ()
1498 {
1499 #ifdef PLATFORM_WINDOWS
1500         LARGE_INTEGER Count;
1501         if (QueryPerformanceCounter (&Count)) {
1502                 _rseed = Count.QuadPart % UINT_MAX;
1503         } else
1504 #endif
1505         {
1506         _rseed = g_get_monotonic_time() % UINT_MAX;
1507         }
1508         _rseed = (_rseed + (uint64_t)this) % UINT_MAX;
1509 }
1510
1511 inline uint32_t
1512 DummyPort::randi ()
1513 {
1514         // 31bit Park-Miller-Carta Pseudo-Random Number Generator
1515         // http://www.firstpr.com.au/dsp/rand31/
1516         uint32_t hi, lo;
1517         lo = 16807 * (_rseed & 0xffff);
1518         hi = 16807 * (_rseed >> 16);
1519
1520         lo += (hi & 0x7fff) << 16;
1521         lo += hi >> 15;
1522 #if 1
1523         lo = (lo & 0x7fffffff) + (lo >> 31);
1524 #else
1525         if (lo > 0x7fffffff) { lo -= 0x7fffffff; }
1526 #endif
1527         return (_rseed = lo);
1528 }
1529
1530 inline float
1531 DummyPort::randf ()
1532 {
1533         return (randi() / 1073741824.f) - 1.f;
1534 }
1535
1536 /******************************************************************************/
1537
1538 DummyAudioPort::DummyAudioPort (DummyAudioBackend &b, const std::string& name, PortFlags flags)
1539         : DummyPort (b, name, flags)
1540         , _gen_type (Silence)
1541         , _b0 (0)
1542         , _b1 (0)
1543         , _b2 (0)
1544         , _b3 (0)
1545         , _b4 (0)
1546         , _b5 (0)
1547         , _b6 (0)
1548         , _wavetable (0)
1549         , _gen_period (0)
1550         , _gen_offset (0)
1551         , _gen_perio2 (0)
1552         , _gen_count2 (0)
1553         , _pass (false)
1554         , _rn1 (0)
1555 {
1556         memset (_buffer, 0, sizeof (_buffer));
1557 }
1558
1559 DummyAudioPort::~DummyAudioPort () {
1560         free(_wavetable);
1561         _wavetable = 0;
1562 }
1563
1564 void DummyAudioPort::setup_generator (GeneratorType const g, float const samplerate)
1565 {
1566         DummyPort::setup_random_number_generator();
1567         _gen_type = g;
1568
1569         switch (_gen_type) {
1570                 case PinkNoise:
1571                 case PonyNoise:
1572                 case UniformWhiteNoise:
1573                 case GaussianWhiteNoise:
1574                 case Silence:
1575                         break;
1576                 case KronekerDelta:
1577                         _gen_period = (5 + randi() % (int)(samplerate / 20.f));
1578                         break;
1579                 case SquareWave:
1580                         _gen_period = (5 + randi() % (int)(samplerate / 20.f)) & ~1;
1581                         break;
1582                 case SineWave:
1583                         _gen_period = 5 + randi() % (int)(samplerate / 20.f);
1584                         _wavetable = (Sample*) malloc (_gen_period * sizeof(Sample));
1585                         for (uint32_t i = 0 ; i < _gen_period; ++i) {
1586                                 _wavetable[i] = .12589f * sinf(2.0f * M_PI * (float)i / (float)_gen_period); // -18dBFS
1587                         }
1588                         break;
1589                 case SquareSweep:
1590                 case SquareSweepSwell:
1591                 case SineSweep:
1592                 case SineSweepSwell:
1593                         {
1594                                 _gen_period = 5 * samplerate + randi() % (int)(samplerate * 10.f);
1595                                 _gen_period &= ~1;
1596                                 _gen_perio2 = 1 | (int)ceilf (_gen_period * .89f); // Volume Swell period
1597                                 const double f_min = 20.;
1598                                 const double f_max = samplerate * .5;
1599                                 const double g_p2 = _gen_period * .5;
1600 #ifdef LINEAR_SWEEP
1601                                 const double b = (f_max - f_min) / (2. * samplerate * g_p2);
1602                                 const double a = f_min / samplerate;
1603 #else
1604                                 const double b = log (f_max / f_min) / g_p2;
1605                                 const double a = f_min / (b * samplerate);
1606 #endif
1607                                 const uint32_t g_p2i = rint(g_p2);
1608                                 _wavetable = (Sample*) malloc (_gen_period * sizeof(Sample));
1609                                 for (uint32_t i = 0 ; i < g_p2i; ++i) {
1610 #ifdef LINEAR_SWEEP
1611                                         const double phase = i * (a + b * i);
1612 #else
1613                                         const double phase = a * exp (b * i) - a;
1614 #endif
1615                                         _wavetable[i] = (float)sin (2. * M_PI * (phase - floor (phase)));
1616                                 }
1617                                 for (uint32_t i = g_p2i; i < _gen_period; ++i) {
1618                                         const uint32_t j = _gen_period - i;
1619 #ifdef LINEAR_SWEEP
1620                                         const double phase = j * (a + b * j);
1621 #else
1622                                         const double phase = a * exp (b * j) - a;
1623 #endif
1624                                         _wavetable[i] = (float)sin (2. * M_PI * (phase - floor (phase)));
1625                                 }
1626                                 if (_gen_type == SquareSweep) {
1627                                         for (uint32_t i = 0 ; i < _gen_period; ++i) {
1628                                                 _wavetable[i] = _wavetable[i] < 0 ? -.40709f : .40709f;
1629                                         }
1630                                 }
1631                                 else if (_gen_type == SquareSweepSwell) {
1632                                         for (uint32_t i = 0 ; i < _gen_period; ++i) {
1633                                                 _wavetable[i] = _wavetable[i] < 0 ? -1 : 1;
1634                                         }
1635                                 }
1636                         }
1637                         break;
1638                 case Loopback:
1639                         _wavetable = (Sample*) malloc (DummyAudioBackend::max_buffer_size() * sizeof(Sample));
1640                         break;
1641         }
1642 }
1643
1644 void DummyAudioPort::midi_to_wavetable (DummyMidiBuffer const * const src, size_t n_samples)
1645 {
1646         memset(_wavetable, 0, n_samples * sizeof(float));
1647         /* generate an audio spike for every midi message
1648          * to verify layency-compensation alignment
1649          * (here: midi-out playback-latency + audio-in capture-latency)
1650          */
1651         for (DummyMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
1652                 const pframes_t t = (*it)->timestamp();
1653                 assert(t < n_samples);
1654                 // somewhat arbitrary mapping for quick visual feedback
1655                 float v = -.5f;
1656                 if ((*it)->size() == 3) {
1657                         const unsigned char *d = (*it)->const_data();
1658                         if ((d[0] & 0xf0) == 0x90) { // note on
1659                                 v = .25f + d[2] / 512.f;
1660                         }
1661                         else if ((d[0] & 0xf0) == 0x80) { // note off
1662                                 v = .3f - d[2] / 640.f;
1663                         }
1664                         else if ((d[0] & 0xf0) == 0xb0) { // CC
1665                                 v = -.1f - d[2] / 256.f;
1666                         }
1667                 }
1668                 _wavetable[t] += v;
1669         }
1670 }
1671
1672 float DummyAudioPort::grandf ()
1673 {
1674         // Gaussian White Noise
1675         // http://www.musicdsp.org/archive.php?classid=0#109
1676         float x1, x2, r;
1677
1678         if (_pass) {
1679                 _pass = false;
1680                 return _rn1;
1681         }
1682
1683         do {
1684                 x1 = randf ();
1685                 x2 = randf ();
1686                 r = x1 * x1 + x2 * x2;
1687         } while ((r >= 1.0f) || (r < 1e-22f));
1688
1689         r = sqrtf (-2.f * logf (r) / r);
1690
1691         _pass = true;
1692         _rn1 = r * x2;
1693         return r * x1;
1694 }
1695
1696 void DummyAudioPort::generate (const pframes_t n_samples)
1697 {
1698         Glib::Threads::Mutex::Lock lm (generator_lock);
1699         if (_gen_cycle) {
1700                 return;
1701         }
1702
1703         switch (_gen_type) {
1704                 case Silence:
1705                         memset (_buffer, 0, n_samples * sizeof (Sample));
1706                         break;
1707                 case SquareWave:
1708                         assert(_gen_period > 0);
1709                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1710                                 if (_gen_offset < _gen_period * .5f) {
1711                                         _buffer[i] =  .40709f; // -6dBFS
1712                                 } else {
1713                                         _buffer[i] = -.40709f;
1714                                 }
1715                                 _gen_offset = (_gen_offset + 1) % _gen_period;
1716                         }
1717                         break;
1718                 case KronekerDelta:
1719                         assert(_gen_period > 0);
1720                         memset (_buffer, 0, n_samples * sizeof (Sample));
1721                         for (pframes_t i = 0; i < n_samples; ++i) {
1722                                 if (_gen_offset == 0) {
1723                                         _buffer[i] = 1.0f;
1724                                 }
1725                                 _gen_offset = (_gen_offset + 1) % _gen_period;
1726                         }
1727                         break;
1728                 case SineSweepSwell:
1729                 case SquareSweepSwell:
1730                         assert(_wavetable && _gen_period > 0);
1731                         {
1732                                 const float vols = 2.f / (float)_gen_perio2;
1733                                 for (pframes_t i = 0; i < n_samples; ++i) {
1734                                         const float g = fabsf (_gen_count2 * vols - 1.0);
1735                                         _buffer[i] = g * _wavetable[_gen_offset];
1736                                         _gen_offset = (_gen_offset + 1) % _gen_period;
1737                                         _gen_count2 = (_gen_count2 + 1) % _gen_perio2;
1738                                 }
1739                         }
1740                         break;
1741                 case Loopback:
1742                         _gen_period = n_samples; // XXX DummyBackend::_samples_per_period;
1743                 case SineWave:
1744                 case SineSweep:
1745                 case SquareSweep:
1746                         assert(_wavetable && _gen_period > 0);
1747                         {
1748                                 pframes_t written = 0;
1749                                 while (written < n_samples) {
1750                                         const uint32_t remain = n_samples - written;
1751                                         const uint32_t to_copy = std::min(remain, _gen_period - _gen_offset);
1752                                         memcpy((void*)&_buffer[written],
1753                                                         (void*)&_wavetable[_gen_offset],
1754                                                         to_copy * sizeof(Sample));
1755                                         written += to_copy;
1756                                         _gen_offset = (_gen_offset + to_copy) % _gen_period;
1757                                 }
1758                         }
1759                         break;
1760                 case UniformWhiteNoise:
1761                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1762                                 _buffer[i] = .158489f * randf();
1763                         }
1764                         break;
1765                 case GaussianWhiteNoise:
1766                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1767                                 _buffer[i] = .089125f * grandf();
1768                         }
1769                         break;
1770                 case PinkNoise:
1771                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1772                                 // Paul Kellet's refined method
1773                                 // http://www.musicdsp.org/files/pink.txt
1774                                 // NB. If 'white' consists of uniform random numbers,
1775                                 // the pink noise will have an almost gaussian distribution.
1776                                 const float white = .0498f * randf ();
1777                                 _b0 = .99886f * _b0 + white * .0555179f;
1778                                 _b1 = .99332f * _b1 + white * .0750759f;
1779                                 _b2 = .96900f * _b2 + white * .1538520f;
1780                                 _b3 = .86650f * _b3 + white * .3104856f;
1781                                 _b4 = .55000f * _b4 + white * .5329522f;
1782                                 _b5 = -.7616f * _b5 - white * .0168980f;
1783                                 _buffer[i] = _b0 + _b1 + _b2 + _b3 + _b4 + _b5 + _b6 + white * 0.5362f;
1784                                 _b6 = white * 0.115926f;
1785                         }
1786                         break;
1787                 case PonyNoise:
1788                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1789                                 const float white = 0.0498f * randf ();
1790                                 // Paul Kellet's economy method
1791                                 // http://www.musicdsp.org/files/pink.txt
1792                                 _b0 = 0.99765f * _b0 + white * 0.0990460f;
1793                                 _b1 = 0.96300f * _b1 + white * 0.2965164f;
1794                                 _b2 = 0.57000f * _b2 + white * 1.0526913f;
1795                                 _buffer[i] = _b0 + _b1 + _b2 + white * 0.1848f;
1796                         }
1797                         break;
1798         }
1799         _gen_cycle = true;
1800 }
1801
1802 void* DummyAudioPort::get_buffer (pframes_t n_samples)
1803 {
1804         if (is_input ()) {
1805                 std::vector<DummyPort*>::const_iterator it = get_connections ().begin ();
1806                 if (it == get_connections ().end ()) {
1807                         memset (_buffer, 0, n_samples * sizeof (Sample));
1808                 } else {
1809                         DummyAudioPort * source = static_cast<DummyAudioPort*>(*it);
1810                         assert (source && source->is_output ());
1811                         if (source->is_physical() && source->is_terminal()) {
1812                                 source->get_buffer(n_samples); // generate signal.
1813                         }
1814                         memcpy (_buffer, source->const_buffer (), n_samples * sizeof (Sample));
1815                         while (++it != get_connections ().end ()) {
1816                                 source = static_cast<DummyAudioPort*>(*it);
1817                                 assert (source && source->is_output ());
1818                                 Sample* dst = buffer ();
1819                                 if (source->is_physical() && source->is_terminal()) {
1820                                         source->get_buffer(n_samples); // generate signal.
1821                                 }
1822                                 const Sample* src = source->const_buffer ();
1823                                 for (uint32_t s = 0; s < n_samples; ++s, ++dst, ++src) {
1824                                         *dst += *src;
1825                                 }
1826                         }
1827                 }
1828         } else if (is_output () && is_physical () && is_terminal()) {
1829                 if (!_gen_cycle) {
1830                         generate(n_samples);
1831                 }
1832         }
1833         return _buffer;
1834 }
1835
1836
1837 DummyMidiPort::DummyMidiPort (DummyAudioBackend &b, const std::string& name, PortFlags flags)
1838         : DummyPort (b, name, flags)
1839         , _midi_seq_spb (0)
1840         , _midi_seq_time (0)
1841         , _midi_seq_pos (0)
1842 {
1843         _buffer.clear ();
1844         _loopback.clear ();
1845 }
1846
1847 DummyMidiPort::~DummyMidiPort () {
1848         _buffer.clear ();
1849         _loopback.clear ();
1850 }
1851
1852 struct MidiEventSorter {
1853         bool operator() (const boost::shared_ptr<DummyMidiEvent>& a, const boost::shared_ptr<DummyMidiEvent>& b) {
1854                 return *a < *b;
1855         }
1856 };
1857
1858 void DummyMidiPort::set_loopback (DummyMidiBuffer const * const src)
1859 {
1860         _loopback.clear ();
1861         for (DummyMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
1862                 _loopback.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (**it)));
1863         }
1864 }
1865
1866 void DummyMidiPort::setup_generator (int seq_id, const float sr)
1867 {
1868         DummyPort::setup_random_number_generator();
1869         _midi_seq_dat = DummyMidiData::sequences[seq_id % NUM_MIDI_EVENT_GENERATORS];
1870         _midi_seq_spb = sr * .5f; // 120 BPM, beat_time 1.0 per beat.
1871         _midi_seq_pos = 0;
1872         _midi_seq_time = 0;
1873 }
1874
1875 void DummyMidiPort::midi_generate (const pframes_t n_samples)
1876 {
1877         Glib::Threads::Mutex::Lock lm (generator_lock);
1878         if (_gen_cycle) {
1879                 return;
1880         }
1881
1882         _buffer.clear ();
1883         _gen_cycle = true;
1884
1885         if (_midi_seq_spb == 0 || !_midi_seq_dat) {
1886                 for (DummyMidiBuffer::const_iterator it = _loopback.begin (); it != _loopback.end (); ++it) {
1887                         _buffer.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (**it)));
1888                 }
1889                 return;
1890         }
1891
1892         while (1) {
1893                 const int32_t ev_beat_time = _midi_seq_dat[_midi_seq_pos].beat_time * _midi_seq_spb - _midi_seq_time;
1894                 if (ev_beat_time < 0) {
1895                         break;
1896                 }
1897                 if ((pframes_t) ev_beat_time >= n_samples) {
1898                         break;
1899                 }
1900                 _buffer.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (
1901                                                 ev_beat_time,
1902                                                 _midi_seq_dat[_midi_seq_pos].event,
1903                                                 _midi_seq_dat[_midi_seq_pos].size
1904                                                 )));
1905                 ++_midi_seq_pos;
1906
1907                 if (_midi_seq_dat[_midi_seq_pos].event[0] == 0xff && _midi_seq_dat[_midi_seq_pos].event[1] == 0xff) {
1908                         _midi_seq_time -= _midi_seq_dat[_midi_seq_pos].beat_time * _midi_seq_spb;
1909                         _midi_seq_pos = 0;
1910                 }
1911         }
1912         _midi_seq_time += n_samples;
1913 }
1914
1915
1916 void* DummyMidiPort::get_buffer (pframes_t n_samples)
1917 {
1918         if (is_input ()) {
1919                 _buffer.clear ();
1920                 for (std::vector<DummyPort*>::const_iterator i = get_connections ().begin ();
1921                                 i != get_connections ().end ();
1922                                 ++i) {
1923                         DummyMidiPort * source = static_cast<DummyMidiPort*>(*i);
1924                         if (source->is_physical() && source->is_terminal()) {
1925                                 source->get_buffer(n_samples); // generate signal.
1926                         }
1927                         const DummyMidiBuffer *src = source->const_buffer ();
1928                         for (DummyMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
1929                                 _buffer.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (**it)));
1930                         }
1931                 }
1932                 std::sort (_buffer.begin (), _buffer.end (), MidiEventSorter());
1933         } else if (is_output () && is_physical () && is_terminal()) {
1934                 if (!_gen_cycle) {
1935                         midi_generate(n_samples);
1936                 }
1937         }
1938         return &_buffer;
1939 }
1940
1941 DummyMidiEvent::DummyMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size)
1942         : _size (size)
1943         , _timestamp (timestamp)
1944         , _data (0)
1945 {
1946         if (size > 0) {
1947                 _data = (uint8_t*) malloc (size);
1948                 memcpy (_data, data, size);
1949         }
1950 }
1951
1952 DummyMidiEvent::DummyMidiEvent (const DummyMidiEvent& other)
1953         : _size (other.size ())
1954         , _timestamp (other.timestamp ())
1955         , _data (0)
1956 {
1957         if (other.size () && other.const_data ()) {
1958                 _data = (uint8_t*) malloc (other.size ());
1959                 memcpy (_data, other.const_data (), other.size ());
1960         }
1961 };
1962
1963 DummyMidiEvent::~DummyMidiEvent () {
1964         free (_data);
1965 };