Making MIDI Mappings persistent - Alex
[terminatorX.git] / terminatorX / src / tX_seqpar.cc
index d8efcd33b7203fb250c6452d3ffe25d2fd801aa0..833591155962519ae62151e7cc412bc18ae8f939 100644 (file)
@@ -46,6 +46,7 @@ void tX_seqpar :: default_constructor()
        max_value=0;
        min_value=0;
        scale_value=0;
+       is_boolean=false;
        is_mappable=1;
        all.push_back(this);
        last_event_recorded=NULL;
@@ -105,6 +106,40 @@ void tX_seqpar :: handle_mouse_input(float adjustment)
        receive_input_value(tmpvalue);
 }
 
+#ifdef USE_ALSA_MIDI_IN
+void tX_seqpar :: handle_midi_input( const tX_midievent& event )
+{
+       float tmpvalue = -1000;
+
+       //event.print( (string(__FUNCTION__) + " - " + get_name()).c_str() );
+       
+       if( !is_boolean )
+       {
+               if( event.type == tX_midievent::CC || event.type == tX_midievent::PITCHBEND )
+               {       
+                       tmpvalue = event.value * (max_value-min_value) + min_value;
+               }
+               else if( event.type == tX_midievent::NOTE )
+               {
+                       tmpvalue = event.is_noteon;
+               }
+               else
+               {
+                       return;
+               }
+
+               if (tmpvalue>max_value) tmpvalue=max_value;
+               if (tmpvalue<min_value) tmpvalue=min_value;
+       }
+       else
+       {
+               tmpvalue=event.value;
+       }
+               
+       receive_input_value(tmpvalue);
+}
+#endif
+
 void tX_seqpar :: set_vtt (void *mytt)
 {
        vtt=mytt;
@@ -150,7 +185,7 @@ void tX_seqpar :: create_persistence_ids()
        }
 }
 
-tX_seqpar* tX_seqpar :: get_sp_by_persistence_id(int pid)
+tX_seqpar* tX_seqpar :: get_sp_by_persistence_id(unsigned int pid)
 {
        list <tX_seqpar *> :: iterator sp;
        
@@ -219,6 +254,56 @@ char * tX_seqpar :: get_vtt_name()
         else return "Master Track";
 }
 
+void tX_seqpar :: restore_meta(xmlNodePtr node) {
+       char *buffer;
+       
+       buffer=(char *) xmlGetProp(node, (xmlChar *) "id");
+       if (buffer) { sscanf(buffer, "%i", &persistence_id); }
+       else { tX_error("no ID for seqpar %s", this->get_name()); }
+       
+       buffer=(char *) xmlGetProp(node, (xmlChar *) "midiType");
+       if (buffer) {
+               if (strcmp("cc", buffer)==0) {
+                       bound_midi_event.type=tX_midievent::CC;
+               } else if (strcmp("note", buffer)==0) {
+                       bound_midi_event.type=tX_midievent::NOTE;
+               } else if (strcmp("pitchbend", buffer)==0) {
+                       bound_midi_event.type=tX_midievent::PITCHBEND;
+               } else {
+                       tX_error("unknown midiType \"%s\" for seqpar %s", buffer, this->get_name());
+               }
+               
+               buffer=(char *) xmlGetProp(node, (xmlChar *) "midiChannel");
+               if (buffer) { sscanf(buffer, "%i", &bound_midi_event.channel); }
+               else { tX_error("no midiChannel for seqpar %s", this->get_name()); }
+                       
+               buffer=(char *) xmlGetProp(node, (xmlChar *) "midiNumber");
+               if (buffer) { sscanf(buffer, "%i", &bound_midi_event.number); }
+               else { tX_error("no midiNumber for seqpar %s", this->get_name()); }
+       } 
+       /* else: no MIDI init.... */
+}
+
+void tX_seqpar :: store_meta(FILE *output) {
+       char buffer[256];
+       
+       if (bound_midi_event.type!=tX_midievent::NONE) {
+               char *type;
+               
+               switch (bound_midi_event.type) {
+                       case tX_midievent::NOTE: type="note"; break;
+                       case tX_midievent::CC: type="cc"; break;
+                       case tX_midievent::PITCHBEND: type="pitchbend"; break;
+                       default: type="error";
+               }
+               sprintf(buffer, "id=\"%i\" midiType=\"%s\" midiChannel=\"%i\" midiNumber=\"%i\"", persistence_id, type, bound_midi_event.channel, bound_midi_event.number);
+       } else {
+               sprintf(buffer, "id=\"%i\"", persistence_id);
+       }
+       fprintf(output, buffer);
+}
+
+
 const char * tX_seqpar :: get_name()
 {
         return "This string means trouble!";
@@ -227,6 +312,7 @@ const char * tX_seqpar :: get_name()
 float tX_seqpar :: get_value()
 {
        printf("Ooops. tX_seqpar::get_value() called. Trouble.");
+       return 0.0;     
 }
 
 void tX_seqpar :: do_exec(const float value)
@@ -383,7 +469,7 @@ void tX_seqpar_vtt_speed :: handle_mouse_input(float adjustment)
 
 void tX_seqpar_vtt_speed :: do_exec(const float value)
 {
-       tt->speed=value;
+       tt->speed=value*tt->audiofile_pitch_correction;
 }
 
 const char * tX_seqpar_vtt_speed :: get_name()
@@ -433,6 +519,30 @@ const char * tX_seqpar_vtt_volume :: get_name()
         return "Volume";
 }
 
