Implementing MIDI Learn - Alex
authorterminatorX <>
Fri, 20 Jun 2003 13:25:24 +0000 (13:25 +0000)
committerterminatorX <>
Fri, 20 Jun 2003 13:25:24 +0000 (13:25 +0000)
src/tX_audiodevice.cc
src/tX_glade_interface.cc
src/tX_midiin.cc
src/tX_midiin.h
src/tX_seqpar.cc
terminatorX.glade

index 66c293cef38ce29d7a275d458ae8150f829a52ae..5aaafa2bc9941c6a8a0c6fe002a401df00db00ff 100644 (file)
@@ -211,7 +211,7 @@ int tX_audiodevice_alsa :: open()
        sscanf(globals.alsa_device, "%i-%i: %s", &card, &device, foo);
        sprintf(pcm_name, "hw:%i,%i", card, device);
        
-       if (snd_pcm_open(&pcm_handle, pcm_name, stream, NULL) < 0) {
+       if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) < 0) {
                tX_error("ALSA: Failed to access PCM device \"%s\"", pcm_name);
                return -1;
        }
index a3b60b4f1289f2a3c73d8a11e68c059bdf945981..8d49e40d6931f8af77c78bb721015c52a924a5c1 100644 (file)
@@ -997,7 +997,7 @@ create_tX_midilearn (void)
   GtkWidget *vbox4;
   GtkWidget *midilabel;
   GtkWidget *dialog_action_area5;
-  GtkWidget *button1;
+  GtkWidget *cancel;
 
   tX_midilearn = gtk_dialog_new ();
   gtk_window_set_title (GTK_WINDOW (tX_midilearn), "MIDI Learn");
@@ -1019,10 +1019,10 @@ create_tX_midilearn (void)
   gtk_widget_show (dialog_action_area5);
   gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area5), GTK_BUTTONBOX_END);
 
-  button1 = gtk_button_new_from_stock ("gtk-cancel");
-  gtk_widget_show (button1);
-  gtk_dialog_add_action_widget (GTK_DIALOG (tX_midilearn), button1, GTK_RESPONSE_CANCEL);
-  GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
+  cancel = gtk_button_new_from_stock ("gtk-cancel");
+  gtk_widget_show (cancel);
+  gtk_dialog_add_action_widget (GTK_DIALOG (tX_midilearn), cancel, GTK_RESPONSE_CANCEL);
+  GTK_WIDGET_SET_FLAGS (cancel, GTK_CAN_DEFAULT);
 
   /* Store pointers to all widgets, for use by lookup_widget(). */
   GLADE_HOOKUP_OBJECT_NO_REF (tX_midilearn, tX_midilearn, "tX_midilearn");
@@ -1030,7 +1030,7 @@ create_tX_midilearn (void)
   GLADE_HOOKUP_OBJECT (tX_midilearn, vbox4, "vbox4");
   GLADE_HOOKUP_OBJECT (tX_midilearn, midilabel, "midilabel");
   GLADE_HOOKUP_OBJECT_NO_REF (tX_midilearn, dialog_action_area5, "dialog_action_area5");
-  GLADE_HOOKUP_OBJECT (tX_midilearn, button1, "button1");
+  GLADE_HOOKUP_OBJECT (tX_midilearn, cancel, "cancel");
 
   return tX_midilearn;
 }
index 7dfe3d4930dc12818df2705057268400cf86e8d6..7087cd17da4eb3ecf2e22b328c78cf75ab712885 100644 (file)
@@ -31,6 +31,8 @@
 
 #include "tX_midiin.h"
 #include "tX_vtt.h"
+#include "tX_glade_interface.h"
+#include "tX_glade_support.h"
 
 #ifdef USE_ALSA_MIDI_IN
 #include "tX_global.h"
@@ -50,6 +52,8 @@ tX_midiin::tX_midiin()
        
        int portid;
        is_open=false;
+       sp_to_learn=NULL;
+       learn_dialog=NULL;
        
        if (snd_seq_open(&ALSASeqHandle, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
                tX_error("tX_midiin(): failed to open the default sequencer device.");
@@ -144,24 +148,32 @@ int tX_midiin::check_event()
 
                snd_seq_free_event(ev);
                
-               if( event_usable )
-               {
-                       if (event.channel<0 || event.channel>15)
-                       {
+               if( event_usable ) {
+                       if (event.channel<0 || event.channel>15) {
                                tX_error("tX_midiin::check_event(): invaild event channel %i.", event.channel);
                                return -1;
                        }
 
-                       // This should be solved with a hash table. Possibly.
-                       
-                       list <tX_seqpar *> :: iterator sp;                      
-                       
-                       for (sp=tX_seqpar::all.begin(); sp!=tX_seqpar::all.end(); sp++) {
-                               if ( (*sp)->bound_midi_event.type_matches (event) ) {
-                                       (*sp)->handle_midi_input (event);
+                       if (sp_to_learn) {
+                               sp_to_learn->bound_midi_event=event;
+                               sp_to_learn=NULL;
+                               
+                               if (learn_dialog) {
+                                       gtk_widget_destroy(learn_dialog);
+                                       learn_dialog=NULL;
+                               }
+                       } else {
+                               // This should be solved with a hash table. Possibly.
+                               
+                               list <tX_seqpar *> :: iterator sp;                      
+                               
+                               for (sp=tX_seqpar::all.begin(); sp!=tX_seqpar::all.end(); sp++) {
+                                       if ( (*sp)->bound_midi_event.type_matches (event) ) {
+                                               (*sp)->handle_midi_input (event);
+                                       }
                                }
                        }
-
+                       
                        last_event = event;
                }
 
@@ -366,4 +378,45 @@ tX_midiin::midi_binding_gui::~midi_binding_gui ()
        gtk_timeout_remove( timer_tag );
 }
 
+void tX_midiin::set_midi_learn_sp(tX_seqpar *sp)
+{
+       char buffer[512];
+       
+       if (learn_dialog) {
+               gtk_widget_destroy(learn_dialog);
+       }
+       
+       sp_to_learn=sp;
+       
+       if (!sp_to_learn) return;
+       
+       learn_dialog=create_tX_midilearn();
+       GtkWidget *label=lookup_widget(learn_dialog, "midilabel");
+       
+       sprintf(buffer, "Learning MIDI mapping for <b>%s</b>\nfor turntable <b>%s</b>.\n\nWaiting for MIDI event...", sp->get_name(), sp->get_vtt_name());
+       gtk_label_set_markup(GTK_LABEL(label), buffer);
+       gtk_widget_show(learn_dialog);
+       
+       g_signal_connect(G_OBJECT(lookup_widget(learn_dialog, "cancel")), "clicked", G_CALLBACK (tX_midiin::midi_learn_cancel), this);
+       g_signal_connect(G_OBJECT(learn_dialog), "destroy", G_CALLBACK (tX_midiin::midi_learn_destroy), this);
+}
+
+void tX_midiin::cancel_midi_learn()
+{
+       sp_to_learn=NULL;
+       learn_dialog=NULL;
+}
+
+gboolean tX_midiin::midi_learn_cancel(GtkWidget *widget, tX_midiin *midi)
+{
+       midi->sp_to_learn=NULL;
+       gtk_widget_destroy(midi->learn_dialog);
+}
+
+gboolean tX_midiin::midi_learn_destroy(GtkWidget *widget, tX_midiin *midi)
+{
+       midi->cancel_midi_learn();
+}
+
+
 #endif // USE_ALSA_MIDI_IN
index dd16693b7254351314e22860fab0fca15b0367c5..42ed1bb6fdbb0941009637c2e0a6b5cd96a4700e 100644 (file)
@@ -31,6 +31,7 @@
 #include <stdio.h>
 
 class vtt_class;
+class tX_seqpar;
 
 class tX_midievent
 {
@@ -73,6 +74,8 @@ class tX_midiin
        snd_seq_t *ALSASeqHandle;
        tX_midievent last_event;
        bool is_open;
+       tX_seqpar *sp_to_learn;
+       GtkWidget *learn_dialog;
        
   public:
        tX_midiin();
@@ -91,6 +94,12 @@ class tX_midiin
                return last_event;
        }
 
+       void set_midi_learn_sp(tX_seqpar *);
+       void cancel_midi_learn();
+       
+       static gboolean midi_learn_cancel(GtkWidget *, tX_midiin *);
+       static gboolean midi_learn_destroy(GtkWidget *, tX_midiin *);   
+       
   private:
 
        class midi_binding_gui
index 5ee87501c358aceba1700492e31db8d53388ac18..c22eb0874482d0c9c621dbb705edee57f0f23759 100644 (file)
@@ -28,6 +28,7 @@
 #include "tX_global.h"
 #include "tX_sequencer.h"
 #include "tX_extdial.h"
+#include "tX_engine.h"
 #include <malloc.h>
 
 #define TX_SEQPAR_DEFAULT_SCALE 0.05
@@ -1020,7 +1021,7 @@ gboolean tX_seqpar::tX_seqpar_press(GtkWidget *widget, GdkEventButton *event, gp
                gtk_menu_append(menu, item);
                gtk_widget_show(item);          
 
-               if (sp->bound_midi_event.type!=tX_midievent::NONE) {
+               if (sp->bound_midi_event.type==tX_midievent::NONE) {
                        gtk_widget_set_sensitive(item, FALSE);
                }
                g_signal_connect(item, "activate", (GCallback) tX_seqpar::remove_midi_binding, sp);             
@@ -1059,7 +1060,7 @@ gboolean tX_seqpar::remove_midi_binding(GtkWidget *widget, gpointer data) {
 gboolean tX_seqpar::learn_midi_binding(GtkWidget *widget, gpointer data) {
        tX_seqpar *sp=(tX_seqpar *) data;
 
-       /* THIS NEEDS CODE. */
+       tX_engine::get_instance()->get_midi()->set_midi_learn_sp(sp);
        
        return TRUE;
 }
index 4bc5a3c183369713631d2c670504460477762a00..73b4792ba3e39a786bb5692a64e533f4b5ab186c 100644 (file)
          <property name="layout_style">GTK_BUTTONBOX_END</property>
 
          <child>
-           <widget class="GtkButton" id="button1">
+           <widget class="GtkButton" id="cancel">
              <property name="visible">True</property>
              <property name="can_default">True</property>
              <property name="can_focus">True</property>