1ba91f39dd313e67b03a591d2d558a28a2f7275e
[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         _system_inputs.clear();
823         _system_outputs.clear();
824         _system_midi_in.clear();
825         _system_midi_out.clear();
826
827         for (std::vector<DummyPort*>::iterator i = _ports.begin (); i != _ports.end ();) {
828                 DummyPort* port = *i;
829                 if (! system_only || (port->is_physical () && port->is_terminal ())) {
830                         port->disconnect_all ();
831                         delete port;
832                         i = _ports.erase (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 nominal_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 * nominal_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                                 const float load = elapsed_time / (float) nominal_time;
1248                                 if (load > _dsp_load) {
1249                                         _dsp_load = load;
1250                                 } else {
1251                                         const float a = .1 * _samples_per_period / _samplerate;
1252                                         _dsp_load = _dsp_load + a * (load - _dsp_load) + 1e-12;
1253                                 }
1254                         }
1255
1256                         if (elapsed_time < nominal_time) {
1257                                 Glib::usleep (nominal_time - elapsed_time);
1258                         } else {
1259                                 Glib::usleep (100); // don't hog cpu
1260                         }
1261                 } else {
1262                         _dsp_load = 1.0f;
1263                         Glib::usleep (100); // don't hog cpu
1264                 }
1265
1266                 /* beginning of netx cycle */
1267                 clock1 = _x_get_monotonic_usec();
1268
1269                 bool connections_changed = false;
1270                 bool ports_changed = false;
1271                 if (!pthread_mutex_trylock (&_port_callback_mutex)) {
1272                         if (_port_change_flag) {
1273                                 ports_changed = true;
1274                                 _port_change_flag = false;
1275                         }
1276                         if (!_port_connection_queue.empty ()) {
1277                                 connections_changed = true;
1278                         }
1279                         while (!_port_connection_queue.empty ()) {
1280                                 PortConnectData *c = _port_connection_queue.back ();
1281                                 manager.connect_callback (c->a, c->b, c->c);
1282                                 _port_connection_queue.pop_back ();
1283                                 delete c;
1284                         }
1285                         pthread_mutex_unlock (&_port_callback_mutex);
1286                 }
1287                 if (ports_changed) {
1288                         manager.registration_callback();
1289                 }
1290                 if (connections_changed) {
1291                         manager.graph_order_callback();
1292                 }
1293                 if (connections_changed || ports_changed) {
1294                         engine.latency_callback(false);
1295                         engine.latency_callback(true);
1296                 }
1297
1298         }
1299         _running = false;
1300         return 0;
1301 }
1302
1303
1304 /******************************************************************************/
1305
1306 static boost::shared_ptr<DummyAudioBackend> _instance;
1307
1308 static boost::shared_ptr<AudioBackend> backend_factory (AudioEngine& e);
1309 static int instantiate (const std::string& arg1, const std::string& /* arg2 */);
1310 static int deinstantiate ();
1311 static bool already_configured ();
1312 static bool available ();
1313
1314 static ARDOUR::AudioBackendInfo _descriptor = {
1315         "Dummy",
1316         instantiate,
1317         deinstantiate,
1318         backend_factory,
1319         already_configured,
1320         available
1321 };
1322
1323 static boost::shared_ptr<AudioBackend>
1324 backend_factory (AudioEngine& e)
1325 {
1326         if (!_instance) {
1327                 _instance.reset (new DummyAudioBackend (e, _descriptor));
1328         }
1329         return _instance;
1330 }
1331
1332 static int
1333 instantiate (const std::string& arg1, const std::string& /* arg2 */)
1334 {
1335         s_instance_name = arg1;
1336 #ifdef PLATFORM_WINDOWS
1337         LARGE_INTEGER Frequency;
1338         if (!QueryPerformanceFrequency(&Frequency) || Frequency.QuadPart < 1) {
1339                 _win_pc_rate = 0;
1340         } else {
1341                 _win_pc_rate = 1000000.0 / Frequency.QuadPart;
1342         }
1343 #endif
1344         return 0;
1345 }
1346
1347 static int
1348 deinstantiate ()
1349 {
1350         _instance.reset ();
1351         return 0;
1352 }
1353
1354 static bool
1355 already_configured ()
1356 {
1357         if (_instance) {
1358                 return _instance->is_running();
1359         }
1360         return false;
1361 }
1362
1363 static bool
1364 available ()
1365 {
1366         return true;
1367 }
1368
1369 extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor ()
1370 {
1371         return &_descriptor;
1372 }
1373
1374
1375 /******************************************************************************/
1376 DummyPort::DummyPort (DummyAudioBackend &b, const std::string& name, PortFlags flags)
1377         : _dummy_backend (b)
1378         , _name  (name)
1379         , _flags (flags)
1380         , _rseed (0)
1381         , _gen_cycle (false)
1382 {
1383         _capture_latency_range.min = 0;
1384         _capture_latency_range.max = 0;
1385         _playback_latency_range.min = 0;
1386         _playback_latency_range.max = 0;
1387         _dummy_backend.port_connect_add_remove_callback();
1388 }
1389
1390 DummyPort::~DummyPort () {
1391         disconnect_all ();
1392         _dummy_backend.port_connect_add_remove_callback();
1393 }
1394
1395
1396 int DummyPort::connect (DummyPort *port)
1397 {
1398         if (!port) {
1399                 PBD::error << _("DummyPort::connect (): invalid (null) port") << endmsg;
1400                 return -1;
1401         }
1402
1403         if (type () != port->type ()) {
1404                 PBD::error << _("DummyPort::connect (): wrong port-type") << endmsg;
1405                 return -1;
1406         }
1407
1408         if (is_output () && port->is_output ()) {
1409                 PBD::error << _("DummyPort::connect (): cannot inter-connect output ports.") << endmsg;
1410                 return -1;
1411         }
1412
1413         if (is_input () && port->is_input ()) {
1414                 PBD::error << _("DummyPort::connect (): cannot inter-connect input ports.") << endmsg;
1415                 return -1;
1416         }
1417
1418         if (this == port) {
1419                 PBD::error << _("DummyPort::connect (): cannot self-connect ports.") << endmsg;
1420                 return -1;
1421         }
1422
1423         if (is_connected (port)) {
1424 #if 0 // don't bother to warn about this for now. just ignore it
1425                 PBD::error << _("DummyPort::connect (): ports are already connected:")
1426                         << " (" << name () << ") -> (" << port->name () << ")"
1427                         << endmsg;
1428 #endif
1429                 return -1;
1430         }
1431
1432         _connect (port, true);
1433         return 0;
1434 }
1435
1436
1437 void DummyPort::_connect (DummyPort *port, bool callback)
1438 {
1439         _connections.push_back (port);
1440         if (callback) {
1441                 port->_connect (this, false);
1442                 _dummy_backend.port_connect_callback (name(),  port->name(), true);
1443         }
1444 }
1445
1446 int DummyPort::disconnect (DummyPort *port)
1447 {
1448         if (!port) {
1449                 PBD::error << _("DummyPort::disconnect (): invalid (null) port") << endmsg;
1450                 return -1;
1451         }
1452
1453         if (!is_connected (port)) {
1454                 PBD::error << _("DummyPort::disconnect (): ports are not connected:")
1455                         << " (" << name () << ") -> (" << port->name () << ")"
1456                         << endmsg;
1457                 return -1;
1458         }
1459         _disconnect (port, true);
1460         return 0;
1461 }
1462
1463 void DummyPort::_disconnect (DummyPort *port, bool callback)
1464 {
1465         std::vector<DummyPort*>::iterator it = std::find (_connections.begin (), _connections.end (), port);
1466
1467         assert (it != _connections.end ());
1468
1469         _connections.erase (it);
1470
1471         if (callback) {
1472                 port->_disconnect (this, false);
1473                 _dummy_backend.port_connect_callback (name(),  port->name(), false);
1474         }
1475 }
1476
1477
1478 void DummyPort::disconnect_all ()
1479 {
1480         while (!_connections.empty ()) {
1481                 _connections.back ()->_disconnect (this, false);
1482                 _dummy_backend.port_connect_callback (name(),  _connections.back ()->name(), false);
1483                 _connections.pop_back ();
1484         }
1485 }
1486
1487 bool
1488 DummyPort::is_connected (const DummyPort *port) const
1489 {
1490         return std::find (_connections.begin (), _connections.end (), port) != _connections.end ();
1491 }
1492
1493 bool DummyPort::is_physically_connected () const
1494 {
1495         for (std::vector<DummyPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) {
1496                 if ((*it)->is_physical ()) {
1497                         return true;
1498                 }
1499         }
1500         return false;
1501 }
1502
1503 void DummyPort::setup_random_number_generator ()
1504 {
1505 #ifdef PLATFORM_WINDOWS
1506         LARGE_INTEGER Count;
1507         if (QueryPerformanceCounter (&Count)) {
1508                 _rseed = Count.QuadPart % UINT_MAX;
1509         } else
1510 #endif
1511         {
1512         _rseed = g_get_monotonic_time() % UINT_MAX;
1513         }
1514         _rseed = (_rseed + (uint64_t)this) % UINT_MAX;
1515 }
1516
1517 inline uint32_t
1518 DummyPort::randi ()
1519 {
1520         // 31bit Park-Miller-Carta Pseudo-Random Number Generator
1521         // http://www.firstpr.com.au/dsp/rand31/
1522         uint32_t hi, lo;
1523         lo = 16807 * (_rseed & 0xffff);
1524         hi = 16807 * (_rseed >> 16);
1525
1526         lo += (hi & 0x7fff) << 16;
1527         lo += hi >> 15;
1528 #if 1
1529         lo = (lo & 0x7fffffff) + (lo >> 31);
1530 #else
1531         if (lo > 0x7fffffff) { lo -= 0x7fffffff; }
1532 #endif
1533         return (_rseed = lo);
1534 }
1535
1536 inline float
1537 DummyPort::randf ()
1538 {
1539         return (randi() / 1073741824.f) - 1.f;
1540 }
1541
1542 /******************************************************************************/
1543
1544 DummyAudioPort::DummyAudioPort (DummyAudioBackend &b, const std::string& name, PortFlags flags)
1545         : DummyPort (b, name, flags)
1546         , _gen_type (Silence)
1547         , _b0 (0)
1548         , _b1 (0)
1549         , _b2 (0)
1550         , _b3 (0)
1551         , _b4 (0)
1552         , _b5 (0)
1553         , _b6 (0)
1554         , _wavetable (0)
1555         , _gen_period (0)
1556         , _gen_offset (0)
1557         , _gen_perio2 (0)
1558         , _gen_count2 (0)
1559         , _pass (false)
1560         , _rn1 (0)
1561 {
1562         memset (_buffer, 0, sizeof (_buffer));
1563 }
1564
1565 DummyAudioPort::~DummyAudioPort () {
1566         free(_wavetable);
1567         _wavetable = 0;
1568 }
1569
1570 void DummyAudioPort::setup_generator (GeneratorType const g, float const samplerate)
1571 {
1572         DummyPort::setup_random_number_generator();
1573         _gen_type = g;
1574
1575         switch (_gen_type) {
1576                 case PinkNoise:
1577                 case PonyNoise:
1578                 case UniformWhiteNoise:
1579                 case GaussianWhiteNoise:
1580                 case Silence:
1581                         break;
1582                 case KronekerDelta:
1583                         _gen_period = (5 + randi() % (int)(samplerate / 20.f));
1584                         break;
1585                 case SquareWave:
1586                         _gen_period = (5 + randi() % (int)(samplerate / 20.f)) & ~1;
1587                         break;
1588                 case SineWave:
1589                         _gen_period = 5 + randi() % (int)(samplerate / 20.f);
1590                         _wavetable = (Sample*) malloc (_gen_period * sizeof(Sample));
1591                         for (uint32_t i = 0 ; i < _gen_period; ++i) {
1592                                 _wavetable[i] = .12589f * sinf(2.0f * M_PI * (float)i / (float)_gen_period); // -18dBFS
1593                         }
1594                         break;
1595                 case SquareSweep:
1596                 case SquareSweepSwell:
1597                 case SineSweep:
1598                 case SineSweepSwell:
1599                         {
1600                                 _gen_period = 5 * samplerate + randi() % (int)(samplerate * 10.f);
1601                                 _gen_period &= ~1;
1602                                 _gen_perio2 = 1 | (int)ceilf (_gen_period * .89f); // Volume Swell period
1603                                 const double f_min = 20.;
1604                                 const double f_max = samplerate * .5;
1605                                 const double g_p2 = _gen_period * .5;
1606 #ifdef LINEAR_SWEEP
1607                                 const double b = (f_max - f_min) / (2. * samplerate * g_p2);
1608                                 const double a = f_min / samplerate;
1609 #else
1610                                 const double b = log (f_max / f_min) / g_p2;
1611                                 const double a = f_min / (b * samplerate);
1612 #endif
1613                                 const uint32_t g_p2i = rint(g_p2);
1614                                 _wavetable = (Sample*) malloc (_gen_period * sizeof(Sample));
1615                                 for (uint32_t i = 0 ; i < g_p2i; ++i) {
1616 #ifdef LINEAR_SWEEP
1617                                         const double phase = i * (a + b * i);
1618 #else
1619                                         const double phase = a * exp (b * i) - a;
1620 #endif
1621                                         _wavetable[i] = (float)sin (2. * M_PI * (phase - floor (phase)));
1622                                 }
1623                                 for (uint32_t i = g_p2i; i < _gen_period; ++i) {
1624                                         const uint32_t j = _gen_period - i;
1625 #ifdef LINEAR_SWEEP
1626                                         const double phase = j * (a + b * j);
1627 #else
1628                                         const double phase = a * exp (b * j) - a;
1629 #endif
1630                                         _wavetable[i] = -(float)sin (2. * M_PI * (phase - floor (phase)));
1631                                 }
1632                                 if (_gen_type == SquareSweep) {
1633                                         for (uint32_t i = 0 ; i < _gen_period; ++i) {
1634                                                 _wavetable[i] = _wavetable[i] < 0 ? -.40709f : .40709f;
1635                                         }
1636                                 }
1637                                 else if (_gen_type == SquareSweepSwell) {
1638                                         for (uint32_t i = 0 ; i < _gen_period; ++i) {
1639                                                 _wavetable[i] = _wavetable[i] < 0 ? -1 : 1;
1640                                         }
1641                                 }
1642                         }
1643                         break;
1644                 case Loopback:
1645                         _wavetable = (Sample*) malloc (DummyAudioBackend::max_buffer_size() * sizeof(Sample));
1646                         break;
1647         }
1648 }
1649
1650 void DummyAudioPort::midi_to_wavetable (DummyMidiBuffer const * const src, size_t n_samples)
1651 {
1652         memset(_wavetable, 0, n_samples * sizeof(float));
1653         /* generate an audio spike for every midi message
1654          * to verify layency-compensation alignment
1655          * (here: midi-out playback-latency + audio-in capture-latency)
1656          */
1657         for (DummyMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
1658                 const pframes_t t = (*it)->timestamp();
1659                 assert(t < n_samples);
1660                 // somewhat arbitrary mapping for quick visual feedback
1661                 float v = -.5f;
1662                 if ((*it)->size() == 3) {
1663                         const unsigned char *d = (*it)->const_data();
1664                         if ((d[0] & 0xf0) == 0x90) { // note on
1665                                 v = .25f + d[2] / 512.f;
1666                         }
1667                         else if ((d[0] & 0xf0) == 0x80) { // note off
1668                                 v = .3f - d[2] / 640.f;
1669                         }
1670                         else if ((d[0] & 0xf0) == 0xb0) { // CC
1671                                 v = -.1f - d[2] / 256.f;
1672                         }
1673                 }
1674                 _wavetable[t] += v;
1675         }
1676 }
1677
1678 float DummyAudioPort::grandf ()
1679 {
1680         // Gaussian White Noise
1681         // http://www.musicdsp.org/archive.php?classid=0#109
1682         float x1, x2, r;
1683
1684         if (_pass) {
1685                 _pass = false;
1686                 return _rn1;
1687         }
1688
1689         do {
1690                 x1 = randf ();
1691                 x2 = randf ();
1692                 r = x1 * x1 + x2 * x2;
1693         } while ((r >= 1.0f) || (r < 1e-22f));
1694
1695         r = sqrtf (-2.f * logf (r) / r);
1696
1697         _pass = true;
1698         _rn1 = r * x2;
1699         return r * x1;
1700 }
1701
1702 void DummyAudioPort::generate (const pframes_t n_samples)
1703 {
1704         Glib::Threads::Mutex::Lock lm (generator_lock);
1705         if (_gen_cycle) {
1706                 return;
1707         }
1708
1709         switch (_gen_type) {
1710                 case Silence:
1711                         memset (_buffer, 0, n_samples * sizeof (Sample));
1712                         break;
1713                 case SquareWave:
1714                         assert(_gen_period > 0);
1715                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1716                                 if (_gen_offset < _gen_period * .5f) {
1717                                         _buffer[i] =  .40709f; // -6dBFS
1718                                 } else {
1719                                         _buffer[i] = -.40709f;
1720                                 }
1721                                 _gen_offset = (_gen_offset + 1) % _gen_period;
1722                         }
1723                         break;
1724                 case KronekerDelta:
1725                         assert(_gen_period > 0);
1726                         memset (_buffer, 0, n_samples * sizeof (Sample));
1727                         for (pframes_t i = 0; i < n_samples; ++i) {
1728                                 if (_gen_offset == 0) {
1729                                         _buffer[i] = 1.0f;
1730                                 }
1731                                 _gen_offset = (_gen_offset + 1) % _gen_period;
1732                         }
1733                         break;
1734                 case SineSweepSwell:
1735                 case SquareSweepSwell:
1736                         assert(_wavetable && _gen_period > 0);
1737                         {
1738                                 const float vols = 2.f / (float)_gen_perio2;
1739                                 for (pframes_t i = 0; i < n_samples; ++i) {
1740                                         const float g = fabsf (_gen_count2 * vols - 1.0);
1741                                         _buffer[i] = g * _wavetable[_gen_offset];
1742                                         _gen_offset = (_gen_offset + 1) % _gen_period;
1743                                         _gen_count2 = (_gen_count2 + 1) % _gen_perio2;
1744                                 }
1745                         }
1746                         break;
1747                 case Loopback:
1748                         _gen_period = n_samples; // XXX DummyBackend::_samples_per_period;
1749                 case SineWave:
1750                 case SineSweep:
1751                 case SquareSweep:
1752                         assert(_wavetable && _gen_period > 0);
1753                         {
1754                                 pframes_t written = 0;
1755                                 while (written < n_samples) {
1756                                         const uint32_t remain = n_samples - written;
1757                                         const uint32_t to_copy = std::min(remain, _gen_period - _gen_offset);
1758                                         memcpy((void*)&_buffer[written],
1759                                                         (void*)&_wavetable[_gen_offset],
1760                                                         to_copy * sizeof(Sample));
1761                                         written += to_copy;
1762                                         _gen_offset = (_gen_offset + to_copy) % _gen_period;
1763                                 }
1764                         }
1765                         break;
1766                 case UniformWhiteNoise:
1767                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1768                                 _buffer[i] = .158489f * randf();
1769                         }
1770                         break;
1771                 case GaussianWhiteNoise:
1772                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1773                                 _buffer[i] = .089125f * grandf();
1774                         }
1775                         break;
1776                 case PinkNoise:
1777                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1778                                 // Paul Kellet's refined method
1779                                 // http://www.musicdsp.org/files/pink.txt
1780                                 // NB. If 'white' consists of uniform random numbers,
1781                                 // the pink noise will have an almost gaussian distribution.
1782                                 const float white = .0498f * randf ();
1783                                 _b0 = .99886f * _b0 + white * .0555179f;
1784                                 _b1 = .99332f * _b1 + white * .0750759f;
1785                                 _b2 = .96900f * _b2 + white * .1538520f;
1786                                 _b3 = .86650f * _b3 + white * .3104856f;
1787                                 _b4 = .55000f * _b4 + white * .5329522f;
1788                                 _b5 = -.7616f * _b5 - white * .0168980f;
1789                                 _buffer[i] = _b0 + _b1 + _b2 + _b3 + _b4 + _b5 + _b6 + white * 0.5362f;
1790                                 _b6 = white * 0.115926f;
1791                         }
1792                         break;
1793                 case PonyNoise:
1794                         for (pframes_t i = 0 ; i < n_samples; ++i) {
1795                                 const float white = 0.0498f * randf ();
1796                                 // Paul Kellet's economy method
1797                                 // http://www.musicdsp.org/files/pink.txt
1798                                 _b0 = 0.99765f * _b0 + white * 0.0990460f;
1799                                 _b1 = 0.96300f * _b1 + white * 0.2965164f;
1800                                 _b2 = 0.57000f * _b2 + white * 1.0526913f;
1801                                 _buffer[i] = _b0 + _b1 + _b2 + white * 0.1848f;
1802                         }
1803                         break;
1804         }
1805         _gen_cycle = true;
1806 }
1807
1808 void* DummyAudioPort::get_buffer (pframes_t n_samples)
1809 {
1810         if (is_input ()) {
1811                 std::vector<DummyPort*>::const_iterator it = get_connections ().begin ();
1812                 if (it == get_connections ().end ()) {
1813                         memset (_buffer, 0, n_samples * sizeof (Sample));
1814                 } else {
1815                         DummyAudioPort * source = static_cast<DummyAudioPort*>(*it);
1816                         assert (source && source->is_output ());
1817                         if (source->is_physical() && source->is_terminal()) {
1818                                 source->get_buffer(n_samples); // generate signal.
1819                         }
1820                         memcpy (_buffer, source->const_buffer (), n_samples * sizeof (Sample));
1821                         while (++it != get_connections ().end ()) {
1822                                 source = static_cast<DummyAudioPort*>(*it);
1823                                 assert (source && source->is_output ());
1824                                 Sample* dst = buffer ();
1825                                 if (source->is_physical() && source->is_terminal()) {
1826                                         source->get_buffer(n_samples); // generate signal.
1827                                 }
1828                                 const Sample* src = source->const_buffer ();
1829                                 for (uint32_t s = 0; s < n_samples; ++s, ++dst, ++src) {
1830                                         *dst += *src;
1831                                 }
1832                         }
1833                 }
1834         } else if (is_output () && is_physical () && is_terminal()) {
1835                 if (!_gen_cycle) {
1836                         generate(n_samples);
1837                 }
1838         }
1839         return _buffer;
1840 }
1841
1842
1843 DummyMidiPort::DummyMidiPort (DummyAudioBackend &b, const std::string& name, PortFlags flags)
1844         : DummyPort (b, name, flags)
1845         , _midi_seq_spb (0)
1846         , _midi_seq_time (0)
1847         , _midi_seq_pos (0)
1848 {
1849         _buffer.clear ();
1850         _loopback.clear ();
1851 }
1852
1853 DummyMidiPort::~DummyMidiPort () {
1854         _buffer.clear ();
1855         _loopback.clear ();
1856 }
1857
1858 struct MidiEventSorter {
1859         bool operator() (const boost::shared_ptr<DummyMidiEvent>& a, const boost::shared_ptr<DummyMidiEvent>& b) {
1860                 return *a < *b;
1861         }
1862 };
1863
1864 void DummyMidiPort::set_loopback (DummyMidiBuffer const * const src)
1865 {
1866         _loopback.clear ();
1867         for (DummyMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
1868                 _loopback.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (**it)));
1869         }
1870 }
1871
1872 void DummyMidiPort::setup_generator (int seq_id, const float sr)
1873 {
1874         DummyPort::setup_random_number_generator();
1875         _midi_seq_dat = DummyMidiData::sequences[seq_id % NUM_MIDI_EVENT_GENERATORS];
1876         _midi_seq_spb = sr * .5f; // 120 BPM, beat_time 1.0 per beat.
1877         _midi_seq_pos = 0;
1878         _midi_seq_time = 0;
1879 }
1880
1881 void DummyMidiPort::midi_generate (const pframes_t n_samples)
1882 {
1883         Glib::Threads::Mutex::Lock lm (generator_lock);
1884         if (_gen_cycle) {
1885                 return;
1886         }
1887
1888         _buffer.clear ();
1889         _gen_cycle = true;
1890
1891         if (_midi_seq_spb == 0 || !_midi_seq_dat) {
1892                 for (DummyMidiBuffer::const_iterator it = _loopback.begin (); it != _loopback.end (); ++it) {
1893                         _buffer.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (**it)));
1894                 }
1895                 return;
1896         }
1897
1898         while (1) {
1899                 const int32_t ev_beat_time = _midi_seq_dat[_midi_seq_pos].beat_time * _midi_seq_spb - _midi_seq_time;
1900                 if (ev_beat_time < 0) {
1901                         break;
1902                 }
1903                 if ((pframes_t) ev_beat_time >= n_samples) {
1904                         break;
1905                 }
1906                 _buffer.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (
1907                                                 ev_beat_time,
1908                                                 _midi_seq_dat[_midi_seq_pos].event,
1909                                                 _midi_seq_dat[_midi_seq_pos].size
1910                                                 )));
1911                 ++_midi_seq_pos;
1912
1913                 if (_midi_seq_dat[_midi_seq_pos].event[0] == 0xff && _midi_seq_dat[_midi_seq_pos].event[1] == 0xff) {
1914                         _midi_seq_time -= _midi_seq_dat[_midi_seq_pos].beat_time * _midi_seq_spb;
1915                         _midi_seq_pos = 0;
1916                 }
1917         }
1918         _midi_seq_time += n_samples;
1919 }
1920
1921
1922 void* DummyMidiPort::get_buffer (pframes_t n_samples)
1923 {
1924         if (is_input ()) {
1925                 _buffer.clear ();
1926                 for (std::vector<DummyPort*>::const_iterator i = get_connections ().begin ();
1927                                 i != get_connections ().end ();
1928                                 ++i) {
1929                         DummyMidiPort * source = static_cast<DummyMidiPort*>(*i);
1930                         if (source->is_physical() && source->is_terminal()) {
1931                                 source->get_buffer(n_samples); // generate signal.
1932                         }
1933                         const DummyMidiBuffer *src = source->const_buffer ();
1934                         for (DummyMidiBuffer::const_iterator it = src->begin (); it != src->end (); ++it) {
1935                                 _buffer.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (**it)));
1936                         }
1937                 }
1938                 std::sort (_buffer.begin (), _buffer.end (), MidiEventSorter());
1939         } else if (is_output () && is_physical () && is_terminal()) {
1940                 if (!_gen_cycle) {
1941                         midi_generate(n_samples);
1942                 }
1943         }
1944         return &_buffer;
1945 }
1946
1947 DummyMidiEvent::DummyMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size)
1948         : _size (size)
1949         , _timestamp (timestamp)
1950         , _data (0)
1951 {
1952         if (size > 0) {
1953                 _data = (uint8_t*) malloc (size);
1954                 memcpy (_data, data, size);
1955         }
1956 }
1957
1958 DummyMidiEvent::DummyMidiEvent (const DummyMidiEvent& other)
1959         : _size (other.size ())
1960         , _timestamp (other.timestamp ())
1961         , _data (0)
1962 {
1963         if (other.size () && other.const_data ()) {
1964                 _data = (uint8_t*) malloc (other.size ());
1965                 memcpy (_data, other.const_data (), other.size ());
1966         }
1967 };
1968
1969 DummyMidiEvent::~DummyMidiEvent () {
1970         free (_data);
1971 };