parent
758ef64788
commit
a91798ed9f
@ -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
@ -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…
Reference in new issue