@cartesia/cartesia-js 1.0.0-alpha.1 → 1.0.0-alpha.2
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 +36 -36
- package/CHANGELOG.md +6 -0
- package/dist/{chunk-WE63M7PJ.js → chunk-36JBKJUN.js} +2 -2
- package/dist/{chunk-NDNN326Q.js → chunk-3F5E46FT.js} +10 -5
- package/dist/{chunk-BCQ63627.js → chunk-JGP5BIUV.js} +4 -2
- package/dist/{chunk-4RMSIQLG.js → chunk-KWBSQZTY.js} +2 -2
- package/dist/{chunk-JOHSCOLW.js → chunk-PQ6CIPFW.js} +20 -6
- package/dist/{chunk-LYPTISWL.js → chunk-RO7TY474.js} +13 -7
- package/dist/{chunk-X7SJMF2R.js → chunk-T3RG6WV4.js} +3 -3
- package/dist/{chunk-WBK6LLXX.js → chunk-WVTITUXX.js} +1 -1
- package/dist/{chunk-3GBZUGUD.js → chunk-XHTDPLFR.js} +3 -1
- package/dist/index.cjs +43 -17
- package/dist/index.js +9 -9
- package/dist/lib/client.cjs +4 -2
- package/dist/lib/client.js +2 -2
- package/dist/lib/constants.cjs +4 -1
- package/dist/lib/constants.d.cts +3 -2
- package/dist/lib/constants.d.ts +3 -2
- package/dist/lib/constants.js +3 -1
- package/dist/lib/index.cjs +42 -16
- package/dist/lib/index.js +8 -8
- package/dist/react/index.cjs +59 -25
- package/dist/react/index.js +25 -17
- package/dist/tts/index.cjs +42 -16
- package/dist/tts/index.js +6 -6
- package/dist/tts/player.cjs +1 -1
- package/dist/tts/player.js +2 -2
- package/dist/tts/source.cjs +20 -6
- package/dist/tts/source.js +1 -1
- package/dist/tts/utils.cjs +13 -7
- package/dist/tts/utils.js +1 -1
- package/dist/tts/websocket.cjs +42 -16
- package/dist/tts/websocket.js +5 -5
- package/dist/voices/index.cjs +4 -2
- package/dist/voices/index.js +3 -3
- package/package.json +1 -1
- package/src/lib/client.ts +3 -2
- package/src/lib/constants.ts +2 -1
- package/src/react/index.ts +20 -8
- package/src/tts/player.ts +2 -1
- package/src/tts/source.ts +22 -5
- package/src/tts/utils.ts +15 -7
- package/src/tts/websocket.ts +6 -2
package/dist/tts/source.js
CHANGED
package/dist/tts/utils.cjs
CHANGED
|
@@ -42,13 +42,19 @@ __export(utils_exports, {
|
|
|
42
42
|
module.exports = __toCommonJS(utils_exports);
|
|
43
43
|
var import_base64_js = __toESM(require("base64-js"), 1);
|
|
44
44
|
function base64ToArray(b64) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
const byteArrays = filterSentinel(b64).map((b) => import_base64_js.default.toByteArray(b));
|
|
46
|
+
const totalLength = byteArrays.reduce(
|
|
47
|
+
(acc, arr) => acc + arr.length / Float32Array.BYTES_PER_ELEMENT,
|
|
48
|
+
0
|
|
49
|
+
);
|
|
50
|
+
const result = new Float32Array(totalLength);
|
|
51
|
+
let offset = 0;
|
|
52
|
+
for (const arr of byteArrays) {
|
|
53
|
+
const floats = new Float32Array(arr.buffer);
|
|
54
|
+
result.set(floats, offset);
|
|
55
|
+
offset += floats.length;
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
52
58
|
}
|
|
53
59
|
function playAudioBuffer(floats, context, startAt, sampleRate) {
|
|
54
60
|
const source = context.createBufferSource();
|
package/dist/tts/utils.js
CHANGED
package/dist/tts/websocket.cjs
CHANGED
|
@@ -100,7 +100,8 @@ var import_partysocket = require("partysocket");
|
|
|
100
100
|
var import_cross_fetch = __toESM(require("cross-fetch"), 1);
|
|
101
101
|
|
|
102
102
|
// src/lib/constants.ts
|
|
103
|
-
var BASE_URL = "https://api.cartesia.ai/
|
|
103
|
+
var BASE_URL = "https://api.cartesia.ai/";
|
|
104
|
+
var CARTESIA_VERSION = "2024-06-10";
|
|
104
105
|
var constructApiUrl = (baseUrl, path, protocol) => {
|
|
105
106
|
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
106
107
|
if (!protocol) {
|
|
@@ -125,7 +126,8 @@ var Client = class {
|
|
|
125
126
|
const url = constructApiUrl(this.baseUrl, path);
|
|
126
127
|
return (0, import_cross_fetch.default)(url.toString(), __spreadProps(__spreadValues({}, options), {
|
|
127
128
|
headers: __spreadValues({
|
|
128
|
-
"X-API-
|
|
129
|
+
"X-API-Key": this.apiKey,
|
|
130
|
+
"Cartesia-Version": CARTESIA_VERSION
|
|
129
131
|
}, options.headers)
|
|
130
132
|
}));
|
|
131
133
|
}
|
|
@@ -133,7 +135,7 @@ var Client = class {
|
|
|
133
135
|
|
|
134
136
|
// src/tts/source.ts
|
|
135
137
|
var import_emittery = __toESM(require("emittery"), 1);
|
|
136
|
-
var _emitter, _buffer, _readIndex, _closed, _sampleRate;
|
|
138
|
+
var _emitter, _buffer, _readIndex, _writeIndex, _closed, _sampleRate;
|
|
137
139
|
var Source = class {
|
|
138
140
|
/**
|
|
139
141
|
* Create a new Source.
|
|
@@ -143,8 +145,9 @@ var Source = class {
|
|
|
143
145
|
*/
|
|
144
146
|
constructor({ sampleRate }) {
|
|
145
147
|
__privateAdd(this, _emitter, new import_emittery.default());
|
|
146
|
-
__privateAdd(this, _buffer,
|
|
148
|
+
__privateAdd(this, _buffer, void 0);
|
|
147
149
|
__privateAdd(this, _readIndex, 0);
|
|
150
|
+
__privateAdd(this, _writeIndex, 0);
|
|
148
151
|
__privateAdd(this, _closed, false);
|
|
149
152
|
__privateAdd(this, _sampleRate, void 0);
|
|
150
153
|
this.on = __privateGet(this, _emitter).on.bind(__privateGet(this, _emitter));
|
|
@@ -152,6 +155,7 @@ var Source = class {
|
|
|
152
155
|
this.events = __privateGet(this, _emitter).events.bind(__privateGet(this, _emitter));
|
|
153
156
|
this.off = __privateGet(this, _emitter).off.bind(__privateGet(this, _emitter));
|
|
154
157
|
__privateSet(this, _sampleRate, sampleRate);
|
|
158
|
+
__privateSet(this, _buffer, new Float32Array(1024));
|
|
155
159
|
}
|
|
156
160
|
get sampleRate() {
|
|
157
161
|
return __privateGet(this, _sampleRate);
|
|
@@ -163,7 +167,18 @@ var Source = class {
|
|
|
163
167
|
*/
|
|
164
168
|
enqueue(src) {
|
|
165
169
|
return __async(this, null, function* () {
|
|
166
|
-
|
|
170
|
+
const requiredCapacity = __privateGet(this, _writeIndex) + src.length;
|
|
171
|
+
if (requiredCapacity > __privateGet(this, _buffer).length) {
|
|
172
|
+
let newCapacity = __privateGet(this, _buffer).length;
|
|
173
|
+
while (newCapacity < requiredCapacity) {
|
|
174
|
+
newCapacity *= 2;
|
|
175
|
+
}
|
|
176
|
+
const newBuffer = new Float32Array(newCapacity);
|
|
177
|
+
newBuffer.set(__privateGet(this, _buffer));
|
|
178
|
+
__privateSet(this, _buffer, newBuffer);
|
|
179
|
+
}
|
|
180
|
+
__privateGet(this, _buffer).set(src, __privateGet(this, _writeIndex));
|
|
181
|
+
__privateSet(this, _writeIndex, __privateGet(this, _writeIndex) + src.length);
|
|
167
182
|
yield __privateGet(this, _emitter).emit("enqueue");
|
|
168
183
|
});
|
|
169
184
|
}
|
|
@@ -177,7 +192,7 @@ var Source = class {
|
|
|
177
192
|
read(dst) {
|
|
178
193
|
return __async(this, null, function* () {
|
|
179
194
|
const targetReadIndex = __privateGet(this, _readIndex) + dst.length;
|
|
180
|
-
while (!__privateGet(this, _closed) && targetReadIndex > __privateGet(this,
|
|
195
|
+
while (!__privateGet(this, _closed) && targetReadIndex > __privateGet(this, _writeIndex)) {
|
|
181
196
|
yield __privateGet(this, _emitter).emit("wait");
|
|
182
197
|
yield Promise.race([
|
|
183
198
|
__privateGet(this, _emitter).once("enqueue"),
|
|
@@ -185,8 +200,8 @@ var Source = class {
|
|
|
185
200
|
]);
|
|
186
201
|
yield __privateGet(this, _emitter).emit("read");
|
|
187
202
|
}
|
|
188
|
-
const read = Math.min(dst.length, __privateGet(this,
|
|
189
|
-
dst.set(__privateGet(this, _buffer).
|
|
203
|
+
const read = Math.min(dst.length, __privateGet(this, _writeIndex) - __privateGet(this, _readIndex));
|
|
204
|
+
dst.set(__privateGet(this, _buffer).subarray(__privateGet(this, _readIndex), __privateGet(this, _readIndex) + read));
|
|
190
205
|
__privateSet(this, _readIndex, __privateGet(this, _readIndex) + read);
|
|
191
206
|
return read;
|
|
192
207
|
});
|
|
@@ -224,19 +239,26 @@ var Source = class {
|
|
|
224
239
|
_emitter = new WeakMap();
|
|
225
240
|
_buffer = new WeakMap();
|
|
226
241
|
_readIndex = new WeakMap();
|
|
242
|
+
_writeIndex = new WeakMap();
|
|
227
243
|
_closed = new WeakMap();
|
|
228
244
|
_sampleRate = new WeakMap();
|
|
229
245
|
|
|
230
246
|
// src/tts/utils.ts
|
|
231
247
|
var import_base64_js = __toESM(require("base64-js"), 1);
|
|
232
248
|
function base64ToArray(b64) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
249
|
+
const byteArrays = filterSentinel(b64).map((b) => import_base64_js.default.toByteArray(b));
|
|
250
|
+
const totalLength = byteArrays.reduce(
|
|
251
|
+
(acc, arr) => acc + arr.length / Float32Array.BYTES_PER_ELEMENT,
|
|
252
|
+
0
|
|
253
|
+
);
|
|
254
|
+
const result = new Float32Array(totalLength);
|
|
255
|
+
let offset = 0;
|
|
256
|
+
for (const arr of byteArrays) {
|
|
257
|
+
const floats = new Float32Array(arr.buffer);
|
|
258
|
+
result.set(floats, offset);
|
|
259
|
+
offset += floats.length;
|
|
260
|
+
}
|
|
261
|
+
return result;
|
|
240
262
|
}
|
|
241
263
|
function createMessageHandlerForContextId(contextId, handler) {
|
|
242
264
|
return (event) => {
|
|
@@ -386,7 +408,11 @@ var WebSocket = class extends Client {
|
|
|
386
408
|
* @throws {Error} If the WebSocket fails to connect.
|
|
387
409
|
*/
|
|
388
410
|
connect() {
|
|
389
|
-
const url = constructApiUrl(
|
|
411
|
+
const url = constructApiUrl(
|
|
412
|
+
this.baseUrl,
|
|
413
|
+
`/tts/websocket?cartesia_version=${CARTESIA_VERSION}`,
|
|
414
|
+
"ws"
|
|
415
|
+
);
|
|
390
416
|
url.searchParams.set("api_key", this.apiKey);
|
|
391
417
|
const emitter = new import_emittery2.default();
|
|
392
418
|
this.socket = new import_partysocket.WebSocket(url.toString());
|
package/dist/tts/websocket.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
WebSocket
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-3F5E46FT.js";
|
|
4
|
+
import "../chunk-PQ6CIPFW.js";
|
|
5
|
+
import "../chunk-JGP5BIUV.js";
|
|
6
|
+
import "../chunk-XHTDPLFR.js";
|
|
7
|
+
import "../chunk-RO7TY474.js";
|
|
8
8
|
import "../chunk-WIFMLPT5.js";
|
|
9
9
|
export {
|
|
10
10
|
WebSocket as default
|
package/dist/voices/index.cjs
CHANGED
|
@@ -75,7 +75,8 @@ module.exports = __toCommonJS(voices_exports);
|
|
|
75
75
|
var import_cross_fetch = __toESM(require("cross-fetch"), 1);
|
|
76
76
|
|
|
77
77
|
// src/lib/constants.ts
|
|
78
|
-
var BASE_URL = "https://api.cartesia.ai/
|
|
78
|
+
var BASE_URL = "https://api.cartesia.ai/";
|
|
79
|
+
var CARTESIA_VERSION = "2024-06-10";
|
|
79
80
|
var constructApiUrl = (baseUrl, path, protocol) => {
|
|
80
81
|
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
81
82
|
if (!protocol) {
|
|
@@ -100,7 +101,8 @@ var Client = class {
|
|
|
100
101
|
const url = constructApiUrl(this.baseUrl, path);
|
|
101
102
|
return (0, import_cross_fetch.default)(url.toString(), __spreadProps(__spreadValues({}, options), {
|
|
102
103
|
headers: __spreadValues({
|
|
103
|
-
"X-API-
|
|
104
|
+
"X-API-Key": this.apiKey,
|
|
105
|
+
"Cartesia-Version": CARTESIA_VERSION
|
|
104
106
|
}, options.headers)
|
|
105
107
|
}));
|
|
106
108
|
}
|
package/dist/voices/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Voices
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-WVTITUXX.js";
|
|
4
|
+
import "../chunk-JGP5BIUV.js";
|
|
5
|
+
import "../chunk-XHTDPLFR.js";
|
|
6
6
|
import "../chunk-WIFMLPT5.js";
|
|
7
7
|
export {
|
|
8
8
|
Voices as default
|
package/package.json
CHANGED
package/src/lib/client.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fetch from "cross-fetch";
|
|
2
2
|
import type { ClientOptions } from "../types";
|
|
3
|
-
import { BASE_URL, constructApiUrl } from "./constants";
|
|
3
|
+
import { BASE_URL, CARTESIA_VERSION, constructApiUrl } from "./constants";
|
|
4
4
|
|
|
5
5
|
export class Client {
|
|
6
6
|
apiKey: string;
|
|
@@ -22,7 +22,8 @@ export class Client {
|
|
|
22
22
|
return fetch(url.toString(), {
|
|
23
23
|
...options,
|
|
24
24
|
headers: {
|
|
25
|
-
"X-API-
|
|
25
|
+
"X-API-Key": this.apiKey,
|
|
26
|
+
"Cartesia-Version": CARTESIA_VERSION,
|
|
26
27
|
...options.headers,
|
|
27
28
|
},
|
|
28
29
|
});
|
package/src/lib/constants.ts
CHANGED
package/src/react/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UnsubscribeFunction } from "emittery";
|
|
1
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
3
|
import { Cartesia } from "../lib";
|
|
3
4
|
import Player from "../tts/player";
|
|
@@ -91,11 +92,12 @@ export function useTTS({
|
|
|
91
92
|
if (!websocketReturn.current) {
|
|
92
93
|
return;
|
|
93
94
|
}
|
|
94
|
-
websocketReturn.current.on("message", (message) => {
|
|
95
|
+
const unsubscribe = websocketReturn.current.on("message", (message) => {
|
|
95
96
|
setMessages((messages) => [...messages, JSON.parse(message)]);
|
|
96
97
|
});
|
|
97
98
|
await websocketReturn.current.source.once("close");
|
|
98
99
|
setBufferStatus("buffered");
|
|
100
|
+
unsubscribe();
|
|
99
101
|
},
|
|
100
102
|
[websocket],
|
|
101
103
|
);
|
|
@@ -121,13 +123,21 @@ export function useTTS({
|
|
|
121
123
|
if (!connection) {
|
|
122
124
|
return;
|
|
123
125
|
}
|
|
126
|
+
const unsubscribes = <UnsubscribeFunction[]>[];
|
|
127
|
+
// The await ensures that the connection is open, so we already know that we are connected.
|
|
124
128
|
setIsConnected(true);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
// If the WebSocket is the kind that automatically reconnects, we need an additional
|
|
130
|
+
// listener for the open event to update the connection status.
|
|
131
|
+
unsubscribes.push(
|
|
132
|
+
connection.on("open", () => {
|
|
133
|
+
setIsConnected(true);
|
|
134
|
+
}),
|
|
135
|
+
);
|
|
136
|
+
unsubscribes.push(
|
|
137
|
+
connection.on("close", () => {
|
|
138
|
+
setIsConnected(false);
|
|
139
|
+
}),
|
|
140
|
+
);
|
|
131
141
|
const intervalId = setInterval(() => {
|
|
132
142
|
if (baseUrl) {
|
|
133
143
|
pingServer(new URL(baseUrl).origin).then((ping) => {
|
|
@@ -144,7 +154,9 @@ export function useTTS({
|
|
|
144
154
|
}
|
|
145
155
|
}, PING_INTERVAL);
|
|
146
156
|
return () => {
|
|
147
|
-
unsubscribe
|
|
157
|
+
for (const unsubscribe of unsubscribes) {
|
|
158
|
+
unsubscribe();
|
|
159
|
+
}
|
|
148
160
|
clearInterval(intervalId);
|
|
149
161
|
websocket?.disconnect();
|
|
150
162
|
};
|
package/src/tts/player.ts
CHANGED
|
@@ -54,7 +54,8 @@ export default class Player {
|
|
|
54
54
|
// If we've reached the end of the source, then read < buffer.length.
|
|
55
55
|
// In that case, we don't want to play the entire buffer, as that
|
|
56
56
|
// will cause repeated audio.
|
|
57
|
-
|
|
57
|
+
// So we set the buffer to the correct length.
|
|
58
|
+
const playableAudio = buffer.subarray(0, read);
|
|
58
59
|
plays.push(this.#playBuffer(playableAudio, source.sampleRate));
|
|
59
60
|
|
|
60
61
|
if (read < buffer.length) {
|
package/src/tts/source.ts
CHANGED
|
@@ -3,8 +3,9 @@ import type { SourceEventData } from "../types";
|
|
|
3
3
|
|
|
4
4
|
export default class Source {
|
|
5
5
|
#emitter = new Emittery<SourceEventData>();
|
|
6
|
-
#buffer
|
|
6
|
+
#buffer: Float32Array;
|
|
7
7
|
#readIndex = 0;
|
|
8
|
+
#writeIndex = 0;
|
|
8
9
|
#closed = false;
|
|
9
10
|
#sampleRate: number;
|
|
10
11
|
|
|
@@ -21,6 +22,7 @@ export default class Source {
|
|
|
21
22
|
*/
|
|
22
23
|
constructor({ sampleRate }: { sampleRate: number }) {
|
|
23
24
|
this.#sampleRate = sampleRate;
|
|
25
|
+
this.#buffer = new Float32Array(1024); // Initial size, can be adjusted
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
get sampleRate() {
|
|
@@ -33,8 +35,23 @@ export default class Source {
|
|
|
33
35
|
* @param src The audio to append.
|
|
34
36
|
*/
|
|
35
37
|
async enqueue(src: Float32Array) {
|
|
38
|
+
const requiredCapacity = this.#writeIndex + src.length;
|
|
39
|
+
|
|
40
|
+
// Resize buffer if necessary
|
|
41
|
+
if (requiredCapacity > this.#buffer.length) {
|
|
42
|
+
let newCapacity = this.#buffer.length;
|
|
43
|
+
while (newCapacity < requiredCapacity) {
|
|
44
|
+
newCapacity *= 2; // Double the buffer size
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const newBuffer = new Float32Array(newCapacity);
|
|
48
|
+
newBuffer.set(this.#buffer);
|
|
49
|
+
this.#buffer = newBuffer;
|
|
50
|
+
}
|
|
51
|
+
|
|
36
52
|
// Append the audio to the buffer.
|
|
37
|
-
this.#buffer
|
|
53
|
+
this.#buffer.set(src, this.#writeIndex);
|
|
54
|
+
this.#writeIndex += src.length;
|
|
38
55
|
await this.#emitter.emit("enqueue");
|
|
39
56
|
}
|
|
40
57
|
|
|
@@ -49,7 +66,7 @@ export default class Source {
|
|
|
49
66
|
// Read the buffer into the provided buffer.
|
|
50
67
|
const targetReadIndex = this.#readIndex + dst.length;
|
|
51
68
|
|
|
52
|
-
while (!this.#closed && targetReadIndex > this.#
|
|
69
|
+
while (!this.#closed && targetReadIndex > this.#writeIndex) {
|
|
53
70
|
// Wait for more audio to be enqueued.
|
|
54
71
|
await this.#emitter.emit("wait");
|
|
55
72
|
await Promise.race([
|
|
@@ -59,8 +76,8 @@ export default class Source {
|
|
|
59
76
|
await this.#emitter.emit("read");
|
|
60
77
|
}
|
|
61
78
|
|
|
62
|
-
const read = Math.min(dst.length, this.#
|
|
63
|
-
dst.set(this.#buffer.
|
|
79
|
+
const read = Math.min(dst.length, this.#writeIndex - this.#readIndex);
|
|
80
|
+
dst.set(this.#buffer.subarray(this.#readIndex, this.#readIndex + read));
|
|
64
81
|
this.#readIndex += read;
|
|
65
82
|
return read;
|
|
66
83
|
}
|
package/src/tts/utils.ts
CHANGED
|
@@ -10,13 +10,21 @@ import type { Chunk, EmitteryCallbacks, Sentinel } from "../types";
|
|
|
10
10
|
* @returns The audio buffer(s) as a Float32Array.
|
|
11
11
|
*/
|
|
12
12
|
export function base64ToArray(b64: Chunk[]): Float32Array {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
const byteArrays = filterSentinel(b64).map((b) => base64.toByteArray(b));
|
|
14
|
+
const totalLength = byteArrays.reduce(
|
|
15
|
+
(acc, arr) => acc + arr.length / Float32Array.BYTES_PER_ELEMENT,
|
|
16
|
+
0,
|
|
17
|
+
);
|
|
18
|
+
const result = new Float32Array(totalLength);
|
|
19
|
+
|
|
20
|
+
let offset = 0;
|
|
21
|
+
for (const arr of byteArrays) {
|
|
22
|
+
const floats = new Float32Array(arr.buffer);
|
|
23
|
+
result.set(floats, offset);
|
|
24
|
+
offset += floats.length;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return result;
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
/**
|
package/src/tts/websocket.ts
CHANGED
|
@@ -2,7 +2,7 @@ import Emittery from "emittery";
|
|
|
2
2
|
import { humanId } from "human-id";
|
|
3
3
|
import { WebSocket as PartySocketWebSocket } from "partysocket";
|
|
4
4
|
import { Client } from "../lib/client";
|
|
5
|
-
import { constructApiUrl } from "../lib/constants";
|
|
5
|
+
import { CARTESIA_VERSION, constructApiUrl } from "../lib/constants";
|
|
6
6
|
import type {
|
|
7
7
|
ConnectionEventData,
|
|
8
8
|
EmitteryCallbacks,
|
|
@@ -150,7 +150,11 @@ export default class WebSocket extends Client {
|
|
|
150
150
|
* @throws {Error} If the WebSocket fails to connect.
|
|
151
151
|
*/
|
|
152
152
|
connect() {
|
|
153
|
-
const url = constructApiUrl(
|
|
153
|
+
const url = constructApiUrl(
|
|
154
|
+
this.baseUrl,
|
|
155
|
+
`/tts/websocket?cartesia_version=${CARTESIA_VERSION}`,
|
|
156
|
+
"ws",
|
|
157
|
+
);
|
|
154
158
|
url.searchParams.set("api_key", this.apiKey);
|
|
155
159
|
const emitter = new Emittery<ConnectionEventData>();
|
|
156
160
|
this.socket = new PartySocketWebSocket(url.toString());
|