spessasynth_lib 3.24.26 → 3.24.27
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/README.md +28 -10
- package/midi_parser/basic_midi.js +36 -17
- package/package.json +1 -1
- package/soundfont/basic_soundfont/modulator.js +151 -119
- package/soundfont/dls/articulator_converter.js +7 -7
- package/soundfont/dls/dls_sources.js +28 -28
- package/soundfont/read_sf2/modulators.js +6 -7
- package/synthetizer/worklet_processor.min.js +15 -15
- package/synthetizer/worklet_system/worklet_methods/controller_control/reset_controllers.js +17 -3
- package/synthetizer/worklet_system/worklet_utilities/controller_tables.js +2 -1
- package/synthetizer/worklet_system/worklet_utilities/worklet_voice.js +1 -1
package/README.md
CHANGED
|
@@ -32,13 +32,28 @@ document.getElementById("button").onclick = async () =>
|
|
|
32
32
|
|
|
33
33
|
## Current Features
|
|
34
34
|
|
|
35
|
+
### Numerous Format Support
|
|
36
|
+
Supported formats list:
|
|
37
|
+
- `.mid` - Standard MIDI File
|
|
38
|
+
- `.kar` - Soft Karaoke MIDI File
|
|
39
|
+
- `.sf2` - SoundFont2 File
|
|
40
|
+
- `.sf3` - SoundFont2 Compressed File
|
|
41
|
+
- `.sfogg` - SF2Pack With Vorbis Compression
|
|
42
|
+
- `.dls` - Downloadable Sounds Levels 1 & 2 (as well as Mobile DLS)
|
|
43
|
+
- `.rmi` - RIFF MIDI File
|
|
44
|
+
- `.rmi` - RIFF MIDI File With Embedded DLS
|
|
45
|
+
- `.rmi` - [RIFF MIDI File With Embedded SF2](https://github.com/spessasus/sf2-rmidi-specification)
|
|
46
|
+
|
|
47
|
+
*With [an easy way of converting between them!](https://github.com/spessasus/SpessaSynth/wiki/Converting-Between-Formats)*
|
|
48
|
+
|
|
35
49
|
### Easy Integration
|
|
36
|
-
- **Modular design:** Easy integration into other projects (load what you need)
|
|
37
|
-
- **[Detailed documentation:](https://github.com/spessasus/SpessaSynth/wiki/Home)** With [examples!](https://github.com/spessasus/SpessaSynth/wiki/Usage-As-Library#examples)
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
50
|
+
- **Modular design:** *Easy integration into other projects (load what you need)*
|
|
51
|
+
- **[Detailed documentation:](https://github.com/spessasus/SpessaSynth/wiki/Home)** *With [examples!](https://github.com/spessasus/SpessaSynth/wiki/Usage-As-Library#examples)*
|
|
52
|
+
- **Flexible:** *It's not just a MIDI player!*
|
|
53
|
+
- **Easy to Use:** *Basic setup is just [two lines of code!](https://github.com/spessasus/SpessaSynth/wiki/Usage-As-Library#minimal-setup)*
|
|
54
|
+
- **No dependencies:** *Batteries included!*
|
|
40
55
|
|
|
41
|
-
### Powerful
|
|
56
|
+
### Powerful Synthesizer
|
|
42
57
|
- Suitable for both **real-time** and **offline** synthesis
|
|
43
58
|
- **Excellent SoundFont support:**
|
|
44
59
|
- **Full Generator Support**
|
|
@@ -63,19 +78,22 @@ document.getElementById("button").onclick = async () =>
|
|
|
63
78
|
- **[Custom modulators for additional controllers](https://github.com/spessasus/SpessaSynth/wiki/Modulator-Class#default-modulators):** *Why not?*
|
|
64
79
|
- **Written using AudioWorklets:**
|
|
65
80
|
- Runs in a **separate thread** for maximum performance
|
|
81
|
+
- Doesn't stop playing even when the main thread is frozen
|
|
66
82
|
- Supported by all modern browsers
|
|
67
83
|
- **Unlimited channel count:** Your CPU is the limit!
|
|
68
84
|
- **Excellent MIDI Standards Support:**
|
|
69
85
|
- **MIDI Controller Support:** Default supported controllers [here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-controllers)
|
|
86
|
+
- **Portamento Support:** Glide the notes!
|
|
87
|
+
- **Sound Controllers:** Real-time filter and envelope control!
|
|
70
88
|
- **MIDI Tuning Standard Support:** [more info here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#midi-tuning-standard)
|
|
71
89
|
- [Full **RPN** and limited **NRPN** support](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-registered-parameters)
|
|
72
90
|
- Supports some [**Roland GS** and **Yamaha XG** system exclusives](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-system-exclusives)
|
|
73
|
-
- **High-performance mode:** Play Rush E!
|
|
91
|
+
- **High-performance mode:** Play Rush E! *note: may kill your browser ;)*
|
|
74
92
|
|
|
75
|
-
###
|
|
76
|
-
- **Supports MIDI formats 0, 1, and 2:**
|
|
93
|
+
### Powerful and Fast MIDI Sequencer
|
|
94
|
+
- **Supports MIDI formats 0, 1, and 2:** *note: format 2 support is experimental as it's very, very rare.*
|
|
77
95
|
- **[Multi-Port MIDI](https://github.com/spessasus/SpessaSynth/wiki/About-Multi-Port) support:** More than 16 channels!
|
|
78
|
-
- **Smart preloading:** Only preloads the samples used in the MIDI file for smooth playback (down to key and velocity!)
|
|
96
|
+
- **Smart preloading:** Only preloads the samples used in the MIDI file for smooth playback *(down to key and velocity!)*
|
|
79
97
|
- **Lyrics support:** Add karaoke to your program!
|
|
80
98
|
- **Raw lyrics available:** Decode in any encoding! *(Kanji? No problem!)*
|
|
81
99
|
- **Runs in Audio Thread as well:** Never blocks the main thread
|
|
@@ -89,7 +107,7 @@ document.getElementById("button").onclick = async () =>
|
|
|
89
107
|
- **Used channels on track:** Quickly determine which channels are used
|
|
90
108
|
- **Key range detection:** Detect the key range of the MIDI
|
|
91
109
|
- **Easy MIDI editing:** Use [helper functions](https://github.com/spessasus/SpessaSynth/wiki/Writing-MIDI-Files#modifymidi) to modify the song to your needs!
|
|
92
|
-
- **Loop detection:** Automatically detects loops in MIDIs (e.g., from
|
|
110
|
+
- **Loop detection:** Automatically detects loops in MIDIs (e.g., from *Touhou Project*)
|
|
93
111
|
- **First note detection:** Skip unnecessary silence at the start by jumping to the first note!
|
|
94
112
|
- **Lyrics support:** Both regular MIDI and .kar files!
|
|
95
113
|
- **[Write MIDI files from scratch](https://github.com/spessasus/SpessaSynth/wiki/Creating-MIDI-Files)**
|
|
@@ -92,9 +92,6 @@ export class BasicMIDI extends MIDISequenceData
|
|
|
92
92
|
* @type {boolean}
|
|
93
93
|
*/
|
|
94
94
|
let karaokeHasTitle = false;
|
|
95
|
-
let portOffset = 0;
|
|
96
|
-
this.midiPorts = [];
|
|
97
|
-
this.midiPortChannelOffsets = [];
|
|
98
95
|
|
|
99
96
|
this.keyRange = { max: 0, min: 127 };
|
|
100
97
|
|
|
@@ -126,7 +123,6 @@ export class BasicMIDI extends MIDISequenceData
|
|
|
126
123
|
{
|
|
127
124
|
const track = this.tracks[i];
|
|
128
125
|
const usedChannels = new Set();
|
|
129
|
-
this.midiPorts.push(-1);
|
|
130
126
|
let trackHasVoiceMessages = false;
|
|
131
127
|
|
|
132
128
|
for (const e of track)
|
|
@@ -230,16 +226,6 @@ export class BasicMIDI extends MIDISequenceData
|
|
|
230
226
|
e.messageData.currentIndex = 0;
|
|
231
227
|
break;
|
|
232
228
|
|
|
233
|
-
case messageTypes.midiPort:
|
|
234
|
-
const port = e.messageData[0];
|
|
235
|
-
this.midiPorts[i] = port;
|
|
236
|
-
if (this.midiPortChannelOffsets[port] === undefined)
|
|
237
|
-
{
|
|
238
|
-
this.midiPortChannelOffsets[port] = portOffset;
|
|
239
|
-
portOffset += 16;
|
|
240
|
-
}
|
|
241
|
-
break;
|
|
242
|
-
|
|
243
229
|
case messageTypes.copyright:
|
|
244
230
|
if (!copyrightDetected)
|
|
245
231
|
{
|
|
@@ -399,6 +385,33 @@ export class BasicMIDI extends MIDISequenceData
|
|
|
399
385
|
consoleColors.recognized
|
|
400
386
|
);
|
|
401
387
|
|
|
388
|
+
// determine ports
|
|
389
|
+
let portOffset = 0;
|
|
390
|
+
this.midiPorts = [];
|
|
391
|
+
this.midiPortChannelOffsets = [];
|
|
392
|
+
for (let trackNum = 0; trackNum < this.tracks.length; trackNum++)
|
|
393
|
+
{
|
|
394
|
+
this.midiPorts.push(-1);
|
|
395
|
+
if (this.usedChannelsOnTrack[trackNum].size === 0)
|
|
396
|
+
{
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
for (const e of this.tracks[trackNum])
|
|
400
|
+
{
|
|
401
|
+
if (e.messageStatusByte !== messageTypes.midiPort)
|
|
402
|
+
{
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
const port = e.messageData[0];
|
|
406
|
+
this.midiPorts[trackNum] = port;
|
|
407
|
+
if (this.midiPortChannelOffsets[port] === undefined)
|
|
408
|
+
{
|
|
409
|
+
this.midiPortChannelOffsets[port] = portOffset;
|
|
410
|
+
portOffset += 16;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
402
415
|
// fix midi ports:
|
|
403
416
|
// midi tracks without ports will have a value of -1
|
|
404
417
|
// if all ports have a value of -1, set it to 0,
|
|
@@ -408,15 +421,21 @@ export class BasicMIDI extends MIDISequenceData
|
|
|
408
421
|
// but leave the conductor track with no port pref.
|
|
409
422
|
// this spessasynth to reserve the first 16 channels for the conductor track
|
|
410
423
|
// (which doesn't play anything) and use the additional 16 for the actual ports.
|
|
411
|
-
let defaultPort =
|
|
424
|
+
let defaultPort = Infinity;
|
|
412
425
|
for (let port of this.midiPorts)
|
|
413
426
|
{
|
|
414
427
|
if (port !== -1)
|
|
415
428
|
{
|
|
416
|
-
defaultPort
|
|
417
|
-
|
|
429
|
+
if (defaultPort > port)
|
|
430
|
+
{
|
|
431
|
+
defaultPort = port;
|
|
432
|
+
}
|
|
418
433
|
}
|
|
419
434
|
}
|
|
435
|
+
if (defaultPort === Infinity)
|
|
436
|
+
{
|
|
437
|
+
defaultPort = 0;
|
|
438
|
+
}
|
|
420
439
|
this.midiPorts = this.midiPorts.map(port => port === -1 ? defaultPort : port);
|
|
421
440
|
// add fake port if empty
|
|
422
441
|
if (this.midiPortChannelOffsets.length === 0)
|
package/package.json
CHANGED
|
@@ -33,19 +33,50 @@ export class Modulator
|
|
|
33
33
|
currentValue = 0;
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
37
|
-
* @
|
|
36
|
+
* The source enumeration for this modulator
|
|
37
|
+
* @type {number}
|
|
38
|
+
*/
|
|
39
|
+
sourceEnum;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The secondary source enumeration for this modulator
|
|
43
|
+
* @type {number}
|
|
38
44
|
*/
|
|
39
|
-
|
|
45
|
+
secondarySourceEnum;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The generator destination of this modulator
|
|
49
|
+
* @type {generatorTypes}
|
|
50
|
+
*/
|
|
51
|
+
modulatorDestination;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The transform amount for this modulator
|
|
55
|
+
* @type {number}
|
|
56
|
+
*/
|
|
57
|
+
transformAmount;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The transform type for this modulator
|
|
61
|
+
* @type {0|2}
|
|
62
|
+
*/
|
|
63
|
+
transformType;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* creates a modulator
|
|
67
|
+
* @param srcEnum {number}
|
|
68
|
+
* @param secSrcEnum {number}
|
|
69
|
+
* @param destination {generatorTypes|number}
|
|
70
|
+
* @param amount {number}
|
|
71
|
+
* @param transformType {number}
|
|
72
|
+
*/
|
|
73
|
+
constructor(srcEnum, secSrcEnum, destination, amount, transformType)
|
|
40
74
|
{
|
|
41
|
-
this.sourceEnum =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
this.
|
|
46
|
-
this.secondarySourceEnum = params.secSrcEnum;
|
|
47
|
-
this.transformAmount = params.amt;
|
|
48
|
-
this.transformType = params.transform;
|
|
75
|
+
this.sourceEnum = srcEnum;
|
|
76
|
+
this.modulatorDestination = destination;
|
|
77
|
+
this.secondarySourceEnum = secSrcEnum;
|
|
78
|
+
this.transformAmount = amount;
|
|
79
|
+
this.transformType = transformType;
|
|
49
80
|
|
|
50
81
|
|
|
51
82
|
if (this.modulatorDestination > 58)
|
|
@@ -96,13 +127,13 @@ export class Modulator
|
|
|
96
127
|
*/
|
|
97
128
|
static copy(modulator)
|
|
98
129
|
{
|
|
99
|
-
return new Modulator(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
130
|
+
return new Modulator(
|
|
131
|
+
modulator.sourceEnum,
|
|
132
|
+
modulator.secondarySourceEnum,
|
|
133
|
+
modulator.modulatorDestination,
|
|
134
|
+
modulator.transformAmount,
|
|
135
|
+
modulator.transformType
|
|
136
|
+
);
|
|
106
137
|
}
|
|
107
138
|
|
|
108
139
|
/**
|
|
@@ -121,62 +152,63 @@ export class Modulator
|
|
|
121
152
|
}
|
|
122
153
|
|
|
123
154
|
/**
|
|
124
|
-
*
|
|
125
|
-
* @param modulator {Modulator}
|
|
126
|
-
* @returns {Modulator}
|
|
127
|
-
*/
|
|
128
|
-
sumTransform(modulator)
|
|
129
|
-
{
|
|
130
|
-
return new Modulator({
|
|
131
|
-
srcEnum: this.sourceEnum,
|
|
132
|
-
secSrcEnum: this.secondarySourceEnum,
|
|
133
|
-
dest: this.modulatorDestination,
|
|
134
|
-
transform: this.transformType,
|
|
135
|
-
amt: this.transformAmount + modulator.transformAmount
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
155
|
+
* @param mod {Modulator}
|
|
140
156
|
* @returns {string}
|
|
141
157
|
*/
|
|
142
|
-
debugString()
|
|
158
|
+
static debugString(mod)
|
|
143
159
|
{
|
|
144
160
|
function getKeyByValue(object, value)
|
|
145
161
|
{
|
|
146
162
|
return Object.keys(object).find(key => object[key] === value);
|
|
147
163
|
}
|
|
148
164
|
|
|
149
|
-
let sourceString = getKeyByValue(modulatorCurveTypes,
|
|
150
|
-
sourceString +=
|
|
151
|
-
sourceString +=
|
|
152
|
-
if (
|
|
165
|
+
let sourceString = getKeyByValue(modulatorCurveTypes, mod.sourceCurveType);
|
|
166
|
+
sourceString += mod.sourcePolarity === 0 ? " unipolar " : " bipolar ";
|
|
167
|
+
sourceString += mod.sourceDirection === 0 ? "forwards " : "backwards ";
|
|
168
|
+
if (mod.sourceUsesCC)
|
|
153
169
|
{
|
|
154
|
-
sourceString += getKeyByValue(midiControllers,
|
|
170
|
+
sourceString += getKeyByValue(midiControllers, mod.sourceIndex);
|
|
155
171
|
}
|
|
156
172
|
else
|
|
157
173
|
{
|
|
158
|
-
sourceString += getKeyByValue(modulatorSources,
|
|
174
|
+
sourceString += getKeyByValue(modulatorSources, mod.sourceIndex);
|
|
159
175
|
}
|
|
160
176
|
|
|
161
|
-
let secSrcString = getKeyByValue(modulatorCurveTypes,
|
|
162
|
-
secSrcString +=
|
|
163
|
-
secSrcString +=
|
|
164
|
-
if (
|
|
177
|
+
let secSrcString = getKeyByValue(modulatorCurveTypes, mod.secSrcCurveType);
|
|
178
|
+
secSrcString += mod.secSrcPolarity === 0 ? " unipolar " : " bipolar ";
|
|
179
|
+
secSrcString += mod.secSrcCurveType === 0 ? "forwards " : "backwards ";
|
|
180
|
+
if (mod.secSrcUsesCC)
|
|
165
181
|
{
|
|
166
|
-
secSrcString += getKeyByValue(midiControllers,
|
|
182
|
+
secSrcString += getKeyByValue(midiControllers, mod.secSrcIndex);
|
|
167
183
|
}
|
|
168
184
|
else
|
|
169
185
|
{
|
|
170
|
-
secSrcString += getKeyByValue(modulatorSources,
|
|
186
|
+
secSrcString += getKeyByValue(modulatorSources, mod.secSrcIndex);
|
|
171
187
|
}
|
|
172
188
|
return `Modulator:
|
|
173
189
|
Source: ${sourceString}
|
|
174
190
|
Secondary source: ${secSrcString}
|
|
175
|
-
Destination: ${getKeyByValue(generatorTypes,
|
|
176
|
-
Trasform amount: ${
|
|
177
|
-
Transform type: ${
|
|
191
|
+
Destination: ${getKeyByValue(generatorTypes, mod.modulatorDestination)}
|
|
192
|
+
Trasform amount: ${mod.transformAmount}
|
|
193
|
+
Transform type: ${mod.transformType}
|
|
178
194
|
\n\n`;
|
|
179
195
|
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Sum transform and create a NEW modulator
|
|
199
|
+
* @param modulator {Modulator}
|
|
200
|
+
* @returns {Modulator}
|
|
201
|
+
*/
|
|
202
|
+
sumTransform(modulator)
|
|
203
|
+
{
|
|
204
|
+
return new Modulator(
|
|
205
|
+
this.sourceEnum,
|
|
206
|
+
this.secondarySourceEnum,
|
|
207
|
+
this.modulatorDestination,
|
|
208
|
+
this.transformAmount + modulator.transformAmount,
|
|
209
|
+
this.transformType
|
|
210
|
+
);
|
|
211
|
+
}
|
|
180
212
|
}
|
|
181
213
|
|
|
182
214
|
export const DEFAULT_ATTENUATION_MOD_AMOUNT = 960;
|
|
@@ -189,155 +221,155 @@ export function getModSourceEnum(curveType, polarity, direction, isCC, index)
|
|
|
189
221
|
|
|
190
222
|
const soundFontModulators = [
|
|
191
223
|
// vel to attenuation
|
|
192
|
-
new Modulator(
|
|
193
|
-
|
|
224
|
+
new Modulator(
|
|
225
|
+
getModSourceEnum(
|
|
194
226
|
DEFAULT_ATTENUATION_MOD_CURVE_TYPE,
|
|
195
227
|
0,
|
|
196
228
|
1,
|
|
197
229
|
0,
|
|
198
230
|
modulatorSources.noteOnVelocity
|
|
199
231
|
),
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
232
|
+
0x0,
|
|
233
|
+
generatorTypes.initialAttenuation,
|
|
234
|
+
DEFAULT_ATTENUATION_MOD_AMOUNT,
|
|
235
|
+
0
|
|
236
|
+
),
|
|
205
237
|
|
|
206
238
|
// mod wheel to vibrato
|
|
207
|
-
new Modulator(
|
|
239
|
+
new Modulator(0x0081, 0x0, generatorTypes.vibLfoToPitch, 50, 0),
|
|
208
240
|
|
|
209
241
|
// vol to attenuation
|
|
210
|
-
new Modulator(
|
|
211
|
-
|
|
242
|
+
new Modulator(
|
|
243
|
+
getModSourceEnum(
|
|
212
244
|
DEFAULT_ATTENUATION_MOD_CURVE_TYPE,
|
|
213
245
|
0,
|
|
214
246
|
1,
|
|
215
247
|
1,
|
|
216
248
|
midiControllers.mainVolume
|
|
217
249
|
),
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
250
|
+
0x0,
|
|
251
|
+
generatorTypes.initialAttenuation,
|
|
252
|
+
DEFAULT_ATTENUATION_MOD_AMOUNT,
|
|
253
|
+
0
|
|
254
|
+
),
|
|
223
255
|
|
|
224
256
|
// channel pressure to vibrato
|
|
225
|
-
new Modulator(
|
|
257
|
+
new Modulator(0x000D, 0x0, generatorTypes.vibLfoToPitch, 50, 0),
|
|
226
258
|
|
|
227
259
|
// pitch wheel to tuning
|
|
228
|
-
new Modulator(
|
|
260
|
+
new Modulator(0x020E, 0x0010, generatorTypes.fineTune, 12700, 0),
|
|
229
261
|
|
|
230
262
|
// pan to uhh, pan
|
|
231
263
|
// amount is 500 instead of 1000, see #59
|
|
232
|
-
new Modulator(
|
|
264
|
+
new Modulator(0x028A, 0x0, generatorTypes.pan, 500, 0),
|
|
233
265
|
|
|
234
266
|
// expression to attenuation
|
|
235
|
-
new Modulator(
|
|
236
|
-
|
|
267
|
+
new Modulator(
|
|
268
|
+
getModSourceEnum(
|
|
237
269
|
DEFAULT_ATTENUATION_MOD_CURVE_TYPE,
|
|
238
270
|
0,
|
|
239
271
|
1,
|
|
240
272
|
1,
|
|
241
273
|
midiControllers.expressionController
|
|
242
274
|
),
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
275
|
+
0x0,
|
|
276
|
+
generatorTypes.initialAttenuation,
|
|
277
|
+
DEFAULT_ATTENUATION_MOD_AMOUNT,
|
|
278
|
+
0
|
|
279
|
+
),
|
|
248
280
|
|
|
249
281
|
// reverb effects to send
|
|
250
|
-
new Modulator(
|
|
282
|
+
new Modulator(0x00DB, 0x0, generatorTypes.reverbEffectsSend, 200, 0),
|
|
251
283
|
|
|
252
284
|
// chorus effects to send
|
|
253
|
-
new Modulator(
|
|
285
|
+
new Modulator(0x00DD, 0x0, generatorTypes.chorusEffectsSend, 200, 0)
|
|
254
286
|
];
|
|
255
287
|
|
|
256
288
|
const customModulators = [
|
|
257
289
|
// custom modulators heck yeah
|
|
258
290
|
// poly pressure to vibrato
|
|
259
|
-
new Modulator(
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
291
|
+
new Modulator(
|
|
292
|
+
getModSourceEnum(modulatorCurveTypes.linear, 0, 0, 0, modulatorSources.polyPressure),
|
|
293
|
+
0x0,
|
|
294
|
+
generatorTypes.vibLfoToPitch,
|
|
295
|
+
50,
|
|
296
|
+
0
|
|
297
|
+
),
|
|
266
298
|
|
|
267
299
|
// cc 92 (tremolo) to modLFO volume
|
|
268
|
-
new Modulator(
|
|
269
|
-
|
|
300
|
+
new Modulator(
|
|
301
|
+
getModSourceEnum(
|
|
270
302
|
modulatorCurveTypes.linear,
|
|
271
303
|
0,
|
|
272
304
|
0,
|
|
273
305
|
1,
|
|
274
306
|
midiControllers.tremoloDepth
|
|
275
307
|
), /*linear forward unipolar cc 92 */
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
308
|
+
0x0, // no controller
|
|
309
|
+
generatorTypes.modLfoToVolume,
|
|
310
|
+
24,
|
|
311
|
+
0
|
|
312
|
+
),
|
|
281
313
|
|
|
282
314
|
// cc 73 (attack time) to volEnv attack
|
|
283
|
-
new Modulator(
|
|
284
|
-
|
|
315
|
+
new Modulator(
|
|
316
|
+
getModSourceEnum(
|
|
285
317
|
modulatorCurveTypes.convex,
|
|
286
318
|
1,
|
|
287
319
|
0,
|
|
288
320
|
1,
|
|
289
321
|
midiControllers.attackTime
|
|
290
322
|
), // linear forward bipolar cc 72
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
323
|
+
0x0, // no controller
|
|
324
|
+
generatorTypes.attackVolEnv,
|
|
325
|
+
6000,
|
|
326
|
+
0
|
|
327
|
+
),
|
|
296
328
|
|
|
297
329
|
// cc 72 (release time) to volEnv release
|
|
298
|
-
new Modulator(
|
|
299
|
-
|
|
330
|
+
new Modulator(
|
|
331
|
+
getModSourceEnum(
|
|
300
332
|
modulatorCurveTypes.linear,
|
|
301
333
|
1,
|
|
302
334
|
0,
|
|
303
335
|
1,
|
|
304
336
|
midiControllers.releaseTime
|
|
305
337
|
), // linear forward bipolar cc 72
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
338
|
+
0x0, // no controller
|
|
339
|
+
generatorTypes.releaseVolEnv,
|
|
340
|
+
3600,
|
|
341
|
+
0
|
|
342
|
+
),
|
|
311
343
|
|
|
312
344
|
// cc 74 (brightness) to filterFc
|
|
313
|
-
new Modulator(
|
|
314
|
-
|
|
345
|
+
new Modulator(
|
|
346
|
+
getModSourceEnum(
|
|
315
347
|
modulatorCurveTypes.linear,
|
|
316
348
|
1,
|
|
317
349
|
0,
|
|
318
350
|
1,
|
|
319
351
|
midiControllers.brightness
|
|
320
352
|
), // linear forwards bipolar cc 74
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
353
|
+
0x0, // no controller
|
|
354
|
+
generatorTypes.initialFilterFc,
|
|
355
|
+
6000,
|
|
356
|
+
0
|
|
357
|
+
),
|
|
326
358
|
|
|
327
359
|
// cc 71 (filter Q) to filter Q
|
|
328
|
-
new Modulator(
|
|
329
|
-
|
|
360
|
+
new Modulator(
|
|
361
|
+
getModSourceEnum(
|
|
330
362
|
modulatorCurveTypes.linear,
|
|
331
363
|
1,
|
|
332
364
|
0,
|
|
333
365
|
1,
|
|
334
366
|
midiControllers.filterResonance
|
|
335
367
|
), // linear forwards bipolar cc 74
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
368
|
+
0x0, // no controller
|
|
369
|
+
generatorTypes.initialFilterQ,
|
|
370
|
+
250,
|
|
371
|
+
0
|
|
372
|
+
)
|
|
341
373
|
];
|
|
342
374
|
|
|
343
375
|
export const defaultModulators = soundFontModulators.concat(customModulators);
|
|
@@ -384,12 +384,12 @@ export function getSF2ModulatorFromArticulator(
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
// return the modulator!
|
|
387
|
-
return new Modulator(
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
387
|
+
return new Modulator(
|
|
388
|
+
sourceEnumFinal,
|
|
389
|
+
secSourceEnumFinal,
|
|
390
|
+
destinationGenerator,
|
|
391
|
+
newValue,
|
|
392
|
+
0x0
|
|
393
|
+
);
|
|
394
394
|
|
|
395
395
|
}
|
|
@@ -28,34 +28,34 @@ export const DLSSources = {
|
|
|
28
28
|
coarseTune: 0x102
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
export const DEFAULT_DLS_REVERB = new Modulator(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
export const DEFAULT_DLS_REVERB = new Modulator(
|
|
32
|
+
0x00DB,
|
|
33
|
+
0x0,
|
|
34
|
+
generatorTypes.reverbEffectsSend,
|
|
35
|
+
1000,
|
|
36
|
+
0
|
|
37
|
+
);
|
|
38
38
|
|
|
39
|
-
export const DEFAULT_DLS_CHORUS = new Modulator(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
export const DEFAULT_DLS_CHORUS = new Modulator(
|
|
40
|
+
0x00DD,
|
|
41
|
+
0x0,
|
|
42
|
+
generatorTypes.chorusEffectsSend,
|
|
43
|
+
1000,
|
|
44
|
+
0
|
|
45
|
+
);
|
|
46
46
|
|
|
47
|
-
export const DLS_1_NO_VIBRATO_MOD = new Modulator(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
47
|
+
export const DLS_1_NO_VIBRATO_MOD = new Modulator(
|
|
48
|
+
0x0081,
|
|
49
|
+
0x0,
|
|
50
|
+
generatorTypes.vibLfoToPitch,
|
|
51
|
+
0,
|
|
52
|
+
0
|
|
53
|
+
);
|
|
54
54
|
|
|
55
|
-
export const DLS_1_NO_VIBRATO_PRESSURE = new Modulator(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
export const DLS_1_NO_VIBRATO_PRESSURE = new Modulator(
|
|
56
|
+
0x000D,
|
|
57
|
+
0x0,
|
|
58
|
+
generatorTypes.vibLfoToPitch,
|
|
59
|
+
0,
|
|
60
|
+
0
|
|
61
|
+
);
|