+/**** Sequencable Parameter : Pan ****/
+
+tX_seqpar_vtt_pan :: tX_seqpar_vtt_pan()
+{
+       set_mapping_parameters(1.0, -1.0, TX_SEQPAR_DEFAULT_SCALE, 1);
+}
+
+float tX_seqpar_vtt_pan :: get_value(){ return tt->pan; }
+
+void tX_seqpar_vtt_pan :: do_exec(const float value)
+{
+       tt->set_pan(value);
+}
+
+void tX_seqpar_vtt_pan :: do_update_graphics ()
+{
+       gtk_adjustment_set_value(tt->gui.pan, tt->pan);
+}
+
+const char * tX_seqpar_vtt_pan :: get_name()
+{
+        return "Pan";
+}
+
 /**** Sequencable Parameter: TURNTABLE PITCH ****/
 
 tX_seqpar_vtt_pitch :: tX_seqpar_vtt_pitch()
@@ -461,7 +571,8 @@ const char * tX_seqpar_vtt_pitch :: get_name()
 
 tX_seqpar_vtt_trigger :: tX_seqpar_vtt_trigger()
 {
-       set_mapping_parameters(0, 0, 0, 0);
+       set_mapping_parameters(0.01, 0, 1, 1);
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_trigger :: do_exec(const float value)
@@ -480,6 +591,8 @@ const char * tX_seqpar_vtt_trigger :: get_name()
 tX_seqpar_vtt_loop :: tX_seqpar_vtt_loop()
 {
        set_mapping_parameters(0, 0, 0, 0);
+       
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_loop :: do_exec(const float value)
@@ -545,7 +658,8 @@ const char * tX_seqpar_vtt_sync_cycles :: get_name()
 
 tX_seqpar_vtt_lp_enable :: tX_seqpar_vtt_lp_enable()
 {
-       set_mapping_parameters(0,0,0,0);
+       set_mapping_parameters(0.01,0,1,1);
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_lp_enable :: do_exec(const float value)
@@ -615,7 +729,7 @@ const char * tX_seqpar_vtt_lp_reso :: get_name()
 
 tX_seqpar_vtt_lp_freq :: tX_seqpar_vtt_lp_freq()
 {
-       set_mapping_parameters(1.0, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
+       set_mapping_parameters(0.99, 0, TX_SEQPAR_DEFAULT_SCALE, 1);
 }
 
 float tX_seqpar_vtt_lp_freq :: get_value() { return tt->lp_freq; }
@@ -639,7 +753,8 @@ void tX_seqpar_vtt_lp_freq :: do_update_graphics ()
 
 tX_seqpar_vtt_ec_enable :: tX_seqpar_vtt_ec_enable()
 {
-       set_mapping_parameters(1.0, 0, 0, 0);
+       set_mapping_parameters(0.01,0,1,1);
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_ec_enable :: do_exec(const float value)
@@ -705,11 +820,61 @@ const char * tX_seqpar_vtt_ec_feedback :: get_name()
         return "Echo: Feedback";
 }
 
+/**** Sequencable Parameter: TURNTABLE ECHO PAN ****/
+
+tX_seqpar_vtt_ec_pan :: tX_seqpar_vtt_ec_pan()
+{
+       set_mapping_parameters(1.0, -1.0, TX_SEQPAR_DEFAULT_SCALE, 1);
+}
+
+float tX_seqpar_vtt_ec_pan :: get_value() { return tt->ec_pan; }
+
+void tX_seqpar_vtt_ec_pan :: do_exec(const float value)
+{
+       tt->ec_set_pan(value);
+}
+
+void tX_seqpar_vtt_ec_pan :: do_update_graphics ()
+{
+       gtk_adjustment_set_value(tt->gui.ec_pan, tt->ec_pan);
+}
+
+const char * tX_seqpar_vtt_ec_pan :: get_name()
+{
+        return "Echo: Pan";
+}
+
+/**** Sequencable Parameter: TURNTABLE ECHO VOLUME ****/
+
+tX_seqpar_vtt_ec_volume :: tX_seqpar_vtt_ec_volume()
+{
+       set_mapping_parameters(0.0, 3.0, TX_SEQPAR_DEFAULT_SCALE, 1);
+}
+
+float tX_seqpar_vtt_ec_volume :: get_value() { return tt->ec_volume; }
+
+void tX_seqpar_vtt_ec_volume :: do_exec(const float value)
+{
+       tt->ec_set_volume(value);
+}
+
+void tX_seqpar_vtt_ec_volume :: do_update_graphics ()
+{
+       gtk_adjustment_set_value(tt->gui.ec_volume, tt->ec_volume);
+}
+
+const char * tX_seqpar_vtt_ec_volume :: get_name()
+{
+        return "Echo: Volume";
+}
+
+
 /**** Sequencable Parameter: TURNTABLE MUTE ****/
 
 tX_seqpar_vtt_mute :: tX_seqpar_vtt_mute()
 {
-       set_mapping_parameters(0,0,0,0);
+       set_mapping_parameters(0.01,0,1,1);
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_mute :: do_exec(const float value)
@@ -787,6 +952,7 @@ void tX_seqpar_vttfx_float :: do_update_graphics()
 GtkSignalFunc tX_seqpar_vttfx_float :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_float *sp)
 {
        sp->receive_gui_value(sp->myadj->value);        
+       return NULL;    
 }
 
 #define WID_DYN TRUE, TRUE, 0
@@ -829,6 +995,7 @@ void tX_seqpar_vttfx_int :: do_update_graphics()
 GtkSignalFunc tX_seqpar_vttfx_int :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_int *sp)
 {
        sp->receive_gui_value(sp->myadj->value);        
+       return NULL;
 }
 
 void tX_seqpar_vttfx_bool :: create_widget()
@@ -852,6 +1019,7 @@ void tX_seqpar_vttfx_bool :: do_exec(const float value)
 GtkSignalFunc tX_seqpar_vttfx_bool :: gtk_callback(GtkWidget* w, tX_seqpar_vttfx_bool *sp)
 {
        sp->receive_gui_value(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sp->widget)));     
+       return NULL;
 }
 
 void tX_seqpar_vttfx_bool :: do_update_graphics()