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