spessasynth_lib 3.24.12 → 3.24.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spessasynth_lib",
3
- "version": "3.24.12",
3
+ "version": "3.24.13",
4
4
  "description": "MIDI and SoundFont2/DLS library with no compromises",
5
5
  "browser": "index.js",
6
6
  "type": "module",
@@ -106,7 +106,6 @@ export function _playTo(time, ticks = undefined)
106
106
  break;
107
107
 
108
108
  case messageTypes.noteOff:
109
- case messageTypes.keySignature:
110
109
  break;
111
110
 
112
111
  // skip pitch bend
@@ -43,11 +43,12 @@ export const DEFAULT_SYNTH_MODE = "gs";
43
43
  export class Synthetizer
44
44
  {
45
45
  /**
46
- * Creates a new instance of the SpessaSynth synthesizer
46
+ * Creates a new instance of the SpessaSynth synthesizer.
47
47
  * @param targetNode {AudioNode}
48
- * @param soundFontBuffer {ArrayBuffer} the soundfont file array buffer
49
- * @param enableEventSystem {boolean} enables the event system. Defaults to true
50
- * @param startRenderingData {StartRenderingDataConfig} if set, starts playing this immediately and restores the values
48
+ * @param soundFontBuffer {ArrayBuffer} the soundfont file array buffer.
49
+ * @param enableEventSystem {boolean} enables the event system.
50
+ * Defaults to true.
51
+ * @param startRenderingData {StartRenderingDataConfig} if set, starts playing this immediately and restores the values.
51
52
  * @param synthConfig {SynthConfig} optional configuration for the synthesizer.
52
53
  */
53
54
  constructor(targetNode,
@@ -244,7 +245,7 @@ export class Synthetizer
244
245
  }
245
246
 
246
247
  /**
247
- * The maximum number of voices allowed at once
248
+ * The maximum number of voices allowed at once.
248
249
  * @returns {number}
249
250
  */
250
251
  get voiceCap()
@@ -253,7 +254,7 @@ export class Synthetizer
253
254
  }
254
255
 
255
256
  /**
256
- * The maximum number of voices allowed at once
257
+ * The maximum number of voices allowed at once.
257
258
  * @param value {number}
258
259
  */
259
260
  set voiceCap(value)
@@ -268,7 +269,7 @@ export class Synthetizer
268
269
  }
269
270
 
270
271
  /**
271
- * For Black MIDI's - forces release time to 50 ms
272
+ * For Black MIDI's - forces release time to 50 ms.
272
273
  * @param {boolean} value
273
274
  */
274
275
  set highPerformanceMode(value)
@@ -278,7 +279,7 @@ export class Synthetizer
278
279
  }
279
280
 
280
281
  /**
281
- * @returns {number} the audioContext's current time
282
+ * @returns {number} the audioContext's current time.
282
283
  */
283
284
  get currentTime()
284
285
  {
@@ -286,7 +287,7 @@ export class Synthetizer
286
287
  }
287
288
 
288
289
  /**
289
- * @returns {number} the current number of voices playing
290
+ * @returns {number} the current number of voices playing.
290
291
  */
291
292
  get voicesAmount()
292
293
  {
@@ -294,10 +295,10 @@ export class Synthetizer
294
295
  }
295
296
 
296
297
  /**
297
- * Sets the SpessaSynth's log level
298
+ * Sets the SpessaSynth's log level.
298
299
  * @param enableInfo {boolean} - enable info (verbose)
299
300
  * @param enableWarning {boolean} - enable warnings (unrecognized messages)
300
- * @param enableGroup {boolean} - enable groups (recomended)
301
+ * @param enableGroup {boolean} - enable groups (to group a lot of logs)
301
302
  * @param enableTable {boolean} - enable table (debug message)
302
303
  */
303
304
  setLogLevel(enableInfo, enableWarning, enableGroup, enableTable)
@@ -327,6 +328,7 @@ export class Synthetizer
327
328
  * Sets the interpolation type for the synthesizer:
328
329
  * 0. - linear
329
330
  * 1. - nearest neighbor
331
+ * 2. - cubic
330
332
  * @param type {interpolationTypes}
331
333
  */
332
334
  setInterpolationType(type)
