spessasynth_lib 3.16.5 → 3.20.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.
Files changed (87) hide show
  1. package/@types/index.d.ts +5 -4
  2. package/@types/midi_parser/basic_midi.d.ts +125 -0
  3. package/@types/midi_parser/midi_builder.d.ts +69 -0
  4. package/@types/midi_parser/midi_data.d.ts +2 -2
  5. package/@types/midi_parser/midi_editor.d.ts +4 -4
  6. package/@types/midi_parser/midi_loader.d.ts +3 -100
  7. package/@types/midi_parser/midi_writer.d.ts +2 -2
  8. package/@types/midi_parser/rmidi_writer.d.ts +3 -3
  9. package/@types/midi_parser/used_keys_loaded.d.ts +2 -2
  10. package/@types/sequencer/sequencer.d.ts +1 -1
  11. package/@types/soundfont/basic_soundfont/basic_sample.d.ts +2 -2
  12. package/@types/soundfont/basic_soundfont/basic_zone.d.ts +12 -12
  13. package/@types/soundfont/basic_soundfont/basic_zones.d.ts +4 -0
  14. package/@types/soundfont/basic_soundfont/riff_chunk.d.ts +6 -0
  15. package/@types/soundfont/basic_soundfont/write_sf2/soundfont_trimmer.d.ts +2 -2
  16. package/@types/soundfont/dls/articulator_converter.d.ts +10 -0
  17. package/@types/soundfont/dls/dls_destinations.d.ts +29 -0
  18. package/@types/soundfont/dls/dls_preset.d.ts +13 -0
  19. package/@types/soundfont/dls/dls_sample.d.ts +18 -0
  20. package/@types/soundfont/dls/dls_soundfont.d.ts +31 -0
  21. package/@types/soundfont/dls/dls_sources.d.ts +22 -0
  22. package/@types/soundfont/dls/dls_zone.d.ts +22 -0
  23. package/@types/soundfont/dls/read_articulation.d.ts +12 -0
  24. package/@types/soundfont/dls/read_instrument.d.ts +5 -0
  25. package/@types/soundfont/dls/read_instrument_list.d.ts +5 -0
  26. package/@types/soundfont/dls/read_lart.d.ts +7 -0
  27. package/@types/soundfont/dls/read_region.d.ts +7 -0
  28. package/@types/soundfont/dls/read_samples.d.ts +5 -0
  29. package/@types/soundfont/load_soundfont.d.ts +6 -0
  30. package/@types/soundfont/read_sf2/generators.d.ts +18 -5
  31. package/@types/soundfont/read_sf2/modulators.d.ts +1 -0
  32. package/@types/soundfont/soundfont.d.ts +2 -1
  33. package/@types/synthetizer/synthetizer.d.ts +2 -2
  34. package/@types/utils/byte_functions/little_endian.d.ts +1 -1
  35. package/README.md +27 -15
  36. package/index.js +6 -4
  37. package/midi_parser/basic_midi.js +146 -0
  38. package/midi_parser/midi_builder.js +281 -0
  39. package/midi_parser/midi_data.js +1 -1
  40. package/midi_parser/midi_editor.js +2 -2
  41. package/midi_parser/midi_loader.js +38 -56
  42. package/midi_parser/midi_writer.js +1 -1
  43. package/midi_parser/rmidi_writer.js +2 -2
  44. package/midi_parser/used_keys_loaded.js +1 -1
  45. package/package.json +1 -1
  46. package/sequencer/sequencer.js +1 -1
  47. package/sequencer/worklet_sequencer/song_control.js +3 -3
  48. package/sequencer/worklet_sequencer/worklet_sequencer.js +1 -1
  49. package/soundfont/README.md +6 -2
  50. package/soundfont/basic_soundfont/basic_sample.js +3 -3
  51. package/soundfont/basic_soundfont/basic_zone.js +28 -28
  52. package/soundfont/basic_soundfont/basic_zones.js +15 -19
  53. package/soundfont/basic_soundfont/riff_chunk.js +20 -4
  54. package/soundfont/basic_soundfont/write_sf2/soundfont_trimmer.js +1 -1
  55. package/soundfont/dls/articulator_converter.js +311 -0
  56. package/soundfont/dls/dls_destinations.js +38 -0
  57. package/soundfont/dls/dls_preset.js +32 -0
  58. package/soundfont/dls/dls_sample.js +58 -0
  59. package/soundfont/dls/dls_soundfont.js +150 -0
  60. package/soundfont/dls/dls_sources.js +26 -0
  61. package/soundfont/dls/dls_zone.js +75 -0
  62. package/soundfont/dls/read_articulation.js +327 -0
  63. package/soundfont/dls/read_instrument.js +100 -0
  64. package/soundfont/dls/read_instrument_list.js +17 -0
  65. package/soundfont/dls/read_lart.js +35 -0
  66. package/soundfont/dls/read_region.js +129 -0
  67. package/soundfont/dls/read_samples.js +174 -0
  68. package/soundfont/load_soundfont.js +21 -0
  69. package/soundfont/read_sf2/generators.js +41 -6
  70. package/soundfont/read_sf2/instruments.js +2 -2
  71. package/soundfont/read_sf2/modulators.js +8 -8
  72. package/soundfont/read_sf2/presets.js +7 -7
  73. package/soundfont/read_sf2/samples.js +8 -8
  74. package/soundfont/read_sf2/zones.js +5 -5
  75. package/soundfont/soundfont.js +8 -3
  76. package/synthetizer/synthetizer.js +1 -1
  77. package/synthetizer/worklet_processor.min.js +10 -7
  78. package/synthetizer/worklet_system/main_processor.js +1 -2
  79. package/synthetizer/worklet_system/worklet_methods/program_control.js +6 -3
  80. package/synthetizer/worklet_system/worklet_methods/worklet_soundfont_manager/worklet_soundfont_manager.js +5 -5
  81. package/utils/buffer_to_wav.js +5 -26
  82. package/utils/byte_functions/little_endian.js +1 -1
  83. /package/@types/{midi_handler → external_midi}/midi_handler.d.ts +0 -0
  84. /package/@types/{midi_handler → external_midi}/web_midi_link.d.ts +0 -0
  85. /package/{midi_handler → external_midi}/README.md +0 -0
  86. /package/{midi_handler → external_midi}/midi_handler.js +0 -0
  87. /package/{midi_handler → external_midi}/web_midi_link.js +0 -0
