create parse function
This commit is contained in:
+172
-7
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user