ALSA fixes, MIDI fixes and some new features, misc fixes and a
[terminatorX.git] / src / tX_midiin.cc
index df977e5ef143d1cfc6d44200aba7c3337fc8e4e8..3cd565dd11c5ffcacf34468b31d23f44d6c25bb5 100644 (file)
@@ -37,6 +37,7 @@
 #ifdef USE_ALSA_MIDI_IN
 #include "tX_global.h"
 #include <iostream>
+#include "tX_engine.h"
 
 using namespace std;
 
@@ -49,8 +50,6 @@ static gboolean midi_callback(GIOChannel *source, GIOCondition condition, gpoint
 
 tX_midiin::tX_midiin()
 {
-       
-       int portid;
        is_open=false;
        sp_to_learn=NULL;
        learn_dialog=NULL;
@@ -110,9 +109,10 @@ int tX_midiin::check_event()
                tX_midievent event;
                event.is_noteon = false;
                bool event_usable = true;
-               
+               printf("type: %i\n", ev->type);
                switch (ev->type) {
                        case SND_SEQ_EVENT_CONTROLLER: 
+                               printf("ctrl: p: %i, v: %i, c: %i\n", ev->data.control.param, ev->data.control.value, ev->data.control.channel);
                                event.type = tX_midievent::CC;
                                event.number = ev->data.control.param;
                                event.value = ev->data.control.value / 127.0;
@@ -131,12 +131,14 @@ int tX_midiin::check_event()
                                event.channel = ev->data.control.channel;
                                break;
                        case SND_SEQ_EVENT_REGPARAM:
+                               printf("rpn: p: %i, v: %i, c: %i\n", ev->data.control.param, ev->data.control.value, ev->data.control.channel);
                                event.type = tX_midievent::RPN;
                                event.number = ev->data.control.param;
                                event.value = ev->data.control.value / 16383.0;
                                event.channel = ev->data.control.channel;
                                break;
                        case SND_SEQ_EVENT_NONREGPARAM:
+                               printf("nrpn: p: %i, v: %i, c: %i\n", ev->data.control.param, ev->data.control.value, ev->data.control.channel);
                                event.type = tX_midievent::NRPN;
                                event.number = ev->data.control.param;
                                event.value = ev->data.control.value / 16383.0;
@@ -436,5 +438,100 @@ gboolean tX_midiin::midi_learn_destroy(GtkWidget *widget, tX_midiin *midi)
        midi->cancel_midi_learn();
 }
 
+void tX_midiin::store_connections(FILE *rc, char *indent) 
+{
+       gzFile *rz;
+       
+       tX_store("%s<midi_connections>\n", indent);
+       strcat(indent, "\t");
+
+       snd_seq_addr_t my_addr;
+       my_addr.client=snd_seq_client_id(ALSASeqHandle);
+       my_addr.port=portid;
+
+       snd_seq_query_subscribe_t *subs;
+       snd_seq_query_subscribe_alloca(&subs);
+       snd_seq_query_subscribe_set_root(subs, &my_addr);
+       snd_seq_query_subscribe_set_type(subs, SND_SEQ_QUERY_SUBS_WRITE);
+       snd_seq_query_subscribe_set_index(subs, 0);
+       
+       while (snd_seq_query_port_subscribers(ALSASeqHandle, subs) >= 0) {
+               const snd_seq_addr_t *addr;
+               addr = snd_seq_query_subscribe_get_addr(subs);
+               
+               tX_store("%s<link client=\"%i\" port=\"%i\"/>\n", indent, addr->client, addr->port);
+               snd_seq_query_subscribe_set_index(subs, snd_seq_query_subscribe_get_index(subs) + 1);
+       }       
+               
+       indent[strlen(indent)-1]=0;
+       tX_store("%s</midi_connections>\n", indent);    
+}
+
+void tX_midiin::restore_connections(xmlNodePtr node)
+{
+       snd_seq_addr_t my_addr;
+       my_addr.client=snd_seq_client_id(ALSASeqHandle);
+       my_addr.port=portid;
+       
+       if (xmlStrcmp(node->name, (xmlChar *) "midi_connections")==0) {
+               for (xmlNodePtr cur=node->xmlChildrenNode; cur != NULL; cur = cur->next) {
+                       if (cur->type == XML_ELEMENT_NODE) {
+                               if (xmlStrcmp(cur->name, (xmlChar *) "link")==0) {
+                                       char *buffer;
+                                       int client=-1;
+                                       int port=-1;
+                                       
+                                       buffer=(char *) xmlGetProp(cur, (xmlChar *) "client");
+                                       if (buffer) {
+                                               sscanf(buffer, "%i", &client);
+                                       }
+                                       
+                                       buffer=(char *) xmlGetProp(cur, (xmlChar *) "port");
+                                       if (buffer) {
+                                               sscanf(buffer, "%i", &port);
+                                       }
+                                       
+                                       if ((port>=0) && (client>=0)) {
+                                               snd_seq_addr_t sender_addr;
+                                               sender_addr.client=client;
+                                               sender_addr.port=port;
+                                               
+                                               snd_seq_port_subscribe_t *subs;
+                                               snd_seq_port_subscribe_alloca(&subs);
+                                               snd_seq_port_subscribe_set_sender(subs, &sender_addr);
+                                               snd_seq_port_subscribe_set_dest(subs, &my_addr);
+
+                                               if (snd_seq_subscribe_port(ALSASeqHandle, subs) < 0) {
+                                                       tX_error("tX_midiin::restore_connections() -> failed to connect to: %d:%d.", port, client);
+                                               }
+                                       } else {
+                                               tX_error("tX_midiin::restore_connections() -> invalid port: %d:%d.", port, client);
+                                       }
+                                       
+                               } else {
+                                       tX_error("tX_midiin::restore_connections() -> invalid element: %s.", cur->name);
+                               }
+                       }
+               }
+       } else {
+               tX_error("tX_midiin::restore_connections() -> invalid XML element.");
+       }
+}
+
+
+extern "C" {
+       void tX_midiin_store_connections(FILE *rc, char *indent);
+       void tX_midiin_restore_connections(xmlNodePtr node);
+};
+
+void tX_midiin_store_connections(FILE *rc, char *indent) 
+{
+       tX_engine::get_instance()->get_midi()->store_connections(rc, indent);
+}
+
+void tX_midiin_restore_connections(xmlNodePtr node) 
+{
+       tX_engine::get_instance()->get_midi()->restore_connections(node);
+}
 
 #endif // USE_ALSA_MIDI_IN