pull/32/head
Holger Wirtz 4 years ago
parent 1533e6ba12
commit 0058a83f3c
  1. 6
      MicroDexed.ino
  2. 16
      config.h
  3. 51
      dexed_sysex.cpp
  4. 2
      dexed_sysex.h
  5. 147
      doc/sysex-format_dexed-setup.txt

@ -1328,8 +1328,6 @@ void initial_values_from_eeprom(bool init)
void check_configuration(void)
{
configuration.instances = constrain(configuration.instances, INSTANCES_MIN, INSTANCES_MAX);
configuration.instance_mode = constrain(configuration.instance_mode, INSTANCE_MODE_MIN, INSTANCE_MODE_MAX);
configuration.instance_splitpoint = constrain(configuration.instance_splitpoint, INSTANCE_SPLITPOINT_MAX, INSTANCE_SPLITPOINT_MAX);
configuration.vol = constrain(configuration.vol, VOLUME_MIN, VOLUME_MAX);
configuration.mono = constrain(configuration.mono, MONO_MIN, MONO_MAX);
configuration.reverb_roomsize = constrain(configuration.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX);
@ -1347,6 +1345,8 @@ void check_configuration(void)
configuration.dexed[instance_id].midi_channel = constrain(configuration.dexed[instance_id].midi_channel, MIDI_CHANNEL_MIN, MIDI_CHANNEL_MAX);
configuration.dexed[instance_id].bank = constrain(configuration.dexed[instance_id].bank, 0, MAX_BANKS - 1);
configuration.dexed[instance_id].voice = constrain(configuration.dexed[instance_id].voice, 0, MAX_VOICES - 1);
configuration.dexed[instance_id].lowest_note = constrain(configuration.dexed[instance_id].lowest_note, INSTANCE_LOWEST_NOTE_MIN, INSTANCE_LOWEST_NOTE_MAX);
configuration.dexed[instance_id].highest_note = constrain(configuration.dexed[instance_id].highest_note, INSTANCE_HIGHEST_NOTE_MIN, INSTANCE_HIGHEST_NOTE_MAX);
configuration.dexed[instance_id].reverb_send = constrain(configuration.dexed[instance_id].reverb_send, REVERB_SEND_MIN, REVERB_SEND_MAX);
configuration.dexed[instance_id].chorus_send = constrain(configuration.dexed[instance_id].chorus_send, CHORUS_SEND_MIN, CHORUS_SEND_MAX);
configuration.dexed[instance_id].delay_send = constrain(configuration.dexed[instance_id].delay_send, DELAY_SEND_MIN, DELAY_SEND_MAX);
@ -1389,8 +1389,6 @@ void init_configuration(void)
configuration.checksum = 0xffff;
configuration.instances = INSTANCES_DEFAULT;
configuration.instance_mode = INSTANCE_MODE_DEFAULT;
configuration.instance_splitpoint = INSTANCE_SPLITPOINT_DEFAULT;
configuration.vol = VOLUME_DEFAULT;
configuration.mono = MONO_DEFAULT;
configuration.reverb_roomsize = REVERB_ROOMSIZE_DEFAULT;

@ -290,6 +290,14 @@ enum { DEXED, CHORUS, DELAY, REVERB};
#define MIDI_CHANNEL_MAX 16
#define MIDI_CHANNEL_DEFAULT MIDI_CHANNEL_OMNI
#define INSTANCE_LOWEST_NOTE_MIN 21
#define INSTANCE_LOWEST_NOTE_MAX 108
#define INSTANCE_LOWEST_NOTE_DEFAULT 21
#define INSTANCE_HIGHEST_NOTE_MIN 21
#define INSTANCE_HIGHEST_NOTE_MAX 108
#define INSTANCE_HIGHEST_NOTE_DEFAULT 108
#define REVERB_ROOMSIZE_MIN 0
#define REVERB_ROOMSIZE_MAX 100
#define REVERB_ROOMSIZE_DEFAULT 0
@ -438,15 +446,13 @@ enum { DEXED, CHORUS, DELAY, REVERB};
#define INSTANCE_MODE_MAX 1
#define INSTANCE_MODE_DEFAULT 0
#define INSTANCE_SPLITPOINT_MIN MIDI_AIS0
#define INSTANCE_SPLITPOINT_MAX MIDI_B7
#define INSTANCE_SPLITPOINT_DEFAULT MIDI_C3
//
typedef struct {
uint8_t midi_channel;
uint8_t bank;
uint8_t voice;
uint8_t lowest_note;
uint8_t highest_note;
uint8_t reverb_send;
uint8_t chorus_send;
uint8_t delay_send;
@ -479,8 +485,6 @@ typedef struct {
typedef struct {
uint32_t checksum;
uint8_t instances;
uint8_t instance_mode;
uint8_t instance_splitpoint;
uint8_t vol;
uint8_t mono;
uint8_t reverb_roomsize;

@ -408,6 +408,7 @@ bool get_sysex_setup(File sysex, config_t configuration)
#endif
return (false);
}
sysex.seek(3);
uint8_t dexed_sysex_setup_type = sysex.read();
if (dexed_sysex_setup_type >= 0x42 && dexed_sysex_setup_type < 0x45) // check for sysex type (0x75=MicroDexed setup for one to four instances)
@ -417,6 +418,10 @@ bool get_sysex_setup(File sysex, config_t configuration)
#endif
return (false);
}
sysex.seek(4);
uint8_t sysex_config_size = sysex.read();
sysex.seek(sysex.size() - 1); // Bulk checksum
bulk_checksum = sysex.read();
@ -424,11 +429,6 @@ bool get_sysex_setup(File sysex, config_t configuration)
for (n = 0; n < sysex.size() - 2; n++)
{
uint8_t d = sysex.read();
#ifdef DEBUG
Serial.print(n + 6, DEC);
Serial.print(F("="));
Serial.println(d);
#endif
bulk_checksum_calc -= d;
}
bulk_checksum_calc &= 0x7f;
@ -452,6 +452,21 @@ bool get_sysex_setup(File sysex, config_t configuration)
return (false);
}
// Now everything is ok and we can read the data
sysex.seek(6); // start of bulk data
uint8_t* conf = (uint8_t*)&configuration + 4;
for (n = 0; n < sysex_config_size; n++)
{
uint8_t d = sysex.read();
#ifdef DEBUG
Serial.print(n + 6, DEC);
Serial.print(F("="));
Serial.println(d);
#endif
*(conf + n) = d;
}
configuration.checksum = crc32((uint8_t*)&configuration + 4, sizeof(configuration) - 4);
return (true);
}
@ -504,3 +519,29 @@ bool load_sysex_setup(uint8_t b, uint8_t v, uint8_t instance_id)
return (false);
}
bool save_sysex_setup(uint8_t b, uint8_t v, config_t configuration)
{
const char* sysex_filename = "config.syx";
if (sd_card_available)
{
File sysex;
char sysex_file_name[20];
create_sysex_filename(b, sysex_file_name, v);
sysex = SD.create(sysex_file_name);
if (!sysex)
{
#ifdef DEBUG
Serial.print(F("E : Cannot create "));
Serial.print(sysex_file_name);
Serial.println(F("on SD."));
#endif
return (false);
}
}
return (false);
}

