Complete Fender Floor MIDI implementation

This commit is contained in:
hirsch 2016-07-03 10:57:50 -04:00
parent 6638fc5bf3
commit 92ffd60808
21 changed files with 1834 additions and 367 deletions

View file

@ -21,7 +21,7 @@ $(BIN): $(OBJ)
$(CXX) $^ -o $@ $(LDLIBS) $(CXX) $^ -o $@ $(LDLIBS)
clean: clean:
rm -f $(DEP) $(OBJ) $(BIN) rm -f $(DEP) $(OBJ) $(BIN) *~
-include $(SRC:.cpp=.d) -include $(SRC:.cpp=.d)

95
amp.cpp
View file

@ -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 );
}

63
amp.h
View file

@ -28,23 +28,32 @@ public:
private: private:
// Gain // Gain
virtual int cc69( int value ); virtual int cc69( int value ) { return continuous_control( 0x01, 0x01, 0x0c, value );}
// Ch. Volume // Ch. Volume
virtual int cc70( int value ); virtual int cc70( int value ) { return continuous_control( 0x00, 0x00, 0x0c, value );}
// Treble // Treble
virtual int cc71( int value ); virtual int cc71( int value ) { return continuous_control( 0x04, 0x04, 0x0c, value );}
// Mid // Mid
virtual int cc72( int value ); virtual int cc72( int value ) { return continuous_control( 0x05, 0x05, 0x0c, value );}
// Bass // Bass
virtual int cc73( int value ); virtual int cc73( int value ) { return continuous_control( 0x06, 0x06, 0x0c, value );}
// Sag // 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 // Bias
virtual int cc75( int value ); virtual int cc75( int value ) { return continuous_control( 0x0a, 0x0a, 0x0d, value );}
// Noise Gate // 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 // 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 // Dummy in base class
virtual int cc78( int value ) { return 0;} virtual int cc78( int value ) { return 0;}
@ -60,9 +69,9 @@ public:
AmpCC1( Mustang * theAmp ) : AmpCC(theAmp) {} AmpCC1( Mustang * theAmp ) : AmpCC(theAmp) {}
private: private:
// Presence // Presence
virtual int cc78( int value ); virtual int cc78( int value ) { return continuous_control( 0x07, 0x07, 0x0c, value );}
// Blend // 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) {} AmpCC2( Mustang * theAmp ) : AmpCC(theAmp) {}
private: private:
// Gain2 // Gain2
virtual int cc78( int value ); virtual int cc78( int value ) { return continuous_control( 0x02, 0x02, 0x0c, value );}
// Master Volume // 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) {} AmpCC3( Mustang * theAmp ) : AmpCC(theAmp) {}
private: private:
// Cut // Cut
virtual int cc78( int value ); virtual int cc78( int value ) { return continuous_control( 0x07, 0x07, 0x0c, value );}
// Master Volume // 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) {} AmpCC4( Mustang * theAmp ) : AmpCC(theAmp) {}
private: private:
// Presence // Presence
virtual int cc78( int value ); virtual int cc78( int value ) { return continuous_control( 0x07, 0x07, 0x0c, value );}
// Master Volume // 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;} 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 #endif

View file

@ -2,6 +2,13 @@
// //
// This header is auto-generated from decoded pcap capture. // 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[] = { static unsigned char f57_deluxe[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

164
delay.cpp
View file

@ -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 );
}

92
delay.h
View file

