midi-audio-player 1.0.0 → 1.0.1
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 +1 -1
- package/src/downloader.js +2 -11
- package/src/webaudiofontplayer.js +52 -44
package/package.json
CHANGED
package/src/downloader.js
CHANGED
|
@@ -7,10 +7,8 @@ import path from 'path';
|
|
|
7
7
|
* @param {string} filename - Le nom du fichier de sortie (ex: "ma_police.json")
|
|
8
8
|
*/
|
|
9
9
|
export async function downloadWebAudioFont(id, filename) {
|
|
10
|
-
// Nettoyage du nom de fichier : s'assurer qu'il finit par .json
|
|
11
10
|
const cleanFilename = filename.endsWith('.json') ? filename : `${filename}.json`;
|
|
12
11
|
|
|
13
|
-
// On définit la destination par rapport au dossier de travail actuel
|
|
14
12
|
const destPath = path.join(process.cwd(), cleanFilename);
|
|
15
13
|
const url = `https://surikov.github.io/webaudiofontdata/sound/${id}.js`;
|
|
16
14
|
|
|
@@ -25,7 +23,6 @@ export async function downloadWebAudioFont(id, filename) {
|
|
|
25
23
|
|
|
26
24
|
const rawContent = await response.text();
|
|
27
25
|
|
|
28
|
-
// Extraction de l'objet JS entre les premières '{' et les dernières '}'
|
|
29
26
|
const firstBrace = rawContent.indexOf('{');
|
|
30
27
|
const lastBrace = rawContent.lastIndexOf('}');
|
|
31
28
|
|
|
@@ -34,21 +31,15 @@ export async function downloadWebAudioFont(id, filename) {
|
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
const objectString = rawContent.substring(firstBrace, lastBrace + 1);
|
|
37
|
-
|
|
38
|
-
// Transformation de la chaîne en objet JavaScript
|
|
39
34
|
const data = new Function(`return ${objectString}`)();
|
|
40
|
-
|
|
41
|
-
// Création du dossier parent s'il n'existe pas
|
|
42
35
|
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
43
|
-
|
|
44
|
-
// Sauvegarde en format JSON
|
|
45
36
|
await fs.writeFile(destPath, JSON.stringify(data, null, 2));
|
|
46
37
|
|
|
47
38
|
console.log(`✅ Terminé ! Fichier créé : ${destPath}`);
|
|
48
|
-
return data;
|
|
39
|
+
return data;
|
|
49
40
|
|
|
50
41
|
} catch (error) {
|
|
51
42
|
console.error(`❌ Échec : ${error.message}`);
|
|
52
|
-
throw error;
|
|
43
|
+
throw error;
|
|
53
44
|
}
|
|
54
45
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
1
|
class WebAudioFontChannel {
|
|
4
2
|
|
|
5
3
|
constructor(audioContext) {
|
|
@@ -44,7 +42,7 @@ class WebAudioFontPlayer {
|
|
|
44
42
|
|
|
45
43
|
#audioCtx = null;
|
|
46
44
|
#preset = null;
|
|
47
|
-
|
|
45
|
+
|
|
48
46
|
constructor(audioCtx, preset) {
|
|
49
47
|
this.#audioCtx = audioCtx;
|
|
50
48
|
this.#preset = preset;
|
|
@@ -59,46 +57,46 @@ class WebAudioFontPlayer {
|
|
|
59
57
|
|
|
60
58
|
adjustZone(audioContext, zone) {
|
|
61
59
|
if (zone.buffer) return Promise.resolve(zone);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
audioContext.decodeAudioData(
|
|
87
|
-
uint8Array.buffer,
|
|
88
|
-
audioBuffer => {
|
|
89
|
-
zone.buffer = audioBuffer;
|
|
90
|
-
this.applyZoneParameters(zone);
|
|
91
|
-
return zone;
|
|
92
|
-
},
|
|
93
|
-
error => {
|
|
94
|
-
console.error("Erreur de décodage audio:", error);
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
);
|
|
98
|
-
} else {
|
|
99
|
-
this.applyZoneParameters(zone);
|
|
100
|
-
return zone;
|
|
60
|
+
zone.delay = 0;
|
|
61
|
+
|
|
62
|
+
if (zone.sample) {
|
|
63
|
+
const decoded = atob(zone.sample);
|
|
64
|
+
zone.buffer = audioContext.createBuffer(1, decoded.length / 2, zone.sampleRate);
|
|
65
|
+
const float32Array = zone.buffer.getChannelData(0);
|
|
66
|
+
|
|
67
|
+
for (let i = 0; i < decoded.length / 2; i++) {
|
|
68
|
+
const b1 = decoded.charCodeAt(i * 2) & 0xFF;
|
|
69
|
+
const b2 = decoded.charCodeAt(i * 2 + 1) & 0xFF;
|
|
70
|
+
let n = (b2 << 8) | b1;
|
|
71
|
+
if (n >= 32768) n -= 65536;
|
|
72
|
+
float32Array[i] = n / 32768.0;
|
|
73
|
+
}
|
|
74
|
+
this.applyZoneParameters(zone);
|
|
75
|
+
return zone;
|
|
76
|
+
|
|
77
|
+
} else if (zone.file) {
|
|
78
|
+
const decoded = atob(zone.file);
|
|
79
|
+
const uint8Array = new Uint8Array(decoded.length);
|
|
80
|
+
for (let i = 0; i < decoded.length; i++) {
|
|
81
|
+
uint8Array[i] = decoded.charCodeAt(i);
|
|
101
82
|
}
|
|
83
|
+
|
|
84
|
+
audioContext.decodeAudioData(
|
|
85
|
+
uint8Array.buffer,
|
|
86
|
+
audioBuffer => {
|
|
87
|
+
zone.buffer = audioBuffer;
|
|
88
|
+
this.applyZoneParameters(zone);
|
|
89
|
+
return zone;
|
|
90
|
+
},
|
|
91
|
+
error => {
|
|
92
|
+
console.error("Erreur de décodage audio:", error);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
} else {
|
|
97
|
+
this.applyZoneParameters(zone);
|
|
98
|
+
return zone;
|
|
99
|
+
}
|
|
102
100
|
};
|
|
103
101
|
|
|
104
102
|
applyZoneParameters = (zone) => {
|
|
@@ -193,6 +191,9 @@ class WebAudioFontPlayer {
|
|
|
193
191
|
envelope.gain.linearRampToValueAtTime(this.noZeroVolume(0), when + duration + this.afterTime);
|
|
194
192
|
}
|
|
195
193
|
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
196
197
|
findEnvelope(audioContext, target) {
|
|
197
198
|
let envelope = this.envelopes.find(e =>
|
|
198
199
|
e.target === target && audioContext.currentTime > e.when + e.duration + 0.001
|
|
@@ -200,17 +201,24 @@ class WebAudioFontPlayer {
|
|
|
200
201
|
|
|
201
202
|
if (envelope) {
|
|
202
203
|
if (envelope.audioBufferSourceNode) {
|
|
203
|
-
try {
|
|
204
|
+
try {
|
|
205
|
+
envelope.audioBufferSourceNode.stop(0);
|
|
206
|
+
envelope.audioBufferSourceNode.disconnect();
|
|
207
|
+
} catch (e) { }
|
|
204
208
|
envelope.audioBufferSourceNode = null;
|
|
205
209
|
}
|
|
206
210
|
} else {
|
|
207
211
|
envelope = audioContext.createGain();
|
|
212
|
+
|
|
213
|
+
envelope.gain.value = 0;
|
|
214
|
+
|
|
208
215
|
envelope.target = target;
|
|
209
216
|
envelope.connect(target);
|
|
217
|
+
|
|
210
218
|
envelope.cancel = () => {
|
|
211
219
|
if (envelope.when + envelope.duration > audioContext.currentTime) {
|
|
212
220
|
envelope.gain.cancelScheduledValues(0);
|
|
213
|
-
envelope.gain.setTargetAtTime(
|
|
221
|
+
envelope.gain.setTargetAtTime(this.nearZero, audioContext.currentTime, 0.1);
|
|
214
222
|
envelope.when = audioContext.currentTime + 0.00001;
|
|
215
223
|
envelope.duration = 0;
|
|
216
224
|
}
|