Implement Delay CC
This commit is contained in:
parent
1130fceea5
commit
6638fc5bf3
11 changed files with 720 additions and 140 deletions
|
|
@ -27,6 +27,7 @@ implemented:
|
|||
+ EFX bypass (on/off)
|
||||
+ Amp CC messages (except for on/off)
|
||||
+ Reverb CC messages
|
||||
+ Delay CC messages
|
||||
|
||||
I'm using WinPCAP and tshark to snoop communication and plan to
|
||||
implement all features accessible from the Fender FUSE application.
|
||||
|
|
|
|||
58
amp.cpp
58
amp.cpp
|
|
@ -3,13 +3,29 @@
|
|||
#include "mustang.h"
|
||||
|
||||
int
|
||||
AmpCC::control_common1( int parm, int bucket, int value ) {
|
||||
return amp->control_common1( parm, bucket, value );
|
||||
AmpCC::continuous_control( int parm5, int parm6, int parm7, int value ) {
|
||||
Mustang::Cmd cmd;
|
||||
cmd.state_index = AMP_STATE;
|
||||
cmd.parm2 = 0x02;
|
||||
cmd.parm5 = parm5;
|
||||
cmd.parm6 = parm6;
|
||||
cmd.parm7 = parm7;
|
||||
cmd.value = value;
|
||||
|
||||
return amp->continuous_control( cmd );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC::control_common2( int parm, int bucket, int value ) {
|
||||
return amp->control_common2( parm, bucket, value );
|
||||
AmpCC::discrete_control( int parm5, int parm6, int parm7, int value ) {
|
||||
Mustang::Cmd cmd;
|
||||
cmd.state_index = AMP_STATE;
|
||||
cmd.parm2 = 0x02;
|
||||
cmd.parm5 = parm5;
|
||||
cmd.parm6 = parm6;
|
||||
cmd.parm7 = parm7;
|
||||
cmd.value = value;
|
||||
|
||||
return amp->discrete_control( cmd );
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -68,96 +84,96 @@ AmpCC::dispatch( int cc, int value ) {
|
|||
|
||||
int
|
||||
AmpCC::cc69( int value ) {
|
||||
return control_common1( 0x01, 0x0c, value );
|
||||
return continuous_control( 0x01, 0x01, 0x0c, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC::cc70( int value ) {
|
||||
return control_common1( 0x00, 0x0c, value );
|
||||
return continuous_control( 0x00, 0x00, 0x0c, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC::cc71( int value ) {
|
||||
return control_common1( 0x04, 0x0c, value );
|
||||
return continuous_control( 0x04, 0x04, 0x0c, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC::cc72( int value ) {
|
||||
return control_common1( 0x05, 0x0c, value );
|
||||
return continuous_control( 0x05, 0x05, 0x0c, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC::cc73( int value ) {
|
||||
return control_common1( 0x06, 0x0c, value );
|
||||
return continuous_control( 0x06, 0x06, 0x0c, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC::cc74( int value ) {
|
||||
if ( value > 2 ) return 0;
|
||||
return control_common2( 0x13, 0x8f, value );
|
||||
return discrete_control( 0x13, 0x13, 0x8f, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC::cc75( int value ) {
|
||||
return control_common1( 0x0a, 0x0d, value );
|
||||
return continuous_control( 0x0a, 0x0a, 0x0d, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC::cc76( int value ) {
|
||||
if ( value > 4 ) return 0;
|
||||
return control_common2( 0x0f, 0x90, value );
|
||||
return discrete_control( 0x0f, 0x0f, 0x90, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC::cc77( int value ) {
|
||||
if ( value < 1 || value > 12 ) return 0;
|
||||
return control_common2( 0x11, 0x8e, value );
|
||||
return discrete_control( 0x11, 0x11, 0x8e, value );
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
AmpCC1::cc78( int value ) {
|
||||
return control_common1( 0x07, 0x0c, value );
|
||||
return continuous_control( 0x07, 0x07, 0x0c, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC1::cc79( int value ) {
|
||||
return control_common1( 0x02, 0x0c, value );
|
||||
return continuous_control( 0x02, 0x02, 0x0c, value );
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
AmpCC2::cc78( int value ) {
|
||||
return control_common1( 0x02, 0x0c, value );
|
||||
return continuous_control( 0x02, 0x02, 0x0c, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC2::cc79( int value ) {
|
||||
return control_common1( 0x03, 0x0c, value );
|
||||
return continuous_control( 0x03, 0x03, 0x0c, value );
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
AmpCC3::cc78( int value ) {
|
||||
return control_common1( 0x07, 0x0c, value );
|
||||
return continuous_control( 0x07, 0x07, 0x0c, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC3::cc79( int value ) {
|
||||
return control_common1( 0x03, 0x0c, value );
|
||||
return continuous_control( 0x03, 0x03, 0x0c, value );
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
AmpCC4::cc78( int value ) {
|
||||
return control_common1( 0x07, 0x0c, value );
|
||||
return continuous_control( 0x07, 0x07, 0x0c, value );
|
||||
}
|
||||
|
||||
int
|
||||
AmpCC4::cc79( int value ) {
|
||||
return control_common1( 0x03, 0x0c, value );
|
||||
return continuous_control( 0x03, 0x03, 0x0c, value );
|
||||
}
|
||||
|
|
|
|||
4
amp.h
4
amp.h
|
|
@ -18,8 +18,8 @@ protected:
|
|||
|
||||
// Only base class is friend of Mustang, so forward calls from
|
||||
// derived classes through these methods.
|
||||
int control_common1( int parm, int bucket, int value );
|
||||
int control_common2( int parm, int bucket, int value );
|
||||
int continuous_control( int parm5, int parm6, int parm7, int value );
|
||||
int discrete_control( int parm5, int parm6, int parm7, int value );
|
||||
|
||||
public:
|
||||
AmpCC( Mustang * theAmp ) : amp(theAmp) {}
|
||||
|
|
|
|||
229
delay.cpp
Normal file
229
delay.cpp
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
|
||||
#include "delay.h"
|
||||
#include "mustang.h"
|
||||
|
||||
int
|
||||
DelayCC::continuous_control( int parm5, int parm6, int parm7, int value ) {
|
||||
Mustang::Cmd cmd;
|
||||
cmd.state_index = DELAY_STATE;
|
||||
cmd.parm2 = 0x05;
|
||||
cmd.parm5 = parm5;
|
||||
cmd.parm6 = parm6;
|
||||
cmd.parm7 = parm7;
|
||||
cmd.value = value;
|
||||
|
||||
return amp->continuous_control( cmd );
|
||||
}
|
||||
|
||||
int
|
||||
DelayCC::discrete_control( int parm5, int parm6, int parm7, int value ) {
|
||||
Mustang::Cmd cmd;
|
||||
cmd.state_index = DELAY_STATE;
|
||||
cmd.parm2 = 0x05;
|
||||
cmd.parm5 = parm5;
|
||||
cmd.parm6 = parm6;
|
||||
cmd.parm7 = parm7;
|
||||
cmd.value = value;
|
||||
|
||||
return amp->discrete_control( cmd );
|
||||
}
|
||||
|
||||
int
|
||||
DelayCC::dispatch( int cc, int value ) {
|
||||
|
||||
switch ( cc ) {
|
||||
case 49:
|
||||
// Level
|
||||
return cc49( value );
|
||||
break;
|
||||
case 50:
|
||||
// Delay Time
|
||||
return cc50( value );
|
||||
break;
|
||||
case 51:
|
||||
// Feedback / FFdbk
|
||||
return cc51( value );
|
||||
break;
|
||||
case 52:
|
||||
// Brightness / Frequency / Release / RFdbk / Flutter
|
||||
return cc52( value );
|
||||
break;
|
||||
case 53:
|
||||
// Attenuation / Resonance / Mode / Stereo / Threshold
|
||||
// Tone / Brightness / Separation
|
||||
return cc53( value );
|
||||
break;
|
||||
case 54:
|
||||
// Input Level / Stereo / Brightness
|
||||
return cc54( value );
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
144
delay.h
Normal file
144
delay.h
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
// -*-c++-*-
|
||||
|
||||
#ifndef _DELAY_H
|
||||
#define _DELAY_H
|
||||
|
||||
class Mustang;
|
||||
|
||||
class DelayCC {
|
||||
|
||||
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:
|
||||
DelayCC( Mustang * theAmp ) : amp(theAmp) {}
|
||||
|
||||
int dispatch( int cc, int value );
|
||||
|
||||
private:
|
||||
// Level
|
||||
virtual int cc49( int value );
|
||||
// Delay Time
|
||||
virtual int cc50( int 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;}
|
||||
};
|
||||
|
||||
|
||||
class MonoDelayCC : public DelayCC {
|
||||
public:
|
||||
MonoDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
|
||||
private:
|
||||
// Feedback
|
||||
virtual int cc51( int value );
|
||||
// Brightness
|
||||
virtual int cc52( int value );
|
||||
// Attenuation
|
||||
virtual int cc53( int value );
|
||||
};
|
||||
|
||||
|
||||
class EchoFilterCC : public DelayCC {
|
||||
public:
|
||||
EchoFilterCC( Mustang * theAmp ) : DelayCC(theAmp) {}
|
||||
private:
|
||||
// Feedback
|
||||
virtual int cc51( int value );
|
||||
// Frequency
|
||||
virtual int cc52( int value );
|
||||
// Resonance
|
||||
virtual int cc53( int value );
|
||||
// Input Level
|
||||
virtual int cc54( int value );
|
||||
};
|
||||
|
||||
|
||||
class MultitapDelayCC : public DelayCC {
|
||||
public:
|
||||
MultitapDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
|
||||
private:
|
||||
// Feedback
|
||||
virtual int cc51( int value );
|
||||
// Brightness
|
||||
virtual int cc52( int value );
|
||||
// Mode
|
||||
virtual int cc53( int value );
|
||||
};
|
||||
|
||||
|
||||
class PingPongDelayCC : public DelayCC {
|
||||
public:
|
||||
PingPongDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
|
||||
private:
|
||||
// Feedback
|
||||
virtual int cc51( int value );
|
||||
// Brightness
|
||||
virtual int cc52( int value );
|
||||
// Stereo
|
||||
virtual int cc53( int value );
|
||||
};
|
||||
|
||||
|
||||
class DuckingDelayCC : public DelayCC {
|
||||
public:
|
||||
DuckingDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
|
||||
private:
|
||||
// Feedback
|
||||
virtual int cc51( int value );
|
||||
// Release
|
||||
virtual int cc52( int value );
|
||||
// Threshold
|
||||
virtual int cc53( int value );
|
||||
};
|
||||
|
||||
|
||||
class ReverseDelayCC : public DelayCC {
|
||||
public:
|
||||
ReverseDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
|
||||
private:
|
||||
// FFdbk
|
||||
virtual int cc51( int value );
|
||||
// RFdbk
|
||||
virtual int cc52( int value );
|
||||
// Tone
|
||||
virtual int cc53( int value );
|
||||
};
|
||||
|
||||
|
||||
class TapeDelayCC : public DelayCC {
|
||||
public:
|
||||
TapeDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
|
||||
private:
|
||||
// Feedback
|
||||
virtual int cc51( int value );
|
||||
// Flutter
|
||||
virtual int cc52( int value );
|
||||
// Brightness
|
||||
virtual int cc53( int value );
|
||||
// Stereo
|
||||
virtual int cc54( int value );
|
||||
};
|
||||
|
||||
|
||||
class StereoTapeDelayCC : public DelayCC {
|
||||
public:
|
||||
StereoTapeDelayCC( Mustang * theAmp ) : DelayCC(theAmp) {}
|
||||
private:
|
||||
// Feedback
|
||||
virtual int cc51( int value );
|
||||
// Flutter
|
||||
virtual int cc52( int value );
|
||||
// Separation
|
||||
virtual int cc53( int value );
|
||||
// Brightness
|
||||
virtual int cc54( int value );
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
67
delay_defaults.h
Normal file
67
delay_defaults.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Default settings for Mustang III (original) delay models
|
||||
//
|
||||
// This header is auto-generated from decoded pcap capture.
|
||||
|
||||
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,
|
||||
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 mono_echo_filter[] = {
|
||||
0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x43, 0x00, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 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
|
||||
};
|
||||
|
||||
static unsigned char stereo_echo_filter[] = {
|
||||
0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x00, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0xb3, 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
|
||||
};
|
||||
|
||||
static unsigned char multitap_delay[] = {
|
||||
0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x44, 0x00, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0x80, 0x66, 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 ping_pong_delay[] = {
|
||||
0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x45, 0x00, 0x06, 0x02, 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 ducking_delay[] = {
|
||||
0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x15, 0x00, 0x06, 0x02, 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 reverse_delay[] = {
|
||||
0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x46, 0x00, 0x06, 0x02, 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 tape_delay[] = {
|
||||
0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2b, 0x00, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7d, 0x1c, 0x00, 0x63, 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 stereo_tape_delay[] = {
|
||||
0x1c, 0x03, 0x08, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x2a, 0x00, 0x06, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7d, 0x88, 0x1c, 0x63, 0xff, 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
|
||||
};
|
||||
|
||||
245
mustang.cpp
245
mustang.cpp
|
|
@ -3,8 +3,14 @@
|
|||
#include <cmath>
|
||||
|
||||
#include "magic.h"
|
||||
|
||||
#include "amp.h"
|
||||
#include "reverb.h"
|
||||
#include "delay.h"
|
||||
|
||||
#include "amp_defaults.h"
|
||||
#include "reverb_defaults.h"
|
||||
#include "delay_defaults.h"
|
||||
|
||||
Mustang::Mustang()
|
||||
{
|
||||
|
|
@ -130,8 +136,9 @@ int Mustang::start_amp(void)
|
|||
// Current preset name, amp settings, efx settings
|
||||
for(j = 0; j < 7; i++, j++) memcpy(curr_state[j], received_data[i], LENGTH);
|
||||
|
||||
updateAmp();
|
||||
curr_reverb = new ReverbCC( this );
|
||||
updateAmpObj();
|
||||
updateReverbObj();
|
||||
updateDelayObj();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -166,9 +173,9 @@ int Mustang::stop_amp()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Mustang::updateAmp(void) {
|
||||
void Mustang::updateAmpObj(void) {
|
||||
|
||||
int curr = curr_state[AMP_STATE][AMPLIFIER];
|
||||
int curr = curr_state[AMP_STATE][MODEL];
|
||||
switch (curr) {
|
||||
case F57_DELUXE_ID:
|
||||
case F57_CHAMP_ID:
|
||||
|
|
@ -214,8 +221,62 @@ void Mustang::updateAmp(void) {
|
|||
}
|
||||
|
||||
|
||||
void Mustang::updateReverb(void) {
|
||||
// No-op for now
|
||||
void Mustang::updateReverbObj(void) {
|
||||
delete curr_reverb;
|
||||
curr_reverb = new ReverbCC( this );
|
||||
}
|
||||
|
||||
|
||||
void Mustang::updateDelayObj(void) {
|
||||
|
||||
int curr = curr_state[DELAY_STATE][MODEL];
|
||||
|
||||
switch (curr) {
|
||||
case MONO_DLY_ID:
|
||||
delete curr_delay;
|
||||
curr_delay = new MonoDelayCC(this);
|
||||
break;
|
||||
|
||||
case MONO_FILTER_ID:
|
||||
case ST_FILTER_ID:
|
||||
delete curr_delay;
|
||||
curr_delay = new EchoFilterCC(this);
|
||||
break;
|
||||
|
||||
case MTAP_DLY_ID:
|
||||
delete curr_delay;
|
||||
curr_delay = new MultitapDelayCC(this);
|
||||
break;
|
||||
|
||||
case PONG_DLY_ID:
|
||||
delete curr_delay;
|
||||
curr_delay = new PingPongDelayCC(this);
|
||||
break;
|
||||
|
||||
case DUCK_DLY_ID:
|
||||
delete curr_delay;
|
||||
curr_delay = new DuckingDelayCC(this);
|
||||
break;
|
||||
|
||||
case REVERSE_DLY_ID:
|
||||
delete curr_delay;
|
||||
curr_delay = new ReverseDelayCC(this);
|
||||
break;
|
||||
|
||||
case TAPE_DLY_ID:
|
||||
delete curr_delay;
|
||||
curr_delay = new TapeDelayCC(this);
|
||||
break;
|
||||
|
||||
case ST_TAPE_DLY_ID:
|
||||
delete curr_delay;
|
||||
curr_delay = new StereoTapeDelayCC(this);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf( stderr, "W - Delay id %x not supported yet\n", curr );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -252,69 +313,6 @@ int Mustang::effect_toggle(int cc, int value)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int Mustang::control_common1(int parm, int bucket, int value)
|
||||
{
|
||||
static unsigned short previous = 0;
|
||||
|
||||
int ret, received;
|
||||
unsigned char array[LENGTH];
|
||||
|
||||
memset(array, 0x00, LENGTH);
|
||||
array[0] = 0x05;
|
||||
array[1] = 0xc3;
|
||||
array[2] = 0x02;
|
||||
array[3] = curr_state[AMP_STATE][AMPLIFIER];
|
||||
// target parameter
|
||||
array[5] = array[6] = parm;
|
||||
// bucket
|
||||
array[7] = bucket;
|
||||
|
||||
// Scale and clamp to valid index range
|
||||
int index = (int) ceil( (double)value * magic_scale_factor );
|
||||
if ( index > magic_max ) index = magic_max;
|
||||
|
||||
unsigned short eff_value = magic_values[index];
|
||||
|
||||
// Try to prevent extra traffic if successive calls resolve to the same
|
||||
// slot.
|
||||
if (eff_value == previous) return 0;
|
||||
previous = eff_value;
|
||||
|
||||
array[9] = eff_value & 0xff;
|
||||
array[10] = (eff_value >> 8) & 0xff;
|
||||
|
||||
// Send command and flush reply
|
||||
ret = libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT);
|
||||
libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int Mustang::control_common2(int parm, int bucket, int value)
|
||||
{
|
||||
int ret, received;
|
||||
unsigned char array[LENGTH];
|
||||
|
||||
memset(array, 0x00, LENGTH);
|
||||
array[0] = 0x05;
|
||||
array[1] = 0xc3;
|
||||
array[2] = 0x02;
|
||||
array[3] = curr_state[AMP_STATE][AMPLIFIER];
|
||||
// target parameter
|
||||
array[5] = array[6] = parm;
|
||||
// bucket
|
||||
array[7] = bucket;
|
||||
// value
|
||||
array[9] = value;
|
||||
|
||||
// Send command and flush reply
|
||||
ret = libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT);
|
||||
libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Mustang::setAmp( int ord ) {
|
||||
int ret, received;
|
||||
unsigned char scratch[LENGTH];
|
||||
|
|
@ -372,7 +370,7 @@ int Mustang::setAmp( int ord ) {
|
|||
|
||||
// Copy to current setting store
|
||||
memcpy(curr_state[AMP_STATE], array, LENGTH);
|
||||
updateAmp();
|
||||
updateAmpObj();
|
||||
|
||||
// Setup USB gain
|
||||
memset(scratch, 0x00, LENGTH);
|
||||
|
|
@ -445,7 +443,62 @@ int Mustang::setReverb( int ord ) {
|
|||
|
||||
// Copy to current setting store
|
||||
memcpy(curr_state[REVERB_STATE], array, LENGTH);
|
||||
updateReverb();
|
||||
updateReverbObj();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Mustang::setDelay( int ord ) {
|
||||
int ret, received;
|
||||
unsigned char scratch[LENGTH];
|
||||
|
||||
unsigned char *array;
|
||||
|
||||
switch (ord) {
|
||||
case 1:
|
||||
array = mono_delay;
|
||||
break;
|
||||
case 2:
|
||||
array = mono_echo_filter;
|
||||
break;
|
||||
case 3:
|
||||
array = stereo_echo_filter;
|
||||
break;
|
||||
case 4:
|
||||
array = multitap_delay;
|
||||
break;
|
||||
case 5:
|
||||
array = ping_pong_delay;
|
||||
break;
|
||||
case 6:
|
||||
array = ducking_delay;
|
||||
break;
|
||||
case 7:
|
||||
array = reverse_delay;
|
||||
break;
|
||||
case 8:
|
||||
array = tape_delay;
|
||||
break;
|
||||
case 9:
|
||||
array = stereo_tape_delay;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "W - Delay select %d not supported\n", ord );
|
||||
return 0;
|
||||
}
|
||||
|
||||
array[FXSLOT] = curr_state[DELAY_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[DELAY_STATE], array, LENGTH);
|
||||
updateDelayObj();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -477,34 +530,27 @@ int Mustang::save_on_amp(char *name, int slot)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int Mustang::efx_common1(int parm, int bucket, int type, int value)
|
||||
{
|
||||
static unsigned short previous = 0;
|
||||
|
||||
int Mustang::continuous_control( const Mustang::Cmd & cmd ) {
|
||||
int ret, received;
|
||||
unsigned char array[LENGTH];
|
||||
|
||||
memset(array, 0x00, LENGTH);
|
||||
array[0] = 0x05;
|
||||
array[1] = 0xc3;
|
||||
array[2] = 0x06;
|
||||
array[3] = curr_state[type][EFFECT];
|
||||
array[2] = cmd.parm2;
|
||||
array[3] = curr_state[cmd.state_index][MODEL];
|
||||
|
||||
// target parameter
|
||||
array[5] = array[6] = parm;
|
||||
// bucket
|
||||
array[7] = bucket;
|
||||
array[5] = cmd.parm5;
|
||||
array[6] = cmd.parm6;
|
||||
array[7] = cmd.parm7;
|
||||
|
||||
// Scale and clamp to valid index range
|
||||
int index = (int) ceil( (double)value * magic_scale_factor );
|
||||
int index = (int) ceil( (double)cmd.value * magic_scale_factor );
|
||||
if ( index > magic_max ) index = magic_max;
|
||||
|
||||
unsigned short eff_value = magic_values[index];
|
||||
|
||||
// Try to prevent extra traffic if successive calls resolve to the same
|
||||
// slot.
|
||||
if (eff_value == previous) return 0;
|
||||
previous = eff_value;
|
||||
|
||||
array[9] = eff_value & 0xff;
|
||||
array[10] = (eff_value >> 8) & 0xff;
|
||||
|
||||
|
|
@ -516,6 +562,31 @@ int Mustang::efx_common1(int parm, int bucket, int type, int value)
|
|||
}
|
||||
|
||||
|
||||
int Mustang::discrete_control( const Mustang::Cmd & cmd ) {
|
||||
int ret, received;
|
||||
unsigned char array[LENGTH];
|
||||
|
||||
memset(array, 0x00, LENGTH);
|
||||
array[0] = 0x05;
|
||||
array[1] = 0xc3;
|
||||
array[2] = cmd.parm2;
|
||||
array[3] = curr_state[cmd.state_index][MODEL];
|
||||
|
||||
array[5] = cmd.parm5;
|
||||
array[6] = cmd.parm6;
|
||||
array[7] = cmd.parm7;
|
||||
|
||||
// Discrete value
|
||||
array[9] = cmd.value;
|
||||
|
||||
// Send command and flush reply
|
||||
ret = libusb_interrupt_transfer(amp_hand, 0x01, array, LENGTH, &received, TMOUT);
|
||||
libusb_interrupt_transfer(amp_hand, 0x81, array, LENGTH, &received, TMOUT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int Mustang::load_memory_bank( int slot )
|
||||
{
|
||||
int ret, received;
|
||||
|
|
@ -536,7 +607,7 @@ int Mustang::load_memory_bank( int slot )
|
|||
if(i < 7)
|
||||
memcpy(curr_state[i], array, LENGTH);
|
||||
}
|
||||
updateAmp();
|
||||
updateAmpObj();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
52
mustang.h
52
mustang.h
|
|
@ -9,8 +9,6 @@
|
|||
#include <libusb-1.0/libusb.h>
|
||||
#include "effects_enum.h"
|
||||
#include "data_structs.h"
|
||||
#include "amp.h"
|
||||
#include "reverb.h"
|
||||
|
||||
// amp's VID and PID
|
||||
#define USB_VID 0x1ed8
|
||||
|
|
@ -74,6 +72,9 @@
|
|||
#define FAMILY 2
|
||||
#define ACTIVE_INVERT 3
|
||||
|
||||
// Offset to current device model for any state structure
|
||||
#define MODEL 16
|
||||
|
||||
// Index into current state structure
|
||||
#define PRESET_NAME 0
|
||||
#define AMP_STATE 1
|
||||
|
|
@ -96,7 +97,7 @@
|
|||
#define DELAY_FAM 5
|
||||
#define REVERB_FAM 6
|
||||
|
||||
// Amp id values
|
||||
// Amp model id values
|
||||
#define F57_DELUXE_ID 0x67
|
||||
#define F59_BASSMAN_ID 0x64
|
||||
#define F57_CHAMP_ID 0x7c
|
||||
|
|
@ -116,7 +117,7 @@
|
|||
#define BRIT_WATT_ID 0xff
|
||||
#define BRIT_COLOR_ID 0xfc
|
||||
|
||||
// Reverb id values
|
||||
// Reverb model id values
|
||||
#define SM_HALL_ID 0x24
|
||||
#define LG_HALL_ID 0x3a
|
||||
#define SM_ROOM_ID 0x26
|
||||
|
|
@ -128,9 +129,27 @@
|
|||
#define SPRING_63_ID 0x21
|
||||
#define SPRING_65_ID 0x0b
|
||||
|
||||
// Delay model id values
|
||||
#define MONO_DLY_ID 0x16
|
||||
#define MONO_FILTER_ID 0x43
|
||||
#define ST_FILTER_ID 0x48
|
||||
#define MTAP_DLY_ID 0x44
|
||||
#define PONG_DLY_ID 0x45
|
||||
#define DUCK_DLY_ID 0x15
|
||||
#define REVERSE_DLY_ID 0x46
|
||||
#define TAPE_DLY_ID 0x2b
|
||||
#define ST_TAPE_DLY_ID 0x2a
|
||||
|
||||
|
||||
class AmpCC;
|
||||
class ReverbCC;
|
||||
class DelayCC;
|
||||
|
||||
|
||||
class Mustang {
|
||||
friend class AmpCC;
|
||||
friend class ReverbCC;
|
||||
friend class DelayCC;
|
||||
|
||||
public:
|
||||
Mustang();
|
||||
|
|
@ -138,9 +157,10 @@ public:
|
|||
int start_amp(void); // initialize communication
|
||||
int stop_amp(void); // terminate communication
|
||||
int set_effect(struct fx_pedal_settings);
|
||||
int setAmp( int ord );
|
||||
|
||||
int setAmp( int ord );
|
||||
int setReverb( int ord );
|
||||
int setDelay( int ord );
|
||||
|
||||
int save_on_amp(char *, int);
|
||||
int load_memory_bank(int);
|
||||
|
|
@ -150,6 +170,16 @@ public:
|
|||
|
||||
AmpCC * getAmp( void ) { return curr_amp;}
|
||||
ReverbCC * getReverb( void ) { return curr_reverb;}
|
||||
DelayCC * getDelay( void ) { return curr_delay;}
|
||||
|
||||
struct Cmd {
|
||||
int state_index;
|
||||
int parm2;
|
||||
int parm5;
|
||||
int parm6;
|
||||
int parm7;
|
||||
int value;
|
||||
};
|
||||
|
||||
private:
|
||||
libusb_device_handle *amp_hand; // handle for USB communication
|
||||
|
|
@ -180,14 +210,14 @@ public:
|
|||
|
||||
AmpCC * curr_amp;
|
||||
ReverbCC * curr_reverb;
|
||||
DelayCC * curr_delay;
|
||||
|
||||
int control_common1(int parm, int bucket, int value);
|
||||
int control_common2(int parm, int bucket, int value);
|
||||
int continuous_control( const Mustang::Cmd & cmd );
|
||||
int discrete_control( const Mustang::Cmd & cmd );
|
||||
|
||||
int efx_common1(int parm, int bucket, int type, int value);
|
||||
|
||||
void updateAmp(void);
|
||||
void updateReverb(void);
|
||||
void updateAmpObj(void);
|
||||
void updateReverbObj(void);
|
||||
void updateDelayObj(void);
|
||||
};
|
||||
|
||||
#endif // MUSTANG_H
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@
|
|||
|
||||
#include "mustang.h"
|
||||
|
||||
#include "amp.h"
|
||||
#include "reverb.h"
|
||||
#include "delay.h"
|
||||
|
||||
|
||||
static Mustang mustang;
|
||||
|
||||
static int channel;
|
||||
|
|
@ -47,14 +52,23 @@ void message_action( double deltatime, std::vector< unsigned char > *message, vo
|
|||
if ( cc >= 23 && cc <= 26 ) {
|
||||
rc = mustang.effect_toggle( cc, value );
|
||||
}
|
||||
// Set delay model
|
||||
else if ( cc == 48 ) {
|
||||
rc = mustang.setDelay( value );
|
||||
}
|
||||
// Delay CC handler
|
||||
else if ( cc >= 49 && cc <= 54 ) {
|
||||
DelayCC *delayObj = mustang.getDelay();
|
||||
rc = delayObj->dispatch( cc, value );
|
||||
}
|
||||
// Set reverb model
|
||||
else if ( cc == 58 ) {
|
||||
rc = mustang.setReverb( value );
|
||||
}
|
||||
// Reverb CC handler
|
||||
else if ( cc >= 59 && cc <= 63 ) {
|
||||
ReverbCC *reverbModel = mustang.getReverb();
|
||||
rc = reverbModel->dispatch( cc, value );
|
||||
ReverbCC *reverbObj = mustang.getReverb();
|
||||
rc = reverbObj->dispatch( cc, value );
|
||||
}
|
||||
// Set amp model
|
||||
else if ( cc == 68 ) {
|
||||
|
|
@ -62,8 +76,8 @@ void message_action( double deltatime, std::vector< unsigned char > *message, vo
|
|||
}
|
||||
// Amp CC Handler
|
||||
else if ( cc >= 69 && cc <= 79 ) {
|
||||
AmpCC *ampModel = mustang.getAmp();
|
||||
rc = ampModel->dispatch( cc, value );
|
||||
AmpCC *ampObj = mustang.getAmp();
|
||||
rc = ampObj->dispatch( cc, value );
|
||||
}
|
||||
if ( rc ) {
|
||||
fprintf( stderr, "Error: CC#%d failed. RC = %d\n", cc, rc );
|
||||
|
|
|
|||
22
reverb.cpp
22
reverb.cpp
|
|
@ -3,8 +3,16 @@
|
|||
#include "mustang.h"
|
||||
|
||||
int
|
||||
ReverbCC::efx_common1(int parm, int bucket, int type, int value) {
|
||||
return amp->efx_common1( parm, bucket, type, value );
|
||||
ReverbCC::continuous_control( int parm5, int parm6, int parm7, int value ) {
|
||||
Mustang::Cmd cmd;
|
||||
cmd.state_index = REVERB_STATE;
|
||||
cmd.parm2 = 0x06;
|
||||
cmd.parm5 = parm5;
|
||||
cmd.parm6 = parm6;
|
||||
cmd.parm7 = parm7;
|
||||
cmd.value = value;
|
||||
|
||||
return amp->continuous_control( cmd );
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -39,26 +47,26 @@ ReverbCC::dispatch( int cc, int value ) {
|
|||
|
||||
int
|
||||
ReverbCC::cc59( int value ) {
|
||||
return efx_common1( 0x00, 0x0b, REVERB_STATE, value );
|
||||
return continuous_control( 0x00, 0x00, 0x0b, value );
|
||||
}
|
||||
|
||||
int
|
||||
ReverbCC::cc60( int value ) {
|
||||
return efx_common1( 0x01, 0x0b, REVERB_STATE, value );
|
||||
return continuous_control( 0x01, 0x01, 0x0b, value );
|
||||
}
|
||||
|
||||
int
|
||||
ReverbCC::cc61( int value ) {
|
||||
return efx_common1( 0x02, 0x0b, REVERB_STATE, value );
|
||||
return continuous_control( 0x02, 0x02, 0x0b, value );
|
||||
}
|
||||
|
||||
int
|
||||
ReverbCC::cc62( int value ) {
|
||||
return efx_common1( 0x03, 0x0b, REVERB_STATE, value );
|
||||
return continuous_control( 0x03, 0x03, 0x0b, value );
|
||||
}
|
||||
|
||||
int
|
||||
ReverbCC::cc63( int value ) {
|
||||
return efx_common1( 0x04, 0x0b, REVERB_STATE, value );
|
||||
return continuous_control( 0x04, 0x04, 0x0b, value );
|
||||
}
|
||||
|
||||
|
|
|
|||
2
reverb.h
2
reverb.h
|
|
@ -10,7 +10,7 @@ class ReverbCC {
|
|||
protected:
|
||||
Mustang * amp;
|
||||
|
||||
int efx_common1(int parm, int bucket, int type, int value);
|
||||
int continuous_control( int parm5, int parm6, int parm7, int value );
|
||||
|
||||
public:
|
||||
ReverbCC( Mustang * theAmp ) : amp(theAmp) {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue