cartesia 1.0.3__tar.gz → 1.0.5__tar.gz
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.
- cartesia-1.0.5/LICENSE.md +21 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/PKG-INFO +183 -9
- {cartesia-1.0.3 → cartesia-1.0.5}/README.md +181 -8
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia/_types.py +5 -4
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia/client.py +507 -83
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia/utils/deprecated.py +2 -0
- cartesia-1.0.5/cartesia/version.py +1 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia.egg-info/PKG-INFO +183 -9
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia.egg-info/SOURCES.txt +1 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia.egg-info/requires.txt +1 -0
- cartesia-1.0.5/tests/test_tts.py +768 -0
- cartesia-1.0.3/cartesia/version.py +0 -1
- cartesia-1.0.3/tests/test_tts.py +0 -349
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia/__init__.py +0 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia/utils/__init__.py +0 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia/utils/retry.py +0 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia.egg-info/dependency_links.txt +0 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/cartesia.egg-info/top_level.txt +0 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/pyproject.toml +0 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/setup.cfg +0 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/setup.py +0 -0
- {cartesia-1.0.3 → cartesia-1.0.5}/tests/test_deprecated.py +0 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2024 Cartesia AI, Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: cartesia
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.5
|
4
4
|
Summary: The official Python library for the Cartesia API.
|
5
5
|
Home-page:
|
6
6
|
Author: Cartesia, Inc.
|
@@ -12,6 +12,7 @@ Requires-Python: >=3.8.0
|
|
12
12
|
Description-Content-Type: text/markdown
|
13
13
|
Provides-Extra: dev
|
14
14
|
Provides-Extra: all
|
15
|
+
License-File: LICENSE.md
|
15
16
|
|
16
17
|
|
17
18
|
# Cartesia Python API Library
|
@@ -80,10 +81,10 @@ voice = client.voices.get(id=voice_id)
|
|
80
81
|
|
81
82
|
transcript = "Hello! Welcome to Cartesia"
|
82
83
|
|
83
|
-
# You can check out our models at
|
84
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
84
85
|
model_id = "sonic-english"
|
85
86
|
|
86
|
-
# You can find the supported `output_format`s
|
87
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
87
88
|
output_format = {
|
88
89
|
"container": "raw",
|
89
90
|
"encoding": "pcm_f32le",
|
@@ -131,10 +132,10 @@ async def write_stream():
|
|
131
132
|
voice_id = "a0e99841-438c-4a64-b679-ae501e7d6091"
|
132
133
|
voice = client.voices.get(id=voice_id)
|
133
134
|
transcript = "Hello! Welcome to Cartesia"
|
134
|
-
# You can check out our models at
|
135
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
135
136
|
model_id = "sonic-english"
|
136
137
|
|
137
|
-
# You can find the supported `output_format`s
|
138
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
138
139
|
output_format = {
|
139
140
|
"container": "raw",
|
140
141
|
"encoding": "pcm_f32le",
|
@@ -186,10 +187,10 @@ voice_id = "a0e99841-438c-4a64-b679-ae501e7d6091"
|
|
186
187
|
voice = client.voices.get(id=voice_id)
|
187
188
|
transcript = "Hello! Welcome to Cartesia"
|
188
189
|
|
189
|
-
# You can check out our models at
|
190
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
190
191
|
model_id = "sonic-english"
|
191
192
|
|
192
|
-
# You can find the supported `output_format`s
|
193
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
193
194
|
output_format = {
|
194
195
|
"container": "raw",
|
195
196
|
"encoding": "pcm_f32le",
|
@@ -227,6 +228,179 @@ p.terminate()
|
|
227
228
|
ws.close() # Close the websocket connection
|
228
229
|
```
|
229
230
|
|
231
|
+
#### Conditioning speech on previous generations using WebSocket
|
232
|
+
|
233
|
+
In some cases, input text may need to be streamed in. In these cases, it would be slow to wait for all the text to buffer before sending it to Cartesia's TTS service.
|
234
|
+
|
235
|
+
To mitigate this, Cartesia offers audio continuations. In this setting, users can send input text, as it becomes available, over a websocket connection.
|
236
|
+
|
237
|
+
To do this, we will create a `context` and send multiple requests without awaiting the response. Then you can listen to the responses in the order they were sent.
|
238
|
+
|
239
|
+
Each `context` will be closed automatically after 5 seconds of inactivity or when the `no_more_inputs` method is called. `no_more_inputs` sends a request with the `continue_=False`, which indicates no more inputs will be sent over this context
|
240
|
+
|
241
|
+
```python
|
242
|
+
import asyncio
|
243
|
+
import os
|
244
|
+
import pyaudio
|
245
|
+
from cartesia import AsyncCartesia
|
246
|
+
|
247
|
+
async def send_transcripts(ctx):
|
248
|
+
# Check out voice IDs by calling `client.voices.list()` or on https://play.cartesia.ai/
|
249
|
+
voice_id = "87748186-23bb-4158-a1eb-332911b0b708"
|
250
|
+
|
251
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
252
|
+
model_id = "sonic-english"
|
253
|
+
|
254
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
255
|
+
output_format = {
|
256
|
+
"container": "raw",
|
257
|
+
"encoding": "pcm_f32le",
|
258
|
+
"sample_rate": 44100,
|
259
|
+
}
|
260
|
+
|
261
|
+
transcripts = [
|
262
|
+
"Sonic and Yoshi team up in a dimension-hopping adventure! ",
|
263
|
+
"Racing through twisting zones, they dodge Eggman's badniks and solve ancient puzzles. ",
|
264
|
+
"In the Echoing Caverns, they find the Harmonic Crystal, unlocking new powers. ",
|
265
|
+
"Sonic's speed creates sound waves, while Yoshi's eggs become sonic bolts. ",
|
266
|
+
"As they near Eggman's lair, our heroes charge their abilities for an epic boss battle. ",
|
267
|
+
"Get ready to spin, jump, and sound-blast your way to victory in this high-octane crossover!"
|
268
|
+
]
|
269
|
+
|
270
|
+
for transcript in transcripts:
|
271
|
+
# Send text inputs as they become available
|
272
|
+
await ctx.send(
|
273
|
+
model_id=model_id,
|
274
|
+
transcript=transcript,
|
275
|
+
voice_id=voice_id,
|
276
|
+
continue_=True,
|
277
|
+
output_format=output_format,
|
278
|
+
)
|
279
|
+
|
280
|
+
# Indicate that no more inputs will be sent. Otherwise, the context will close after 5 seconds of inactivity.
|
281
|
+
await ctx.no_more_inputs()
|
282
|
+
|
283
|
+
async def receive_and_play_audio(ctx):
|
284
|
+
p = pyaudio.PyAudio()
|
285
|
+
stream = None
|
286
|
+
rate = 44100
|
287
|
+
|
288
|
+
async for output in ctx.receive():
|
289
|
+
buffer = output["audio"]
|
290
|
+
|
291
|
+
if not stream:
|
292
|
+
stream = p.open(
|
293
|
+
format=pyaudio.paFloat32,
|
294
|
+
channels=1,
|
295
|
+
rate=rate,
|
296
|
+
output=True
|
297
|
+
)
|
298
|
+
|
299
|
+
stream.write(buffer)
|
300
|
+
|
301
|
+
stream.stop_stream()
|
302
|
+
stream.close()
|
303
|
+
p.terminate()
|
304
|
+
|
305
|
+
async def stream_and_listen():
|
306
|
+
client = AsyncCartesia(api_key=os.environ.get("CARTESIA_API_KEY"))
|
307
|
+
|
308
|
+
# Set up the websocket connection
|
309
|
+
ws = await client.tts.websocket()
|
310
|
+
|
311
|
+
# Create a context to send and receive audio
|
312
|
+
ctx = ws.context() # Generates a random context ID if not provided
|
313
|
+
|
314
|
+
send_task = asyncio.create_task(send_transcripts(ctx))
|
315
|
+
listen_task = asyncio.create_task(receive_and_play_audio(ctx))
|
316
|
+
|
317
|
+
# Call the two coroutine tasks concurrently
|
318
|
+
await asyncio.gather(send_task, listen_task)
|
319
|
+
|
320
|
+
await ws.close()
|
321
|
+
await client.close()
|
322
|
+
|
323
|
+
asyncio.run(stream_and_listen())
|
324
|
+
```
|
325
|
+
|
326
|
+
You can also use continuations on the synchronous Cartesia client to stream in text as it becomes available. To do this, pass in a text generator that produces text chunks at intervals of less than 1 second, as shown below. This ensures smooth audio playback.
|
327
|
+
|
328
|
+
Note: the sync client has a different API for continuations compared to the async client.
|
329
|
+
|
330
|
+
```python
|
331
|
+
from cartesia import Cartesia
|
332
|
+
import pyaudio
|
333
|
+
import os
|
334
|
+
|
335
|
+
client = Cartesia(api_key=os.environ.get("CARTESIA_API_KEY"))
|
336
|
+
|
337
|
+
transcripts = [
|
338
|
+
"The crew engaged in a range of activities designed to mirror those "
|
339
|
+
"they might perform on a real Mars mission. ",
|
340
|
+
"Aside from growing vegetables and maintaining their habitat, they faced "
|
341
|
+
"additional stressors like communication delays with Earth, ",
|
342
|
+
"up to twenty-two minutes each way, to simulate the distance from Mars to our planet. ",
|
343
|
+
"These exercises were critical for understanding how astronauts can "
|
344
|
+
"maintain not just physical health but also mental well-being under such challenging conditions. ",
|
345
|
+
]
|
346
|
+
|
347
|
+
# Ending each transcript with a space makes the audio smoother
|
348
|
+
def chunk_generator(transcripts):
|
349
|
+
for transcript in transcripts:
|
350
|
+
if transcript.endswith(" "):
|
351
|
+
yield transcript
|
352
|
+
else:
|
353
|
+
yield transcript + " "
|
354
|
+
|
355
|
+
|
356
|
+
# You can check out voice IDs by calling `client.voices.list()` or on https://play.cartesia.ai/
|
357
|
+
voice_id = "87748186-23bb-4158-a1eb-332911b0b708"
|
358
|
+
|
359
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
360
|
+
model_id = "sonic-english"
|
361
|
+
|
362
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
363
|
+
output_format = {
|
364
|
+
"container": "raw",
|
365
|
+
"encoding": "pcm_f32le",
|
366
|
+
"sample_rate": 44100,
|
367
|
+
}
|
368
|
+
|
369
|
+
p = pyaudio.PyAudio()
|
370
|
+
rate = 44100
|
371
|
+
|
372
|
+
stream = None
|
373
|
+
|
374
|
+
# Set up the websocket connection
|
375
|
+
ws = client.tts.websocket()
|
376
|
+
|
377
|
+
# Create a context to send and receive audio
|
378
|
+
ctx = ws.context() # Generates a random context ID if not provided
|
379
|
+
|
380
|
+
# Pass in a text generator to generate & stream the audio
|
381
|
+
output_stream = ctx.send(
|
382
|
+
model_id=model_id,
|
383
|
+
transcript=chunk_generator(transcripts),
|
384
|
+
voice_id=voice_id,
|
385
|
+
output_format=output_format,
|
386
|
+
)
|
387
|
+
|
388
|
+
for output in output_stream:
|
389
|
+
buffer = output["audio"]
|
390
|
+
|
391
|
+
if not stream:
|
392
|
+
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=rate, output=True)
|
393
|
+
|
394
|
+
# Write the audio data to the stream
|
395
|
+
stream.write(buffer)
|
396
|
+
|
397
|
+
stream.stop_stream()
|
398
|
+
stream.close()
|
399
|
+
p.terminate()
|
400
|
+
|
401
|
+
ws.close() # Close the websocket connection
|
402
|
+
```
|
403
|
+
|
230
404
|
### Multilingual Text-to-Speech [Alpha]
|
231
405
|
|
232
406
|
You can use our `sonic-multilingual` model to generate audio in multiple languages. The languages supported are available at [docs.cartesia.ai](https://docs.cartesia.ai/getting-started/available-models).
|
@@ -244,10 +418,10 @@ voice = client.voices.get(id=voice_id)
|
|
244
418
|
transcript = "Hola! Bienvenido a Cartesia"
|
245
419
|
language = "es" # Language code corresponding to the language of the transcript
|
246
420
|
|
247
|
-
# Make sure you use the multilingual model! You can check out all models at
|
421
|
+
# Make sure you use the multilingual model! You can check out all models at https://docs.cartesia.ai/getting-started/available-models
|
248
422
|
model_id = "sonic-multilingual"
|
249
423
|
|
250
|
-
# You can find the supported `output_format`s
|
424
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
251
425
|
output_format = {
|
252
426
|
"container": "raw",
|
253
427
|
"encoding": "pcm_f32le",
|
@@ -64,10 +64,10 @@ voice = client.voices.get(id=voice_id)
|
|
64
64
|
|
65
65
|
transcript = "Hello! Welcome to Cartesia"
|
66
66
|
|
67
|
-
# You can check out our models at
|
67
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
68
68
|
model_id = "sonic-english"
|
69
69
|
|
70
|
-
# You can find the supported `output_format`s
|
70
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
71
71
|
output_format = {
|
72
72
|
"container": "raw",
|
73
73
|
"encoding": "pcm_f32le",
|
@@ -115,10 +115,10 @@ async def write_stream():
|
|
115
115
|
voice_id = "a0e99841-438c-4a64-b679-ae501e7d6091"
|
116
116
|
voice = client.voices.get(id=voice_id)
|
117
117
|
transcript = "Hello! Welcome to Cartesia"
|
118
|
-
# You can check out our models at
|
118
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
119
119
|
model_id = "sonic-english"
|
120
120
|
|
121
|
-
# You can find the supported `output_format`s
|
121
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
122
122
|
output_format = {
|
123
123
|
"container": "raw",
|
124
124
|
"encoding": "pcm_f32le",
|
@@ -170,10 +170,10 @@ voice_id = "a0e99841-438c-4a64-b679-ae501e7d6091"
|
|
170
170
|
voice = client.voices.get(id=voice_id)
|
171
171
|
transcript = "Hello! Welcome to Cartesia"
|
172
172
|
|
173
|
-
# You can check out our models at
|
173
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
174
174
|
model_id = "sonic-english"
|
175
175
|
|
176
|
-
# You can find the supported `output_format`s
|
176
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
177
177
|
output_format = {
|
178
178
|
"container": "raw",
|
179
179
|
"encoding": "pcm_f32le",
|
@@ -211,6 +211,179 @@ p.terminate()
|
|
211
211
|
ws.close() # Close the websocket connection
|
212
212
|
```
|
213
213
|
|
214
|
+
#### Conditioning speech on previous generations using WebSocket
|
215
|
+
|
216
|
+
In some cases, input text may need to be streamed in. In these cases, it would be slow to wait for all the text to buffer before sending it to Cartesia's TTS service.
|
217
|
+
|
218
|
+
To mitigate this, Cartesia offers audio continuations. In this setting, users can send input text, as it becomes available, over a websocket connection.
|
219
|
+
|
220
|
+
To do this, we will create a `context` and send multiple requests without awaiting the response. Then you can listen to the responses in the order they were sent.
|
221
|
+
|
222
|
+
Each `context` will be closed automatically after 5 seconds of inactivity or when the `no_more_inputs` method is called. `no_more_inputs` sends a request with the `continue_=False`, which indicates no more inputs will be sent over this context
|
223
|
+
|
224
|
+
```python
|
225
|
+
import asyncio
|
226
|
+
import os
|
227
|
+
import pyaudio
|
228
|
+
from cartesia import AsyncCartesia
|
229
|
+
|
230
|
+
async def send_transcripts(ctx):
|
231
|
+
# Check out voice IDs by calling `client.voices.list()` or on https://play.cartesia.ai/
|
232
|
+
voice_id = "87748186-23bb-4158-a1eb-332911b0b708"
|
233
|
+
|
234
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
235
|
+
model_id = "sonic-english"
|
236
|
+
|
237
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
238
|
+
output_format = {
|
239
|
+
"container": "raw",
|
240
|
+
"encoding": "pcm_f32le",
|
241
|
+
"sample_rate": 44100,
|
242
|
+
}
|
243
|
+
|
244
|
+
transcripts = [
|
245
|
+
"Sonic and Yoshi team up in a dimension-hopping adventure! ",
|
246
|
+
"Racing through twisting zones, they dodge Eggman's badniks and solve ancient puzzles. ",
|
247
|
+
"In the Echoing Caverns, they find the Harmonic Crystal, unlocking new powers. ",
|
248
|
+
"Sonic's speed creates sound waves, while Yoshi's eggs become sonic bolts. ",
|
249
|
+
"As they near Eggman's lair, our heroes charge their abilities for an epic boss battle. ",
|
250
|
+
"Get ready to spin, jump, and sound-blast your way to victory in this high-octane crossover!"
|
251
|
+
]
|
252
|
+
|
253
|
+
for transcript in transcripts:
|
254
|
+
# Send text inputs as they become available
|
255
|
+
await ctx.send(
|
256
|
+
model_id=model_id,
|
257
|
+
transcript=transcript,
|
258
|
+
voice_id=voice_id,
|
259
|
+
continue_=True,
|
260
|
+
output_format=output_format,
|
261
|
+
)
|
262
|
+
|
263
|
+
# Indicate that no more inputs will be sent. Otherwise, the context will close after 5 seconds of inactivity.
|
264
|
+
await ctx.no_more_inputs()
|
265
|
+
|
266
|
+
async def receive_and_play_audio(ctx):
|
267
|
+
p = pyaudio.PyAudio()
|
268
|
+
stream = None
|
269
|
+
rate = 44100
|
270
|
+
|
271
|
+
async for output in ctx.receive():
|
272
|
+
buffer = output["audio"]
|
273
|
+
|
274
|
+
if not stream:
|
275
|
+
stream = p.open(
|
276
|
+
format=pyaudio.paFloat32,
|
277
|
+
channels=1,
|
278
|
+
rate=rate,
|
279
|
+
output=True
|
280
|
+
)
|
281
|
+
|
282
|
+
stream.write(buffer)
|
283
|
+
|
284
|
+
stream.stop_stream()
|
285
|
+
stream.close()
|
286
|
+
p.terminate()
|
287
|
+
|
288
|
+
async def stream_and_listen():
|
289
|
+
client = AsyncCartesia(api_key=os.environ.get("CARTESIA_API_KEY"))
|
290
|
+
|
291
|
+
# Set up the websocket connection
|
292
|
+
ws = await client.tts.websocket()
|
293
|
+
|
294
|
+
# Create a context to send and receive audio
|
295
|
+
ctx = ws.context() # Generates a random context ID if not provided
|
296
|
+
|
297
|
+
send_task = asyncio.create_task(send_transcripts(ctx))
|
298
|
+
listen_task = asyncio.create_task(receive_and_play_audio(ctx))
|
299
|
+
|
300
|
+
# Call the two coroutine tasks concurrently
|
301
|
+
await asyncio.gather(send_task, listen_task)
|
302
|
+
|
303
|
+
await ws.close()
|
304
|
+
await client.close()
|
305
|
+
|
306
|
+
asyncio.run(stream_and_listen())
|
307
|
+
```
|
308
|
+
|
309
|
+
You can also use continuations on the synchronous Cartesia client to stream in text as it becomes available. To do this, pass in a text generator that produces text chunks at intervals of less than 1 second, as shown below. This ensures smooth audio playback.
|
310
|
+
|
311
|
+
Note: the sync client has a different API for continuations compared to the async client.
|
312
|
+
|
313
|
+
```python
|
314
|
+
from cartesia import Cartesia
|
315
|
+
import pyaudio
|
316
|
+
import os
|
317
|
+
|
318
|
+
client = Cartesia(api_key=os.environ.get("CARTESIA_API_KEY"))
|
319
|
+
|
320
|
+
transcripts = [
|
321
|
+
"The crew engaged in a range of activities designed to mirror those "
|
322
|
+
"they might perform on a real Mars mission. ",
|
323
|
+
"Aside from growing vegetables and maintaining their habitat, they faced "
|
324
|
+
"additional stressors like communication delays with Earth, ",
|
325
|
+
"up to twenty-two minutes each way, to simulate the distance from Mars to our planet. ",
|
326
|
+
"These exercises were critical for understanding how astronauts can "
|
327
|
+
"maintain not just physical health but also mental well-being under such challenging conditions. ",
|
328
|
+
]
|
329
|
+
|
330
|
+
# Ending each transcript with a space makes the audio smoother
|
331
|
+
def chunk_generator(transcripts):
|
332
|
+
for transcript in transcripts:
|
333
|
+
if transcript.endswith(" "):
|
334
|
+
yield transcript
|
335
|
+
else:
|
336
|
+
yield transcript + " "
|
337
|
+
|
338
|
+
|
339
|
+
# You can check out voice IDs by calling `client.voices.list()` or on https://play.cartesia.ai/
|
340
|
+
voice_id = "87748186-23bb-4158-a1eb-332911b0b708"
|
341
|
+
|
342
|
+
# You can check out our models at https://docs.cartesia.ai/getting-started/available-models
|
343
|
+
model_id = "sonic-english"
|
344
|
+
|
345
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
346
|
+
output_format = {
|
347
|
+
"container": "raw",
|
348
|
+
"encoding": "pcm_f32le",
|
349
|
+
"sample_rate": 44100,
|
350
|
+
}
|
351
|
+
|
352
|
+
p = pyaudio.PyAudio()
|
353
|
+
rate = 44100
|
354
|
+
|
355
|
+
stream = None
|
356
|
+
|
357
|
+
# Set up the websocket connection
|
358
|
+
ws = client.tts.websocket()
|
359
|
+
|
360
|
+
# Create a context to send and receive audio
|
361
|
+
ctx = ws.context() # Generates a random context ID if not provided
|
362
|
+
|
363
|
+
# Pass in a text generator to generate & stream the audio
|
364
|
+
output_stream = ctx.send(
|
365
|
+
model_id=model_id,
|
366
|
+
transcript=chunk_generator(transcripts),
|
367
|
+
voice_id=voice_id,
|
368
|
+
output_format=output_format,
|
369
|
+
)
|
370
|
+
|
371
|
+
for output in output_stream:
|
372
|
+
buffer = output["audio"]
|
373
|
+
|
374
|
+
if not stream:
|
375
|
+
stream = p.open(format=pyaudio.paFloat32, channels=1, rate=rate, output=True)
|
376
|
+
|
377
|
+
# Write the audio data to the stream
|
378
|
+
stream.write(buffer)
|
379
|
+
|
380
|
+
stream.stop_stream()
|
381
|
+
stream.close()
|
382
|
+
p.terminate()
|
383
|
+
|
384
|
+
ws.close() # Close the websocket connection
|
385
|
+
```
|
386
|
+
|
214
387
|
### Multilingual Text-to-Speech [Alpha]
|
215
388
|
|
216
389
|
You can use our `sonic-multilingual` model to generate audio in multiple languages. The languages supported are available at [docs.cartesia.ai](https://docs.cartesia.ai/getting-started/available-models).
|
@@ -228,10 +401,10 @@ voice = client.voices.get(id=voice_id)
|
|
228
401
|
transcript = "Hola! Bienvenido a Cartesia"
|
229
402
|
language = "es" # Language code corresponding to the language of the transcript
|
230
403
|
|
231
|
-
# Make sure you use the multilingual model! You can check out all models at
|
404
|
+
# Make sure you use the multilingual model! You can check out all models at https://docs.cartesia.ai/getting-started/available-models
|
232
405
|
model_id = "sonic-multilingual"
|
233
406
|
|
234
|
-
# You can find the supported `output_format`s
|
407
|
+
# You can find the supported `output_format`s at https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events
|
235
408
|
output_format = {
|
236
409
|
"container": "raw",
|
237
410
|
"encoding": "pcm_f32le",
|
@@ -45,15 +45,16 @@ class DeprecatedOutputFormatMapping:
|
|
45
45
|
"mulaw_8000": {"container": "raw", "encoding": "pcm_mulaw", "sample_rate": 8000},
|
46
46
|
"alaw_8000": {"container": "raw", "encoding": "pcm_alaw", "sample_rate": 8000},
|
47
47
|
}
|
48
|
-
|
48
|
+
|
49
|
+
@classmethod
|
49
50
|
@deprecated(
|
50
51
|
vdeprecated="1.0.1",
|
51
52
|
vremove="1.2.0",
|
52
53
|
reason="Old output format names are being deprecated in favor of names aligned with the Cartesia API. Use names from `OutputFormatMapping` instead.",
|
53
54
|
)
|
54
|
-
def get_format_deprecated(
|
55
|
-
if format_name in
|
56
|
-
return
|
55
|
+
def get_format_deprecated(cls, format_name):
|
56
|
+
if format_name in cls._format_mapping:
|
57
|
+
return cls._format_mapping[format_name]
|
57
58
|
else:
|
58
59
|
raise ValueError(f"Unsupported format: {format_name}")
|
59
60
|
|