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 +27 -0
- dscaper-1.7.2/PKG-INFO +544 -0
- dscaper-1.7.2/README.md +503 -0
- dscaper-1.7.2/dscaper/__init__.py +15 -0
- dscaper-1.7.2/dscaper/audio.py +138 -0
- dscaper-1.7.2/dscaper/core.py +2662 -0
- dscaper-1.7.2/dscaper/dscaper.py +746 -0
- dscaper-1.7.2/dscaper/dscaper_datatypes.py +82 -0
- dscaper-1.7.2/dscaper/scaper_exceptions.py +11 -0
- dscaper-1.7.2/dscaper/scaper_warnings.py +11 -0
- dscaper-1.7.2/dscaper/util.py +511 -0
- dscaper-1.7.2/dscaper/version.py +6 -0
- dscaper-1.7.2/dscaper.egg-info/PKG-INFO +544 -0
- dscaper-1.7.2/dscaper.egg-info/SOURCES.txt +23 -0
- dscaper-1.7.2/dscaper.egg-info/dependency_links.txt +1 -0
- dscaper-1.7.2/dscaper.egg-info/requires.txt +17 -0
- dscaper-1.7.2/dscaper.egg-info/top_level.txt +1 -0
- dscaper-1.7.2/pyproject.toml +64 -0
- dscaper-1.7.2/setup.cfg +13 -0
- dscaper-1.7.2/setup.py +55 -0
- dscaper-1.7.2/tests/test_audio.py +171 -0
- dscaper-1.7.2/tests/test_core.py +2620 -0
- dscaper-1.7.2/tests/test_dscaper.py +545 -0
- dscaper-1.7.2/tests/test_util.py +372 -0
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
|
+

|
|
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
|
+

|
|
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
|
+
```
|