Small API change of Synth_Dexed.

pull/46/head
Holger Wirtz 3 years ago
parent 758ef64788
commit a91798ed9f
  1. 2
      dexed_sd.cpp
  2. 4
      third-party/Synth_Dexed/README.md
  3. 65
      third-party/Synth_Dexed/examples/Banks/Banks.ino
  4. 5788
      third-party/Synth_Dexed/examples/Banks/banks.h
  5. 0
      third-party/Synth_Dexed/examples/SimplePlay/SimplePlay.ino
  6. 2
      third-party/Synth_Dexed/src/synth_dexed.cpp
  7. 2
      third-party/Synth_Dexed/src/synth_dexed.h
  8. 148
      third-party/Synth_Dexed/tools/sysex2c.py

@ -74,7 +74,7 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id)
Serial.println(F("]"));
#endif
uint8_t tmp_data[156];
bool ret = MicroDexed[instance_id]->decodeVoice(tmp_data, tmp);
bool ret = MicroDexed[instance_id]->decodeVoice(tmp_data, data);
MicroDexed[instance_id]->loadVoiceParameters(tmp_data);
#ifdef DEBUG
show_patch(instance_id);

@ -36,7 +36,7 @@ See example sketch.
void setMaxNotes(uint8_t n);
uint8_t getMaxNotes(void);
void doRefreshVoice(void);
bool decodeVoice(uint8_t* encoded_data, uint8_t* data);
bool decodeVoice(uint8_t* data, uint8_t* encoded_data);
bool encodeVoice(uint8_t* encoded_data);
bool getVoiceData(uint8_t* data_copy);
void setVoiceDataElement(uint8_t address, uint8_t value);
@ -169,4 +169,4 @@ See example sketch.
void setTranspose(uint8_t transpose);
uint8_t getTranspose(void);
void setName(char* name);
void getName(char* buffer);
void getName(char* buffer);

@ -0,0 +1,65 @@
#include <Audio.h>
#include "synth_dexed.h"
#include "banks.h"
AudioSynthDexed dexed(4, SAMPLE_RATE); // 4 voices max
AudioOutputI2S i2s1;
AudioControlSGTL5000 sgtl5000_1;
AudioConnection patchCord1(dexed, 0, i2s1, 0);
AudioConnection patchCord2(dexed, 0, i2s1, 1);
void setup()
{
Serial.begin(230400);
AudioMemory(32);
sgtl5000_1.enable();
sgtl5000_1.lineOutLevel(29);
sgtl5000_1.dacVolumeRamp();
sgtl5000_1.dacVolume(1.0);
sgtl5000_1.unmuteHeadphone();
sgtl5000_1.unmuteLineout();
sgtl5000_1.volume(0.8, 0.8); // Headphone volume
randomSeed(analogRead(0));
}
void loop()
{
uint8_t b = random(0, 10);
uint8_t v = random(0, 32);
uint8_t t = random(0, 36);
char voice_name[11];
uint8_t decoded_voice[156];
memset(voice_name, 0, 11);
memcpy(voice_name, &progmem_bank[b][v][117], 10);
Serial.print("Voice: ");
Serial.print(voice_name);
Serial.print(" ");
Serial.print("Transpose: ");
Serial.println(t);
dexed.decodeVoice(progmem_bank[b][v],decoded_voice);
dexed.loadVoiceParameters(decoded_voice);
dexed.setTranspose(t);
Serial.println("Key-Down");
dexed.keydown(48, 100);
delay(100);
dexed.keydown(52, 100);
delay(100);
dexed.keydown(55, 100);
delay(100);
dexed.keydown(60, 100);
delay(2000);
Serial.println("Key-Up");
dexed.keyup(48);
dexed.keyup(52);
dexed.keyup(55);
dexed.keyup(60);
delay(1000);
}

File diff suppressed because it is too large Load Diff

