spessasynth_lib 3.9.23 → 3.10.0

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.
@@ -81,6 +81,12 @@ class SpessaSynthProcessor extends AudioWorkletProcessor {
81
81
 
82
82
  this.transposition = 0;
83
83
 
84
+ /**
85
+ * Bank offset for things like embedded RMIDIS. Added for every program change
86
+ * @type {number}
87
+ */
88
+ this.soundfontBankOffset = 0;
89
+
84
90
  /**
85
91
  * The volume gain, set by user
86
92
  * @type {number}
@@ -179,6 +179,7 @@ export function controllerChange(channel, controllerNumber, controllerValue, for
179
179
  }
180
180
 
181
181
  /**
182
+ * @param volume {number} 0 to 1
182
183
  * @this {SpessaSynthProcessor}
183
184
  */
184
185
  export function setMIDIVolume(volume)
@@ -39,6 +39,10 @@ export function dataEntryCoarse(channel, dataValue)
39
39
  // https://cdn.roland.com/assets/media/pdf/SC-88PRO_OM.pdf
40
40
  // http://hummer.stanford.edu/sig/doc/classes/MidiOutput/rpn.html
41
41
  case dataEntryStates.NRPFine:
42
+ if(this.system !== "gs")
43
+ {
44
+ return;
45
+ }
42
46
  switch(channelObject.NRPCoarse)
43
47
  {
44
48
  default:
@@ -24,7 +24,7 @@ export function programChange(channel, programNumber, userChange=false)
24
24
  return;
25
25
  }
26
26
  // always 128 for percussion
27
- const bank = channelObject.drumChannel ? 128 : channelObject.midiControllers[midiControllers.bankSelect];
27
+ const bank = channelObject.drumChannel ? 128 : channelObject.midiControllers[midiControllers.bankSelect] - this.soundfontBankOffset;
28
28
  const preset = this.soundfont.getPreset(bank, programNumber);
29
29
  this.setPreset(channel, preset);
30
30
  this.callEvent("programchange",{
@@ -1,5 +1,6 @@
1
1
  import { arrayToHexString, consoleColors } from '../../../utils/other.js'
2
2
  import { SpessaSynthInfo, SpessaSynthWarn } from '../../../utils/loggin.js'
3
+ import { midiControllers } from '../../../midi_parser/midi_message.js'
3
4
  /**
4
5
  * Executes a system exclusive
5
6
  * @param messageData {number[]|IndexedByteArray} - the message data without f0
@@ -273,12 +274,108 @@ export function systemExclusive(messageData, channelOffset = 0)
273
274
  }
274
275
 
275
276
  // yamaha
277
+ // http://www.studio4all.de/htmle/main91.html
276
278
  case 0x43:
277
- // XG on
278
- if(messageData[2] === 0x4C && messageData[5] === 0x7E && messageData[6] === 0x00)
279
+ // XG sysex
280
+ if(messageData[2] === 0x4C)
279
281
  {
280
- SpessaSynthInfo("%cXG system on", consoleColors.info);
281
- this.system = "xg";
282
+ // XG system parameter
283
+ if(messageData[3] === 0x00 && messageData[4] === 0x00)
284
+ {
285
+ switch (messageData[5])
286
+ {
287
+ // master volume
288
+ case 0x04:
289
+ const vol = messageData[6];
290
+ this.setMIDIVolume(vol / 127);
291
+ SpessaSynthInfo(`%cXG master volume. Volume: %c${vol}`,
292
+ consoleColors.info,
293
+ consoleColors.recognized);
294
+ break;
295
+
296
+ // master transpose
297
+ case 0x06:
298
+ const transpose = messageData[6] - 64;
299
+ this.transposeAllChannels(transpose);
300
+ SpessaSynthInfo(`%cXG master transpose. Volume: %c${transpose}`,
301
+ consoleColors.info,
302
+ consoleColors.recognized);
303
+ break;
304
+
305
+ // XG on
306
+ case 0x7E:
307
+ SpessaSynthInfo("%cXG system on", consoleColors.info);
308
+ this.system = "xg";
309
+ break;
310
+ }
311
+ }
312
+ else
313
+ // XG part parameter
314
+ if(messageData[3] === 0x08)
315
+ {
316
+ if(this.system !== "xg")
317
+ {
318
+ return;
319
+ }
320
+ const channel = messageData[4] + channelOffset;
321
+ const value = messageData[6]
322
+ switch (messageData[5])
323
+ {
324
+ // bank select
325
+ case 0x01:
326
+ this.controllerChange(channel, midiControllers.bankSelect, value);
327
+ break;
328
+
329
+ // bank select lsb
330
+ case 0x02:
331
+ this.controllerChange(channel, midiControllers.lsbForControl0BankSelect, value);
332
+ break;
333
+
334
+ // program change
335
+ case 0x03:
336
+ this.programChange(channel, value);
337
+ break;
338
+
339
+ // volume
340
+ case 0x0B:
341
+ this.controllerChange(channel, midiControllers.mainVolume, value);
342
+ break;
343
+
344
+ // panpot
345
+ case 0x0E:
346
+ let pan = value;
347
+ if(pan === 0)
348
+ {
349
+ // 0 means random
350
+ pan = Math.floor(Math.random() * 127);
351
+ }
352
+ this.controllerChange(channel, midiControllers.pan, pan);
353
+ break;
354
+
355
+ // reverb
356
+ case 0x13:
357
+ this.controllerChange(channel, midiControllers.effects1Depth, value);
358
+ break;
359
+
360
+ // chorus
361
+ case 0x12:
362
+ this.controllerChange(channel, midiControllers.effects3Depth, value);
363
+ break;
364
+
365
+ default:
366
+ SpessaSynthWarn(`%cUnrecognized Yamaha XG Part Setup: %c${messageData[5].toString(16).toUpperCase()}`,
367
+ consoleColors.warn,
368
+ consoleColors.unrecognized);
369
+ }
370
+ }
371
+ else
372
+ if(this.system === "xg")
373
+ {
374
+ SpessaSynthWarn(`%cUnrecognized Yamaha XG SysEx: %c${arrayToHexString(messageData)}`,
375
+ consoleColors.warn,
376
+ consoleColors.unrecognized);
377
+ }
378
+
282
379
  }
283
380
  else
284
381
  {