Implement reverb CCs
This commit is contained in:
parent
7e45418d0f
commit
fae1d3c727
7 changed files with 299 additions and 6 deletions
11
50-mustang.rules
Normal file
11
50-mustang.rules
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0004", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0005", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0006", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0007", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0010", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0011", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0012", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0013", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0014", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0015", GROUP="plugdev"
|
||||
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="1ed8", ATTRS{idProduct}=="0016", GROUP="plugdev"
|
||||
104
mustang.cpp
104
mustang.cpp
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "magic.h"
|
||||
#include "amp_defaults.h"
|
||||
#include "reverb_defaults.h"
|
||||
|
||||
Mustang::Mustang()
|
||||
{
|
||||
|
|
@ -130,6 +131,7 @@ int Mustang::start_amp(void)
|
|||
for(j = 0; j < 7; i++, j++) memcpy(curr_state[j], received_data[i], LENGTH);
|
||||
|
||||
updateAmp();
|
||||
curr_reverb = new ReverbCC( this );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -212,6 +214,11 @@ void Mustang::updateAmp(void) {
|
|||
}
|
||||
|
||||
|
||||
void Mustang::updateReverb(void) {
|
||||
// No-op for now
|
||||
}
|
||||
|
||||
|
||||
int Mustang::effect_toggle(int state_index, int state)
|
||||
{
|
||||
int ret, received;
|
||||
|
|
@ -379,6 +386,64 @@ int Mustang::setAmp( int ord ) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int Mustang::setReverb( int ord ) {
|
||||
int ret, received;
|
||||
unsigned char scratch[LENGTH];
|
||||
|
||||
unsigned char *array;
|
||||
|
||||
switch (ord) {
|
||||
case 1:
|
||||
array = small_hall;
|
||||
break;
|
||||
case 2:
|
||||
array = large_hall;
|
||||
break;
|
||||
case 3:
|
||||
array = small_room;
|
||||
break;
|
||||
case 4:
|
||||
array = large_room;
|
||||
break;
|
||||
case 5:
|
||||
array = small_plate;
|
||||
break;
|
||||
case 6:
|
||||
array = large_plate;
|
||||
break;
|
||||
case 7:
|
||||
array = ambient;
|
||||
break;
|
||||
case 8:
|
||||
array = arena;
|
||||
break;
|
||||
case 9:
|
||||
array = spring_63;
|
||||
break;
|
||||
case 10:
|
||||
array = spring_65;
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "W - Reverb select %d not supported\n", ord );
|
||||
return 0;
|
||||
}
|
||||
|
||||
array[FXSLOT] = curr_state[REVERB_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[REVERB_STATE], array, LENGTH);
|
||||
updateReverb();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Mustang::save_on_amp(char *name, int slot)
|
||||
{
|
||||
int ret, received;
|
||||
|
|
@ -406,6 +471,45 @@ 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 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];
|
||||
// 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::load_memory_bank( int slot )
|
||||
{
|
||||
int ret, received;
|
||||
|
|
|
|||
24
mustang.h
24
mustang.h
|
|
@ -7,11 +7,10 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
//#include <QtDebug>
|
||||
#include "effects_enum.h"
|
||||
#include "data_structs.h"
|
||||
//#include <time.h>
|
||||
#include "amp.h"
|
||||
#include "reverb.h"
|
||||
|
||||
// amp's VID and PID
|
||||
#define USB_VID 0x1ed8
|
||||
|
|
@ -117,6 +116,18 @@
|
|||
#define BRIT_WATT_ID 0xff
|
||||
#define BRIT_COLOR_ID 0xfc
|
||||
|
||||
// Reverb id values
|
||||
#define SM_HALL_ID 0x24
|
||||
#define LG_HALL_ID 0x3a
|
||||
#define SM_ROOM_ID 0x26
|
||||
#define LG_ROOM_ID 0x3b
|
||||
#define SM_PLATE_ID 0x4e
|
||||
#define LG_PLATE_ID 0x4b
|
||||
#define AMBIENT_ID 0x4c
|
||||
#define ARENA_ID 0x4d
|
||||
#define SPRING_63_ID 0x21
|
||||
#define SPRING_65_ID 0x0b
|
||||
|
||||
class Mustang
|
||||
{
|
||||
public:
|
||||
|
|
@ -126,6 +137,9 @@ public:
|
|||
int stop_amp(void); // terminate communication
|
||||
int set_effect(struct fx_pedal_settings);
|
||||
int setAmp( int ord );
|
||||
|
||||
int setReverb( int ord );
|
||||
|
||||
int save_on_amp(char *, int);
|
||||
int load_memory_bank(int);
|
||||
int save_effects(int , char *, int , struct fx_pedal_settings *);
|
||||
|
|
@ -136,7 +150,10 @@ public:
|
|||
int control_common1(int parm, int bucket, int value);
|
||||
int control_common2(int parm, int bucket, int value);
|
||||
|
||||
int efx_common1(int parm, int bucket, int type, int value);
|
||||
|
||||
AmpCC * getAmp( void ) { return curr_amp;}
|
||||
ReverbCC * getReverb( void ) { return curr_reverb;}
|
||||
|
||||
private:
|
||||
libusb_device_handle *amp_hand; // handle for USB communication
|
||||
|
|
@ -166,8 +183,11 @@ public:
|
|||
unsigned char curr_state[7][LENGTH];
|
||||
|
||||
AmpCC * curr_amp;
|
||||
ReverbCC * curr_reverb;
|
||||
|
||||
void updateAmp(void);
|
||||
void updateReverb(void);
|
||||
|
||||
};
|
||||
|
||||
#endif // MUSTANG_H
|
||||
|
|
|
|||
|
|
@ -39,10 +39,11 @@ void message_action( double deltatime, std::vector< unsigned char > *message, vo
|
|||
|
||||
case 0xb0: {
|
||||
// Control change
|
||||
int rc;
|
||||
int rc = 0;
|
||||
int cc = (*message)[1];
|
||||
int value = (*message)[2];
|
||||
AmpCC *ampModel = mustang.getAmp();
|
||||
ReverbCC *reverbModel = mustang.getReverb();
|
||||
|
||||
// Effects on/off
|
||||
if ( cc >= 23 && cc <= 26 ) {
|
||||
|
|
@ -53,6 +54,30 @@ void message_action( double deltatime, std::vector< unsigned char > *message, vo
|
|||
else if ( value > 63 && value <= 127 ) state = 1;
|
||||
rc = mustang.effect_toggle( index, state );
|
||||
}
|
||||
// Set reverb model
|
||||
else if ( cc == 58 ) {
|
||||
rc = mustang.setReverb( value );
|
||||
}
|
||||
// Level
|
||||
else if ( cc == 59 ) {
|
||||
rc = reverbModel->cc59( value );
|
||||
}
|
||||
// Decay
|
||||
else if ( cc == 60 ) {
|
||||
rc = reverbModel->cc60( value );
|
||||
}
|
||||
// Dwell
|
||||
else if ( cc == 61 ) {
|
||||
rc = reverbModel->cc61( value );
|
||||
}
|
||||
// Diffusion
|
||||
else if ( cc == 62 ) {
|
||||
rc = reverbModel->cc62( value );
|
||||
}
|
||||
// Tone
|
||||
else if ( cc == 63 ) {
|
||||
rc = reverbModel->cc63( value );
|
||||
}
|
||||
// Set amp model
|
||||
else if ( cc == 68 ) {
|
||||
// fprintf( stderr, "DEBUG: %d\n", value );
|
||||
|
|
|
|||
29
reverb.cpp
Normal file
29
reverb.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
#include "reverb.h"
|
||||
#include "mustang.h"
|
||||
|
||||
int
|
||||
ReverbCC::cc59( int value ) {
|
||||
return amp->efx_common1( 0x00, 0x0b, REVERB_STATE, value );
|
||||
}
|
||||
|
||||
int
|
||||
ReverbCC::cc60( int value ) {
|
||||
return amp->efx_common1( 0x01, 0x0b, REVERB_STATE, value );
|
||||
}
|
||||
|
||||
int
|
||||
ReverbCC::cc61( int value ) {
|
||||
return amp->efx_common1( 0x02, 0x0b, REVERB_STATE, value );
|
||||
}
|
||||
|
||||
int
|
||||
ReverbCC::cc62( int value ) {
|
||||
return amp->efx_common1( 0x03, 0x0b, REVERB_STATE, value );
|
||||
}
|
||||
|
||||
int
|
||||
ReverbCC::cc63( int value ) {
|
||||
return amp->efx_common1( 0x04, 0x0b, REVERB_STATE, value );
|
||||
}
|
||||
|
||||
30
reverb.h
Normal file
30
reverb.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// -*-c++-*-
|
||||
|
||||
#ifndef _REVERB_H
|
||||
#define _REVERB_H
|
||||
|
||||
class Mustang;
|
||||
|
||||
class ReverbCC {
|
||||
|
||||
protected:
|
||||
|
||||
Mustang * amp;
|
||||
|
||||
public:
|
||||
|
||||
ReverbCC( Mustang * theAmp ) : amp(theAmp) {}
|
||||
|
||||
// Level
|
||||
int cc59( int value );
|
||||
// Decay
|
||||
int cc60( int value );
|
||||
// Dwell
|
||||
int cc61( int value );
|
||||
// Diffusion
|
||||
int cc62( int value );
|
||||
// Tone
|
||||
int cc63( int value );
|
||||
};
|
||||
|
||||
#endif
|
||||
74
reverb_defaults.h
Normal file
74
reverb_defaults.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
// Default settings for Mustang III (original) reverb models
|
||||
//
|
||||
// This header is auto-generated from decoded pcap capture.
|
||||
|
||||
static unsigned char small_hall[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x24, 0x00, 0x05, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x6e, 0x5d, 0x6e, 0x80, 0x91, 0x00, 0x00, 0x00, 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 large_hall[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3a, 0x00, 0x05, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x4f, 0x3e, 0x80, 0x05, 0xb0, 0x00, 0x00, 0x00, 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_room[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x26, 0x00, 0x05, 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 large_room[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3b, 0x00, 0x05, 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 small_plate[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x4e, 0x00, 0x05, 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 large_plate[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x4b, 0x00, 0x05, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x38, 0x80, 0x91, 0x80, 0xb6, 0x00, 0x00, 0x00, 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 ambient[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x4c, 0x00, 0x05, 0x00, 0x08, 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 arena[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x4d, 0x00, 0x05, 0x00, 0x08, 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 spring_63[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x21, 0x00, 0x05, 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 spring_65[] = {
|
||||
0x1c, 0x03, 0x09, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0b, 0x00, 0x05, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x8b, 0x49, 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, 0x00
|
||||
};
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue