, _systemic_input_latency (0)
, _systemic_output_latency (0)
, _processed_samples (0)
+ , _port_change_flag (false)
{
_instance_name = s_instance_name;
pthread_mutex_init (&_port_callback_mutex, 0);
return -1;
}
+ engine.sample_rate_change (_samplerate);
+ engine.buffer_size_change (_samples_per_period);
+
if (engine.reestablish_ports ()) {
PBD::error << _("DummyAudioBackend: Could not re-establish ports.") << endmsg;
stop ();
return -1;
}
- engine.buffer_size_change (_samples_per_period);
engine.reconnect_ports ();
+ _port_change_flag = false;
if (pthread_create (&_main_thread, NULL, pthread_process, this)) {
PBD::error << _("DummyAudioBackend: cannot start.") << endmsg;
void
DummyAudioBackend::update_latencies ()
{
+ // trigger latency callback in RT thread (locked graph)
+ port_connect_add_remove_callback();
}
/* PORTENGINE API */
snprintf(tmp, sizeof(tmp), "system:playback_%d", i);
PortHandle p = add_port(std::string(tmp), DataType::AUDIO, static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
if (!p) return -1;
- set_latency_range (p, false, lr);
+ set_latency_range (p, true, lr);
}
/* midi ports */
snprintf(tmp, sizeof(tmp), "system:midi_playback_%d", i);
PortHandle p = add_port(std::string(tmp), DataType::MIDI, static_cast<PortFlags>(IsInput | IsPhysical | IsTerminal));
if (!p) return -1;
- set_latency_range (p, false, lr);
+ set_latency_range (p, true, lr);
}
-
return 0;
}
_running = true;
_processed_samples = 0;
+ manager.registration_callback();
+ manager.graph_order_callback();
+
uint64_t clock1, clock2;
clock1 = g_get_monotonic_time();
while (_running) {
}
clock1 = g_get_monotonic_time();
+ bool connections_changed = false;
+ bool ports_changed = false;
if (!pthread_mutex_trylock (&_port_callback_mutex)) {
+ if (_port_change_flag) {
+ ports_changed = true;
+ _port_change_flag = false;
+ }
+ if (!_port_connection_queue.empty ()) {
+ connections_changed = true;
+ }
while (!_port_connection_queue.empty ()) {
PortConnectData *c = _port_connection_queue.back ();
manager.connect_callback (c->a, c->b, c->c);
}
pthread_mutex_unlock (&_port_callback_mutex);
}
+ if (ports_changed) {
+ manager.registration_callback();
+ }
+ if (connections_changed) {
+ manager.graph_order_callback();
+ }
+ if (connections_changed || ports_changed) {
+ engine.latency_callback(false);
+ engine.latency_callback(true);
+ }
}
_running = false;
_capture_latency_range.max = 0;
_playback_latency_range.min = 0;
_playback_latency_range.max = 0;
+ _dummy_backend.port_connect_add_remove_callback();
}
DummyPort::~DummyPort () {
disconnect_all ();
+ _dummy_backend.port_connect_add_remove_callback();
}
DummyMidiPort::~DummyMidiPort () { }
+struct MidiEventSorter {
+ bool operator() (const boost::shared_ptr<DummyMidiEvent>& a, const boost::shared_ptr<DummyMidiEvent>& b) {
+ return *a < *b;
+ }
+};
+
void* DummyMidiPort::get_buffer (pframes_t /* nframes */)
{
if (is_input ()) {
_buffer.push_back (boost::shared_ptr<DummyMidiEvent>(new DummyMidiEvent (**it)));
}
}
- std::sort (_buffer.begin (), _buffer.end ());
+ std::sort (_buffer.begin (), _buffer.end (), MidiEventSorter());
} else if (is_output () && is_physical () && is_terminal()) {
_buffer.clear ();
}