move parsing code over from master
This commit is contained in:
Generated
+13
@@ -3764,6 +3764,14 @@
|
||||
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
|
||||
"optional": true
|
||||
},
|
||||
"binary-parser-encoder": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/binary-parser-encoder/-/binary-parser-encoder-1.5.3.tgz",
|
||||
"integrity": "sha512-yu3tdLBYqPIwGRaXyswLoLrhaffkuZkNuXveq/jYoyBHQbFMjamHCWPFOmI2Qz+Go0Rh6wE9f6tt0EAvsgDD0g==",
|
||||
"requires": {
|
||||
"smart-buffer": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||
@@ -14092,6 +14100,11 @@
|
||||
"is-fullwidth-code-point": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"smart-buffer": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz",
|
||||
"integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw=="
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.5.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"binary-parser-encoder": "^1.5.3",
|
||||
"rc-slider": "^9.6.3",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
import { Parser } from 'binary-parser-encoder';
|
||||
|
||||
function parse(parser, 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((_, idx) => idx % 8);
|
||||
|
||||
const buffer = Buffer.from(
|
||||
Buffer.from(unpaddedBinary).toString('hex'),
|
||||
'hex'
|
||||
);
|
||||
|
||||
console.log(parser.parse(buffer));
|
||||
|
||||
// do stuff with the parsed object
|
||||
}
|
||||
|
||||
const timbre = new Parser()
|
||||
.int8('midiChannel') // in 7 bits
|
||||
.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')
|
||||
.skip(1)
|
||||
.bit2('not-use1')
|
||||
.bit2('osc2ModSelect')
|
||||
.bit2('not-use2')
|
||||
.bit2('osc2Wave')
|
||||
.uint8('osc2Semitone')
|
||||
.uint8('osc2Tune')
|
||||
.bit1('not-use3')
|
||||
.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('not-use4')
|
||||
.bit1('ampSW')
|
||||
.bit5('not-use5')
|
||||
.bit1('ampDistortion')
|
||||
.uint8('ampVelocitySense')
|
||||
.uint8('ampKeyboardTrack')
|
||||
.uint8('eg1Attack')
|
||||
.uint8('eg1Decay')
|
||||
.uint8('eg1Sustain')
|
||||
.uint8('eg1Release')
|
||||
.uint8('eg2Attack')
|
||||
.uint8('eg2Decay')
|
||||
.uint8('eg2Sustain')
|
||||
.uint8('eg2Release')
|
||||
.bit2('not-use6')
|
||||
.bit2('lfo1KeySync')
|
||||
.bit2('not-use7')
|
||||
.bit2('lfo1Wave')
|
||||
.uint8('lfo1Freq')
|
||||
.bit1('lfo1TempoSync')
|
||||
.bit2('not-use8')
|
||||
.bit5('lfo1SyncNote')
|
||||
.bit2('not-use9')
|
||||
.bit2('lfo2KeySync')
|
||||
.bit2('not-use10')
|
||||
.bit2('lfo2Wave')
|
||||
.uint8('lfo2Freq')
|
||||
.bit1('lfo2TempoSync')
|
||||
.bit2('not-use11')
|
||||
.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 vocoder = new Parser()
|
||||
.int8('midiChannel') // in 7 bits
|
||||
.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')
|
||||
.skip(1) // dummy byte
|
||||
.bit7('not-use17')
|
||||
.bit1('HPF Gate')
|
||||
.skip(1)
|
||||
.bit1('not-use18')
|
||||
.bit7('portamentoTime')
|
||||
.uint8('osc1Level')
|
||||
.uint8('ext1Level')
|
||||
.uint8('noiseLevel')
|
||||
.uint8('hpfLevel')
|
||||
.uint8('gateSense')
|
||||
.uint8('threshold')
|
||||
.uint8('shift')
|
||||
.uint8('cutoff')
|
||||
.uint8('resonance')
|
||||
.uint8('modSource')
|
||||
.uint8('intensity')
|
||||
.uint8('efSense')
|
||||
.uint8('ampLevel')
|
||||
.uint8('ampDirectLevel')
|
||||
.bit7('not-use19')
|
||||
.bit1('ampDistortion')
|
||||
.uint8('velocitySense')
|
||||
.uint8('keyTrack')
|
||||
// always 0
|
||||
.uint8('eg1Attack')
|
||||
// always 0
|
||||
.uint8('eg1Decay')
|
||||
// always 127
|
||||
.uint8('eg1Sustain')
|
||||
// always 0
|
||||
.uint8('eg1Release')
|
||||
.uint8('eg2Attack')
|
||||
.uint8('eg2Decay')
|
||||
.uint8('eg2Sustain')
|
||||
.uint8('eg2Release')
|
||||
.bit2('not-use20')
|
||||
.bit2('lfo1KeySync')
|
||||
.bit2('not-use21')
|
||||
.bit2('lfo1Wave')
|
||||
.uint8('lfo1Freq')
|
||||
.bit1('lfo1TempoSync')
|
||||
.bit2('not-use22')
|
||||
.bit5('lfo1SyncNote')
|
||||
.bit2('not-use23')
|
||||
.bit2('lfo2KeySync')
|
||||
.bit2('not-use24')
|
||||
.bit2('lfo2Wave')
|
||||
.uint8('lfo2Freq')
|
||||
.bit1('lfo2TempoSync')
|
||||
.bit2('not-use25')
|
||||
.bit5('lfo2SyncNote')
|
||||
.array('levels', {
|
||||
type: 'uint8',
|
||||
length: 16,
|
||||
})
|
||||
.array('pans', {
|
||||
type: 'uint8',
|
||||
length: 16,
|
||||
})
|
||||
.array('efSenseLevels', {
|
||||
type: 'uint8',
|
||||
length: 16,
|
||||
});
|
||||
|
||||
const parser = new Parser()
|
||||
.endianess('big')
|
||||
.string('name', { encoding: 'ASCII', length: 12 })
|
||||
.skip(2)
|
||||
.bit5('not-use12')
|
||||
.bit3('arpTriggerLength')
|
||||
.bit8('arpTriggerPattern')
|
||||
.bit2('not-use13')
|
||||
.bit2('voiceMode')
|
||||
.bit4('not-use14')
|
||||
.bit4('scaleKey')
|
||||
.bit4('scaleType')
|
||||
.skip(1)
|
||||
.bit1('delayFxSync')
|
||||
.bit3('not-use15')
|
||||
.bit4('delayFXTimeBase')
|
||||
.uint8('delayFXDelayTime')
|
||||
.uint8('delayFXDepth')
|
||||
.uint8('delayFXType')
|
||||
.uint8('modFXLFOSpeed')
|
||||
.uint8('modFXDepth')
|
||||
.uint8('modFXType')
|
||||
.uint8('eqHiFreq')
|
||||
.uint8('eqHiGain')
|
||||
.uint8('eqLowFreq')
|
||||
.uint8('eqLowGain')
|
||||
.uint8('arpTempo')
|
||||
.uint8('arpSeqTempo')
|
||||
.bit1('arpOnOff')
|
||||
.bit1('arpLatchOnOff')
|
||||
.bit2('arpTarget')
|
||||
.bit1('not-use16')
|
||||
.bit1('arpKeySync')
|
||||
.bit4('arpRange')
|
||||
.bit4('arpType')
|
||||
.uint8('arpGateTime')
|
||||
.uint8('arpResolution')
|
||||
.uint8('arpSwing')
|
||||
.uint8('kbdOctave')
|
||||
.nest('timbre1', { type: timbre })
|
||||
// dummy bytes *see documentation
|
||||
.skip(56)
|
||||
.nest('timbre2', { type: timbre })
|
||||
// dummy bytes *see documentation
|
||||
.skip(56)
|
||||
.nest('vocoder', { type: vocoder })
|
||||
// dummy bytes *see documentation
|
||||
.skip(111);
|
||||
|
||||
// converts patch object to dump format the system uses
|
||||
function serialise(parser, object) {
|
||||
console.log(parser.encode(object));
|
||||
}
|
||||
@@ -86,6 +86,15 @@
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
padding: 0.5em;
|
||||
-webkit-user-drag: none;
|
||||
-khtml-user-drag: none;
|
||||
-moz-user-drag: none;
|
||||
-o-user-drag: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.menu-title {
|
||||
|
||||
@@ -110,7 +110,12 @@ export default function MainMenu() {
|
||||
<div
|
||||
className={`menu ${open.className}`}
|
||||
onAnimationEnd={AnimationEnd}>
|
||||
<img src={logo} className="menu-logo" alt="logo" />
|
||||
<img
|
||||
src={logo}
|
||||
className="menu-logo"
|
||||
alt="logo"
|
||||
draggable={false}
|
||||
/>
|
||||
<header className="menu-title">
|
||||
<h1>Alapatch</h1>
|
||||
<h2>A microKORG Patch Editor</h2>
|
||||
|
||||
Reference in New Issue
Block a user