@@ -0,0 +1,22 @@
1
+ export class DLSZone extends BasicInstrumentZone {
2
+ /**
3
+ * @param keyRange {SoundFontRange}
4
+ * @param velRange {SoundFontRange}
5
+ */
6
+ constructor(keyRange: SoundFontRange, velRange: SoundFontRange);
7
+ keyRange: SoundFontRange;
8
+ velRange: SoundFontRange;
9
+ /**
10
+ * @param attenuationCb {number} with EMU correction
11
+ * @param loopingMode {number} the sfont one
12
+ * @param loop {{start: number, end: number}}
13
+ * @param sampleKey {number}
14
+ * @param sample {BasicSample}
15
+ * @param sampleID {number}
16
+ */
17
+ setWavesample(attenuationCb: number, loopingMode: number, loop: {
18
+ start: number;
19
+ end: number;
20
+ }, sampleKey: number, sample: BasicSample, sampleID: number): void;
21
+ }
22
+ import { BasicInstrumentZone } from '../basic_soundfont/basic_zones.js';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Reads the articulator chunk
3
+ * @param chunk {RiffChunk}
4
+ * @param disableVibrato {boolean} it seems that dls 1 does not have vibrato lfo, so we shall disable it
5
+ * @returns {{modulators: Modulator[], generators: Generator[]}}
6
+ */
7
+ export function readArticulation(chunk: RiffChunk, disableVibrato: boolean): {
8
+ modulators: Modulator[];
9
+ generators: Generator[];
10
+ };
11
+ import { Modulator } from '../read_sf2/modulators.js';
12
+ import { Generator } from '../read_sf2/generators.js';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @this {DLSSoundFont}
3
+ * @param chunk {RiffChunk}
4
+ */
5
+ export function readDLSInstrument(this: DLSSoundFont, chunk: RiffChunk): void;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @this {DLSSoundFont}
3
+ * @param instrumentListChunk {RiffChunk}
4
+ */
5
+ export function readDLSInstrumentList(this: DLSSoundFont, instrumentListChunk: RiffChunk): void;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @param lartChunk {RiffChunk|undefined}
3
+ * @param lar2Chunk {RiffChunk|undefined}
4
+ * @param zone {BasicInstrumentZone}
5
+ * @this {DLSSoundFont}
6
+ */
7
+ export function readLart(this: DLSSoundFont, lartChunk: RiffChunk | undefined, lar2Chunk: RiffChunk | undefined, zone: BasicInstrumentZone): void;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @this {DLSSoundFont}
3
+ * @param chunk {RiffChunk}
4
+ * @returns {DLSZone}
5
+ */
6
+ export function readRegion(this: DLSSoundFont, chunk: RiffChunk): DLSZone;
7
+ import { DLSZone } from './dls_zone.js';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @this {DLSSoundFont}
3
+ * @param waveListChunk {RiffChunk}
4
+ */
5
+ export function readDLSSamples(this: DLSSoundFont, waveListChunk: RiffChunk): void;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Loads a soundfont file
3
+ * @param buffer {ArrayBuffer}
4
+ * @returns {BasicSoundFont}
5
+ */
6
+ export function loadSoundFont(buffer: ArrayBuffer): BasicSoundFont;
@@ -84,16 +84,29 @@ export const generatorLimits: {
84
84
  def: number;
85
85
  }[];
