diff --git a/Makefile b/Makefile index 5cb97c1..797ad95 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ $(BIN): $(OBJ) $(CXX) $^ -o $@ $(LDLIBS) clean: - rm -f $(DEP) $(OBJ) $(BIN) + rm -f $(DEP) $(OBJ) $(BIN) *~ -include $(SRC:.cpp=.d) diff --git a/amp.cpp b/amp.cpp index 353e3ea..3810a7b 100644 --- a/amp.cpp +++ b/amp.cpp @@ -82,98 +82,3 @@ AmpCC::dispatch( int cc, int value ) { } } -int -AmpCC::cc69( int value ) { - return continuous_control( 0x01, 0x01, 0x0c, value ); -} - -int -AmpCC::cc70( int value ) { - return continuous_control( 0x00, 0x00, 0x0c, value ); -} - -int -AmpCC::cc71( int value ) { - return continuous_control( 0x04, 0x04, 0x0c, value ); -} - -int -AmpCC::cc72( int value ) { - return continuous_control( 0x05, 0x05, 0x0c, value ); -} - -int -AmpCC::cc73( int value ) { - return continuous_control( 0x06, 0x06, 0x0c, value ); -} - -int -AmpCC::cc74( int value ) { - if ( value > 2 ) return 0; - return discrete_control( 0x13, 0x13, 0x8f, value ); -} - -int -AmpCC::cc75( int value ) { - return continuous_control( 0x0a, 0x0a, 0x0d, value ); -} - -int -AmpCC::cc76( int value ) { - if ( value > 4 ) return 0; - return discrete_control( 0x0f, 0x0f, 0x90, value ); -} - -int -AmpCC::cc77( int value ) { - if ( value < 1 || value > 12 ) return 0; - return discrete_control( 0x11, 0x11, 0x8e, value ); -} - - - -int -AmpCC1::cc78( int value ) { - return continuous_control( 0x07, 0x07, 0x0c, value ); -} - -int -AmpCC1::cc79( int value ) { - return continuous_control( 0x02, 0x02, 0x0c, value ); -} - - - -int -AmpCC2::cc78( int value ) { - return continuous_control( 0x02, 0x02, 0x0c, value ); -} - -int -AmpCC2::cc79( int value ) { - return continuous_control( 0x03, 0x03, 0x0c, value ); -} - - - -int -AmpCC3::cc78( int value ) { - return continuous_control( 0x07, 0x07, 0x0c, value ); -} - -int -AmpCC3::cc79( int value ) { - return continuous_control( 0x03, 0x03, 0x0c, value ); -} - - - -int -AmpCC4::cc78( int value ) { - return continuous_control( 0x07, 0x07, 0x0c, value ); -} - -int -AmpCC4::cc79( int value ) { - return continuous_control( 0x03, 0x03, 0x0c, value ); -} diff --git a/amp.h b/amp.h index f064541..cc61406 100644 --- a/amp.h +++ b/amp.h @@ -28,23 +28,32 @@ public: private: // Gain - virtual int cc69( int value ); + virtual int cc69( int value ) { return continuous_control( 0x01, 0x01, 0x0c, value );} // Ch. Volume - virtual int cc70( int value ); + virtual int cc70( int value ) { return continuous_control( 0x00, 0x00, 0x0c, value );} // Treble - virtual int cc71( int value ); + virtual int cc71( int value ) { return continuous_control( 0x04, 0x04, 0x0c, value );} // Mid - virtual int cc72( int value ); + virtual int cc72( int value ) { return continuous_control( 0x05, 0x05, 0x0c, value );} // Bass - virtual int cc73( int value ); + virtual int cc73( int value ) { return continuous_control( 0x06, 0x06, 0x0c, value );} // Sag - virtual int cc74( int value ); + virtual int cc74( int value ) { + if ( value > 2 ) return 0; + else return discrete_control( 0x13, 0x13, 0x8f, value ); + } // Bias - virtual int cc75( int value ); + virtual int cc75( int value ) { return continuous_control( 0x0a, 0x0a, 0x0d, value );} // Noise Gate - virtual int cc76( int value ); + virtual int cc76( int value ) { + if ( value > 4 ) return 0; + else return discrete_control( 0x0f, 0x0f, 0x90, value ); + } // Cabinet - virtual int cc77( int value ); + virtual int cc77( int value ) { + if ( value < 1 || value > 12 ) return 0; + else return discrete_control( 0x11, 0x11, 0x8e, value ); + } // Dummy in base class virtual int cc78( int value ) { return 0;} @@ -60,9 +69,9 @@ public: AmpCC1( Mustang * theAmp ) : AmpCC(theAmp) {} private: // Presence - virtual int cc78( int value ); + virtual int cc78( int value ) { return continuous_control( 0x07, 0x07, 0x0c, value );} // Blend - virtual int cc79( int value ); + virtual int cc79( int value ) { return continuous_control( 0x02, 0x02, 0x0c, value );} }; @@ -73,9 +82,9 @@ public: AmpCC2( Mustang * theAmp ) : AmpCC(theAmp) {} private: // Gain2 - virtual int cc78( int value ); + virtual int cc78( int value ) { return continuous_control( 0x02, 0x02, 0x0c, value );} // Master Volume - virtual int cc79( int value ); + virtual int cc79( int value ) { return continuous_control( 0x03, 0x03, 0x0c, value );} }; @@ -86,9 +95,9 @@ public: AmpCC3( Mustang * theAmp ) : AmpCC(theAmp) {} private: // Cut - virtual int cc78( int value ); + virtual int cc78( int value ) { return continuous_control( 0x07, 0x07, 0x0c, value );} // Master Volume - virtual int cc79( int value ); + virtual int cc79( int value ) { return continuous_control( 0x03, 0x03, 0x0c, value );} }; @@ -101,9 +110,9 @@ public: AmpCC4( Mustang * theAmp ) : AmpCC(theAmp) {} private: // Presence - virtual int cc78( int value ); + virtual int cc78( int value ) { return continuous_control( 0x07, 0x07, 0x0c, value );} // Master Volume - virtual int cc79( int value ); + virtual int cc79( int value ) { return continuous_control( 0x03, 0x03, 0x0c, value );} }; @@ -117,4 +126,24 @@ private: virtual int cc79( int value ) { return 0;} }; + +// Null Amp +// +class NullAmpCC : public AmpCC { +public: + NullAmpCC( Mustang * theAmp ) : AmpCC(theAmp) {} +private: + virtual int cc69( int value ) { return 0;} + virtual int cc70( int value ) { return 0;} + virtual int cc71( int value ) { return 0;} + virtual int cc72( int value ) { return 0;} + virtual int cc73( int value ) { return 0;} + virtual int cc74( int value ) { return 0;} + virtual int cc75( int value ) { return 0;} + virtual int cc76( int value ) { return 0;} + virtual int cc77( int value ) { return 0;} + virtual int cc78( int value ) { return 0;} + virtual int cc79( int value ) { return 0;} +}; + #endif diff --git a/amp_defaults.h b/amp_defaults.h index ee1e995..1e6a53f 100644 --- a/amp_defaults.h +++ b/amp_defaults.h @@ -2,6 +2,13 @@ // // This header is auto-generated from decoded pcap capture. +static unsigned char amp_none[] = { + 0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + static unsigned char f57_deluxe[] = { 0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/delay.cpp b/delay.cpp index 224cb90..d1469ad 100644 --- a/delay.cpp +++ b/delay.cpp @@ -63,167 +63,3 @@ DelayCC::dispatch( int cc, int value ) { } } -int -DelayCC::cc49( int value ) { - return continuous_control( 0x00, 0x00, 0x01, value ); -} - -int -DelayCC::cc50( int value ) { - return continuous_control( 0x01, 0x01, 0x06, value ); -} - - - -int -MonoDelayCC::cc51( int value ) { - return continuous_control( 0x02, 0x02, 0x01, value ); -} - -int -MonoDelayCC::cc52( int value ) { - return continuous_control( 0x03, 0x03, 0x01, value ); -} - -int -MonoDelayCC::cc53( int value ) { - return continuous_control( 0x04, 0x04, 0x01, value ); -} - - - -int -EchoFilterCC::cc51( int value ) { - return continuous_control( 0x02, 0x02, 0x01, value ); -} - -int -EchoFilterCC::cc52( int value ) { - return continuous_control( 0x03, 0x03, 0x01, value ); -} - -int -EchoFilterCC::cc53( int value ) { - return continuous_control( 0x04, 0x04, 0x01, value ); -} - -int -EchoFilterCC::cc54( int value ) { - return continuous_control( 0x05, 0x05, 0x01, value ); -} - - - -int -MultitapDelayCC::cc51( int value ) { - return continuous_control( 0x02, 0x02, 0x01, value ); -} - -int -MultitapDelayCC::cc52( int value ) { - return continuous_control( 0x03, 0x03, 0x01, value ); -} - -int -MultitapDelayCC::cc53( int value ) { - if ( value > 3 ) return 0; - return discrete_control( 0x04, 0x04, 0x8b, value ); -} - - - -int -PingPongDelayCC::cc51( int value ) { - return continuous_control( 0x02, 0x02, 0x01, value ); -} - -int -PingPongDelayCC::cc52( int value ) { - return continuous_control( 0x03, 0x03, 0x01, value ); -} - -int -PingPongDelayCC::cc53( int value ) { - return continuous_control( 0x04, 0x04, 0x01, value ); -} - - - -int -DuckingDelayCC::cc51( int value ) { - return continuous_control( 0x02, 0x02, 0x01, value ); -} - -int -DuckingDelayCC::cc52( int value ) { - return continuous_control( 0x03, 0x03, 0x01, value ); -} - -int -DuckingDelayCC::cc53( int value ) { - return continuous_control( 0x04, 0x04, 0x01, value ); -} - - - -int -ReverseDelayCC::cc51( int value ) { - return continuous_control( 0x02, 0x02, 0x01, value ); -} - -int -ReverseDelayCC::cc52( int value ) { - return continuous_control( 0x03, 0x03, 0x01, value ); -} - -int -ReverseDelayCC::cc53( int value ) { - return continuous_control( 0x04, 0x04, 0x01, value ); -} - - - -int -TapeDelayCC::cc51( int value ) { - return continuous_control( 0x02, 0x02, 0x01, value ); -} - -int -TapeDelayCC::cc52( int value ) { - return continuous_control( 0x03, 0x03, 0x01, value ); -} - -int -TapeDelayCC::cc53( int value ) { - return continuous_control( 0x04, 0x04, 0x01, value ); -} - -int -TapeDelayCC::cc54( int value ) { - return continuous_control( 0x05, 0x05, 0x01, value ); -} - - - -int -StereoTapeDelayCC::cc51( int value ) { - return continuous_control( 0x02, 0x02, 0x01, value ); -} - -int -StereoTapeDelayCC::cc52( int value ) { - return continuous_control( 0x03, 0x03, 0x01, value ); -} - -int -StereoTapeDelayCC::cc53( int value ) { - return continuous_control( 0x04, 0x05, 0x01, value ); -} - -int -StereoTapeDelayCC::cc54( int value ) { - return continuous_control( 0x05, 0x04, 0x01, value ); -} - - - diff --git a/delay.h b/delay.h index ae89d51..9e8f6fc 100644 --- a/delay.h +++ b/delay.h @@ -20,14 +20,14 @@ public: private: // Level - virtual int cc49( int value ); + virtual int cc49( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} // Delay Time - virtual int cc50( int value ); + virtual int cc50( int value ) { return continuous_control( 0x01, 0x01, 0x06, value );} - virtual int cc51( int value ) { return 0;} - virtual int cc52( int value ) { return 0;} - virtual int cc53( int value ) { return 0;} - virtual int cc54( int value ) { return 0;} + virtual int cc51( int value ) = 0; + virtual int cc52( int value ) = 0; + virtual int cc53( int value ) = 0; + virtual int cc54( int value ) = 0; }; @@ -36,11 +36,13 @@ public: MonoDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {} private: // Feedback - virtual int cc51( int value ); + virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} // Brightness - virtual int cc52( int value ); + virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} // Attenuation - virtual int cc53( int value ); + virtual int cc53( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} + // no-op + virtual int cc54( int value ) { return 0;} }; @@ -49,13 +51,13 @@ public: EchoFilterCC( Mustang * theAmp ) : DelayCC(theAmp) {} private: // Feedback - virtual int cc51( int value ); + virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} // Frequency - virtual int cc52( int value ); + virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} // Resonance - virtual int cc53( int value ); + virtual int cc53( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} // Input Level - virtual int cc54( int value ); + virtual int cc54( int value ) { return continuous_control( 0x05, 0x05, 0x01, value );} }; @@ -64,11 +66,16 @@ public: MultitapDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {} private: // Feedback - virtual int cc51( int value ); + virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} // Brightness - virtual int cc52( int value ); + virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} // Mode - virtual int cc53( int value ); + virtual int cc53( int value ) { + if ( value > 3 ) return 0; + else return discrete_control( 0x04, 0x04, 0x8b, value ); + } + // no-op + virtual int cc54( int value ) { return 0;} }; @@ -77,11 +84,13 @@ public: PingPongDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {} private: // Feedback - virtual int cc51( int value ); + virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} // Brightness - virtual int cc52( int value ); + virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} // Stereo - virtual int cc53( int value ); + virtual int cc53( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} + // no-op + virtual int cc54( int value ) { return 0;} }; @@ -90,11 +99,13 @@ public: DuckingDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {} private: // Feedback - virtual int cc51( int value ); + virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} // Release - virtual int cc52( int value ); + virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} // Threshold - virtual int cc53( int value ); + virtual int cc53( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} + // no-op + virtual int cc54( int value ) { return 0;} }; @@ -103,11 +114,13 @@ public: ReverseDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {} private: // FFdbk - virtual int cc51( int value ); + virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} // RFdbk - virtual int cc52( int value ); + virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} // Tone - virtual int cc53( int value ); + virtual int cc53( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} + // no-op + virtual int cc54( int value ) { return 0;} }; @@ -116,13 +129,13 @@ public: TapeDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {} private: // Feedback - virtual int cc51( int value ); + virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} // Flutter - virtual int cc52( int value ); + virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} // Brightness - virtual int cc53( int value ); + virtual int cc53( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} // Stereo - virtual int cc54( int value ); + virtual int cc54( int value ) { return continuous_control( 0x05, 0x05, 0x01, value );} }; @@ -131,13 +144,26 @@ public: StereoTapeDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {} private: // Feedback - virtual int cc51( int value ); + virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} // Flutter - virtual int cc52( int value ); + virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} // Separation - virtual int cc53( int value ); + virtual int cc53( int value ) { return continuous_control( 0x04, 0x05, 0x01, value );} // Brightness - virtual int cc54( int value ); + virtual int cc54( int value ) { return continuous_control( 0x05, 0x04, 0x01, value );} +}; + + +class NullDelayCC : public DelayCC { +public: + NullDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {} +private: + virtual int cc49( int value ) { return 0;} + virtual int cc50( int value ) { return 0;} + virtual int cc51( int value ) { return 0;} + virtual int cc52( int value ) { return 0;} + virtual int cc53( int value ) { return 0;} + virtual int cc54( int value ) { return 0;} }; diff --git a/delay_defaults.h b/delay_defaults.h index 9351a67..d9800a2 100644 --- a/delay_defaults.h +++ b/delay_defaults.h @@ -2,6 +2,13 @@ // // This header is auto-generated from decoded pcap capture. +static unsigned char delay_none[] = { + 0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + static unsigned char mono_delay[] = { 0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/doc/fender_mustang_protocol.txt b/doc/fender_mustang_protocol.txt index aea8b60..9b0b340 100644 --- a/doc/fender_mustang_protocol.txt +++ b/doc/fender_mustang_protocol.txt @@ -147,7 +147,7 @@ Data format for setting an effect is: +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 00 | 1c| 03|DSP| 00 | 01| 01| 00 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ -16 |fxm| 00|slt| ??| ??| ??| 00 | +16 |fxm| 00|slt| ??| ??| ??|en | 00 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 32 |kb1|kb2|kb3|kb4|kb5|kb6| 00 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ @@ -160,6 +160,7 @@ slt - slot; before amp have numbers from 0 to 3, after from 4 to 7 kb1, kb2, kb3, kb4, kb5, kb6 - knobs values; not every time all are used; maximum value of the knob depends on the effect ?? - some strange numbers specific for each effect +en - Effect state (1 = off, 0 = on) If you want to remove the effect send normal effect-setting packet but set "effect model" and knobs fields to zeros. I haven't tried what diff --git a/doc/fender_mustang_protocol.txt~ b/doc/fender_mustang_protocol.txt~ new file mode 100644 index 0000000..aea8b60 --- /dev/null +++ b/doc/fender_mustang_protocol.txt~ @@ -0,0 +1,672 @@ +Technicalities + +Here I want to put all the info I have about how Mustang amp works +under the hood. + +Table of contents + + Overview + Connecting + Setting amp + Setting and clearing effects + Saving settings on amplifier + Choosing memory bank + Captured data + +1. Overview + +It has five DSPs. One for each effect family and one for amplifier +emulation. DSPs are addressed from 5 to 9. I don't know why first five +addresses are omitted and if this means anything. DSPs with their +functionality are as follows: + + 0x05 - amplifier emulation + 0x06 - stompbox effects + 0x07 - modulation effects + 0x08 - delay effects + 0x09 - reverb effects + + I also have found packets with device address 0x0a but don't know what this is. + +2. Connecting + +All the transmission between program and amplifier is using USB +interrupt transfer. Endpoint to which you want to send data is 0x01 +and USB interface which you want to claim is 0x00. If you want to +receive data from amplifier use endpoint 0x81. + +Each packet carries 64 bytes of data. + +When connecting you should send two packets to the amp and get +response for each of them. First should have value "0xc3" set on the +first position (counting from zero) and second values "0x1a" and +"0x03" on zeroth and first position. + +After that a packet asking for amp's settings is send. The packet is +of form "0xff" on zeroth and "0xc1" on first position. Amplifier +responds to that sending: + + names of all presets in the form: + + packet with name in a form: values "0x1c 0x01 0x04" as first + three bytes, then slot number on forth byte and name encoded + in ASCII on 32 bytes starting from sixteenth + + packet with two first bytes and forth (slot of the preset) the + same as in name packet + + current state of the amp in the form: + + name of the current preset in the form as described above + + amplifiers setting in the form the same as when setting + amplifier's settings (below) except that first byte is not + "0x03" but "0x01" and preset number encoded on the forth byte + + settings of four effects as described below with the same + change to the first byte as in amplifier's settings and preset + number encoded on the forth byte + + setting of some mysterious device with address "0x0a" + + confirmation packet same as in preset names + + names with settings of all presets on the Mod and Dly/Rev knobs + (first all settings for Mod knob then all settings for Dly/Rev + knob) in the form: + + name of the preset in the form: values "0x1c 0x01 0x04" as + first three bytes, value "0x01" for Mod or "0x02" for Dly/Rev + knob on third position, slot number on forth position (counted + from zero), name encoded in ASCII on 24 bytes starting from + sixteenth byte + + settings of the effect in the same form as for setting the + effect (below) except that first byte is "0x01" not "0x03" and + preset number encoded on the forth byte + + This packet is set only when sending Dly/Rev presets Dly/Rev + knob hold settings for two effects so the next packet carries + info about second effect, if effect is not set the packet have + the same form as packet for clearing effect except that first + byte is "0x01" not "0x03" and preset number encoded on the + forth byte + + confirmation packet with values "0x1c 0x01" on zeroth and + first byte, "0x01" or "0x02" depending on the knob on third + byte and preset number encoded on the forth byte + +Wireshark file with whole initialization communication can be found here. + +3. Setting amp + +Format of data for setting amp is as follow: + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +00 | 1c| 03|DSP| 00 | 01| 01| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +16 |mod| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +32 |vol|gai|ga2|mvl|tre|mid|bas|prs|?? |dep|bis|?? | number |ng | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +48 |ths|cab|?? |sag|bri| 01|?? | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + +DSP - for amplifier it is always 5 +mod - amplifier model; different for each emulated amp +vol - volume +gai - gain +ga2 - gain 2 +mvl - master volume +tre - treble +mid - middle +bas - bass +prs - presence +dep - depth +bis - bias +number - don't know what this is; different for each emulated amp +ng - noise gate; value 0x00 - 0x05 +ths - threshold; value 0x00 - 0x09 +cab - cabinet; value 0x00 - 0x0c +sag - sag; value 0x00 - 0x02 +bri - brightness; value 0x00-0x01 +?? - values which I haven't decoded yet; different for each emulated amp + +After packet with data described above you have to send a packet which +will tell the amp to actually apply the settings. This packet have +zeroth byte set to "0x1c", first to "0x03" and all other to "0x00". + +4. Setting and clearing effects + +Data format for setting an effect is: + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +00 | 1c| 03|DSP| 00 | 01| 01| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +16 |fxm| 00|slt| ??| ??| ??| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +32 |kb1|kb2|kb3|kb4|kb5|kb6| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +48 | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + +DSP - can be either 6, 7, 8 or 9; depends on effect familly +fxm - effect model; independent for each effect +slt - slot; before amp have numbers from 0 to 3, after from 4 to 7 + kb1, kb2, kb3, kb4, kb5, kb6 - knobs values; not every time + all are used; maximum value of the knob depends on the effect +?? - some strange numbers specific for each effect + +If you want to remove the effect send normal effect-setting packet but +set "effect model" and knobs fields to zeros. I haven't tried what +happens if you send such packet to DSP 0x05. + +"Execute" command for both setting and clearing the effect is the same +as for the amp setting. + +5. Saving settings on amplifier + +Saving settings is very easy since you don't have to transmit all the +settings which you want to store. You only send a command containing +slot number and name for a preset. Data are taken directly from DSPs. + +Packet format is: + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +00 | 1c| 01| 03| 00|SLT| 00| 01| 01| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +16 | name | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +32 | name | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +48 | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + +SLT - memory bank to which to save settings; value 0x00 - 0x17 + +name - name of the preset ended with "\0"; if not all fields are used + used the rest is set to 0x00 + +Fender FUSE after saving settings chooses memory bank it just +saved. PLUG also does this. + +6. Choosing memory bank + +"Choose memory bank" command looks like this: + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +00 | 1c| 01| 01| 00|SLT| 00| 01| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +16 | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +32 | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +48 | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + +SLT - memory bank to choose + +After choosing memory bank amplifier send you settings of that bank. + +7. Captured data + +Wireshark file with whole initialization communication can be found +here: http://piorekf.org/plug/files/initialization.log And here are +data from captured packets for setting all the amps and effects (only +hex part, the rest are my scribbles): + +AMPLIFIERS: + +fender 57 deluxe: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +67:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:99:80:80:be:80:80:80 80:80:80:80:01:01:01:00 +00:01:01:01:00:01:53:00 00:00:00:00:00:00:00:00 +0-10: gain[6] volume[7] treble[7.5] middle[5] bass[5] +NG: off -> threshold: 0/10 depth: mid sag: 2/3 bias: mid cabinet: 57dlx + +fender 59 bassman: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +64:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:a2:80:80:80:7a:a2:91 80:80:80:80:02:02:02:00 +00:02:02:01:00:01:67:00 00:00:00:00:00:00:00:00 +0-10: gain[6.5] volume[7] treble[5] middle[~5] bass[6.5] presence[~6] + +blend: mid NG: off -> threshold: 0/10 depth: mid sag: 2/3 bias: mid +cabinet: bssmn + +fender 57 champ: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +7c:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:b3:00:ff:80:80:80:80 80:80:80:80:0c:0c:0c:00 +00:05:0c:01:00:01:00:00 00:00:00:00:00:00:00:00 +0-10: gain[7] volume[~7] treble[5] middle[5] bass[5] +NG: off -> threshold: 0/10 depth: mid sag: 2/3 bias: mid cabinet: champ + +fender 65 deluxe reverb: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +53:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:71:00:ff:91:cf:38:00 00:00:80:00:03:03:03:00 +00:03:03:01:00:01:6a:00 00:00:00:00:00:00:00:00 + +1-10: gain[5] volume[7] treble[6.25] middle[8.75] bass[3] -reverb[~1] +-speed[7] -intensivity[9] + +NG: off -> threshold: 0/10 depth: 0 sag: 2/3 bias: mid cabinet: 65dlx + +fender 65 princeton: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +6a:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:55:00:ff:99:cc:4c:80 80:80:80:80:04:04:04:00 +00:04:04:01:00:01:61:00 00:00:00:00:00:00:00:00 + +1-10: gain[4] volume[7] treble[6.5] middle[8.5] bass[4] -reverb[5.5] +-speed[7] -intensivity[9] + +NG: off -> threshold: 0/10 depth: mid sag: 2/3 bias: mid cabinet: +65prn + +fender 65 twin reverb: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +75:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:55:80:63:b3:bb:aa:80 80:80:80:80:05:05:05:00 +00:09:05:01:00:01:72:00 00:00:00:00:00:00:00:00 + +1-10: +bright gain[4] volume[7] treble[7.5] middle[8] bass[7] +-reverb[5.5] -speed[7] -intensivity[9] + +NG: off -> threshold: 0/10 depth: mid sag: 2/3 bias: mid cabinet: +65twn + +fender super sonic: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +72:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:bb:82:55:99:a2:99:80 80:80:80:80:06:06:06:02 +00:0c:06:01:00:01:79:00 00:00:00:00:00:00:00:00 + +1-10: gain[7.5] gain2[5.5] volume[7] treble[6.5] middle[7] bass[6.5] +-reverb[5.5] + +master vol: 33% NG: mid -> threshold: 0/10 depth: mid sag: 2/3 bias: +mid cabinet: ss112 + +british 60s: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +61:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:a2:80:63:99:80:b0:00 80:80:80:80:07:07:07:00 +00:07:07:01:00:01:5e:00 00:00:00:00:00:00:00:00 + +0-10: +bright gain[6.5] volume[7] treble[6] middle[5] bass[7] +-speed[7] -depth[8.75] cut[0] + +NG: off -> threshold: 0/10 depth: mid sag: 2/3 bias: mid cabinet: +2x12c + +british 70s: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +79:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:ff:80:7d:aa:5b:c4:80 80:80:80:80:0b:0b:0b:01 +00:08:0b:01:00:01:7c:00 00:00:00:00:00:00:00:00 + +0-10: gain[10] volume[7] treble[7] middle[3] bass[8] presence[5] + +blend: mid NG: low -> threshold: 0/10 depth: mid sag: 2/3 bias: mid +cabinet: 4x12g + +british 80s: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +5e:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:ff:80:7d:aa:5b:c4:80 80:80:80:80:09:09:09:01 +00:06:09:01:00:01:5d:00 00:00:00:00:00:00:00:00 + +0-10: gain[10] volume[7] treble[7] middle[3] bass[8] presence[5] + +master vol: 50% NG: low -> threshold: 0/10 depth: mid sag: 2/3 bias: +mid cabinet: 4x12m + +american 90s: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +5d:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:8e:80:66:a4:19:c7:71 80:80:80:80:0a:0a:0a:03 +00:0a:0a:01:00:01:6d:00 00:00:00:00:00:00:00:00 + +?1-10?: gain[~1/2] volume[2/3] treble[2/3] middle[~1/10] bass[3/4] +presence[~1/2] + +master vol: 33% NG: high -> threshold: 0/10 depth: mid sag: 2/3 bias: +mid cabinet: 4x12v + +metal 2000: +1c:03:05:00:00:00:01:01 00:00:00:00:00:00:00:00 +6d:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +aa:a4:80:55:99:4c:91:8e 80:80:80:80:08:08:08:02 +00:08:08:01:00:01:75:00 00:00:00:00:00:00:00:00 + +0-10: gain[6.5] volume[7] treble[6] middle[3] bass[6] presence[5.5] + +master vol: 33% NG: mid -> threshold: 0/10 depth: mid sag: 2/3 bias: +mid cabinet: 4x12g + + + +EFFECTS: + +overdrive: +1c:03:06:00:00:00:01:01 00:00:00:00:00:00:00:00 +3c:00:03:00:08:01:00:00 00:00:00:00:00:00:00:00 +80:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level gain low mid high + +fixed wah: +1c:03:06:00:00:00:01:01 00:00:00:00:00:00:00:00 +49:00:03:01:08:01:00:00 00:00:00:00:00:00:00:00 +80:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level frequency min frequency max frequency q + +touch wah: +1c:03:06:00:00:00:01:01 00:00:00:00:00:00:00:00 +4a:00:03:01:08:01:00:00 00:00:00:00:00:00:00:00 +80:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level sensivity min frequency max frequency q + +fuzz: +1c:03:06:00:00:00:01:01 00:00:00:00:00:00:00:00 +1a:00:03:00:08:01:00:00 00:00:00:00:00:00:00:00 +80:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level gain octave low high + +fuzz touch wah: +1c:03:06:00:00:00:01:01 00:00:00:00:00:00:00:00 +1c:00:03:00:08:01:00:00 00:00:00:00:00:00:00:00 +80:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level gain sensivity octave peak + +simple comp (1 knob): +1c:03:06:00:00:00:01:01 00:00:00:00:00:00:00:00 +88:00:03:08:08:01:00:00 00:00:00:00:00:00:00:00 +01:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +type[0-3] + +compressor: +1c:03:06:00:00:00:01:01 00:00:00:00:00:00:00:00 +07:00:03:00:08:01:00:00 00:00:00:00:00:00:00:00 +8d:0f:4f:7f:7f:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level threshhold ratio attack release + + + +sine chorus: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +12:00:02:01:01:01:00:00 00:00:00:00:00:00:00:00 +ff:0e:19:19:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level rate depth average delay lr phase + +triangle chorus: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +13:00:02:01:01:01:00:00 00:00:00:00:00:00:00:00 +5d:0e:19:19:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level rate depth average delay lr phase + +sine flanger: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +18:00:02:01:01:01:00:00 00:00:00:00:00:00:00:00 +ff:0e:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level rate depth feedback lr phase + +triangle flanger: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +19:00:02:01:01:01:00:00 00:00:00:00:00:00:00:00 +ff:00:ff:33:41:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level rate depth feedback lr phase + +vibratone: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +2d:00:02:01:01:01:00:00 00:00:00:00:00:00:00:00 +f4:ff:27:ad:82:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level rotor depth feedback lr phase + +vintage tremolo: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +40:00:02:01:01:01:00:00 00:00:00:00:00:00:00:00 +db:ad:63:f4:f1:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level rate duty cycle attack release + +sine tremolo: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +41:00:02:01:01:01:00:00 00:00:00:00:00:00:00:00 +db:99:7d:00:00:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level rate duty cycle lfo clipping tri shaping + +ring modulator: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +22:00:02:01:08:01:00:00 00:00:00:00:00:00:00:00 +ff:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level frequency depth lfo shape[0-1] lfo phase + +step filter: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +29:00:02:01:01:01:00:00 00:00:00:00:00:00:00:00 +ff:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level rate resonance min frequency max frequency + +phaser: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +4f:00:02:01:01:01:00:00 00:00:00:00:00:00:00:00 +fd:00:fd:b8:00:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level rate depth feedback lfo shape[0-1] + +pitch shifter: +1c:03:07:00:00:00:01:01 00:00:00:00:00:00:00:00 +1f:00:02:01:08:01:00:00 00:00:00:00:00:00:00:00 +c7:3e:80:00:00:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level pitch detune feedback predelay + + + +mono delay: +1c:03:08:00:00:00:01:01 00:00:00:00:00:00:00:00 +16:00:02:02:01:01:00:00 00:00:00:00:00:00:00:00 +ff:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level delay time feedback brightness attenuation + +mono echo filter (6 knobs): +1c:03:08:00:00:00:01:01 00:00:00:00:00:00:00:00 +43:00:02:02:01:01:00:00 00:00:00:00:00:00:00:00 +ff:80:80:80:80:80:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level delay time feedback frequency ressonance input level + +stereo echo filter (6 knobs): +1c:03:08:00:00:00:01:01 00:00:00:00:00:00:00:00 +48:00:02:02:01:01:00:00 00:00:00:00:00:00:00:00 +80:b3:80:80:80:80:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level delay time feedback frequency ressonance input level + +multitap delay: +1c:03:08:00:00:00:01:01 00:00:00:00:00:00:00:00 +44:00:02:02:01:01:00:00 00:00:00:00:00:00:00:00 +ff:80:66:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level delay time feedback brightness attenuation + +ping pong delay: +1c:03:08:00:00:00:01:01 00:00:00:00:00:00:00:00 +45:00:02:02:01:01:00:00 00:00:00:00:00:00:00:00 +ff:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level delay time feedback brightness attenuation + +ducking delay: +1c:03:08:00:00:00:01:01 00:00:00:00:00:00:00:00 +15:00:02:02:01:01:00:00 00:00:00:00:00:00:00:00 +ff:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level delay time feedback release threshold + +reverse delay: +1c:03:08:00:00:00:01:01 00:00:00:00:00:00:00:00 +46:00:02:02:01:01:00:00 00:00:00:00:00:00:00:00 +ff:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level delay time feedback brightness attenuation + +tape delay (6 knobs): +1c:03:08:00:00:00:01:01 00:00:00:00:00:00:00:00 +2b:00:02:02:01:01:00:00 00:00:00:00:00:00:00:00 +7d:1c:00:63:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level delay time feedback flutter brightness stereo + +stereo tape delay (6 knobs): +1c:03:08:00:00:00:01:01 00:00:00:00:00:00:00:00 +2a:00:02:02:01:01:00:00 00:00:00:00:00:00:00:00 +7d:88:1c:63:ff:80:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level delay time feedback flutter separation brightness + + + +small hall reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +24:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +6e:5d:6e:80:91:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +large hall reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +3a:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +4f:3e:80:05:b0:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +small room reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +26:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +80:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +large room reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +3b:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +80:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +small plate reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +4e:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +80:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +large plate reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +4b:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +38:80:91:80:b6:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +ambient reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +4c:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +ff:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +arena reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +4d:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +ff:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +'63 fender spring reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +21:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +80:80:80:80:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +'65 fender spring reverb: +1c:03:09:00:00:00:01:01 00:00:00:00:00:00:00:00 +0b:00:02:00:08:01:00:00 00:00:00:00:00:00:00:00 +80:8b:49:ff:80:00:00:00 00:00:00:00:00:00:00:00 +00:00:00:00:00:00:00:00 00:00:00:00:00:00:00:00 +level decay dwell diffusion tone + +====================================================================== + +Toggling effect on/off: + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +00 | 19| c3|fam| st|slt| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +16 | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +32 | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +48 | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + +fam - (3 = stomp, 4 = mod, 5 = delay, 6 = reverb) +st - status (on = 00, off = 01) +slt - slot; before amp have numbers from 0 to 3, after from 4 to 7 + + +1st data packet resported after toggling an effect on or off is: + + 0 1 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +00 | 1c| 01|DSP| 00 | 01| 01| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +16 |fxm| 00|slt| ??| ??| ??| 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +32 |kb1|kb2|kb3|kb4|kb5|kb6|st | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +48 | ? | ? | ? | ? | ? | 00 | + +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + +efx_family - (3 = stomp, 4 = mod, 5 = delay, 6 = reverb) +fxm - effect model; independent for each effect +slt - slot; before amp have numbers from 0 to 3, after from 4 to 7 + +kb1, kb2, kb3, kb4, kb5, kb6 - knobs values; not every time + all are used; maximum value of the knob depends on the effect + +st - Status (on = 00, off = 01) + +This is followed by two more packets whose purpose is unknown. + diff --git a/mod.cpp b/mod.cpp new file mode 100644 index 0000000..063f281 --- /dev/null +++ b/mod.cpp @@ -0,0 +1,60 @@ + +#include "mod.h" +#include "mustang.h" + +int +ModCC::continuous_control( int parm5, int parm6, int parm7, int value ) { + Mustang::Cmd cmd; + cmd.state_index = MOD_STATE; + cmd.parm2 = 0x04; + cmd.parm5 = parm5; + cmd.parm6 = parm6; + cmd.parm7 = parm7; + cmd.value = value; + + return amp->continuous_control( cmd ); +} + +int +ModCC::discrete_control( int parm5, int parm6, int parm7, int value ) { + Mustang::Cmd cmd; + cmd.state_index = MOD_STATE; + cmd.parm2 = 0x04; + cmd.parm5 = parm5; + cmd.parm6 = parm6; + cmd.parm7 = parm7; + cmd.value = value; + + return amp->discrete_control( cmd ); +} + +int +ModCC::dispatch( int cc, int value ) { + + switch ( cc ) { + case 39: + // Level / Mix + return cc39( value ); + break; + case 40: + // Rate / Rotor / Freq / Pitch + return cc40( value ); + break; + case 41: + // Depth / Duty Cycle / Resonance / Detune / Heel Freq + return cc41( value ); + break; + case 42: + // Delay / Fdbk / LFO / Min Freq / Feedback / Toe Freq + return cc42( value ); + break; + case 43: + // LR Phase / Release / Tri Shape / PreDelay / High Q + return cc43( value ); + break; + default: + return 0; + break; + } +} + diff --git a/mod.h b/mod.h new file mode 100644 index 0000000..601e319 --- /dev/null +++ b/mod.h @@ -0,0 +1,184 @@ +// -*-c++-*- + +#ifndef _MOD_H +#define _MOD_H + +class Mustang; + +class ModCC { + +protected: + Mustang * amp; + + int continuous_control( int parm5, int parm6, int parm7, int value ); + int discrete_control( int parm5, int parm6, int parm7, int value ); + +public: + ModCC( Mustang * theAmp ) : amp(theAmp) {} + + int dispatch( int cc, int value ); + +private: + virtual int cc39( int value ) = 0; + virtual int cc40( int value ) = 0; + virtual int cc41( int value ) = 0; + virtual int cc42( int value ) = 0; + virtual int cc43( int value ) = 0; + }; + + +class ChorusCC : public ModCC { +public: + ChorusCC( Mustang * theAmp ) : ModCC(theAmp) {} +private: + // Level + virtual int cc39( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Rate + virtual int cc40( int value ) { return continuous_control( 0x01, 0x01, 0x10, value );} + // Depth + virtual int cc41( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Avg Delay + virtual int cc42( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // LR Phase + virtual int cc43( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class FlangerCC : public ModCC { +public: + FlangerCC( Mustang * theAmp ) : ModCC(theAmp) {} +private: + // Level + virtual int cc39( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Rate + virtual int cc40( int value ) { return continuous_control( 0x01, 0x01, 0x10, value );} + // Depth + virtual int cc41( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Feedback + virtual int cc42( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // LR Phase + virtual int cc43( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class VibratoneCC : public ModCC { +public: + VibratoneCC( Mustang * theAmp ) : ModCC(theAmp) {} +private: + // Level + virtual int cc39( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Rotor Speed + virtual int cc40( int value ) { return continuous_control( 0x01, 0x01, 0x0f, value );} + // Depth + virtual int cc41( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Feedback + virtual int cc42( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // LR Phase + virtual int cc43( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class TremCC : public ModCC { +public: + TremCC( Mustang * theAmp ) : ModCC(theAmp) {} +private: + // Level + virtual int cc39( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Rotor Speed + virtual int cc40( int value ) { return continuous_control( 0x01, 0x01, 0x0e, value );} + // Duty Cycle + virtual int cc41( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Attack / LFO Clip + virtual int cc42( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // Release / Tri Shape + virtual int cc43( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class RingModCC : public ModCC { +public: + RingModCC( Mustang * theAmp ) : ModCC(theAmp) {} +private: + // Level + virtual int cc39( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Freq + virtual int cc40( int value ) { return continuous_control( 0x01, 0x01, 0x01, value );} + // Depth + virtual int cc41( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // LFO Depth + virtual int cc42( int value ) { + if ( value > 1 ) return 0; + else return discrete_control( 0x03, 0x03, 0x8c, value ); + } + // LFO Phase + virtual int cc43( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class StepFilterCC : public ModCC { +public: + StepFilterCC( Mustang * theAmp ) : ModCC(theAmp) {} +private: + // Level + virtual int cc39( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Rate + virtual int cc40( int value ) { return continuous_control( 0x01, 0x01, 0x10, value );} + // Resonance + virtual int cc41( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Min Freq + virtual int cc42( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // Max Freq + virtual int cc43( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class PhaserCC : public ModCC { +public: + PhaserCC( Mustang * theAmp ) : ModCC(theAmp) {} +private: + // Level + virtual int cc39( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Rate + virtual int cc40( int value ) { return continuous_control( 0x01, 0x01, 0x10, value );} + // Depth + virtual int cc41( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Feedback + virtual int cc42( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // LFO Shape + virtual int cc43( int value ) { + if ( value > 1 ) return 0; + else return discrete_control( 0x04, 0x04, 0x8c, value ); + } +}; + + +class PitchShifterCC : public ModCC { +public: + PitchShifterCC( Mustang * theAmp ) : ModCC(theAmp) {} +private: + // Level + virtual int cc39( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Pitch + virtual int cc40( int value ) { return continuous_control( 0x01, 0x01, 0x01, value );} + // Detune + virtual int cc41( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Feedback + virtual int cc42( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // Predelay + virtual int cc43( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class NullModCC : public ModCC { +public: + NullModCC( Mustang * theAmp ) : ModCC(theAmp) {} +private: + virtual int cc39( int value ) { return 0;} + virtual int cc40( int value ) { return 0;} + virtual int cc41( int value ) { return 0;} + virtual int cc42( int value ) { return 0;} + virtual int cc43( int value ) { return 0;} +}; + + +#endif diff --git a/mod_defaults.h b/mod_defaults.h new file mode 100644 index 0000000..5bbf888 --- /dev/null +++ b/mod_defaults.h @@ -0,0 +1,84 @@ +static unsigned char mod_none[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char sine_chorus[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x04, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x0e, 0x19, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char triangle_chorus[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x04, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0e, 0x19, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char sine_flanger[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x04, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x0e, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char triangle_flanger[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x04, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0xff, 0x33, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char vibratone[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2d, 0x00, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf4, 0xff, 0x27, 0xad, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char vintage_tremolo[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xdb, 0xad, 0x63, 0xf4, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char sine_tremolo[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xdb, 0x99, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char ring_modulator[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x04, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char step_filter[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char phaser[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4f, 0x00, 0x04, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfd, 0x00, 0xfd, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char pitch_shifter[] = { + 0x1c, 0x03, 0x07, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x04, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc7, 0x3e, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + diff --git a/mustang.cpp b/mustang.cpp index 6076843..24b73d9 100644 --- a/mustang.cpp +++ b/mustang.cpp @@ -7,16 +7,21 @@ #include "amp.h" #include "reverb.h" #include "delay.h" +#include "mod.h" +#include "stomp.h" #include "amp_defaults.h" #include "reverb_defaults.h" #include "delay_defaults.h" +#include "mod_defaults.h" +#include "stomp_defaults.h" Mustang::Mustang() { amp_hand = NULL; curr_amp = NULL; - + tuner_active = false; + // "apply efect" command memset(execute, 0x00, LENGTH); execute[0] = 0x1c; @@ -42,8 +47,6 @@ int Mustang::start_amp(void) { int ret, received; unsigned char array[LENGTH]; - unsigned char received_data[296][LENGTH], data[7][LENGTH]; - memset(received_data, 0x00, 296*LENGTH); if(amp_hand == NULL) { @@ -107,8 +110,6 @@ int Mustang::start_amp(void) libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT); libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT); - int i = 0, j = 0; - memset(array, 0x00, LENGTH); array[0] = 0xff; array[1] = 0xc1; @@ -116,6 +117,20 @@ int Mustang::start_amp(void) // Request parameter dump from amplifier libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT); + handle_parm_dump(); + + return 0; +} + +void Mustang::handle_parm_dump() +{ + int ret, received; + unsigned char array[LENGTH]; + unsigned char received_data[296][LENGTH], data[7][LENGTH]; + memset(received_data, 0x00, 296*LENGTH); + + int i = 0, j = 0; + // Count probably varies by model. Brute-force flush appears to create problems // so we'll need to get this right case by case. for(i = 0; i < 210; i++) @@ -139,10 +154,11 @@ int Mustang::start_amp(void) updateAmpObj(); updateReverbObj(); updateDelayObj(); - - return 0; + updateModObj(); + updateStompObj(); } + int Mustang::stop_amp() { int ret; @@ -173,10 +189,51 @@ int Mustang::stop_amp() return 0; } +int Mustang::tunerMode( int value ) +{ + int ret, received; + unsigned char array[LENGTH]; + memset(array, 0x00, LENGTH); + + array[0] = 0x0a; + array[1] = 0x01; + + // This is a bit odd. When turning ON the tuner, the amp responds + // with a complete parameter dump reflecting all null devices + // (basically useless). When turning it off, we get only a single + // response message. + // + if ( value > 63 && value <= 127 ) { + // Tuner on + array[2] = array[3] = array[4] = 0x01; + ret = libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT); + + int i = 0; + for(i = 0; i < 210; i++) { + int rc = libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT); + if (rc) fprintf( stderr, "DEBUG: Timeout. i = %d, rc = %d\n", i, rc ); + } + tuner_active = true; + } + else if ( value >= 0 && value <= 63 ) { + // Tuner off + ret = libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT); + libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT); + sleep( 1 ); + tuner_active = false; + } + + return ret; +} + + void Mustang::updateAmpObj(void) { int curr = curr_state[AMP_STATE][MODEL]; switch (curr) { + case 0: + break; + case F57_DELUXE_ID: case F57_CHAMP_ID: case F65_DELUXE_ID: @@ -222,8 +279,18 @@ void Mustang::updateAmpObj(void) { void Mustang::updateReverbObj(void) { - delete curr_reverb; - curr_reverb = new ReverbCC( this ); + + int curr = curr_state[REVERB_STATE][MODEL]; + + switch (curr) { + case 0: + break; + + default: + delete curr_reverb; + curr_reverb = new ReverbCC( this ); + break; + } } @@ -232,6 +299,9 @@ void Mustang::updateDelayObj(void) { int curr = curr_state[DELAY_STATE][MODEL]; switch (curr) { + case 0: + break; + case MONO_DLY_ID: delete curr_delay; curr_delay = new MonoDelayCC(this); @@ -280,8 +350,114 @@ void Mustang::updateDelayObj(void) { } +void Mustang::updateModObj(void) { + + int curr = curr_state[MOD_STATE][MODEL]; + + switch (curr) { + case 0: + break; + + case SINE_CHORUS_ID: + case TRI_CHORUS_ID: + delete curr_mod; + curr_mod = new ChorusCC(this); + break; + + case SINE_FLANGE_ID: + case TRI_FLANGE_ID: + delete curr_mod; + curr_mod = new FlangerCC(this); + break; + + case VIBRATONE_ID: + delete curr_mod; + curr_mod = new VibratoneCC(this); + break; + + case VINT_TREM_ID: + case SINE_TREM_ID: + delete curr_mod; + curr_mod = new TremCC(this); + break; + + case RING_MOD_ID: + delete curr_mod; + curr_mod = new RingModCC(this); + break; + + case STEP_FILT_ID: + delete curr_mod; + curr_mod = new StepFilterCC(this); + break; + + case PHASER_ID: + delete curr_mod; + curr_mod = new PhaserCC(this); + break; + + case PITCH_SHIFT_ID: + delete curr_mod; + curr_mod = new PitchShifterCC(this); + break; + + default: + fprintf( stderr, "W - Mod id %x not supported yet\n", curr ); + break; + } +} + + +void Mustang::updateStompObj(void) { + + int curr = curr_state[STOMP_STATE][MODEL]; + + switch (curr) { + case 0: + break; + + case OVERDRIVE_ID: + delete curr_stomp; + curr_stomp = new OverdriveCC(this); + break; + + case WAH_ID: + case TOUCH_WAH_ID: + delete curr_stomp; + curr_stomp = new WahCC(this); + break; + + case FUZZ_ID: + delete curr_stomp; + curr_stomp = new FuzzCC(this); + break; + + case FUZZ_TWAH_ID: + delete curr_stomp; + curr_stomp = new FuzzTouchWahCC(this); + break; + + case SIMPLE_COMP_ID: + delete curr_stomp; + curr_stomp = new SimpleCompCC(this); + break; + + case COMP_ID: + delete curr_stomp; + curr_stomp = new CompCC(this); + break; + + default: + fprintf( stderr, "W - Stomp id %x not supported yet\n", curr ); + break; + } +} + + int Mustang::effect_toggle(int cc, int value) { + if ( tuner_active ) return 0; + int ret, received; unsigned char array[LENGTH]; @@ -314,12 +490,17 @@ int Mustang::effect_toggle(int cc, int value) } int Mustang::setAmp( int ord ) { + if ( tuner_active ) return 0; + int ret, received; unsigned char scratch[LENGTH]; unsigned char *array; switch (ord) { + case 0: + array = amp_none; + break; case 1: array = f57_deluxe; break; @@ -373,30 +554,35 @@ int Mustang::setAmp( int ord ) { updateAmpObj(); // Setup USB gain - memset(scratch, 0x00, LENGTH); - scratch[0] = 0x1c; - scratch[1] = 0x03; - scratch[2] = 0x0d; - scratch[6] = 0x01; - scratch[7] = 0x01; - scratch[16] = 0x80; + // memset(scratch, 0x00, LENGTH); + // scratch[0] = 0x1c; + // scratch[1] = 0x03; + // scratch[2] = 0x0d; + // scratch[6] = 0x01; + // scratch[7] = 0x01; + // scratch[16] = 0x80; - ret = libusb_interrupt_transfer(amp_hand, 0x01, scratch, LENGTH, &received, TMOUT); - libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT); + // ret = libusb_interrupt_transfer(amp_hand, 0x01, scratch, LENGTH, &received, TMOUT); + // libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT); - ret = libusb_interrupt_transfer(amp_hand, 0x01, execute, LENGTH, &received, TMOUT); - libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT); + // ret = libusb_interrupt_transfer(amp_hand, 0x01, execute, LENGTH, &received, TMOUT); + // libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT); return ret; } int Mustang::setReverb( int ord ) { + if ( tuner_active ) return 0; + int ret, received; unsigned char scratch[LENGTH]; unsigned char *array; switch (ord) { + case 0: + array = reverb_none; + break; case 1: array = small_hall; break; @@ -449,12 +635,17 @@ int Mustang::setReverb( int ord ) { } int Mustang::setDelay( int ord ) { + if ( tuner_active ) return 0; + int ret, received; unsigned char scratch[LENGTH]; unsigned char *array; switch (ord) { + case 0: + array = delay_none; + break; case 1: array = mono_delay; break; @@ -503,8 +694,130 @@ int Mustang::setDelay( int ord ) { return ret; } +int Mustang::setMod( int ord ) { + if ( tuner_active ) return 0; + + int ret, received; + unsigned char scratch[LENGTH]; + + unsigned char *array; + + switch (ord) { + case 0: + array = mod_none; + break; + case 1: + array = sine_chorus; + break; + case 2: + array = triangle_chorus; + break; + case 3: + array = sine_flanger; + break; + case 4: + array = triangle_flanger; + break; + case 5: + array = vibratone; + break; + case 6: + array = vintage_tremolo; + break; + case 7: + array = sine_tremolo; + break; + case 8: + array = ring_modulator; + break; + case 9: + array = step_filter; + break; + case 10: + array = phaser; + break; + case 11: + array = pitch_shifter; + break; + default: + fprintf( stderr, "W - Mod select %d not supported\n", ord ); + return 0; + } + + array[FXSLOT] = curr_state[MOD_STATE][FXSLOT]; + + // Setup amp personality + ret = libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT); + libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT); + + ret = libusb_interrupt_transfer(amp_hand, 0x01, execute, LENGTH, &received, TMOUT); + libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT); + + // Copy to current setting store + memcpy(curr_state[MOD_STATE], array, LENGTH); + updateModObj(); + + return ret; +} + +int Mustang::setStomp( int ord ) { + if ( tuner_active ) return 0; + + int ret, received; + unsigned char scratch[LENGTH]; + + unsigned char *array; + + switch (ord) { + case 0: + array = stomp_none; + break; + case 1: + array = overdrive; + break; + case 2: + array = wah; + break; + case 3: + array = touch_wah; + break; + case 4: + array = fuzz; + break; + case 5: + array = fuzz_touch_wah; + break; + case 6: + array = simple_comp; + break; + case 7: + array = compressor; + break; + default: + fprintf( stderr, "W - Stomp select %d not supported\n", ord ); + return 0; + } + + array[FXSLOT] = curr_state[STOMP_STATE][FXSLOT]; + + // Setup amp personality + ret = libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT); + libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT); + + ret = libusb_interrupt_transfer(amp_hand, 0x01, execute, LENGTH, &received, TMOUT); + libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT); + + // Copy to current setting store + memcpy(curr_state[STOMP_STATE], array, LENGTH); + updateStompObj(); + + return ret; +} + int Mustang::save_on_amp(char *name, int slot) { + if ( tuner_active ) return 0; + int ret, received; unsigned char array[LENGTH]; @@ -531,6 +844,8 @@ int Mustang::save_on_amp(char *name, int slot) } int Mustang::continuous_control( const Mustang::Cmd & cmd ) { + if ( tuner_active ) return 0; + int ret, received; unsigned char array[LENGTH]; @@ -563,6 +878,8 @@ int Mustang::continuous_control( const Mustang::Cmd & cmd ) { int Mustang::discrete_control( const Mustang::Cmd & cmd ) { + if ( tuner_active ) return 0; + int ret, received; unsigned char array[LENGTH]; @@ -589,6 +906,8 @@ int Mustang::discrete_control( const Mustang::Cmd & cmd ) { int Mustang::load_memory_bank( int slot ) { + if ( tuner_active ) return 0; + int ret, received; unsigned char array[LENGTH], data[7][LENGTH]; @@ -604,10 +923,15 @@ int Mustang::load_memory_bank( int slot ) // Mustang III has nine responses for(int i=0; i < 9; i++) { libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT); - if(i < 7) - memcpy(curr_state[i], array, LENGTH); + int dsp = array[2]; + if ( dsp >= 4 && dsp <= 9 ) + memcpy(curr_state[dsp - 4], array, LENGTH); } updateAmpObj(); + updateReverbObj(); + updateDelayObj(); + updateModObj(); + updateStompObj(); return ret; } diff --git a/mustang.h b/mustang.h index baf6513..0a64182 100644 --- a/mustang.h +++ b/mustang.h @@ -140,16 +140,41 @@ #define TAPE_DLY_ID 0x2b #define ST_TAPE_DLY_ID 0x2a +// Mod model id values +#define SINE_CHORUS_ID 0x12 +#define TRI_CHORUS_ID 0x13 +#define SINE_FLANGE_ID 0x18 +#define TRI_FLANGE_ID 0x19 +#define VIBRATONE_ID 0x2d +#define VINT_TREM_ID 0x40 +#define SINE_TREM_ID 0x41 +#define RING_MOD_ID 0x22 +#define STEP_FILT_ID 0x29 +#define PHASER_ID 0x4f +#define PITCH_SHIFT_ID 0x1f + +// Stomp model id values +#define OVERDRIVE_ID 0x3c +#define WAH_ID 0x49 +#define TOUCH_WAH_ID 0x4a +#define FUZZ_ID 0x1a +#define FUZZ_TWAH_ID 0x1c +#define SIMPLE_COMP_ID 0x88 +#define COMP_ID 0x07 + class AmpCC; class ReverbCC; class DelayCC; - +class ModCC; +class StompCC; class Mustang { friend class AmpCC; friend class ReverbCC; friend class DelayCC; + friend class ModCC; + friend class StompCC; public: Mustang(); @@ -161,6 +186,10 @@ public: int setAmp( int ord ); int setReverb( int ord ); int setDelay( int ord ); + int setMod( int ord ); + int setStomp( int ord ); + + int tunerMode( int value ); int save_on_amp(char *, int); int load_memory_bank(int); @@ -171,6 +200,8 @@ public: AmpCC * getAmp( void ) { return curr_amp;} ReverbCC * getReverb( void ) { return curr_reverb;} DelayCC * getDelay( void ) { return curr_delay;} + ModCC * getMod( void ) { return curr_mod;} + StompCC * getStomp( void ) { return curr_stomp;} struct Cmd { int state_index; @@ -207,17 +238,25 @@ private: // 6 : Expression Pedal // unsigned char curr_state[7][LENGTH]; - + + bool tuner_active; + AmpCC * curr_amp; ReverbCC * curr_reverb; DelayCC * curr_delay; + ModCC * curr_mod; + StompCC * curr_stomp; int continuous_control( const Mustang::Cmd & cmd ); int discrete_control( const Mustang::Cmd & cmd ); + void handle_parm_dump(void); + void updateAmpObj(void); void updateReverbObj(void); void updateDelayObj(void); + void updateModObj(void); + void updateStompObj(void); }; #endif // MUSTANG_H diff --git a/mustang_midi.cpp b/mustang_midi.cpp index f343ccc..a06ed65 100644 --- a/mustang_midi.cpp +++ b/mustang_midi.cpp @@ -8,7 +8,8 @@ #include "amp.h" #include "reverb.h" #include "delay.h" - +#include "mod.h" +#include "stomp.h" static Mustang mustang; @@ -48,10 +49,45 @@ void message_action( double deltatime, std::vector< unsigned char > *message, vo int cc = (*message)[1]; int value = (*message)[2]; + // Tuner toggle + if ( cc == 20 ) { + rc = mustang.tunerMode( value ); + } + // All EFX toggle + else if ( cc == 22 ) { + rc = mustang.effect_toggle( 23, value ); + if ( rc == 0 ) { + rc = mustang.effect_toggle( 24, value ); + if ( rc == 0 ) { + rc = mustang.effect_toggle( 25, value ); + if ( rc == 0 ) { + rc = mustang.effect_toggle( 26, value ); + } + } + } + } // Effects on/off - if ( cc >= 23 && cc <= 26 ) { + else if ( cc >= 23 && cc <= 26 ) { rc = mustang.effect_toggle( cc, value ); } + // Set stomp model + else if ( cc == 28 ) { + rc = mustang.setStomp( value ); + } + // Stomp CC handler + else if ( cc >= 29 && cc <= 33 ) { + StompCC *stompObj = mustang.getStomp(); + rc = stompObj->dispatch( cc, value ); + } + // Set mod model + else if ( cc == 38 ) { + rc = mustang.setStomp( value ); + } + // Mod CC handler + else if ( cc >= 39 && cc <= 43 ) { + StompCC *modObj = mustang.getStomp(); + rc = modObj->dispatch( cc, value ); + } // Set delay model else if ( cc == 48 ) { rc = mustang.setDelay( value ); diff --git a/reverb.cpp b/reverb.cpp index 516fdc8..080057b 100644 --- a/reverb.cpp +++ b/reverb.cpp @@ -45,28 +45,3 @@ ReverbCC::dispatch( int cc, int value ) { } } -int -ReverbCC::cc59( int value ) { - return continuous_control( 0x00, 0x00, 0x0b, value ); -} - -int -ReverbCC::cc60( int value ) { - return continuous_control( 0x01, 0x01, 0x0b, value ); -} - -int -ReverbCC::cc61( int value ) { - return continuous_control( 0x02, 0x02, 0x0b, value ); -} - -int -ReverbCC::cc62( int value ) { - return continuous_control( 0x03, 0x03, 0x0b, value ); -} - -int -ReverbCC::cc63( int value ) { - return continuous_control( 0x04, 0x04, 0x0b, value ); -} - diff --git a/reverb.h b/reverb.h index 7404606..f9eb0d1 100644 --- a/reverb.h +++ b/reverb.h @@ -19,15 +19,28 @@ public: private: // Level - int cc59( int value ); + int cc59( int value ) { return continuous_control( 0x00, 0x00, 0x0b, value );} // Decay - int cc60( int value ); + int cc60( int value ) { return continuous_control( 0x01, 0x01, 0x0b, value );} // Dwell - int cc61( int value ); + int cc61( int value ) { return continuous_control( 0x02, 0x02, 0x0b, value );} // Diffusion - int cc62( int value ); + int cc62( int value ) { return continuous_control( 0x03, 0x03, 0x0b, value );} // Tone - int cc63( int value ); + int cc63( int value ) { return continuous_control( 0x04, 0x04, 0x0b, value );} }; + +class NullReverbCC : public ReverbCC { +public: + NullReverbCC( Mustang * theAmp ) : ReverbCC(theAmp) {} +private: + int cc59( int value ) { return 0;} + int cc60( int value ) { return 0;} + int cc61( int value ) { return 0;} + int cc62( int value ) { return 0;} + int cc63( int value ) { return 0;} +}; + + #endif diff --git a/reverb_defaults.h b/reverb_defaults.h index 8bff376..7fe52a2 100644 --- a/reverb_defaults.h +++ b/reverb_defaults.h @@ -2,6 +2,13 @@ // // This header is auto-generated from decoded pcap capture. +static unsigned char reverb_none[] = { + 0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + static unsigned char small_hall[] = { 0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x05, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/stomp.cpp b/stomp.cpp new file mode 100644 index 0000000..f027d77 --- /dev/null +++ b/stomp.cpp @@ -0,0 +1,60 @@ + +#include "stomp.h" +#include "mustang.h" + +int +StompCC::continuous_control( int parm5, int parm6, int parm7, int value ) { + Mustang::Cmd cmd; + cmd.state_index = STOMP_STATE; + cmd.parm2 = 0x03; + cmd.parm5 = parm5; + cmd.parm6 = parm6; + cmd.parm7 = parm7; + cmd.value = value; + + return amp->continuous_control( cmd ); +} + +int +StompCC::discrete_control( int parm5, int parm6, int parm7, int value ) { + Mustang::Cmd cmd; + cmd.state_index = STOMP_STATE; + cmd.parm2 = 0x03; + cmd.parm5 = parm5; + cmd.parm6 = parm6; + cmd.parm7 = parm7; + cmd.value = value; + + return amp->discrete_control( cmd ); +} + +int +StompCC::dispatch( int cc, int value ) { + + switch ( cc ) { + case 29: + // Level / Mix / Type + return cc29( value ); + break; + case 30: + // Gain / Freq / Sens / Thresh + return cc30( value ); + break; + case 31: + // Low / Heel Freq / Octave / Sens / Ratio + return cc31( value ); + break; + case 32: + // Mid / Toe Freq / Low / Octave / Attack + return cc32( value ); + break; + case 33: + // High / High Q / Peak / Relase + return cc33( value ); + break; + default: + return 0; + break; + } +} + diff --git a/stomp.h b/stomp.h new file mode 100644 index 0000000..f1f2724 --- /dev/null +++ b/stomp.h @@ -0,0 +1,146 @@ +// -*-c++-*- + +#ifndef _STOMP_H +#define _STOMP_H + +class Mustang; + +class StompCC { + +protected: + Mustang * amp; + + int continuous_control( int parm5, int parm6, int parm7, int value ); + int discrete_control( int parm5, int parm6, int parm7, int value ); + +public: + StompCC( Mustang * theAmp ) : amp(theAmp) {} + + int dispatch( int cc, int value ); + +private: + virtual int cc29( int value ) = 0; + virtual int cc30( int value ) = 0; + virtual int cc31( int value ) = 0; + virtual int cc32( int value ) = 0; + virtual int cc33( int value ) = 0; + }; + + +class OverdriveCC : public StompCC { +public: + OverdriveCC( Mustang * theAmp ) : StompCC(theAmp) {} +private: + // Level + virtual int cc29( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Gain + virtual int cc30( int value ) { return continuous_control( 0x01, 0x01, 0x01, value );} + // Low + virtual int cc31( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Mid + virtual int cc32( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // High + virtual int cc33( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class WahCC : public StompCC { +public: + WahCC( Mustang * theAmp ) : StompCC(theAmp) {} +private: + // Mix + virtual int cc29( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Freq + virtual int cc30( int value ) { return continuous_control( 0x01, 0x01, 0x01, value );} + // Heel Freq + virtual int cc31( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Toe Freq + virtual int cc32( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // High Q + virtual int cc33( int value ) { + if ( value > 1 ) return 0; + else return discrete_control( 0x04, 0x04, 0x81, value ); + } +}; + + +class FuzzCC : public StompCC { +public: + FuzzCC( Mustang * theAmp ) : StompCC(theAmp) {} +private: + // Level + virtual int cc29( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Gain + virtual int cc30( int value ) { return continuous_control( 0x01, 0x01, 0x01, value );} + // Octave + virtual int cc31( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Low + virtual int cc32( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // High + virtual int cc33( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class FuzzTouchWahCC : public StompCC { +public: + FuzzTouchWahCC( Mustang * theAmp ) : StompCC(theAmp) {} +private: + // Level + virtual int cc29( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Gain + virtual int cc30( int value ) { return continuous_control( 0x01, 0x01, 0x01, value );} + // Sens + virtual int cc31( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );} + // Octave + virtual int cc32( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // Peak + virtual int cc33( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class SimpleCompCC : public StompCC { +public: + SimpleCompCC( Mustang * theAmp ) : StompCC(theAmp) {} +private: + // Type + virtual int cc29( int value ) { + if ( value > 3 ) return 0; + else return discrete_control( 0x00, 0x05, 0x92, value ); + } + virtual int cc30( int value ) { return 0;} + virtual int cc31( int value ) { return 0;} + virtual int cc32( int value ) { return 0;} + virtual int cc33( int value ) { return 0;} +}; + + +class CompCC : public StompCC { +public: + CompCC( Mustang * theAmp ) : StompCC(theAmp) {} +private: + // Level + virtual int cc29( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );} + // Thresh + virtual int cc30( int value ) { return continuous_control( 0x01, 0x01, 0x01, value );} + // Ratio + virtual int cc31( int value ) { return continuous_control( 0x02, 0x02, 0x04, value );} + // Attack + virtual int cc32( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );} + // Release + virtual int cc33( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );} +}; + + +class NullStompCC : public StompCC { +public: + NullStompCC( Mustang * theAmp ) : StompCC(theAmp) {} +private: + virtual int cc29( int value ) { return 0;} + virtual int cc30( int value ) { return 0;} + virtual int cc31( int value ) { return 0;} + virtual int cc32( int value ) { return 0;} + virtual int cc33( int value ) { return 0;} +}; + + +#endif diff --git a/stomp_defaults.h b/stomp_defaults.h new file mode 100644 index 0000000..1ce9539 --- /dev/null +++ b/stomp_defaults.h @@ -0,0 +1,56 @@ +static unsigned char stomp_none[] = { + 0x1c, 0x03, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char overdrive[] = { + 0x1c, 0x03, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char wah[] = { + 0x1c, 0x03, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x00, 0x00, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x80, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char touch_wah[] = { + 0x1c, 0x03, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4a, 0x00, 0x00, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x80, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char fuzz[] = { + 0x1c, 0x03, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char fuzz_touch_wah[] = { + 0x1c, 0x03, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char simple_comp[] = { + 0x1c, 0x03, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x00, 0x08, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char compressor[] = { + 0x1c, 0x03, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8d, 0x0f, 0x4f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +