UNPKG

dxex

Version:

Create and parse sysex for Yamaha DX synthesizers.

74 lines (73 loc) 3.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveSysex = void 0; /** * Resolve sysex data. * @param {DX21Voice} data The data to resolve. * @param {DXResolveOptions} options * @return {number[]} */ function resolveSysex(data, options) { const mode = options?.mode || 'bulk32'; const res = []; if (mode === 'bulk32') { for (let i = 0; i < 32; i++) { res.push(..._resolveChunk(data[i]), ...Array(55).fill(0)); } } else { } res.push(_checksum(res)); res.unshift(0xF0, 0x43, 0x00, 0x04, 0x20, 0x00); res.push(0xF7); return res; } exports.resolveSysex = resolveSysex; /** * Resolve a single DX voice. * @param {DX21Voice} data * @return {number[]} */ function _resolveChunk(data) { const res = []; for (const i of [3, 1, 2, 0]) { res.push(data.op[i].envelopeGenerator.attackRate, data.op[i].envelopeGenerator.decay1Rate, data.op[i].envelopeGenerator.decay2Rate, data.op[i].envelopeGenerator.releaseRate, data.op[i].envelopeGenerator.decay1Level, data.op[i].keyboardScalingLevel, ((data.op[i].amplitudeModulationEnable << 6) + (data.op[i].egBiasSensitivity << 3) + data.op[i].keyVelocity), data.op[i].outputLevel, data.op[i].oscillatorFrequency, ((data.op[i].keyboardScalingRate << 3) + data.op[i].detune)); } res.push(((data.lfo.lfoSync << 6) + (data.feedbackLevel << 3) + data.algorithm), data.lfo.lfoSpeed, data.lfo.lfoDelay, data.lfo.pitchModulationDepth, data.lfo.amplitudeModulationDepth, ((data.lfo.pitchModulationSensitivity << 5) + (data.lfo.amplitudeModulationSensitivity << 2) + data.lfo.lfoWave), data.transpose, data.performance.pitchBendRange, ((data.performance.chorusSwitch << 4) + (data.performance.playMode << 3) + (data.performance.sustainFootSwitch << 2) + (data.performance.portamentoFootSwitch << 1) + data.performance.portamentoMode), data.performance.portamentoTime, data.performance.footVolume, data.performance.modulationWheelPitchModulationRange, data.performance.modulationWheelAmplitudeModulationRange, data.performance.breathControlPitchModulationRange, data.performance.breathControlAmplitudeModulationRange, data.performance.breathControlPitchBiasRange, data.performance.breathControlEgBiasRange, ..._formatVoiceName(data.voiceName), data.pitchEnvelopeGenerator.pitchEgRate1, data.pitchEnvelopeGenerator.pitchEgRate2, data.pitchEnvelopeGenerator.pitchEgRate3, data.pitchEnvelopeGenerator.pitchEgLevel1, data.pitchEnvelopeGenerator.pitchEgLevel2, data.pitchEnvelopeGenerator.pitchEgLevel3); return res; } /** * Create a checksum. * @param {data} data * @return {number} */ function _checksum(data) { let sum = 0; for (let i = 0; i < data.length; i++) { sum += data[i]; } return sum > 0 ? -sum & 127 : sum & 127; } /** * Format voice name to 10-byte ASCII. * @param {string} voiceName * @return {number[]} */ function _formatVoiceName(voiceName) { const res = Array(10).fill(0); for (let i = 0; i < Math.min(voiceName.length, 10); i++) { res[i] = voiceName.charCodeAt(i); } return res; }