Implement amp continuous controls

This commit is contained in:
hirsch 2016-06-22 12:04:59 -04:00
parent 53b1366f9b
commit e1e8305195
8 changed files with 787 additions and 811 deletions

99
amp.cpp Normal file
View file

@ -0,0 +1,99 @@
#include "amp.h"
#include "mustang.h"
int
AmpCC::cc69( int value ) {
return amp->control_common1( 0x01, 0x0c, value );
}
int
AmpCC::cc70( int value ) {
return amp->control_common1( 0x00, 0x0c, value );
}
int
AmpCC::cc71( int value ) {
return amp->control_common1( 0x04, 0x0c, value );
}
int
AmpCC::cc72( int value ) {
return amp->control_common1( 0x05, 0x0c, value );
}
int
AmpCC::cc73( int value ) {
return amp->control_common1( 0x06, 0x0c, value );
}
int
AmpCC::cc74( int value ) {
if ( value > 2 ) return 0;
return amp->control_common2( 0x13, 0x8f, value );
}
int
AmpCC::cc75( int value ) {
return amp->control_common1( 0x0a, 0x0d, value );
}
int
AmpCC::cc76( int value ) {
if ( value > 4 ) return 0;
return amp->control_common2( 0x0f, 0x90, value );
}
int
AmpCC::cc77( int value ) {
if ( value < 1 || value > 12 ) return 0;
return amp->control_common2( 0x11, 0x8e, value );
}
int
AmpCC1::cc78( int value ) {
return amp->control_common1( 0x07, 0x0c, value );
}
int
AmpCC1::cc79( int value ) {
return amp->control_common1( 0x02, 0x0c, value );
}
int
AmpCC2::cc78( int value ) {
return amp->control_common1( 0x02, 0x0c, value );
}
int
AmpCC2::cc79( int value ) {
return amp->control_common1( 0x03, 0x0c, value );
}
int
AmpCC3::cc78( int value ) {
return amp->control_common1( 0x07, 0x0c, value );
}
int
AmpCC3::cc79( int value ) {
return amp->control_common1( 0x03, 0x0c, value );
}
int
AmpCC4::cc78( int value ) {
return amp->control_common1( 0x07, 0x0c, value );
}
int
AmpCC4::cc79( int value ) {
return amp->control_common1( 0x03, 0x0c, value );
}

109
amp.h Normal file
View file

@ -0,0 +1,109 @@
// -*-c++-*-
#ifndef _AMPCC_H
#define _AMPCC_H
class Mustang;
// F57 Deluxe
// F57 Champ
// F65 Deluxe
// F65 Princeton
// F65 Twin
//
class AmpCC {
protected:
Mustang * amp;
public:
AmpCC( Mustang * theAmp ) : amp(theAmp) {}
// Gain
int cc69( int value );
// Ch. Volume
int cc70( int value );
// Treble
int cc71( int value );
// Mid
int cc72( int value );
// Bass
int cc73( int value );
// Sag
virtual int cc74( int value );
// Bias
virtual int cc75( int value );
// Noise Gate
int cc76( int value );
// Cabinet
int cc77( int value );
// Dummy in base class
virtual int cc78( int value ) { return 0;}
virtual int cc79( int value ) { return 0;}
};
// F59 Bassman
// British 70s
//
class AmpCC1 : public AmpCC {
public:
AmpCC1( Mustang * theAmp ) : AmpCC(theAmp) {}
// Presence
virtual int cc78( int value );
// Blend
virtual int cc79( int value );
};
// Fender Supersonic
//
class AmpCC2 : public AmpCC {
public:
AmpCC2( Mustang * theAmp ) : AmpCC(theAmp) {}
// Gain2
virtual int cc78( int value );
// Master Volume
virtual int cc79( int value );
};
// British 60s
//
class AmpCC3 : public AmpCC {
public:
AmpCC3( Mustang * theAmp ) : AmpCC(theAmp) {}
// Cut
virtual int cc78( int value );
// Master Volume
virtual int cc79( int value );
};
// British 80s
// American 90s
// Metal 2000
//
class AmpCC4 : public AmpCC {
public:
AmpCC4( Mustang * theAmp ) : AmpCC(theAmp) {}
// Presence
virtual int cc78( int value );
// Master Volume
virtual int cc79( int value );
};
// Studio Preamp
//
class AmpCC5 : public AmpCC {
public:
AmpCC5( Mustang * theAmp ) : AmpCC(theAmp) {}
virtual int cc78( int value ) { return 0;}
virtual int cc79( int value ) { return 0;}
};
#endif

