Last minute stuff - Alex
authorterminatorX <>
Thu, 21 Aug 2003 22:41:50 +0000 (22:41 +0000)
committerterminatorX <>
Thu, 21 Aug 2003 22:41:50 +0000 (22:41 +0000)
ChangeLog
doc/terminatorX-manual/C/terminatorX-manual.xml
src/main.cc
src/tX_engine.cc
src/tX_global.c
src/tX_global.h
src/tX_loaddlg.cc
src/tX_mastergui.cc
src/tX_midiin.cc
src/tX_midiin.h

index 9540a4898614210956bfea8fafe85c1dc9d654ef..a16bf70752fee05a847eaee46b6e4ece655be4bf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,11 @@ This is not a GNU-style ChangeLog but you sort of get the idea what was
 changed.
 
 [v3.81]
+- removed the disfunctional "Cancel" button from the load-progress dialog.
+- switched default MIDI mapping to non-destructive. (previous settings will not
+  be overwritten now).
+- added a default MIDI mapping accessible via the "Turntables" menu. The actual
+  mapping is documented in the manual.
 - fixed a bug that caused enabling sync-client setting via MIDI to fail.
 - when compiled with rt-scheduling suppport terminatorX will now display the 
   resulting scheduling policy in the "About" dialog.
index 52ae70c1747681175af201d462ce65101d2bcb07..1d68d72bed1971c70f8273fdd446a48441fd3ca1 100644 (file)
@@ -4,7 +4,7 @@
 <!ENTITY legal SYSTEM "legal.xml">
 
 ]>
-<article lang="en" id="index">
+<article id="index" lang="en">
   <articleinfo>
     <title>terminatorX - Manual</title>
 
@@ -97,7 +97,7 @@
 
       <para>Try the following steps:</para>
 
-      <orderedlist continuation="restarts" inheritnum="ignore">
+      <orderedlist inheritnum="ignore" continuation="restarts">
         <listitem>
           <para>If you don&#39;t have <application moreinfo="none">LADSPA</application>
           (Linux Audio Developer&#39;s Simple Plugin API) installed, go and
             <para>Adds a new turntable to the current set of turntables.</para>
           </listitem>
 
+          <listitem>
+            <para><emphasis>Assign Default MIDI Mappnigs</emphasis></para>
+
+            <para>Will assign the Default MIDI Mappings (see <xref
+            linkend="MIDI" />) to all standard parameters. Existing
+           mappings will not be overridden.
+           </para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis>Auto Assign Default MIDI Mappings</emphasis></para>
+
+            <para>When this option is enabled will always re-apply the Default
+            MIDI Mappings (see <xref linkend="MIDI" />) whenever you load a
+            set, add a new turntable or create a new set. Existing 
+           mappings will not be overridden.</para>
+          </listitem>
+
+          <listitem>
+            <para><emphasis>Clear MIDI Mappings</emphasis></para>
+
+            <para>Removes all currently assigned MIDI mappings.</para>
+          </listitem>
+
           <listitem>
             <para><emphasis>Record Audio to Disk</emphasis></para>
 
       parameter and click the <emphasis>Remove Binding</emphasis> button to
       get rid of the parameter&#39;s MIDI mapping.</para>
 
+      <para>TeriminatorX now features a default MIDI mapping that can be
+      enabled via the <emphasis>Turntables Menu</emphasis> (see <xref
+      linkend="TURNTABLESMENU" />). The controllers are mapped in a one
+      channel per turntable fashion:</para>
+
+      <table>
+        <title>Default MIDI Controller Mapping</title>
+
+        <tgroup cols="2">
+          <thead>
+            <row>
+              <entry>Turntable Parameter</entry>
+
+              <entry>MIDI Controller</entry>
+
+              <entry>MIDI CC Name</entry>
+            </row>
+          </thead>
+
+          <tbody>
+            <row>
+              <entry>Volume</entry>
+
+              <entry>7</entry>
+
+              <entry><quote>Main Volume</quote></entry>
+            </row>
+
+            <row>
+              <entry>Pan</entry>
+
+              <entry>10</entry>
+
+              <entry><quote>Pan</quote></entry>
+            </row>
+
+            <row>
+              <entry>Lowpass Cutoff Frequency</entry>
+
+              <entry>12</entry>
+
+              <entry><quote>Effect Control 1</quote></entry>
+            </row>
+
+            <row>
+              <entry>Lowpass Resonance</entry>
+
+              <entry>13</entry>
+
+              <entry><quote>Effect Control 2</quote></entry>
+            </row>
+
+            <row>
+              <entry>Lowpass Gain</entry>
+
+              <entry>16</entry>
+
+              <entry><quote>General Purpose Controller 1</quote></entry>
+            </row>
+
+            <row>
+              <entry>Speed</entry>
+
+              <entry>17</entry>
+
+              <entry><quote>General Purpose Controller 2</quote></entry>
+            </row>
+
+            <row>
+              <entry>Pitch</entry>
+
+              <entry>18</entry>
+
+              <entry><quote>General Purpose Controller 3</quote></entry>
+            </row>
+
+            <row>
+              <entry>Sync Cycles</entry>
+
+              <entry>19</entry>
+
+              <entry><quote>General Purpose Controller 4</quote></entry>
+            </row>
+
+            <row>
+              <entry>Echo Length</entry>
+
+              <entry>75</entry>
+
+              <entry><quote>Sound Controller 6</quote></entry>
+            </row>
+
+            <row>
+              <entry>Echo Feedback</entry>
+
+              <entry>76</entry>
+
+              <entry><quote>Sound Controller 7</quote></entry>
+            </row>
+
+            <row>
+              <entry>Echo Volume</entry>
+
+              <entry>77</entry>
+
+              <entry><quote>Sound Controller 8</quote></entry>
+            </row>
+
+            <row>
+              <entry>Echo Pan</entry>
+
+              <entry>78</entry>
+
+              <entry><quote>Sound Controller 9</quote></entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+
+      <para>The toggle parameters of a turntable (where things can only be
+      turned on or off) are mapped to MIDI NOTE events, where the first
+      turntable is mapped to &#39;C&#39;, the next to &#39;C#&#39;, the next
+      to &#39;D&#39; and so on. The &#34;function&#34; of the toggle is
+      defined via the selected MIDI channel:</para>
+
+      <table>
+        <title>Default MIDI Note On/Off Mapping</title>
+
+        <tgroup cols="2">
+          <thead>
+            <row>
+              <entry>Turntable Parameter</entry>
+
+              <entry>MIDI Channel</entry>
+            </row>
+          </thead>
+
+          <tbody>
+            <row>
+              <entry>Trigger</entry>
+
+              <entry>0</entry>
+            </row>
+
+            <row>
+              <entry>Sync Client</entry>
+
+              <entry>1</entry>
+            </row>
+
+            <row>
+              <entry>Loop</entry>
+
+              <entry>2</entry>
+            </row>
+
+            <row>
+              <entry>Lowpass Enable</entry>
+
+              <entry>3</entry>
+            </row>
+
+            <row>
+              <entry>Echo Enable</entry>
+
+              <entry>4</entry>
+            </row>
+
+            <row>
+              <entry>Mute</entry>
+
+              <entry>5</entry>
+            </row>
+
+            <row>
+              <entry>Motor Spin On/Off</entry>
+
+              <entry>6</entry>
+            </row>
+          </tbody>
+        </tgroup>
+      </table>
+
       <para>If you want to use your joystick to control terminatorX - I wrote
       a tiny tool to create MIDI events from joystick motion called
       <emphasis>aseqjoy</emphasis>. It&#39;s available from the <ulink
     <para>Send me comments, bug-reports, patches or scratches (see scratches
     section on the terminatorX homepage) at: <email>alex@lisas.de</email></para>
   </sect1>
-</article>
\ No newline at end of file
+</article>
index 609819f2a31baae1855378184c9985e0ba377243..4afcb912cfc52efa2c98bf8db1ab6dd59c358525 100644 (file)
@@ -247,7 +247,7 @@ int main(int argc, char **argv)
 #endif 
 
 #ifdef USE_SCHEDULER
-       tX_debug("main() GUI thread is p:%i, t:%i and has policy %i.", getpid(), pthread_self(), sched_getscheduler(getpid()));
+       tX_debug("main() GUI thread is p:%i, t:%i and has policy %i.", getpid(), (int) pthread_self(), sched_getscheduler(getpid()));
 #endif 
        
        create_mastergui(globals.width, globals.height);
@@ -271,6 +271,10 @@ int main(int argc, char **argv)
                tX_cursor::set_cursor(tX_cursor::WAIT_CURSOR);
                load_tt_part(globals.startup_set);
                tX_cursor::reset_cursor();
+       } else {
+#ifdef USE_ALSA_MIDI_IN
+               if (globals.auto_assign_midi) tX_midiin::auto_assign_midi_mappings(NULL, NULL);
+#endif         
        }
 
 #ifndef CREATE_BENCHMARK