@ -44,6 +44,7 @@ extern char voice_names[NUM_DEXED][MAX_VOICES][VOICE_NAME_LEN];
extern uint8_t ui_state;
extern uint8_t ui_main_state;
extern config_t configuration;
extern uint32_t crc32(byte * calc_start, uint16_t calc_bytes);
void create_sysex_filename(uint8_t b, char* sysex_file_name);
void strip_extension(char* s, char *target);
@ -55,5 +56,6 @@ bool get_sysex_voice(File sysex, uint8_t voice_number, uint8_t* data);
void create_sysex_setup_filename(uint8_t b, uint8_t v, char* sysex_setup_file_name);
bool get_sysex_setup(File sysex, uint8_t voice_number, uint8_t* data);
bool load_sysex_setup(uint8_t b, uint8_t v, uint8_t instance_id);
bool save_sysex_setup(uint8_t b, uint8_t v, config_t configuration);
#endif

@ -7,42 +7,42 @@ SYSEX Message Controller-Set
11110000 F0 Status byte - start sysex
0iiiiiii 67 ID # (i=103; unofficial SYSEX-ID for MicroDexed)
0sssnnnn 00 Sub-status (s=0) & channel number (n=0; ch 1)
0fffffff 00 format number (f=66..69; 1..4 MicroDexed setup(s))
0bbbbbbb 01 byte count MS byte
0bbbbbbb 1B byte count LS byte (b=44; 1 instance
b=73; 2 instances
b=102; 3 instances
b=131; 4 instances)
0fffffff ** format number (f=66..69; 1..4 MicroDexed setup(s))
0bbbbbbb ** byte count MS byte
0bbbbbbb ** byte count LS byte (b=44; 1 instance
b=75; 2 instances
b=106; 3 instances
b=137; 4 instances)
0ddddddd ** data byte 1 setup config
| | |
0ddddddd ** data byte 19
0ddddddd ** data byte 20 instance config 0
0ddddddd ** data byte 13
0ddddddd ** data byte 14 instance config 0
| | |
0ddddddd ** data byte 43
0ddddddd ** data byte 44
/-Optional--------------------------------------------\
0ddddddd ** data byte 44 instance config 1
0ddddddd ** data byte 45 instance config 1
| | |
0ddddddd ** data byte 72
0ddddddd ** data byte 74
\-----------------------------------------------------/
/-Optional--------------------------------------------\
0ddddddd ** data byte 73 instance config 2
0ddddddd ** data byte 75 instance config 2
| | |
0ddddddd ** data byte 101
0ddddddd ** data byte 105
\-----------------------------------------------------/
/-Optional--------------------------------------------\
0ddddddd ** data byte 102 instance config 3
0ddddddd ** data byte 106 instance config 3
| | |
0ddddddd ** data byte 131
0ddddddd ** data byte 137
\-----------------------------------------------------/
0eeeeeee ** checksum (masked 2's comp. of sum of ** bytes)
11110111 F7 Status - end sysex
@ -50,77 +50,48 @@ SYSEX Message Controller-Set
Data Structure: MicroDexed Setup Dump
-------------------------------------
Parameter
Number Parameter Value Range
--------- --------- -----------
0 GLOBAL STERO/MONO 0-3 (0=stereo, 1=mono, 2=mono-r, 3=mono-l)
1 GLOBAL REVERB-ROOMSIZE 0-100
2 GLOBAL REVERB-DAMPING 0-100
3 GLOBAL CHORUS-FREQUENCY 0-100 (multiplied by 1/10 Hz)
4 GLOBAL CHORUS-WAVEFORM 0-1 (0=triangle, 1=sine)
5 GLOBAL CHORUS-DEPTH 0-100
6 GLOBAL DELAY-TIME 0-60 (multiplied by 10ms)
7 GLOBAL DELAY-FEEDBACK 0-100
8 DEXED 1 MONO/POLY MODE CHANGE 0-1 O=POLY
9 DEXED 1 PITCH BEND RANGE 0-12
10 DEXED 1 " " STEP 0-12
11 DEXED 1 PORTAMENTO MODE 0-1 0=RETAIN 1=FOLLOW
12 DEXED 1 " GLISS 0-1
13 DEXED 1 " TIME 0-99
14 DEXED 1 MOD WHEEL RANGE 0-99
15 DEXED 1 " " ASSIGN 0-7 b0: pitch, b1:amp, b2: EG bias
16 DEXED 1 FOOT CONTROL RANGE 0-99
17 DEXED 1 " " ASSIGN 0-7 "
18 DEXED 1 BREATH CONT RANGE 0-99
19 DEXED 1 " " ASSIGN 0-7 "
20 DEXED 1 AFTERTOUCH RANGE 0-99
21 DEXED 1 " ASSIGN 0-7 "
22 DEXED 1 OP1_ENABLE 0-1
23 DEXED 1 OP2_ENABLE 0-1
24 DEXED 1 OP3_ENABLE 0-1
25 DEXED 1 OP4_ENABLE 0-1
26 DEXED 1 OP5_ENABLE 0-1
27 DEXED 1 OP6_ENABLE 0-1
28 DEXED 1 MAX_NOTES 0-32
29 DEXED 1 LOUDNESS 0-100
30 DEXED 1 PANORAMA 0-40 (20 is middle)
31 DEXED 1 REVERB-LEVEL 0-100
32 DEXED 1 CHORUS-LEVEL 0-100
33 DEXED 1 DELAY-LEVEL 0-100
34 DEXED 1 FILTER-CUTOFF 0-100
35 DEXED 1 FILTER-RESONANCE 0-100
26 DEXED 1 MIDI-CHANNEL 0-16 (0=OMNI)
37 DEXED 1 POLYPHONY 0-32 (depends on CPU and FX)
38 DEXED 1 ENGINE 0-2 (1=Modern, 2=Mark1, 2=OPL)
Number Parameter Value Range
--------- --------- -----------
0 GLOBAL STERO/MONO 0-3 (0=stereo, 1=mono, 2=mono-r, 3=mono-l)
1 GLOBAL REVERB-ROOMSIZE 0-100
2 GLOBAL REVERB-DAMPING 0-100
3 GLOBAL REVERB-LEVEL 0-100
4 GLOBAL CHORUS-FREQUENCY 0-100 (multiplied by 1/10 Hz)
5 GLOBAL CHORUS-WAVEFORM 0-1 (0=triangle, 1=sine)
6 GLOBAL CHORUS-DEPTH 0-100
7 GLOBAL CHORUS-LEVEL 0-100
8 GLOBAL DELAY-TIME 0-50 (multiplied by 10ms)
9 GLOBAL DELAY-FEEDBACK 0-100
10 GLOBAL DELAY-LEVEL 0-100
--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
39 DEXED 2 MONO/POLY MODE CHANGE 0-1 O=POLY
40 DEXED 2 PITCH BEND RANGE 0-12
41 DEXED 2 " " STEP 0-12
42 DEXED 2 PORTAMENTO MODE 0-1 0=RETAIN 1=FOLLOW
43 DEXED 2 " GLISS 0-1
44 DEXED 2 " TIME 0-99
45 DEXED 2 MOD WHEEL RANGE 0-99
46 DEXED 2 " " ASSIGN 0-7 b0: pitch, b1:amp, b2: EG bias
47 DEXED 2 FOOT CONTROL RANGE 0-99
48 DEXED 2 " " ASSIGN 0-7 "
49 DEXED 2 BREATH CONT RANGE 0-99
40 DEXED 2 " " ASSIGN 0-7 "
51 DEXED 2 AFTERTOUCH RANGE 0-99
52 DEXED 2 " ASSIGN 0-7 "
53 DEXED 2 OP1_ENABLE 0-1
54 DEXED 2 OP2_ENABLE 0-1
55 DEXED 2 OP3_ENABLE 0-1
56 DEXED 2 OP4_ENABLE 0-1
57 DEXED 2 OP5_ENABLE 0-1
58 DEXED 2 OP6_ENABLE 0-1
59 DEXED 2 MAX_NOTES 0-32
60 DEXED 2 LOUDNESS 0-100
61 DEXED 2 PANORAMA 0-40 (20 is middle)
62 DEXED 2 REVERB-LEVEL 0-100
63 DEXED 2 CHORUS-LEVEL 0-100
64 DEXED 2 DELAY-LEVEL 0-100
65 DEXED 2 FILTER-CUTOFF 0-100
66 DEXED 2 FILTER-RESONANCE 0-100
67 DEXED 2 MIDI-CHANNEL 0-16 (0=OMNI)
68 DEXED 2 POLYPHONY 0-32 (depends on CPU and FX)
69 DEXED 2 ENGINE 0-2 (1=Modern, 2=Mark1, 2=OPL)
11 DEXED 1 MIDI-CHANNEL 0-16 (0=OMNI)
12 DEXED 1 BANK 0-99
13 DEXED 1 VOICE 0-31
14 DEXED 1 LOWEST NOTE 21-108
15 DEXED 1 HIGHEST NOTE 21-108
16 DEXED 1 REVERB SEND 0-100
17 DEXED 1 CHORUS SEND 0-100
18 DEXED 1 DELAY SEND 0-100
19 DEXED 2 FILTER-CUTOFF 0-100
20 DEXED 2 FILTER-RESONANCE 0-100
21 DEXED 2 TRANSPOSE 0-48
22 DEXED 2 TUNE 0-100
23 DEXED 2 SOUND INTENSITY 0-100
24 DEXED 2 PANORAMA 0-40 (20 is middle)
25 DEXED 1 POLYPHONY 0-32 (depends on CPU and FX)
26 DEXED 1 ENGINE 0-2 (1=Modern, 2=Mark1, 2=OPL)
27 DEXED 1 MONO/POLY MODE CHANGE 0-1 O=POLY
28 DEXED 1 PITCH BEND RANGE 0-12
29 DEXED 1 " " STEP 0-12
30 DEXED 1 MOD WHEEL RANGE 0-99
31 DEXED 1 " " ASSIGN 0-7 b0: pitch, b1:amp, b2: EG bias
32 DEXED 1 FOOT CONTROL RANGE 0-99
33 DEXED 1 " " ASSIGN 0-7 "
34 DEXED 1 BREATH CONT RANGE 0-99
35 DEXED 1 " " ASSIGN 0-7 "
36 DEXED 1 AFTERTOUCH RANGE 0-99
37 DEXED 1 " ASSIGN 0-7 "
38 DEXED 1 PORTAMENTO MODE 0-1 0=RETAIN 1=FOLLOW
39 DEXED 1 " GLISS 0-1
40 DEXED 1 " TIME 0-99
41 DEXED 1 OP_ENABLE 0-31

Loading…
Cancel
Save