86
86
  export class Generator {
87
+ /**
88
+ * Constructs a new generator
89
+ * @param type {generatorTypes|number}
90
+ * @param value {number}
91
+ */
92
+ constructor(type?: generatorTypes | number, value?: number);
93
+ /**
94
+ * The generator's enum number
95
+ * @type {generatorTypes|number}
96
+ */
97
+ generatorType: generatorTypes | number;
98
+ /**
99
+ * The generator's 16-bit value
100
+ * @type {number}
101
+ */
102
+ generatorValue: number;
103
+ }
104
+ export class ReadGenerator extends Generator {
87
105
  /**
88
106
  * Creates a generator
89
107
  * @param dataArray {IndexedByteArray}
90
108
  */
91
109
  constructor(dataArray: IndexedByteArray);
92
- /**
93
- * @type {generatorTypes}
94
- **/
95
- generatorType: generatorTypes;
96
- generatorValue: number;
97
110
  }
98
111
  import { RiffChunk } from '../basic_soundfont/riff_chunk.js';
99
112
  import { IndexedByteArray } from '../../utils/indexed_array.js';
@@ -1,3 +1,4 @@
1
+ export function getModSourceEnum(curveType: any, polarity: any, direction: any, isCC: any, index: any): number;
1
2
  /**
2
3
  * Reads the modulator read
3
4
  * @param modulatorChunk {RiffChunk}
@@ -6,8 +6,9 @@ export class SoundFont2 extends BasicSoundFont {
6
6
  /**
7
7
  * Initializes a new SoundFont2 Parser and parses the given data array
8
8
  * @param arrayBuffer {ArrayBuffer}
9
+ * @param warnDeprecated {boolean}
9
10
  */
10
- constructor(arrayBuffer: ArrayBuffer);
11
+ constructor(arrayBuffer: ArrayBuffer, warnDeprecated?: boolean);
11
12
  dataArray: IndexedByteArray;
12
13
  sampleDataStartIndex: number;
13
14
  instruments: import("./read_sf2/instruments.js").Instrument[];
@@ -4,7 +4,7 @@
4
4
  */
5
5
  /**
6
6
  * @typedef {Object} StartRenderingDataConfig
7
- * @property {MIDI} parsedMIDI - the MIDI to render
7
+ * @property {BasicMIDI} parsedMIDI - the MIDI to render
8
8
  * @property {SynthesizerSnapshot} snapshot - the snapshot to apply
9
9
  * @property {boolean|undefined} oneOutput - if synth should use one output with 32 channels (2 audio channels for each midi channel). this disables chorus and reverb.
10
10
  */
