spessasynth_lib 3.23.13 → 3.24.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.
@@ -44,6 +44,12 @@ export class MIDISequenceData
44
44
  */
45
45
  lyrics = [];
46
46
 
47
+ /**
48
+ * An array of tick positions where lyrics events occur in the sequence.
49
+ * @type {number[]}
50
+ */
51
+ lyricsTicks = [];
52
+
47
53
  /**
48
54
  * The tick position of the first note-on event in the MIDI sequence.
49
55
  * @type {number}
@@ -130,4 +136,11 @@ export class MIDISequenceData
130
136
  * @type {number}
131
137
  */
132
138
  bankOffset = 0;
139
+
140
+ /**
141
+ * If the MIDI file is a Soft Karaoke file (.kar), this flag is set to true.
142
+ * https://www.mixagesoftware.com/en/midikit/help/HTML/karaoke_formats.html
143
+ * @type {boolean}
144
+ */
145
+ isKaraokeFile = false;
133
146
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spessasynth_lib",
3
- "version": "3.23.13",
3
+ "version": "3.24.0",
4
4
  "description": "MIDI and SoundFont2/DLS library with no compromises",
5
5
  "browser": "index.js",
6
6
  "types": "@types/index.d.ts",
@@ -121,13 +121,33 @@ export function _processEvent(event, trackIndex)
121
121
  if (statusByteData.status === messageTypes.lyric)
122
122
  {
123
123
  lyricsIndex = Math.min(
124
- this.midiData.lyrics.indexOf(event.messageData) + 1,
124
+ this.midiData.lyricsTicks.indexOf(event.ticks) + 1,
125
125
  this.midiData.lyrics.length - 1
126
126
  );
127
127
  }
128
+ let sentStatus = statusByteData.status;
129
+ // if MIDI is a karaoke file, it uses the "text" event type or "lyrics" for lyrics (duh)
130
+ // why?
131
+ // because the MIDI standard is a messy pile of garbage and it's not my fault that it's like this :(
132
+ // I'm just trying to make the best out of a bad situation
133
+ // I'm sorry
134
+ // okay i should get back to work
135
+ // anyways,
136
+ // check for karaoke file and change the status byte to "lyric" if it's a karaoke file
137
+ if (this.midiData.isKaraokeFile && (
138
+ statusByteData.status === messageTypes.text ||
139
+ statusByteData.status === messageTypes.lyric
140
+ ))
141
+ {
142
+ lyricsIndex = Math.min(
143
+ this.midiData.lyricsTicks.indexOf(event.ticks) + 1,
144
+ this.midiData.lyricsTicks.length
145
+ );
146
+ sentStatus = messageTypes.lyric;
147
+ }
128
148
  this.post(
129
149
  WorkletSequencerReturnMessageType.textEvent,
130
- [event.messageData, statusByteData.status, lyricsIndex]
150
+ [event.messageData, sentStatus, lyricsIndex]
131
151
  );
132
152
  break;
133
153
 
@@ -4,62 +4,80 @@
4
4
  */
5
5
 
