spessasynth_core 4.0.23 → 4.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +15 -8
- package/dist/index.js +1114 -950
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3007,6 +3007,32 @@ var BasicMIDI2 = class _BasicMIDI {
|
|
|
3007
3007
|
getUsedProgramsAndKeys(soundbank) {
|
|
3008
3008
|
return getUsedProgramsAndKeys(this, soundbank);
|
|
3009
3009
|
}
|
|
3010
|
+
/**
|
|
3011
|
+
* Preloads all voices for this sequence in a given synth.
|
|
3012
|
+
* This caches all the needed voices for playing back this sequencer, resulting in a smooth playback.
|
|
3013
|
+
* The sequencer calls this function by default when loading the songs.
|
|
3014
|
+
* @param synth
|
|
3015
|
+
*/
|
|
3016
|
+
preloadSynth(synth) {
|
|
3017
|
+
SpessaSynthGroupCollapsed(
|
|
3018
|
+
`%cPreloading samples...`,
|
|
3019
|
+
consoleColors.info
|
|
3020
|
+
);
|
|
3021
|
+
const used = this.getUsedProgramsAndKeys(synth.soundBankManager);
|
|
3022
|
+
used.forEach((combos, preset) => {
|
|
3023
|
+
SpessaSynthInfo(
|
|
3024
|
+
`%cPreloading used samples on %c${preset.name}%c...`,
|
|
3025
|
+
consoleColors.info,
|
|
3026
|
+
consoleColors.recognized,
|
|
3027
|
+
consoleColors.info
|
|
3028
|
+
);
|
|
3029
|
+
for (const combo of combos) {
|
|
3030
|
+
const [midiNote, velocity] = combo.split("-").map(Number);
|
|
3031
|
+
synth.getVoicesForPreset(preset, midiNote, velocity, midiNote);
|
|
3032
|
+
}
|
|
3033
|
+
});
|
|
3034
|
+
SpessaSynthGroupEnd();
|
|
3035
|
+
}
|
|
3010
3036
|
/**
|
|
3011
3037
|
* Updates all internal values of the MIDI.
|
|
3012
3038
|
* @param sortEvents if the events should be sorted by ticks. Recommended to be true.
|
|
@@ -3438,6 +3464,10 @@ var BasicMIDI2 = class _BasicMIDI {
|
|
|
3438
3464
|
loopEnd = this.lastVoiceEventTick;
|
|
3439
3465
|
}
|
|
3440
3466
|
this.loop = { start: loopStart, end: loopEnd, type: loopType };
|
|
3467
|
+
this.lastVoiceEventTick = Math.max(
|
|
3468
|
+
this.lastVoiceEventTick,
|
|
3469
|
+
this.loop.end
|
|
3470
|
+
);
|
|
3441
3471
|
SpessaSynthInfo(
|
|
3442
3472
|
`%cLoop points: start: %c${this.loop.start}%c end: %c${this.loop.end}`,
|
|
3443
3473
|
consoleColors.info,
|
|
@@ -3958,33 +3988,9 @@ function loadNewSequenceInternal(parsedMidi) {
|
|
|
3958
3988
|
this._midiData.embeddedSoundBank,
|
|
3959
3989
|
this._midiData.bankOffset
|
|
3960
3990
|
);
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
"%cPreloading samples...",
|
|
3965
|
-
consoleColors.info
|
|
3966
|
-
);
|
|
3967
|
-
const used = this._midiData.getUsedProgramsAndKeys(
|
|
3968
|
-
this.synth.soundBankManager
|
|
3969
|
-
);
|
|
3970
|
-
used.forEach((combos, preset) => {
|
|
3971
|
-
SpessaSynthInfo(
|
|
3972
|
-
`%cPreloading used samples on %c${preset.name}%c...`,
|
|
3973
|
-
consoleColors.info,
|
|
3974
|
-
consoleColors.recognized,
|
|
3975
|
-
consoleColors.info
|
|
3976
|
-
);
|
|
3977
|
-
for (const combo of combos) {
|
|
3978
|
-
const [midiNote, velocity] = combo.split("-").map(Number);
|
|
3979
|
-
this.synth.getVoicesForPreset(
|
|
3980
|
-
preset,
|
|
3981
|
-
midiNote,
|
|
3982
|
-
velocity,
|
|
3983
|
-
midiNote
|
|
3984
|
-
);
|
|
3985
|
-
}
|
|
3986
|
-
});
|
|
3987
|
-
SpessaSynthGroupEnd();
|
|
3991
|
+
if (this.preload) {
|
|
3992
|
+
this._midiData.preloadSynth(this.synth);
|
|
3993
|
+
}
|
|
3988
3994
|
}
|
|
3989
3995
|
this.currentMIDIPorts = this._midiData.tracks.map((t) => t.port);
|
|
3990
3996
|
this.midiPortChannelOffset = 0;
|
|
@@ -4582,8 +4588,6 @@ setResetValue(midiControllers.registeredParameterLSB, 127);
|
|
|
4582
4588
|
setResetValue(midiControllers.registeredParameterMSB, 127);
|
|
4583
4589
|
setResetValue(midiControllers.nonRegisteredParameterLSB, 127);
|
|
4584
4590
|
setResetValue(midiControllers.nonRegisteredParameterMSB, 127);
|
|
4585
|
-
var PORTAMENTO_CONTROL_UNSET = 1;
|
|
4586
|
-
defaultMIDIControllerValues[midiControllers.portamentoControl] = PORTAMENTO_CONTROL_UNSET;
|
|
4587
4591
|
setResetValue(
|
|
4588
4592
|
NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel,
|
|
4589
4593
|
64
|
|
@@ -4597,12 +4601,9 @@ var customResetArray = new Float32Array(CUSTOM_CONTROLLER_TABLE_SIZE);
|
|
|
4597
4601
|
customResetArray[customControllers.modulationMultiplier] = 1;
|
|
4598
4602
|
|
|
4599
4603
|
// src/synthesizer/audio_engine/engine_methods/controller_control/reset_controllers.ts
|
|
4600
|
-
function resetAllControllersInternal(
|
|
4601
|
-
if (log) {
|
|
4602
|
-
SpessaSynthInfo("%cResetting all controllers!", consoleColors.info);
|
|
4603
|
-
}
|
|
4604
|
+
function resetAllControllersInternal(system = DEFAULT_SYNTH_MODE) {
|
|
4604
4605
|
this.privateProps.callEvent("allControllerReset", void 0);
|
|
4605
|
-
this.setMasterParameter("midiSystem",
|
|
4606
|
+
this.setMasterParameter("midiSystem", system);
|
|
4606
4607
|
this.privateProps.tunings.length = 0;
|
|
4607
4608
|
for (let i = 0; i < 128; i++) {
|
|
4608
4609
|
this.privateProps.tunings.push([]);
|
|
@@ -4642,27 +4643,34 @@ function resetAllControllersInternal(log = true) {
|
|
|
4642
4643
|
}
|
|
4643
4644
|
}
|
|
4644
4645
|
}
|
|
4646
|
+
function resetPortamento(sendCC) {
|
|
4647
|
+
if (this.lockedControllers[midiControllers.portamentoControl]) return;
|
|
4648
|
+
if (this.channelSystem === "xg") {
|
|
4649
|
+
this.controllerChange(midiControllers.portamentoControl, 60, sendCC);
|
|
4650
|
+
} else {
|
|
4651
|
+
this.controllerChange(midiControllers.portamentoControl, 0, sendCC);
|
|
4652
|
+
}
|
|
4653
|
+
}
|
|
4645
4654
|
function resetControllers(sendCCEvents = true) {
|
|
4646
4655
|
this.channelOctaveTuning.fill(0);
|
|
4647
|
-
for (let
|
|
4648
|
-
if (this.lockedControllers[
|
|
4656
|
+
for (let cc = 0; cc < defaultMIDIControllerValues.length; cc++) {
|
|
4657
|
+
if (this.lockedControllers[cc]) {
|
|
4649
4658
|
continue;
|
|
4650
4659
|
}
|
|
4651
|
-
const resetValue = defaultMIDIControllerValues[
|
|
4652
|
-
if (this.midiControllers[
|
|
4653
|
-
if (
|
|
4654
|
-
this.midiControllers[i] = PORTAMENTO_CONTROL_UNSET;
|
|
4655
|
-
} else if (i !== midiControllers.portamentoControl && i !== midiControllers.dataEntryMSB && i !== midiControllers.registeredParameterMSB && i !== midiControllers.registeredParameterLSB && i !== midiControllers.nonRegisteredParameterMSB && i !== midiControllers.nonRegisteredParameterLSB) {
|
|
4660
|
+
const resetValue = defaultMIDIControllerValues[cc];
|
|
4661
|
+
if (this.midiControllers[cc] !== resetValue && cc < 127) {
|
|
4662
|
+
if (cc !== midiControllers.portamentoControl && cc !== midiControllers.dataEntryMSB && cc !== midiControllers.registeredParameterMSB && cc !== midiControllers.registeredParameterLSB && cc !== midiControllers.nonRegisteredParameterMSB && cc !== midiControllers.nonRegisteredParameterLSB) {
|
|
4656
4663
|
this.controllerChange(
|
|
4657
|
-
|
|
4664
|
+
cc,
|
|
4658
4665
|
resetValue >> 7,
|
|
4659
4666
|
sendCCEvents
|
|
4660
4667
|
);
|
|
4661
4668
|
}
|
|
4662
4669
|
} else {
|
|
4663
|
-
this.midiControllers[
|
|
4670
|
+
this.midiControllers[cc] = resetValue;
|
|
4664
4671
|
}
|
|
4665
4672
|
}
|
|
4673
|
+
resetPortamento.call(this, sendCCEvents);
|
|
4666
4674
|
this.channelVibrato = { rate: 0, depth: 0, delay: 0 };
|
|
4667
4675
|
this.randomPan = false;
|
|
4668
4676
|
this.sysExModulators.resetModulators();
|
|
@@ -4708,13 +4716,12 @@ function resetControllersRP15Compliant() {
|
|
|
4708
4716
|
for (let i = 0; i < 128; i++) {
|
|
4709
4717
|
const resetValue = defaultMIDIControllerValues[i];
|
|
4710
4718
|
if (!nonResettableCCs.has(i) && resetValue !== this.midiControllers[i]) {
|
|
4711
|
-
if (i
|
|
4712
|
-
this.midiControllers[i] = PORTAMENTO_CONTROL_UNSET;
|
|
4713
|
-
} else {
|
|
4719
|
+
if (i !== midiControllers.portamentoControl) {
|
|
4714
4720
|
this.controllerChange(i, resetValue >> 7);
|
|
4715
4721
|
}
|
|
4716
4722
|
}
|
|
4717
4723
|
}
|
|
4724
|
+
resetPortamento.call(this, true);
|
|
4718
4725
|
this.resetGeneratorOverrides();
|
|
4719
4726
|
this.resetGeneratorOffsets();
|
|
4720
4727
|
}
|
|
@@ -5166,6 +5173,15 @@ var SpessaSynthSequencer = class {
|
|
|
5166
5173
|
this._songIndex = 0;
|
|
5167
5174
|
this.shuffleSongIndexes();
|
|
5168
5175
|
this.callEvent("songListChange", { newSongList: [...this.songs] });
|
|
5176
|
+
if (this.preload) {
|
|
5177
|
+
SpessaSynthGroup("%cPreloading all songs...", consoleColors.info);
|
|
5178
|
+
this.songs.forEach((song) => {
|
|
5179
|
+
if (song.embeddedSoundBank === void 0) {
|
|
5180
|
+
song.preloadSynth(this.synth);
|
|
5181
|
+
}
|
|
5182
|
+
});
|
|
5183
|
+
SpessaSynthGroupEnd();
|
|
5184
|
+
}
|
|
5169
5185
|
this.loadCurrentSong();
|
|
5170
5186
|
}
|
|
5171
5187
|
callEvent(type, data) {
|
|
@@ -6902,20 +6918,6 @@ var defaultSoundFont2Modulators = [
|
|
|
6902
6918
|
];
|
|
6903
6919
|
var defaultSpessaSynthModulators = [
|
|
6904
6920
|
// Custom modulators heck yeah
|
|
6905
|
-
// Poly pressure to vibrato
|
|
6906
|
-
new DecodedModulator(
|
|
6907
|
-
getModSourceEnum(
|
|
6908
|
-
modulatorCurveTypes.linear,
|
|
6909
|
-
false,
|
|
6910
|
-
false,
|
|
6911
|
-
false,
|
|
6912
|
-
modulatorSources.polyPressure
|
|
6913
|
-
),
|
|
6914
|
-
0,
|
|
6915
|
-
generatorTypes.vibLfoToPitch,
|
|
6916
|
-
50,
|
|
6917
|
-
0
|
|
6918
|
-
),
|
|
6919
6921
|
// Cc 92 (tremolo) to modLFO volume
|
|
6920
6922
|
new DecodedModulator(
|
|
6921
6923
|
getModSourceEnum(
|
|
@@ -6963,6 +6965,22 @@ var defaultSpessaSynthModulators = [
|
|
|
6963
6965
|
3600,
|
|
6964
6966
|
0
|
|
6965
6967
|
),
|
|
6968
|
+
// Cc 75 (decay time) to vol env decay
|
|
6969
|
+
new DecodedModulator(
|
|
6970
|
+
getModSourceEnum(
|
|
6971
|
+
modulatorCurveTypes.linear,
|
|
6972
|
+
true,
|
|
6973
|
+
false,
|
|
6974
|
+
true,
|
|
6975
|
+
midiControllers.decayTime
|
|
6976
|
+
),
|
|
6977
|
+
// Linear forward bipolar cc 75
|
|
6978
|
+
0,
|
|
6979
|
+
// No controller
|
|
6980
|
+
generatorTypes.decayVolEnv,
|
|
6981
|
+
3600,
|
|
6982
|
+
0
|
|
6983
|
+
),
|
|
6966
6984
|
// Cc 74 (brightness) to filterFc
|
|
6967
6985
|
new DecodedModulator(
|
|
6968
6986
|
getModSourceEnum(
|
|
@@ -6976,7 +6994,7 @@ var defaultSpessaSynthModulators = [
|
|
|
6976
6994
|
0,
|
|
6977
6995
|
// No controller
|
|
6978
6996
|
generatorTypes.initialFilterFc,
|
|
6979
|
-
|
|
6997
|
+
9600,
|
|
6980
6998
|
0
|
|
6981
6999
|
),
|
|
6982
7000
|
// Cc 71 (filter Q) to filter Q (default resonant modulator)
|
|
@@ -6985,7 +7003,55 @@ var defaultSpessaSynthModulators = [
|
|
|
6985
7003
|
0,
|
|
6986
7004
|
// No controller
|
|
6987
7005
|
generatorTypes.initialFilterQ,
|
|
6988
|
-
|
|
7006
|
+
200,
|
|
7007
|
+
0
|
|
7008
|
+
),
|
|
7009
|
+
// Cc 67 (soft pedal) to attenuation
|
|
7010
|
+
new DecodedModulator(
|
|
7011
|
+
getModSourceEnum(
|
|
7012
|
+
modulatorCurveTypes.switch,
|
|
7013
|
+
false,
|
|
7014
|
+
false,
|
|
7015
|
+
true,
|
|
7016
|
+
midiControllers.softPedal
|
|
7017
|
+
),
|
|
7018
|
+
// Switch unipolar positive 67
|
|
7019
|
+
0,
|
|
7020
|
+
// No controller
|
|
7021
|
+
generatorTypes.initialAttenuation,
|
|
7022
|
+
50,
|
|
7023
|
+
0
|
|
7024
|
+
),
|
|
7025
|
+
// Cc 67 (soft pedal) to filter fc
|
|
7026
|
+
new DecodedModulator(
|
|
7027
|
+
getModSourceEnum(
|
|
7028
|
+
modulatorCurveTypes.switch,
|
|
7029
|
+
false,
|
|
7030
|
+
false,
|
|
7031
|
+
true,
|
|
7032
|
+
midiControllers.softPedal
|
|
7033
|
+
),
|
|
7034
|
+
// Switch unipolar positive 67
|
|
7035
|
+
0,
|
|
7036
|
+
// No controller
|
|
7037
|
+
generatorTypes.initialFilterFc,
|
|
7038
|
+
-2400,
|
|
7039
|
+
0
|
|
7040
|
+
),
|
|
7041
|
+
// Cc 8 (balance) to pan
|
|
7042
|
+
new DecodedModulator(
|
|
7043
|
+
getModSourceEnum(
|
|
7044
|
+
modulatorCurveTypes.linear,
|
|
7045
|
+
true,
|
|
7046
|
+
false,
|
|
7047
|
+
true,
|
|
7048
|
+
midiControllers.balance
|
|
7049
|
+
),
|
|
7050
|
+
// Linear bipolar positive 8
|
|
7051
|
+
0,
|
|
7052
|
+
// No controller
|
|
7053
|
+
generatorTypes.pan,
|
|
7054
|
+
500,
|
|
6989
7055
|
0
|
|
6990
7056
|
)
|
|
6991
7057
|
];
|
|
@@ -8274,7 +8340,7 @@ function panAndMixVoice(voice, inputBuffer, outputLeft, outputRight, reverbLeft,
|
|
|
8274
8340
|
}
|
|
8275
8341
|
|
|
8276
8342
|
// src/synthesizer/audio_engine/engine_components/dsp_chain/lowpass_filter.ts
|
|
8277
|
-
var FILTER_SMOOTHING_FACTOR = 0.
|
|
8343
|
+
var FILTER_SMOOTHING_FACTOR = 0.03;
|
|
8278
8344
|
var LowpassFilter = class _LowpassFilter {
|
|
8279
8345
|
/**
|
|
8280
8346
|
* Cached coefficient calculations.
|
|
@@ -8955,7 +9021,29 @@ function getVoicesInternal(channel, midiNote, velocity, realKey) {
|
|
|
8955
9021
|
return this.getVoicesForPreset(preset, midiNote, velocity, realKey);
|
|
8956
9022
|
}
|
|
8957
9023
|
|
|
8958
|
-
// src/synthesizer/audio_engine/engine_methods/system_exclusive.ts
|
|
9024
|
+
// src/synthesizer/audio_engine/engine_methods/system_exclusive/helpers.ts
|
|
9025
|
+
function sysExLogging(syx, channel, value, what, units) {
|
|
9026
|
+
SpessaSynthInfo(
|
|
9027
|
+
`%cChannel %c${channel}%c ${what}. %c${value} ${units}%c, with %c${arrayToHexString(syx)}`,
|
|
9028
|
+
consoleColors.info,
|
|
9029
|
+
consoleColors.recognized,
|
|
9030
|
+
consoleColors.info,
|
|
9031
|
+
consoleColors.value,
|
|
9032
|
+
consoleColors.info,
|
|
9033
|
+
consoleColors.value
|
|
9034
|
+
);
|
|
9035
|
+
}
|
|
9036
|
+
function sysExNotRecognized(syx, what) {
|
|
9037
|
+
SpessaSynthInfo(
|
|
9038
|
+
`%cUnrecognized %c${what} %cSysEx: %c${arrayToHexString(syx)}`,
|
|
9039
|
+
consoleColors.warn,
|
|
9040
|
+
consoleColors.recognized,
|
|
9041
|
+
consoleColors.warn,
|
|
9042
|
+
consoleColors.unrecognized
|
|
9043
|
+
);
|
|
9044
|
+
}
|
|
9045
|
+
|
|
9046
|
+
// src/synthesizer/audio_engine/engine_methods/system_exclusive/handle_gm.ts
|
|
8959
9047
|
function getTuning(byte1, byte2, byte3) {
|
|
8960
9048
|
const midiNote = byte1;
|
|
8961
9049
|
const fraction = byte2 << 7 | byte3;
|
|
@@ -8964,900 +9052,971 @@ function getTuning(byte1, byte2, byte3) {
|
|
|
8964
9052
|
}
|
|
8965
9053
|
return { midiNote, centTuning: fraction * 61e-4 };
|
|
8966
9054
|
}
|
|
8967
|
-
function
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
9055
|
+
function handleGM(syx, channelOffset = 0) {
|
|
9056
|
+
switch (syx[2]) {
|
|
9057
|
+
case 4: {
|
|
9058
|
+
let cents;
|
|
9059
|
+
switch (syx[3]) {
|
|
9060
|
+
case 1: {
|
|
9061
|
+
const vol = syx[5] << 7 | syx[4];
|
|
9062
|
+
this.setMIDIVolume(vol / 16384);
|
|
9063
|
+
SpessaSynthInfo(
|
|
9064
|
+
`%cMaster Volume. Volume: %c${vol}`,
|
|
9065
|
+
consoleColors.info,
|
|
9066
|
+
consoleColors.value
|
|
9067
|
+
);
|
|
9068
|
+
break;
|
|
9069
|
+
}
|
|
9070
|
+
case 2: {
|
|
9071
|
+
const balance = syx[5] << 7 | syx[4];
|
|
9072
|
+
const pan = (balance - 8192) / 8192;
|
|
9073
|
+
this.setMasterParameter("masterPan", pan);
|
|
9074
|
+
SpessaSynthInfo(
|
|
9075
|
+
`%cMaster Pan. Pan: %c${pan}`,
|
|
9076
|
+
consoleColors.info,
|
|
9077
|
+
consoleColors.value
|
|
9078
|
+
);
|
|
9079
|
+
break;
|
|
9080
|
+
}
|
|
9081
|
+
case 3: {
|
|
9082
|
+
const tuningValue = (syx[5] << 7 | syx[6]) - 8192;
|
|
9083
|
+
cents = Math.floor(tuningValue / 81.92);
|
|
9084
|
+
this.setMasterTuning(cents);
|
|
9085
|
+
SpessaSynthInfo(
|
|
9086
|
+
`%cMaster Fine Tuning. Cents: %c${cents}`,
|
|
9087
|
+
consoleColors.info,
|
|
9088
|
+
consoleColors.value
|
|
9089
|
+
);
|
|
9090
|
+
break;
|
|
9091
|
+
}
|
|
9092
|
+
case 4: {
|
|
9093
|
+
const semitones = syx[5] - 64;
|
|
9094
|
+
cents = semitones * 100;
|
|
9095
|
+
this.setMasterTuning(cents);
|
|
9096
|
+
SpessaSynthInfo(
|
|
9097
|
+
`%cMaster Coarse Tuning. Cents: %c${cents}`,
|
|
9098
|
+
consoleColors.info,
|
|
9099
|
+
consoleColors.value
|
|
9100
|
+
);
|
|
9101
|
+
break;
|
|
9102
|
+
}
|
|
9103
|
+
default:
|
|
9104
|
+
SpessaSynthInfo(
|
|
9105
|
+
`%cUnrecognized MIDI Device Control Real-time message: %c${arrayToHexString(syx)}`,
|
|
9106
|
+
consoleColors.warn,
|
|
9107
|
+
consoleColors.unrecognized
|
|
9108
|
+
);
|
|
9109
|
+
}
|
|
9110
|
+
break;
|
|
8972
9111
|
}
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
SpessaSynthInfo(
|
|
8988
|
-
`%cUnrecognized SysEx: %c${arrayToHexString(syx)}`,
|
|
8989
|
-
consoleColors.warn,
|
|
8990
|
-
consoleColors.unrecognized
|
|
8991
|
-
);
|
|
9112
|
+
case 9:
|
|
9113
|
+
if (syx[3] === 1) {
|
|
9114
|
+
SpessaSynthInfo("%cGM1 system on", consoleColors.info);
|
|
9115
|
+
this.resetAllControllers("gm");
|
|
9116
|
+
} else if (syx[3] === 3) {
|
|
9117
|
+
SpessaSynthInfo("%cGM2 system on", consoleColors.info);
|
|
9118
|
+
this.resetAllControllers("gm2");
|
|
9119
|
+
} else {
|
|
9120
|
+
SpessaSynthInfo(
|
|
9121
|
+
"%cGM system off, defaulting to GS",
|
|
9122
|
+
consoleColors.info
|
|
9123
|
+
);
|
|
9124
|
+
this.setMasterParameter("midiSystem", "gs");
|
|
9125
|
+
}
|
|
8992
9126
|
break;
|
|
8993
|
-
//
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
switch (syx[
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
}
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
cents = semitones * 100;
|
|
9036
|
-
this.setMasterTuning(cents);
|
|
9037
|
-
SpessaSynthInfo(
|
|
9038
|
-
`%cMaster Coarse Tuning. Cents: %c${cents}`,
|
|
9039
|
-
consoleColors.info,
|
|
9040
|
-
consoleColors.value
|
|
9041
|
-
);
|
|
9042
|
-
break;
|
|
9043
|
-
}
|
|
9044
|
-
default:
|
|
9045
|
-
SpessaSynthInfo(
|
|
9046
|
-
`%cUnrecognized MIDI Device Control Real-time message: %c${arrayToHexString(syx)}`,
|
|
9047
|
-
consoleColors.warn,
|
|
9048
|
-
consoleColors.unrecognized
|
|
9049
|
-
);
|
|
9127
|
+
// MIDI Tuning standard
|
|
9128
|
+
// https://midi.org/midi-tuning-updated-specification
|
|
9129
|
+
case 8: {
|
|
9130
|
+
let currentMessageIndex = 4;
|
|
9131
|
+
switch (syx[3]) {
|
|
9132
|
+
// Bulk tuning dump: all 128 notes
|
|
9133
|
+
case 1: {
|
|
9134
|
+
const program = syx[currentMessageIndex++];
|
|
9135
|
+
const tuningName = readBinaryString(
|
|
9136
|
+
syx,
|
|
9137
|
+
16,
|
|
9138
|
+
currentMessageIndex
|
|
9139
|
+
);
|
|
9140
|
+
currentMessageIndex += 16;
|
|
9141
|
+
if (syx.length < 384) {
|
|
9142
|
+
SpessaSynthWarn(
|
|
9143
|
+
`The Bulk Tuning Dump is too short! (${syx.length} bytes, at least 384 are expected)`
|
|
9144
|
+
);
|
|
9145
|
+
return;
|
|
9146
|
+
}
|
|
9147
|
+
for (let i = 0; i < 128; i++) {
|
|
9148
|
+
this.privateProps.tunings[program][i] = getTuning(
|
|
9149
|
+
syx[currentMessageIndex++],
|
|
9150
|
+
syx[currentMessageIndex++],
|
|
9151
|
+
syx[currentMessageIndex++]
|
|
9152
|
+
);
|
|
9153
|
+
}
|
|
9154
|
+
SpessaSynthInfo(
|
|
9155
|
+
`%cBulk Tuning Dump %c${tuningName}%c Program: %c${program}`,
|
|
9156
|
+
consoleColors.info,
|
|
9157
|
+
consoleColors.value,
|
|
9158
|
+
consoleColors.info,
|
|
9159
|
+
consoleColors.recognized
|
|
9160
|
+
);
|
|
9161
|
+
break;
|
|
9162
|
+
}
|
|
9163
|
+
// Single note change
|
|
9164
|
+
// Single note change bank
|
|
9165
|
+
case 2:
|
|
9166
|
+
case 7: {
|
|
9167
|
+
if (syx[3] === 7) {
|
|
9168
|
+
currentMessageIndex++;
|
|
9050
9169
|
}
|
|
9170
|
+
const tuningProgram = syx[currentMessageIndex++];
|
|
9171
|
+
const numberOfChanges = syx[currentMessageIndex++];
|
|
9172
|
+
for (let i = 0; i < numberOfChanges; i++) {
|
|
9173
|
+
this.privateProps.tunings[tuningProgram][syx[currentMessageIndex++]] = getTuning(
|
|
9174
|
+
syx[currentMessageIndex++],
|
|
9175
|
+
syx[currentMessageIndex++],
|
|
9176
|
+
syx[currentMessageIndex++]
|
|
9177
|
+
);
|
|
9178
|
+
}
|
|
9179
|
+
SpessaSynthInfo(
|
|
9180
|
+
`%cSingle Note Tuning. Program: %c${tuningProgram}%c Keys affected: %c${numberOfChanges}`,
|
|
9181
|
+
consoleColors.info,
|
|
9182
|
+
consoleColors.recognized,
|
|
9183
|
+
consoleColors.info,
|
|
9184
|
+
consoleColors.recognized
|
|
9185
|
+
);
|
|
9051
9186
|
break;
|
|
9052
9187
|
}
|
|
9188
|
+
// Octave tuning (1 byte)
|
|
9189
|
+
// And octave tuning (2 bytes)
|
|
9053
9190
|
case 9:
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9191
|
+
case 8: {
|
|
9192
|
+
const newOctaveTuning = new Int8Array(12);
|
|
9193
|
+
if (syx[3] === 8) {
|
|
9194
|
+
for (let i = 0; i < 12; i++) {
|
|
9195
|
+
newOctaveTuning[i] = syx[7 + i] - 64;
|
|
9196
|
+
}
|
|
9060
9197
|
} else {
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9198
|
+
for (let i = 0; i < 24; i += 2) {
|
|
9199
|
+
const tuning = (syx[7 + i] << 7 | syx[8 + i]) - 8192;
|
|
9200
|
+
newOctaveTuning[i / 2] = Math.floor(tuning / 81.92);
|
|
9201
|
+
}
|
|
9202
|
+
}
|
|
9203
|
+
if ((syx[4] & 1) === 1) {
|
|
9204
|
+
this.midiChannels[14 + channelOffset].setOctaveTuning(
|
|
9205
|
+
newOctaveTuning
|
|
9064
9206
|
);
|
|
9065
|
-
this.setMasterParameter("midiSystem", "gs");
|
|
9066
9207
|
}
|
|
9208
|
+
if ((syx[4] >> 1 & 1) === 1) {
|
|
9209
|
+
this.midiChannels[15 + channelOffset].setOctaveTuning(
|
|
9210
|
+
newOctaveTuning
|
|
9211
|
+
);
|
|
9212
|
+
}
|
|
9213
|
+
for (let i = 0; i < 7; i++) {
|
|
9214
|
+
const bit = syx[5] >> i & 1;
|
|
9215
|
+
if (bit === 1) {
|
|
9216
|
+
this.midiChannels[7 + i + channelOffset].setOctaveTuning(newOctaveTuning);
|
|
9217
|
+
}
|
|
9218
|
+
}
|
|
9219
|
+
for (let i = 0; i < 7; i++) {
|
|
9220
|
+
const bit = syx[6] >> i & 1;
|
|
9221
|
+
if (bit === 1) {
|
|
9222
|
+
this.midiChannels[i + channelOffset].setOctaveTuning(newOctaveTuning);
|
|
9223
|
+
}
|
|
9224
|
+
}
|
|
9225
|
+
SpessaSynthInfo(
|
|
9226
|
+
`%cMIDI Octave Scale ${syx[3] === 8 ? "(1 byte)" : "(2 bytes)"} tuning via Tuning: %c${newOctaveTuning.join(" ")}`,
|
|
9227
|
+
consoleColors.info,
|
|
9228
|
+
consoleColors.value
|
|
9229
|
+
);
|
|
9067
9230
|
break;
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9231
|
+
}
|
|
9232
|
+
default:
|
|
9233
|
+
sysExNotRecognized(syx, "MIDI Tuning Standard");
|
|
9234
|
+
break;
|
|
9235
|
+
}
|
|
9236
|
+
break;
|
|
9237
|
+
}
|
|
9238
|
+
default:
|
|
9239
|
+
sysExNotRecognized(syx, "General MIDI");
|
|
9240
|
+
}
|
|
9241
|
+
}
|
|
9242
|
+
|
|
9243
|
+
// src/synthesizer/audio_engine/engine_methods/system_exclusive/handle_gs.ts
|
|
9244
|
+
function handleGS(syx, channelOffset = 0) {
|
|
9245
|
+
if (syx[3] === 18) {
|
|
9246
|
+
switch (syx[2]) {
|
|
9247
|
+
case 66: {
|
|
9248
|
+
const messageValue = syx[7];
|
|
9249
|
+
if (syx[4] === 64 || syx[4] === 0 && syx[6] === 127) {
|
|
9250
|
+
if ((syx[5] & 16) > 0) {
|
|
9251
|
+
const channel = [
|
|
9252
|
+
9,
|
|
9253
|
+
0,
|
|
9254
|
+
1,
|
|
9255
|
+
2,
|
|
9256
|
+
3,
|
|
9257
|
+
4,
|
|
9258
|
+
5,
|
|
9259
|
+
6,
|
|
9260
|
+
7,
|
|
9261
|
+
8,
|
|
9262
|
+
10,
|
|
9263
|
+
11,
|
|
9264
|
+
12,
|
|
9265
|
+
13,
|
|
9266
|
+
14,
|
|
9267
|
+
15
|
|
9268
|
+
][syx[5] & 15] + channelOffset;
|
|
9269
|
+
const channelObject = this.midiChannels[channel];
|
|
9270
|
+
switch (syx[6]) {
|
|
9271
|
+
default:
|
|
9272
|
+
sysExNotRecognized(syx, "Roland GS");
|
|
9273
|
+
break;
|
|
9274
|
+
case 21: {
|
|
9275
|
+
const isDrums = messageValue > 0 && syx[5] >> 4 > 0;
|
|
9276
|
+
channelObject.setGSDrums(isDrums);
|
|
9277
|
+
SpessaSynthInfo(
|
|
9278
|
+
`%cChannel %c${channel}%c ${isDrums ? "is now a drum channel" : "now isn't a drum channel"}%c via: %c${arrayToHexString(syx)}`,
|
|
9279
|
+
consoleColors.info,
|
|
9280
|
+
consoleColors.value,
|
|
9281
|
+
consoleColors.recognized,
|
|
9282
|
+
consoleColors.info,
|
|
9283
|
+
consoleColors.value
|
|
9085
9284
|
);
|
|
9086
9285
|
return;
|
|
9087
9286
|
}
|
|
9088
|
-
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
|
|
9287
|
+
case 22: {
|
|
9288
|
+
const keyShift = messageValue - 64;
|
|
9289
|
+
channelObject.setCustomController(
|
|
9290
|
+
customControllers.channelKeyShift,
|
|
9291
|
+
keyShift
|
|
9093
9292
|
);
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
consoleColors.recognized
|
|
9101
|
-
);
|
|
9102
|
-
break;
|
|
9103
|
-
}
|
|
9104
|
-
// Single note change
|
|
9105
|
-
// Single note change bank
|
|
9106
|
-
case 2:
|
|
9107
|
-
case 7: {
|
|
9108
|
-
if (syx[3] === 7) {
|
|
9109
|
-
currentMessageIndex++;
|
|
9110
|
-
}
|
|
9111
|
-
const tuningProgram = syx[currentMessageIndex++];
|
|
9112
|
-
const numberOfChanges = syx[currentMessageIndex++];
|
|
9113
|
-
for (let i = 0; i < numberOfChanges; i++) {
|
|
9114
|
-
this.privateProps.tunings[tuningProgram][syx[currentMessageIndex++]] = getTuning(
|
|
9115
|
-
syx[currentMessageIndex++],
|
|
9116
|
-
syx[currentMessageIndex++],
|
|
9117
|
-
syx[currentMessageIndex++]
|
|
9293
|
+
sysExLogging(
|
|
9294
|
+
syx,
|
|
9295
|
+
channel,
|
|
9296
|
+
keyShift,
|
|
9297
|
+
"key shift",
|
|
9298
|
+
"keys"
|
|
9118
9299
|
);
|
|
9300
|
+
return;
|
|
9119
9301
|
}
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
|
|
9135
|
-
|
|
9136
|
-
|
|
9137
|
-
}
|
|
9138
|
-
} else {
|
|
9139
|
-
for (let i = 0; i < 24; i += 2) {
|
|
9140
|
-
const tuning = (syx[7 + i] << 7 | syx[8 + i]) - 8192;
|
|
9141
|
-
newOctaveTuning[i / 2] = Math.floor(
|
|
9142
|
-
tuning / 81.92
|
|
9302
|
+
// Pan position
|
|
9303
|
+
case 28: {
|
|
9304
|
+
const panPosition = messageValue;
|
|
9305
|
+
if (panPosition === 0) {
|
|
9306
|
+
channelObject.randomPan = true;
|
|
9307
|
+
SpessaSynthInfo(
|
|
9308
|
+
`%cRandom pan is set to %cON%c for %c${channel}`,
|
|
9309
|
+
consoleColors.info,
|
|
9310
|
+
consoleColors.recognized,
|
|
9311
|
+
consoleColors.info,
|
|
9312
|
+
consoleColors.value
|
|
9313
|
+
);
|
|
9314
|
+
} else {
|
|
9315
|
+
channelObject.randomPan = false;
|
|
9316
|
+
channelObject.controllerChange(
|
|
9317
|
+
midiControllers.pan,
|
|
9318
|
+
panPosition
|
|
9143
9319
|
);
|
|
9144
9320
|
}
|
|
9321
|
+
break;
|
|
9145
9322
|
}
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
|
|
9154
|
-
|
|
9155
|
-
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
|
|
9160
|
-
|
|
9161
|
-
|
|
9323
|
+
// Chorus send
|
|
9324
|
+
case 33:
|
|
9325
|
+
channelObject.controllerChange(
|
|
9326
|
+
midiControllers.chorusDepth,
|
|
9327
|
+
messageValue
|
|
9328
|
+
);
|
|
9329
|
+
break;
|
|
9330
|
+
// Reverb send
|
|
9331
|
+
case 34:
|
|
9332
|
+
channelObject.controllerChange(
|
|
9333
|
+
midiControllers.reverbDepth,
|
|
9334
|
+
messageValue
|
|
9335
|
+
);
|
|
9336
|
+
break;
|
|
9337
|
+
case 64:
|
|
9338
|
+
case 65:
|
|
9339
|
+
case 66:
|
|
9340
|
+
case 67:
|
|
9341
|
+
case 68:
|
|
9342
|
+
case 69:
|
|
9343
|
+
case 70:
|
|
9344
|
+
case 71:
|
|
9345
|
+
case 72:
|
|
9346
|
+
case 73:
|
|
9347
|
+
case 74:
|
|
9348
|
+
case 75: {
|
|
9349
|
+
const tuningBytes = syx.length - 9;
|
|
9350
|
+
const newTuning = new Int8Array(12);
|
|
9351
|
+
for (let i = 0; i < tuningBytes; i++) {
|
|
9352
|
+
newTuning[i] = syx[i + 7] - 64;
|
|
9162
9353
|
}
|
|
9354
|
+
channelObject.setOctaveTuning(newTuning);
|
|
9355
|
+
const cents = messageValue - 64;
|
|
9356
|
+
sysExLogging(
|
|
9357
|
+
syx,
|
|
9358
|
+
channel,
|
|
9359
|
+
newTuning.join(" "),
|
|
9360
|
+
"octave scale tuning",
|
|
9361
|
+
"cents"
|
|
9362
|
+
);
|
|
9363
|
+
channelObject.setTuning(cents);
|
|
9364
|
+
break;
|
|
9163
9365
|
}
|
|
9164
|
-
SpessaSynthInfo(
|
|
9165
|
-
`%cMIDI Octave Scale ${syx[3] === 8 ? "(1 byte)" : "(2 bytes)"} tuning via Tuning: %c${newOctaveTuning.join(" ")}`,
|
|
9166
|
-
consoleColors.info,
|
|
9167
|
-
consoleColors.value
|
|
9168
|
-
);
|
|
9169
|
-
break;
|
|
9170
9366
|
}
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
|
|
9192
|
-
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
|
|
9199
|
-
consoleColors.warn,
|
|
9200
|
-
consoleColors.unrecognized
|
|
9201
|
-
);
|
|
9202
|
-
};
|
|
9203
|
-
var notRecognized = notRecognized2;
|
|
9204
|
-
switch (syx[2]) {
|
|
9205
|
-
case 66: {
|
|
9206
|
-
const messageValue = syx[7];
|
|
9207
|
-
if (syx[4] === 64 || syx[4] === 0 && syx[6] === 127) {
|
|
9208
|
-
if ((syx[5] & 16) > 0) {
|
|
9209
|
-
const channel = [
|
|
9210
|
-
9,
|
|
9211
|
-
0,
|
|
9212
|
-
1,
|
|
9213
|
-
2,
|
|
9214
|
-
3,
|
|
9215
|
-
4,
|
|
9216
|
-
5,
|
|
9217
|
-
6,
|
|
9218
|
-
7,
|
|
9219
|
-
8,
|
|
9220
|
-
10,
|
|
9221
|
-
11,
|
|
9222
|
-
12,
|
|
9223
|
-
13,
|
|
9224
|
-
14,
|
|
9225
|
-
15
|
|
9226
|
-
][syx[5] & 15] + channelOffset;
|
|
9227
|
-
const channelObject = this.midiChannels[channel];
|
|
9228
|
-
switch (syx[6]) {
|
|
9229
|
-
default:
|
|
9230
|
-
notRecognized2();
|
|
9231
|
-
break;
|
|
9232
|
-
case 21: {
|
|
9233
|
-
const isDrums = messageValue > 0 && syx[5] >> 4 > 0;
|
|
9234
|
-
channelObject.setGSDrums(isDrums);
|
|
9235
|
-
SpessaSynthInfo(
|
|
9236
|
-
`%cChannel %c${channel}%c ${isDrums ? "is now a drum channel" : "now isn't a drum channel"}%c via: %c${arrayToHexString(syx)}`,
|
|
9237
|
-
consoleColors.info,
|
|
9238
|
-
consoleColors.value,
|
|
9239
|
-
consoleColors.recognized,
|
|
9240
|
-
consoleColors.info,
|
|
9241
|
-
consoleColors.value
|
|
9242
|
-
);
|
|
9243
|
-
return;
|
|
9244
|
-
}
|
|
9245
|
-
case 22: {
|
|
9246
|
-
const keyShift = messageValue - 64;
|
|
9247
|
-
channelObject.setCustomController(
|
|
9248
|
-
customControllers.channelKeyShift,
|
|
9249
|
-
keyShift
|
|
9250
|
-
);
|
|
9251
|
-
niceLogging(
|
|
9252
|
-
channel,
|
|
9253
|
-
keyShift,
|
|
9254
|
-
"key shift",
|
|
9255
|
-
"keys"
|
|
9256
|
-
);
|
|
9257
|
-
return;
|
|
9258
|
-
}
|
|
9259
|
-
// Pan position
|
|
9260
|
-
case 28: {
|
|
9261
|
-
const panPosition = messageValue;
|
|
9262
|
-
if (panPosition === 0) {
|
|
9263
|
-
channelObject.randomPan = true;
|
|
9264
|
-
SpessaSynthInfo(
|
|
9265
|
-
`%cRandom pan is set to %cON%c for %c${channel}`,
|
|
9266
|
-
consoleColors.info,
|
|
9267
|
-
consoleColors.recognized,
|
|
9268
|
-
consoleColors.info,
|
|
9269
|
-
consoleColors.value
|
|
9270
|
-
);
|
|
9271
|
-
} else {
|
|
9272
|
-
channelObject.randomPan = false;
|
|
9273
|
-
channelObject.controllerChange(
|
|
9274
|
-
midiControllers.pan,
|
|
9275
|
-
panPosition
|
|
9276
|
-
);
|
|
9277
|
-
}
|
|
9278
|
-
break;
|
|
9279
|
-
}
|
|
9280
|
-
// Chorus send
|
|
9281
|
-
case 33:
|
|
9367
|
+
return;
|
|
9368
|
+
} else if ((syx[5] & 32) > 0) {
|
|
9369
|
+
const channel = [
|
|
9370
|
+
9,
|
|
9371
|
+
0,
|
|
9372
|
+
1,
|
|
9373
|
+
2,
|
|
9374
|
+
3,
|
|
9375
|
+
4,
|
|
9376
|
+
5,
|
|
9377
|
+
6,
|
|
9378
|
+
7,
|
|
9379
|
+
8,
|
|
9380
|
+
10,
|
|
9381
|
+
11,
|
|
9382
|
+
12,
|
|
9383
|
+
13,
|
|
9384
|
+
14,
|
|
9385
|
+
15
|
|
9386
|
+
][syx[5] & 15] + channelOffset;
|
|
9387
|
+
const channelObject = this.midiChannels[channel];
|
|
9388
|
+
const centeredValue = messageValue - 64;
|
|
9389
|
+
const normalizedValue = centeredValue / 64;
|
|
9390
|
+
const normalizedNotCentered = messageValue / 128;
|
|
9391
|
+
const setupReceivers = (source, sourceName, bipolar = false) => {
|
|
9392
|
+
switch (syx[6] & 15) {
|
|
9393
|
+
case 0:
|
|
9394
|
+
if (source === NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel) {
|
|
9282
9395
|
channelObject.controllerChange(
|
|
9283
|
-
midiControllers.
|
|
9284
|
-
|
|
9396
|
+
midiControllers.registeredParameterMSB,
|
|
9397
|
+
0
|
|
9285
9398
|
);
|
|
9286
|
-
break;
|
|
9287
|
-
// Reverb send
|
|
9288
|
-
case 34:
|
|
9289
9399
|
channelObject.controllerChange(
|
|
9290
|
-
midiControllers.
|
|
9291
|
-
|
|
9292
|
-
);
|
|
9293
|
-
break;
|
|
9294
|
-
case 64:
|
|
9295
|
-
case 65:
|
|
9296
|
-
case 66:
|
|
9297
|
-
case 67:
|
|
9298
|
-
case 68:
|
|
9299
|
-
case 69:
|
|
9300
|
-
case 70:
|
|
9301
|
-
case 71:
|
|
9302
|
-
case 72:
|
|
9303
|
-
case 73:
|
|
9304
|
-
case 74:
|
|
9305
|
-
case 75: {
|
|
9306
|
-
const tuningBytes = syx.length - 9;
|
|
9307
|
-
const newTuning = new Int8Array(12);
|
|
9308
|
-
for (let i = 0; i < tuningBytes; i++) {
|
|
9309
|
-
newTuning[i] = syx[i + 7] - 64;
|
|
9310
|
-
}
|
|
9311
|
-
channelObject.setOctaveTuning(
|
|
9312
|
-
newTuning
|
|
9313
|
-
);
|
|
9314
|
-
const cents = messageValue - 64;
|
|
9315
|
-
niceLogging(
|
|
9316
|
-
channel,
|
|
9317
|
-
newTuning.join(" "),
|
|
9318
|
-
"octave scale tuning",
|
|
9319
|
-
"cents"
|
|
9320
|
-
);
|
|
9321
|
-
channelObject.setTuning(cents);
|
|
9322
|
-
break;
|
|
9323
|
-
}
|
|
9324
|
-
}
|
|
9325
|
-
return;
|
|
9326
|
-
} else if ((syx[5] & 32) > 0) {
|
|
9327
|
-
const channel = [
|
|
9328
|
-
9,
|
|
9329
|
-
0,
|
|
9330
|
-
1,
|
|
9331
|
-
2,
|
|
9332
|
-
3,
|
|
9333
|
-
4,
|
|
9334
|
-
5,
|
|
9335
|
-
6,
|
|
9336
|
-
7,
|
|
9337
|
-
8,
|
|
9338
|
-
10,
|
|
9339
|
-
11,
|
|
9340
|
-
12,
|
|
9341
|
-
13,
|
|
9342
|
-
14,
|
|
9343
|
-
15
|
|
9344
|
-
][syx[5] & 15] + channelOffset;
|
|
9345
|
-
const channelObject = this.midiChannels[channel];
|
|
9346
|
-
const centeredValue = messageValue - 64;
|
|
9347
|
-
const normalizedValue = centeredValue / 64;
|
|
9348
|
-
const normalizedNotCentered = messageValue / 128;
|
|
9349
|
-
const setupReceivers = (source, sourceName, bipolar = false) => {
|
|
9350
|
-
switch (syx[6] & 15) {
|
|
9351
|
-
case 0:
|
|
9352
|
-
if (source === NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel) {
|
|
9353
|
-
channelObject.controllerChange(
|
|
9354
|
-
midiControllers.registeredParameterMSB,
|
|
9355
|
-
0
|
|
9356
|
-
);
|
|
9357
|
-
channelObject.controllerChange(
|
|
9358
|
-
midiControllers.registeredParameterLSB,
|
|
9359
|
-
0
|
|
9360
|
-
);
|
|
9361
|
-
channelObject.controllerChange(
|
|
9362
|
-
midiControllers.dataEntryMSB,
|
|
9363
|
-
Math.floor(centeredValue)
|
|
9364
|
-
);
|
|
9365
|
-
} else {
|
|
9366
|
-
channelObject.sysExModulators.setModulator(
|
|
9367
|
-
source,
|
|
9368
|
-
generatorTypes.fineTune,
|
|
9369
|
-
centeredValue * 100,
|
|
9370
|
-
bipolar
|
|
9371
|
-
);
|
|
9372
|
-
niceLogging(
|
|
9373
|
-
channel,
|
|
9374
|
-
centeredValue,
|
|
9375
|
-
`${sourceName} pitch control`,
|
|
9376
|
-
"semitones"
|
|
9377
|
-
);
|
|
9378
|
-
}
|
|
9379
|
-
break;
|
|
9380
|
-
case 1:
|
|
9381
|
-
channelObject.sysExModulators.setModulator(
|
|
9382
|
-
source,
|
|
9383
|
-
generatorTypes.initialFilterFc,
|
|
9384
|
-
normalizedValue * 9600,
|
|
9385
|
-
bipolar
|
|
9386
|
-
);
|
|
9387
|
-
niceLogging(
|
|
9388
|
-
channel,
|
|
9389
|
-
normalizedValue * 9600,
|
|
9390
|
-
`${sourceName} pitch control`,
|
|
9391
|
-
"cents"
|
|
9392
|
-
);
|
|
9393
|
-
break;
|
|
9394
|
-
case 2:
|
|
9395
|
-
channelObject.sysExModulators.setModulator(
|
|
9396
|
-
source,
|
|
9397
|
-
generatorTypes.initialAttenuation,
|
|
9398
|
-
normalizedValue * 960,
|
|
9399
|
-
// Spec says "100%" so 960cB in sf2
|
|
9400
|
-
bipolar
|
|
9401
|
-
);
|
|
9402
|
-
niceLogging(
|
|
9403
|
-
channel,
|
|
9404
|
-
normalizedValue * 960,
|
|
9405
|
-
`${sourceName} amplitude`,
|
|
9406
|
-
"cB"
|
|
9407
|
-
);
|
|
9408
|
-
break;
|
|
9409
|
-
// Rate control is ignored as it is in hertz
|
|
9410
|
-
case 4:
|
|
9411
|
-
channelObject.sysExModulators.setModulator(
|
|
9412
|
-
source,
|
|
9413
|
-
generatorTypes.vibLfoToPitch,
|
|
9414
|
-
normalizedNotCentered * 600,
|
|
9415
|
-
bipolar
|
|
9416
|
-
);
|
|
9417
|
-
niceLogging(
|
|
9418
|
-
channel,
|
|
9419
|
-
normalizedNotCentered * 600,
|
|
9420
|
-
`${sourceName} LFO1 pitch depth`,
|
|
9421
|
-
"cents"
|
|
9422
|
-
);
|
|
9423
|
-
break;
|
|
9424
|
-
case 5:
|
|
9425
|
-
channelObject.sysExModulators.setModulator(
|
|
9426
|
-
source,
|
|
9427
|
-
generatorTypes.vibLfoToFilterFc,
|
|
9428
|
-
normalizedNotCentered * 2400,
|
|
9429
|
-
bipolar
|
|
9430
|
-
);
|
|
9431
|
-
niceLogging(
|
|
9432
|
-
channel,
|
|
9433
|
-
normalizedNotCentered * 2400,
|
|
9434
|
-
`${sourceName} LFO1 filter depth`,
|
|
9435
|
-
"cents"
|
|
9436
|
-
);
|
|
9437
|
-
break;
|
|
9438
|
-
case 6:
|
|
9439
|
-
channelObject.sysExModulators.setModulator(
|
|
9440
|
-
source,
|
|
9441
|
-
generatorTypes.vibLfoToVolume,
|
|
9442
|
-
normalizedValue * 960,
|
|
9443
|
-
bipolar
|
|
9444
|
-
);
|
|
9445
|
-
niceLogging(
|
|
9446
|
-
channel,
|
|
9447
|
-
normalizedValue * 960,
|
|
9448
|
-
`${sourceName} LFO1 amplitude depth`,
|
|
9449
|
-
"cB"
|
|
9450
|
-
);
|
|
9451
|
-
break;
|
|
9452
|
-
// Rate control is ignored as it is in hertz
|
|
9453
|
-
case 8:
|
|
9454
|
-
channelObject.sysExModulators.setModulator(
|
|
9455
|
-
source,
|
|
9456
|
-
generatorTypes.modLfoToPitch,
|
|
9457
|
-
normalizedNotCentered * 600,
|
|
9458
|
-
bipolar
|
|
9459
|
-
);
|
|
9460
|
-
niceLogging(
|
|
9461
|
-
channel,
|
|
9462
|
-
normalizedNotCentered * 600,
|
|
9463
|
-
`${sourceName} LFO2 pitch depth`,
|
|
9464
|
-
"cents"
|
|
9465
|
-
);
|
|
9466
|
-
break;
|
|
9467
|
-
case 9:
|
|
9468
|
-
channelObject.sysExModulators.setModulator(
|
|
9469
|
-
source,
|
|
9470
|
-
generatorTypes.modLfoToFilterFc,
|
|
9471
|
-
normalizedNotCentered * 2400,
|
|
9472
|
-
bipolar
|
|
9473
|
-
);
|
|
9474
|
-
niceLogging(
|
|
9475
|
-
channel,
|
|
9476
|
-
normalizedNotCentered * 2400,
|
|
9477
|
-
`${sourceName} LFO2 filter depth`,
|
|
9478
|
-
"cents"
|
|
9479
|
-
);
|
|
9480
|
-
break;
|
|
9481
|
-
case 10:
|
|
9482
|
-
channelObject.sysExModulators.setModulator(
|
|
9483
|
-
source,
|
|
9484
|
-
generatorTypes.modLfoToVolume,
|
|
9485
|
-
normalizedValue * 960,
|
|
9486
|
-
bipolar
|
|
9487
|
-
);
|
|
9488
|
-
niceLogging(
|
|
9489
|
-
channel,
|
|
9490
|
-
normalizedValue * 960,
|
|
9491
|
-
`${sourceName} LFO2 amplitude depth`,
|
|
9492
|
-
"cB"
|
|
9493
|
-
);
|
|
9494
|
-
break;
|
|
9495
|
-
}
|
|
9496
|
-
};
|
|
9497
|
-
switch (syx[6] & 240) {
|
|
9498
|
-
default:
|
|
9499
|
-
notRecognized2();
|
|
9500
|
-
break;
|
|
9501
|
-
case 0:
|
|
9502
|
-
setupReceivers(
|
|
9503
|
-
midiControllers.modulationWheel,
|
|
9504
|
-
"mod wheel"
|
|
9505
|
-
);
|
|
9506
|
-
break;
|
|
9507
|
-
case 16:
|
|
9508
|
-
setupReceivers(
|
|
9509
|
-
NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel,
|
|
9510
|
-
"pitch wheel",
|
|
9511
|
-
true
|
|
9400
|
+
midiControllers.registeredParameterLSB,
|
|
9401
|
+
0
|
|
9512
9402
|
);
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
NON_CC_INDEX_OFFSET + modulatorSources.channelPressure,
|
|
9517
|
-
"channel pressure"
|
|
9518
|
-
);
|
|
9519
|
-
break;
|
|
9520
|
-
case 48:
|
|
9521
|
-
setupReceivers(
|
|
9522
|
-
NON_CC_INDEX_OFFSET + modulatorSources.polyPressure,
|
|
9523
|
-
"poly pressure"
|
|
9524
|
-
);
|
|
9525
|
-
break;
|
|
9526
|
-
}
|
|
9527
|
-
return;
|
|
9528
|
-
} else if (syx[5] === 0) {
|
|
9529
|
-
switch (syx[6]) {
|
|
9530
|
-
default:
|
|
9531
|
-
notRecognized2();
|
|
9532
|
-
break;
|
|
9533
|
-
case 127:
|
|
9534
|
-
if (messageValue === 0) {
|
|
9535
|
-
SpessaSynthInfo(
|
|
9536
|
-
"%cGS Reset received!",
|
|
9537
|
-
consoleColors.info
|
|
9538
|
-
);
|
|
9539
|
-
this.resetAllControllers(false);
|
|
9540
|
-
this.setMasterParameter(
|
|
9541
|
-
"midiSystem",
|
|
9542
|
-
"gs"
|
|
9543
|
-
);
|
|
9544
|
-
} else if (messageValue === 127) {
|
|
9545
|
-
SpessaSynthInfo(
|
|
9546
|
-
"%cGS system off, switching to GM",
|
|
9547
|
-
consoleColors.info
|
|
9548
|
-
);
|
|
9549
|
-
this.resetAllControllers(false);
|
|
9550
|
-
this.setMasterParameter(
|
|
9551
|
-
"midiSystem",
|
|
9552
|
-
"gm"
|
|
9553
|
-
);
|
|
9554
|
-
}
|
|
9555
|
-
break;
|
|
9556
|
-
case 6:
|
|
9557
|
-
SpessaSynthInfo(
|
|
9558
|
-
`%cRoland GS Master Pan set to: %c${messageValue}%c with: %c${arrayToHexString(
|
|
9559
|
-
syx
|
|
9560
|
-
)}`,
|
|
9561
|
-
consoleColors.info,
|
|
9562
|
-
consoleColors.value,
|
|
9563
|
-
consoleColors.info,
|
|
9564
|
-
consoleColors.value
|
|
9565
|
-
);
|
|
9566
|
-
this.setMasterParameter(
|
|
9567
|
-
"masterPan",
|
|
9568
|
-
(messageValue - 64) / 64
|
|
9569
|
-
);
|
|
9570
|
-
break;
|
|
9571
|
-
case 4:
|
|
9572
|
-
SpessaSynthInfo(
|
|
9573
|
-
`%cRoland GS Master Volume set to: %c${messageValue}%c with: %c${arrayToHexString(
|
|
9574
|
-
syx
|
|
9575
|
-
)}`,
|
|
9576
|
-
consoleColors.info,
|
|
9577
|
-
consoleColors.value,
|
|
9578
|
-
consoleColors.info,
|
|
9579
|
-
consoleColors.value
|
|
9403
|
+
channelObject.controllerChange(
|
|
9404
|
+
midiControllers.dataEntryMSB,
|
|
9405
|
+
Math.floor(centeredValue)
|
|
9580
9406
|
);
|
|
9581
|
-
|
|
9582
|
-
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9586
|
-
|
|
9587
|
-
syx
|
|
9588
|
-
)}`,
|
|
9589
|
-
consoleColors.info,
|
|
9590
|
-
consoleColors.value,
|
|
9591
|
-
consoleColors.info,
|
|
9592
|
-
consoleColors.value
|
|
9407
|
+
} else {
|
|
9408
|
+
channelObject.sysExModulators.setModulator(
|
|
9409
|
+
source,
|
|
9410
|
+
generatorTypes.fineTune,
|
|
9411
|
+
centeredValue * 100,
|
|
9412
|
+
bipolar
|
|
9593
9413
|
);
|
|
9594
|
-
|
|
9595
|
-
break;
|
|
9596
|
-
}
|
|
9597
|
-
}
|
|
9598
|
-
return;
|
|
9599
|
-
} else if (syx[5] === 1) {
|
|
9600
|
-
switch (syx[6]) {
|
|
9601
|
-
default:
|
|
9602
|
-
notRecognized2();
|
|
9603
|
-
break;
|
|
9604
|
-
case 0: {
|
|
9605
|
-
const patchName = readBinaryString(
|
|
9414
|
+
sysExLogging(
|
|
9606
9415
|
syx,
|
|
9607
|
-
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
|
|
9611
|
-
`%cGS Patch name: %c${patchName}`,
|
|
9612
|
-
consoleColors.info,
|
|
9613
|
-
consoleColors.value
|
|
9416
|
+
channel,
|
|
9417
|
+
centeredValue,
|
|
9418
|
+
`${sourceName} pitch control`,
|
|
9419
|
+
"semitones"
|
|
9614
9420
|
);
|
|
9615
|
-
break;
|
|
9616
9421
|
}
|
|
9617
|
-
|
|
9618
|
-
|
|
9619
|
-
|
|
9620
|
-
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9627
|
-
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
9636
|
-
|
|
9637
|
-
|
|
9638
|
-
|
|
9639
|
-
|
|
9640
|
-
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
9422
|
+
break;
|
|
9423
|
+
case 1:
|
|
9424
|
+
channelObject.sysExModulators.setModulator(
|
|
9425
|
+
source,
|
|
9426
|
+
generatorTypes.initialFilterFc,
|
|
9427
|
+
normalizedValue * 9600,
|
|
9428
|
+
bipolar
|
|
9429
|
+
);
|
|
9430
|
+
sysExLogging(
|
|
9431
|
+
syx,
|
|
9432
|
+
channel,
|
|
9433
|
+
normalizedValue * 9600,
|
|
9434
|
+
`${sourceName} pitch control`,
|
|
9435
|
+
"cents"
|
|
9436
|
+
);
|
|
9437
|
+
break;
|
|
9438
|
+
case 2:
|
|
9439
|
+
channelObject.sysExModulators.setModulator(
|
|
9440
|
+
source,
|
|
9441
|
+
generatorTypes.initialAttenuation,
|
|
9442
|
+
normalizedValue * 960,
|
|
9443
|
+
// Spec says "100%" so 960cB in sf2
|
|
9444
|
+
bipolar
|
|
9445
|
+
);
|
|
9446
|
+
sysExLogging(
|
|
9447
|
+
syx,
|
|
9448
|
+
channel,
|
|
9449
|
+
normalizedValue * 960,
|
|
9450
|
+
`${sourceName} amplitude`,
|
|
9451
|
+
"cB"
|
|
9452
|
+
);
|
|
9453
|
+
break;
|
|
9454
|
+
// Rate control is ignored as it is in hertz
|
|
9455
|
+
case 4:
|
|
9456
|
+
channelObject.sysExModulators.setModulator(
|
|
9457
|
+
source,
|
|
9458
|
+
generatorTypes.vibLfoToPitch,
|
|
9459
|
+
normalizedNotCentered * 600,
|
|
9460
|
+
bipolar
|
|
9461
|
+
);
|
|
9462
|
+
sysExLogging(
|
|
9463
|
+
syx,
|
|
9464
|
+
channel,
|
|
9465
|
+
normalizedNotCentered * 600,
|
|
9466
|
+
`${sourceName} LFO1 pitch depth`,
|
|
9467
|
+
"cents"
|
|
9468
|
+
);
|
|
9469
|
+
break;
|
|
9470
|
+
case 5:
|
|
9471
|
+
channelObject.sysExModulators.setModulator(
|
|
9472
|
+
source,
|
|
9473
|
+
generatorTypes.vibLfoToFilterFc,
|
|
9474
|
+
normalizedNotCentered * 2400,
|
|
9475
|
+
bipolar
|
|
9476
|
+
);
|
|
9477
|
+
sysExLogging(
|
|
9478
|
+
syx,
|
|
9479
|
+
channel,
|
|
9480
|
+
normalizedNotCentered * 2400,
|
|
9481
|
+
`${sourceName} LFO1 filter depth`,
|
|
9482
|
+
"cents"
|
|
9483
|
+
);
|
|
9484
|
+
break;
|
|
9485
|
+
case 6:
|
|
9486
|
+
channelObject.sysExModulators.setModulator(
|
|
9487
|
+
source,
|
|
9488
|
+
generatorTypes.vibLfoToVolume,
|
|
9489
|
+
normalizedValue * 960,
|
|
9490
|
+
bipolar
|
|
9491
|
+
);
|
|
9492
|
+
sysExLogging(
|
|
9493
|
+
syx,
|
|
9494
|
+
channel,
|
|
9495
|
+
normalizedValue * 960,
|
|
9496
|
+
`${sourceName} LFO1 amplitude depth`,
|
|
9497
|
+
"cB"
|
|
9498
|
+
);
|
|
9499
|
+
break;
|
|
9500
|
+
// Rate control is ignored as it is in hertz
|
|
9501
|
+
case 8:
|
|
9502
|
+
channelObject.sysExModulators.setModulator(
|
|
9503
|
+
source,
|
|
9504
|
+
generatorTypes.modLfoToPitch,
|
|
9505
|
+
normalizedNotCentered * 600,
|
|
9506
|
+
bipolar
|
|
9507
|
+
);
|
|
9508
|
+
sysExLogging(
|
|
9509
|
+
syx,
|
|
9510
|
+
channel,
|
|
9511
|
+
normalizedNotCentered * 600,
|
|
9512
|
+
`${sourceName} LFO2 pitch depth`,
|
|
9513
|
+
"cents"
|
|
9514
|
+
);
|
|
9515
|
+
break;
|
|
9516
|
+
case 9:
|
|
9517
|
+
channelObject.sysExModulators.setModulator(
|
|
9518
|
+
source,
|
|
9519
|
+
generatorTypes.modLfoToFilterFc,
|
|
9520
|
+
normalizedNotCentered * 2400,
|
|
9521
|
+
bipolar
|
|
9522
|
+
);
|
|
9523
|
+
sysExLogging(
|
|
9524
|
+
syx,
|
|
9525
|
+
channel,
|
|
9526
|
+
normalizedNotCentered * 2400,
|
|
9527
|
+
`${sourceName} LFO2 filter depth`,
|
|
9528
|
+
"cents"
|
|
9529
|
+
);
|
|
9530
|
+
break;
|
|
9531
|
+
case 10:
|
|
9532
|
+
channelObject.sysExModulators.setModulator(
|
|
9533
|
+
source,
|
|
9534
|
+
generatorTypes.modLfoToVolume,
|
|
9535
|
+
normalizedValue * 960,
|
|
9536
|
+
bipolar
|
|
9537
|
+
);
|
|
9538
|
+
sysExLogging(
|
|
9539
|
+
syx,
|
|
9540
|
+
channel,
|
|
9541
|
+
normalizedValue * 960,
|
|
9542
|
+
`${sourceName} LFO2 amplitude depth`,
|
|
9543
|
+
"cB"
|
|
9544
|
+
);
|
|
9545
|
+
break;
|
|
9662
9546
|
}
|
|
9663
|
-
}
|
|
9664
|
-
|
|
9547
|
+
};
|
|
9548
|
+
switch (syx[6] & 240) {
|
|
9549
|
+
default:
|
|
9550
|
+
sysExNotRecognized(syx, "Roland GS");
|
|
9551
|
+
break;
|
|
9552
|
+
case 0:
|
|
9553
|
+
setupReceivers(
|
|
9554
|
+
midiControllers.modulationWheel,
|
|
9555
|
+
"mod wheel"
|
|
9556
|
+
);
|
|
9557
|
+
break;
|
|
9558
|
+
case 16:
|
|
9559
|
+
setupReceivers(
|
|
9560
|
+
NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel,
|
|
9561
|
+
"pitch wheel",
|
|
9562
|
+
true
|
|
9563
|
+
);
|
|
9564
|
+
break;
|
|
9565
|
+
case 32:
|
|
9566
|
+
setupReceivers(
|
|
9567
|
+
NON_CC_INDEX_OFFSET + modulatorSources.channelPressure,
|
|
9568
|
+
"channel pressure"
|
|
9569
|
+
);
|
|
9570
|
+
break;
|
|
9571
|
+
case 48:
|
|
9572
|
+
setupReceivers(
|
|
9573
|
+
NON_CC_INDEX_OFFSET + modulatorSources.polyPressure,
|
|
9574
|
+
"poly pressure"
|
|
9575
|
+
);
|
|
9576
|
+
break;
|
|
9665
9577
|
}
|
|
9666
9578
|
return;
|
|
9667
|
-
}
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9579
|
+
} else if (syx[5] === 0) {
|
|
9580
|
+
switch (syx[6]) {
|
|
9581
|
+
default:
|
|
9582
|
+
sysExNotRecognized(syx, "Roland GS");
|
|
9583
|
+
break;
|
|
9584
|
+
case 127:
|
|
9585
|
+
if (messageValue === 0) {
|
|
9586
|
+
SpessaSynthInfo(
|
|
9587
|
+
"%cGS Reset received!",
|
|
9588
|
+
consoleColors.info
|
|
9589
|
+
);
|
|
9590
|
+
this.resetAllControllers("gs");
|
|
9591
|
+
} else if (messageValue === 127) {
|
|
9592
|
+
SpessaSynthInfo(
|
|
9593
|
+
"%cGS system off, switching to GM",
|
|
9594
|
+
consoleColors.info
|
|
9595
|
+
);
|
|
9596
|
+
this.resetAllControllers("gm");
|
|
9597
|
+
}
|
|
9598
|
+
break;
|
|
9599
|
+
case 6:
|
|
9600
|
+
SpessaSynthInfo(
|
|
9601
|
+
`%cRoland GS Master Pan set to: %c${messageValue}%c with: %c${arrayToHexString(
|
|
9602
|
+
syx
|
|
9603
|
+
)}`,
|
|
9604
|
+
consoleColors.info,
|
|
9605
|
+
consoleColors.value,
|
|
9606
|
+
consoleColors.info,
|
|
9607
|
+
consoleColors.value
|
|
9674
9608
|
);
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
|
|
9609
|
+
this.setMasterParameter(
|
|
9610
|
+
"masterPan",
|
|
9611
|
+
(messageValue - 64) / 64
|
|
9612
|
+
);
|
|
9613
|
+
break;
|
|
9614
|
+
case 4:
|
|
9615
|
+
SpessaSynthInfo(
|
|
9616
|
+
`%cRoland GS Master Volume set to: %c${messageValue}%c with: %c${arrayToHexString(
|
|
9617
|
+
syx
|
|
9618
|
+
)}`,
|
|
9619
|
+
consoleColors.info,
|
|
9620
|
+
consoleColors.value,
|
|
9621
|
+
consoleColors.info,
|
|
9622
|
+
consoleColors.value
|
|
9623
|
+
);
|
|
9624
|
+
this.setMIDIVolume(messageValue / 127);
|
|
9625
|
+
break;
|
|
9626
|
+
case 5: {
|
|
9627
|
+
const transpose = messageValue - 64;
|
|
9628
|
+
SpessaSynthInfo(
|
|
9629
|
+
`%cRoland GS Master Key-Shift set to: %c${transpose}%c with: %c${arrayToHexString(
|
|
9630
|
+
syx
|
|
9631
|
+
)}`,
|
|
9632
|
+
consoleColors.info,
|
|
9633
|
+
consoleColors.value,
|
|
9634
|
+
consoleColors.info,
|
|
9635
|
+
consoleColors.value
|
|
9679
9636
|
);
|
|
9680
|
-
|
|
9681
|
-
|
|
9637
|
+
this.setMasterTuning(transpose * 100);
|
|
9638
|
+
break;
|
|
9682
9639
|
}
|
|
9683
9640
|
}
|
|
9684
9641
|
return;
|
|
9685
|
-
}
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
return;
|
|
9699
|
-
}
|
|
9700
|
-
}
|
|
9701
|
-
} else {
|
|
9702
|
-
SpessaSynthInfo(
|
|
9703
|
-
`%cUnrecognized Roland SysEx: %c${arrayToHexString(syx)}`,
|
|
9704
|
-
consoleColors.warn,
|
|
9705
|
-
consoleColors.unrecognized
|
|
9706
|
-
);
|
|
9707
|
-
return;
|
|
9708
|
-
}
|
|
9709
|
-
break;
|
|
9710
|
-
// Yamaha
|
|
9711
|
-
// http://www.studio4all.de/htmle/main91.html
|
|
9712
|
-
case 67:
|
|
9713
|
-
if (syx[2] === 76) {
|
|
9714
|
-
if (syx[3] === 0 && syx[4] === 0) {
|
|
9715
|
-
switch (syx[5]) {
|
|
9716
|
-
// Master volume
|
|
9717
|
-
case 4: {
|
|
9718
|
-
const vol = syx[6];
|
|
9719
|
-
this.setMIDIVolume(vol / 127);
|
|
9720
|
-
SpessaSynthInfo(
|
|
9721
|
-
`%cXG master volume. Volume: %c${vol}`,
|
|
9722
|
-
consoleColors.info,
|
|
9723
|
-
consoleColors.recognized
|
|
9724
|
-
);
|
|
9725
|
-
break;
|
|
9726
|
-
}
|
|
9727
|
-
// Master transpose
|
|
9728
|
-
case 6: {
|
|
9729
|
-
const transpose = syx[6] - 64;
|
|
9730
|
-
this.setMasterParameter("transposition", transpose);
|
|
9731
|
-
SpessaSynthInfo(
|
|
9732
|
-
`%cXG master transpose. Volume: %c${transpose}`,
|
|
9733
|
-
consoleColors.info,
|
|
9734
|
-
consoleColors.recognized
|
|
9735
|
-
);
|
|
9736
|
-
break;
|
|
9737
|
-
}
|
|
9738
|
-
// XG on
|
|
9739
|
-
case 126:
|
|
9740
|
-
SpessaSynthInfo(
|
|
9741
|
-
"%cXG system on",
|
|
9742
|
-
consoleColors.info
|
|
9743
|
-
);
|
|
9744
|
-
this.resetAllControllers(false);
|
|
9745
|
-
this.setMasterParameter("midiSystem", "xg");
|
|
9746
|
-
break;
|
|
9747
|
-
}
|
|
9748
|
-
} else if (syx[3] === 8) {
|
|
9749
|
-
if (!BankSelectHacks.isSystemXG(
|
|
9750
|
-
this.privateProps.masterParameters.midiSystem
|
|
9751
|
-
)) {
|
|
9752
|
-
return;
|
|
9753
|
-
}
|
|
9754
|
-
const channel = syx[4] + channelOffset;
|
|
9755
|
-
if (channel >= this.midiChannels.length) {
|
|
9756
|
-
return;
|
|
9757
|
-
}
|
|
9758
|
-
const channelObject = this.midiChannels[channel];
|
|
9759
|
-
const value = syx[6];
|
|
9760
|
-
switch (syx[5]) {
|
|
9761
|
-
// Bank-select MSB
|
|
9762
|
-
case 1:
|
|
9763
|
-
channelObject.controllerChange(
|
|
9764
|
-
midiControllers.bankSelect,
|
|
9765
|
-
value
|
|
9766
|
-
);
|
|
9767
|
-
break;
|
|
9768
|
-
// Bank-select LSB
|
|
9769
|
-
case 2:
|
|
9770
|
-
channelObject.controllerChange(
|
|
9771
|
-
midiControllers.bankSelectLSB,
|
|
9772
|
-
value
|
|
9773
|
-
);
|
|
9774
|
-
break;
|
|
9775
|
-
// Program change
|
|
9776
|
-
case 3:
|
|
9777
|
-
channelObject.programChange(value);
|
|
9778
|
-
break;
|
|
9779
|
-
// Note shift
|
|
9780
|
-
case 8: {
|
|
9781
|
-
if (channelObject.drumChannel) {
|
|
9782
|
-
return;
|
|
9642
|
+
} else if (syx[5] === 1) {
|
|
9643
|
+
switch (syx[6]) {
|
|
9644
|
+
default:
|
|
9645
|
+
sysExNotRecognized(syx, "Roland GS");
|
|
9646
|
+
break;
|
|
9647
|
+
case 0: {
|
|
9648
|
+
const patchName = readBinaryString(syx, 16, 7);
|
|
9649
|
+
SpessaSynthInfo(
|
|
9650
|
+
`%cGS Patch name: %c${patchName}`,
|
|
9651
|
+
consoleColors.info,
|
|
9652
|
+
consoleColors.value
|
|
9653
|
+
);
|
|
9654
|
+
break;
|
|
9783
9655
|
}
|
|
9784
|
-
|
|
9785
|
-
break;
|
|
9786
|
-
}
|
|
9787
|
-
// Volume
|
|
9788
|
-
case 11:
|
|
9789
|
-
channelObject.controllerChange(
|
|
9790
|
-
midiControllers.mainVolume,
|
|
9791
|
-
value
|
|
9792
|
-
);
|
|
9793
|
-
break;
|
|
9794
|
-
// Pan position
|
|
9795
|
-
case 14: {
|
|
9796
|
-
const pan = value;
|
|
9797
|
-
if (pan === 0) {
|
|
9798
|
-
channelObject.randomPan = true;
|
|
9656
|
+
case 51:
|
|
9799
9657
|
SpessaSynthInfo(
|
|
9800
|
-
`%
|
|
9658
|
+
`%cGS Reverb level: %c${messageValue}`,
|
|
9801
9659
|
consoleColors.info,
|
|
9802
|
-
consoleColors.
|
|
9660
|
+
consoleColors.value
|
|
9661
|
+
);
|
|
9662
|
+
this.privateProps.reverbSend = messageValue / 64;
|
|
9663
|
+
break;
|
|
9664
|
+
// Unsupported reverb params
|
|
9665
|
+
case 48:
|
|
9666
|
+
case 49:
|
|
9667
|
+
case 50:
|
|
9668
|
+
case 52:
|
|
9669
|
+
case 53:
|
|
9670
|
+
case 55:
|
|
9671
|
+
SpessaSynthInfo(
|
|
9672
|
+
`%cUnsupported GS Reverb Parameter: %c${syx[6].toString(16)}`,
|
|
9673
|
+
consoleColors.warn,
|
|
9674
|
+
consoleColors.unrecognized
|
|
9675
|
+
);
|
|
9676
|
+
break;
|
|
9677
|
+
case 58:
|
|
9678
|
+
SpessaSynthInfo(
|
|
9679
|
+
`%cGS Chorus level: %c${messageValue}`,
|
|
9803
9680
|
consoleColors.info,
|
|
9804
9681
|
consoleColors.value
|
|
9805
9682
|
);
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9683
|
+
this.privateProps.chorusSend = messageValue / 64;
|
|
9684
|
+
break;
|
|
9685
|
+
// Unsupported chorus params
|
|
9686
|
+
case 56:
|
|
9687
|
+
case 57:
|
|
9688
|
+
case 59:
|
|
9689
|
+
case 60:
|
|
9690
|
+
case 61:
|
|
9691
|
+
case 62:
|
|
9692
|
+
case 63:
|
|
9693
|
+
case 64:
|
|
9694
|
+
SpessaSynthInfo(
|
|
9695
|
+
`%cUnsupported GS Chorus Parameter: %c${syx[6].toString(16)}`,
|
|
9696
|
+
consoleColors.warn,
|
|
9697
|
+
consoleColors.unrecognized
|
|
9810
9698
|
);
|
|
9811
|
-
|
|
9812
|
-
break;
|
|
9699
|
+
break;
|
|
9813
9700
|
}
|
|
9814
|
-
// Reverb
|
|
9815
|
-
case 19:
|
|
9816
|
-
channelObject.controllerChange(
|
|
9817
|
-
midiControllers.reverbDepth,
|
|
9818
|
-
value
|
|
9819
|
-
);
|
|
9820
|
-
break;
|
|
9821
|
-
// Chorus
|
|
9822
|
-
case 18:
|
|
9823
|
-
channelObject.controllerChange(
|
|
9824
|
-
midiControllers.chorusDepth,
|
|
9825
|
-
value
|
|
9826
|
-
);
|
|
9827
|
-
break;
|
|
9828
|
-
default:
|
|
9829
|
-
SpessaSynthInfo(
|
|
9830
|
-
`%cUnrecognized Yamaha XG Part Setup: %c${syx[5].toString(16).toUpperCase()}`,
|
|
9831
|
-
consoleColors.warn,
|
|
9832
|
-
consoleColors.unrecognized
|
|
9833
|
-
);
|
|
9834
9701
|
}
|
|
9835
|
-
} else
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9702
|
+
} else {
|
|
9703
|
+
sysExNotRecognized(syx, "Roland GS");
|
|
9704
|
+
}
|
|
9705
|
+
return;
|
|
9706
|
+
}
|
|
9707
|
+
case 69: {
|
|
9708
|
+
if (syx[4] === 16) {
|
|
9709
|
+
if (syx[5] === 0) {
|
|
9710
|
+
this.privateProps.callEvent(
|
|
9711
|
+
"synthDisplay",
|
|
9712
|
+
Array.from(syx)
|
|
9713
|
+
);
|
|
9714
|
+
} else if (syx[5] === 1) {
|
|
9715
|
+
this.privateProps.callEvent(
|
|
9716
|
+
"synthDisplay",
|
|
9717
|
+
Array.from(syx)
|
|
9718
|
+
);
|
|
9719
|
+
} else {
|
|
9720
|
+
sysExNotRecognized(syx, "Roland GS");
|
|
9721
|
+
}
|
|
9722
|
+
}
|
|
9723
|
+
return;
|
|
9724
|
+
}
|
|
9725
|
+
case 22:
|
|
9726
|
+
if (syx[4] === 16) {
|
|
9727
|
+
this.setMIDIVolume(syx[7] / 100);
|
|
9728
|
+
SpessaSynthInfo(
|
|
9729
|
+
`%cRoland Master Volume control set to: %c${syx[7]}%c via: %c${arrayToHexString(
|
|
9730
|
+
syx
|
|
9731
|
+
)}`,
|
|
9732
|
+
consoleColors.info,
|
|
9733
|
+
consoleColors.value,
|
|
9734
|
+
consoleColors.info,
|
|
9735
|
+
consoleColors.value
|
|
9840
9736
|
);
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
|
|
9737
|
+
return;
|
|
9738
|
+
}
|
|
9739
|
+
}
|
|
9740
|
+
} else {
|
|
9741
|
+
sysExNotRecognized(syx, "Roland GS");
|
|
9742
|
+
return;
|
|
9743
|
+
}
|
|
9744
|
+
}
|
|
9745
|
+
|
|
9746
|
+
// src/synthesizer/audio_engine/engine_methods/system_exclusive/handle_xg.ts
|
|
9747
|
+
function handleXG(syx, channelOffset = 0) {
|
|
9748
|
+
if (syx[2] === 76) {
|
|
9749
|
+
const a1 = syx[3];
|
|
9750
|
+
const a2 = syx[4];
|
|
9751
|
+
if (a1 === 0 && a2 === 0) {
|
|
9752
|
+
switch (syx[5]) {
|
|
9753
|
+
// Master tune
|
|
9754
|
+
case 0:
|
|
9755
|
+
{
|
|
9756
|
+
const tune = (syx[6] & 15) << 12 | (syx[7] & 15) << 8 | (syx[8] & 15) << 4 | syx[9] & 15;
|
|
9757
|
+
const cents = (tune - 1024) / 10;
|
|
9758
|
+
this.setMasterTuning(cents);
|
|
9759
|
+
SpessaSynthInfo(
|
|
9760
|
+
`%cXG master tune. Cents: %c${cents}`,
|
|
9761
|
+
consoleColors.info,
|
|
9762
|
+
consoleColors.recognized
|
|
9763
|
+
);
|
|
9764
|
+
}
|
|
9765
|
+
break;
|
|
9766
|
+
// Master volume
|
|
9767
|
+
case 4: {
|
|
9768
|
+
const vol = syx[6];
|
|
9769
|
+
this.setMIDIVolume(vol / 127);
|
|
9844
9770
|
SpessaSynthInfo(
|
|
9845
|
-
`%
|
|
9846
|
-
consoleColors.
|
|
9847
|
-
consoleColors.
|
|
9771
|
+
`%cXG master volume. Volume: %c${vol}`,
|
|
9772
|
+
consoleColors.info,
|
|
9773
|
+
consoleColors.recognized
|
|
9848
9774
|
);
|
|
9775
|
+
break;
|
|
9849
9776
|
}
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
|
|
9777
|
+
// Master attenuation
|
|
9778
|
+
case 5: {
|
|
9779
|
+
const vol = 127 - syx[6];
|
|
9780
|
+
this.setMIDIVolume(vol / 127);
|
|
9854
9781
|
SpessaSynthInfo(
|
|
9855
|
-
`%
|
|
9856
|
-
consoleColors.
|
|
9857
|
-
consoleColors.
|
|
9782
|
+
`%cXG master attenuation. Volume: %c${vol}`,
|
|
9783
|
+
consoleColors.info,
|
|
9784
|
+
consoleColors.recognized
|
|
9785
|
+
);
|
|
9786
|
+
break;
|
|
9787
|
+
}
|
|
9788
|
+
// Master transpose
|
|
9789
|
+
case 6: {
|
|
9790
|
+
const transpose = syx[6] - 64;
|
|
9791
|
+
this.setMasterParameter("transposition", transpose);
|
|
9792
|
+
SpessaSynthInfo(
|
|
9793
|
+
`%cXG master transpose. Volume: %c${transpose}`,
|
|
9794
|
+
consoleColors.info,
|
|
9795
|
+
consoleColors.recognized
|
|
9796
|
+
);
|
|
9797
|
+
break;
|
|
9798
|
+
}
|
|
9799
|
+
//
|
|
9800
|
+
// XG on
|
|
9801
|
+
case 126:
|
|
9802
|
+
SpessaSynthInfo("%cXG system on", consoleColors.info);
|
|
9803
|
+
this.resetAllControllers("xg");
|
|
9804
|
+
break;
|
|
9805
|
+
}
|
|
9806
|
+
} else if (a1 === 2 && a2 === 1) {
|
|
9807
|
+
let effectType;
|
|
9808
|
+
const effect = syx[5];
|
|
9809
|
+
if (effect <= 21) effectType = "Reverb";
|
|
9810
|
+
else if (effect <= 35) effectType = "Chorus";
|
|
9811
|
+
else effectType = "Variation";
|
|
9812
|
+
SpessaSynthInfo(
|
|
9813
|
+
`%cUnsupported XG ${effectType} Parameter: %c${effect.toString(16)}`,
|
|
9814
|
+
consoleColors.warn,
|
|
9815
|
+
consoleColors.unrecognized
|
|
9816
|
+
);
|
|
9817
|
+
} else if (a1 === 8) {
|
|
9818
|
+
if (!BankSelectHacks.isSystemXG(
|
|
9819
|
+
this.privateProps.masterParameters.midiSystem
|
|
9820
|
+
)) {
|
|
9821
|
+
return;
|
|
9822
|
+
}
|
|
9823
|
+
const channel = a2 + channelOffset;
|
|
9824
|
+
if (channel >= this.midiChannels.length) {
|
|
9825
|
+
return;
|
|
9826
|
+
}
|
|
9827
|
+
const channelObject = this.midiChannels[channel];
|
|
9828
|
+
const value = syx[6];
|
|
9829
|
+
switch (syx[5]) {
|
|
9830
|
+
// Bank-select MSB
|
|
9831
|
+
case 1:
|
|
9832
|
+
channelObject.controllerChange(
|
|
9833
|
+
midiControllers.bankSelect,
|
|
9834
|
+
value
|
|
9835
|
+
);
|
|
9836
|
+
break;
|
|
9837
|
+
// Bank-select LSB
|
|
9838
|
+
case 2:
|
|
9839
|
+
channelObject.controllerChange(
|
|
9840
|
+
midiControllers.bankSelectLSB,
|
|
9841
|
+
value
|
|
9842
|
+
);
|
|
9843
|
+
break;
|
|
9844
|
+
// Program change
|
|
9845
|
+
case 3:
|
|
9846
|
+
channelObject.programChange(value);
|
|
9847
|
+
break;
|
|
9848
|
+
// Part mode
|
|
9849
|
+
case 7:
|
|
9850
|
+
channelObject.setDrums(value != 0);
|
|
9851
|
+
break;
|
|
9852
|
+
// Note shift
|
|
9853
|
+
case 8: {
|
|
9854
|
+
if (channelObject.drumChannel) {
|
|
9855
|
+
break;
|
|
9856
|
+
}
|
|
9857
|
+
channelObject.setCustomController(
|
|
9858
|
+
customControllers.channelKeyShift,
|
|
9859
|
+
value - 64
|
|
9860
|
+
);
|
|
9861
|
+
break;
|
|
9862
|
+
}
|
|
9863
|
+
// Volume
|
|
9864
|
+
case 11:
|
|
9865
|
+
channelObject.controllerChange(
|
|
9866
|
+
midiControllers.mainVolume,
|
|
9867
|
+
value
|
|
9858
9868
|
);
|
|
9869
|
+
break;
|
|
9870
|
+
// Pan position
|
|
9871
|
+
case 14: {
|
|
9872
|
+
const pan = value;
|
|
9873
|
+
if (pan === 0) {
|
|
9874
|
+
channelObject.randomPan = true;
|
|
9875
|
+
SpessaSynthInfo(
|
|
9876
|
+
`%cRandom pan is set to %cON%c for %c${channel}`,
|
|
9877
|
+
consoleColors.info,
|
|
9878
|
+
consoleColors.recognized,
|
|
9879
|
+
consoleColors.info,
|
|
9880
|
+
consoleColors.value
|
|
9881
|
+
);
|
|
9882
|
+
} else {
|
|
9883
|
+
channelObject.controllerChange(
|
|
9884
|
+
midiControllers.pan,
|
|
9885
|
+
pan
|
|
9886
|
+
);
|
|
9887
|
+
}
|
|
9888
|
+
break;
|
|
9859
9889
|
}
|
|
9890
|
+
// Dry
|
|
9891
|
+
case 17:
|
|
9892
|
+
channelObject.controllerChange(
|
|
9893
|
+
midiControllers.mainVolume,
|
|
9894
|
+
value
|
|
9895
|
+
);
|
|
9896
|
+
break;
|
|
9897
|
+
// Chorus
|
|
9898
|
+
case 18:
|
|
9899
|
+
channelObject.controllerChange(
|
|
9900
|
+
midiControllers.chorusDepth,
|
|
9901
|
+
value
|
|
9902
|
+
);
|
|
9903
|
+
break;
|
|
9904
|
+
// Reverb
|
|
9905
|
+
case 19:
|
|
9906
|
+
channelObject.controllerChange(
|
|
9907
|
+
midiControllers.reverbDepth,
|
|
9908
|
+
value
|
|
9909
|
+
);
|
|
9910
|
+
break;
|
|
9911
|
+
// Vibrato rate
|
|
9912
|
+
case 21:
|
|
9913
|
+
channelObject.controllerChange(
|
|
9914
|
+
midiControllers.vibratoRate,
|
|
9915
|
+
value
|
|
9916
|
+
);
|
|
9917
|
+
break;
|
|
9918
|
+
// Vibrato depth
|
|
9919
|
+
case 22:
|
|
9920
|
+
channelObject.controllerChange(
|
|
9921
|
+
midiControllers.vibratoDepth,
|
|
9922
|
+
value
|
|
9923
|
+
);
|
|
9924
|
+
break;
|
|
9925
|
+
// Vibrato delay
|
|
9926
|
+
case 23:
|
|
9927
|
+
channelObject.controllerChange(
|
|
9928
|
+
midiControllers.vibratoDelay,
|
|
9929
|
+
value
|
|
9930
|
+
);
|
|
9931
|
+
break;
|
|
9932
|
+
// Filter cutoff
|
|
9933
|
+
case 24:
|
|
9934
|
+
channelObject.controllerChange(
|
|
9935
|
+
midiControllers.brightness,
|
|
9936
|
+
value
|
|
9937
|
+
);
|
|
9938
|
+
break;
|
|
9939
|
+
// Filter resonance
|
|
9940
|
+
case 25:
|
|
9941
|
+
channelObject.controllerChange(
|
|
9942
|
+
midiControllers.filterResonance,
|
|
9943
|
+
value
|
|
9944
|
+
);
|
|
9945
|
+
break;
|
|
9946
|
+
// Attack time
|
|
9947
|
+
case 26:
|
|
9948
|
+
channelObject.controllerChange(
|
|
9949
|
+
midiControllers.attackTime,
|
|
9950
|
+
value
|
|
9951
|
+
);
|
|
9952
|
+
break;
|
|
9953
|
+
// Decay time
|
|
9954
|
+
case 27:
|
|
9955
|
+
channelObject.controllerChange(
|
|
9956
|
+
midiControllers.decayTime,
|
|
9957
|
+
value
|
|
9958
|
+
);
|
|
9959
|
+
break;
|
|
9960
|
+
// Release time
|
|
9961
|
+
case 28:
|
|
9962
|
+
channelObject.controllerChange(
|
|
9963
|
+
midiControllers.releaseTime,
|
|
9964
|
+
value
|
|
9965
|
+
);
|
|
9966
|
+
break;
|
|
9967
|
+
default:
|
|
9968
|
+
SpessaSynthInfo(
|
|
9969
|
+
`%cUnsupported Yamaha XG Part Setup: %c${syx[5].toString(16).toUpperCase()}%c for channel ${channel}`,
|
|
9970
|
+
consoleColors.warn,
|
|
9971
|
+
consoleColors.unrecognized,
|
|
9972
|
+
consoleColors.warn
|
|
9973
|
+
);
|
|
9860
9974
|
}
|
|
9975
|
+
} else if (a1 === 6 && // XG System parameter
|
|
9976
|
+
a2 === 0) {
|
|
9977
|
+
this.privateProps.callEvent("synthDisplay", Array.from(syx));
|
|
9978
|
+
} else if (BankSelectHacks.isSystemXG(
|
|
9979
|
+
this.privateProps.masterParameters.midiSystem
|
|
9980
|
+
)) {
|
|
9981
|
+
sysExNotRecognized(syx, "Yamaha XG");
|
|
9982
|
+
}
|
|
9983
|
+
} else {
|
|
9984
|
+
sysExNotRecognized(syx, "Yamaha");
|
|
9985
|
+
}
|
|
9986
|
+
}
|
|
9987
|
+
|
|
9988
|
+
// src/synthesizer/audio_engine/engine_methods/system_exclusive.ts
|
|
9989
|
+
function systemExclusiveInternal(syx, channelOffset = 0) {
|
|
9990
|
+
const manufacturer = syx[0];
|
|
9991
|
+
if (
|
|
9992
|
+
// The device ID can be set to "all" which it is by default
|
|
9993
|
+
this.privateProps.masterParameters.deviceID !== ALL_CHANNELS_OR_DIFFERENT_ACTION && syx[1] !== 127
|
|
9994
|
+
) {
|
|
9995
|
+
if (this.privateProps.masterParameters.deviceID !== syx[1]) {
|
|
9996
|
+
return;
|
|
9997
|
+
}
|
|
9998
|
+
}
|
|
9999
|
+
switch (manufacturer) {
|
|
10000
|
+
default:
|
|
10001
|
+
SpessaSynthInfo(
|
|
10002
|
+
`%cUnrecognized SysEx: %c${arrayToHexString(syx)} (unknown manufacturer)`,
|
|
10003
|
+
consoleColors.warn,
|
|
10004
|
+
consoleColors.unrecognized
|
|
10005
|
+
);
|
|
10006
|
+
break;
|
|
10007
|
+
// Non realtime GM
|
|
10008
|
+
case 126:
|
|
10009
|
+
// Realtime GM
|
|
10010
|
+
case 127:
|
|
10011
|
+
handleGM.call(this, syx, channelOffset);
|
|
10012
|
+
break;
|
|
10013
|
+
// Roland
|
|
10014
|
+
case 65:
|
|
10015
|
+
handleGS.call(this, syx, channelOffset);
|
|
10016
|
+
break;
|
|
10017
|
+
// Yamaha
|
|
10018
|
+
case 67:
|
|
10019
|
+
handleXG.call(this, syx, channelOffset);
|
|
9861
10020
|
break;
|
|
9862
10021
|
}
|
|
9863
10022
|
}
|
|
@@ -10251,8 +10410,7 @@ var ProtectedSynthValues = class {
|
|
|
10251
10410
|
voiceKilling;
|
|
10252
10411
|
/**
|
|
10253
10412
|
* Cached voices for all presets for this synthesizer.
|
|
10254
|
-
* Nesting
|
|
10255
|
-
* this.cachedVoices[bankMSB][bankLSB][programNumber][midiNote][velocity] = a list of voices for that.
|
|
10413
|
+
* Nesting is calculated in getCachedVoiceIndex, returns a list of voices for this note.
|
|
10256
10414
|
*/
|
|
10257
10415
|
cachedVoices = [];
|
|
10258
10416
|
constructor(eventCallbackHandler, getVoices, voiceKillingFunction, volumeEnvelopeSmoothingFactor, panSmoothingFactor, filterSmoothingFactor) {
|
|
@@ -10606,13 +10764,14 @@ var nonRegisteredMSB = {
|
|
|
10606
10764
|
awe32: 127,
|
|
10607
10765
|
SF2: 120
|
|
10608
10766
|
};
|
|
10609
|
-
var
|
|
10767
|
+
var nonRegisteredLSB = {
|
|
10610
10768
|
vibratoRate: 8,
|
|
10611
10769
|
vibratoDepth: 9,
|
|
10612
10770
|
vibratoDelay: 10,
|
|
10613
10771
|
TVFFilterCutoff: 32,
|
|
10614
10772
|
TVFFilterResonance: 33,
|
|
10615
10773
|
EGAttackTime: 99,
|
|
10774
|
+
EGDecayTime: 100,
|
|
10616
10775
|
EGReleaseTime: 102
|
|
10617
10776
|
};
|
|
10618
10777
|
function dataEntryCoarse(dataValue) {
|
|
@@ -10641,7 +10800,7 @@ function dataEntryCoarse(dataValue) {
|
|
|
10641
10800
|
default:
|
|
10642
10801
|
case dataEntryStates.Idle:
|
|
10643
10802
|
break;
|
|
10644
|
-
// Process
|
|
10803
|
+
// Process NRPNs
|
|
10645
10804
|
case dataEntryStates.NRPFine: {
|
|
10646
10805
|
if (this.lockGSNRPNParams) {
|
|
10647
10806
|
return;
|
|
@@ -10668,7 +10827,7 @@ function dataEntryCoarse(dataValue) {
|
|
|
10668
10827
|
consoleColors.value
|
|
10669
10828
|
);
|
|
10670
10829
|
break;
|
|
10671
|
-
// Part parameters
|
|
10830
|
+
// Part parameters
|
|
10672
10831
|
case nonRegisteredMSB.partParameter:
|
|
10673
10832
|
switch (NRPNFine) {
|
|
10674
10833
|
default:
|
|
@@ -10687,8 +10846,8 @@ function dataEntryCoarse(dataValue) {
|
|
|
10687
10846
|
consoleColors.value
|
|
10688
10847
|
);
|
|
10689
10848
|
break;
|
|
10690
|
-
// Vibrato rate
|
|
10691
|
-
case
|
|
10849
|
+
// Vibrato rate (custom vibrato)
|
|
10850
|
+
case nonRegisteredLSB.vibratoRate:
|
|
10692
10851
|
if (dataValue === 64) {
|
|
10693
10852
|
return;
|
|
10694
10853
|
}
|
|
@@ -10700,8 +10859,8 @@ function dataEntryCoarse(dataValue) {
|
|
|
10700
10859
|
"Hz"
|
|
10701
10860
|
);
|
|
10702
10861
|
break;
|
|
10703
|
-
// Vibrato depth
|
|
10704
|
-
case
|
|
10862
|
+
// Vibrato depth (custom vibrato)
|
|
10863
|
+
case nonRegisteredLSB.vibratoDepth:
|
|
10705
10864
|
if (dataValue === 64) {
|
|
10706
10865
|
return;
|
|
10707
10866
|
}
|
|
@@ -10713,8 +10872,8 @@ function dataEntryCoarse(dataValue) {
|
|
|
10713
10872
|
"cents of detune"
|
|
10714
10873
|
);
|
|
10715
10874
|
break;
|
|
10716
|
-
// Vibrato delay
|
|
10717
|
-
case
|
|
10875
|
+
// Vibrato delay (custom vibrato)
|
|
10876
|
+
case nonRegisteredLSB.vibratoDelay:
|
|
10718
10877
|
if (dataValue === 64) {
|
|
10719
10878
|
return;
|
|
10720
10879
|
}
|
|
@@ -10727,15 +10886,26 @@ function dataEntryCoarse(dataValue) {
|
|
|
10727
10886
|
);
|
|
10728
10887
|
break;
|
|
10729
10888
|
// Filter cutoff
|
|
10730
|
-
case
|
|
10889
|
+
case nonRegisteredLSB.TVFFilterCutoff:
|
|
10731
10890
|
this.controllerChange(
|
|
10732
10891
|
midiControllers.brightness,
|
|
10733
10892
|
dataValue
|
|
10734
10893
|
);
|
|
10735
10894
|
coolInfo("Filter cutoff", dataValue.toString(), "");
|
|
10736
10895
|
break;
|
|
10896
|
+
case nonRegisteredLSB.TVFFilterResonance:
|
|
10897
|
+
this.controllerChange(
|
|
10898
|
+
midiControllers.filterResonance,
|
|
10899
|
+
dataValue
|
|
10900
|
+
);
|
|
10901
|
+
coolInfo(
|
|
10902
|
+
"Filter resonance",
|
|
10903
|
+
dataValue.toString(),
|
|
10904
|
+
""
|
|
10905
|
+
);
|
|
10906
|
+
break;
|
|
10737
10907
|
// Attack time
|
|
10738
|
-
case
|
|
10908
|
+
case nonRegisteredLSB.EGAttackTime:
|
|
10739
10909
|
this.controllerChange(
|
|
10740
10910
|
midiControllers.attackTime,
|
|
10741
10911
|
dataValue
|
|
@@ -10746,8 +10916,15 @@ function dataEntryCoarse(dataValue) {
|
|
|
10746
10916
|
""
|
|
10747
10917
|
);
|
|
10748
10918
|
break;
|
|
10919
|
+
case nonRegisteredLSB.EGDecayTime:
|
|
10920
|
+
this.controllerChange(
|
|
10921
|
+
midiControllers.decayTime,
|
|
10922
|
+
dataValue
|
|
10923
|
+
);
|
|
10924
|
+
coolInfo("EG decay time", dataValue.toString(), "");
|
|
10925
|
+
break;
|
|
10749
10926
|
// Release time
|
|
10750
|
-
case
|
|
10927
|
+
case nonRegisteredLSB.EGReleaseTime:
|
|
10751
10928
|
this.controllerChange(
|
|
10752
10929
|
midiControllers.releaseTime,
|
|
10753
10930
|
dataValue
|
|
@@ -11164,9 +11341,10 @@ var portamentoLookup = {
|
|
|
11164
11341
|
124: 80,
|
|
11165
11342
|
127: 480
|
|
11166
11343
|
};
|
|
11167
|
-
function
|
|
11344
|
+
function portaTimeToRate(value) {
|
|
11345
|
+
let portaTime = 0;
|
|
11168
11346
|
if (portamentoLookup[value] !== void 0) {
|
|
11169
|
-
|
|
11347
|
+
portaTime = portamentoLookup[value];
|
|
11170
11348
|
}
|
|
11171
11349
|
let lower = null;
|
|
11172
11350
|
let upper = null;
|
|
@@ -11182,12 +11360,12 @@ function getLookup(value) {
|
|
|
11182
11360
|
if (lower !== null && upper !== null) {
|
|
11183
11361
|
const lowerTime = portamentoLookup[lower];
|
|
11184
11362
|
const upperTime = portamentoLookup[upper];
|
|
11185
|
-
|
|
11363
|
+
portaTime = lowerTime + (value - lower) * (upperTime - lowerTime) / (upper - lower);
|
|
11186
11364
|
}
|
|
11187
|
-
return
|
|
11365
|
+
return portaTime / 40;
|
|
11188
11366
|
}
|
|
11189
11367
|
function portamentoTimeToSeconds(time, distance) {
|
|
11190
|
-
return
|
|
11368
|
+
return portaTimeToRate(time) * distance;
|
|
11191
11369
|
}
|
|
11192
11370
|
|
|
11193
11371
|
// src/synthesizer/audio_engine/engine_methods/note_on.ts
|
|
@@ -11231,16 +11409,15 @@ function noteOn(midiNote, velocity) {
|
|
|
11231
11409
|
let portamentoFromKey = -1;
|
|
11232
11410
|
let portamentoDuration = 0;
|
|
11233
11411
|
const portamentoTime = this.midiControllers[midiControllers.portamentoTime] >> 7;
|
|
11234
|
-
const
|
|
11235
|
-
const currentFromKey = control >> 7;
|
|
11412
|
+
const portaControl = this.midiControllers[midiControllers.portamentoControl] >> 7;
|
|
11236
11413
|
if (!this.drumChannel && // No portamento on drum channel
|
|
11237
|
-
|
|
11414
|
+
portaControl !== internalMidiNote && // If the same note, there's no portamento
|
|
11238
11415
|
this.midiControllers[midiControllers.portamentoOnOff] >= 8192 && // (64 << 7)
|
|
11239
11416
|
portamentoTime > 0) {
|
|
11240
|
-
if (
|
|
11241
|
-
const diff = Math.abs(internalMidiNote -
|
|
11417
|
+
if (portaControl > 0) {
|
|
11418
|
+
const diff = Math.abs(internalMidiNote - portaControl);
|
|
11242
11419
|
portamentoDuration = portamentoTimeToSeconds(portamentoTime, diff);
|
|
11243
|
-
portamentoFromKey =
|
|
11420
|
+
portamentoFromKey = portaControl;
|
|
11244
11421
|
}
|
|
11245
11422
|
this.controllerChange(
|
|
11246
11423
|
midiControllers.portamentoControl,
|
|
@@ -17058,16 +17235,12 @@ var SpessaSynthProcessor3 = class {
|
|
|
17058
17235
|
});
|
|
17059
17236
|
}
|
|
17060
17237
|
getCachedVoice(patch, midiNote, velocity) {
|
|
17061
|
-
|
|
17062
|
-
let bankLSB = patch.bankLSB;
|
|
17063
|
-
const { isGMGSDrum, program } = patch;
|
|
17064
|
-
if (isGMGSDrum) {
|
|
17065
|
-
bankMSB = 128;
|
|
17066
|
-
bankLSB = 0;
|
|
17067
|
-
}
|
|
17068
|
-
return this.privateProps.cachedVoices?.[bankMSB]?.[bankLSB]?.[program]?.[midiNote]?.[velocity];
|
|
17238
|
+
return this.privateProps.cachedVoices?.[this.getCachedVoiceIndex(patch, midiNote, velocity)];
|
|
17069
17239
|
}
|
|
17070
17240
|
setCachedVoice(patch, midiNote, velocity, voices) {
|
|
17241
|
+
this.privateProps.cachedVoices[this.getCachedVoiceIndex(patch, midiNote, velocity)] = voices;
|
|
17242
|
+
}
|
|
17243
|
+
getCachedVoiceIndex(patch, midiNote, velocity) {
|
|
17071
17244
|
let bankMSB = patch.bankMSB;
|
|
17072
17245
|
let bankLSB = patch.bankLSB;
|
|
17073
17246
|
const { isGMGSDrum, program } = patch;
|
|
@@ -17075,19 +17248,11 @@ var SpessaSynthProcessor3 = class {
|
|
|
17075
17248
|
bankMSB = 128;
|
|
17076
17249
|
bankLSB = 0;
|
|
17077
17250
|
}
|
|
17078
|
-
|
|
17079
|
-
|
|
17080
|
-
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
}
|
|
17084
|
-
if (!this.privateProps.cachedVoices[bankMSB][bankLSB][program]) {
|
|
17085
|
-
this.privateProps.cachedVoices[bankMSB][bankLSB][program] = [];
|
|
17086
|
-
}
|
|
17087
|
-
if (!this.privateProps.cachedVoices[bankMSB][bankLSB][program][midiNote]) {
|
|
17088
|
-
this.privateProps.cachedVoices[bankMSB][bankLSB][program][midiNote] = [];
|
|
17089
|
-
}
|
|
17090
|
-
this.privateProps.cachedVoices[bankMSB][bankLSB][program][midiNote][velocity] = voices;
|
|
17251
|
+
return bankMSB + // 128 ^ 0
|
|
17252
|
+
bankLSB * 128 + // 128 ^ 1
|
|
17253
|
+
program * 16384 + // 128 ^ 2
|
|
17254
|
+
2097152 * midiNote + // 128 ^ 3
|
|
17255
|
+
268435456 * velocity;
|
|
17091
17256
|
}
|
|
17092
17257
|
createMIDIChannelInternal(sendEvent) {
|
|
17093
17258
|
const channel = new MIDIChannel(
|
|
@@ -17111,7 +17276,7 @@ var SpessaSynthProcessor3 = class {
|
|
|
17111
17276
|
this.midiChannels.forEach((c) => {
|
|
17112
17277
|
c.setPresetLock(false);
|
|
17113
17278
|
});
|
|
17114
|
-
this.resetAllControllers(
|
|
17279
|
+
this.resetAllControllers();
|
|
17115
17280
|
}
|
|
17116
17281
|
getDefaultPresets() {
|
|
17117
17282
|
this.privateProps.defaultPreset = this.soundBankManager.getPreset(
|
|
@@ -17165,7 +17330,6 @@ export {
|
|
|
17165
17330
|
Modulator,
|
|
17166
17331
|
ModulatorSource,
|
|
17167
17332
|
NON_CC_INDEX_OFFSET,
|
|
17168
|
-
PORTAMENTO_CONTROL_UNSET,
|
|
17169
17333
|
SoundBankLoader,
|
|
17170
17334
|
SpessaSynthCoreUtils,
|
|
17171
17335
|
SpessaSynthLogging,
|