88
amp_defaults.h Normal file
View file

@ -0,0 +1,88 @@
// Default settings for Mustang III (original) amp models
//
// This header is auto-generated from decoded pcap capture.
static unsigned char f57_deluxe[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0x99, 0x80, 0x80, 0xbe, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01, 0x01, 0x01, 0x00,
0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char f59_bassman[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0xa2, 0x80, 0x80, 0x80, 0x7a, 0xa2, 0x91, 0x80, 0x80, 0x80, 0x80, 0x02, 0x02, 0x02, 0x00,
0x00, 0x02, 0x02, 0x01, 0x00, 0x01, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char f57_champ[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0xb3, 0x00, 0xff, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0c, 0x0c, 0x0c, 0x00,
0x00, 0x05, 0x0c, 0x01, 0x00, 0x01, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char f65_deluxe[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0x71, 0x00, 0xff, 0x91, 0xcf, 0x38, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x03, 0x03, 0x00,
0x00, 0x03, 0x03, 0x01, 0x00, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char f65_princeton[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0x55, 0x00, 0xff, 0x99, 0xcc, 0x4c, 0x80, 0x80, 0x80, 0x80, 0x80, 0x04, 0x04, 0x04, 0x00,
0x00, 0x04, 0x04, 0x01, 0x00, 0x01, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char f65_twin[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0x55, 0x80, 0x63, 0xb3, 0xbb, 0xaa, 0x80, 0x80, 0x80, 0x80, 0x80, 0x05, 0x05, 0x05, 0x00,
0x00, 0x09, 0x05, 0x01, 0x00, 0x01, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char f_supersonic[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0xbb, 0x82, 0x55, 0x99, 0xa2, 0x99, 0x80, 0x80, 0x80, 0x80, 0x80, 0x06, 0x06, 0x06, 0x02,
0x00, 0x0c, 0x06, 0x01, 0x00, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char brit_60[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0xa2, 0x80, 0x63, 0x99, 0x80, 0xb0, 0x00, 0x80, 0x80, 0x80, 0x80, 0x07, 0x07, 0x07, 0x00,
0x00, 0x07, 0x07, 0x01, 0x00, 0x01, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char brit_70[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0xff, 0x80, 0x7d, 0xaa, 0x5b, 0xc4, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0b, 0x0b, 0x0b, 0x01,
0x00, 0x08, 0x0b, 0x01, 0x00, 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char brit_80[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0xff, 0x80, 0x7d, 0xaa, 0x5b, 0xc4, 0x80, 0x80, 0x80, 0x80, 0x80, 0x09, 0x09, 0x09, 0x01,
0x00, 0x06, 0x09, 0x01, 0x00, 0x01, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char us_90[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0x8e, 0x80, 0x66, 0xa4, 0x19, 0xc7, 0x71, 0x80, 0x80, 0x80, 0x80, 0x0a, 0x0a, 0x0a, 0x03,
0x00, 0x0a, 0x0a, 0x01, 0x00, 0x01, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static unsigned char metal_2k[] = {
0x1c, 0x03, 0x05, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xaa, 0xa4, 0x80, 0x55, 0x99, 0x4c, 0x91, 0x8e, 0x80, 0x80, 0x80, 0x80, 0x08, 0x08, 0x08, 0x02,
0x00, 0x08, 0x08, 0x01, 0x00, 0x01, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

View file

@ -631,7 +631,7 @@ 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|DSP| st|slt| 00 |
00 | 19| c3|fam| st|slt| 00 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
16 | 00 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
@ -640,7 +640,7 @@ Toggling effect on/off:
48 | 00 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
DSP - can be either 6, 7, 8 or 9; depends on effect familly
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
@ -659,7 +659,7 @@ slt - slot; before amp have numbers from 0 to 3, after from 4 to 7
48 | ? | ? | ? | ? | ? | 00 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
DSP - can be either 6, 7, 8 or 9; depends on effect familly
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

38
magic.h Normal file
View file

@ -0,0 +1,38 @@
// Magic values for direct conditioning of Mustang analog controls
//
#ifndef _MAGIC_H
#define _MAGIC_H
unsigned short magic_values[] = {
0x0000, 0x013b, 0x02ef, 0x036a, 0x04a4, 0x0659, 0x06d4, 0x080e, 0x0a3d, 0x0b78,
0x0bf2, 0x0d2d, 0x0da7, 0x0ee2, 0x0f5c, 0x1111, 0x124c, 0x12c6, 0x1400, 0x147b,
0x1630, 0x176a, 0x17e5, 0x191f, 0x1999, 0x1ad4, 0x1b4e, 0x1c89, 0x1d03, 0x1e3e,
0x1eb8, 0x1ff3, 0x206d, 0x21a8, 0x2222, 0x235d, 0x23d7, 0x2511, 0x258c, 0x26c6,
0x2741, 0x287b, 0x28f6, 0x2a30, 0x2aaa, 0x2be5, 0x2c5f, 0x2d9a, 0x2e14, 0x2f4f,
0x2fc9, 0x3104, 0x317e, 0x32b9, 0x3333, 0x346e, 0x34e8, 0x3622, 0x369d, 0x37d7,
0x3852, 0x398c, 0x3a07, 0x3b41, 0x3bbb, 0x3cf6, 0x3d70, 0x3eab, 0x3f25, 0x4060,
0x40da, 0x4215, 0x428f, 0x43ca, 0x4444, 0x457f, 0x45f9, 0x4733, 0x47ae, 0x48e8,
0x4963, 0x4a9d, 0x4b18, 0x4c52, 0x4ccc, 0x4e07, 0x4e81, 0x4fbc, 0x5036, 0x5171,
0x51eb, 0x5326, 0x53a0, 0x54db, 0x5555, 0x5690, 0x570a, 0x5844, 0x58bf, 0x59f9,
0x5a74, 0x5bae, 0x5c29, 0x5d63, 0x5dde, 0x5f18, 0x5f92, 0x60cd, 0x6282, 0x62fc,
0x6437, 0x64b1, 0x65ec, 0x6666, 0x67a1, 0x681b, 0x6955, 0x69d0, 0x6b0a, 0x6b85,
0x6cbf, 0x6d3a, 0x6e74, 0x6eef, 0x7029, 0x70a3, 0x71de, 0x7258, 0x7393, 0x740d,
0x7548, 0x75c2, 0x76fd, 0x7777, 0x78b2, 0x792c, 0x7a66, 0x7ae1, 0x7c1b, 0x7c96,
0x7dd0, 0x7e4b, 0x7f85, 0x8000, 0x813a, 0x81b4, 0x82ef, 0x8369, 0x84a4, 0x851e,
0x8659, 0x86d3, 0x880e, 0x8888, 0x89c3, 0x8a3d, 0x8bf2, 0x8d2c, 0x8da7, 0x8ee1,
0x9096, 0x9111, 0x924b, 0x92c5, 0x947a, 0x962f, 0x97e4, 0x9b4e, 0x9d03, 0x9eb8,
0xa06d, 0xa222, 0xa3d6, 0xa58b, 0xa740, 0xa8f5, 0xaaaa, 0xac5f, 0xafc9, 0xb17e,
0xb333, 0xb4e7, 0xb851, 0xba06, 0xbbbb, 0xbd70, 0xbf25, 0xc0da, 0xc28f, 0xc444,
0xc5f8, 0xc962, 0xcb17, 0xcccc, 0xce81, 0xd036, 0xd1eb, 0xd3a0, 0xd555, 0xd709,
0xd8be, 0xda73, 0xdc28, 0xdddd, 0xdf92, 0xe147, 0xe2fc, 0xe4b1, 0xe666, 0xe81a,
0xe9cf, 0xeb84, 0xf0a3, 0xf258, 0xf5c2, 0xf92b, 0xfae0, 0xfe4a, 0xffff
};
// Max index in array
unsigned magic_max = 218;
// Scale MIDI CC value to array index
double magic_scale_factor = 1.711;
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,9 @@
// -*-c++-*-
#ifndef MUSTANG_H
#define MUSTANG_H
#include <stdio.h>
#include <cstdio>
#include <string.h>
#include <unistd.h>
#include <libusb-1.0/libusb.h>
@ -10,6 +11,7 @@
#include "effects_enum.h"
#include "data_structs.h"
//#include <time.h>
#include "amp.h"
// amp's VID and PID
#define USB_VID 0x1ed8
@ -69,30 +71,74 @@
#define SAVE_SLOT 4
#define FXKNOB 3
// effect category (slot in 'prev_array'). Used to toggle state.
#define STOMP 0
#define MOD 1
#define DELAY 2
#define REVERB 3
// direct control fields
#define FAMILY 2
#define ACTIVE_INVERT 3
// Index into current state structure
#define PRESET_NAME 0
#define AMP_STATE 1
#define STOMP_STATE 2
#define MOD_STATE 3
#define DELAY_STATE 4
#define REVERB_STATE 5
#define EXP_STATE 6
// DSP Category
#define AMP_DSP 5
#define STOMP_DSP 6
#define MOD_DSP 7
#define DELAY_DSP 8
#define REVERB_DSP 9
// DSP Family (used for direct parm set) - Effectively DSP - 3
#define STOMP_FAM 3
#define MOD_FAM 4
#define DELAY_FAM 5
#define REVERB_FAM 6
// Amp id values
#define F57_DELUXE_ID 0x67
#define F59_BASSMAN_ID 0x64
#define F57_CHAMP_ID 0x7c
#define F65_DELUXE_ID 0x53
#define F65_PRINCETON_ID 0x6a
#define F65_TWIN_ID 0x75
#define F_SUPERSONIC_ID 0x72
#define BRIT_60S_ID 0x61
#define BRIT_70S_ID 0x79
#define BRIT_80S_ID 0x5e
#define US_90S_ID 0x5d
#define METAL_2K_ID 0x6d
#define STUDIO_PREAMP_ID 0xf1
#define F57_TWIN_ID 0xf6
#define S60S_THRIFT_ID 0xf9
#define BRIT_WATT_ID 0xff
#define BRIT_COLOR_ID 0xfc
class Mustang
{
public:
Mustang();
~Mustang();
int start_amp(char list[][32]=NULL, char *name=NULL, struct amp_settings *amp_set=NULL, struct fx_pedal_settings *effects_set=NULL); // initialize communication
int start_amp(void); // initialize communication
int stop_amp(void); // terminate communication
int set_effect(struct fx_pedal_settings);
int set_amplifier(struct amp_settings);
int setAmp( int ord );
int save_on_amp(char *, int);
int load_memory_bank(int, char *name=NULL, struct amp_settings *amp_set=NULL, struct fx_pedal_settings *effects_set=NULL);
int load_memory_bank(int);
int save_effects(int , char *, int , struct fx_pedal_settings *);
int update(char *);
// State: 1 = off, 0 = on
int effect_toggle(int category, int state);
private:
int control_common1(int parm, int bucket, int value);
int control_common2(int parm, int bucket, int value);
AmpCC * getAmp( void ) { return curr_amp;}
private:
libusb_device_handle *amp_hand; // handle for USB communication
unsigned char execute[LENGTH]; // "apply" command sent after each instruction
@ -106,7 +152,22 @@ private:
//
unsigned char prev_array[4][LENGTH]; // array used to clear the effect
int decode_data(unsigned char [6][LENGTH], char *name=NULL, struct amp_settings *amp_set=NULL, struct fx_pedal_settings *effects_set=NULL);
// Current state of amp.
//
// 0 : Preset Name
// 1 : Amp
// 2 : Stomp
// 3 : Mod
// 4 : Delay
// 5 : Reverb
// 6 : Expression Pedal
//
unsigned char curr_state[7][LENGTH];
AmpCC * curr_amp;
void updateAmp(void);
};
#endif // MUSTANG_H

View file

@ -5,17 +5,12 @@
#include "mustang.h"
static Mustang amp;
static amp_settings amp_parms;
static fx_pedal_settings pedal_parms;
static char name[32];
static char names[100][32];
static Mustang mustang;
static int channel;
void message_action( double deltatime, std::vector< unsigned char > *message, void *userData ) {
#if 1
#if 0
unsigned int nBytes = message->size();
if ( nBytes > 0 ) {
for ( unsigned int i=0; i<nBytes; i++ )
@ -28,31 +23,87 @@ void message_action( double deltatime, std::vector< unsigned char > *message, vo
int msg_channel = (*message)[0] & 0x0f;
if ( msg_channel != channel ) return;
int rc;
int msg_type = (*message)[0] & 0xf0;
switch ( msg_type ) {
case 0xc0: {
// Program change
int bank = (int)(*message)[1];
rc = amp.load_memory_bank( bank, name, &amp_parms, &pedal_parms );
int rc = mustang.load_memory_bank( bank );
if ( rc ) {
std::cout << "Error: load_memory_bank " << bank << " failed. rc = " << rc << "\n";
fprintf( stderr, "Error: PC#%d failed. RC = %d\n", bank, rc );
}
}
break;
case 0xb0: {
// Control change
if ( (*message)[1] >= 23 && (*message)[1] <= 26 ) {
int category = (*message)[1] - 23;
int rc;
int cc = (*message)[1];
int value = (*message)[2];
AmpCC *ampModel = mustang.getAmp();
// Effects on/off
if ( cc >= 23 && cc <= 26 ) {
// Translate 23..26 --> 2..5 (current state index)
int index = cc - 21;
int state;
if ( value >= 0 && value <= 63 ) state = 1;
else if ( value > 63 && value <= 127 ) state = 0;
rc = amp.effect_toggle( category, state );
if ( rc ) {
std::cout << "Error: effect_toggle " << category << " failed. rc = " << rc << "\n";
if ( value >= 0 && value <= 63 ) state = 0;
else if ( value > 63 && value <= 127 ) state = 1;
rc = mustang.effect_toggle( index, state );
}
// Set amp model
else if ( cc == 68 ) {
// fprintf( stderr, "DEBUG: %d\n", value );
rc = mustang.setAmp( value );
}
// Gain
else if ( cc == 69 ) {
rc = ampModel->cc69( value );
}
// Channel volume
else if ( cc == 70 ) {
rc = ampModel->cc70( value );
}
// Treble
else if ( cc == 71 ) {
rc = ampModel->cc71( value );
}
// Mid
else if ( cc == 72 ) {
rc = ampModel->cc72( value );
}
// Bass
else if ( cc == 73 ) {
rc = ampModel->cc73( value );
}
// Sag
else if ( cc == 74 ) {
rc = ampModel->cc74( value );
}
// Bias
else if ( cc == 75 ) {
rc = ampModel->cc75( value );
}
// Noise Gate
else if ( cc == 76 ) {
rc = ampModel->cc76( value );
}
// Cabinet
else if ( cc == 77 ) {
rc = ampModel->cc77( value );
}
// Presence / Gain2 / Cut
else if ( cc == 78 ) {
rc = ampModel->cc78( value );
}
// Blend / Master Volume
else if ( cc == 79 ) {
rc = ampModel->cc79( value );
}
if ( rc ) {
fprintf( stderr, "Error: CC#%d failed. RC = %d\n", cc, rc );
}
}
break;
@ -84,7 +135,7 @@ int main( int argc, const char **argv ) {
if ( endptr == argv[0] ) usage();
if ( channel < 0 || channel > 15 ) usage();
int rc = amp.start_amp( names, name, &amp_parms, &pedal_parms );
int rc = mustang.start_amp();
if (rc) {
std::cout << "Fender USB initialization failed: " << rc << "\n";
return 8;