6
6
  /**
7
- *
8
- * @typedef {{
9
- * midiNote: number,
10
- * channel: number,
11
- * velocity: number
12
- * }} NoteOnCallback
13
- *
14
- * @typedef {{
15
- * midiNote: number,
16
- * channel: number
17
- * }} NoteOffCallback
18
- *
19
- * @typedef {{
20
- * channel: number,
21
- * isDrumChannel: boolean
22
- * }} DrumChangeCallback
23
- *
24
- * @typedef {{
25
- * channel: number,
26
- * program: number,
27
- * bank: number,
28
- * userCalled: boolean
29
- * }} ProgramChangeCallback
30
- *
31
- * @typedef {{
32
- * channel: number,
33
- * controllerNumber: number,
34
- * controllerValue: number
35
- * }} ControllerChangeCallback
36
- *
37
- * @typedef {{
38
- * channel:number,
39
- * isMuted: boolean
40
- * }} MuteChannelCallback
41
- *
42
- * @typedef {{
43
- * presetName: string,
44
- * bank: number,
45
- * program: number
46
- * }[]} PresetListChangeCallback
47
- *
48
- *
49
- * @typedef {{
50
- * channel: number,
51
- * MSB: number,
52
- * LSB: number
53
- * }} PitchWheelCallback
54
- *
55
- * @typedef {{
56
- * channel: number,
57
- * pressure: number
58
- * }} ChannelPressureCallback
59
- *
60
- * @typedef {string} SoundfontErrorCallback
61
- *
62
- *
7
+ * @typedef {Object} NoteOnCallback
8
+ * @property {number} midiNote - The MIDI note number.
9
+ * @property {number} channel - The MIDI channel number.
10
+ * @property {number} velocity - The velocity of the note.
11
+ */
12
+
13
+ /**
14
+ * @typedef {Object} NoteOffCallback
15
+ * @property {number} midiNote - The MIDI note number.
16
+ * @property {number} channel - The MIDI channel number.
17
+ */
18
+
19
+ /**
20
+ * @typedef {Object} DrumChangeCallback
21
+ * @property {number} channel - The MIDI channel number.
22
+ * @property {boolean} isDrumChannel - Indicates if the channel is a drum channel.
23
+ */
24
+
25
+ /**
26
+ * @typedef {Object} ProgramChangeCallback
27
+ * @property {number} channel - The MIDI channel number.
28
+ * @property {number} program - The program number.
29
+ * @property {number} bank - The bank number.
30
+ * @property {boolean} userCalled - Indicates if the change was user-initiated.
31
+ */
32
+
33
+ /**
34
+ * @typedef {Object} ControllerChangeCallback
35
+ * @property {number} channel - The MIDI channel number.
36
+ * @property {number} controllerNumber - The controller number.
37
+ * @property {number} controllerValue - The value of the controller.
38
+ */
39
+
40
+ /**
41
+ * @typedef {Object} MuteChannelCallback
42
+ * @property {number} channel - The MIDI channel number.
43
+ * @property {boolean} isMuted - Indicates if the channel is muted.
44
+ */
45
+
46
+ /**
47
+ * @typedef {Object} PresetListChangeCallbackSingle
48
+ * @property {string} presetName - The name of the preset.
49
+ * @property {number} bank - The bank number.
50
+ * @property {number} program - The program number.
51
+ */
52
+
53
+ /**
54
+ * @typedef {PresetListChangeCallbackSingle[]} PresetListChangeCallback - A list of preset objects.
55
+ */
56
+
57
+ /**
58
+ * @typedef {Object} SynthDisplayCallback
59
+ * @property {Uint8Array} displayData - The data to display.
60
+ * @property {SynthDisplayType} displayType - The type of display.
61
+ */
62
+
63
+ /**
64
+ * @typedef {Object} PitchWheelCallback
65
+ * @property {number} channel - The MIDI channel number.
66
+ * @property {number} MSB - The most significant byte of the pitch wheel value.
67
+ * @property {number} LSB - The least significant byte of the pitch wheel value.
68
+ */
69
+
70
+ /**
71
+ * @typedef {Object} ChannelPressureCallback
72
+ * @property {number} channel - The MIDI channel number.
73
+ * @property {number} pressure - The pressure value.
74
+ */
75
+
76
+ /**
77
+ * @typedef {Error} SoundfontErrorCallback - The error message for soundfont errors.
78
+ */
79
+
80
+ /**
63
81
  * @typedef {
64
82
  * NoteOnCallback |
65
83
  * NoteOffCallback |
@@ -71,6 +89,7 @@
71
89
  * PitchWheelCallback |
72
90
  * SoundfontErrorCallback |
73
91
  * ChannelPressureCallback |
92
+ * SynthDisplayCallback |
74
93
  * undefined
75
94
  * } EventCallbackData
76
95
  */
@@ -90,7 +109,8 @@
90
109
  * "mutechannel"|
91
110
  * "presetlistchange"|
92
111
  * "allcontrollerreset"|
93
- * "soundfonterror"} EventTypes
112
+ * "soundfonterror"|
113
+ * "synthdisplay"} EventTypes
94
114
  */
95
115
  export class EventHandler
96
116
  {
@@ -104,20 +124,21 @@ export class EventHandler
104
124
  * @type {Object<EventTypes, Object<string, function(EventCallbackData)>>}
105
125
  */
106
126
  this.events = {
107
- "noteoff": {},
108
- "noteon": {},
109
- "pitchwheel": {},
110
- "controllerchange": {},
111
- "programchange": {},
112
- "channelpressure": {},
113
- "polypressure": {},
114
- "drumchange": {},
115
- "stopall": {},
116
- "newchannel": {},
117
- "mutechannel": {},
118
- "presetlistchange": {},
119
- "allcontrollerreset": {},
120
- "soundfonterror": {}
127
+ "noteoff": {}, // called on note off message
128
+ "noteon": {}, // called on note on message
129
+ "pitchwheel": {}, // called on pitch wheel change
130
+ "controllerchange": {}, // called on controller change
131
+ "programchange": {}, // called on program change
132
+ "channelpressure": {}, // called on channel pressure message
133
+ "polypressure": {}, // called on poly pressure message
134
+ "drumchange": {}, // called when channel type changes
135
+ "stopall": {}, // called when synth receives stop all command
136
+ "newchannel": {}, // called when a new channel is created
137
+ "mutechannel": {}, // called when a channel is muted/unmuted
138
+ "presetlistchange": {}, // called when the preset list changes (soundfont gets reloaded)
139
+ "allcontrollerreset": {}, // called when all controllers are reset
140
+ "soundfonterror": {}, // called when a soundfont parsing error occurs
141
+ "synthdisplay": {} // called when there's a SysEx message to display some text
121
142
  };
122
143
 
123
144
  /**