"""Extract sequence,bank and program files from SQ80 dump""" from os.path import * ################################################ # Written 2021-02-19 Gerhard Pichelhofer (c) # in python 3.4 # Finished 2021-02-22 print ("##########################################") print ("# #") print ("# ##### ###### ###### ###### #") print ("# # # # # # # # #") print ("# ##### # # ###### # # #") print ("# # # ## # # # # #") print ("# ##### #######_ ###### ###### #") print ("# #") print ("##########################################") print ("##########################################") print ("# ENSONIQ SQ80 BankProg extractor #") print ("# 2021-02-23 G. Pichelhofer (c) #") print ("##########################################") print ("Please type in the SQ80 (bnk/prg)filename ") inpfile = input("Filename: ") outfile = splitext(inpfile)[0] + ".txt" if (exists(inpfile)): fileend = splitext(inpfile)[1] if (fileend == ".bnk"): snd = 40 elif (fileend == ".prg"): snd = 128 else: input("Sorry. This is not a correct bank file (*.bnk)") exit() else: input("Sorry. File not found") exit() inpmode = input("Only reading content (r) or also extract data to file (w)?") f = None with open(inpfile, "rb") as fp: f = fp.read() sndlist = "" for x in range(snd): pos = x * 102 Name = str(f[pos:pos+6].replace(b'm\xb6',b' ').replace(b'\x00',b' '))[1:] sndlist += ("%3i %s | " % ((x+1), Name)) if ( (x+1) % 5 == 0 ): sndlist += ('\n') if (inpmode == "w"): if (exists(outfile) == False): with open(outfile, "w") as fout: fout.write(sndlist) print (sndlist) abf = 0 while (abf != -1): sumstring = "" abf = input("Show details of a PROG (1-"+ str(snd) + ") \nby typing the number or '0' for continue ? ") try: abf = int(abf) - 1 except ValueError: print ("Incorrect number! Please try again") continue if (abf == -1): break elif (int(abf) > (snd-1)): print ("Incorrect number! Please try again") continue pos = abf * 102 progname = str(f[pos:pos+6])[1:] if (f[pos:pos+3] == b'm\xb6m'): print ("Program empty") continue sumstring += ("#########################\n") sumstring += ("# Program %3i: %s #\n" % (abf+1,str(f[pos:pos+6])[1:])) sumstring += ("#########################\n") onoff = ['OFF', 'ON '] mods = ['LFO1','LFO2','LFO3','ENV1','ENV2','ENV3','ENV4','VEL','VEL-X','KYBD','KYBD2','WHEEL','PEDAL','XCTRL','PRESS','*OFF*'] pos += 6 sumstring += ("Envelopes: \n") for x in range(4): pnam = "ENV" + str(x+1) linexp = ['L','X'] secrel = [' ','R'] sumstring += ("%s L1=%3i L2=%3i L3=%3i | " % (pnam,f[pos+0],f[pos+1],f[pos+2])) sumstring += ("T1=%3i T2=%3i T3=%3i T4=%3i%s | " % (f[pos+3],f[pos+4],f[pos+5],f[pos+6] & 63,secrel[f[pos+6] >> 7])) sumstring += ("LV=%3i%s T1-V=%3i TK=%3i\n" % ((f[pos+7] & 252),linexp[(f[pos+7]&1)],f[pos+8],f[pos+9])) pos += 10 sumstring += ("-------------------------- \n") sumstring += ("Low Frequency Oscillators: \n") for x in range(3): pnam = "LFO" + str(x+1) waves = [' TRI',' SAW',' SQR','NOISE'] ms1 = f[pos+1]>>6 ms2 = f[pos+2]>>6 ms = (ms2<<2) + ms1 sumstring += ("%s LFO FREQ=%3i RESET=%s HUMAN=%s WAV=%s | " % (pnam, f[pos+0],onoff[f[pos+3]>>7],onoff[(f[pos+3]>>6)&1],waves[f[pos+0]>>6])) sumstring += ("LFO L1=%2i DELAY=%2i L2=%3i MOD=%5s\n" % (f[pos+1],f[pos+3],f[pos+2],mods[ms])) pos += 4 sumstring += ("-------------------------- \n") sumstring += ("Oscillators: \n") for x in range(3): pnam = "OSC" + str(x+1) waves = ['SAW','BELL','SINE','SQUARE','PULSE','NOISE1','NOISE2','NOISE3','BASS','PIANO','EL PNO','VOICE1','VOICE2','KICK','REED','ORGAN','SYNTH1','SYNTH2','SYNTH3','FORMT1','FORMT2','FORMT3','FORMT4','FORMT5','PULSE2','SQR2','4OCTS','PRIME','BASS2','EPNO2','OCTAVE','OCT+5','SAW2','TRIANG','REED2','REED3','GRIT1','GRIT2','GRIT3','GLINT1','GLINT2','GLINT3','CLAV','BRASS','STRING','DIGIT1','DIGIT2','BELL2','ALIEN','BREATH','VOICE3','STEAM','METAL','CHIME','BOWING','PICK1','PICK2','MALLET','SLAP','PLINK','PLUCK','PLUNK','CLICK','CHIFF','THUMP','LOGDRM','KICK2','SNARE','TOMTOM','HIHAT','DRUMS1','DRUMS2','DRUMS3','DRUMS4','DRUMS5'] octav = int(f[pos+0]/12-3) sumstring += ("%s OCT=%2i SEMI=%2i FINE=%2i WAVE=%6s | " % (pnam,octav,f[pos+0]%12,(f[pos+1]>>3),waves[f[pos+5]])) sumstring += ("MOD1=%5s Depth=%3i MOD2=%5s Depth=%3i\n" % (mods[f[pos+2]&15],f[pos+3],mods[(f[pos+2]&0xF0)>>4],f[pos+4])) sumstring += (" DCA Level=%3i OUTPUT=%s | " % (f[pos+6]&127,onoff[f[pos+6]>>7])) sumstring += ("MOD1=%5s Depth=%3i MOD2=%5s Depth=%3i\n" % (mods[f[pos+7]&15],f[pos+8],mods[(f[pos+7]&0xF0)>>4],f[pos+9])) pos += 10 sumstring += ("-------------------------- \n") sumstring += ("Volume: DCA4 MOD=ENV4 Depth=%3i " % (f[pos+0]&127)) sumstring += ("PAN=%i MOD=%5s Depth=%i\n" % ((f[pos+12]>>4),mods[f[pos+12]&15],f[pos+13]&127)) sumstring += ("Modes : SYNC=%s AM=%s MONO=%s Glide=%2i\n" % (onoff[f[pos+1]>>7],onoff[f[pos+0]>>7],onoff[f[pos+5]>>7],f[pos+7]&63)) sumstring += ("Restart: VOICE=%s ENV=%s WAVE=%s Cycle=%s\n" % (onoff[f[pos+4]>>7],onoff[f[pos+6]>>7],onoff[f[pos+7]>>7],onoff[f[pos+13]>>7])) sumstring += ("------\n") sumstring += ("Filter : FREQ=%i Q=%i KEYBD=%3i\n" % (f[pos+1]&127,f[pos+2],f[pos+6]&127)) sumstring += (" MOD1=%5s Depth=%i " % (mods[f[pos+3]&15],f[pos+4]&127)) sumstring += ("MOD2=%5s Depth=%i\n" % (mods[f[pos+3]>>4],f[pos+5]&127)) sumstring += ("Split/Layer: \n") uplow = ['OFF','UPPER','LOWER'] sumstring += (" SPLIT/LAYER=%s Prog:%3i " % (onoff[f[pos+11]>>7],f[pos+11]&127)) sumstring += ("LAYER=%s Prog:%3i\n" % (onoff[f[pos+9]>>7],f[pos+9]&127)) sumstring += (" SPLIT=%s Prog:%3i " % (onoff[f[pos+10]>>7],f[pos+10]&127)) sumstring += ("SPLIT-KEY#%3i Direction: %s\n" % (f[pos+8]&127,uplow[f[pos+8]>>7])) sumstring += ("-------------------------- \n") if (inpmode == 'w'): if (exists(outfile)): modus = "a" else: modus = "w" with open(outfile, modus) as fout: fout.write(sumstring) print (sumstring) if (inpmode == 'w'): print ("--------------------------") print ("Data written into file %s" % outfile)