index b839a841a8c2bd9e08ed583f68c198065ee559fa..9eaa89d2aec3f369d5e2bf139608c30b2c732ed8 100644 (file)
@@ -143,7 +143,7 @@ void *engine_thread_entry(void *engine_void) {
                
 #ifndef ALLOW_SUID_ROOT
                tX_error("This binary doesn't support running suid-root.");
-               tX_error("Reconfigure with --enable-suidroot if you really want that.");
+               tX_error("Reconfigure with --enable-capabilities or --enable-suidroot if you really want that.");
                exit(-1);
 #endif         
                tX_debug("engine_thread_entry() - Running suid root - dropping privileges.");
@@ -190,7 +190,7 @@ void *engine_thread_entry(void *engine_void) {
 #endif 
 
 #ifdef USE_SCHEDULER
-       tX_debug("engine_thread_entry() engine thread is p: %i, t: %i and has policy %i.", getpid(), pthread_self(), sched_getscheduler(getpid()));
+       tX_debug("engine_thread_entry() engine thread is p: %i, t: %i and has policy %i.", getpid(), (int) pthread_self(), sched_getscheduler(getpid()));
 #endif
        
        engine->loop();
@@ -209,7 +209,14 @@ tX_engine :: tX_engine() {
        
        /* Creating the actual engine thread.. */
 #ifdef USE_SCHEDULER   
-       if (!geteuid() && globals.use_realtime) {
+       if (!geteuid() /* && globals.use_realtime */) {
+
+#ifndef ALLOW_SUID_ROOT
+               tX_error("This binary doesn't support running suid-root.");
+               tX_error("Reconfigure with --enable-capabilities or --enable-suidroot if you really want that.");
+               exit(-1);
+#endif         
+               
                pthread_attr_t pattr;
                struct sched_param sparm;
                
@@ -229,6 +236,8 @@ tX_engine :: tX_engine() {
                result=pthread_create(&thread, &pattr, engine_thread_entry, (void *) this);
        } else {
 #endif // USE_SCHEDULER
+               //tX_debug("tX_engine() - can't set SCHED_FIFO euid: %i.", geteuid());
+               
                result=pthread_create(&thread, NULL, engine_thread_entry, (void *) this);
 #ifdef USE_SCHEDULER           
        }
index 575d02e872bef8b4d965f5f4fb9e766c9f1cda57..28113f4bc1f0ef6419643af803f8593624ecb7ce 100644 (file)
@@ -153,6 +153,7 @@ void set_global_defaults() {
        globals.vu_meter_border_intensity=0.7;
        globals.quit_confirm=1;
        globals.use_realtime=1;
+       globals.auto_assign_midi=0;
 }
 
 int load_globals_xml() {
@@ -251,6 +252,7 @@ int load_globals_xml() {
 
                        restore_int("quit_confirm", globals.quit_confirm);
                        restore_int("use_realtime", globals.use_realtime);
+                       restore_int("auto_assign_midi", globals.auto_assign_midi);
 
 #ifdef USE_ALSA_MIDI_IN
                        if (!elementFound && (xmlStrcmp(cur->name, (xmlChar *) "midi_connections")==0)) {
@@ -367,7 +369,8 @@ void store_globals() {
 
                store_int("quit_confirm", globals.quit_confirm);
                store_int("use_realtime", globals.use_realtime);
-               
+               store_int("auto_assign_midi", globals.auto_assign_midi);
+
 #ifdef USE_ALSA_MIDI_IN
                tX_midiin_store_connections(rc, indent);
 #endif         
index f6aec1bbefde1b0b260f9a9525e0004d02cd9574..121ca609c0af66d5a185591c34e143e34faa0024 100644 (file)
@@ -163,6 +163,7 @@ typedef struct {
        
        int quit_confirm;
        int use_realtime;
+       int auto_assign_midi;
 } tx_global;
 
 extern tx_global globals;
index 4d6c2aaba530b7c75daa86d5c9cae3a55ea2ebdd..36f68a41dca3f30d8be216e51f96e5185b7a9cba 100644 (file)
@@ -34,7 +34,7 @@ GtkWidget *ld_single_l=(GtkWidget *)NULL;
 GtkWidget *ld_single_p=(GtkWidget *)NULL;
 GtkWidget *ld_multi_l=(GtkWidget *)NULL;
 GtkWidget *ld_multi_p=(GtkWidget *)NULL;
-GtkWindow *ld_window=(GtkWindow *)NULL;
+//GtkWindow *ld_window=(GtkWindow *)NULL;
 
 int ld_mode;
 int ld_count;
@@ -55,7 +55,7 @@ gfloat ld_old_prog;
 
 int ld_create_loaddlg(int mode, int count)
 {
-       GtkWidget *vbox;
+       GtkWidget *vbox=gtk_vbox_new(0, 5);
        GtkWidget *actionarea;
        GtkWidget *dummy;
        
@@ -64,18 +64,18 @@ int ld_create_loaddlg(int mode, int count)
        ld_mode=mode;
        ld_count=count;
 
-       ld_loaddlg=gtk_dialog_new_with_buttons("terminatorX - loading",
-               GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_NONE, NULL);
-       ld_window=&(GTK_DIALOG(ld_loaddlg)->window);
+       ld_loaddlg=gtk_window_new(GTK_WINDOW_POPUP);
+       gtk_window_set_position(GTK_WINDOW(ld_loaddlg), GTK_WIN_POS_CENTER_ON_PARENT);
+       gtk_window_set_title(GTK_WINDOW(ld_loaddlg), "terminatorX - loading");
+       gtk_window_set_transient_for(GTK_WINDOW(ld_loaddlg), GTK_WINDOW(main_window));
        
-       gtk_container_set_border_width(GTK_CONTAINER(ld_window), 5);
-       
-       vbox=GTK_WIDGET(GTK_DIALOG(ld_loaddlg)->vbox);
-       gtk_box_set_spacing(GTK_BOX(vbox), 5);
-
-       actionarea=GTK_WIDGET(GTK_DIALOG(ld_loaddlg)->action_area);
-       gtk_box_set_spacing(GTK_BOX(actionarea), 5);
+       gtk_container_set_border_width(GTK_CONTAINER(ld_loaddlg), 5);
+       gtk_container_add(GTK_CONTAINER(ld_loaddlg), vbox);
+       gtk_widget_set_size_request(vbox, 400, -1);
+       gtk_widget_show(vbox);
        
+       //gtk_widget_show(ld_loaddlg);
+               
        if (mode==TX_LOADDLG_MODE_MULTI) {
                ld_multi_l=gtk_label_new("Loading Set");
                gtk_misc_set_alignment(GTK_MISC(ld_multi_l), 0.5, 0.5);
@@ -96,10 +96,10 @@ int ld_create_loaddlg(int mode, int count)
        ld_single_p=gtk_progress_bar_new();
        add_widget_fix(ld_single_p);
 
-       gtk_window_set_modal(ld_window, TRUE);
-       gtk_window_set_default_size(ld_window, 400, 100);
+       gtk_window_set_modal(GTK_WINDOW(ld_loaddlg), TRUE);
+       //gtk_window_set_default_size(GTK_WINDOW(ld_loaddlg), 400, 100);
        gtk_widget_realize(ld_loaddlg);
-       gdk_window_set_decorations(gtk_widget_get_parent_window(vbox),(GdkWMDecoration) 0);
+       gdk_window_set_decorations(ld_loaddlg->window, (GdkWMDecoration) 0);
        gtk_widget_show(ld_loaddlg);
        gdk_window_set_cursor(ld_loaddlg->window, tX_cursor::get_cursor());
 
index a4c076413d5edd009a2c59024c3d5d74b2ed132a..38959018972d811f55945ce18ac6d140cac70ddf 100644 (file)
@@ -46,6 +46,7 @@
 #include "tX_glade_support.h"
 #include <sys/time.h>
 #include <sys/wait.h>
+#include "tX_midiin.h"
 
 #ifdef USE_SCHEDULER
 #include <sys/resource.h>
@@ -241,28 +242,11 @@ GtkSignalFunc new_table(GtkWidget *, char *fn)
        
        if (fn) ld_destroy();           
        mg_update_status();
-       return NULL;
-}
-
-GtkSignalFunc drop_new_table(GtkWidget *widget, GdkDragContext *context,
-               gint x, gint y, GtkSelectionData *selection_data,
-               guint info, guint time, vtt_class *vtt)
-{
-       char filename[PATH_MAX];
-       char *fn;
        
-       strncpy(filename, (char *) selection_data->data, (size_t) selection_data->length);
-       filename[selection_data->length]=0;
-
-       fn = strchr (filename, '\r');
-       *fn=0;  
-       
-       fn = strchr (filename, ':');
-       if (fn) fn++; else fn=(char *) selection_data->data;
+#ifdef USE_ALSA_MIDI_IN
+       if (globals.auto_assign_midi) tX_midiin::auto_assign_midi_mappings(NULL, NULL);
+#endif
        
-       new_table(NULL, fn);
-
-       strcpy (filename, "dont segfault workaround ;)");
        return NULL;
 }
 
@@ -284,6 +268,10 @@ GtkSignalFunc new_tables() {
        vtt_class::delete_all();
        new_table(NULL, NULL);
 
+#ifdef USE_ALSA_MIDI_IN
+       if (globals.auto_assign_midi) tX_midiin::auto_assign_midi_mappings(NULL, NULL);
+#endif
+       
        gtk_window_set_title(GTK_WINDOW(main_window), "terminatorX");
 
        return NULL;
@@ -368,6 +356,9 @@ void load_tt_part(char * buffer)
        gtk_adjustment_set_value(volume_adj, globals.volume);
        gtk_adjustment_set_value(pitch_adj, globals.pitch);
        sprintf(wbuf,"terminatorX - %s", strip_path(buffer));
+#ifdef USE_ALSA_MIDI_IN
+       if (globals.auto_assign_midi) tX_midiin::auto_assign_midi_mappings(NULL, NULL);
+#endif 
        gtk_window_set_title(GTK_WINDOW(main_window), wbuf);            
 }
 
@@ -977,8 +968,30 @@ GCallback create_table_sequencer_menu(GtkWidget *widget, void *param)
 
 GCallback toggle_confirm_events(GtkWidget *widget, void *dummy)
 {      
-       globals.confirm_events=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
-       
+       globals.confirm_events=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));     
+       return NULL;    
+}
+
+GCallback toggle_auto_assign(GtkWidget *widget, void *dummy)
+{      
+       globals.auto_assign_midi=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+#ifdef USE_ALSA_MIDI_IN
+       tX_midiin::auto_assign_midi_mappings(NULL, NULL);
+#endif
+/*     if (globals.auto_assign_midi) {
+               GtkWidget *dialog=gtk_message_dialog_new(GTK_WINDOW(main_window), 
+               GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO,
+               "Note: Enabling \"Auto Assign Default MIDI Settings\" will constantly overwrite the\
+MIDI mappings for the standard parameters. \
+Are you sure you really want this?");
+               
+               int res=gtk_dialog_run(GTK_DIALOG(dialog));
+               gtk_widget_destroy(dialog);
+                       
+               if (res!=GTK_RESPONSE_YES) {
+                       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), 0);
+               }                       
+       } */
        return NULL;    
 }
 
@@ -1041,6 +1054,48 @@ void create_master_menu()
        gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_A, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);    
        g_signal_connect(menu_item, "activate", (GCallback) new_table, NULL);
 
+       menu_item = gtk_menu_item_new ();
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       gtk_widget_set_sensitive (menu_item, FALSE);
+
+       menu_item = gtk_menu_item_new_with_mnemonic("Assign _Default MIDI Mappings");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_M, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+
+#ifdef USE_ALSA_MIDI_IN
+       g_signal_connect(menu_item, "activate", G_CALLBACK(tX_midiin::auto_assign_midi_mappings), (void *) true);
+#else
+       gtk_widget_set_sensitive(menu_item, FALSE);
+#endif
+
+       menu_item = gtk_check_menu_item_new_with_mnemonic("A_uto Assign Default MIDI Mappings");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), globals.auto_assign_midi);
+#ifdef USE_ALSA_MIDI_IN        
+       g_signal_connect(menu_item, "activate", (GCallback) toggle_auto_assign, NULL);
+#else
+       gtk_widget_set_sensitive(menu_item, FALSE);
+#endif
+
+       menu_item = gtk_menu_item_new_with_mnemonic("_Clear MIDI Mappings");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_C, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+
+#ifdef USE_ALSA_MIDI_IN
+       g_signal_connect(menu_item, "activate", G_CALLBACK(tX_midiin::clear_midi_mappings), (void *) true);
+#else
+       gtk_widget_set_sensitive(menu_item, FALSE);
+#endif
+
+       menu_item = gtk_menu_item_new ();
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       gtk_widget_set_sensitive (menu_item, FALSE);
+
        menu_item = gtk_check_menu_item_new_with_mnemonic("_Record Audio To Disk");
        rec_menu_item = menu_item;
        gtk_widget_show (menu_item);
index ada068e7d6e1cf1ef38622a8eea533466dfad8b7..fdb37a09b18982a970fefe3ee1d980b4997dfe15 100644 (file)
@@ -27,6 +27,9 @@
        - Adding destroy handler for the GUI
        - moving printf to tX_* macros
        - removing some debug code
+       for 3.81
+       - re-connect to MIDI devices
+       - auto MIDI mappings
 */    
 
 #include "tX_midiin.h"
@@ -34,6 +37,7 @@
 #include "tX_glade_interface.h"
 #include "tX_glade_support.h"
 #include "tX_dialog.h"
+#include "tX_mastergui.h"
 
 #ifdef USE_ALSA_MIDI_IN
 #include "tX_global.h"
@@ -521,7 +525,6 @@ void tX_midiin::restore_connections(xmlNodePtr node)
        }
 }
 
-
 extern "C" {
        void tX_midiin_store_connections(FILE *rc, char *indent);
        void tX_midiin_restore_connections(xmlNodePtr node);
@@ -537,4 +540,101 @@ void tX_midiin_restore_connections(xmlNodePtr node)
        tX_engine::get_instance()->get_midi()->restore_connections(node);
 }
 
+static inline void cc_map(tX_seqpar *sp, int channel, int number) {
+       if (sp->bound_midi_event.type==tX_midievent::NONE) {
+               sp->bound_midi_event.type=tX_midievent::CC;
+               sp->bound_midi_event.channel=channel;
+               sp->bound_midi_event.number=number;
+               sp->reset_upper_midi_bound();
+               sp->reset_lower_midi_bound();
+       }
+}
+
+static inline void cc_note(tX_seqpar *sp, int channel, int number) {
+       if (sp->bound_midi_event.type==tX_midievent::NONE) {
+               sp->bound_midi_event.type=tX_midievent::NOTE;
+               sp->bound_midi_event.channel=channel;
+               sp->bound_midi_event.number=number;
+               sp->reset_upper_midi_bound();
+               sp->reset_lower_midi_bound();
+       }
+}
+
+void tX_midiin::auto_assign_midi_mappings(GtkWidget *widget, gpointer dummy)
+{
+       std::list<vtt_class *>::iterator vtt;
+       int ctr=0;
+       
+/*     if (dummy) {
+               GtkWidget *dialog=gtk_message_dialog_new(GTK_WINDOW(main_window), 
+               GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO,
+               "Assigning the default mappings will overwrite existing MIDI mappings. OK, to overwrite existing MIDI mappings?");
+               
+               int res=gtk_dialog_run(GTK_DIALOG(dialog));
+               gtk_widget_destroy(dialog);
+                       
+               if (res!=GTK_RESPONSE_YES) {
+                       return;
+               }               
+       } */
+       
+       /* Works on my hardware :) */
+       cc_map(&sp_master_volume, 0, 28);
+       cc_map(&sp_master_volume, 0, 29);       
+       
+       for (vtt=vtt_class::main_list.begin(); (vtt!=vtt_class::main_list.end()) && (ctr<16); vtt++, ctr++) {
+               /* These are pretty standard... */
+               cc_map((&(*vtt)->sp_volume),            ctr, 07);
+               cc_map((&(*vtt)->sp_pan),                       ctr, 10);
+               cc_map((&(*vtt)->sp_lp_freq),           ctr, 13);
+               cc_map((&(*vtt)->sp_lp_reso),           ctr, 12);
+               
+               /* These are on "general purpose"... */
+               cc_map((&(*vtt)->sp_lp_gain),           ctr, 16);
+               cc_map((&(*vtt)->sp_speed),             ctr, 17);
+               cc_map((&(*vtt)->sp_pitch),             ctr, 18);
+               cc_map((&(*vtt)->sp_sync_cycles),       ctr, 19);
+               
+               /* Sound Controller 6-10 */
+               cc_map((&(*vtt)->sp_ec_length),         ctr, 75);
+               cc_map((&(*vtt)->sp_ec_feedback),       ctr, 76);
+               cc_map((&(*vtt)->sp_ec_volume),         ctr, 77);
+               cc_map((&(*vtt)->sp_ec_pan),            ctr, 78);
+               
+               /* The toggles mapped to notes... */
+               cc_note((&(*vtt)->sp_trigger),          0, 60+ctr);
+               cc_note((&(*vtt)->sp_sync_client),      1, 60+ctr);
+               cc_note((&(*vtt)->sp_loop),             2, 60+ctr);
+               cc_note((&(*vtt)->sp_lp_enable),        3, 60+ctr);
+               cc_note((&(*vtt)->sp_ec_enable),        4, 60+ctr);
+               cc_note((&(*vtt)->sp_mute),             5, 60+ctr);
+               cc_note((&(*vtt)->sp_spin),             6, 60+ctr);
+       }
+}
+
+void tX_midiin::clear_midi_mappings(GtkWidget *widget, gpointer dummy)
+{
+       std::list<tX_seqpar *>::iterator sp;
+       
+       if (dummy) {
+               GtkWidget *dialog=gtk_message_dialog_new(GTK_WINDOW(main_window), 
+               GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO,
+               "Really clear all current MIDI mappings?");
+               
+               int res=gtk_dialog_run(GTK_DIALOG(dialog));
+               gtk_widget_destroy(dialog);
+                       
+               if (res!=GTK_RESPONSE_YES) {
+                       return;
+               }               
+       }
+       
+       for (sp=tX_seqpar::all.begin(); sp!=tX_seqpar::all.end(); sp++) {
+               (*sp)->bound_midi_event.type=tX_midievent::NONE;
+               (*sp)->bound_midi_event.channel=0;
+               (*sp)->bound_midi_event.number=0;
+               (*sp)->reset_upper_midi_bound();
+               (*sp)->reset_lower_midi_bound();
+       }
+}
 #endif // USE_ALSA_MIDI_IN
index 71013be90b087323a2c84bf991425920bcac8ff7..f8d87f218151d9cf74fb517b8fab014a5d5b72f2 100644 (file)
@@ -108,6 +108,8 @@ class tX_midiin
        
        static gboolean midi_learn_cancel(GtkWidget *, tX_midiin *);
        static gboolean midi_learn_destroy(GtkWidget *, tX_midiin *);   
+       static void auto_assign_midi_mappings(GtkWidget *, gpointer);
+       static void clear_midi_mappings(GtkWidget *, gpointer);
        
   private: