move parsing code over from master
This commit is contained in:
Generated
+13
@@ -3764,6 +3764,14 @@
|
|||||||
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
|
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
|
||||||
"optional": true
|
"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": {
|
"bluebird": {
|
||||||
"version": "3.7.2",
|
"version": "3.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||||
@@ -14092,6 +14100,11 @@
|
|||||||
"is-fullwidth-code-point": "^2.0.0"
|
"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": {
|
"snapdragon": {
|
||||||
"version": "0.8.2",
|
"version": "0.8.2",
|
||||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.5.0",
|
"@testing-library/react": "^9.5.0",
|
||||||
"@testing-library/user-event": "^7.2.1",
|
"@testing-library/user-event": "^7.2.1",
|
||||||
|
"binary-parser-encoder": "^1.5.3",
|
||||||
"rc-slider": "^9.6.3",
|
"rc-slider": "^9.6.3",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^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;
|
height: 40vmin;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
padding: 0.5em;
|
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 {
|
.menu-title {
|
||||||
|
|||||||
@@ -110,7 +110,12 @@ export default function MainMenu() {
|
|||||||
<div
|
<div
|
||||||
className={`menu ${open.className}`}
|
className={`menu ${open.className}`}
|
||||||
onAnimationEnd={AnimationEnd}>
|
onAnimationEnd={AnimationEnd}>
|
||||||
<img src={logo} className="menu-logo" alt="logo" />
|
<img
|
||||||
|
src={logo}
|
||||||
|
className="menu-logo"
|
||||||
|
alt="logo"
|
||||||
|
draggable={false}
|
||||||
|
/>
|
||||||
<header className="menu-title">
|
<header className="menu-title">
|
||||||
<h1>Alapatch</h1>
|
<h1>Alapatch</h1>
|
||||||
<h2>A microKORG Patch Editor</h2>
|
<h2>A microKORG Patch Editor</h2>
|
||||||
|
|||||||
Reference in New Issue
Block a user