@ -751,7 +751,7 @@ uint8_t Dexed::getNumNotesPlaying(void)
return (count_playing_voices);
}
bool Dexed::decodeVoice(uint8_t* encoded_data, uint8_t* new_data)
bool Dexed::decodeVoice(uint8_t* new_data, uint8_t* encoded_data)
{
uint8_t* p_data = new_data;
uint8_t op;

@ -1126,7 +1126,7 @@ class Dexed
uint8_t getMaxNotes(void);
void doRefreshVoice(void);
void setOPAll(uint8_t ops);
bool decodeVoice(uint8_t* encoded_data, uint8_t* data);
bool decodeVoice(uint8_t* data, uint8_t* encoded_data);
bool encodeVoice(uint8_t* encoded_data);
bool getVoiceData(uint8_t* data_copy);
void setVoiceDataElement(uint8_t address, uint8_t value);

@ -0,0 +1,148 @@
#!/usr/bin/python3
import sys
import os.path
# From: https://github.com/bwhitman/learnfm/blob/master/dx7db.py
def unpack_packed_patch(p):
# Input is a 128 byte thing from compact.bin
# Output is a 156 byte thing that the synth knows about
o = [0]*156
for op in range(6):
o[op*21:op*21 + 11] = p[op*17:op*17+11]
leftrightcurves = p[op*17+11]
o[op * 21 + 11] = leftrightcurves & 3
o[op * 21 + 12] = (leftrightcurves >> 2) & 3
detune_rs = p[op * 17 + 12]
o[op * 21 + 13] = detune_rs & 7
o[op * 21 + 20] = detune_rs >> 3
kvs_ams = p[op * 17 + 13]
o[op * 21 + 14] = kvs_ams & 3
o[op * 21 + 15] = kvs_ams >> 2
o[op * 21 + 16] = p[op * 17 + 14]
fcoarse_mode = p[op * 17 + 15]
o[op * 21 + 17] = fcoarse_mode & 1
o[op * 21 + 18] = fcoarse_mode >> 1
o[op * 21 + 19] = p[op * 17 + 16]
o[126:126+9] = p[102:102+9]
oks_fb = p[111]
o[135] = oks_fb & 7
o[136] = oks_fb >> 3
o[137:137+4] = p[112:112+4]
lpms_lfw_lks = p[116]
o[141] = lpms_lfw_lks & 1
o[142] = (lpms_lfw_lks >> 1) & 7
o[143] = lpms_lfw_lks >> 4
o[144:144+11] = p[117:117+11]
o[155] = 0x3f
# Clamp the unpacked patches to a known max.
maxes = [
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, # osc6
3, 3, 7, 3, 7, 99, 1, 31, 99, 14,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, # osc5
3, 3, 7, 3, 7, 99, 1, 31, 99, 14,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, # osc4
3, 3, 7, 3, 7, 99, 1, 31, 99, 14,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, # osc3
3, 3, 7, 3, 7, 99, 1, 31, 99, 14,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, # osc2
3, 3, 7, 3, 7, 99, 1, 31, 99, 14,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, # osc1
3, 3, 7, 3, 7, 99, 1, 31, 99, 14,
99, 99, 99, 99, 99, 99, 99, 99, # pitch eg rate & level
31, 7, 1, 99, 99, 99, 99, 1, 5, 7, 48, # algorithm etc
126, 126, 126, 126, 126, 126, 126, 126, 126, 126, # name
127 # operator on/off
]
for i in range(156):
if(o[i] > maxes[i]): o[i] = maxes[i]
if(o[i] < 0): o[i] = 0
return o
def print_header_data(voice_data):
print("\t\t\t",end="")
for y in range(0,len(voice_data)):
if(y!=len(voice_data)-1):
print("%3d, " % voice_data[y],end="")
else:
print("%3d\n" % voice_data[y],end="")
if((y+1)%8==0 and y!=len(voice_data)-1):
print("\n\t\t\t",end="")
def help_message():
print(progname+" [--decode] <sysex1> [<sysex2> ... <sysexn>]")
#---------------------------------------------------------------------------
progname=sys.argv.pop(0)
if(len(sys.argv)==0):
help_message()
exit(1)
if(sys.argv[0]=="-h" or sys.argv[0]=="--help"):
help_message()
exit(1)
if(sys.argv[0]=="--decode"):
decode=True
sys.argv.pop(0)
else:
decode=False
print("""
//
// File generated with sysex2c.py
//
""")
if(decode==True):
print("uint8_t progmem_bank[%d][32][156] PROGMEM =\n{" % int(len(sys.argv)))
else:
print("uint8_t progmem_bank[%d][32][128] PROGMEM =\n{" % int(len(sys.argv)))
for sysex in sys.argv:
if(not os.path.isfile(sysex)):
print("* File "+sysex+" does not exists.")
exit(10)
if(not os.access(sysex,os.R_OK)):
print("* File "+sysex+" does not readable.")
exit(11)
print("\t{\t// %s" % os.path.basename(sysex))
with open(sysex, "rb") as f:
header = f.read(6)
if(header[0]!=240):
print("* %s: Start of sysex not found." % sysex)
exit(200)
if(header[1]!=67):
print("* %s: Manufactorer-ID not Yamaha." % sysex)
exit(201)
if(header[3]!=9):
print("* %s: Not a 32 voice sysex file." % sysex)
exit(202)
byte_count = header[4]*128+header[5]
if(byte_count!=4096):
print("* %s: Byte count mismatch." % sysex)
exit(203)
patch_data=f.read(4096)
check = ~sum(patch_data) + 1 & 0x7F
f.seek(4102) # Bulk checksum
checksum=int.from_bytes(f.read(1),"little")
if(check!=checksum):
print("* %s: Checksum mismatch!" % sysex)
exit(204)
f.seek(6)
for v in range(1,33):
data=f.read(128)
print("\t\t{\t// %d: %s" % (v, data[118:128].decode('ascii')))
if(decode==True):
print_header_data(unpack_packed_patch(data))
else:
print_header_data(data)
if(v!=32):
print("\t\t},")
else:
print("\t\t}")
if(sys.argv[len(sys.argv)-1]==sysex):
print("\t}")
else:
print("\t},")
print("};")
Loading…
Cancel
Save