@@ -335,7 +337,7 @@ export class Synthetizer
335
337
  }
336
338
 
337
339
  /**
338
- * Handles the messages received from the worklet
340
+ * Handles the messages received from the worklet.
339
341
  * @param message {WorkletReturnMessage}
340
342
  * @private
341
343
  */
@@ -383,7 +385,7 @@ export class Synthetizer
383
385
  }
384
386
 
385
387
  /**
386
- * Gets a complete snapshot of the synthesizer, including controllers
388
+ * Gets a complete snapshot of the synthesizer, including controllers.
387
389
  * @returns {Promise<SynthesizerSnapshot>}
388
390
  */
389
391
  async getSynthesizerSnapshot()
@@ -405,8 +407,8 @@ export class Synthetizer
405
407
  }
406
408
 
407
409
  /**
408
- * Adds a new channel to the synthesizer
409
- * @param postMessage {boolean} leave at true, set to false only at initialization
410
+ * Adds a new channel to the synthesizer..
411
+ * @param postMessage {boolean} leave at true, set to false only at initialization.
410
412
  */
411
413
  addNewChannel(postMessage = true)
412
414
  {
@@ -460,7 +462,7 @@ export class Synthetizer
460
462
  }
461
463
 
462
464
  /*
463
- * Disables the GS NRPN parameters like vibrato or drum key tuning
465
+ * Disables the GS NRPN parameters like vibrato or drum key tuning.
464
466
  */
465
467
  disableGSNRPparams()
466
468
  {
@@ -470,7 +472,7 @@ export class Synthetizer
470
472
  }
471
473
 
472
474
  /**
473
- * A message for debugging
475
+ * A message for debugging.
474
476
  */
475
477
  debugMessage()
476
478
  {
@@ -484,10 +486,10 @@ export class Synthetizer
484
486
 
485
487
  /**
486
488
  * Starts playing a note
487
- * @param channel {number} usually 0-15: the channel to play the note
488
- * @param midiNote {number} 0-127 the key number of the note
489
- * @param velocity {number} 0-127 the velocity of the note (generally controls loudness)
490
- * @param enableDebugging {boolean} set to true to log technical details to console
489
+ * @param channel {number} usually 0-15: the channel to play the note.
490
+ * @param midiNote {number} 0-127 the key number of the note.
491
+ * @param velocity {number} 0-127 the velocity of the note (generally controls loudness).
492
+ * @param enableDebugging {boolean} set to true to log technical details to console.
491
493
  */
492
494
  noteOn(channel, midiNote, velocity, enableDebugging = false)
493
495
  {
@@ -499,10 +501,10 @@ export class Synthetizer
499
501
  }
500
502
 
501
503
  /**
502
- * Stops playing a note
503
- * @param channel {number} usually 0-15: the channel of the note
504
- * @param midiNote {number} 0-127 the key number of the note
505
- * @param force {boolean} instantly kills the note if true
504
+ * Stops playing a note.
505
+ * @param channel {number} usually 0-15: the channel of the note.
506
+ * @param midiNote {number} 0-127 the key number of the note.
507
+ * @param force {boolean} instantly kills the note if true.
506
508
  */
507
509
  noteOff(channel, midiNote, force = false)
508
510
  {
@@ -525,8 +527,8 @@ export class Synthetizer
525
527
  }
526
528
 
527
529
  /**
528
- * Stops all notes
529
- * @param force {boolean} if we should instantly kill the note, defaults to false
530
+ * Stops all notes.
531
+ * @param force {boolean} if we should instantly kill the note, defaults to false.
530
532
  */
531
533
  stopAll(force = false)
532
534
  {
@@ -540,10 +542,10 @@ export class Synthetizer
540
542
 
541
543
  /**
542
544
  * Changes the given controller
543
- * @param channel {number} usually 0-15: the channel to change the controller
544
- * @param controllerNumber {number} 0-127 the MIDI CC number
545
- * @param controllerValue {number} 0-127 the controller value
546
- * @param force {boolean} forces the controller change, even if it's locked or gm system is set and the cc is bank select
545
+ * @param channel {number} usually 0-15: the channel to change the controller.
546
+ * @param controllerNumber {number} 0-127 the MIDI CC number.
547
+ * @param controllerValue {number} 0-127 the controller value.
548
+ * @param force {boolean} forces the controller change message, even if it's locked or gm system is set and the cc is bank select.
547
549
  */
548
550
  controllerChange(channel, controllerNumber, controllerValue, force = false)
549
551
  {
@@ -573,9 +575,9 @@ export class Synthetizer
573
575
  }
574
576
 
575
577
  /**
576
- * Applies pressure to a given channel
577
- * @param channel {number} usually 0-15: the channel to change the controller
578
- * @param pressure {number} 0-127: the pressure to apply
578
+ * Applies pressure to a given channel.
579
+ * @param channel {number} usually 0-15: the channel to change the controller.
580
+ * @param pressure {number} 0-127: the pressure to apply.
579
581
  */
580
582
  channelPressure(channel, pressure)
581
583
  {
@@ -587,10 +589,10 @@ export class Synthetizer
587
589
  }
588
590
 
589
591
  /**
590
- * Applies pressure to a given note
591
- * @param channel {number} usually 0-15: the channel to change the controller
592
- * @param midiNote {number} 0-127: the MIDI note
593
- * @param pressure {number} 0-127: the pressure to apply
592
+ * Applies pressure to a given note.
593
+ * @param channel {number} usually 0-15: the channel to change the controller.
594
+ * @param midiNote {number} 0-127: the MIDI note.
595
+ * @param pressure {number} 0-127: the pressure to apply.
594
596
  */
595
597
  polyPressure(channel, midiNote, pressure)
596
598
  {
@@ -614,10 +616,10 @@ export class Synthetizer
614
616
  }
615
617
 
616
618
  /**
617
- * Sets the pitch of the given channel
618
- * @param channel {number} usually 0-15: the channel to change pitch
619
- * @param MSB {number} SECOND byte of the MIDI pitchWheel message
620
- * @param LSB {number} FIRST byte of the MIDI pitchWheel message
619
+ * Sets the pitch of the given channel.
620
+ * @param channel {number} usually 0-15: the channel to change pitch.
621
+ * @param MSB {number} SECOND byte of the MIDI pitchWheel message.
622
+ * @param LSB {number} FIRST byte of the MIDI pitchWheel message.
621
623
  */
622
624
  pitchWheel(channel, MSB, LSB)
623
625
  {
@@ -629,8 +631,8 @@ export class Synthetizer
629
631
  }
630
632
 
631
633
  /**
632
- * Transposes the synthetizer's pitch by given semitones amount (percussion channels don’t get affected)
633
- * @param semitones {number} the semitones to transpose by. Can be a floating point number for more precision
634
+ * Transposes the synthetizer's pitch by given semitones amount (percussion channels don’t get affected).
635
+ * @param semitones {number} the semitones to transpose by. Can be a floating point number for more precision.
634
636
  */
635
637
  transpose(semitones)
636
638
  {
@@ -638,10 +640,10 @@ export class Synthetizer
638
640
  }
639
641
 
640
642
  /**
641
- * Transposes the channel by given amount of semitones
642
- * @param channel {number} the channel number
643
- * @param semitones {number} the transposition of the channel, can be a float
644
- * @param force {boolean} defaults to false, if true transposes the channel even if it's a drum channel
643
+ * Transposes the channel by given amount of semitones.
644
+ * @param channel {number} the channel number.
645
+ * @param semitones {number} the transposition of the channel, can be a float.
646
+ * @param force {boolean} defaults to false, if true transposes the channel even if it's a drum channel.
645
647
  */
646
648
  transposeChannel(channel, semitones, force = false)
647
649
  {
@@ -653,8 +655,8 @@ export class Synthetizer
653
655
  }
654
656
 
655
657
  /**
656
- * Sets the main volume
657
- * @param volume {number} 0-1 the volume
658
+ * Sets the main volume.
659
+ * @param volume {number} 0-1 the volume.
658
660
  */
659
661
  setMainVolume(volume)
660
662
  {
@@ -662,7 +664,7 @@ export class Synthetizer
662
664
  }
663
665
 
664
666
  /**
665
- * Sets the master stereo panning
667
+ * Sets the master stereo panning.
666
668
  * @param pan {number} (-1 to 1), the pan (-1 is left, 0 is midde, 1 is right)
667
669
  */
668
670
  setMasterPan(pan)
@@ -704,8 +706,8 @@ export class Synthetizer
704
706
  }
705
707
 
706
708
  /**
707
- * Overrides velocity on a given channel
708
- * @param channel {number} usually 0-15: the channel to change
709
+ * Overrides velocity on a given channel.
710
+ * @param channel {number} usually 0-15: the channel to change.
709
711
  * @param velocity {number} 1-127, the velocity to use.
710
712
  * 0 Disables this functionality
711
713
  */
@@ -719,9 +721,9 @@ export class Synthetizer
719
721
  }
720
722
 
721
723
  /**
722
- * Causes the given midi channel to ignore controller messages for the given controller number
723
- * @param channel {number} usually 0-15: the channel to lock
724
- * @param controllerNumber {number} 0-127 MIDI CC number NOTE: -1 locks the preset
724
+ * Causes the given midi channel to ignore controller messages for the given controller number.
725
+ * @param channel {number} usually 0-15: the channel to lock.
726
+ * @param controllerNumber {number} 0-127 MIDI CC number NOTE: -1 locks the preset.
725
727
  * @param isLocked {boolean} true if locked, false if unlocked
726
728
  */
727
729
  lockController(channel, controllerNumber, isLocked)
@@ -734,9 +736,9 @@ export class Synthetizer
734
736
  }
735
737
 
736
738
  /**
737
- * Mutes or unmutes the given channel
738
- * @param channel {number} usually 0-15: the channel to lock
739
- * @param isMuted {boolean} indicates if the channel is muted
739
+ * Mutes or unmutes the given channel.
740
+ * @param channel {number} usually 0-15: the channel to lock.
741
+ * @param isMuted {boolean} indicates if the channel is muted.
740
742
  */
741
743
  muteChannel(channel, isMuted)
742
744
  {
@@ -750,10 +752,10 @@ export class Synthetizer
750
752
  /**
751
753
  * Reloads the sounfont.
752
754
  * THIS IS DEPRECATED!
753
- * USE soundfontManager INSTEAD
754
- * @param soundFontBuffer {ArrayBuffer} the new soundfont file array buffer
755
+ * USE soundfontManager instead.
756
+ * @param soundFontBuffer {ArrayBuffer} the new soundfont file array buffer.
755
757
  * @return {Promise<void>}
756
- * @deprecated Use the soundfontManager property
758
+ * @deprecated Use the soundfontManager property.
757
759
  */
758
760
  async reloadSoundFont(soundFontBuffer)
759
761
  {
@@ -762,21 +764,66 @@ export class Synthetizer
762
764
  }
763
765
 
764
766
  /**
765
- * Sends a MIDI Sysex message to the synthesizer
767
+ * Sends a MIDI Sysex message to the synthesizer.
766
768
  * @param messageData {number[]|ArrayLike|Uint8Array} the message's data
767
- * (excluding the F0 byte, but including the F7 at the end)
769
+ * (excluding the F0 byte, but including the F7 at the end).
770
+ * @param channelOffset {number} channel offset for the system exclusive message, defaults to zero.
768
771
  */
769
- systemExclusive(messageData)
772
+ systemExclusive(messageData, channelOffset = 0)
770
773
  {
771
774
  this.post({
772
775
  channelNumber: ALL_CHANNELS_OR_DIFFERENT_ACTION,
773
776
  messageType: workletMessageType.systemExclusive,
774
- messageData: Array.from(messageData)
777
+ messageData: [Array.from(messageData), channelOffset]
775
778
  });
776
779
  }
777
780
 
781
+ // noinspection JSUnusedGlobalSymbols
782
+ /**
783
+ * Tune MIDI keys of a given program using the MIDI Tuning Standard.
784
+ * @param program {number} 0 - 127 the MIDI program number to use.
785
+ * @param tunings {{sourceKey: number, targetPitch: number}[]} - the keys and their tunings.
786
+ * TargetPitch of -1 sets the tuning for this key to be tuned regularly.
787
+ */
788
+ tuneKeys(program, tunings)
789
+ {
790
+ if (tunings.length > 127)
791
+ {
792
+ throw new Error("Too many tunings. Maximum allowed is 127.");
793
+ }
794
+ const systemExclusive = [
795
+ 0x7F, // real-time
796
+ 0x10, // device id
797
+ 0x08, // MIDI Tuning
798
+ 0x02, // note change
799
+ program, // tuning program number
800
+ tunings.length // number of changes
801
+ ];
802
+ for (const tuning of tunings)
803
+ {
804
+ systemExclusive.push(tuning.sourceKey); // [kk] MIDI Key number
805
+ if (tuning.targetPitch === -1)
806
+ {
807
+ // no change
808
+ systemExclusive.push(0x7F, 0x7F, 0x7F);
809
+ }
810
+ else
811
+ {
812
+ const midiNote = Math.floor(tuning.targetPitch);
813
+ const fraction = Math.floor((tuning.targetPitch - midiNote) / 0.000061);
814
+ systemExclusive.push(
815
+ midiNote,// frequency data byte 1
816
+ (fraction >> 7) & 0x7F, // frequency data byte 2
817
+ fraction & 0x7F // frequency data byte 3
818
+ );
819
+ }
820
+ }
821
+ systemExclusive.push(0xF7);
822
+ this.systemExclusive(systemExclusive);
823
+ }
824
+
778
825
  /**
779
- * Toggles drums on a given channel
826
+ * Toggles drums on a given channel.
780
827
  * @param channel {number}
781
828
  * @param isDrum {boolean}
782
829
  */
@@ -790,9 +837,9 @@ export class Synthetizer
790
837
  }
791
838
 
792
839
  /**
793
- * sends a raw MIDI message to the synthesizer
794
- * @param message {number[]|Uint8Array} the midi message, each number is a byte
795
- * @param channelOffset {number} the channel offset of the message
840
+ * sends a raw MIDI message to the synthesizer.
841
+ * @param message {number[]|Uint8Array} the midi message, each number is a byte.
842
+ * @param channelOffset {number} the channel offset of the message.
796
843
  */
797
844
  sendMessage(message, channelOffset = 0)
798
845
  {
@@ -854,8 +901,8 @@ export class Synthetizer
854
901
  }
855
902
 
856
903
  /**
857
- * Updates the reverb processor with a new impulse response
858
- * @param buffer {AudioBuffer} the new reverb impulse response
904
+ * Updates the reverb processor with a new impulse response.
905
+ * @param buffer {AudioBuffer} the new reverb impulse response.
859
906
  */
860
907
  setReverbResponse(buffer)
861
908
  {
@@ -864,8 +911,8 @@ export class Synthetizer
864
911
  }
865
912
 
866
913
  /**
867
- * Updates the chorus processor parameters
868
- * @param config {ChorusConfig} the new chorus
914
+ * Updates the chorus processor parameters.
915
+ * @param config {ChorusConfig} the new chorus.
869
916
  */
870
917
  setChorusConfig(config)
871
918
  {
@@ -878,9 +925,9 @@ export class Synthetizer
878
925
  }
879
926
 
880
927
  /**
881
- * Changes the effects gain
882
- * @param reverbGain {number} the reverb gain, 0-1
883
- * @param chorusGain {number} the chorus gain, 0-1
928
+ * Changes the effects gain.
929
+ * @param reverbGain {number} the reverb gain, 0-1.
930
+ * @param chorusGain {number} the chorus gain, 0-1.
884
931
  */
885
932
  setEffectsGain(reverbGain, chorusGain)
886
933
  {
@@ -891,7 +938,7 @@ export class Synthetizer
891
938
  }
892
939
 
893
940
  /**
894
- * Destroys the synthesizer instance
941
+ * Destroys the synthesizer instance.
895
942
  */
896
943
  destroy()
897
944
  {
@@ -908,6 +955,7 @@ export class Synthetizer
908
955
  this._destroyed = true;
909
956
  }
910
957
 
958
+ // noinspection JSUnusedGlobalSymbols
911
959
  reverbateEverythingBecauseWhyNot()
912
960
  {
913
961
  for (let i = 0; i < this.channelsAmount; i++)