cartesia 1.0.3__tar.gz → 1.0.4__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.3 → cartesia-1.0.4}/PKG-INFO +96 -1
- {cartesia-1.0.3 → cartesia-1.0.4}/README.md +95 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia/_types.py +5 -4
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia/client.py +316 -80
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia/utils/deprecated.py +2 -0
- cartesia-1.0.4/cartesia/version.py +1 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia.egg-info/PKG-INFO +96 -1
- cartesia-1.0.4/tests/test_tts.py +736 -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.4}/cartesia/__init__.py +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia/utils/__init__.py +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia/utils/retry.py +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia.egg-info/SOURCES.txt +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia.egg-info/dependency_links.txt +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia.egg-info/requires.txt +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/cartesia.egg-info/top_level.txt +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/pyproject.toml +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/setup.cfg +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/setup.py +0 -0
- {cartesia-1.0.3 → cartesia-1.0.4}/tests/test_deprecated.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: cartesia
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.4
|
4
4
|
Summary: The official Python library for the Cartesia API.
|
5
5
|
Home-page:
|
6
6
|
Author: Cartesia, Inc.
|
@@ -227,6 +227,101 @@ p.terminate()
|
|
227
227
|
ws.close() # Close the websocket connection
|
228
228
|
```
|
229
229
|
|
230
|
+
#### Conditioning speech on previous generations using WebSocket
|
231
|
+
|
232
|
+
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.
|
233
|
+
|
234
|
+
To mitigate this, Cartesia offers audio continuations. In this setting, users can send input text, as it becomes available, over a websocket connection.
|
235
|
+
|
236
|
+
To do this, we will create a `context` and sending multiple requests without awaiting the response. Then you can listen to the responses in the order they were sent.
|
237
|
+
|
238
|
+
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
|
239
|
+
|
240
|
+
```python
|
241
|
+
import asyncio
|
242
|
+
import os
|
243
|
+
import pyaudio
|
244
|
+
from cartesia import AsyncCartesia
|
245
|
+
|
246
|
+
async def send_transcripts(ctx):
|
247
|
+
# Check out voice IDs by calling `client.voices.list()` or on [play.cartesia.ai](https://play.cartesia.ai/)
|
248
|
+
voice_id = "87748186-23bb-4158-a1eb-332911b0b708"
|
249
|
+
|
250
|
+
# You can check out our models at [docs.cartesia.ai](https://docs.cartesia.ai/getting-started/available-models).
|
251
|
+
model_id = "sonic-english"
|
252
|
+
|
253
|
+
# You can find the supported `output_format`s in our [API Reference](https://docs.cartesia.ai/api-reference/endpoints/stream-speech-server-sent-events).
|
254
|
+
output_format = {
|
255
|
+
"container": "raw",
|
256
|
+
"encoding": "pcm_f32le",
|
257
|
+
"sample_rate": 44100,
|
258
|
+
}
|
259
|
+
|
260
|
+
transcripts = [
|
261
|
+
"Sonic and Yoshi team up in a dimension-hopping adventure! ",
|
262
|
+
"Racing through twisting zones, they dodge Eggman's badniks and solve ancient puzzles. ",
|
263
|
+
"In the Echoing Caverns, they find the Harmonic Crystal, unlocking new powers. ",
|
264
|
+
"Sonic's speed creates sound waves, while Yoshi's eggs become sonic bolts. ",
|
265
|
+
"As they near Eggman's lair, our heroes charge their abilities for an epic boss battle. ",
|
266
|
+
"Get ready to spin, jump, and sound-blast your way to victory in this high-octane crossover!"
|
267
|
+
]
|
268
|
+
|
269
|
+
for transcript in transcripts:
|
270
|
+
# Send text inputs as they become available
|
271
|
+
await ctx.send(
|
272
|
+
model_id=model_id,
|
273
|
+
transcript=transcript,
|
274
|
+
voice_id=voice_id,
|
275
|
+
continue_=True,
|
276
|
+
output_format=output_format,
|
277
|
+
)
|
278
|
+
|
279
|
+
# Indicate that no more inputs will be sent. Otherwise, the context will close after 5 seconds of inactivity.
|
280
|
+
await ctx.no_more_inputs()
|
281
|
+
|
282
|
+
async def receive_and_play_audio(ctx):
|
283
|
+
p = pyaudio.PyAudio()
|
284
|
+
stream = None
|
285
|
+
rate = 44100
|
286
|
+
|
287
|
+
async for output in ctx.receive():
|
288
|
+
buffer = output["audio"]
|
289
|
+
|
290
|
+
if not stream:
|
291
|
+
stream = p.open(
|
292
|
+
format=pyaudio.paFloat32,
|
293
|
+
channels=1,
|
294
|
+
rate=rate,
|
295
|
+
output=True
|
296
|
+
)
|
297
|
+
|
298
|
+
stream.write(buffer)
|
299
|
+
|
300
|
+
stream.stop_stream()
|
301
|
+
stream.close()
|
302
|
+
p.terminate()
|
303
|
+
|
304
|
+
async def stream_and_listen():
|
305
|
+
client = AsyncCartesia(api_key=os.environ.get("CARTESIA_API_KEY"))
|
306
|
+
|
307
|
+
# Set up the websocket connection
|
308
|
+
ws = await client.tts.websocket()
|
309
|
+
|
310
|
+
# Create a context to send and receive audio
|
311
|
+
ctx = ws.context() # Generates a random context ID if not provided
|
312
|
+
|
313
|
+
send_task = asyncio.create_task(send_transcripts(ctx))
|
314
|
+
listen_task = asyncio.create_task(receive_and_play_audio(ctx))
|
315
|
+
|
316
|
+
# Call the two coroutine tasks concurrently
|
317
|
+
await asyncio.gather(send_task, listen_task)
|
318
|
+
|
319
|
+
await ws.close()
|
320
|
+
await client.close()
|
321
|
+
|
322
|
+
asyncio.run(stream_and_listen())
|
323
|
+
```
|
324
|
+
|
230
325
|
### Multilingual Text-to-Speech [Alpha]
|
231
326
|
|
232
327
|
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).
|
@@ -211,6 +211,101 @@ 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 sending 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 [play.cartesia.ai](https://play.cartesia.ai/)
|
232
|
+
voice_id = "87748186-23bb-4158-a1eb-332911b0b708"
|
233
|
+
|
234
|
+
# You can check out our models at [docs.cartesia.ai](https://docs.cartesia.ai/getting-started/available-models).
|
235
|
+
model_id = "sonic-english"
|
236
|
+
|
237
|
+
# You can find the supported `output_format`s in our [API Reference](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
|
+
|
214
309
|
### Multilingual Text-to-Speech [Alpha]
|
215
310
|
|
216
311
|
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).
|
@@ -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
|
|