@cartesia/cartesia-js 0.0.3 → 1.0.0-alpha.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/.turbo/turbo-build.log +68 -38
- package/CHANGELOG.md +12 -0
- package/README.md +123 -16
- package/dist/chunk-3FL2SNIR.js +17 -0
- package/dist/chunk-3GBZUGUD.js +17 -0
- package/dist/chunk-4RMSIQLG.js +25 -0
- package/dist/chunk-BCQ63627.js +32 -0
- package/dist/chunk-JOHSCOLW.js +106 -0
- package/dist/chunk-LYPTISWL.js +75 -0
- package/dist/chunk-NDNN326Q.js +207 -0
- package/dist/chunk-WBK6LLXX.js +58 -0
- package/dist/chunk-WE63M7PJ.js +119 -0
- package/dist/{chunk-HNLIBHEN.mjs → chunk-WIFMLPT5.js} +31 -16
- package/dist/chunk-X7SJMF2R.js +22 -0
- package/dist/index.cjs +652 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +20 -0
- package/dist/lib/client.cjs +89 -0
- package/dist/lib/client.d.cts +11 -0
- package/dist/lib/client.d.ts +2 -0
- package/dist/lib/client.js +7 -42
- package/dist/lib/constants.cjs +42 -0
- package/dist/lib/constants.d.cts +4 -0
- package/dist/lib/constants.d.ts +2 -3
- package/dist/lib/constants.js +8 -37
- package/dist/lib/index.cjs +531 -0
- package/dist/lib/index.d.cts +16 -0
- package/dist/lib/index.d.ts +6 -2
- package/dist/lib/index.js +13 -409
- package/dist/react/index.cjs +846 -0
- package/dist/react/index.d.cts +33 -0
- package/dist/react/index.d.ts +20 -13
- package/dist/react/index.js +161 -501
- package/dist/react/utils.cjs +57 -0
- package/dist/react/utils.d.cts +7 -0
- package/dist/react/utils.d.ts +7 -0
- package/dist/react/utils.js +7 -0
- package/dist/tts/index.cjs +470 -0
- package/dist/tts/index.d.cts +17 -0
- package/dist/tts/index.d.ts +17 -0
- package/dist/tts/index.js +12 -0
- package/dist/tts/player.cjs +198 -0
- package/dist/tts/player.d.cts +43 -0
- package/dist/tts/player.d.ts +43 -0
- package/dist/tts/player.js +8 -0
- package/dist/tts/source.cjs +167 -0
- package/dist/tts/source.d.cts +53 -0
- package/dist/tts/source.d.ts +53 -0
- package/dist/tts/source.js +7 -0
- package/dist/{audio/utils.js → tts/utils.cjs} +13 -54
- package/dist/tts/utils.d.cts +67 -0
- package/dist/tts/utils.d.ts +67 -0
- package/dist/{audio/utils.mjs → tts/utils.js} +2 -6
- package/dist/tts/websocket.cjs +453 -0
- package/dist/tts/websocket.d.cts +53 -0
- package/dist/tts/websocket.d.ts +53 -0
- package/dist/tts/websocket.js +11 -0
- package/dist/types/index.cjs +18 -0
- package/dist/types/index.d.cts +55 -0
- package/dist/types/index.d.ts +50 -1
- package/dist/types/index.js +1 -18
- package/dist/voices/index.cjs +155 -0
- package/dist/voices/index.d.cts +12 -0
- package/dist/voices/index.d.ts +12 -0
- package/dist/voices/index.js +9 -0
- package/package.json +11 -7
- package/src/index.ts +4 -0
- package/src/lib/client.ts +14 -1
- package/src/lib/constants.ts +13 -3
- package/src/lib/index.ts +6 -3
- package/src/react/index.ts +167 -75
- package/src/react/utils.ts +11 -0
- package/src/tts/index.ts +17 -0
- package/src/tts/player.ts +109 -0
- package/src/tts/source.ts +98 -0
- package/src/{audio → tts}/utils.ts +19 -97
- package/src/tts/websocket.ts +210 -0
- package/src/types/index.ts +63 -0
- package/src/voices/index.ts +47 -0
- package/dist/audio/index.d.mts +0 -5
- package/dist/audio/index.d.ts +0 -5
- package/dist/audio/index.js +0 -396
- package/dist/audio/index.mjs +0 -9
- package/dist/audio/utils.d.mts +0 -5
- package/dist/audio/utils.d.ts +0 -5
- package/dist/chunk-3CYTAFLF.mjs +0 -262
- package/dist/chunk-FRIBQZPN.mjs +0 -113
- package/dist/chunk-XSFPHPPG.mjs +0 -18
- package/dist/index-DSBmfK9-.d.mts +0 -158
- package/dist/index-qwAyxV5I.d.ts +0 -158
- package/dist/lib/client.d.mts +0 -9
- package/dist/lib/client.mjs +0 -7
- package/dist/lib/constants.d.mts +0 -5
- package/dist/lib/constants.mjs +0 -10
- package/dist/lib/index.d.mts +0 -12
- package/dist/lib/index.mjs +0 -19
- package/dist/react/index.d.mts +0 -26
- package/dist/react/index.mjs +0 -130
- package/dist/types/index.d.mts +0 -6
- package/index.ts +0 -3
- package/src/audio/index.ts +0 -282
- /package/dist/{types/index.mjs → chunk-FXPGR372.js} +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var __accessCheck = (obj, member, msg) => {
|
|
30
|
+
if (!member.has(obj))
|
|
31
|
+
throw TypeError("Cannot " + msg);
|
|
32
|
+
};
|
|
33
|
+
var __privateGet = (obj, member, getter) => {
|
|
34
|
+
__accessCheck(obj, member, "read from private field");
|
|
35
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
36
|
+
};
|
|
37
|
+
var __privateAdd = (obj, member, value) => {
|
|
38
|
+
if (member.has(obj))
|
|
39
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
40
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
41
|
+
};
|
|
42
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
43
|
+
__accessCheck(obj, member, "write to private field");
|
|
44
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
45
|
+
return value;
|
|
46
|
+
};
|
|
47
|
+
var __privateMethod = (obj, member, method) => {
|
|
48
|
+
__accessCheck(obj, member, "access private method");
|
|
49
|
+
return method;
|
|
50
|
+
};
|
|
51
|
+
var __async = (__this, __arguments, generator) => {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
var fulfilled = (value) => {
|
|
54
|
+
try {
|
|
55
|
+
step(generator.next(value));
|
|
56
|
+
} catch (e) {
|
|
57
|
+
reject(e);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
var rejected = (value) => {
|
|
61
|
+
try {
|
|
62
|
+
step(generator.throw(value));
|
|
63
|
+
} catch (e) {
|
|
64
|
+
reject(e);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
68
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/tts/player.ts
|
|
73
|
+
var player_exports = {};
|
|
74
|
+
__export(player_exports, {
|
|
75
|
+
default: () => Player
|
|
76
|
+
});
|
|
77
|
+
module.exports = __toCommonJS(player_exports);
|
|
78
|
+
var import_emittery = __toESM(require("emittery"), 1);
|
|
79
|
+
|
|
80
|
+
// src/tts/utils.ts
|
|
81
|
+
var import_base64_js = __toESM(require("base64-js"), 1);
|
|
82
|
+
function playAudioBuffer(floats, context, startAt, sampleRate) {
|
|
83
|
+
const source = context.createBufferSource();
|
|
84
|
+
const buffer = context.createBuffer(1, floats.length, sampleRate);
|
|
85
|
+
buffer.getChannelData(0).set(floats);
|
|
86
|
+
source.buffer = buffer;
|
|
87
|
+
source.connect(context.destination);
|
|
88
|
+
source.start(startAt);
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
source.onended = () => {
|
|
91
|
+
resolve();
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/tts/player.ts
|
|
97
|
+
var _context, _startNextPlaybackAt, _bufferDuration, _emitter, _playBuffer, playBuffer_fn;
|
|
98
|
+
var Player = class {
|
|
99
|
+
/**
|
|
100
|
+
* Create a new Player.
|
|
101
|
+
*
|
|
102
|
+
* @param options - Options for the Player.
|
|
103
|
+
* @param options.bufferDuration - The duration of the audio buffer to play.
|
|
104
|
+
*/
|
|
105
|
+
constructor({ bufferDuration }) {
|
|
106
|
+
__privateAdd(this, _playBuffer);
|
|
107
|
+
__privateAdd(this, _context, null);
|
|
108
|
+
__privateAdd(this, _startNextPlaybackAt, 0);
|
|
109
|
+
__privateAdd(this, _bufferDuration, void 0);
|
|
110
|
+
__privateAdd(this, _emitter, new import_emittery.default());
|
|
111
|
+
__privateSet(this, _bufferDuration, bufferDuration);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Play audio from a source.
|
|
115
|
+
*
|
|
116
|
+
* @param source The source to play audio from.
|
|
117
|
+
* @returns A promise that resolves when the audio has finished playing.
|
|
118
|
+
*/
|
|
119
|
+
play(source) {
|
|
120
|
+
return __async(this, null, function* () {
|
|
121
|
+
__privateSet(this, _startNextPlaybackAt, 0);
|
|
122
|
+
__privateSet(this, _context, new AudioContext({ sampleRate: source.sampleRate }));
|
|
123
|
+
const buffer = new Float32Array(
|
|
124
|
+
source.durationToSampleCount(__privateGet(this, _bufferDuration))
|
|
125
|
+
);
|
|
126
|
+
const plays = [];
|
|
127
|
+
while (true) {
|
|
128
|
+
const read = yield source.read(buffer);
|
|
129
|
+
const playableAudio = buffer.slice(0, read);
|
|
130
|
+
plays.push(__privateMethod(this, _playBuffer, playBuffer_fn).call(this, playableAudio, source.sampleRate));
|
|
131
|
+
if (read < buffer.length) {
|
|
132
|
+
yield __privateGet(this, _emitter).emit("finish");
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
yield Promise.all(plays);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Pause the audio.
|
|
141
|
+
*
|
|
142
|
+
* @returns A promise that resolves when the audio has been paused.
|
|
143
|
+
*/
|
|
144
|
+
pause() {
|
|
145
|
+
return __async(this, null, function* () {
|
|
146
|
+
if (!__privateGet(this, _context)) {
|
|
147
|
+
throw new Error("AudioContext not initialized.");
|
|
148
|
+
}
|
|
149
|
+
yield __privateGet(this, _context).suspend();
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Resume the audio.
|
|
154
|
+
*
|
|
155
|
+
* @returns A promise that resolves when the audio has been resumed.
|
|
156
|
+
*/
|
|
157
|
+
resume() {
|
|
158
|
+
return __async(this, null, function* () {
|
|
159
|
+
if (!__privateGet(this, _context)) {
|
|
160
|
+
throw new Error("AudioContext not initialized.");
|
|
161
|
+
}
|
|
162
|
+
yield __privateGet(this, _context).resume();
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Toggle the audio.
|
|
167
|
+
*
|
|
168
|
+
* @returns A promise that resolves when the audio has been toggled.
|
|
169
|
+
*/
|
|
170
|
+
toggle() {
|
|
171
|
+
return __async(this, null, function* () {
|
|
172
|
+
if (!__privateGet(this, _context)) {
|
|
173
|
+
throw new Error("AudioContext not initialized.");
|
|
174
|
+
}
|
|
175
|
+
if (__privateGet(this, _context).state === "running") {
|
|
176
|
+
yield this.pause();
|
|
177
|
+
} else {
|
|
178
|
+
yield this.resume();
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
_context = new WeakMap();
|
|
184
|
+
_startNextPlaybackAt = new WeakMap();
|
|
185
|
+
_bufferDuration = new WeakMap();
|
|
186
|
+
_emitter = new WeakMap();
|
|
187
|
+
_playBuffer = new WeakSet();
|
|
188
|
+
playBuffer_fn = function(buf, sampleRate) {
|
|
189
|
+
return __async(this, null, function* () {
|
|
190
|
+
if (!__privateGet(this, _context)) {
|
|
191
|
+
throw new Error("AudioContext not initialized.");
|
|
192
|
+
}
|
|
193
|
+
const startAt = __privateGet(this, _startNextPlaybackAt);
|
|
194
|
+
const duration = buf.length / sampleRate;
|
|
195
|
+
__privateSet(this, _startNextPlaybackAt, duration + Math.max(__privateGet(this, _context).currentTime, __privateGet(this, _startNextPlaybackAt)));
|
|
196
|
+
yield playAudioBuffer(buf, __privateGet(this, _context), startAt, sampleRate);
|
|
197
|
+
});
|
|
198
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import Source from './source.cjs';
|
|
2
|
+
import 'emittery';
|
|
3
|
+
import '../types/index.cjs';
|
|
4
|
+
|
|
5
|
+
declare class Player {
|
|
6
|
+
#private;
|
|
7
|
+
/**
|
|
8
|
+
* Create a new Player.
|
|
9
|
+
*
|
|
10
|
+
* @param options - Options for the Player.
|
|
11
|
+
* @param options.bufferDuration - The duration of the audio buffer to play.
|
|
12
|
+
*/
|
|
13
|
+
constructor({ bufferDuration }: {
|
|
14
|
+
bufferDuration: number;
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Play audio from a source.
|
|
18
|
+
*
|
|
19
|
+
* @param source The source to play audio from.
|
|
20
|
+
* @returns A promise that resolves when the audio has finished playing.
|
|
21
|
+
*/
|
|
22
|
+
play(source: Source): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Pause the audio.
|
|
25
|
+
*
|
|
26
|
+
* @returns A promise that resolves when the audio has been paused.
|
|
27
|
+
*/
|
|
28
|
+
pause(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Resume the audio.
|
|
31
|
+
*
|
|
32
|
+
* @returns A promise that resolves when the audio has been resumed.
|
|
33
|
+
*/
|
|
34
|
+
resume(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Toggle the audio.
|
|
37
|
+
*
|
|
38
|
+
* @returns A promise that resolves when the audio has been toggled.
|
|
39
|
+
*/
|
|
40
|
+
toggle(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { Player as default };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import Source from './source.js';
|
|
2
|
+
import 'emittery';
|
|
3
|
+
import '../types/index.js';
|
|
4
|
+
|
|
5
|
+
declare class Player {
|
|
6
|
+
#private;
|
|
7
|
+
/**
|
|
8
|
+
* Create a new Player.
|
|
9
|
+
*
|
|
10
|
+
* @param options - Options for the Player.
|
|
11
|
+
* @param options.bufferDuration - The duration of the audio buffer to play.
|
|
12
|
+
*/
|
|
13
|
+
constructor({ bufferDuration }: {
|
|
14
|
+
bufferDuration: number;
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Play audio from a source.
|
|
18
|
+
*
|
|
19
|
+
* @param source The source to play audio from.
|
|
20
|
+
* @returns A promise that resolves when the audio has finished playing.
|
|
21
|
+
*/
|
|
22
|
+
play(source: Source): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Pause the audio.
|
|
25
|
+
*
|
|
26
|
+
* @returns A promise that resolves when the audio has been paused.
|
|
27
|
+
*/
|
|
28
|
+
pause(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Resume the audio.
|
|
31
|
+
*
|
|
32
|
+
* @returns A promise that resolves when the audio has been resumed.
|
|
33
|
+
*/
|
|
34
|
+
resume(): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Toggle the audio.
|
|
37
|
+
*
|
|
38
|
+
* @returns A promise that resolves when the audio has been toggled.
|
|
39
|
+
*/
|
|
40
|
+
toggle(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { Player as default };
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var __accessCheck = (obj, member, msg) => {
|
|
30
|
+
if (!member.has(obj))
|
|
31
|
+
throw TypeError("Cannot " + msg);
|
|
32
|
+
};
|
|
33
|
+
var __privateGet = (obj, member, getter) => {
|
|
34
|
+
__accessCheck(obj, member, "read from private field");
|
|
35
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
36
|
+
};
|
|
37
|
+
var __privateAdd = (obj, member, value) => {
|
|
38
|
+
if (member.has(obj))
|
|
39
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
40
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
41
|
+
};
|
|
42
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
43
|
+
__accessCheck(obj, member, "write to private field");
|
|
44
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
45
|
+
return value;
|
|
46
|
+
};
|
|
47
|
+
var __async = (__this, __arguments, generator) => {
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
var fulfilled = (value) => {
|
|
50
|
+
try {
|
|
51
|
+
step(generator.next(value));
|
|
52
|
+
} catch (e) {
|
|
53
|
+
reject(e);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var rejected = (value) => {
|
|
57
|
+
try {
|
|
58
|
+
step(generator.throw(value));
|
|
59
|
+
} catch (e) {
|
|
60
|
+
reject(e);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
64
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// src/tts/source.ts
|
|
69
|
+
var source_exports = {};
|
|
70
|
+
__export(source_exports, {
|
|
71
|
+
default: () => Source
|
|
72
|
+
});
|
|
73
|
+
module.exports = __toCommonJS(source_exports);
|
|
74
|
+
var import_emittery = __toESM(require("emittery"), 1);
|
|
75
|
+
var _emitter, _buffer, _readIndex, _closed, _sampleRate;
|
|
76
|
+
var Source = class {
|
|
77
|
+
/**
|
|
78
|
+
* Create a new Source.
|
|
79
|
+
*
|
|
80
|
+
* @param options - Options for the Source.
|
|
81
|
+
* @param options.sampleRate - The sample rate of the audio.
|
|
82
|
+
*/
|
|
83
|
+
constructor({ sampleRate }) {
|
|
84
|
+
__privateAdd(this, _emitter, new import_emittery.default());
|
|
85
|
+
__privateAdd(this, _buffer, new Float32Array());
|
|
86
|
+
__privateAdd(this, _readIndex, 0);
|
|
87
|
+
__privateAdd(this, _closed, false);
|
|
88
|
+
__privateAdd(this, _sampleRate, void 0);
|
|
89
|
+
this.on = __privateGet(this, _emitter).on.bind(__privateGet(this, _emitter));
|
|
90
|
+
this.once = __privateGet(this, _emitter).once.bind(__privateGet(this, _emitter));
|
|
91
|
+
this.events = __privateGet(this, _emitter).events.bind(__privateGet(this, _emitter));
|
|
92
|
+
this.off = __privateGet(this, _emitter).off.bind(__privateGet(this, _emitter));
|
|
93
|
+
__privateSet(this, _sampleRate, sampleRate);
|
|
94
|
+
}
|
|
95
|
+
get sampleRate() {
|
|
96
|
+
return __privateGet(this, _sampleRate);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Append audio to the buffer.
|
|
100
|
+
*
|
|
101
|
+
* @param src The audio to append.
|
|
102
|
+
*/
|
|
103
|
+
enqueue(src) {
|
|
104
|
+
return __async(this, null, function* () {
|
|
105
|
+
__privateSet(this, _buffer, new Float32Array([...__privateGet(this, _buffer), ...src]));
|
|
106
|
+
yield __privateGet(this, _emitter).emit("enqueue");
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Read audio from the buffer.
|
|
111
|
+
*
|
|
112
|
+
* @param dst The buffer to read the audio into.
|
|
113
|
+
* @returns The number of samples read. If the source is closed, this will be
|
|
114
|
+
* less than the length of the provided buffer.
|
|
115
|
+
*/
|
|
116
|
+
read(dst) {
|
|
117
|
+
return __async(this, null, function* () {
|
|
118
|
+
const targetReadIndex = __privateGet(this, _readIndex) + dst.length;
|
|
119
|
+
while (!__privateGet(this, _closed) && targetReadIndex > __privateGet(this, _buffer).length) {
|
|
120
|
+
yield __privateGet(this, _emitter).emit("wait");
|
|
121
|
+
yield Promise.race([
|
|
122
|
+
__privateGet(this, _emitter).once("enqueue"),
|
|
123
|
+
__privateGet(this, _emitter).once("close")
|
|
124
|
+
]);
|
|
125
|
+
yield __privateGet(this, _emitter).emit("read");
|
|
126
|
+
}
|
|
127
|
+
const read = Math.min(dst.length, __privateGet(this, _buffer).length - __privateGet(this, _readIndex));
|
|
128
|
+
dst.set(__privateGet(this, _buffer).slice(__privateGet(this, _readIndex), __privateGet(this, _readIndex) + read));
|
|
129
|
+
__privateSet(this, _readIndex, __privateGet(this, _readIndex) + read);
|
|
130
|
+
return read;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get the number of samples in a given duration.
|
|
135
|
+
*
|
|
136
|
+
* @param durationSecs The duration in seconds.
|
|
137
|
+
* @returns The number of samples.
|
|
138
|
+
*/
|
|
139
|
+
durationToSampleCount(durationSecs) {
|
|
140
|
+
return Math.trunc(durationSecs * __privateGet(this, _sampleRate));
|
|
141
|
+
}
|
|
142
|
+
get buffer() {
|
|
143
|
+
return __privateGet(this, _buffer);
|
|
144
|
+
}
|
|
145
|
+
get readIndex() {
|
|
146
|
+
return __privateGet(this, _readIndex);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Close the source. This signals that no more audio will be enqueued.
|
|
150
|
+
*
|
|
151
|
+
* This will emit a "close" event.
|
|
152
|
+
*
|
|
153
|
+
* @returns A promise that resolves when the source is closed.
|
|
154
|
+
*/
|
|
155
|
+
close() {
|
|
156
|
+
return __async(this, null, function* () {
|
|
157
|
+
__privateSet(this, _closed, true);
|
|
158
|
+
yield __privateGet(this, _emitter).emit("close");
|
|
159
|
+
__privateGet(this, _emitter).clearListeners();
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
_emitter = new WeakMap();
|
|
164
|
+
_buffer = new WeakMap();
|
|
165
|
+
_readIndex = new WeakMap();
|
|
166
|
+
_closed = new WeakMap();
|
|
167
|
+
_sampleRate = new WeakMap();
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as emittery from 'emittery';
|
|
2
|
+
import { SourceEventData } from '../types/index.cjs';
|
|
3
|
+
|
|
4
|
+
declare class Source {
|
|
5
|
+
#private;
|
|
6
|
+
on: <Name extends keyof SourceEventData | keyof emittery.OmnipresentEventData>(eventName: Name | readonly Name[], listener: (eventData: (SourceEventData & emittery.OmnipresentEventData)[Name]) => void | Promise<void>) => emittery.UnsubscribeFunction;
|
|
7
|
+
once: <Name extends keyof SourceEventData | keyof emittery.OmnipresentEventData>(eventName: Name | readonly Name[]) => emittery.EmitteryOncePromise<(SourceEventData & emittery.OmnipresentEventData)[Name]>;
|
|
8
|
+
events: <Name extends keyof SourceEventData>(eventName: Name | readonly Name[]) => AsyncIterableIterator<SourceEventData[Name]>;
|
|
9
|
+
off: <Name extends keyof SourceEventData | keyof emittery.OmnipresentEventData>(eventName: Name | readonly Name[], listener: (eventData: (SourceEventData & emittery.OmnipresentEventData)[Name]) => void | Promise<void>) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Create a new Source.
|
|
12
|
+
*
|
|
13
|
+
* @param options - Options for the Source.
|
|
14
|
+
* @param options.sampleRate - The sample rate of the audio.
|
|
15
|
+
*/
|
|
16
|
+
constructor({ sampleRate }: {
|
|
17
|
+
sampleRate: number;
|
|
18
|
+
});
|
|
19
|
+
get sampleRate(): number;
|
|
20
|
+
/**
|
|
21
|
+
* Append audio to the buffer.
|
|
22
|
+
*
|
|
23
|
+
* @param src The audio to append.
|
|
24
|
+
*/
|
|
25
|
+
enqueue(src: Float32Array): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Read audio from the buffer.
|
|
28
|
+
*
|
|
29
|
+
* @param dst The buffer to read the audio into.
|
|
30
|
+
* @returns The number of samples read. If the source is closed, this will be
|
|
31
|
+
* less than the length of the provided buffer.
|
|
32
|
+
*/
|
|
33
|
+
read(dst: Float32Array): Promise<number>;
|
|
34
|
+
/**
|
|
35
|
+
* Get the number of samples in a given duration.
|
|
36
|
+
*
|
|
37
|
+
* @param durationSecs The duration in seconds.
|
|
38
|
+
* @returns The number of samples.
|
|
39
|
+
*/
|
|
40
|
+
durationToSampleCount(durationSecs: number): number;
|
|
41
|
+
get buffer(): Float32Array;
|
|
42
|
+
get readIndex(): number;
|
|
43
|
+
/**
|
|
44
|
+
* Close the source. This signals that no more audio will be enqueued.
|
|
45
|
+
*
|
|
46
|
+
* This will emit a "close" event.
|
|
47
|
+
*
|
|
48
|
+
* @returns A promise that resolves when the source is closed.
|
|
49
|
+
*/
|
|
50
|
+
close(): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { Source as default };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import * as emittery from 'emittery';
|
|
2
|
+
import { SourceEventData } from '../types/index.js';
|
|
3
|
+
|
|
4
|
+
declare class Source {
|
|
5
|
+
#private;
|
|
6
|
+
on: <Name extends keyof SourceEventData | keyof emittery.OmnipresentEventData>(eventName: Name | readonly Name[], listener: (eventData: (SourceEventData & emittery.OmnipresentEventData)[Name]) => void | Promise<void>) => emittery.UnsubscribeFunction;
|
|
7
|
+
once: <Name extends keyof SourceEventData | keyof emittery.OmnipresentEventData>(eventName: Name | readonly Name[]) => emittery.EmitteryOncePromise<(SourceEventData & emittery.OmnipresentEventData)[Name]>;
|
|
8
|
+
events: <Name extends keyof SourceEventData>(eventName: Name | readonly Name[]) => AsyncIterableIterator<SourceEventData[Name]>;
|
|
9
|
+
off: <Name extends keyof SourceEventData | keyof emittery.OmnipresentEventData>(eventName: Name | readonly Name[], listener: (eventData: (SourceEventData & emittery.OmnipresentEventData)[Name]) => void | Promise<void>) => void;
|
|
10
|
+
/**
|
|
11
|
+
* Create a new Source.
|
|
12
|
+
*
|
|
13
|
+
* @param options - Options for the Source.
|
|
14
|
+
* @param options.sampleRate - The sample rate of the audio.
|
|
15
|
+
*/
|
|
16
|
+
constructor({ sampleRate }: {
|
|
17
|
+
sampleRate: number;
|
|
18
|
+
});
|
|
19
|
+
get sampleRate(): number;
|
|
20
|
+
/**
|
|
21
|
+
* Append audio to the buffer.
|
|
22
|
+
*
|
|
23
|
+
* @param src The audio to append.
|
|
24
|
+
*/
|
|
25
|
+
enqueue(src: Float32Array): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Read audio from the buffer.
|
|
28
|
+
*
|
|
29
|
+
* @param dst The buffer to read the audio into.
|
|
30
|
+
* @returns The number of samples read. If the source is closed, this will be
|
|
31
|
+
* less than the length of the provided buffer.
|
|
32
|
+
*/
|
|
33
|
+
read(dst: Float32Array): Promise<number>;
|
|
34
|
+
/**
|
|
35
|
+
* Get the number of samples in a given duration.
|
|
36
|
+
*
|
|
37
|
+
* @param durationSecs The duration in seconds.
|
|
38
|
+
* @returns The number of samples.
|
|
39
|
+
*/
|
|
40
|
+
durationToSampleCount(durationSecs: number): number;
|
|
41
|
+
get buffer(): Float32Array;
|
|
42
|
+
get readIndex(): number;
|
|
43
|
+
/**
|
|
44
|
+
* Close the source. This signals that no more audio will be enqueued.
|
|
45
|
+
*
|
|
46
|
+
* This will emit a "close" event.
|
|
47
|
+
*
|
|
48
|
+
* @returns A promise that resolves when the source is closed.
|
|
49
|
+
*/
|
|
50
|
+
close(): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { Source as default };
|
|
@@ -27,14 +27,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
));
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
|
|
30
|
-
// src/
|
|
30
|
+
// src/tts/utils.ts
|
|
31
31
|
var utils_exports = {};
|
|
32
32
|
__export(utils_exports, {
|
|
33
33
|
base64ToArray: () => base64ToArray,
|
|
34
|
-
bufferToWav: () => bufferToWav,
|
|
35
34
|
createMessageHandlerForContextId: () => createMessageHandlerForContextId,
|
|
36
35
|
filterSentinel: () => filterSentinel,
|
|
37
|
-
getBufferDuration: () => getBufferDuration,
|
|
38
36
|
getEmitteryCallbacks: () => getEmitteryCallbacks,
|
|
39
37
|
getSentinel: () => getSentinel,
|
|
40
38
|
isComplete: () => isComplete,
|
|
@@ -42,16 +40,7 @@ __export(utils_exports, {
|
|
|
42
40
|
playAudioBuffer: () => playAudioBuffer
|
|
43
41
|
});
|
|
44
42
|
module.exports = __toCommonJS(utils_exports);
|
|
45
|
-
var import_base64_js = __toESM(require("base64-js"));
|
|
46
|
-
|
|
47
|
-
// src/lib/constants.ts
|
|
48
|
-
var SAMPLE_RATE = 44100;
|
|
49
|
-
|
|
50
|
-
// src/audio/utils.ts
|
|
51
|
-
function getBufferDuration(b64) {
|
|
52
|
-
const floats = base64ToArray(b64);
|
|
53
|
-
return floats.length / SAMPLE_RATE;
|
|
54
|
-
}
|
|
43
|
+
var import_base64_js = __toESM(require("base64-js"), 1);
|
|
55
44
|
function base64ToArray(b64) {
|
|
56
45
|
return filterSentinel(b64).reduce((acc, b) => {
|
|
57
46
|
const floats = new Float32Array(import_base64_js.default.toByteArray(b).buffer);
|
|
@@ -61,20 +50,24 @@ function base64ToArray(b64) {
|
|
|
61
50
|
return newAcc;
|
|
62
51
|
}, new Float32Array(0));
|
|
63
52
|
}
|
|
64
|
-
function playAudioBuffer(
|
|
65
|
-
const startAt = maybeStartAt != null ? maybeStartAt : context.currentTime;
|
|
66
|
-
const floats = base64ToArray(b64);
|
|
53
|
+
function playAudioBuffer(floats, context, startAt, sampleRate) {
|
|
67
54
|
const source = context.createBufferSource();
|
|
68
|
-
const buffer = context.createBuffer(1, floats.length,
|
|
55
|
+
const buffer = context.createBuffer(1, floats.length, sampleRate);
|
|
69
56
|
buffer.getChannelData(0).set(floats);
|
|
70
57
|
source.buffer = buffer;
|
|
71
58
|
source.connect(context.destination);
|
|
72
59
|
source.start(startAt);
|
|
73
|
-
|
|
74
|
-
|
|
60
|
+
return new Promise((resolve) => {
|
|
61
|
+
source.onended = () => {
|
|
62
|
+
resolve();
|
|
63
|
+
};
|
|
64
|
+
});
|
|
75
65
|
}
|
|
76
66
|
function createMessageHandlerForContextId(contextId, handler) {
|
|
77
67
|
return (event) => {
|
|
68
|
+
if (typeof event.data !== "string") {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
78
71
|
const message = JSON.parse(event.data);
|
|
79
72
|
if (message.context_id !== contextId) {
|
|
80
73
|
return;
|
|
@@ -85,7 +78,7 @@ function createMessageHandlerForContextId(contextId, handler) {
|
|
|
85
78
|
} else {
|
|
86
79
|
chunk = message.data;
|
|
87
80
|
}
|
|
88
|
-
handler({ chunk, message });
|
|
81
|
+
handler({ chunk, message: event.data });
|
|
89
82
|
};
|
|
90
83
|
}
|
|
91
84
|
function getSentinel() {
|
|
@@ -110,45 +103,11 @@ function getEmitteryCallbacks(emitter) {
|
|
|
110
103
|
events: emitter.events.bind(emitter)
|
|
111
104
|
};
|
|
112
105
|
}
|
|
113
|
-
function bufferToWav(sampleRate, channelBuffers) {
|
|
114
|
-
const totalSamples = channelBuffers[0].length * channelBuffers.length;
|
|
115
|
-
const buffer = new ArrayBuffer(44 + totalSamples * 2);
|
|
116
|
-
const view = new DataView(buffer);
|
|
117
|
-
const writeString = (view2, offset2, string) => {
|
|
118
|
-
for (let i = 0; i < string.length; i++) {
|
|
119
|
-
view2.setUint8(offset2 + i, string.charCodeAt(i));
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
writeString(view, 0, "RIFF");
|
|
123
|
-
view.setUint32(4, 36 + totalSamples * 2, true);
|
|
124
|
-
writeString(view, 8, "WAVE");
|
|
125
|
-
writeString(view, 12, "fmt ");
|
|
126
|
-
view.setUint32(16, 16, true);
|
|
127
|
-
view.setUint16(20, 1, true);
|
|
128
|
-
view.setUint16(22, channelBuffers.length, true);
|
|
129
|
-
view.setUint32(24, sampleRate, true);
|
|
130
|
-
view.setUint32(28, sampleRate * 4, true);
|
|
131
|
-
view.setUint16(32, channelBuffers.length * 2, true);
|
|
132
|
-
view.setUint16(34, 16, true);
|
|
133
|
-
writeString(view, 36, "data");
|
|
134
|
-
view.setUint32(40, totalSamples * 2, true);
|
|
135
|
-
let offset = 44;
|
|
136
|
-
for (let i = 0; i < channelBuffers[0].length; i++) {
|
|
137
|
-
for (let channel = 0; channel < channelBuffers.length; channel++) {
|
|
138
|
-
const s = Math.max(-1, Math.min(1, channelBuffers[channel][i]));
|
|
139
|
-
view.setInt16(offset, s < 0 ? s * 32768 : s * 32767, true);
|
|
140
|
-
offset += 2;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return buffer;
|
|
144
|
-
}
|
|
145
106
|
// Annotate the CommonJS export names for ESM import in node:
|
|
146
107
|
0 && (module.exports = {
|
|
147
108
|
base64ToArray,
|
|
148
|
-
bufferToWav,
|
|
149
109
|
createMessageHandlerForContextId,
|
|
150
110
|
filterSentinel,
|
|
151
|
-
getBufferDuration,
|
|
152
111
|
getEmitteryCallbacks,
|
|
153
112
|
getSentinel,
|
|
154
113
|
isComplete,
|