@@ -290,7 +290,7 @@ export type StartRenderingDataConfig = {
290
290
  /**
291
291
  * - the MIDI to render
292
292
  */
293
- parsedMIDI: MIDI;
293
+ parsedMIDI: BasicMIDI;
294
294
  /**
295
295
  * - the snapshot to apply
296
296
  */
@@ -4,7 +4,7 @@
4
4
  * @param bytesAmount {number}
5
5
  * @returns {number}
6
6
  */
7
- export function readBytesAsUintLittleEndian(dataArray: IndexedByteArray, bytesAmount: number): number;
7
+ export function readLittleEndian(dataArray: IndexedByteArray, bytesAmount: number): number;
8
8
  /**
9
9
  * Writes a number as little endian seems to also work for negative numbers so yay?
10
10
  * @param dataArray {IndexedByteArray}
package/README.md CHANGED
@@ -36,24 +36,24 @@ document.getElementById("button").onclick = async () => {
36
36
  ### Powerful SoundFont Synthesizer
37
37
  - Suitable for both **real-time** and **offline** synthesis
38
38
  - **Excellent SoundFont support:**
39
- - **Generator Support**
40
- - **Modulator Support:** _First (to my knowledge) JavaScript SoundFont synth with that feature!_
41
- - **SoundFont3 Support:** Play compressed SoundFonts!
42
- - **Can load very large SoundFonts:** up to 4GB! _Note: Only Firefox handles this well; Chromium has a hard-coded memory limit_
43
- - **Soundfont manager:** Stack multiple soundfonts!
39
+ - **Generator Support**
40
+ - **Modulator Support:** *First (to my knowledge) JavaScript SoundFont synth with that feature!*
41
+ - **SoundFont3 Support:** Play compressed SoundFonts!
42
+ - **Experimental SF2Pack Support:** Play soundfonts compressed with BASSMIDI! (*Note: only works with vorbis compression*)
43
+ - **Can load very large SoundFonts:** up to 4GB! *Note: Only Firefox handles this well; Chromium has a hard-coded memory limit*
44
+ - **Soundfont manager:** Stack multiple soundfonts!
44
45
  - **Reverb and chorus support:** [customizable!](https://github.com/spessasus/SpessaSynth/wiki/Synthetizer-Class#effects-configuration-object)
45
46
  - **Export audio files** using [OfflineAudioContext](https://developer.mozilla.org/en-US/docs/Web/API/OfflineAudioContext)
46
47
  - **[Custom modulators for additional controllers](https://github.com/spessasus/SpessaSynth/wiki/Modulator-Class#default-modulators):** Why not?
47
48
  - **Written using AudioWorklets:**
48
- - Runs in a **separate thread** for maximum performance
49
- - Supported by all modern browsers
49
+ - Runs in a **separate thread** for maximum performance
50
+ - Supported by all modern browsers
50
51
  - **Unlimited channel count:** Your CPU is the limit!
51
52
  - **Excellent MIDI Standards Support:**
52
- - **MIDI Controller Support:** Default supported controllers [here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-controllers)
53
- - **MIDI Tuning Standard Support:** [more info here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#midi-tuning-standard)
54
- - [Full **RPN** and limited **NRPN** support](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-registered-parameters)
55
- - **MIDI Tuning Standard Support:** [more info here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#midi-tuning-standard)
56
- - Supports some [**Roland GS** and **Yamaha XG** system exclusives](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-system-exclusives)
53
+ - **MIDI Controller Support:** Default supported controllers [here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-controllers)
54
+ - **MIDI Tuning Standard Support:** [more info here](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#midi-tuning-standard)
55
+ - [Full **RPN** and limited **NRPN** support](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-registered-parameters)
56
+ - Supports some [**Roland GS** and **Yamaha XG** system exclusives](https://github.com/spessasus/SpessaSynth/wiki/MIDI-Implementation#supported-system-exclusives)
57
57
 
58
58
  - **High-performance mode:** Play Rush E! _note: may kill your browser ;)_
59
59
 
@@ -76,25 +76,37 @@ document.getElementById("button").onclick = async () => {
76
76
  - **Easy MIDI editing:** Use [helper functions](https://github.com/spessasus/SpessaSynth/wiki/Writing-MIDI-Files#modifymidi) to modify the song to your needs!
77
77
  - **Loop detection:** Automatically detects loops in MIDIs (e.g., from _Touhou Project_)
78
78
  - **First note detection:** Skip unnecessary silence at the start by jumping to the first note!
79
+ - **[Write MIDI files from scratch](https://github.com/spessasus/SpessaSynth/wiki/Creating-MIDI-Files.md)**
79
80
  - **Easy saving:** Save with just [one function!](https://github.com/spessasus/SpessaSynth/wiki/Writing-MIDI-Files#writemidifile)
80
- -
81
+
81
82
  #### Read and write [RMID files with embedded SF2 soundfonts](https://github.com/spessasus/sf2-rmidi-specification#readme)
82
83
  - **[Level 4](https://github.com/spessasus/sf2-rmidi-specification#level-4) compliance:** Reads and writes *everything!*
83
84
  - **Compression and trimming support:** Reduce a MIDI file with a 1GB soundfont to **as small as 5MB**!
85
+ - **DLS Version support:** The original legacy format with bank offset detection!
84
86
  - **Automatic bank shifting and validation:** Every soundfont *just works!*
85
87
  - **Metadata support:** Add title, artist, album name and cover and more! And of course read them too! *(In any encoding!)*
86
88
  - **Compatible with [Falcosoft Midi Player 6!](https://falcosoft.hu/softwares.html#midiplayer)**
87
89
  - **Easy saving:** [As simple as saving a MIDI file!](https://github.com/spessasus/SpessaSynth/wiki/Writing-MIDI-Files#writermidi)
88
- -
90
+
89
91
  #### Read and write SoundFont2 files
90
92
  - **Easy info access:** Just an [object of strings!](https://github.com/spessasus/SpessaSynth/wiki/SoundFont2-Class#soundfontinfo)
91
93
  - **Smart trimming:** Trim the SoundFont to only include samples used in the MIDI *(down to key and velocity!)*
92
94
  - **sf3 conversion:** Compress SoundFont2 files to SoundFont3 with variable quality!
93
95
  - **Easy saving:** Also just [one function!](https://github.com/spessasus/SpessaSynth/wiki/SoundFont2-Class#write)
94
- -
96
+
95
97
  #### Read and write SoundFont3 files
96
98
  - Same features as SoundFont2 but with now with **Ogg Vorbis compression!**
97
99
  - **Variable compression quality:** You choose between file size and quality!
98
100
  - **Compression preserving:** Avoid decompressing and recompressing uncompressed samples for minimal quality loss!
101
+
102
+ #### Read and play DLS Level 1 or 2 files
103
+ - Read DLS (DownLoadable Sounds) files as SF2 files!
104
+ - **Works like a normal soundfont:** *Saving is still [just one function!](https://github.com/spessasus/SpessaSynth/wiki/SoundFont2-Class#write)*
105
+ - Converts articulators to both **modulators** and **generators**!
106
+ - Works with both unsigned 8-bit samples and signed 16-bit samples!
107
+ - **Covers special generator cases:** *such as modLfoToPitch*!
108
+ - **Correct volume:** *looking at you, Viena and gm.sf2!*
109
+ - Support built right into the synthesizer!
110
+
99
111
  ## License
100
112
  MIT License, except for the stbvorbis_sync.js in the `externals` folder which is licensed under the Apache-2.0 license.
package/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // Import modules
2
- import { SoundFont2 } from './soundfont/soundfont.js';
2
+ import { loadSoundFont } from "./soundfont/load_soundfont.js";
3
3
  import { MIDI } from './midi_parser/midi_loader.js';
4
+ import { MIDIBuilder } from "./midi_parser/midi_builder.js";
4
5
  import { Synthetizer, VOICE_CAP, DEFAULT_PERCUSSION } from './synthetizer/synthetizer.js';
5
6
  import { Sequencer } from './sequencer/sequencer.js';
6
7
  import { IndexedByteArray } from './utils/indexed_array.js';
@@ -18,8 +19,8 @@ import {
18
19
  SpessaSynthGroup
19
20
  } from './utils/loggin.js';
20
21
  import { midiControllers, messageTypes } from './midi_parser/midi_message.js';
21
- import { MIDIDeviceHandler } from './midi_handler/midi_handler.js';
22
- import { WebMidiLinkHandler } from './midi_handler/web_midi_link.js';
22
+ import { MIDIDeviceHandler} from "./external_midi/midi_handler.js";
23
+ import { WebMidiLinkHandler} from "./external_midi/web_midi_link.js";
23
24
  import { formatTime, formatTitle, consoleColors, arrayToHexString } from './utils/other.js';
24
25
  import { readBytesAsUintBigEndian } from './utils/byte_functions/big_endian.js';
25
26
  import { NON_CC_INDEX_OFFSET } from './synthetizer/worklet_system/worklet_utilities/worklet_processor_channel.js';
@@ -38,13 +39,14 @@ export {
38
39
  VOICE_CAP,
39
40
 
40
41
  // SoundFont
41
- SoundFont2,
42
+ loadSoundFont,
42
43
  trimSoundfont,
43
44
  modulatorSources,
44
45
  encodeVorbis,
45
46
 
46
47
  // MIDI
47
48
  MIDI,
49
+ MIDIBuilder,
48
50
  IndexedByteArray,
49
51
  writeMIDIFile,
50
52
  writeRMIDI,
@@ -0,0 +1,146 @@
1
+ export class BasicMIDI
2
+ {
3
+ constructor()
4
+ {
5
+ /**
6
+ * The time division of the sequence
7
+ * @type {number}
8
+ */
9
+ this.timeDivision = 0;
10
+ /**
11
+ * The duration of the sequence, in seconds
12
+ * @type {number}
13
+ */
14
+ this.duration = 0;
15
+ /**
16
+ * The tempo changes in the sequence, ordered from last to first
17
+ * @type {{ticks: number, tempo: number}[]}
18
+ */
19
+ this.tempoChanges = [{ticks: 0, tempo: 120}];
20
+ /**
21
+ * Contains the copyright strings
22
+ * @type {string}
23
+ */
24
+ this.copyright = "";
25
+
26
+ /**
27
+ * The amount of tracks in the sequence
28
+ * @type {number}
29
+ */
30
+ this.tracksAmount = 0;
31
+
32
+ /**
33
+ * The lyrics of the sequence as binary chunks
34
+ * @type {Uint8Array[]}
35
+ */
36
+ this.lyrics = [];
37
+
38
+ /**
39
+ * First note on of the MIDI file
40
+ * @type {number}
41
+ */
42
+ this.firstNoteOn = 0;
43
+
44
+ /**
45
+ * The MIDI's key range
46
+ * @type {{min: number, max: number}}
47
+ */
48
+ this.keyRange = { min: 0, max: 127 };
49
+
50
+ /**
51
+ * The last voice (note on, off, cc change etc.) event tick
52
+ * @type {number}
53
+ */
54
+ this.lastVoiceEventTick = 0;
55
+
56
+ /**
57
+ * Midi port numbers for each track
58
+ * @type {number[]}
59
+ */
60
+ this.midiPorts = [0];
61
+
62
+ /**
63
+ * Channel offsets for each port, using the SpessaSynth method
64
+ * @type {number[]}
65
+ */
66
+ this.midiPortChannelOffsets = [0];
67
+
68
+ /**
69
+ * All channels that each track uses
70
+ * @type {Set<number>[]}
71
+ */
72
+ this.usedChannelsOnTrack = [];
73
+
74
+ /**
75
+ * The loop points (in ticks) of the sequence
76
+ * @type {{start: number, end: number}}
77
+ */
78
+ this.loop = { start: 0, end: 0 };
79
+
80
+ /**
81
+ * The sequence's name
82
+ * @type {string}
83
+ */
84
+ this.midiName = "";
85
+
86
+ /**
87
+ * The file name of the sequence, if provided in the MIDI class
88
+ * @type {string}
89
+ */
90
+ this.fileName = "";
91
+
92
+ /**
93
+ * The raw, encoded MIDI name.
94
+ * @type {Uint8Array}
95
+ */
96
+ this.rawMidiName = undefined;
97
+
98
+ /**
99
+ * The MIDI's embedded soundfont
100
+ * @type {ArrayBuffer|undefined}
101
+ */
102
+ this.embeddedSoundFont = undefined;
103
+
104
+ /**
105
+ * The MIDI file's format
106
+ * @type {number}
107
+ */
108
+ this.format = 0;
109
+
110
+ /**
111
+ * The RMID Info data if RMID, otherwise undefined
112
+ * @type {Object<string, IndexedByteArray>}
113
+ */
114
+ this.RMIDInfo = {};
115
+ /**
116
+ * The bank offset for RMIDI
117
+ * @type {number}
118
+ */
119
+ this.bankOffset = 0;
120
+
121
+ /**
122
+ * The actual track data of the MIDI file
123
+ * @type {MidiMessage[][]}
124
+ */
125
+ this.tracks = [];
126
+ }
127
+
128
+ /**
129
+ * Coverts ticks to time in seconds
130
+ * @param ticks {number}
131
+ * @returns {number}
132
+ * @protected
133
+ */
134
+ _ticksToSeconds(ticks)
135
+ {
136
+ if (ticks <= 0) {
137
+ return 0;
138
+ }
139
+
140
+ // find the last tempo change that has occured
141
+ let tempo = this.tempoChanges.find(v => v.ticks < ticks);
142
+
143
+ let timeSinceLastTempo = ticks - tempo.ticks;
144
+ return this._ticksToSeconds(ticks - timeSinceLastTempo) + (timeSinceLastTempo * 60) / (tempo.tempo * this.timeDivision);
145
+ }
146
+ }