dxex
Version:
Create and parse sysex for Yamaha DX synthesizers.
74 lines (73 loc) • 3.23 kB
JavaScript
;
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;
}