214 lines
7.4 KiB
JavaScript
214 lines
7.4 KiB
JavaScript
import { getBits, toBitArray } from '../utils/functions';
|
|
|
|
export default function parse(sysex) {
|
|
const patch = build_patch(sysex.slice(0, 38));
|
|
switch (patch.voice_mode) {
|
|
default:
|
|
case 0:
|
|
return [
|
|
{ ...patch },
|
|
{ ...build_timbre(1, sysex.slice(38, 146)) },
|
|
null,
|
|
null,
|
|
];
|
|
|
|
case 2:
|
|
return [
|
|
{ ...patch },
|
|
{ ...build_timbre(1, sysex.slice(38, 146)) },
|
|
{ ...build_timbre(2, sysex.slice(146, 254)) },
|
|
null,
|
|
];
|
|
case 3:
|
|
return [
|
|
{ ...patch },
|
|
null,
|
|
null,
|
|
{ ...build_vocoder(sysex.slice(38, 142)) },
|
|
];
|
|
}
|
|
}
|
|
|
|
function build_patch(patch) {
|
|
return {
|
|
/* BYTES 0, 11 NOT 0, 12 */
|
|
program_name: String.fromCharCode(...patch.slice(0, 12)),
|
|
/* BYTES 12 / 13 SKIPPED */
|
|
arp_trigger_length: patch[14],
|
|
arp_trigger_pattern: toBitArray(patch[15]),
|
|
voice_mode: getBits(patch[16], 4, 5),
|
|
scale_key: getBits(patch[17], 4, 7),
|
|
scale_type: getBits(patch[17], 0, 3),
|
|
/* BYTE 18 SKIPPED */
|
|
delay_sync: (patch[19] & (1 << 7)) !== 0,
|
|
delay_timebase: getBits(patch[19], 0, 3),
|
|
delay_time: patch[20],
|
|
delay_depth: patch[21],
|
|
delay_type: patch[22],
|
|
mod_lfo_speed: patch[23],
|
|
mod_depth: patch[24],
|
|
mod_type: patch[25],
|
|
eq_hi_freq: patch[26],
|
|
eq_hi_gain: patch[27],
|
|
eq_low_freq: patch[28],
|
|
eq_low_gain: patch[29],
|
|
arp_tempo: (patch[30] << 8) + patch[31],
|
|
arp_on_off: (patch[32] & (1 << 7)) !== 0,
|
|
arp_latch: (patch[32] & (1 << 6)) !== 0,
|
|
arp_target: getBits(patch[32], 4, 5),
|
|
arp_key_sync: (patch[32] & (1 << 0)) !== 0,
|
|
arp_type: getBits(patch[33], 0, 3),
|
|
arp_range: getBits(patch[33], 4, 7),
|
|
arp_gate_time: patch[34],
|
|
arp_resolution: patch[35],
|
|
arp_swing: patch[36],
|
|
keyboard_octave: patch[37],
|
|
};
|
|
}
|
|
|
|
function build_timbre(num, timbre) {
|
|
return {
|
|
[`t${num}_midi_channel`]: timbre[0],
|
|
[`t${num}_assign_mode`]: getBits(timbre[1], 6, 7),
|
|
[`t${num}_eg_2_reset`]: (timbre[1] & (1 << 5)) !== 0,
|
|
[`t${num}_eg_1_reset`]: (timbre[1] & (1 << 4)) !== 0,
|
|
[`t${num}_trigger_mode`]: (timbre[1] & (1 << 3)) !== 0,
|
|
[`t${num}_key_priority`]: getBits(timbre[1], 0, 1),
|
|
[`t${num}_unison_detune`]: timbre[2],
|
|
[`t${num}_tune`]: timbre[3],
|
|
[`t${num}_bend_range`]: timbre[4],
|
|
[`t${num}_transpose`]: timbre[5],
|
|
[`t${num}_vibrato_int`]: timbre[6],
|
|
[`t${num}_osc_1_wave`]: timbre[7],
|
|
[`t${num}_osc_1_ctrl_1`]: timbre[8],
|
|
[`t${num}_osc_1_ctrl_2`]: timbre[9],
|
|
[`t${num}_osc_1_dgws`]: timbre[10],
|
|
/* SKIP BYTE 11 */
|
|
[`t${num}_osc_2_mod_select`]: getBits(timbre[12], 4, 5),
|
|
[`t${num}_osc_2_wave`]: getBits(timbre[12], 0, 1),
|
|
[`t${num}_osc_2_semitone`]: timbre[13],
|
|
[`t${num}_osc_2_tune`]: timbre[14],
|
|
[`t${num}_portamento`]: getBits(timbre[15], 0, 6),
|
|
[`t${num}_osc_1_level`]: timbre[16],
|
|
[`t${num}_osc_2_level`]: timbre[17],
|
|
[`t${num}_noise_level`]: timbre[18],
|
|
[`t${num}_filter_type`]: timbre[19],
|
|
[`t${num}_filter_cutoff`]: timbre[20],
|
|
[`t${num}_filter_resonance`]: timbre[21],
|
|
[`t${num}_filter_eg_intensity`]: timbre[22],
|
|
[`t${num}_filter_vel_sense`]: timbre[23],
|
|
[`t${num}_filter_key_track`]: timbre[24],
|
|
[`t${num}_amp_level`]: timbre[25],
|
|
[`t${num}_amp_panpot`]: timbre[26],
|
|
[`t${num}_amp_switch`]: (timbre[27] & (1 << 6)) !== 0,
|
|
[`t${num}_amp_distortion`]: (timbre[27] & (1 << 0)) !== 0,
|
|
[`t${num}_amp_vel_sense`]: timbre[28],
|
|
[`t${num}_amp_key_track`]: timbre[29],
|
|
[`t${num}_eg_1_attack`]: timbre[30],
|
|
[`t${num}_eg_1_decay`]: timbre[31],
|
|
[`t${num}_eg_1_sustain`]: timbre[32],
|
|
[`t${num}_eg_1_release`]: timbre[33],
|
|
[`t${num}_eg_2_attack`]: timbre[34],
|
|
[`t${num}_eg_2_decay`]: timbre[35],
|
|
[`t${num}_eg_2_sustain`]: timbre[36],
|
|
[`t${num}_eg_2_release`]: timbre[37],
|
|
[`t${num}_lfo_1_key_sync`]: getBits(timbre[38], 4, 5),
|
|
[`t${num}_lfo_1_wave`]: getBits(timbre[38], 0, 1),
|
|
[`t${num}_lfo_1_frequency`]: timbre[39],
|
|
[`t${num}_lfo_1_tempo_sync`]: (timbre[40] & (1 << 7)) !== 0,
|
|
[`t${num}_lfo_1_sync_note`]: getBits(timbre[40], 0, 4),
|
|
[`t${num}_lfo_2_key_sync`]: getBits(timbre[41], 4, 5),
|
|
[`t${num}_lfo_2_wave`]: getBits(timbre[41], 0, 1),
|
|
[`t${num}_lfo_2_frequency`]: timbre[42],
|
|
[`t${num}_lfo_2_tempo_sync`]: (timbre[43] & (1 << 7)) !== 0,
|
|
[`t${num}_lfo_2_sync_note`]: getBits(timbre[43], 0, 4),
|
|
[`t${num}_patch_1_dest`]: getBits(timbre[44], 4, 6),
|
|
[`t${num}_patch_1_src`]: getBits(timbre[44], 0, 2),
|
|
[`t${num}_patch_1_intensity`]: timbre[45],
|
|
[`t${num}_patch_2_dest`]: getBits(timbre[46], 4, 6),
|
|
[`t${num}_patch_2_src`]: getBits(timbre[46], 0, 2),
|
|
[`t${num}_patch_2_intensity`]: timbre[47],
|
|
[`t${num}_patch_3_dest`]: getBits(timbre[48], 4, 6),
|
|
[`t${num}_patch_3_src`]: getBits(timbre[48], 0, 2),
|
|
[`t${num}_patch_3_intensity`]: timbre[49],
|
|
[`t${num}_patch_4_dest`]: getBits(timbre[50], 4, 6),
|
|
[`t${num}_patch_4_src`]: getBits(timbre[50], 0, 2),
|
|
[`t${num}_patch_4_intensity`]: timbre[51],
|
|
};
|
|
}
|
|
|
|
function build_vocoder(vocoder) {
|
|
return {
|
|
v_midi_channel: vocoder[0],
|
|
v_assign_mode: getBits(vocoder[1], 6, 7),
|
|
v_eg_2_reset: (vocoder[1] & (1 << 5)) !== 0,
|
|
v_eg_1_reset: (vocoder[1] & (1 << 4)) !== 0,
|
|
v_trigger_mode: (vocoder[1] & (1 << 3)) !== 0,
|
|
v_key_priority: getBits(vocoder[1], 0, 1),
|
|
v_unison_detune: vocoder[2],
|
|
v_tune: vocoder[3],
|
|
v_bend_range: vocoder[4],
|
|
v_transpose: vocoder[5],
|
|
v_vibrato_int: vocoder[6],
|
|
v_osc_wave: vocoder[7],
|
|
v_osc_ctrl_1: vocoder[8],
|
|
v_osc_ctrl_2: vocoder[9],
|
|
v_osc_dgws: vocoder[10],
|
|
/* BYTE 11 SKIPPED */
|
|
v_audio_in_hpf_gate: (vocoder[12] & (1 << 0)) !== 0,
|
|
/* BYTE 13 SKIPPED */
|
|
v_portamento_time: getBits(vocoder[14], 0, 6),
|
|
v_osc_level: vocoder[15],
|
|
v_ext_level: vocoder[16],
|
|
v_noise_level: vocoder[17],
|
|
v_audio_in_hpf_level: vocoder[18],
|
|
v_audio_in_gate_sense: vocoder[19],
|
|
v_audio_in_threshold: vocoder[20],
|
|
v_filter_shift: vocoder[21],
|
|
v_filter_cutoff: vocoder[22],
|
|
v_filter_resonance: vocoder[23],
|
|
v_filter_mod_source: vocoder[24],
|
|
v_filter_intensity: vocoder[25],
|
|
v_filter_e_f_sense: vocoder[26],
|
|
v_amp_level: vocoder[27],
|
|
v_amp_direct_level: vocoder[28],
|
|
v_amp_distortion: (vocoder[29] & (1 << 0)) !== 0,
|
|
v_amp_vel_sense: vocoder[30],
|
|
v_amp_key_track: vocoder[31],
|
|
v_eg_1_attack: vocoder[32],
|
|
v_eg_1_decay: vocoder[33],
|
|
v_eg_1_sustain: vocoder[34],
|
|
v_eg_1_release: vocoder[35],
|
|
v_eg_2_attack: vocoder[36],
|
|
v_eg_2_decay: vocoder[37],
|
|
v_eg_2_sustain: vocoder[38],
|
|
v_eg_2_release: vocoder[39],
|
|
v_lfo_1_key_sync: getBits(vocoder[40], 4, 5),
|
|
v_lfo_1_wave: getBits(vocoder[40], 0, 1),
|
|
v_lfo_1_frequency: vocoder[41],
|
|
v_lfo_1_tempo_sync: (vocoder[42] & (1 << 7)) !== 0,
|
|
v_lfo_1_sync_note: getBits(vocoder[42], 0, 4),
|
|
v_lfo_2_key_sync: getBits(vocoder[43], 4, 5),
|
|
v_lfo_2_wave: getBits(vocoder[43], 0, 1),
|
|
v_lfo_2_frequency: vocoder[44],
|
|
v_lfo_2_tempo_sync: (vocoder[45] & (1 << 7)) !== 0,
|
|
v_lfo_2_sync_note: getBits(vocoder[45], 0, 4),
|
|
v_level_1: vocoder[46],
|
|
v_level_2: vocoder[47],
|
|
v_level_3: vocoder[48],
|
|
v_level_4: vocoder[49],
|
|
v_level_5: vocoder[50],
|
|
v_level_6: vocoder[51],
|
|
v_level_7: vocoder[52],
|
|
v_level_8: vocoder[53],
|
|
v_pan_1: vocoder[62],
|
|
v_pan_2: vocoder[63],
|
|
v_pan_3: vocoder[64],
|
|
v_pan_4: vocoder[65],
|
|
v_pan_5: vocoder[66],
|
|
v_pan_6: vocoder[67],
|
|
v_pan_7: vocoder[68],
|
|
v_pan_8: vocoder[69],
|
|
};
|
|
}
|