spessasynth_lib 3.12.3 → 3.13.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.
@@ -1,18 +1,24 @@
1
1
  /**
2
2
  * @typedef {Object} WaveMetadata
3
- * @property {string} title - the song's title
4
- * @property {string} album - the song's album
5
- * @property {string} genre - the song's genre
3
+ * @property {string|undefined} title - the song's title
4
+ * @property {string|undefined} artist - the song's artist
5
+ * @property {string|undefined} album - the song's album
6
+ * @property {string|undefined} genre - the song's genre
6
7
  */
7
8
 
9
+ import { combineArrays } from './indexed_array.js'
10
+ import { getStringBytes } from './byte_functions/string.js'
11
+ import { writeRIFFOddSize } from '../soundfont/read/riff_chunk.js'
12
+
8
13
  /**
9
14
  *
10
15
  * @param audioBuffer {AudioBuffer}
11
16
  * @param normalizeAudio {boolean} find the max sample point and set it to 1, and scale others with it
12
17
  * @param channelOffset {number} channel offset and channel offset + 1 get saved
18
+ * @param metadata {WaveMetadata}
13
19
  * @returns {Blob}
14
20
  */
15
- export function audioBufferToWav(audioBuffer, normalizeAudio = true, channelOffset = 0)
21
+ export function audioBufferToWav(audioBuffer, normalizeAudio = true, channelOffset = 0, metadata = {})
16
22
  {
17
23
  // this code currently doesn't add any metadata
18
24
  const channel1Data = audioBuffer.getChannelData(channelOffset);
@@ -57,11 +63,52 @@ export function audioBufferToWav(audioBuffer, normalizeAudio = true, channelOffs
57
63
  // data chunk length
58
64
  header.set(new Uint8Array([dataSize & 0xff, (dataSize >> 8) & 0xff, (dataSize >> 16) & 0xff, (dataSize >> 24) & 0xff]), 40);
59
65
 
60
- const wavData = new Uint8Array(headerSize + dataSize);
61
- wavData.set(header, 0);
62
- // Interleave audio data (combine channels)
66
+ let wavData;
63
67
  let offset = headerSize;
68
+ let infoChunk = undefined;
69
+ // INFO chunk
70
+ if(Object.keys(metadata).length > 0)
71
+ {
72
+ const encoder = new TextEncoder();
73
+ const infoChunks = [
74
+ getStringBytes("INFO"),
75
+ writeRIFFOddSize("ICMT", encoder.encode("Created with SpessaSynth"))
76
+ ];
77
+ if(metadata.artist)
78
+ {
79
+ infoChunks.push(
80
+ writeRIFFOddSize("IART", encoder.encode(metadata.artist))
81
+ );
82
+ }
83
+ if(metadata.album)
84
+ {
85
+ infoChunks.push(
86
+ writeRIFFOddSize("IPRD", encoder.encode(metadata.album))
87
+ );
88
+ }
89
+ if(metadata.genre)
90
+ {
91
+ infoChunks.push(
92
+ writeRIFFOddSize("IGNR", encoder.encode(metadata.genre))
93
+ );
94
+ }
95
+ if(metadata.title)
96
+ {
97
+ infoChunks.push(
98
+ writeRIFFOddSize("INAM", encoder.encode(metadata.title))
99
+ );
100
+ }
101
+ infoChunk = writeRIFFOddSize("LIST", combineArrays(infoChunks));
102
+ wavData = new Uint8Array(headerSize + dataSize + infoChunk.length);
103
+ }
104
+ else
105
+ {
106
+ wavData = new Uint8Array(headerSize + dataSize);
107
+
108
+ }
109
+ wavData.set(header, 0);
64
110
 
111
+ // Interleave audio data (combine channels)
65
112
  let multiplier;
66
113
  if(normalizeAudio)
67
114
  {
@@ -103,6 +150,10 @@ export function audioBufferToWav(audioBuffer, normalizeAudio = true, channelOffs
103
150
  wavData[offset++] = (sample2 >> 8) & 0xff;
104
151
  }
105
152
 
153
+ if(infoChunk)
154
+ {
155
+ wavData.set(infoChunk, offset);
156
+ }
106
157
 
107
158
  return new Blob([wavData.buffer], { type: 'audio/wav' });
108
159
  }