From d82dcd232f201b531a0be165ee44aede1bc8a1df Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 19 Sep 2006 18:11:19 +0000 Subject: Alsa MIDI fixes. git-svn-id: http://svn.drobilla.net/lad/ingen@144 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/client/SigClientInterface.h | 63 +++++++++++++++++++++++++++++++ src/libs/client/Store.cpp | 72 ++++++++++++++++++------------------ src/libs/client/Store.h | 17 +++++---- src/libs/engine/AlsaMidiDriver.cpp | 7 ++-- src/libs/engine/AlsaMidiDriver.h | 6 ++- src/libs/engine/Engine.cpp | 2 +- 6 files changed, 118 insertions(+), 49 deletions(-) (limited to 'src/libs') diff --git a/src/libs/client/SigClientInterface.h b/src/libs/client/SigClientInterface.h index 1f24ad40..4639bdc7 100644 --- a/src/libs/client/SigClientInterface.h +++ b/src/libs/client/SigClientInterface.h @@ -63,6 +63,69 @@ public: sigc::signal program_add_sig; sigc::signal program_remove_sig; +protected: + + // ClientInterface hooks that fire the above signals + + void bundle_begin() {} + void bundle_end() {} + + void transfer_begin() {} + void transfer_end() {} + + void num_plugins(uint32_t num) { num_plugins_sig.emit(num); } + + void response(int32_t id, bool success, string msg) + { response_sig.emit(id, success, msg); } + + void error(string msg) + { error_sig.emit(msg); } + + void new_plugin(string uri, string name) + { new_plugin_sig.emit(uri, name); } + + void new_patch(string path, uint32_t poly) + { new_patch_sig.emit(path, poly); } + + void new_node(string plugin_uri, string node_path, bool is_polyphonic, uint32_t num_ports) + { new_node_sig.emit(plugin_uri, node_path, is_polyphonic, num_ports); } + + void new_port(string path, string data_type, bool is_output) + { new_port_sig.emit(path, data_type, is_output); } + + void connection(string src_port_path, string dst_port_path) + { connection_sig.emit(src_port_path, dst_port_path); } + + void object_destroyed(string path) + { object_destroyed_sig.emit(path); } + + void patch_enabled(string path) + { patch_enabled_sig.emit(path); } + + void patch_disabled(string path) + { patch_disabled_sig.emit(path); } + + void patch_cleared(string path) + { patch_cleared_sig.emit(path); } + + void object_renamed(string old_path, string new_path) + { object_renamed_sig.emit(old_path, new_path); } + + void disconnection(string src_port_path, string dst_port_path) + { disconnection_sig.emit(src_port_path, dst_port_path); } + + void metadata_update(string path, string key, Atom value) + { metadata_update_sig.emit(path, key, value); } + + void control_change(string port_path, float value) + { control_change_sig.emit(port_path, value); } + + void program_add(string path, uint32_t bank, uint32_t program, string name) + { program_add_sig.emit(path, bank, program, name); } + + void program_remove(string path, uint32_t bank, uint32_t program) + { program_remove_sig.emit(path, bank, program); } + protected: SigClientInterface() {} }; diff --git a/src/libs/client/Store.cpp b/src/libs/client/Store.cpp index 3b7e9768..f9b3f17a 100644 --- a/src/libs/client/Store.cpp +++ b/src/libs/client/Store.cpp @@ -50,8 +50,8 @@ Store::Store(CountedPtr engine, CountedPtr void Store::clear() { - m_objects.clear(); - m_plugins.clear(); + _objects.clear(); + _plugins.clear(); } @@ -63,16 +63,16 @@ Store::add_plugin_orphan(CountedPtr node) << node->plugin_uri() << " unknown." << endl; map > >::iterator spawn - = m_plugin_orphans.find(node->plugin_uri()); + = _plugin_orphans.find(node->plugin_uri()); _engine->request_plugin(node->plugin_uri()); - if (spawn != m_plugin_orphans.end()) { + if (spawn != _plugin_orphans.end()) { spawn->second.push_back(node); } else { list > l; l.push_back(node); - m_plugin_orphans[node->plugin_uri()] = l; + _plugin_orphans[node->plugin_uri()] = l; } } @@ -81,13 +81,13 @@ void Store::resolve_plugin_orphans(CountedPtr plugin) { map > >::iterator n - = m_plugin_orphans.find(plugin->uri()); + = _plugin_orphans.find(plugin->uri()); - if (n != m_plugin_orphans.end()) { + if (n != _plugin_orphans.end()) { list > spawn = n->second; // take a copy - m_plugin_orphans.erase(plugin->uri()); // prevent infinite recursion + _plugin_orphans.erase(plugin->uri()); // prevent infinite recursion for (list >::iterator i = spawn.begin(); i != spawn.end(); ++i) { @@ -103,7 +103,7 @@ Store::add_connection_orphan(CountedPtr connection) cerr << "WARNING: Orphan connection " << connection->src_port_path() << " -> " << connection->dst_port_path() << " received." << endl; - m_connection_orphans.push_back(connection); + _connection_orphans.push_back(connection); } @@ -112,8 +112,8 @@ Store::resolve_connection_orphans(CountedPtr port) { assert(port->parent()); - for (list >::iterator c = m_connection_orphans.begin(); - c != m_connection_orphans.end(); ) { + for (list >::iterator c = _connection_orphans.begin(); + c != _connection_orphans.end(); ) { if ((*c)->src_port_path() == port->path()) (*c)->set_src_port(port); @@ -130,7 +130,7 @@ Store::resolve_connection_orphans(CountedPtr port) cerr << "Resolved orphan connection " << (*c)->src_port_path() << (*c)->dst_port_path() << endl; patch->add_connection(*c); - m_connection_orphans.erase(c); + _connection_orphans.erase(c); } } @@ -145,16 +145,16 @@ Store::add_orphan(CountedPtr child) cerr << "WARNING: Orphan object " << child->path() << " received." << endl; map > >::iterator children - = m_orphans.find(child->path().parent()); + = _orphans.find(child->path().parent()); _engine->request_object(child->path().parent()); - if (children != m_orphans.end()) { + if (children != _orphans.end()) { children->second.push_back(child); } else { list > l; l.push_back(child); - m_orphans[child->path().parent()] = l; + _orphans[child->path().parent()] = l; } } @@ -163,16 +163,16 @@ void Store::add_metadata_orphan(const Path& subject_path, const string& predicate, const Atom& value) { map > >::iterator orphans - = m_metadata_orphans.find(subject_path); + = _metadata_orphans.find(subject_path); _engine->request_object(subject_path); - if (orphans != m_metadata_orphans.end()) { + if (orphans != _metadata_orphans.end()) { orphans->second.push_back(std::pair(predicate, value)); } else { list > l; l.push_back(std::pair(predicate, value)); - m_metadata_orphans[subject_path] = l; + _metadata_orphans[subject_path] = l; } } @@ -181,13 +181,13 @@ void Store::resolve_metadata_orphans(CountedPtr subject) { map > >::iterator v - = m_metadata_orphans.find(subject->path()); + = _metadata_orphans.find(subject->path()); - if (v != m_metadata_orphans.end()) { + if (v != _metadata_orphans.end()) { list > values = v->second; // take a copy - m_metadata_orphans.erase(subject->path()); + _metadata_orphans.erase(subject->path()); for (list >::iterator i = values.begin(); i != values.end(); ++i) { @@ -201,13 +201,13 @@ void Store::resolve_orphans(CountedPtr parent) { map > >::iterator c - = m_orphans.find(parent->path()); + = _orphans.find(parent->path()); - if (c != m_orphans.end()) { + if (c != _orphans.end()) { list > children = c->second; // take a copy - m_orphans.erase(parent->path()); // prevent infinite recursion + _orphans.erase(parent->path()); // prevent infinite recursion for (list >::iterator i = children.begin(); i != children.end(); ++i) { @@ -222,8 +222,8 @@ Store::add_object(CountedPtr object) { // If we already have "this" object, merge the existing one into the new // one (with precedence to the new values). - ObjectMap::iterator existing = m_objects.find(object->path()); - if (existing != m_objects.end()) { + ObjectMap::iterator existing = _objects.find(object->path()); + if (existing != _objects.end()) { existing->second->set(object); } else { @@ -235,7 +235,7 @@ Store::add_object(CountedPtr object) parent->add_child(object); assert(parent && (object->parent() == parent)); - m_objects[object->path()] = object; + _objects[object->path()] = object; new_object_sig.emit(object); resolve_metadata_orphans(parent); @@ -249,7 +249,7 @@ Store::add_object(CountedPtr object) add_orphan(object); } } else { - m_objects[object->path()] = object; + _objects[object->path()] = object; new_object_sig.emit(object); } @@ -262,12 +262,12 @@ Store::add_object(CountedPtr object) CountedPtr Store::remove_object(const Path& path) { - map >::iterator i = m_objects.find(path); + map >::iterator i = _objects.find(path); - if (i != m_objects.end()) { + if (i != _objects.end()) { assert((*i).second->path() == path); CountedPtr result = (*i).second; - m_objects.erase(i); + _objects.erase(i); //cout << "[Store] Removed " << path << endl; if (result) @@ -297,8 +297,8 @@ CountedPtr Store::plugin(const string& uri) { assert(uri.length() > 0); - map >::iterator i = m_plugins.find(uri); - if (i == m_plugins.end()) + map >::iterator i = _plugins.find(uri); + if (i == _plugins.end()) return CountedPtr(); else return (*i).second; @@ -309,8 +309,8 @@ CountedPtr Store::object(const Path& path) { assert(path.length() > 0); - map >::iterator i = m_objects.find(path); - if (i == m_objects.end()) { + map >::iterator i = _objects.find(path); + if (i == _objects.end()) { return CountedPtr(); } else { assert(i->second->path() == "/" || i->second->parent()); @@ -323,7 +323,7 @@ Store::add_plugin(CountedPtr pm) { // FIXME: dupes? merge, like with objects? - m_plugins[pm->uri()] = pm; + _plugins[pm->uri()] = pm; } diff --git a/src/libs/client/Store.h b/src/libs/client/Store.h index a2083ba2..6a8700f9 100644 --- a/src/libs/client/Store.h +++ b/src/libs/client/Store.h @@ -54,9 +54,10 @@ public: void clear(); - size_t num_objects() { return m_objects.size(); } + size_t num_object() { return _objects.size(); } - const map >& plugins() const { return m_plugins; } + const map >& plugins() const { return _plugins; } + const map >& objects() const { return _objects; } sigc::signal > new_object_sig; private: @@ -98,23 +99,23 @@ private: CountedPtr _emitter; typedef map > ObjectMap; - ObjectMap m_objects; ///< Keyed by Ingen path + ObjectMap _objects; ///< Keyed by Ingen path - map > m_plugins; ///< Keyed by URI + map > _plugins; ///< Keyed by URI /** Objects we've received, but depend on the existance of another unknown object. * Keyed by the path of the depended-on object (for tolerance of orderless comms) */ - map > > m_orphans; + map > > _orphans; /** Same idea, except with plugins instead of parents. * It's unfortunate everything doesn't just have a URI and this was the same.. ahem.. */ - map > > m_plugin_orphans; + map > > _plugin_orphans; /** Not orphans OF metadata like the above, but orphans which are metadata */ - map > > m_metadata_orphans; + map > > _metadata_orphans; /** Ditto */ - list > m_connection_orphans; + list > _connection_orphans; }; diff --git a/src/libs/engine/AlsaMidiDriver.cpp b/src/libs/engine/AlsaMidiDriver.cpp index 78d032be..3f6b060d 100644 --- a/src/libs/engine/AlsaMidiDriver.cpp +++ b/src/libs/engine/AlsaMidiDriver.cpp @@ -118,7 +118,7 @@ void AlsaMidiPort::event(snd_seq_event_t* const ev) { // Abuse the tick field to hold the timestamp - ev->time.tick = _driver->clock()->time_stamp(); + ev->time.tick = _driver->audio_driver()->frame_time(); // Fix noteons with velocity 0 (required for DSSI spec) if (ev->type == SND_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0) @@ -187,8 +187,9 @@ AlsaMidiPort::prepare_block(const SampleCount block_start, const SampleCount blo bool AlsaMidiDriver::_midi_thread_exit_flag = true; -AlsaMidiDriver::AlsaMidiDriver() -: _seq_handle(NULL), +AlsaMidiDriver::AlsaMidiDriver(AudioDriver* audio_driver) +: _audio_driver(audio_driver), + _seq_handle(NULL), _event_coder(NULL), _is_activated(false) { diff --git a/src/libs/engine/AlsaMidiDriver.h b/src/libs/engine/AlsaMidiDriver.h index ad40ed17..bc5e6203 100644 --- a/src/libs/engine/AlsaMidiDriver.h +++ b/src/libs/engine/AlsaMidiDriver.h @@ -27,6 +27,7 @@ namespace Ingen { class Node; class SetPortValueEvent; class AlsaMidiDriver; +class AudioDriver; template class DuplexPort; static const int MAX_MIDI_EVENT_SIZE = 3; @@ -76,7 +77,7 @@ private: class AlsaMidiDriver : public MidiDriver { public: - AlsaMidiDriver(); + AlsaMidiDriver(AudioDriver* audio_driver); ~AlsaMidiDriver(); void activate(); @@ -86,6 +87,8 @@ public: void prepare_block(const SampleCount block_start, const SampleCount block_end); + AudioDriver* audio_driver() { return _audio_driver; } + DriverPort* create_port(DuplexPort* patch_port) { return new AlsaMidiPort(this, patch_port); } @@ -113,6 +116,7 @@ private: // MIDI thread static void* process_midi_in(void* me); + AudioDriver* _audio_driver; snd_seq_t* _seq_handle; snd_midi_event_t* _event_coder; pthread_t _process_thread; diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp index 94f964dc..5d064d49 100644 --- a/src/libs/engine/Engine.cpp +++ b/src/libs/engine/Engine.cpp @@ -54,7 +54,7 @@ Engine::Engine(AudioDriver* audio_driver) #ifdef HAVE_JACK_MIDI m_midi_driver(new JackMidiDriver(((JackAudioDriver*)m_audio_driver)->jack_client())), #elif HAVE_ALSA_MIDI - m_midi_driver(new AlsaMidiDriver()), + m_midi_driver(new AlsaMidiDriver(m_audio_driver)), #else m_midi_driver(new DummyMidiDriver()), #endif -- cgit v1.2.1