Skip to content

Commit

Permalink
Refactor controller reset positions
Browse files Browse the repository at this point in the history
and update MIDI implementation with it
  • Loading branch information
spessasus committed Oct 7, 2024
1 parent a4f230e commit 838458d
Show file tree
Hide file tree
Showing 22 changed files with 180 additions and 148 deletions.
13 changes: 13 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/spessasynth_lib/midi_parser/midi_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { IndexedByteArray } from "../utils/indexed_array.js";
import { SpessaSynthGroupCollapsed, SpessaSynthGroupEnd, SpessaSynthInfo, SpessaSynthWarn } from "../utils/loggin.js";
import { consoleColors } from "../utils/other.js";
import { DEFAULT_PERCUSSION } from "../synthetizer/synthetizer.js";
import { customControllers } from "../synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js";

import { customControllers } from "../synthetizer/worklet_system/worklet_utilities/controller_tables.js";

/**
* @param ticks {number}
Expand Down
10 changes: 5 additions & 5 deletions src/spessasynth_lib/midi_parser/midi_message.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,11 @@ export const midiControllers = {
generalPurposeController7: 82,
generalPurposeController8: 83,
portamentoControl: 84,
effects1Depth: 91,
effects2Depth: 92,
effects3Depth: 93,
effects4Depth: 94,
effects5Depth: 95,
reverbDepth: 91,
tremoloDepth: 92,
chorusDepth: 93,
detuneDepth: 94,
phaserDepth: 95,
dataIncrement: 96,
dataDecrement: 97,
NRPNLsb: 98,
Expand Down
2 changes: 1 addition & 1 deletion src/spessasynth_lib/sequencer/worklet_sequencer/play.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defaultControllerArray[midiControllers.expressionController] = 127;
defaultControllerArray[midiControllers.pan] = 64;
defaultControllerArray[midiControllers.releaseTime] = 64;
defaultControllerArray[midiControllers.brightness] = 64;
defaultControllerArray[midiControllers.effects1Depth] = 0;
defaultControllerArray[midiControllers.reverbDepth] = 0;

/**
* plays from start to the target time, excluding note messages (to get the synth to the correct state)
Expand Down
2 changes: 1 addition & 1 deletion src/spessasynth_lib/soundfont/basic_soundfont/modulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ export const defaultModulators = [

// cc 92 (tremolo) to modLFO volume
new Modulator({
srcEnum: getModSourceEnum(modulatorCurveTypes.linear, 0, 0, 1, midiControllers.effects2Depth), /*linear forward unipolar cc 92 */
srcEnum: getModSourceEnum(modulatorCurveTypes.linear, 0, 0, 1, midiControllers.tremoloDepth), /*linear forward unipolar cc 92 */
dest: generatorTypes.modLfoToVolume,
amt: 24,
secSrcEnum: 0x0, // no controller
Expand Down
4 changes: 2 additions & 2 deletions src/spessasynth_lib/soundfont/dls/articulator_converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ function getSF2SourceFromDLS(source)
isCC = true;
break;
case DLSSources.reverb:
sourceEnum = midiControllers.effects1Depth;
sourceEnum = midiControllers.reverbDepth;
isCC = true;
break;
case DLSSources.chorus:
sourceEnum = midiControllers.effects3Depth;
sourceEnum = midiControllers.chorusDepth;
isCC = true;
break;
case DLSSources.expression:
Expand Down
2 changes: 1 addition & 1 deletion src/spessasynth_lib/synthetizer/synthetizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ export class Synthetizer
{
for (let i = 0; i < this.channelsAmount; i++)
{
this.controllerChange(i, midiControllers.effects1Depth, 127);
this.controllerChange(i, midiControllers.reverbDepth, 127);
}
return "That's the spirit!";
}
Expand Down
22 changes: 11 additions & 11 deletions src/spessasynth_lib/synthetizer/worklet_processor.min.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { returnMessageType } from "./worklet_message.js";
import { NON_CC_INDEX_OFFSET } from "../worklet_utilities/worklet_processor_channel.js";

import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
import { NON_CC_INDEX_OFFSET } from "../worklet_utilities/controller_tables.js";

