dscaper 1.7.2__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.
dscaper-1.7.2/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2017, Justin Salamon
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of the copyright holder nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dscaper-1.7.2/PKG-INFO ADDED
@@ -0,0 +1,544 @@
1
+ Metadata-Version: 2.4
2
+ Name: dscaper
3
+ Version: 1.7.2
4
+ Summary: A library for soundscape synthesis and augmentation
5
+ Home-page: https://github.com/dscaper/dscaper
6
+ Download-URL:
7
+ Author: Duncan MacConnell
8
+ Author-email: Justin Salamon <justin.salamon@gmail.com>, David Grünert <grud@zhaw.ch>
9
+ License: BSD-3-Clause
10
+ Project-URL: Homepage, https://github.com/dscaper/dscaper
11
+ Project-URL: Repository, https://github.com/dscaper/dscaper
12
+ Project-URL: Issues, https://github.com/dscaper/dscaper/issues
13
+ Keywords: audio,sound,soundscape,environmental,dsp,mixing
14
+ Classifier: License :: OSI Approved :: BSD License
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
19
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Sound Synthesis
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: sox
25
+ Requires-Dist: soundfile
26
+ Requires-Dist: scipy
27
+ Requires-Dist: fastapi
28
+ Requires-Dist: jams
29
+ Requires-Dist: pyloudnorm
30
+ Provides-Extra: docs
31
+ Requires-Dist: sphinx; extra == "docs"
32
+ Requires-Dist: sphinx_rtd_theme; extra == "docs"
33
+ Requires-Dist: sphinx_issues; extra == "docs"
34
+ Provides-Extra: tests
35
+ Requires-Dist: backports.tempfile; extra == "tests"
36
+ Requires-Dist: pytest; extra == "tests"
37
+ Requires-Dist: pytest-cov; extra == "tests"
38
+ Requires-Dist: tqdm; extra == "tests"
39
+ Dynamic: home-page
40
+ Dynamic: license-file
41
+
42
+ # dScaper
43
+
44
+ ![dScaper logo](/docs/dScaper-logo.png)
45
+
46
+ ***A [Scaper](https://github.com/justinsalamon/scaper) fork optimized for audio generation pipelines.***
47
+
48
+ dScaper was developped during [JSALT25](https://jsalt2025.fit.vut.cz/) Workshop by David Grünert. dScaper offers an
49
+ alternative API for accessing Scaper that is optimized for the usage in pipelines. Please refer to
50
+ [Scaper documentation](http://scaper.readthedocs.io/) for details of the original Scaper API.
51
+
52
+ ## Table of Contents
53
+
54
+ - [Architecture and key features](#architecture-and-key-features)
55
+ - [Installation](#installation)
56
+ - [Python API](#python-api)
57
+ - [Adding audio files to the library](#adding-audio-files-to-the-library)
58
+ - [Assemble timelines](#assemble-timelines)
59
+ - [Adding background sounds](#adding-background-sounds)
60
+ - [Adding events](#adding-events)
61
+ - [Generating timelines](#generating-timelines)
62
+ - [dScaper class methods](#dscaper-class-methods)
63
+ - [Web API](#web-api)
64
+ - [Audio API](#audio-api)
65
+ - [Timeline API](#timeline-api)
66
+ - [Distribution lists](#distribution-lists)
67
+ - [Folder structure](#folder-structure)
68
+ - [Misc](#misc)
69
+
70
+
71
+ ## Architecture and key features
72
+
73
+ dScaper can eighter be use as python module or as separate server. In both variants, dScaper not only handles timeline generation, but it also stores and manages audio files.
74
+
75
+ ![architecture overview](docs/dscaper_architecture.drawio.svg)
76
+
77
+ The main features of dScaper are:
78
+ - **Audio library management**: dScaper allows you to store and manage audio files in a structured way. Audio files are organized into libraries and labels, making it easy to retrieve and use them in multiple timelines.
79
+ - **Timeline management**: dScaper allows you to create and edit timelines, which define the structure of the generated audio including background sounds and events. dScaper supports the same distributions for sampling as the original Scaper library.
80
+ - **Audio generation**: dScaper can generate multiple version of a timeline. It stores the generated audio files along with their metadata making it easy to retrieve and compare them later.
81
+ - **Event positions**: dScaper supports event positions, allowing you to categorize events in the timeline. This is useful for generating multiple audio files for different event positions, e.g. to apply different room acoustics to different speakers and sound sources.
82
+ - **Speaker and text metadata**: dScaper allows you to add speaker and text metadata to events. This is useful for generating audio files with speaker and text annotations.
83
+ - **Web API and Python API**: dScaper provides a RESTful Web API and a Python API. The web API allows to use dScaper as a standalone server simplifying integration and scaling of pipelines.
84
+
85
+ ## Installation
86
+
87
+ ### Non-python dependencies
88
+ Scaper has one non-python dependency:
89
+ - FFmpeg: https://ffmpeg.org/
90
+
91
+ If you are installing Scaper on Windows, you will also need:
92
+ - SoX: http://sox.sourceforge.net/
93
+
94
+ #### macOS
95
+ On macOS FFmpeg can be installed using [homebrew](https://brew.sh/):
96
+
97
+ ```
98
+ brew install ffmpeg
99
+ ```
100
+
101
+ #### Linux
102
+ On linux you can use your distribution's package manager, e.g. on Ubuntu (15.04 "Vivid Vervet" or newer):
103
+
104
+ ```
105
+ sudo apt-get install ffmpeg
106
+ ```
107
+
108
+ #### Windows
109
+ On windows you can use the provided installation binaries:
110
+ - SoX: https://sourceforge.net/projects/sox/files/sox/
111
+ - FFmpeg: https://ffmpeg.org/download.html#build-windows
112
+
113
+ ### Installing dScaper
114
+
115
+ To install the latest version of dScaper from source, clone or pull the lastest version:
116
+
117
+ ```
118
+ git clone https://github.com/cyrta/dscaper
119
+ ```
120
+
121
+ Then create an environment and install the package from requirements.txt:
122
+
123
+ ```
124
+ cd dscaper
125
+ python -m venv venv
126
+ source venv/bin/activate # On Windows use `venv\Scripts\activate`
127
+ pip install -r requirements.txt
128
+ ```
129
+
130
+ ## Python API
131
+ You can use dScaper as a Python module. The main class is `Dscaper`, which provides methods for creating timelines, adding audio files, and generating audio. dScaper needs a folder to store audio files, metadata and timelines. You can specify this folder using the `dscaper_base_path` parameter when creating an instance of `Dscaper`. If you do not specify it, dScaper will use the default path `./data`.
132
+
133
+ ```python
134
+ import scaper
135
+
136
+ dsc = scaper.Dscaper(dscaper_base_path="/path/to/dscaper/data")
137
+ ```
138
+
139
+ dScaper will create two subfolders `libraries` and `timelines` in the specified path if they do not already exist.
140
+
141
+ ```/path/to/dscaper/data/
142
+ ├── libraries
143
+ │ └── [library_data...]
144
+ └── timelines
145
+ └── [timeline_data...]
146
+ ```
147
+ The librarys folder is used to store the input audio files and their metadata. The timeline folder contains the definition and the resulting audio of the generated timelines. Further details of the folder structure can be found in the [Folder structure](#folder-structure) section below.
148
+
149
+ ### Adding audio files to the library
150
+
151
+ You can add audio files to the dScaper library using the `store_audio` method. This method takes a file path and metadata as parameters. The metadata should be an instance of `DscaperAudio`. It defines library, label, and filename for storing the audio file. As most methods in dScaper, it returns a `DscaperJsonResponse` object that contains the result of the operation. More details about the `DscaperJsonResponse` can be found in the [Dscaper class methods](#dscaper-class-methods) section below.
152
+
153
+ ```python
154
+ from scaper.dscaper_datatypes import DscaperAudio
155
+
156
+ file_path = "/path/to/audio/file.wav"
157
+ metadata = DscaperAudio(library="my_library", label="my_label", filename="my_file.wav")
158
+ resp = dsc.store_audio(file_path, metadata)
159
+
160
+ if (resp.status == "success"):
161
+ print("Audio file stored successfully.")
162
+ else:
163
+ print(f"Error storing audio file: {resp.content}")
164
+ ```
165
+
166
+ ### Assemble timelines
167
+ To assemble a timeline, you first create an empty timeline using the `create_timeline` method. This method takes a `DscaperTimeline` instance as a parameter which allows you to specify the name, duration, and description of the timeline. The name of the timeline should be unique and will be used to reference the timeline later. dScaper will refuse to create a timeline with the same name as an existing one.
168
+
169
+ ```python
170
+ from scaper.dscaper_datatypes import DscaperTimeline
171
+
172
+ timeline_metadata = DscaperTimeline(name="my_timeline", duration=10.0, description="Test timeline")
173
+ dsc.create_timeline(timeline_metadata)
174
+ ```
175
+ #### Adding background sounds
176
+ Now you can add background sounds and events to the timeline. Background sounds are added using the `add_background` method that takes a `DscaperBackground` instance as a parameter. Paramters of type `list[str]` are used to represent distributions in the format described in the [Distribution lists](#distribution-lists) section below.
177
+
178
+ Attributes of `DscaperBackground`:
179
+ - `library (str)`: The name of the audio library from which the background is sourced.
180
+ - `label (list[str])`: The label(s) describing the background audio. Defaults to `['choose', '[]']` which will randomly choose one label in the library.
181
+ - `source_file (list[str])`: The file(s) from which the background audio is taken. Defaults to `['choose', '[]']` which will randomly choose one file in the library.
182
+ - `source_time (list[str])`: The time specification for the source audio. Defaults to `['const', '0']` which means the background starts at the beginning of the source file.
183
+
184
+
185
+ ```python
186
+ from scaper.dscaper_datatypes import DscaperBackground
187
+
188
+ background_metadata = DscaperBackground(..)
189
+ dsc.add_background("my_timeline", background_metadata)
190
+ ```
191
+ #### Adding events
192
+
193
+ Events are added using the `add_event` method that takes a `DscaperEvent` instance as a parameter. Again, paramters of type `list[str]` represent distributions (see [Distribution lists](#distribution-lists)).
194
+
195
+ Attributes of `DscaperEvent`:
196
+ - `library (str)`: The name of the audio library from which the event is sourced.
197
+ - `label (list[str])`: The label from which the event is sourced. Defaults to `['choose', '[]']` which will randomly choose one label in the library.
198
+ - `source_file (list[str])`: The source audio file for the event, typically in the form `['choose', '[]']` which will randomly choose one file in the library.
199
+ - `source_time (list[str])`: The start time within the source file, typically in the form `['const', '0']` which means the event starts at the beginning of the source file.
200
+ - `event_time (list[str])`: The time at which the event occurs in the timeline, typically in the form `['const', '0']` which means the event starts at the beginning of the timeline.
201
+ - `event_duration (list[str]) | None`: The duration of the event. Can be set to `None` to use the duration of the source file, or specified as a distribution like `['const', '5']` which means the event lasts for 5 seconds. If not set and no source file is specified, it defaults to `['const', '5']`.
202
+ , typically in the form `['const', '5']` which means the event lasts for 5 seconds.
203
+ - `snr (list[str])`: The signal-to-noise ratio for the event, typically in the form `['const', '0']`.
204
+ - `pitch_shift (list[str] | None)`: Optional pitch shift parameters for the event. Defaults to `None`.
205
+ - `time_stretch (list[str] | None)`: Optional time stretch parameters for the event. Defaults to `None`.
206
+ - `position (str | None)`: Optional position of the event (e.g., seat_1, seat_2, door, window). Defaults to `None`. This allows you to categorize events in the timeline and write them to separate audio files when generating the timeline. This is useful for applying different post-processings, e.g. applying different room acoustics to different speakers and sound sources.
207
+ - `speaker (str | None)`: Optional speaker of the event. Defaults to `None`. This allows you to categorize events by speaker.
208
+ - `text (str | None)`: Used for audio with speech content. This is a string that can be used to save the content.
209
+
210
+ ```python
211
+ from scaper.dscaper_datatypes import DscaperEvent
212
+
213
+ event_metadata = DscaperEvent(..)
214
+ dsc.add_event("my_timeline", event_metadata)
215
+ ```
216
+ ### Generating timelines
217
+ Once you have added all the necessary background sounds and events to the timeline, you can generate the audio using the `generate_timeline` method. This method takes a `DscaperGenerate` instance as a parameter.
218
+ It represents the configuration and metadata for a soundscape generation process. The method returns a `DscaperJsonResponse` object containing the ID of the generated timeline. This ID is used to reference the generated audio later.
219
+
220
+ Attributes of `DscaperGenerate`:
221
+ - `seed (int)`: Random seed used for reproducibility of the generation process. Default is 0.
222
+ - `ref_db (int)`: Reference decibel level for the generated audio. Default is -20.
223
+ - `reverb (float)`: Amount of reverb to apply to the generated audio. Default is 0.0.
224
+ - `save_isolated_events (bool)`: Whether to save isolated audio files for each event. Default is False.
225
+ - `save_isolated_positions (bool)`: Whether to save isolated audio files for each event position. Default is False.
226
+
227
+ ```python
228
+ from scaper.dscaper_datatypes import DscaperGenerate
229
+
230
+ generate_metadata = DscaperGenerate(...)
231
+ resp = dsc.generate_timeline("my_timeline", generate_metadata)
232
+
233
+ content = DscaperGenerate(**resp.content)
234
+ print("ID:",content.id)
235
+ ```
236
+
237
+ ### Reading generated timelines
238
+ You can retrieve the generated audio and metadata using the `get_generated_timeline_by_id` method. This method takes the timeline name and the generated ID as parameters. It returns a `DscaperJsonResponse` object containing the generated audio and metadata.
239
+
240
+ ```python
241
+ resp = dsc.get_generated_timeline_by_id("my_timeline", content.id)
242
+ if resp.status == "success":
243
+ content = DscaperGenerate(**resp.content)
244
+ print(content.generated_files)
245
+ ```
246
+
247
+ You can also download all generated files as archive using `get_generated_files`. This method takes the timeline name and the generated ID as parameters. It returns a `DscaperJsonResponse` object containing the archive file.
248
+
249
+ ```python
250
+ resp = dsc.get_generated_files("restaurant_timeline", id)
251
+ if resp.status == "success":
252
+ filename = f"generated_files_{id}.zip"
253
+ with open(filename, 'wb') as f:
254
+ if resp.content is not None:
255
+ if isinstance(resp.content, bytes):
256
+ f.write(resp.content)
257
+ else:
258
+ raise TypeError("resp.content is not of type bytes")
259
+ else:
260
+ print("No content to write to file.")
261
+ ```
262
+
263
+ ### dScaper class methods
264
+ Here is a complete list of the methods available in the `Dscaper` class. Most methods return a `DscaperJsonResponse` object, which contains the result of the operation and any relevant metadata. It has the following attributes:
265
+
266
+ - `status`: The status of the operation (e.g., "success", "error").
267
+ - `status_code`: The HTTP status code of the response (e.g., 200, 400).
268
+ - `content`: The main content of the response. This depends on the method. See below for details.
269
+ - `media_type`: The media type of the response content (e.g., "application/json", "text/plain").
270
+
271
+
272
+ | Method | Description |
273
+ |--------|-------------|
274
+ | `store_audio(file, metadata, update=False)` | Store an audio file and its metadata in the library. Supports file upload and update. Returns a `DscaperJsonResponse`. Content has type `DscaperAudio` and contains all data stored. |
275
+ | `read_audio(library, label, filename)` | Retrieve an audio file or its metadata from the library. Returns a `DscaperApiResponse` with content having the audio data. |
276
+ | `create_timeline(properties)` | Create a new timeline with specified properties. Returns a `DscaperJsonResponse`. Content is of type `DscaperTimeline` and contains all data stored.|
277
+ | `add_background(timeline_name, properties)` | Add a background sound to a timeline. Returns a `DscaperJsonResponse`. Content is of type `DscaperBackground` and contains all data stored.|
278
+ | `add_event(timeline_name, properties)` | Add an event to a timeline. Returns a `DscaperJsonResponse`. Content is of type `DscaperEvent` and contains all data stored. |
279
+ | `generate_timeline(timeline_name, properties)` | Generate audio for a timeline using the provided generation parameters. Returns a `DscaperJsonResponse`. Content is of type `DscaperGenerate` and contains all data stored.|
280
+ | `get_dscaper_base_path()` | Returns the base path used for libraries and timelines as string. |
281
+ | `get_libraries()` | List all available audio libraries. Returns a `DscaperJsonResponse`. Content is a list of strings. |
282
+ | `get_filenames(library, label)` | List all filenames within a specific library and label. Returns a `DscaperJsonResponse`. Content is a list of strings.|
283
+ | `get_labels(library)` | List all labels within a specific library. Returns a `DscaperJsonResponse`. Content is a list of strings. |
284
+ | `get_label_metadata(library, label)` | Retrieve all metadata entries for a specific label in a library. Returns a `DscaperJsonResponse`. Content is a list of `DscaperAudio` metadata entries. |
285
+ | `get_file_metadata(library, label, filename)` | Retrieve metadata for a specific audio file in a library. Returns a `DscaperJsonResponse`. Content is of type `DscaperAudio` and contains all data stored. |
286
+ | `list_timelines()` | List all timelines and their metadata. Returns a `DscaperJsonResponse`. Content is of type `DscaperTimelines`. |
287
+ | `list_backgrounds(timeline_name)` | List all backgrounds in a specified timeline. Returns a `DscaperJsonResponse`. Content is of type `DscaperBackgrounds`. |
288
+ | `list_events(timeline_name)` | List all events in a specified timeline. Returns a `DscaperJsonResponse`. Content is of type `DscaperEvents`. |
289
+ | `get_generated_timelines(timeline_name)` | List all generated outputs for a specified timeline. Returns a `DscaperJsonResponse`. Content is of type `DscaperGenerations`.|
290
+ | `get_generated_timeline_by_id(timeline_name, generate_id)` | Retrieve details of a specific generated output by its ID. Returns a `DscaperJsonResponse`. Content is of type `DscaperGenerate` and contains all data stored. |
291
+ | `get_generated_file(timeline_name, generate_id, file_name)` | Download a specific generated file (audio or metadata) by name. Returns a `DscaperJsonResponse`. Content is of type `DscaperGenerate` and contains all data stored. |
292
+ | `get_generated_files(timeline_name, generate_id)` | Download all generated files as an archive. Returns a `DscaperJsonResponse`. Content is of type `bytes` containing the archive data (zip). |
293
+
294
+
295
+ ## Web API
296
+ The dScaper Web API provides a RESTful interface for interacting with dScaper functionality over HTTP. The API is implemented in the `web/api` directory and allows you to manage libraries, timelines, audio files, and trigger audio generation remotely. For development, you can run the API server using FastAPI dev server:
297
+
298
+ ```bash
299
+ > fastapi dev main.py
300
+ ```
301
+
302
+ There is a [postman](https://www.postman.com/) collection available in the `docs` directory that contains all endpoints and example requests. You can import this collection into Postman to test the API.
303
+
304
+ ### Audio API
305
+
306
+ The Audio API provides endpoints for managing audio libraries, labels, and files. It allows you to upload, update, list, and retrieve audio files and their metadata.
307
+
308
+ #### Endpoints
309
+
310
+ - `POST /api/v1/audio/{library}/{label}/{filename}`
311
+ Upload a new audio file and its metadata to a specific library and label.
312
+ **Path parameters:**
313
+ - `library` (str): The library to store the audio in.
314
+ - `label` (str): The label for the audio file.
315
+ - `filename` (str): The name of the audio file.
316
+ **Request body (multipart/form-data):**
317
+ - `file` (bytes): The audio file to be uploaded.
318
+ - `sandbox` (str): JSON string containing sandbox data (metadata).
319
+ Returns the stored audio's metadata.
320
+ Errors: 400 if the file is empty/invalid or already exists.
321
+
322
+ - `PUT /api/v1/audio/{library}/{label}/{filename}`
323
+ Update an existing audio file and its metadata.
324
+ **Path parameters:**
325
+ - `library` (str): The library containing the audio.
326
+ - `label` (str): The label of the audio file.
327
+ - `filename` (str): The name of the audio file.
328
+ **Request body (multipart/form-data):**
329
+ - `file` (bytes): The new audio file to replace the existing one.
330
+ - `sandbox` (str): JSON string containing updated sandbox data (metadata).
331
+ Returns the updated audio's metadata.
332
+ Errors: 400 if the file is empty/invalid or does not exist.
333
+
334
+ - `GET /api/v1/audio/`
335
+ List all available audio libraries.
336
+ **Response:** List of library names.
337
+
338
+ - `GET /api/v1/audio/{library}`
339
+ List all labels within a specific library.
340
+ **Path parameters:**
341
+ - `library` (str): The library to get labels from.
342
+ **Response:** List of label names.
343
+ Errors: 404 if the library does not exist.
344
+
345
+ - `GET /api/v1/audio/{library}/{label}`
346
+ List all filenames within a specific label of a library.
347
+ **Path parameters:**
348
+ - `library` (str): The library to get filenames from.
349
+ - `label` (str): The label to get filenames from.
350
+ **Response:** List of filenames.
351
+ Errors: 404 if the library or label does not exist.
352
+
353
+ - `GET /api/v1/audio/{library}/{label}/{filename}`
354
+ Retrieve metadata or the audio file itself for a given library, label, and filename.
355
+ **Path parameters:**
356
+ - `library` (str): The library of the audio file.
357
+ - `label` (str): The label of the audio file.
358
+ - `filename` (str): The name of the audio file or its metadata.
359
+ **Response:** The audio file or its metadata.
360
+ Errors: 404 if the audio file does not exist.
361
+
362
+ All responses are wrapped in a standard response object. Errors such as missing files or libraries return appropriate HTTP status codes (e.g., 400, 404).
363
+
364
+ ### Timeline API
365
+ The Timeline API provides endpoints for creating and managing timelines, adding backgrounds and events, and generating audio. Each timeline represents a sequence of audio events and backgrounds, which can be generated into audio files.
366
+
367
+ #### Endpoints
368
+
369
+ - `POST /api/v1/timeline/{timeline_name}`
370
+ Create a new timeline with the specified name and properties.
371
+ **Path parameters:**
372
+ - `timeline_name` (str): The name of the timeline to create.
373
+ **Request body (application/json):**
374
+ - `duration` (float): Duration of the timeline in seconds.
375
+ - `description` (str, optional): Description of the timeline.
376
+ - `sandbox` (dict, optional): Additional metadata or sandbox data.
377
+ **Response:** Confirmation and details of the created timeline.
378
+
379
+ - `POST /api/v1/timeline/{timeline_name}/background`
380
+ Add a background sound to the specified timeline.
381
+ **Path parameters:**
382
+ - `timeline_name` (str): The name of the timeline.
383
+ **Request body (application/json):**
384
+ - Background properties as defined by `DscaperBackground`.
385
+ **Response:** Confirmation and details of the added background.
386
+
387
+ - `POST /api/v1/timeline/{timeline_name}/event`
388
+ Add an event to the specified timeline.
389
+ **Path parameters:**
390
+ - `timeline_name` (str): The name of the timeline.
391
+ **Request body (application/json):**
392
+ - Event properties as defined by `DscaperEvent`.
393
+ **Response:** Confirmation and details of the added event.
394
+
395
+ - `POST /api/v1/timeline/{timeline_name}/generate`
396
+ Generate audio for the specified timeline using provided generation parameters.
397
+ **Path parameters:**
398
+ - `timeline_name` (str): The name of the timeline.
399
+ **Request body (application/json):**
400
+ - Generation parameters as defined by `DscaperGenerate`.
401
+ **Response:** Confirmation and details of the generation process.
402
+
403
+ - `GET /api/v1/timeline/`
404
+ List all available timelines.
405
+ **Response:** List of timeline names and metadata.
406
+
407
+ - `GET /api/v1/timeline/{timeline_name}/background`
408
+ List all backgrounds in the specified timeline.
409
+ **Path parameters:**
410
+ - `timeline_name` (str): The name of the timeline.
411
+ **Response:** List of backgrounds.
412
+
413
+ - `GET /api/v1/timeline/{timeline_name}/event`
414
+ List all events in the specified timeline.
415
+ **Path parameters:**
416
+ - `timeline_name` (str): The name of the timeline.
417
+ **Response:** List of events.
418
+
419
+ - `GET /api/v1/timeline/{timeline_name}/generate`
420
+ List all generated outputs for the specified timeline.
421
+ **Path parameters:**
422
+ - `timeline_name` (str): The name of the timeline.
423
+ **Response:** List of generated outputs.
424
+
425
+ - `GET /api/v1/timeline/{timeline_name}/generate/{generate_id}`
426
+ Retrieve all files generated for a specific timeline by its ID as an archive.
427
+ **Path parameters:**
428
+ - `timeline_name` (str): The name of the timeline.
429
+ - `generate_id` (str): The ID of the generated output.
430
+ **Response:** Details of the generated output.
431
+
432
+ - `GET /api/v1/timeline/{timeline_name}/generate/{generate_id}/{file_name}`
433
+ Download a specific generated file (e.g., audio or metadata) by name.
434
+ **Path parameters:**
435
+ - `timeline_name` (str): The name of the timeline.
436
+ - `generate_id` (str): The ID of the generated output.
437
+ - `file_name` (str): The name of the file to download.
438
+ **Response:** The requested file or its metadata.
439
+
440
+ All endpoints return responses wrapped in a standard response object. Errors such as missing timelines or invalid parameters return appropriate HTTP status codes.
441
+ """
442
+
443
+ ## Distribution lists
444
+ dScaper supports the same distributions as the original Scaper library. Instead of tuples, it uses lists to represent distributions. All list elements must be of type string. The following distributions are supported:
445
+
446
+ - `['const', value]`: Constant value distribution.
447
+ - `['choose', list]`: Uniformly sample from a finite set of values given by `list`.
448
+ - `['choose_weighted', list, weights]`: Sample from a finite set of values given by `list` with specified `weights` for each value.
449
+ - `['uniform', min, max]`: Uniform distribution between `min` and `max`.
450
+ - `['normal', mean, std]`: Normal distribution with specified `mean` and `std` (standard deviation).
451
+ - `['truncnorm', mean, std, min, max]`: Truncated normal distribution with specified `mean`, `std`, and limits between `min` and `max`.
452
+
453
+ If you use an empty list `[]`, it is interpreted as a distribution that samples from all available values. For example, if you specify `['choose', '[]']` for the label, it will sample from all available values in the library.
454
+
455
+ ## Folder structure
456
+ The dScaper library and timelines are stored in the `libraries` and `timelines` directories, respectively. The structure for `libraries` is as follows:
457
+
458
+ ```/path/to/dscaper/data/
459
+ └── libraries
460
+ ├── [library_1_name]
461
+ │ ├── [label_1]
462
+ │ │ ├── [audio_file_1.wav]
463
+ │ │ ├── [audio_file_1.json]
464
+ │ │ ├── [audio_file_2.wav]
465
+ │ │ └── [...]
466
+ │ ├── [label_2]
467
+ │ │ ├── [audio_file_2.wav]
468
+ │ │ └── [audio_file_2.json]
469
+ │ └── [...]
470
+ └── [library_2_name]
471
+ └── [...]
472
+ ```
473
+ Timelines define the structure of the generated audio. They are organized as follows:
474
+ ```
475
+ └── timelines
476
+ ├── [timeline_1_name]
477
+ │ ├── timeline.json
478
+ │ ├── background
479
+ │ │ ├── [background_1_id].json
480
+ │ │ ├── [background_2_id].json
481
+ │ │ └── [...]
482
+ │ ├── events
483
+ │ │ ├── [event_1_id].json
484
+ │ │ ├── [event_2_id].json
485
+ │ │ └── [...]
486
+ │ └── generate
487
+ │ ├── [generation_1_id]
488
+ │ │ ├── generate.json
489
+ │ │ ├── soundscape.wav
490
+ │ │ ├── soundscape.jams
491
+ │ │ └── soundscape.text
492
+ │ └── [...]
493
+ └── [timeline_2_name]
494
+ └── [...]
495
+ ```
496
+ When generating with `save_isolated_positions` set to `True`, an additional subfolder `soundscape_positions` is created in the `[generation_id]` folder. The structure is as follows:
497
+
498
+
499
+ ```
500
+ └── generate
501
+ ├── [generation_1_id]
502
+ │ ├── generate.json
503
+ │ ├── soundscape.wav - complete soundscape with all events
504
+ │ ├── ..
505
+ │ └── soundscape_positions
506
+ │ ├── [position_1].wav - soundscape with only events of position 1
507
+ │ ├── [position_1].jams - JAMS file for event position 1
508
+ │ ├── [position_2].wav - soundscape with only events of position 2
509
+ │ ├── [position_2].jams - JAMS file for event position 2
510
+ │ ├── [...]
511
+ │ └── no_position.wav - soundscape with all events that do not have an event position assigned
512
+ └── [...]
513
+ ```
514
+ You can also generate with `save_isolated_events` set to `True`. In this case, a separate audio file is created for each event in the soundscape. The audio files are stored in a subfolder `soundscape_events` within the `[generation_id]` folder.
515
+
516
+ ## Misc
517
+
518
+ ### Jams to RTTM
519
+ The file `misc/jams_to_rttm` contains a script that converts JAMS files to RTTM format. This is a format that can be used for evaluation or further processing. Example usage:
520
+
521
+ ```python
522
+ import misc.jams_to_rttm as jams2rttm
523
+
524
+ jams_path = "/path/to/input.jams"
525
+ rttm_path = "/path/to/output.rttm"
526
+ jams2rttm.jams_to_rttm(jams_path, rttm_path)
527
+ ```
528
+
529
+ ### Jams to TextGrid
530
+ The file `misc/jams_to_textgrid` contains a script that converts JAMS files to TextGrid format. This is useful for working with audio annotations in tools like Praat. Example usage:
531
+
532
+ ```python
533
+ import misc.jams_to_textgrid as jams2textgrid
534
+
535
+ jams_path = "/path/to/input.jams"
536
+ textgrid_path = "/path/to/output.textgrid"
537
+ jams2textgrid.jams_to_textgrid(jams_path, textgrid_path)
538
+ ```
539
+
540
+ You need to install mytextgrid package to use this script. You can install it using pip:
541
+
542
+ ```bash
543
+ pip install mytextgrid
544
+ ```