@ -20,14 +20,14 @@ public:
private: private:
// Level // Level
virtual int cc49( int value ); virtual int cc49( int value ) { return continuous_control( 0x00, 0x00, 0x01, value );}
// Delay Time // 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 cc51( int value ) = 0;
virtual int cc52( int value ) { return 0;} virtual int cc52( int value ) = 0;
virtual int cc53( int value ) { return 0;} virtual int cc53( int value ) = 0;
virtual int cc54( int value ) { return 0;} virtual int cc54( int value ) = 0;
}; };
@ -36,11 +36,13 @@ public:
MonoDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {} MonoDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
private: private:
// Feedback // Feedback
virtual int cc51( int value ); virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );}
// Brightness // Brightness
virtual int cc52( int value ); virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );}
// Attenuation // 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) {} EchoFilterCC( Mustang * theAmp ) : DelayCC(theAmp) {}
private: private:
// Feedback // Feedback
virtual int cc51( int value ); virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );}
// Frequency // Frequency
virtual int cc52( int value ); virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );}
// Resonance // Resonance
virtual int cc53( int value ); virtual int cc53( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );}
// Input Level // 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) {} MultitapDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
private: private:
// Feedback // Feedback
virtual int cc51( int value ); virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );}
// Brightness // Brightness
virtual int cc52( int value ); virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );}
// Mode // 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) {} PingPongDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
private: private:
// Feedback // Feedback
virtual int cc51( int value ); virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );}
// Brightness // Brightness
virtual int cc52( int value ); virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );}
// Stereo // 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) {} DuckingDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
private: private:
// Feedback // Feedback
virtual int cc51( int value ); virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );}
// Release // Release
virtual int cc52( int value ); virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );}
// Threshold // 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) {} ReverseDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
private: private:
// FFdbk // FFdbk
virtual int cc51( int value ); virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );}
// RFdbk // RFdbk
virtual int cc52( int value ); virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );}
// Tone // 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) {} TapeDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
private: private:
// Feedback // Feedback
virtual int cc51( int value ); virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );}
// Flutter // Flutter
virtual int cc52( int value ); virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );}
// Brightness // Brightness
virtual int cc53( int value ); virtual int cc53( int value ) { return continuous_control( 0x04, 0x04, 0x01, value );}
// Stereo // 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) {} StereoTapeDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
private: private:
// Feedback // Feedback
virtual int cc51( int value ); virtual int cc51( int value ) { return continuous_control( 0x02, 0x02, 0x01, value );}
// Flutter // Flutter
virtual int cc52( int value ); virtual int cc52( int value ) { return continuous_control( 0x03, 0x03, 0x01, value );}
// Separation // Separation
virtual int cc53( int value ); virtual int cc53( int value ) { return continuous_control( 0x04, 0x05, 0x01, value );}
// Brightness // 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;}
}; };

View file

@ -2,6 +2,13 @@
// //
// This header is auto-generated from decoded pcap capture. // 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[] = { static unsigned char mono_delay[] = {
0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x16, 0x00, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

View file

@ -147,7 +147,7 @@ Data format for setting an effect is:
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
00 | 1c| 03|DSP| 00 | 01| 01| 00 | 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 | 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 kb1, kb2, kb3, kb4, kb5, kb6 - knobs values; not every time
all are used; maximum value of the knob depends on the effect all are used; maximum value of the knob depends on the effect
?? - some strange numbers specific for each 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 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 set "effect model" and knobs fields to zeros. I haven't tried what

View file

@ -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.

60
mod.cpp Normal file
View file

@ -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;
}
}

184
mod.h Normal file
View file

@ -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

84
mod_defaults.h Normal file
View file

@ -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
};

View file