/**
* Calls synth event from the worklet side
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { consoleColors } from "../../../utils/other.js";
import { midiControllers } from "../../../midi_parser/midi_message.js";
import { channelConfiguration, dataEntryStates } from "../worklet_utilities/worklet_processor_channel.js";
import { channelConfiguration } from "../worklet_utilities/worklet_processor_channel.js";
import { computeModulators } from "../worklet_utilities/worklet_modulator.js";
import { SpessaSynthInfo, SpessaSynthWarn } from "../../../utils/loggin.js";
import { SYNTHESIZER_GAIN } from "../main_processor.js";
import { DEFAULT_PERCUSSION } from "../../synthetizer.js";
import { dataEntryStates } from "../worklet_utilities/controller_tables.js";

/**
* @param channel {number}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { consoleColors } from "../../../utils/other.js";
import { midiControllers } from "../../../midi_parser/midi_message.js";
import {
customControllers,
dataEntryStates,
NON_CC_INDEX_OFFSET
} from "../worklet_utilities/worklet_processor_channel.js";
import { SpessaSynthInfo, SpessaSynthWarn } from "../../../utils/loggin.js";
import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
import { customControllers, dataEntryStates, NON_CC_INDEX_OFFSET } from "../worklet_utilities/controller_tables.js";

/**
* Executes a data entry for an NRP for a sc88pro NRP (because touhou yes) and RPN tuning
Expand Down Expand Up @@ -176,7 +172,7 @@ export function dataEntryCoarse(channel, dataValue)
// drum reverb
case 0x1D:
const reverb = dataValue;
this.controllerChange(channel, midiControllers.effects1Depth, reverb);
this.controllerChange(channel, midiControllers.reverbDepth, reverb);
SpessaSynthInfo(
`%cGS Drum reverb for %c${channel}%c: %c${reverb}`,
consoleColors.info,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { consoleColors } from "../../../utils/other.js";
import { midiControllers } from "../../../midi_parser/midi_message.js";
import { DEFAULT_PERCUSSION, DEFAULT_SYNTH_MODE } from "../../synthetizer.js";
import { SpessaSynthInfo } from "../../../utils/loggin.js";
import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
import {
customControllers,
customResetArray,
dataEntryStates,
NON_CC_INDEX_OFFSET,
resetArray
} from "../worklet_utilities/worklet_processor_channel.js";
import { SpessaSynthInfo } from "../../../utils/loggin.js";
import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
} from "../worklet_utilities/controller_tables.js";

/**
* @this {SpessaSynthProcessor}
Expand Down Expand Up @@ -89,8 +89,8 @@ export function resetAllControllers(log = true)
restoreControllerValueEvent(midiControllers.pan);
restoreControllerValueEvent(midiControllers.expressionController);
restoreControllerValueEvent(midiControllers.modulationWheel);
restoreControllerValueEvent(midiControllers.effects3Depth);
restoreControllerValueEvent(midiControllers.effects1Depth);
restoreControllerValueEvent(midiControllers.chorusDepth);
restoreControllerValueEvent(midiControllers.reverbDepth);
restoreControllerValueEvent(midiControllers.brightness);

// restore pitch wheel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,12 @@ export function systemExclusive(messageData, channelOffset = 0)

// chorus send
case 0x21:
this.controllerChange(channel, midiControllers.effects3Depth, messageValue);
this.controllerChange(channel, midiControllers.chorusDepth, messageValue);
break;

// reverb send
case 0x22:
this.controllerChange(channel, midiControllers.effects1Depth, messageValue);
this.controllerChange(channel, midiControllers.reverbDepth, messageValue);
break;

case 0x40:
Expand Down Expand Up @@ -598,12 +598,12 @@ export function systemExclusive(messageData, channelOffset = 0)

// reverb
case 0x13:
this.controllerChange(channel, midiControllers.effects1Depth, value);
this.controllerChange(channel, midiControllers.reverbDepth, value);
break;

// chorus
case 0x12:
this.controllerChange(channel, midiControllers.effects3Depth, value);
this.controllerChange(channel, midiControllers.chorusDepth, value);
break;

default:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { customControllers, NON_CC_INDEX_OFFSET } from "../worklet_utilities/worklet_processor_channel.js";
import { consoleColors } from "../../../utils/other.js";
import { computeModulators } from "../worklet_utilities/worklet_modulator.js";
import { SpessaSynthInfo } from "../../../utils/loggin.js";
import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
import { customControllers, NON_CC_INDEX_OFFSET } from "../worklet_utilities/controller_tables.js";

/**
* Transposes all channels by given amount of semitones
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { absCentsToHz, timecentsToSeconds } from "../worklet_utilities/unit_converter.js";
import { getLFOValue } from "../worklet_utilities/lfo.js";
import { customControllers } from "../worklet_utilities/worklet_processor_channel.js";
import { WorkletModulationEnvelope } from "../worklet_utilities/modulation_envelope.js";
import {
getSampleCubic,
Expand All @@ -13,6 +12,7 @@ import { WorkletLowpassFilter } from "../worklet_utilities/lowpass_filter.js";
import { MIN_NOTE_LENGTH } from "../main_processor.js";
import { WorkletVolumeEnvelope } from "../worklet_utilities/volume_envelope.js";
import { generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
import { customControllers } from "../worklet_utilities/controller_tables.js";


const HALF_PI = Math.PI / 2;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { midiControllers } from "../../../midi_parser/midi_message.js";
import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";

/*
* A bit of explanation:
* The controller table is stored as an int16 array, it stores 14-bit values.
* This controller table is then extedned with the modulatorSources section,
* for example pitch range and pitch range depth.
* This allows us for precise control range and supports full pitch wheel resolution.
*/
export const NON_CC_INDEX_OFFSET = 128;
export const CONTROLLER_TABLE_SIZE = 147;


