clustaudio 0.1.0__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.
- clustaudio-0.1.0/LICENSE +22 -0
- clustaudio-0.1.0/MANIFEST.in +2 -0
- clustaudio-0.1.0/PKG-INFO +607 -0
- clustaudio-0.1.0/README.md +549 -0
- clustaudio-0.1.0/clustaudio/__init__.py +87 -0
- clustaudio-0.1.0/clustaudio/atc_example.py +378 -0
- clustaudio-0.1.0/clustaudio/clustaudio.py +2915 -0
- clustaudio-0.1.0/clustaudio/examples.py +779 -0
- clustaudio-0.1.0/clustaudio/fingerprint.py +353 -0
- clustaudio-0.1.0/clustaudio/metadata.py +364 -0
- clustaudio-0.1.0/clustaudio/separation.py +617 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-0agmXf.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-1DTI8r.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-1ZvQqb.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-2nUNxX.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-3qIKv5.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-4BTi3A.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-4U0PXR.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-5n3Cmr.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-6ENnqU.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/atc/ACCU-6y7b3L.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/Gunshot_and_gunfire_1.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/Gunshot_and_gunfire_2.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/Gunshot_and_gunfire_3.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/Knock_2.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/Knock_3.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/Knock_4.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/Splash_and_splatter_1.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/Splash_and_splatter_2.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/Splash_and_splatter_3.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/dog_barking_1.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/dog_barking_2.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/dog_barking_3.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/drilling_1.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/drilling_2.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/drilling_3.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/siren_1.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/siren_2.wav +0 -0
- clustaudio-0.1.0/clustaudio/tests/audio/various/siren_3.wav +0 -0
- clustaudio-0.1.0/clustaudio/vad.py +380 -0
- clustaudio-0.1.0/clustaudio/visualization.py +592 -0
- clustaudio-0.1.0/clustaudio.egg-info/PKG-INFO +607 -0
- clustaudio-0.1.0/clustaudio.egg-info/SOURCES.txt +46 -0
- clustaudio-0.1.0/clustaudio.egg-info/dependency_links.txt +1 -0
- clustaudio-0.1.0/clustaudio.egg-info/requires.txt +34 -0
- clustaudio-0.1.0/clustaudio.egg-info/top_level.txt +1 -0
- clustaudio-0.1.0/pyproject.toml +105 -0
- clustaudio-0.1.0/setup.cfg +4 -0
clustaudio-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Erdogan Taskesen
|
|
4
|
+
clustaudio - Python package
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: clustaudio
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python package clustaudio is for unsupervised clustering of audio files using acoustic features, with support for denoising, voice activity detection, and audio separation.
|
|
5
|
+
Author-email: Erdogan Taskesen <erdogant@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://erdogant.github.io/clustaudio
|
|
8
|
+
Project-URL: Download, https://github.com/erdogant/clustaudio/archive/{version}.tar.gz
|
|
9
|
+
Project-URL: Documentation, https://erdogant.github.io/clustaudio
|
|
10
|
+
Keywords: clustering,audio,unsupervised learning,audio processing,voice activity detection,audio denoising,audio separation,acoustic features,mfcc,spectral features,audio fingerprinting,audio similarity,music information retrieval
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Intended Audience :: Education
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Operating System :: Unix
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Classifier: Operating System :: MacOS
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
20
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: <3.15
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: librosa>=0.10.0
|
|
26
|
+
Requires-Dist: soundfile>=0.12.0
|
|
27
|
+
Requires-Dist: scipy>=1.9.0
|
|
28
|
+
Requires-Dist: numpy<2.0.0,>=1.21.0
|
|
29
|
+
Requires-Dist: scikit-learn>=1.0.0
|
|
30
|
+
Requires-Dist: pandas>=1.3.0
|
|
31
|
+
Requires-Dist: matplotlib>=3.5.0
|
|
32
|
+
Requires-Dist: pca>=1.5.0
|
|
33
|
+
Requires-Dist: clusteval>=2.0.0
|
|
34
|
+
Requires-Dist: distfit>=1.6.0
|
|
35
|
+
Requires-Dist: scatterd>=1.3.0
|
|
36
|
+
Requires-Dist: tqdm>=4.60.0
|
|
37
|
+
Requires-Dist: datazets>=0.2.0
|
|
38
|
+
Requires-Dist: ismember>=1.0.0
|
|
39
|
+
Requires-Dist: pypickle>=0.1.0
|
|
40
|
+
Requires-Dist: geopy
|
|
41
|
+
Requires-Dist: folium
|
|
42
|
+
Requires-Dist: noisereduce>=2.0.0
|
|
43
|
+
Requires-Dist: webrtcvad>=2.0.10
|
|
44
|
+
Requires-Dist: mutagen>=1.45.0
|
|
45
|
+
Requires-Dist: tinytag>=1.9.0
|
|
46
|
+
Requires-Dist: eyed3>=0.9.6
|
|
47
|
+
Requires-Dist: pyacoustid>=1.2.0
|
|
48
|
+
Provides-Extra: dev
|
|
49
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
50
|
+
Requires-Dist: pytest-cov>=3.0.0; extra == "dev"
|
|
51
|
+
Requires-Dist: sphinx>=4.0.0; extra == "dev"
|
|
52
|
+
Requires-Dist: sphinx-rtd-theme>=1.0.0; extra == "dev"
|
|
53
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
54
|
+
Requires-Dist: flake8>=4.0.0; extra == "dev"
|
|
55
|
+
Provides-Extra: all
|
|
56
|
+
Requires-Dist: clustaudio[dev]; extra == "all"
|
|
57
|
+
Dynamic: license-file
|
|
58
|
+
|
|
59
|
+
# clustaudio
|
|
60
|
+
|
|
61
|
+
[](https://img.shields.io/pypi/pyversions/clustaudio)
|
|
62
|
+
[](https://pypi.org/project/clustaudio/)
|
|
63
|
+
[](https://erdogant.github.io/clustaudio/)
|
|
64
|
+
[](https://github.com/erdogant/clustaudio/)
|
|
65
|
+
[](https://pepy.tech/project/clustaudio)
|
|
66
|
+
[](https://pepy.tech/project/clustaudio)
|
|
67
|
+
[](https://github.com/erdogant/clustaudio/blob/master/LICENSE)
|
|
68
|
+
[](https://github.com/erdogant/clustaudio/network)
|
|
69
|
+
[](https://github.com/erdogant/clustaudio/issues)
|
|
70
|
+
[](http://www.repostatus.org/#active)
|
|
71
|
+
[](https://zenodo.org/badge/latestdoi/423822054)
|
|
72
|
+
[](https://erdogant.github.io/clustaudio/pages/html/Documentation.html#)
|
|
73
|
+
[](https://erdogant.github.io/clustaudio/pages/html/Documentation.html#colab-notebook)
|
|
74
|
+
[](https://erdogant.github.io/clustaudio/pages/html/Documentation.html#)
|
|
75
|
+
|
|
76
|
+
<div>
|
|
77
|
+
<a href="https://erdogant.github.io/clustaudio/"><img src="https://github.com/erdogant/clustaudio/blob/main/docs/figs/logo.png" width="75" align="left" /></a>
|
|
78
|
+
clustaudio is a Python library to detect natural groups or clusters of audio files. Multiple steps are pipelined where audio files are processed, acoustic features extracted, and the clusters evaluated across the feature space.
|
|
79
|
+
The optimal number of clusters is determined using methods such as *silhouette, dbindex, and derivatives* in combination with clustering methods, such as *agglomerative, kmeans, dbscan and hdbscan*.
|
|
80
|
+
clustaudio allows you to determine the most robust clustering by efficiently searching across the parameters and by evaluating the clusters.
|
|
81
|
+
Besides clustering of audio, the ``clustaudio`` library can also find the most similar audio files for a new, unseen sample, denoise noisy recordings, separate foreground from background, and extract voice segments. ⭐️Star it if you like it⭐️
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
<p align="center">
|
|
87
|
+
<img src="https://github.com/erdogant/clustaudio/blob/main/docs/figs/schematic_overview.png" width="1000" />
|
|
88
|
+
</p>
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
``clustaudio`` overcomes the following challenges:
|
|
93
|
+
|
|
94
|
+
* 1. Robustly groups similar audio files using acoustic features.
|
|
95
|
+
* 2. Returns the unique representative audio samples per cluster.
|
|
96
|
+
* 3. Finds highly similar audio files for a given input audio.
|
|
97
|
+
* 4. Denoises audio with multiple methods (spectral, wiener, noisereduce).
|
|
98
|
+
* 5. Separates foreground (voice/signal) from background (noise).
|
|
99
|
+
* 6. Extracts voice segments using Voice Activity Detection (VAD).
|
|
100
|
+
* 7. Clusters audio by metadata (artist, album, genre) when available.
|
|
101
|
+
|
|
102
|
+
``clustaudio`` is fun because:
|
|
103
|
+
|
|
104
|
+
* It does not require a learning process.
|
|
105
|
+
* It can group any set of audio files (music, speech, environmental sounds, ATC recordings).
|
|
106
|
+
* It can return only the unique() audio samples per cluster.
|
|
107
|
+
* It can find highly similar audio files given an input audio file.
|
|
108
|
+
* It provides advanced audio processing: denoising, separation, VAD.
|
|
109
|
+
* It handles noisy communications (ATC, radio) with specialized enhancement.
|
|
110
|
+
* It generates playlists and organizes files by cluster.
|
|
111
|
+
* It provides many plots (waveforms, spectrograms, scatter plots) to explore the feature-space.
|
|
112
|
+
* It is built on core audio processing (MFCC, spectral features, chroma) and robust clustering methods.
|
|
113
|
+
* It works out of the box.
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
#### [Documentation pages](https://erdogant.github.io/clustaudio/)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
### Installation
|
|
120
|
+
|
|
121
|
+
##### It is advisable to create a new environment
|
|
122
|
+
```bash
|
|
123
|
+
conda create -n env_clustaudio python=3.14
|
|
124
|
+
conda activate env_clustaudio
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
##### Install clustaudio from PyPI
|
|
128
|
+
```bash
|
|
129
|
+
pip install clustaudio # new install
|
|
130
|
+
pip install -U clustaudio # update to latest version
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
##### Directly install from GitHub source
|
|
134
|
+
```bash
|
|
135
|
+
pip install git+https://github.com/erdogant/clustaudio
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Quick Start
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from clustaudio import Clustaudio
|
|
142
|
+
|
|
143
|
+
# Initialize with MFCC features
|
|
144
|
+
cl = Clustaudio(method='mfcc', sr=22050)
|
|
145
|
+
|
|
146
|
+
paths = cl.import_example(data='various')
|
|
147
|
+
# Cluster audio files from a directory
|
|
148
|
+
results = cl.fit_transform(paths)
|
|
149
|
+
|
|
150
|
+
# Visualize clusters
|
|
151
|
+
cl.clusteval.scatter(s=250)
|
|
152
|
+
|
|
153
|
+
# Plot waveforms for each cluster
|
|
154
|
+
cl.plot(labels=[0, 1, 2], show_waveform=True)
|
|
155
|
+
|
|
156
|
+
# Find similar audio to a query
|
|
157
|
+
similar = cl.find(paths[0], k=10)
|
|
158
|
+
|
|
159
|
+
similar.keys()
|
|
160
|
+
# dict_keys(['feat', 'dog_barking_1.wav'])
|
|
161
|
+
|
|
162
|
+
# Organize files by cluster
|
|
163
|
+
cl.move_to_dir(create_playlists=True)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
<hr>
|
|
167
|
+
|
|
168
|
+
### Core Features
|
|
169
|
+
|
|
170
|
+
The results obtained from the clustaudio library is a dictionary containing the following keys:
|
|
171
|
+
|
|
172
|
+
* audio : Preprocessed audio arrays
|
|
173
|
+
* feat : Acoustic features extracted (MFCC, spectral, chroma, etc.)
|
|
174
|
+
* xycoord : X and Y coordinates from the embedding (t-SNE, UMAP)
|
|
175
|
+
* pathnames : Absolute path location to the audio files
|
|
176
|
+
* filenames : File names of the audio files
|
|
177
|
+
* labels : Cluster labels
|
|
178
|
+
* sample_rates : Sample rates of loaded audio
|
|
179
|
+
* durations : Duration of each audio file
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
### Feature Extraction Methods
|
|
183
|
+
|
|
184
|
+
clustaudio supports multiple acoustic feature extraction methods:
|
|
185
|
+
|
|
186
|
+
| Method | Description | Use Case |
|
|
187
|
+
|--------|-------------|----------|
|
|
188
|
+
| `mfcc` | Mel-Frequency Cepstral Coefficients | General audio, speech recognition |
|
|
189
|
+
| `spectral` | Spectral features (centroid, rolloff, contrast) | Timbre-based clustering |
|
|
190
|
+
| `chroma` | Chromagram features | Music, pitch-based analysis |
|
|
191
|
+
| `mfcc-spectral` | Combined MFCC + spectral | Comprehensive audio analysis |
|
|
192
|
+
| `tempogram` | Tempo and rhythm features | Music tempo analysis |
|
|
193
|
+
| `fingerprint` | Audio fingerprinting | Duplicate detection |
|
|
194
|
+
| `metadata` | ID3, Vorbis, MP4 tags | Organize by artist/album/genre |
|
|
195
|
+
|
|
196
|
+
<hr>
|
|
197
|
+
|
|
198
|
+
### Advanced Features
|
|
199
|
+
|
|
200
|
+
#### Voice Activity Detection (VAD)
|
|
201
|
+
|
|
202
|
+
Extract voice segments from audio files:
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
# Extract voice segments from a podcast
|
|
206
|
+
|
|
207
|
+
from clustaudio import Clustaudio
|
|
208
|
+
|
|
209
|
+
# Initialize with MFCC features
|
|
210
|
+
cl = Clustaudio(method='mfcc', sr=22050)
|
|
211
|
+
paths = cl.import_example(data='atc')
|
|
212
|
+
|
|
213
|
+
segments = cl.extract_voice_segments(
|
|
214
|
+
paths,
|
|
215
|
+
method='webrtcvad',
|
|
216
|
+
min_segment_duration=0.5
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Cluster the extracted voice segments
|
|
220
|
+
total_segments = [item for sublist in segments['pathnames_segments'] for item in sublist]
|
|
221
|
+
results = cl.fit_transform(total_segments)
|
|
222
|
+
|
|
223
|
+
cl.clusteval.scatter(results['xycoord'], s=200)
|
|
224
|
+
|
|
225
|
+
# Make D3Blocks chart
|
|
226
|
+
from d3blocks import D3Blocks
|
|
227
|
+
import pandas as pd
|
|
228
|
+
import numpy as np
|
|
229
|
+
from pathlib import Path
|
|
230
|
+
|
|
231
|
+
df = pd.DataFrame({
|
|
232
|
+
"labels": results["labels"],
|
|
233
|
+
"sample_rates": results["sample_rates"],
|
|
234
|
+
"durations": results["durations"],
|
|
235
|
+
"url": results["url"],
|
|
236
|
+
"directory": results["directory"],
|
|
237
|
+
"pathnames": results["pathnames"],
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
d3 = D3Blocks(chart="Scatter")
|
|
242
|
+
d3.set_node_properties(df)
|
|
243
|
+
d3.set_edge_properties(
|
|
244
|
+
x=results['xycoord'][:, 0],
|
|
245
|
+
y=results['xycoord'][:, 1],
|
|
246
|
+
size=np.minimum(results['durations'], 25),
|
|
247
|
+
tooltip=results['pathnames'],
|
|
248
|
+
opacity=0.55,
|
|
249
|
+
scale=True,
|
|
250
|
+
title="Audio t-SNE",
|
|
251
|
+
cmap="Set2",
|
|
252
|
+
)
|
|
253
|
+
d3.show()
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
#### Audio Denoising
|
|
259
|
+
|
|
260
|
+
Clean up noisy audio recordings:
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
from clustaudio import Clustaudio
|
|
264
|
+
|
|
265
|
+
# Initialize with MFCC features
|
|
266
|
+
cl = Clustaudio(method='mfcc', sr=22050)
|
|
267
|
+
paths = cl.import_example(data='atc')
|
|
268
|
+
|
|
269
|
+
# Denoise audio files
|
|
270
|
+
denoised = cl.denoise(
|
|
271
|
+
pathnames=paths,
|
|
272
|
+
method='spectral',
|
|
273
|
+
save_denoised=True
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
# Cluster denoised audio
|
|
277
|
+
results = cl.fit_transform(denoised['pathnames_denoised'])
|
|
278
|
+
cl.clusteval.scatter(results['xycoord'], s=200)
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### Foreground/Background Separation
|
|
283
|
+
|
|
284
|
+
Separate signal from noise:
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
|
|
288
|
+
# Initialize with MFCC features
|
|
289
|
+
cl = Clustaudio(method='mfcc', sr=22050)
|
|
290
|
+
paths = cl.import_example(data='atc')
|
|
291
|
+
|
|
292
|
+
# Separate foreground (voice) from background (noise)
|
|
293
|
+
separated = cl.separate_foreground_background(paths,
|
|
294
|
+
method='spectral_masking',
|
|
295
|
+
denoise=True
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
# Cluster foreground audio
|
|
299
|
+
results = cl.fit_transform(separated['pathnames_foreground'])
|
|
300
|
+
cl.clusteval.scatter(results['xycoord'], s=200)
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
#### ATC Communication Enhancement
|
|
305
|
+
|
|
306
|
+
Specialized enhancement for Air Traffic Control recordings:
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
cl = Clustaudio(method='mfcc', sr=22050)
|
|
310
|
+
paths = cl.import_example(data='atc')
|
|
311
|
+
|
|
312
|
+
# Enhance noisy ATC communications
|
|
313
|
+
enhanced = cl.enhance_atc_audio(
|
|
314
|
+
paths,
|
|
315
|
+
method='aggressive'
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
# Process and cluster
|
|
319
|
+
results = cl.fit_transform(enhanced['pathnames_enhanced'])
|
|
320
|
+
cl.clusteval.scatter(results['xycoord'], s=200)
|
|
321
|
+
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
<hr>
|
|
325
|
+
|
|
326
|
+
### Example: Music Library Organization
|
|
327
|
+
|
|
328
|
+
```python
|
|
329
|
+
from clustaudio import Clustaudio
|
|
330
|
+
|
|
331
|
+
# Initialize with combined features
|
|
332
|
+
cl = Clustaudio(method='mfcc-spectral', sr=22050)
|
|
333
|
+
paths = cl.import_example(data='various')
|
|
334
|
+
|
|
335
|
+
# Cluster your music library
|
|
336
|
+
results = cl.fit_transform(paths)
|
|
337
|
+
|
|
338
|
+
# Create playlists by cluster
|
|
339
|
+
playlists = cl.create_playlist(
|
|
340
|
+
format='m3u8',
|
|
341
|
+
savedir='/organized_music/'
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
# Visualize clusters
|
|
345
|
+
cl.clusteval.scatter(results['xycoord'], s=200)
|
|
346
|
+
cl.plot(labels=[0, 1, 2], show_waveform=True, show_spectrogram=True)
|
|
347
|
+
|
|
348
|
+
# Find similar songs
|
|
349
|
+
similar = cl.find(paths[0], k=20)
|
|
350
|
+
cl.plot_find()
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
<hr>
|
|
354
|
+
|
|
355
|
+
### Example: Podcast Speaker Identification
|
|
356
|
+
|
|
357
|
+
```python
|
|
358
|
+
from clustaudio import Clustaudio
|
|
359
|
+
|
|
360
|
+
cl = Clustaudio()
|
|
361
|
+
paths = cl.import_example(data='atc')
|
|
362
|
+
|
|
363
|
+
# Extract voice segments
|
|
364
|
+
segments = cl.extract_voice_segments(
|
|
365
|
+
paths,
|
|
366
|
+
method='webrtcvad',
|
|
367
|
+
min_segment_duration=1.0
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
# Cluster speakers
|
|
371
|
+
total_segments = [item for sublist in segments['pathnames_segments'] for item in sublist]
|
|
372
|
+
results = cl.fit_transform(total_segments)
|
|
373
|
+
|
|
374
|
+
# Each cluster represents a different speaker
|
|
375
|
+
cl.plot(labels=[0, 1], show_waveform=True)
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
<hr>
|
|
379
|
+
|
|
380
|
+
### Example: Environmental Sound Clustering
|
|
381
|
+
|
|
382
|
+
```python
|
|
383
|
+
# Initialize for environmental sounds
|
|
384
|
+
cl = Clustaudio()
|
|
385
|
+
paths = cl.import_example(data='atc')
|
|
386
|
+
|
|
387
|
+
# Denoise and cluster
|
|
388
|
+
denoised = cl.denoise(
|
|
389
|
+
paths,
|
|
390
|
+
method='noisereduce',
|
|
391
|
+
save_denoised=True
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
results = cl.fit_transform(denoised['pathnames_denoised'])
|
|
395
|
+
|
|
396
|
+
# Visualize sound clusters
|
|
397
|
+
cl.clusteval.scatter(results['xycoord'], s=200)
|
|
398
|
+
cl.plot_statistics()
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
<hr>
|
|
402
|
+
|
|
403
|
+
### Example: Duplicate Audio Detection
|
|
404
|
+
|
|
405
|
+
```python
|
|
406
|
+
# Use fingerprinting for duplicate detection
|
|
407
|
+
cl = Clustaudio(method='fingerprint')
|
|
408
|
+
paths = cl.import_example(data='atc')
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
# Find duplicates
|
|
412
|
+
results = cl.fit_transform(paths)
|
|
413
|
+
|
|
414
|
+
# Clusters with multiple files are likely duplicates/covers
|
|
415
|
+
for label in np.unique(results['labels']):
|
|
416
|
+
cluster_files = np.array(results['filenames'])[results['labels'] == label]
|
|
417
|
+
if len(cluster_files) > 1:
|
|
418
|
+
print(f"Potential duplicates: {cluster_files}")
|
|
419
|
+
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
<hr>
|
|
423
|
+
|
|
424
|
+
### Example: ATC Communication Analysis
|
|
425
|
+
|
|
426
|
+
Complete workflow for Air Traffic Control recordings:
|
|
427
|
+
|
|
428
|
+
```python
|
|
429
|
+
from clustaudio import Clustaudio
|
|
430
|
+
|
|
431
|
+
# Initialize
|
|
432
|
+
cl = Clustaudio(method='mfcc', sr=16000)
|
|
433
|
+
paths = cl.import_example(data='atc')
|
|
434
|
+
|
|
435
|
+
# Step 1: Enhance noisy ATC audio
|
|
436
|
+
enhanced = cl.enhance_atc_audio(
|
|
437
|
+
paths,
|
|
438
|
+
method='aggressive'
|
|
439
|
+
)
|
|
440
|
+
|
|
441
|
+
# Step 2: Separate foreground (voice) from background (static)
|
|
442
|
+
separated = cl.separate_foreground_background(
|
|
443
|
+
enhanced['pathnames_enhanced'],
|
|
444
|
+
method='spectral_masking',
|
|
445
|
+
denoise=True
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
# Step 3: Extract voice segments
|
|
449
|
+
segments = cl.extract_voice_segments(
|
|
450
|
+
separated['pathnames_foreground'],
|
|
451
|
+
method='energy',
|
|
452
|
+
min_segment_duration=0.5
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
# Step 4: Cluster communications
|
|
456
|
+
total_segments = [item for sublist in segments['pathnames_segments'] for item in sublist]
|
|
457
|
+
results = cl.fit_transform(
|
|
458
|
+
total_segments,
|
|
459
|
+
cluster='agglomerative',
|
|
460
|
+
evaluate='silhouette'
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
# Step 5: Visualize and analyze
|
|
464
|
+
cl.clusteval.scatter(results['xycoord'], s=200)
|
|
465
|
+
cl.plot(labels=[0, 1, 2], show_waveform=True)
|
|
466
|
+
cl.plot_statistics()
|
|
467
|
+
|
|
468
|
+
# Step 6: Organize by cluster
|
|
469
|
+
cl.move_to_dir(savedir='/organized_atc/', create_playlists=True)
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
<hr>
|
|
473
|
+
|
|
474
|
+
### Visualization Examples
|
|
475
|
+
|
|
476
|
+
##### Scatter Plot with Cluster Labels
|
|
477
|
+
|
|
478
|
+
```python
|
|
479
|
+
# Create scatter plot
|
|
480
|
+
from scatterd import scatterd
|
|
481
|
+
|
|
482
|
+
cl.clusteval.plot()
|
|
483
|
+
cl.clusteval.plot_silhouette(results['xycoord'])
|
|
484
|
+
cl.clusteval.scatter(results['xycoord'], s=250)
|
|
485
|
+
cl.clusteval.dendrogram()
|
|
486
|
+
scatterd(results['xycoord'][:, 0], results['xycoord'][:, 1], density=False, labels=results['labels'])
|
|
487
|
+
#cl.pca.scatter3d(labels=results['labels'])
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
##### Waveform Visualization per Cluster
|
|
493
|
+
|
|
494
|
+
```python
|
|
495
|
+
# Plot waveforms for specific clusters
|
|
496
|
+
cl.plot(labels=[0, 1, 2], show_waveform=True, max_per_cluster=4)
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
##### Spectrogram Visualization
|
|
500
|
+
|
|
501
|
+
```python
|
|
502
|
+
# Plot spectrograms
|
|
503
|
+
cl.plot(labels=[0, 1], show_spectrogram=True)
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
##### Denoising Comparison
|
|
507
|
+
|
|
508
|
+
```python
|
|
509
|
+
# Compare before/after denoising
|
|
510
|
+
cl.denoise(paths[0])
|
|
511
|
+
cl.plot_denoise(index=0)
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
##### Separation Results
|
|
515
|
+
|
|
516
|
+
```python
|
|
517
|
+
# Visualize foreground/background separation
|
|
518
|
+
cl.separate_foreground_background(paths[0])
|
|
519
|
+
cl.plot_separation(index=0, figsize=(15, 20))
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
##### Cluster Statistics
|
|
523
|
+
|
|
524
|
+
```python
|
|
525
|
+
# Comprehensive cluster statistics
|
|
526
|
+
cl.plot_statistics()
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
<hr>
|
|
530
|
+
|
|
531
|
+
### Supported Audio Formats
|
|
532
|
+
|
|
533
|
+
clustaudio supports all formats handled by librosa and soundfile:
|
|
534
|
+
|
|
535
|
+
- **WAV** - Uncompressed (fastest loading)
|
|
536
|
+
- **MP3** - Compressed (most common)
|
|
537
|
+
- **FLAC** - Lossless compression
|
|
538
|
+
- **OGG** - Vorbis compressed
|
|
539
|
+
- **M4A** - AAC compressed
|
|
540
|
+
- **AAC** - Advanced Audio Coding
|
|
541
|
+
|
|
542
|
+
<hr>
|
|
543
|
+
|
|
544
|
+
### Documentation
|
|
545
|
+
|
|
546
|
+
Detailed documentation with many examples:
|
|
547
|
+
|
|
548
|
+
##### [Example: Music Library Clustering](https://erdogant.github.io/clustaudio/pages/html/Examples.html#music-library)
|
|
549
|
+
|
|
550
|
+
##### [Example: Podcast Speaker Clustering](https://erdogant.github.io/clustaudio/pages/html/Examples.html#podcast-speakers)
|
|
551
|
+
|
|
552
|
+
##### [Example: ATC Communication Processing](https://erdogant.github.io/clustaudio/pages/html/Examples.html#atc-communications)
|
|
553
|
+
|
|
554
|
+
##### [Example: Environmental Sound Analysis](https://erdogant.github.io/clustaudio/pages/html/Examples.html#environmental-sounds)
|
|
555
|
+
|
|
556
|
+
##### [Example: Find Similar Audio](https://erdogant.github.io/clustaudio/pages/html/Examples.html#find-similar)
|
|
557
|
+
|
|
558
|
+
##### [Example: Break Up the Steps](https://erdogant.github.io/clustaudio/pages/html/Examples.html#breaking-up-steps)
|
|
559
|
+
|
|
560
|
+
<hr>
|
|
561
|
+
|
|
562
|
+
### Feature Comparison
|
|
563
|
+
|
|
564
|
+
| Feature | clustimage (Images) | clustaudio (Audio) |
|
|
565
|
+
|---------|--------------------|--------------------|
|
|
566
|
+
| Core Feature | PCA, HOG | MFCC, Spectral |
|
|
567
|
+
| Duplicate Detection | Perceptual hash | Audio fingerprinting |
|
|
568
|
+
| Metadata | EXIF (datetime, location) | ID3, Vorbis (artist, album, genre) |
|
|
569
|
+
| Advanced Processing | Face detection | VAD, Denoising, Separation |
|
|
570
|
+
| Unique Detection | ✅ | ✅ |
|
|
571
|
+
| Similarity Search | ✅ | ✅ |
|
|
572
|
+
| Clustering | ✅ | ✅ |
|
|
573
|
+
| Visualization | Image grids | Waveforms, Spectrograms |
|
|
574
|
+
|
|
575
|
+
<hr>
|
|
576
|
+
|
|
577
|
+
### Citation
|
|
578
|
+
|
|
579
|
+
Please cite ``clustaudio`` if you use it in your research or project:
|
|
580
|
+
|
|
581
|
+
```bibtex
|
|
582
|
+
@software{clustaudio,
|
|
583
|
+
author = {Taskesen, Erdogan},
|
|
584
|
+
title = {clustaudio - Python library for clustering audio files},
|
|
585
|
+
year = {2024},
|
|
586
|
+
url = {https://github.com/erdogant/clustaudio},
|
|
587
|
+
}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
<hr>
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
### Contributors
|
|
594
|
+
Thank the contributors!
|
|
595
|
+
|
|
596
|
+
<p align="left">
|
|
597
|
+
<a href="https://github.com/erdogant/clustaudio/graphs/contributors">
|
|
598
|
+
<img src="https://contrib.rocks/image?repo=erdogant/clustaudio" />
|
|
599
|
+
</a>
|
|
600
|
+
</p>
|
|
601
|
+
|
|
602
|
+
### Maintainer
|
|
603
|
+
* Erdogan Taskesen, GitHub: [erdogant](https://github.com/erdogant)
|
|
604
|
+
* Contributions are welcome.
|
|
605
|
+
* Yes! This library is entirely **free**, but it runs on coffee! :) Feel free to support with a <a href="https://erdogant.github.io/donate/?currency=USD&amount=5">Coffee</a>.
|
|
606
|
+
|
|
607
|
+
[](https://www.buymeacoffee.com/erdogant)
|