@ -7,15 +7,20 @@
#include "amp.h" #include "amp.h"
#include "reverb.h" #include "reverb.h"
#include "delay.h" #include "delay.h"
#include "mod.h"
#include "stomp.h"
#include "amp_defaults.h" #include "amp_defaults.h"
#include "reverb_defaults.h" #include "reverb_defaults.h"
#include "delay_defaults.h" #include "delay_defaults.h"
#include "mod_defaults.h"
#include "stomp_defaults.h"
Mustang::Mustang() Mustang::Mustang()
{ {
amp_hand = NULL; amp_hand = NULL;
curr_amp = NULL; curr_amp = NULL;
tuner_active = false;
// "apply efect" command // "apply efect" command
memset(execute, 0x00, LENGTH); memset(execute, 0x00, LENGTH);
@ -42,8 +47,6 @@ int Mustang::start_amp(void)
{ {
int ret, received; int ret, received;
unsigned char array[LENGTH]; unsigned char array[LENGTH];
unsigned char received_data[296][LENGTH], data[7][LENGTH];
memset(received_data, 0x00, 296*LENGTH);
if(amp_hand == NULL) 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, 0x01, array, LENGTH, &received, TMOUT);
libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT); libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT);
int i = 0, j = 0;
memset(array, 0x00, LENGTH); memset(array, 0x00, LENGTH);
array[0] = 0xff; array[0] = 0xff;
array[1] = 0xc1; array[1] = 0xc1;
@ -116,6 +117,20 @@ int Mustang::start_amp(void)
// Request parameter dump from amplifier // Request parameter dump from amplifier
libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT); 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 // Count probably varies by model. Brute-force flush appears to create problems
// so we'll need to get this right case by case. // so we'll need to get this right case by case.
for(i = 0; i < 210; i++) for(i = 0; i < 210; i++)
@ -139,10 +154,11 @@ int Mustang::start_amp(void)
updateAmpObj(); updateAmpObj();
updateReverbObj(); updateReverbObj();
updateDelayObj(); updateDelayObj();
updateModObj();
return 0; updateStompObj();
} }
int Mustang::stop_amp() int Mustang::stop_amp()
{ {
int ret; int ret;
@ -173,10 +189,51 @@ int Mustang::stop_amp()
return 0; 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) { void Mustang::updateAmpObj(void) {
int curr = curr_state[AMP_STATE][MODEL]; int curr = curr_state[AMP_STATE][MODEL];
switch (curr) { switch (curr) {
case 0:
break;
case F57_DELUXE_ID: case F57_DELUXE_ID:
case F57_CHAMP_ID: case F57_CHAMP_ID:
case F65_DELUXE_ID: case F65_DELUXE_ID:
@ -222,8 +279,18 @@ void Mustang::updateAmpObj(void) {
void Mustang::updateReverbObj(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]; int curr = curr_state[DELAY_STATE][MODEL];
switch (curr) { switch (curr) {
case 0:
break;
case MONO_DLY_ID: case MONO_DLY_ID:
delete curr_delay; delete curr_delay;
curr_delay = new MonoDelayCC(this); 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) int Mustang::effect_toggle(int cc, int value)
{ {
if ( tuner_active ) return 0;
int ret, received; int ret, received;
unsigned char array[LENGTH]; unsigned char array[LENGTH];
@ -314,12 +490,17 @@ int Mustang::effect_toggle(int cc, int value)
} }
int Mustang::setAmp( int ord ) { int Mustang::setAmp( int ord ) {
if ( tuner_active ) return 0;
int ret, received; int ret, received;
unsigned char scratch[LENGTH]; unsigned char scratch[LENGTH];
unsigned char *array; unsigned char *array;
switch (ord) { switch (ord) {
case 0:
array = amp_none;
break;
case 1: case 1:
array = f57_deluxe; array = f57_deluxe;
break; break;
@ -373,30 +554,35 @@ int Mustang::setAmp( int ord ) {
updateAmpObj(); updateAmpObj();
// Setup USB gain // Setup USB gain
memset(scratch, 0x00, LENGTH); // memset(scratch, 0x00, LENGTH);
scratch[0] = 0x1c; // scratch[0] = 0x1c;
scratch[1] = 0x03; // scratch[1] = 0x03;
scratch[2] = 0x0d; // scratch[2] = 0x0d;
scratch[6] = 0x01; // scratch[6] = 0x01;
scratch[7] = 0x01; // scratch[7] = 0x01;
scratch[16] = 0x80; // scratch[16] = 0x80;
ret = libusb_interrupt_transfer(amp_hand, 0x01, 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); // libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT);
ret = libusb_interrupt_transfer(amp_hand, 0x01, execute, LENGTH, &received, TMOUT); // ret = libusb_interrupt_transfer(amp_hand, 0x01, execute, LENGTH, &received, TMOUT);
libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT); // libusb_interrupt_transfer(amp_hand, 0x81, scratch, LENGTH, &received, TMOUT);
return ret; return ret;
} }
int Mustang::setReverb( int ord ) { int Mustang::setReverb( int ord ) {
if ( tuner_active ) return 0;
int ret, received; int ret, received;
unsigned char scratch[LENGTH]; unsigned char scratch[LENGTH];
unsigned char *array; unsigned char *array;
switch (ord) { switch (ord) {
case 0:
array = reverb_none;
break;
case 1: case 1:
array = small_hall; array = small_hall;
break; break;
@ -449,12 +635,17 @@ int Mustang::setReverb( int ord ) {
} }
int Mustang::setDelay( int ord ) { int Mustang::setDelay( int ord ) {
if ( tuner_active ) return 0;
int ret, received; int ret, received;
unsigned char scratch[LENGTH]; unsigned char scratch[LENGTH];
unsigned char *array; unsigned char *array;
switch (ord) { switch (ord) {
case 0:
array = delay_none;
break;
case 1: case 1:
array = mono_delay; array = mono_delay;
break; break;
@ -503,8 +694,130 @@ int Mustang::setDelay( int ord ) {
return ret; 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) int Mustang::save_on_amp(char *name, int slot)
{ {
if ( tuner_active ) return 0;
int ret, received; int ret, received;
unsigned char array[LENGTH]; 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 ) { int Mustang::continuous_control( const Mustang::Cmd & cmd ) {
if ( tuner_active ) return 0;
int ret, received; int ret, received;
unsigned char array[LENGTH]; unsigned char array[LENGTH];
@ -563,6 +878,8 @@ int Mustang::continuous_control( const Mustang::Cmd & cmd ) {
int Mustang::discrete_control( const Mustang::Cmd & cmd ) { int Mustang::discrete_control( const Mustang::Cmd & cmd ) {
if ( tuner_active ) return 0;
int ret, received; int ret, received;
unsigned char array[LENGTH]; unsigned char array[LENGTH];
@ -589,6 +906,8 @@ int Mustang::discrete_control( const Mustang::Cmd & cmd ) {
int Mustang::load_memory_bank( int slot ) int Mustang::load_memory_bank( int slot )
{ {
if ( tuner_active ) return 0;
int ret, received; int ret, received;
unsigned char array[LENGTH], data[7][LENGTH]; unsigned char array[LENGTH], data[7][LENGTH];
@ -604,10 +923,15 @@ int Mustang::load_memory_bank( int slot )
// Mustang III has nine responses // Mustang III has nine responses
for(int i=0; i < 9; i++) { for(int i=0; i < 9; i++) {
libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT); libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT);
if(i < 7) int dsp = array[2];
memcpy(curr_state[i], array, LENGTH); if ( dsp >= 4 && dsp <= 9 )
memcpy(curr_state[dsp - 4], array, LENGTH);
} }
updateAmpObj(); updateAmpObj();
updateReverbObj();
updateDelayObj();
updateModObj();
updateStompObj();
return ret; return ret;
} }

View file

@ -140,16 +140,41 @@
#define TAPE_DLY_ID 0x2b #define TAPE_DLY_ID 0x2b
#define ST_TAPE_DLY_ID 0x2a #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 AmpCC;
class ReverbCC; class ReverbCC;
class DelayCC; class DelayCC;
class ModCC;
class StompCC;
class Mustang { class Mustang {
friend class AmpCC; friend class AmpCC;
friend class ReverbCC; friend class ReverbCC;
friend class DelayCC; friend class DelayCC;
friend class ModCC;
friend class StompCC;
public: public:
Mustang(); Mustang();
@ -161,6 +186,10 @@ public:
int setAmp( int ord ); int setAmp( int ord );
int setReverb( int ord ); int setReverb( int ord );
int setDelay( 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 save_on_amp(char *, int);
int load_memory_bank(int); int load_memory_bank(int);
@ -171,6 +200,8 @@ public:
AmpCC * getAmp( void ) { return curr_amp;} AmpCC * getAmp( void ) { return curr_amp;}
ReverbCC * getReverb( void ) { return curr_reverb;} ReverbCC * getReverb( void ) { return curr_reverb;}
DelayCC * getDelay( void ) { return curr_delay;} DelayCC * getDelay( void ) { return curr_delay;}
ModCC * getMod( void ) { return curr_mod;}
StompCC * getStomp( void ) { return curr_stomp;}
struct Cmd { struct Cmd {
int state_index; int state_index;
@ -208,16 +239,24 @@ private:
// //
unsigned char curr_state[7][LENGTH]; unsigned char curr_state[7][LENGTH];
bool tuner_active;
AmpCC * curr_amp; AmpCC * curr_amp;
ReverbCC * curr_reverb; ReverbCC * curr_reverb;
DelayCC * curr_delay; DelayCC * curr_delay;
ModCC * curr_mod;
StompCC * curr_stomp;
int continuous_control( const Mustang::Cmd & cmd ); int continuous_control( const Mustang::Cmd & cmd );
int discrete_control( const Mustang::Cmd & cmd ); int discrete_control( const Mustang::Cmd & cmd );
void handle_parm_dump(void);
void updateAmpObj(void); void updateAmpObj(void);
void updateReverbObj(void); void updateReverbObj(void);
void updateDelayObj(void); void updateDelayObj(void);
void updateModObj(void);
void updateStompObj(void);
}; };
#endif // MUSTANG_H #endif // MUSTANG_H

View file

@ -8,7 +8,8 @@
#include "amp.h" #include "amp.h"
#include "reverb.h" #include "reverb.h"
#include "delay.h" #include "delay.h"
#include "mod.h"
#include "stomp.h"
static Mustang mustang; static Mustang mustang;
@ -48,10 +49,45 @@ void message_action( double deltatime, std::vector< unsigned char > *message, vo
int cc = (*message)[1]; int cc = (*message)[1];
int value = (*message)[2]; 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 // Effects on/off
if ( cc >= 23 && cc <= 26 ) { else if ( cc >= 23 && cc <= 26 ) {
rc = mustang.effect_toggle( cc, value ); 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 // Set delay model
else if ( cc == 48 ) { else if ( cc == 48 ) {
rc = mustang.setDelay( value ); rc = mustang.setDelay( value );

View file

@ -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 );
}

View file

@ -19,15 +19,28 @@ public:
private: private:
// Level // Level
int cc59( int value ); int cc59( int value ) { return continuous_control( 0x00, 0x00, 0x0b, value );}
// Decay // Decay
int cc60( int value ); int cc60( int value ) { return continuous_control( 0x01, 0x01, 0x0b, value );}
// Dwell // Dwell
int cc61( int value ); int cc61( int value ) { return continuous_control( 0x02, 0x02, 0x0b, value );}
// Diffusion // Diffusion
int cc62( int value ); int cc62( int value ) { return continuous_control( 0x03, 0x03, 0x0b, value );}
// Tone // 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 #endif

View file

@ -2,6 +2,13 @@
// //
// This header is auto-generated from decoded pcap capture. // 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[] = { static unsigned char small_hall[] = {
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x24, 0x00, 0x05, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

60
stomp.cpp Normal file
View file

@ -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;
}
}

146
stomp.h Normal file
View file

@ -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

56
stomp_defaults.h Normal file
View file

@ -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
};