// an array with preset default values so we can quickly use set() to reset the controllers
export const resetArray = new Int16Array(CONTROLLER_TABLE_SIZE).fill(0);
export const setResetValue = (i, v) => resetArray[i] = v << 7;

// values come from Falcosoft MidiPlayer 6
setResetValue(midiControllers.mainVolume, 100);
setResetValue(midiControllers.balance, 64);
setResetValue(midiControllers.expressionController, 127);
setResetValue(midiControllers.pan, 64);

setResetValue(midiControllers.timbreHarmonicContent, 64);
setResetValue(midiControllers.releaseTime, 64);
setResetValue(midiControllers.attackTime, 64);
setResetValue(midiControllers.brightness, 64);

setResetValue(midiControllers.soundController6, 64);
setResetValue(midiControllers.soundController7, 64);
setResetValue(midiControllers.soundController8, 64);
setResetValue(midiControllers.soundController9, 64);
setResetValue(midiControllers.generalPurposeController6, 64);
setResetValue(midiControllers.generalPurposeController8, 64);

// pitch wheel
setResetValue(NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel, 64);
setResetValue(NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange, 2);

export const customControllers = {
channelTuning: 0, // cents, RPN for fine tuning
channelTransposeFine: 1, // cents, only the decimal tuning, (e.g. transpose is 4.5, then shift by 4 keys + tune by 50 cents)
modulationMultiplier: 2, // cents, set by moduldation depth RPN
masterTuning: 3, // cents, set by system exclusive
channelTuningSemitones: 4 // semitones, for RPN coarse tuning
};
export const CUSTOM_CONTROLLER_TABLE_SIZE = Object.keys(customControllers).length;
export const customResetArray = new Float32Array(CUSTOM_CONTROLLER_TABLE_SIZE);
customResetArray[customControllers.modulationMultiplier] = 1;
/**
* @enum {number}
*/
export const dataEntryStates = {
Idle: 0,
RPCoarse: 1,
RPFine: 2,
NRPCoarse: 3,
NRPFine: 4,
DataCoarse: 5,
DataFine: 6
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getModulatorCurveValue, MOD_PRECOMPUTED_LENGTH } from "./modulator_curves.js";
import { NON_CC_INDEX_OFFSET } from "./worklet_processor_channel.js";
import { WorkletVolumeEnvelope } from "./volume_envelope.js";
import { WorkletModulationEnvelope } from "./modulation_envelope.js";
import { generatorLimits, generatorTypes } from "../../../soundfont/basic_soundfont/generator.js";
import { Modulator, modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
import { NON_CC_INDEX_OFFSET } from "./controller_tables.js";

/**
* worklet_modulator.js
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { midiControllers } from "../../../midi_parser/midi_message.js";

import { modulatorSources } from "../../../soundfont/basic_soundfont/modulator.js";
import { CONTROLLER_TABLE_SIZE, CUSTOM_CONTROLLER_TABLE_SIZE, dataEntryStates } from "./controller_tables.js";

/**
* @typedef {Object} WorkletProcessorChannel
Expand Down Expand Up @@ -87,45 +85,6 @@ export function createWorkletChannel(sendEvent = false)
}
}

export const NON_CC_INDEX_OFFSET = 128;
export const CONTROLLER_TABLE_SIZE = 147;
// an array with preset default values so we can quickly use set() to reset the controllers
export const resetArray = new Int16Array(CONTROLLER_TABLE_SIZE).fill(0);
// default values (the array is 14 bit so shift the 7 bit values by 7 bits)
resetArray[midiControllers.mainVolume] = 100 << 7;
resetArray[midiControllers.expressionController] = 127 << 7;
resetArray[midiControllers.pan] = 64 << 7;
resetArray[midiControllers.releaseTime] = 64 << 7;
resetArray[midiControllers.brightness] = 64 << 7;
resetArray[midiControllers.timbreHarmonicContent] = 64 << 7;
resetArray[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheel] = 8192;
resetArray[NON_CC_INDEX_OFFSET + modulatorSources.pitchWheelRange] = 2 << 7;

/**
* @enum {number}
*/
export const dataEntryStates = {
Idle: 0,
RPCoarse: 1,
RPFine: 2,
NRPCoarse: 3,
NRPFine: 4,
DataCoarse: 5,
DataFine: 6
};


export const customControllers = {
channelTuning: 0, // cents, RPN for fine tuning
channelTransposeFine: 1, // cents, only the decimal tuning, (e.g. transpose is 4.5, then shift by 4 keys + tune by 50 cents)
modulationMultiplier: 2, // cents, set by moduldation depth RPN
masterTuning: 3, // cents, set by system exclusive
channelTuningSemitones: 4 // semitones, for RPN coarse tuning
};
export const CUSTOM_CONTROLLER_TABLE_SIZE = Object.keys(customControllers).length;
export const customResetArray = new Float32Array(CUSTOM_CONTROLLER_TABLE_SIZE);
customResetArray[customControllers.modulationMultiplier] = 1;

/**
* This is a channel configuration enum, it is internally sent from Synthetizer via controller change
* @enum {number}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ import { Selector } from "./synthui_selector.js";
import {
ALL_CHANNELS_OR_DIFFERENT_ACTION
} from "../../../../spessasynth_lib/synthetizer/worklet_system/message_protocol/worklet_message.js";
import {
NON_CC_INDEX_OFFSET
} from "../../../../spessasynth_lib/synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js";

import { modulatorSources } from "../../../../spessasynth_lib/soundfont/basic_soundfont/modulator.js";
import {
NON_CC_INDEX_OFFSET
} from "../../../../spessasynth_lib/synthetizer/worklet_system/worklet_utilities/controller_tables.js";

export const ICON_SIZE = 32;

Expand Down Expand Up @@ -179,11 +179,11 @@ export function createChannelController(channelNumber)
controller.appendChild(modulation.div);

// chorus
const chorus = createCCMeterHelper(midiControllers.effects3Depth, "channelController.chorusMeter", 0);
const chorus = createCCMeterHelper(midiControllers.chorusDepth, "channelController.chorusMeter", 0);
controller.appendChild(chorus.div);

// reverb
const reverb = createCCMeterHelper(midiControllers.effects1Depth, "channelController.reverbMeter", 0);
const reverb = createCCMeterHelper(midiControllers.reverbDepth, "channelController.reverbMeter", 0);
controller.appendChild(reverb.div);

// brightness
Expand Down
4 changes: 2 additions & 2 deletions src/website/js/synthesizer_ui/methods/set_event_listeners.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ export function setEventListeners()
this.controllers[channel].mod.update(value);
break;

case midiControllers.effects3Depth:
case midiControllers.chorusDepth:
// chorus
this.controllers[channel].chorus.update(value);
break;

case midiControllers.effects1Depth:
case midiControllers.reverbDepth:
// reverb
this.controllers[channel].reverb.update(value);
break;
Expand Down
Loading

0 comments on commit 838458d

Please sign in to comment.