create parse function

This commit is contained in:
[poww10s]
2020-09-09 04:04:52 -04:00
parent 16993352ca
commit e02e7232f5
+172 -7
View File
@@ -4,13 +4,178 @@ import "./App.css";
import FileIOComponent from "./components/FileIOComponent"; import FileIOComponent from "./components/FileIOComponent";
import MidiComponent from "./components/MidiComponent"; import MidiComponent from "./components/MidiComponent";
import EditorComponent from "./components/EditorComponent"; //import EditorComponent from "./components/EditorComponent";
import Parser from "binary-parser";
// converts SYSEX file to the dump format the system uses (and the implementation refers to)
function parse(binary) {
// check if the binary is a valid KORG-produced SYSEX file
if (binary.length !== 297) {
throw new Error("incorrect file length");
}
if (binary[0] !== 0xf0) {
throw new Error("first byte is not SYSEX byte");
}
if (binary[1] !== 0x42) {
throw new Error("manufacturer code is not KORG");
}
if (binary[4] !== 0x40) {
throw new Error("not a program dump");
}
if (binary[5] !== 0x00) {
// in all files found in the wild it's always zero
throw new Error("sixth byte is not zero");
}
if (binary[binary.length - 1] !== 0xf7) {
throw new Error("last byte is does not end SYSEX message");
}
const trimmedBinary = binary.slice(5, -1);
// every eigth byte is padding, so we remove it
const unpaddedBinary = trimmedBinary.filter((el, idx) => idx % 8);
const timbre = new Parser()
.uint8("midiChannel")
.bit2("assignMode")
.bit1("eg2Reset")
.bit1("eg1Reset")
.bit1("triggerMode")
.bit2("keyPriority")
.uint8("unisonDetune")
.uint8("pitchTune")
.uint8("pitchBendRange")
.uint8("pitchTranspose")
.uint8("pitchVibratoInt")
.uint8("osc1Wave")
.uint8("osc1WaveCtrl1")
.uint8("osc1WaveCtrl2")
.uint8("osc1DWGSWave")
.seek(1)
.bit2("ignore")
.bit2("osc2ModSelect")
.bit2("ignore")
.bit2("osc2Wave")
.uint8("osc2Semitone")
.uint8("osc2Tune")
.bit1("ignore")
.bit7("portamentoTime")
.uint8("osc1Level")
.uint8("osc2Level")
.uint8("noiseLevel")
.uint8("filterType")
.uint8("filterCutoff")
.uint8("filterResonance")
.uint8("filterEG1Intensity")
.uint8("filterVelocitySense")
.uint8("filterKeyboardTrack")
.uint8("ampLevel")
.uint8("ampPanpot")
.bit1("ignore")
.bit1("ampSW")
.bit6("ignore")
.bit1("ampDistortion")
.uint8("ampVelocitySense")
.uint8("ampKeyboardTrack")
.uint8("eg1Attack")
.uint8("eg1Decay")
.uint8("eg1Sustain")
.uint8("eg1Release")
.uint8("eg2Attack")
.uint8("eg2Decay")
.uint8("eg2Sustain")
.uint8("eg2Release")
.bit2("ignore")
.bit2("lfo1KeySync")
.bit2("ignore")
.bit2("lfo1Wave")
.uint8("lfo1Freq")
.bit1("lfo1TempoSync")
.bit2("ignore")
.bit5("lfo1SyncNote")
.bit2("ignore")
.bit2("lfo2KeySync")
.bit2("ignore")
.bit2("lfo2Wave")
.uint8("lfo2Freq")
.bit1("lfo2TempoSync")
.bit2("ignore")
.bit5("lfo2SyncNote")
.bit4("patch1Dest")
.bit4("patch1Src")
.uint8("patch1Intensity")
.bit4("patch2Dest")
.bit4("patch2Src")
.uint8("patch2Intensity")
.bit4("patch3Dest")
.bit4("patch3Src")
.uint8("patch3Intensity")
.bit4("patch4Dest")
.bit4("patch4Src")
.uint8("patch4Intensity");
const parser = new Parser()
.endianness("big")
.string("name", ["ASCII", 12])
.seek(3)
.bit5("ignore")
.bit3("arpTriggerLength")
.bit8("arpTriggerPattern")
.bit2("ignore")
.bit2("voiceMode")
.bit4("ignore")
.bit4("scaleKey")
.bit4("scaleType")
.seek(1)
.bit1("delayFxSync")
.bit3("ignore")
.bit4("delayFXTimeBase")
.uint8("delayFXDelayTime")
.uint8("delayFXDepth")
.uint8("delayFXType")
.uint8("modFXLFOSpeed")
.uint8("modFXDepth")
.uint8("modFXType")
.uint8("eqHiFreq")
.uint8("eqHiGain")
.uint8("eqLowFreq")
.uint8("eqLowGain")
.uint8be("arpTempo")
.uint8le("arpSeqTempo")
.bit1("arpOnOff")
.bit1("arpLatchOnOff")
.bit2("arpTarget")
.bit1("ignore")
.bit1("arpKeySync")
.bit4("arpRange")
.bit4("arpType")
.uint8("arpGateTime")
.uint8("arpResolution")
.uint8("arpSwing")
.uint8("kbdOctave")
.nest("timbre1", { type: timbre })
.seek(56)
.nest("timbre2", { type: timbre })
.seek(56);
}
function PatchEditor() { function PatchEditor() {
const defaultPatch = { const defaultPatch = {
name: "", name: "",
arpeggio: { length: 8, pattern: [0, 0, 0, 0, 0, 0, 0, 0] }, arpeggio: { length: 8, pattern: [0, 0, 0, 0, 0, 0, 0, 0] },
arpeggio2: {}, arpeggio2: {
tempo: 20,
seq: 0,
on: false,
latch: false,
target: 0,
keySync: false,
type: 0, // 0 - 5
range: 0, // 0 - 4
gate: 0, // 0 - 100
resolution: 0,
swing: 0,
},
voiceMode: 0, voiceMode: 0,
scaleKey: 0, // C scaleKey: 0, // C
scaleType: 0, // Equal Temperment scaleType: 0, // Equal Temperment
@@ -23,13 +188,13 @@ function PatchEditor() {
synthParameter3: {}, // this is for vocoder mode synthParameter3: {}, // this is for vocoder mode
}; };
const [patch, updatePatch] = useState(defaultPatch); const [patch, setPatch] = useState(defaultPatch);
return ( return (
<div> <div>
<FileIOComponent /> <FileIOComponent getBinaryData={parse} />
<EditorComponent /> {/*<EditorComponent />
<MidiComponent /> <MidiComponent />*/}
</div> </div>
); );
} }
@@ -40,7 +205,7 @@ function App() {
<header className="App-header"> <header className="App-header">
<img src={logo} className="App-logo" alt="logo" /> <img src={logo} className="App-logo" alt="logo" />
<div> <div>
<MidiComponent /> <PatchEditor />
</div> </div>
<a <a
className="App-link" className="App-link"