initial commit
Browse files- .gitignore +15 -0
- README.md +52 -12
- Retraining Pipeline/collect_valid_samples.ipynb +0 -0
- Retraining Pipeline/retrain.ipynb +102 -0
- Retraining Pipeline/sample_collection.ipynb +332 -0
- change_song.py +273 -0
- exp.ipynb +224 -0
- generation_utilities.py +201 -0
- requirements.txt +10 -0
- ui/app.py +55 -0
- ui/pages/rating.py +25 -0
.gitignore
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
DataSet/
|
2 |
+
**/Data Processing/pretrained_models
|
3 |
+
.ipynb_checkpoints
|
4 |
+
**/Data Processing/.ipynb_checkpoints
|
5 |
+
node_modules/
|
6 |
+
Retraining Pipeline/models
|
7 |
+
Retraining Pipeline/audio-diffusion
|
8 |
+
Enhancement/
|
9 |
+
ui/*.wav
|
10 |
+
ui/*.npy
|
11 |
+
|
12 |
+
input_songs/
|
13 |
+
uploads/
|
14 |
+
audio/
|
15 |
+
__pycache__/
|
README.md
CHANGED
@@ -1,12 +1,52 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Orpheus_ai- User Study
|
2 |
+
|
3 |
+
## Introduction
|
4 |
+
|
5 |
+
This repository hosts the code for conducting the user study for Orpheus_ai, a system designed for music generation. The user study aims to assess the efficacy of Orpheus_ai in creating music compositions.
|
6 |
+
|
7 |
+
## Requirements
|
8 |
+
|
9 |
+
Before initiating the user study, ensure the following prerequisites are met:
|
10 |
+
|
11 |
+
1. **Install Required Packages:**
|
12 |
+
|
13 |
+
Set up a virtual environment and install the necessary packages using the provided `requirements.txt` file:
|
14 |
+
```
|
15 |
+
pip install -r requirements.txt
|
16 |
+
```
|
17 |
+
|
18 |
+
Alternatively, if you opt not to use a virtual environment, manually install the required versions of `diffusers` and `audiodiffusion` packages:
|
19 |
+
```
|
20 |
+
pip install diffusers==0.17.1 audiodiffusion==1.5.6
|
21 |
+
```
|
22 |
+
|
23 |
+
Note: Ensure compatibility between the installed Torch version and the CUDA version on your system since a GPU is necessary for running the code.
|
24 |
+
|
25 |
+
2. **Create Folders for Data Storage:**
|
26 |
+
|
27 |
+
Create the following directory structure within the root directory for storing songs and spectrograms:
|
28 |
+
```
|
29 |
+
DataSet
|
30 |
+
├───Song
|
31 |
+
├───Spec
|
32 |
+
```
|
33 |
+
|
34 |
+
## Usage
|
35 |
+
|
36 |
+
To execute the user study and generate songs along with spectrograms, follow these steps:
|
37 |
+
|
38 |
+
1. Navigate to the `ui` directory:
|
39 |
+
```
|
40 |
+
cd ui
|
41 |
+
```
|
42 |
+
|
43 |
+
2. Launch the user study interface using Streamlit:
|
44 |
+
```
|
45 |
+
streamlit run main.py
|
46 |
+
```
|
47 |
+
|
48 |
+
Note: It's advisable to select only one song from the provided list during the initial phase. After generating the song and submitting the ratings, the resulting song and spectrogram will be saved in the respective folders. The files follow the naming convention:
|
49 |
+
```
|
50 |
+
<model_name>_<song_name>_<similarity>_<rating>.wav
|
51 |
+
<model_name>_<song_name>_<similarity>_<rating>.npy
|
52 |
+
```
|
Retraining Pipeline/collect_valid_samples.ipynb
ADDED
The diff for this file is too large to render.
See raw diff
|
|
Retraining Pipeline/retrain.ipynb
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 2,
|
6 |
+
"metadata": {},
|
7 |
+
"outputs": [
|
8 |
+
{
|
9 |
+
"name": "stderr",
|
10 |
+
"output_type": "stream",
|
11 |
+
"text": [
|
12 |
+
"Cloning into 'audio-diffusion'...\n"
|
13 |
+
]
|
14 |
+
}
|
15 |
+
],
|
16 |
+
"source": [
|
17 |
+
"!git clone https://github.com/teticio/audio-diffusion\n"
|
18 |
+
]
|
19 |
+
},
|
20 |
+
{
|
21 |
+
"cell_type": "markdown",
|
22 |
+
"metadata": {},
|
23 |
+
"source": [
|
24 |
+
"### Creating Dataset"
|
25 |
+
]
|
26 |
+
},
|
27 |
+
{
|
28 |
+
"cell_type": "code",
|
29 |
+
"execution_count": null,
|
30 |
+
"metadata": {},
|
31 |
+
"outputs": [],
|
32 |
+
"source": [
|
33 |
+
"python audio-diffusion/scripts/audio_to_images.py --resolution 256 --input_dir D:/Projects/Orpheus_ai/DataSet/Generated_music_withratings/training_samples/ --output_dir D:/Projects/Orpheus_ai/DataSet/Generated_music_withratings/train/ --push_to_hub SAint7579/orpheus_samples"
|
34 |
+
]
|
35 |
+
},
|
36 |
+
{
|
37 |
+
"cell_type": "markdown",
|
38 |
+
"metadata": {},
|
39 |
+
"source": [
|
40 |
+
"### Retraining the model"
|
41 |
+
]
|
42 |
+
},
|
43 |
+
{
|
44 |
+
"cell_type": "code",
|
45 |
+
"execution_count": 23,
|
46 |
+
"metadata": {},
|
47 |
+
"outputs": [
|
48 |
+
{
|
49 |
+
"ename": "SyntaxError",
|
50 |
+
"evalue": "invalid syntax (<ipython-input-23-e665de61672a>, line 1)",
|
51 |
+
"output_type": "error",
|
52 |
+
"traceback": [
|
53 |
+
"\u001b[1;36m File \u001b[1;32m\"<ipython-input-23-e665de61672a>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m accelerate launch --config_file audio-diffusion/config/accelerate_local.yaml audio-diffusion/scripts/train_unet.py --dataset_name SAint7579/orpheus_samples --output_dir models/v1-0 --num_epochs 10 --train_batch_size 2 --eval_batch_size 2 --gradient_accumulation_steps 8 --learning_rate 1e-4 --mixed_precision no --push_to_hub True --hub_model_id SAint7579/orpheus_ldm_model_v1-0\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
|
54 |
+
]
|
55 |
+
}
|
56 |
+
],
|
57 |
+
"source": [
|
58 |
+
"accelerate launch --config_file audio-diffusion/config/accelerate_local.yaml audio-diffusion/scripts/train_unet.py --dataset_name SAint7579/orpheus_samples --output_dir models/v1-0 --num_epochs 1 --train_batch_size 2 --eval_batch_size 2 --gradient_accumulation_steps 8 --learning_rate 1e-4 --mixed_precision no --push_to_hub True --hub_model_id SAint7579/orpheus_ldm_model_v1-0 --vae teticio/latent-audio-diffusion-256 --from_pretrained teticio/latent-audio-diffusion-256"
|
59 |
+
]
|
60 |
+
},
|
61 |
+
{
|
62 |
+
"cell_type": "code",
|
63 |
+
"execution_count": null,
|
64 |
+
"metadata": {},
|
65 |
+
"outputs": [],
|
66 |
+
"source": [
|
67 |
+
"--num_epochs 100 \\\n",
|
68 |
+
"--train_batch_size 2 \\\n",
|
69 |
+
"--eval_batch_size 2 \\\n",
|
70 |
+
"--gradient_accumulation_steps 8 \\\n",
|
71 |
+
"--learning_rate 1e-4 \\\n",
|
72 |
+
"--lr_warmup_steps 500 \\\n",
|
73 |
+
"--mixed_precision no \\\n",
|
74 |
+
"--push_to_hub True \\\n",
|
75 |
+
"--hub_model_id audio-diffusion-256 \\\n",
|
76 |
+
"--hub_token $(cat $HOME/.huggingface/token)"
|
77 |
+
]
|
78 |
+
}
|
79 |
+
],
|
80 |
+
"metadata": {
|
81 |
+
"kernelspec": {
|
82 |
+
"display_name": "base",
|
83 |
+
"language": "python",
|
84 |
+
"name": "python3"
|
85 |
+
},
|
86 |
+
"language_info": {
|
87 |
+
"codemirror_mode": {
|
88 |
+
"name": "ipython",
|
89 |
+
"version": 3
|
90 |
+
},
|
91 |
+
"file_extension": ".py",
|
92 |
+
"mimetype": "text/x-python",
|
93 |
+
"name": "python",
|
94 |
+
"nbconvert_exporter": "python",
|
95 |
+
"pygments_lexer": "ipython3",
|
96 |
+
"version": "3.8.8"
|
97 |
+
},
|
98 |
+
"orig_nbformat": 4
|
99 |
+
},
|
100 |
+
"nbformat": 4,
|
101 |
+
"nbformat_minor": 2
|
102 |
+
}
|
Retraining Pipeline/sample_collection.ipynb
ADDED
@@ -0,0 +1,332 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 1,
|
6 |
+
"metadata": {},
|
7 |
+
"outputs": [],
|
8 |
+
"source": [
|
9 |
+
"import sys\n",
|
10 |
+
"sys.path.append('../')"
|
11 |
+
]
|
12 |
+
},
|
13 |
+
{
|
14 |
+
"cell_type": "code",
|
15 |
+
"execution_count": 3,
|
16 |
+
"metadata": {},
|
17 |
+
"outputs": [
|
18 |
+
{
|
19 |
+
"name": "stderr",
|
20 |
+
"output_type": "stream",
|
21 |
+
"text": [
|
22 |
+
"unet\\diffusion_pytorch_model.safetensors not found\n",
|
23 |
+
"unet\\diffusion_pytorch_model.safetensors not found\n"
|
24 |
+
]
|
25 |
+
}
|
26 |
+
],
|
27 |
+
"source": [
|
28 |
+
"import generation_utilities\n",
|
29 |
+
"import numpy as np\n",
|
30 |
+
"import librosa\n",
|
31 |
+
"from glob import glob\n",
|
32 |
+
"import random\n",
|
33 |
+
"import IPython.display as ipd\n",
|
34 |
+
"import soundfile as sf\n",
|
35 |
+
"import importlib\n",
|
36 |
+
"import ipywidgets as widgets\n",
|
37 |
+
"import numpy as np\n",
|
38 |
+
"importlib.reload(generation_utilities)\n",
|
39 |
+
"import os\n",
|
40 |
+
"os.environ[\"KMP_DUPLICATE_LIB_OK\"]=\"TRUE\""
|
41 |
+
]
|
42 |
+
},
|
43 |
+
{
|
44 |
+
"cell_type": "code",
|
45 |
+
"execution_count": 6,
|
46 |
+
"metadata": {},
|
47 |
+
"outputs": [
|
48 |
+
{
|
49 |
+
"data": {
|
50 |
+
"text/plain": [
|
51 |
+
"{'22': '../input_songs\\\\22.mp3',\n",
|
52 |
+
" 'Anti-Hero': '../input_songs\\\\Anti-Hero.mp3',\n",
|
53 |
+
" 'Back-To-December': '../input_songs\\\\Back-To-December.mp3',\n",
|
54 |
+
" 'Blank-Space': '../input_songs\\\\Blank-Space.mp3',\n",
|
55 |
+
" 'Cardigan': '../input_songs\\\\Cardigan.mp3',\n",
|
56 |
+
" 'Delicate': '../input_songs\\\\Delicate.mp3',\n",
|
57 |
+
" 'Love-Story': '../input_songs\\\\Love-Story.mp3',\n",
|
58 |
+
" 'Lover': '../input_songs\\\\Lover.mp3',\n",
|
59 |
+
" 'uploaded_song': '../input_songs\\\\uploaded_song.mp3',\n",
|
60 |
+
" 'Willow': '../input_songs\\\\Willow.mp3',\n",
|
61 |
+
" 'You-Belong-With-Me': '../input_songs\\\\You-Belong-With-Me.mp3'}"
|
62 |
+
]
|
63 |
+
},
|
64 |
+
"execution_count": 6,
|
65 |
+
"metadata": {},
|
66 |
+
"output_type": "execute_result"
|
67 |
+
}
|
68 |
+
],
|
69 |
+
"source": [
|
70 |
+
"music = glob(\"../input_songs/*.mp3\")\n",
|
71 |
+
"\n",
|
72 |
+
"## Create music dictionary with keys as song names and values as path\n",
|
73 |
+
"music_dict = {}\n",
|
74 |
+
"for song in music:\n",
|
75 |
+
" song_name = song.split(\"\\\\\")[-1].split(\".\")[0]\n",
|
76 |
+
" music_dict[song_name] = song\n",
|
77 |
+
"\n",
|
78 |
+
"music_dict"
|
79 |
+
]
|
80 |
+
},
|
81 |
+
{
|
82 |
+
"cell_type": "code",
|
83 |
+
"execution_count": 8,
|
84 |
+
"metadata": {},
|
85 |
+
"outputs": [],
|
86 |
+
"source": [
|
87 |
+
"def load_songs_as_numpy_array(song_dict):\n",
|
88 |
+
" song_names = list(song_dict.keys())\n",
|
89 |
+
" song_paths = list(song_dict.values())\n",
|
90 |
+
"\n",
|
91 |
+
" song_selector = widgets.SelectMultiple(\n",
|
92 |
+
" options=song_names,\n",
|
93 |
+
" description='Select songs:',\n",
|
94 |
+
" rows=len(song_names),\n",
|
95 |
+
" layout=widgets.Layout(width='400px')\n",
|
96 |
+
" )\n",
|
97 |
+
"\n",
|
98 |
+
" ## Add a slider between 0 and 1 to select the similarity\n",
|
99 |
+
" similarity_slider = widgets.FloatSlider(\n",
|
100 |
+
" value=0.75,\n",
|
101 |
+
" min=0,\n",
|
102 |
+
" max=1.0,\n",
|
103 |
+
" step=0.05,\n",
|
104 |
+
" description='Similarity:',\n",
|
105 |
+
" disabled=False,\n",
|
106 |
+
" continuous_update=False,\n",
|
107 |
+
" orientation='horizontal',\n",
|
108 |
+
" readout=True,\n",
|
109 |
+
" readout_format='.2f',\n",
|
110 |
+
" )\n",
|
111 |
+
"\n",
|
112 |
+
"\n",
|
113 |
+
" select_button = widgets.Button(description='Select')\n",
|
114 |
+
" output = widgets.Output()\n",
|
115 |
+
"\n",
|
116 |
+
" def on_select_button_clicked(_):\n",
|
117 |
+
" selected_songs = [librosa.load(song_paths[i], sr=22050)[0] for i in song_selector.index] \n",
|
118 |
+
" name = '+'.join([song_names[i] for i in song_selector.index])\n",
|
119 |
+
"\n",
|
120 |
+
" with output:\n",
|
121 |
+
" output.clear_output()\n",
|
122 |
+
" print(f'Selected songs: {name}')\n",
|
123 |
+
" ## Get similarity from the slider\n",
|
124 |
+
" similarity = similarity_slider.value\n",
|
125 |
+
" spec, song = generation_utilities.generate_songs(selected_songs, similarity=similarity, quality=500, merging_quality=100, device='cuda')\n",
|
126 |
+
"\n",
|
127 |
+
" ## Play all the selected songs\n",
|
128 |
+
" print(\"Selected songs: \")\n",
|
129 |
+
" for s in selected_songs:\n",
|
130 |
+
" ipd.display(ipd.Audio(s, rate=22050))\n",
|
131 |
+
"\n",
|
132 |
+
" # Play song\n",
|
133 |
+
" print(\"\\n\\nGenerated song: \")\n",
|
134 |
+
" ipd.display(ipd.Audio(song, rate=22050))\n",
|
135 |
+
"\n",
|
136 |
+
" ## Get a rating from the user with ipywidgets\n",
|
137 |
+
" rating = widgets.Text(\n",
|
138 |
+
" value='',\n",
|
139 |
+
" placeholder='Type something',\n",
|
140 |
+
" description='Rating:',\n",
|
141 |
+
" disabled=False\n",
|
142 |
+
" )\n",
|
143 |
+
" display(rating)\n",
|
144 |
+
" ## Make a submit button\n",
|
145 |
+
" submit_button = widgets.Button(description='Submit')\n",
|
146 |
+
" display(submit_button)\n",
|
147 |
+
"\n",
|
148 |
+
" def on_submit_button_clicked(_):\n",
|
149 |
+
" ## Convert rating to float\n",
|
150 |
+
" rating_value = float(rating.value)\n",
|
151 |
+
"\n",
|
152 |
+
" ## Save the song\n",
|
153 |
+
" total_files = glob('../DataSet/Song/*')\n",
|
154 |
+
" sf.write(f'../DataSet/Song/{len(total_files)}_{name}_{similarity}_{rating_value}.wav', song, 22050, 'PCM_24')\n",
|
155 |
+
"\n",
|
156 |
+
" ## Save the spectrogram\n",
|
157 |
+
" total_files = glob('../DataSet/Spec/*')\n",
|
158 |
+
" np.save(f'../DataSet/Spec/{len(total_files)}_{name}_{similarity}_{rating_value}.npy', spec)\n",
|
159 |
+
"\n",
|
160 |
+
" with output:\n",
|
161 |
+
" output.clear_output()\n",
|
162 |
+
" print(\"Saved\")\n",
|
163 |
+
"\n",
|
164 |
+
"\n",
|
165 |
+
" submit_button.on_click(on_submit_button_clicked)\n",
|
166 |
+
" \n",
|
167 |
+
" select_button.on_click(on_select_button_clicked)\n",
|
168 |
+
"\n",
|
169 |
+
" display(song_selector)\n",
|
170 |
+
" display(select_button)\n",
|
171 |
+
" display(similarity_slider)\n",
|
172 |
+
" display(output)\n",
|
173 |
+
"\n",
|
174 |
+
"\n",
|
175 |
+
" # return selected_songs, name\n"
|
176 |
+
]
|
177 |
+
},
|
178 |
+
{
|
179 |
+
"cell_type": "code",
|
180 |
+
"execution_count": 9,
|
181 |
+
"metadata": {},
|
182 |
+
"outputs": [
|
183 |
+
{
|
184 |
+
"data": {
|
185 |
+
"application/vnd.jupyter.widget-view+json": {
|
186 |
+
"model_id": "c2beb314b7784af097f04ad2bfd70046",
|
187 |
+
"version_major": 2,
|
188 |
+
"version_minor": 0
|
189 |
+
},
|
190 |
+
"text/plain": [
|
191 |
+
"SelectMultiple(description='Select songs:', layout=Layout(width='400px'), options=('22', 'Anti-Hero', 'Back-To…"
|
192 |
+
]
|
193 |
+
},
|
194 |
+
"metadata": {},
|
195 |
+
"output_type": "display_data"
|
196 |
+
},
|
197 |
+
{
|
198 |
+
"data": {
|
199 |
+
"application/vnd.jupyter.widget-view+json": {
|
200 |
+
"model_id": "2edb699552dd4196bec2683395fc0f11",
|
201 |
+
"version_major": 2,
|
202 |
+
"version_minor": 0
|
203 |
+
},
|
204 |
+
"text/plain": [
|
205 |
+
"Button(description='Select', style=ButtonStyle())"
|
206 |
+
]
|
207 |
+
},
|
208 |
+
"metadata": {},
|
209 |
+
"output_type": "display_data"
|
210 |
+
},
|
211 |
+
{
|
212 |
+
"data": {
|
213 |
+
"application/vnd.jupyter.widget-view+json": {
|
214 |
+
"model_id": "80b12515c92242ffa9483eb3982464a2",
|
215 |
+
"version_major": 2,
|
216 |
+
"version_minor": 0
|
217 |
+
},
|
218 |
+
"text/plain": [
|
219 |
+
"FloatSlider(value=0.75, continuous_update=False, description='Similarity:', max=1.0, step=0.05)"
|
220 |
+
]
|
221 |
+
},
|
222 |
+
"metadata": {},
|
223 |
+
"output_type": "display_data"
|
224 |
+
},
|
225 |
+
{
|
226 |
+
"data": {
|
227 |
+
"application/vnd.jupyter.widget-view+json": {
|
228 |
+
"model_id": "ef000bfed4b94491931224b0cb0ce823",
|
229 |
+
"version_major": 2,
|
230 |
+
"version_minor": 0
|
231 |
+
},
|
232 |
+
"text/plain": [
|
233 |
+
"Output()"
|
234 |
+
]
|
235 |
+
},
|
236 |
+
"metadata": {},
|
237 |
+
"output_type": "display_data"
|
238 |
+
}
|
239 |
+
],
|
240 |
+
"source": [
|
241 |
+
"load_songs_as_numpy_array(music_dict)"
|
242 |
+
]
|
243 |
+
},
|
244 |
+
{
|
245 |
+
"cell_type": "code",
|
246 |
+
"execution_count": 4,
|
247 |
+
"metadata": {},
|
248 |
+
"outputs": [],
|
249 |
+
"source": [
|
250 |
+
"import os\n",
|
251 |
+
"os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'"
|
252 |
+
]
|
253 |
+
},
|
254 |
+
{
|
255 |
+
"cell_type": "code",
|
256 |
+
"execution_count": 5,
|
257 |
+
"metadata": {},
|
258 |
+
"outputs": [
|
259 |
+
{
|
260 |
+
"name": "stdout",
|
261 |
+
"output_type": "stream",
|
262 |
+
"text": [
|
263 |
+
"Merging songs...\n",
|
264 |
+
"Generating song...\n"
|
265 |
+
]
|
266 |
+
},
|
267 |
+
{
|
268 |
+
"data": {
|
269 |
+
"application/vnd.jupyter.widget-view+json": {
|
270 |
+
"model_id": "7ea21aa7cb7249d4ba35c63506cf0031",
|
271 |
+
"version_major": 2,
|
272 |
+
"version_minor": 0
|
273 |
+
},
|
274 |
+
"text/plain": [
|
275 |
+
" 0%| | 0/100 [00:00<?, ?it/s]"
|
276 |
+
]
|
277 |
+
},
|
278 |
+
"metadata": {},
|
279 |
+
"output_type": "display_data"
|
280 |
+
},
|
281 |
+
{
|
282 |
+
"data": {
|
283 |
+
"text/plain": [
|
284 |
+
"(<PIL.Image.Image image mode=L size=256x256>,\n",
|
285 |
+
" array([-2.02207055e-04, -9.85335573e-05, -1.04858875e-04, ...,\n",
|
286 |
+
" -2.07161275e-03, -6.43183384e-03, -6.42244611e-03], dtype=float32))"
|
287 |
+
]
|
288 |
+
},
|
289 |
+
"execution_count": 5,
|
290 |
+
"metadata": {},
|
291 |
+
"output_type": "execute_result"
|
292 |
+
}
|
293 |
+
],
|
294 |
+
"source": [
|
295 |
+
"generation_utilities.generate_songs([librosa.load(music_dict[\"22\"], sr=22050)[0]] ,)"
|
296 |
+
]
|
297 |
+
},
|
298 |
+
{
|
299 |
+
"cell_type": "code",
|
300 |
+
"execution_count": 14,
|
301 |
+
"metadata": {},
|
302 |
+
"outputs": [],
|
303 |
+
"source": [
|
304 |
+
"from streamlit_extras.switch_page_button import switch_page\n",
|
305 |
+
"\n",
|
306 |
+
"switch_page(\"New page name\")"
|
307 |
+
]
|
308 |
+
}
|
309 |
+
],
|
310 |
+
"metadata": {
|
311 |
+
"kernelspec": {
|
312 |
+
"display_name": "base",
|
313 |
+
"language": "python",
|
314 |
+
"name": "python3"
|
315 |
+
},
|
316 |
+
"language_info": {
|
317 |
+
"codemirror_mode": {
|
318 |
+
"name": "ipython",
|
319 |
+
"version": 3
|
320 |
+
},
|
321 |
+
"file_extension": ".py",
|
322 |
+
"mimetype": "text/x-python",
|
323 |
+
"name": "python",
|
324 |
+
"nbconvert_exporter": "python",
|
325 |
+
"pygments_lexer": "ipython3",
|
326 |
+
"version": "3.11.4"
|
327 |
+
},
|
328 |
+
"orig_nbformat": 4
|
329 |
+
},
|
330 |
+
"nbformat": 4,
|
331 |
+
"nbformat_minor": 2
|
332 |
+
}
|
change_song.py
ADDED
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import warnings
|
2 |
+
import psycopg2
|
3 |
+
from io import BytesIO
|
4 |
+
from diffusers.configuration_utils import ConfigMixin, register_to_config
|
5 |
+
from diffusers.schedulers.scheduling_utils import SchedulerMixin
|
6 |
+
from scipy.io import wavfile
|
7 |
+
import soundfile as sf
|
8 |
+
import os
|
9 |
+
warnings.filterwarnings("ignore")
|
10 |
+
import sys
|
11 |
+
from generation_utilities import *
|
12 |
+
|
13 |
+
import numpy as np # noqa: E402
|
14 |
+
from PIL import Image # noqa: E402
|
15 |
+
|
16 |
+
import shutil
|
17 |
+
import torch
|
18 |
+
from IPython.display import Audio
|
19 |
+
from audiodiffusion import AudioDiffusion, AudioDiffusionPipeline
|
20 |
+
from audiodiffusion.audio_encoder import AudioEncoder
|
21 |
+
import librosa
|
22 |
+
import librosa.display
|
23 |
+
|
24 |
+
import IPython.display as ipd
|
25 |
+
|
26 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
27 |
+
|
28 |
+
# audio_diffusion = AudioDiffusionPipeline.from_pretrained("teticio/latent-audio-diffusion-256").to(device)
|
29 |
+
audio_diffusion = AudioDiffusionPipeline.from_pretrained("SAint7579/orpheus_ldm_model_v1-0").to(device)
|
30 |
+
ddim = AudioDiffusionPipeline.from_pretrained("teticio/audio-diffusion-ddim-256").to(device)
|
31 |
+
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
|
36 |
+
try:
|
37 |
+
import librosa # noqa: E402
|
38 |
+
|
39 |
+
_librosa_can_be_imported = True
|
40 |
+
_import_error = ""
|
41 |
+
except Exception as e:
|
42 |
+
_librosa_can_be_imported = False
|
43 |
+
_import_error = (
|
44 |
+
f"Cannot import librosa because {e}. Make sure to correctly install librosa to be able to install it."
|
45 |
+
)
|
46 |
+
|
47 |
+
|
48 |
+
class Mel(ConfigMixin, SchedulerMixin):
|
49 |
+
"""
|
50 |
+
Parameters:
|
51 |
+
x_res (`int`): x resolution of spectrogram (time)
|
52 |
+
y_res (`int`): y resolution of spectrogram (frequency bins)
|
53 |
+
sample_rate (`int`): sample rate of audio
|
54 |
+
n_fft (`int`): number of Fast Fourier Transforms
|
55 |
+
hop_length (`int`): hop length (a higher number is recommended for lower than 256 y_res)
|
56 |
+
top_db (`int`): loudest in decibels
|
57 |
+
n_iter (`int`): number of iterations for Griffin Linn mel inversion
|
58 |
+
"""
|
59 |
+
|
60 |
+
config_name = "mel_config.json"
|
61 |
+
|
62 |
+
@register_to_config
|
63 |
+
def __init__(
|
64 |
+
self,
|
65 |
+
x_res: int = 256,
|
66 |
+
y_res: int = 256,
|
67 |
+
sample_rate: int = 22050,
|
68 |
+
n_fft: int = 2048,
|
69 |
+
hop_length: int = 512,
|
70 |
+
top_db: int = 80,
|
71 |
+
n_iter: int = 32,
|
72 |
+
):
|
73 |
+
self.hop_length = hop_length
|
74 |
+
self.sr = sample_rate
|
75 |
+
self.n_fft = n_fft
|
76 |
+
self.top_db = top_db
|
77 |
+
self.n_iter = n_iter
|
78 |
+
self.set_resolution(x_res, y_res)
|
79 |
+
self.audio = None
|
80 |
+
|
81 |
+
if not _librosa_can_be_imported:
|
82 |
+
raise ValueError(_import_error)
|
83 |
+
|
84 |
+
def set_resolution(self, x_res: int, y_res: int):
|
85 |
+
"""Set resolution.
|
86 |
+
|
87 |
+
Args:
|
88 |
+
x_res (`int`): x resolution of spectrogram (time)
|
89 |
+
y_res (`int`): y resolution of spectrogram (frequency bins)
|
90 |
+
"""
|
91 |
+
self.x_res = x_res
|
92 |
+
self.y_res = y_res
|
93 |
+
self.n_mels = self.y_res
|
94 |
+
self.slice_size = self.x_res * self.hop_length - 1
|
95 |
+
|
96 |
+
def load_audio(self, audio_file: str = None, raw_audio: np.ndarray = None):
|
97 |
+
"""Load audio.
|
98 |
+
|
99 |
+
Args:
|
100 |
+
audio_file (`str`): must be a file on disk due to Librosa limitation or
|
101 |
+
raw_audio (`np.ndarray`): audio as numpy array
|
102 |
+
"""
|
103 |
+
if audio_file is not None:
|
104 |
+
self.audio, _ = librosa.load(audio_file, mono=True, sr=self.sr)
|
105 |
+
else:
|
106 |
+
self.audio = raw_audio
|
107 |
+
|
108 |
+
# Pad with silence if necessary.
|
109 |
+
if len(self.audio) < self.x_res * self.hop_length:
|
110 |
+
self.audio = np.concatenate([self.audio, np.zeros((self.x_res * self.hop_length - len(self.audio),))])
|
111 |
+
|
112 |
+
def get_number_of_slices(self) -> int:
|
113 |
+
"""Get number of slices in audio.
|
114 |
+
|
115 |
+
Returns:
|
116 |
+
`int`: number of spectograms audio can be sliced into
|
117 |
+
"""
|
118 |
+
return len(self.audio) // self.slice_size
|
119 |
+
|
120 |
+
def get_audio_slice(self, slice: int = 0) -> np.ndarray:
|
121 |
+
"""Get slice of audio.
|
122 |
+
|
123 |
+
Args:
|
124 |
+
slice (`int`): slice number of audio (out of get_number_of_slices())
|
125 |
+
|
126 |
+
Returns:
|
127 |
+
`np.ndarray`: audio as numpy array
|
128 |
+
"""
|
129 |
+
return self.audio[self.slice_size * slice : self.slice_size * (slice + 1)]
|
130 |
+
|
131 |
+
def get_sample_rate(self) -> int:
|
132 |
+
"""Get sample rate:
|
133 |
+
|
134 |
+
Returns:
|
135 |
+
`int`: sample rate of audio
|
136 |
+
"""
|
137 |
+
return self.sr
|
138 |
+
|
139 |
+
def audio_slice_to_image(self, slice: int, ref=np.max) -> Image.Image:
|
140 |
+
"""Convert slice of audio to spectrogram.
|
141 |
+
|
142 |
+
Args:
|
143 |
+
slice (`int`): slice number of audio to convert (out of get_number_of_slices())
|
144 |
+
|
145 |
+
Returns:
|
146 |
+
`PIL Image`: grayscale image of x_res x y_res
|
147 |
+
"""
|
148 |
+
S = librosa.feature.melspectrogram(
|
149 |
+
y=self.get_audio_slice(slice), sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_mels=self.n_mels
|
150 |
+
)
|
151 |
+
log_S = librosa.power_to_db(S, ref=ref, top_db=self.top_db)
|
152 |
+
bytedata = (((log_S + self.top_db) * 255 / self.top_db).clip(0, 255) + 0.5).astype(np.uint8)
|
153 |
+
image = Image.fromarray(bytedata)
|
154 |
+
return image
|
155 |
+
|
156 |
+
def image_to_audio(self, image: Image.Image) -> np.ndarray:
|
157 |
+
"""Converts spectrogram to audio.
|
158 |
+
|
159 |
+
Args:
|
160 |
+
image (`PIL Image`): x_res x y_res grayscale image
|
161 |
+
|
162 |
+
Returns:
|
163 |
+
audio (`np.ndarray`): raw audio
|
164 |
+
"""
|
165 |
+
bytedata = np.frombuffer(image.tobytes(), dtype="uint8").reshape((image.height, image.width))
|
166 |
+
log_S = bytedata.astype("float") * self.top_db / 255 - self.top_db
|
167 |
+
S = librosa.db_to_power(log_S)
|
168 |
+
audio = librosa.feature.inverse.mel_to_audio(
|
169 |
+
S, sr=self.sr, n_fft=self.n_fft, hop_length=self.hop_length, n_iter=self.n_iter
|
170 |
+
)
|
171 |
+
return audio
|
172 |
+
|
173 |
+
def audioarray_to_mp3(audioarray, file_path):
|
174 |
+
sample_rate = 22050
|
175 |
+
mel = Mel()
|
176 |
+
# Save the audio array as a temporary WAV file
|
177 |
+
temp_wav_file = "temp.wav"
|
178 |
+
wavfile.write(temp_wav_file, sample_rate, audioarray)
|
179 |
+
|
180 |
+
# Set the output MP3 file path
|
181 |
+
os.remove(file_path)
|
182 |
+
output_mp3_file = file_path
|
183 |
+
|
184 |
+
# Load the temporary WAV file
|
185 |
+
wav_data, sr = sf.read(temp_wav_file)
|
186 |
+
|
187 |
+
# Convert the WAV data to MP3 format
|
188 |
+
sf.write(output_mp3_file, wav_data, sample_rate, format="MP3")
|
189 |
+
|
190 |
+
return None
|
191 |
+
|
192 |
+
def audioarray_to_mp3_highdb(audioarray, file_path):
|
193 |
+
sample_rate = 22050
|
194 |
+
# Save the audio array as a temporary WAV file
|
195 |
+
temp_wav_file = "temp.wav"
|
196 |
+
|
197 |
+
audio = ipd.Audio(audioarray, rate=sample_rate)
|
198 |
+
|
199 |
+
## Write file into a wav file with open
|
200 |
+
with open(file_path, 'wb') as f:
|
201 |
+
f.write(audio.data)
|
202 |
+
|
203 |
+
return None
|
204 |
+
|
205 |
+
|
206 |
+
def main():
|
207 |
+
# # Connect to the PostgreSQL database
|
208 |
+
# conn = psycopg2.connect(database="orpheus", user="postgres", password="1234", host="localhost", port="5432")
|
209 |
+
# cur = conn.cursor()
|
210 |
+
|
211 |
+
# # Assuming you have a table named 'images' with columns 'id' (serial primary key) and 'image_data' (bytea)
|
212 |
+
# table_name = "songs"
|
213 |
+
|
214 |
+
# image_id = np.random.randint(1, 10) # Replace with the actual ID of the image you want to retrieve
|
215 |
+
# print(image_id)
|
216 |
+
# # Retrieve the image data from the database
|
217 |
+
# cur.execute(f"SELECT song FROM {table_name} WHERE id = %s", (image_id,))
|
218 |
+
# result = cur.fetchone()
|
219 |
+
|
220 |
+
# # Convert the bytea data to PIL.Image.Image object
|
221 |
+
# image_bytes = BytesIO(result[0])
|
222 |
+
# image = Image.open(image_bytes)
|
223 |
+
# # image.save("C:/VS code projects/Orpheus-2/audio/thumbnail.png")
|
224 |
+
# # Close the database connection
|
225 |
+
# cur.close()
|
226 |
+
# conn.close()
|
227 |
+
|
228 |
+
# getting the song names
|
229 |
+
song1_name=sys.argv[1]
|
230 |
+
song2_name=sys.argv[2]
|
231 |
+
song3_name=sys.argv[3]
|
232 |
+
similarity_index=float(sys.argv[4])/100
|
233 |
+
print("Similarity index is",similarity_index)
|
234 |
+
print("Song1 name is",song1_name)
|
235 |
+
print("Song2 name is",song2_name)
|
236 |
+
print("Song3 name is",song3_name)
|
237 |
+
print("Similarity index is",similarity_index)
|
238 |
+
#
|
239 |
+
mel = Mel()
|
240 |
+
# audioarray_to_mp3(mel.image_to_audio(image), "audio/output.mp3")
|
241 |
+
# song_array_1, sr = librosa.load("audio\output.mp3", sr=22050)
|
242 |
+
# song_array_1 = song_array_1[:sr*5]
|
243 |
+
|
244 |
+
input_songs_array = []
|
245 |
+
|
246 |
+
if song1_name != "None":
|
247 |
+
song_array_1, sr = librosa.load(f"input_songs/{song1_name}.mp3", sr=22050)
|
248 |
+
input_songs_array.append(song_array_1)
|
249 |
+
# song_array_1, sr = librosa.load(f"input_songs/{song1_name}.mp3", sr=22050)
|
250 |
+
|
251 |
+
# song_array_1 = song_array_1[:sr*5]
|
252 |
+
if song2_name != "None":
|
253 |
+
song_array_2, sr = librosa.load(f"input_songs/{song2_name}.mp3", sr=22050)
|
254 |
+
input_songs_array.append(song_array_2)
|
255 |
+
|
256 |
+
# song_array_2, sr = librosa.load(f"input_songs/{song2_name}.mp3", sr=22050)
|
257 |
+
# song_array_2 = song_array_2[:sr*5]
|
258 |
+
|
259 |
+
if song3_name != "None":
|
260 |
+
song_array_3, sr = librosa.load(f"input_songs/{song3_name}.mp3", sr=22050)
|
261 |
+
input_songs_array.append(song_array_3)
|
262 |
+
# song_array_3, sr = librosa.load(f"input_songs/{song3_name}.mp3", sr=22050)
|
263 |
+
# song_array_3 = song_array_3[:sr*5]
|
264 |
+
mage, audio = generate_songs(input_songs_array, similarity=similarity_index, quality=200)
|
265 |
+
mage.save("audio/thumbnail.png")
|
266 |
+
audioarray_to_mp3_highdb(audio,"audio/generated_song.mp3")
|
267 |
+
# if i==3:
|
268 |
+
# shutil.copy2("aidio/nvg.mp3", "audio/generated_song.mp3")
|
269 |
+
|
270 |
+
print("Python script executed successfully")
|
271 |
+
|
272 |
+
if __name__ == "__main__":
|
273 |
+
main()
|
exp.ipynb
ADDED
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 1,
|
6 |
+
"metadata": {},
|
7 |
+
"outputs": [],
|
8 |
+
"source": [
|
9 |
+
"import numpy as np"
|
10 |
+
]
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"cell_type": "code",
|
14 |
+
"execution_count": 2,
|
15 |
+
"metadata": {},
|
16 |
+
"outputs": [],
|
17 |
+
"source": [
|
18 |
+
"import glob\n",
|
19 |
+
"import matplotlib.pyplot as plt "
|
20 |
+
]
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"cell_type": "code",
|
24 |
+
"execution_count": 15,
|
25 |
+
"metadata": {},
|
26 |
+
"outputs": [],
|
27 |
+
"source": [
|
28 |
+
"songs = glob.glob(\"DataSet/srija/*.wav\")\n",
|
29 |
+
"ratings = [s.split(\"_\")[-1].split(\".\")[0] for s in songs]\n",
|
30 |
+
"ratings = np.array(ratings, dtype=int)\n",
|
31 |
+
"version = [s.split(\"_\")[1][-2:] for s in songs]"
|
32 |
+
]
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"cell_type": "code",
|
36 |
+
"execution_count": 16,
|
37 |
+
"metadata": {},
|
38 |
+
"outputs": [],
|
39 |
+
"source": [
|
40 |
+
"import pandas as pd\n",
|
41 |
+
"rr =pd.DataFrame({\"rating\": ratings, \"version\": version})\n",
|
42 |
+
"\n",
|
43 |
+
"# plt = rr.groupby([\"version\"])[\"ratings\"].mean().plot(kind='bar', stacked=True)\n"
|
44 |
+
]
|
45 |
+
},
|
46 |
+
{
|
47 |
+
"cell_type": "code",
|
48 |
+
"execution_count": 18,
|
49 |
+
"metadata": {},
|
50 |
+
"outputs": [
|
51 |
+
{
|
52 |
+
"data": {
|
53 |
+
"text/html": [
|
54 |
+
"<div>\n",
|
55 |
+
"<style scoped>\n",
|
56 |
+
" .dataframe tbody tr th:only-of-type {\n",
|
57 |
+
" vertical-align: middle;\n",
|
58 |
+
" }\n",
|
59 |
+
"\n",
|
60 |
+
" .dataframe tbody tr th {\n",
|
61 |
+
" vertical-align: top;\n",
|
62 |
+
" }\n",
|
63 |
+
"\n",
|
64 |
+
" .dataframe thead th {\n",
|
65 |
+
" text-align: right;\n",
|
66 |
+
" }\n",
|
67 |
+
"</style>\n",
|
68 |
+
"<table border=\"1\" class=\"dataframe\">\n",
|
69 |
+
" <thead>\n",
|
70 |
+
" <tr style=\"text-align: right;\">\n",
|
71 |
+
" <th></th>\n",
|
72 |
+
" <th>rating</th>\n",
|
73 |
+
" </tr>\n",
|
74 |
+
" <tr>\n",
|
75 |
+
" <th>version</th>\n",
|
76 |
+
" <th></th>\n",
|
77 |
+
" </tr>\n",
|
78 |
+
" </thead>\n",
|
79 |
+
" <tbody>\n",
|
80 |
+
" <tr>\n",
|
81 |
+
" <th>v0</th>\n",
|
82 |
+
" <td>4.740741</td>\n",
|
83 |
+
" </tr>\n",
|
84 |
+
" <tr>\n",
|
85 |
+
" <th>v1</th>\n",
|
86 |
+
" <td>4.703704</td>\n",
|
87 |
+
" </tr>\n",
|
88 |
+
" </tbody>\n",
|
89 |
+
"</table>\n",
|
90 |
+
"</div>"
|
91 |
+
],
|
92 |
+
"text/plain": [
|
93 |
+
" rating\n",
|
94 |
+
"version \n",
|
95 |
+
"v0 4.740741\n",
|
96 |
+
"v1 4.703704"
|
97 |
+
]
|
98 |
+
},
|
99 |
+
"execution_count": 18,
|
100 |
+
"metadata": {},
|
101 |
+
"output_type": "execute_result"
|
102 |
+
}
|
103 |
+
],
|
104 |
+
"source": [
|
105 |
+
"rr.groupby([\"version\"]).mean()"
|
106 |
+
]
|
107 |
+
},
|
108 |
+
{
|
109 |
+
"cell_type": "code",
|
110 |
+
"execution_count": 5,
|
111 |
+
"metadata": {},
|
112 |
+
"outputs": [
|
113 |
+
{
|
114 |
+
"data": {
|
115 |
+
"text/plain": [
|
116 |
+
"<BarContainer object of 54 artists>"
|
117 |
+
]
|
118 |
+
},
|
119 |
+
"execution_count": 5,
|
120 |
+
"metadata": {},
|
121 |
+
"output_type": "execute_result"
|
122 |
+
},
|
123 |
+
{
|
124 |
+
"data": {
|
125 |
+
"image/png": "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",
|
126 |
+
"text/plain": [
|
127 |
+
"<Figure size 640x480 with 1 Axes>"
|
128 |
+
]
|
129 |
+
},
|
130 |
+
"metadata": {},
|
131 |
+
"output_type": "display_data"
|
132 |
+
}
|
133 |
+
],
|
134 |
+
"source": [
|
135 |
+
"plt.bar(rr[\"version\"], rr[\"rating\"])"
|
136 |
+
]
|
137 |
+
},
|
138 |
+
{
|
139 |
+
"cell_type": "code",
|
140 |
+
"execution_count": 4,
|
141 |
+
"metadata": {},
|
142 |
+
"outputs": [],
|
143 |
+
"source": [
|
144 |
+
"avg_ratings = {}"
|
145 |
+
]
|
146 |
+
},
|
147 |
+
{
|
148 |
+
"cell_type": "code",
|
149 |
+
"execution_count": 14,
|
150 |
+
"metadata": {},
|
151 |
+
"outputs": [
|
152 |
+
{
|
153 |
+
"data": {
|
154 |
+
"image/png": "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pk+frp49e6pcuXK6++67Xfbp3bu3Zs2apfr166tPnz6Kjo5Wdna29uzZo0WLFunZZ5/VrbfeetG6WrVqpZEjR6pDhw566qmndPToUY0YMSLHi3/16tXVvn17vfXWW/L29lbjxo21ZcsWvfXWWwoNDZWX1//exR06dKiSkpJ0++23Kz4+XlWqVNHp06f122+/af78+RozZozKlSvn9jl87LHHNHLkSI0YMUI9evRQSEiI6tevrzfffFPFihVTZGSkkpOTNX78eBUpUiTH+ZWksWPHKjg4WAEBAYqKisr17R13DB06VK1atVLz5s3Vq1cvZWVl6c0331RQUNBlz+qEh4ere/fu2rNnjypXrqz58+dr3Lhx6t69u2644QaXvk2bNlW1atW0bNky56W87ujatau++uorffzxx2revLkiIiKc2yIjIzV06FC9+OKL+vXXX9WiRQuFhYXp4MGDWrVqlQoXLqwhQ4ZcdPx58+bpgw8+UFxcnCpUqCBjjL744gudOHFCTZs2veB+ffr00aRJk9SqVSsNHTpU5cuX11dffaUPPvhA3bt3V+XKld16nECe8uD6GOCaiYuLM35+fjkuD/2rhx9+2Pj4+DgXsGZlZZmIiAgjybz44ou57pORkWFeeuklU6VKFePn52dCQ0NNzZo1TZ8+fZzjGGNyXO76VxMmTDBVqlQx/v7+pkKFCiYhIcGMHz/eSDK7du1y9jt9+rTp27evKVGihAkICDC33XabSUlJMaGhoaZPnz4uYx4+fNjEx8ebqKgo4+vra4oWLWpiYmLMiy++6FwMeiEXujzZGGO++uorI8l56fS+ffvMv/71LxMWFmaCg4NNixYtzObNm3Ms1jTGmFGjRpmoqCjnottPPvnEGHPhxbS5na/cxp09e7apWbOm8fPzMzfccIMZPny4iY+PN2FhYRd9nH99rMuXLzexsbHG39/flC5d2gwcONCcPXs2131eeeUVI8l8//33lxz/786cOWNKlixpJJnPP/881z5z5swxjRo1MiEhIcbf39+UL1/ePPjgg2bx4sXOPp06dTKFCxfOse9PP/1k2rdvbypWrGgCAwNNaGioueWWW1wuvzcm9/O4e/du06FDBxMeHm58fX1NlSpVzJtvvmmysrKcfc4vpn3zzTdzHFuSGTx4sBtnA7g8DmP+9qlSAK4b3333ne644w5NnjxZ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1+6WBAAA/qHcnlEZM2aMEhMT9eijj171wcuVK6fhw4frxhtvlCRNnDhR9913n9atW6fq1atf9fgAAOD65nZQOXPmjMuHvV2NNm3auNwfNmyYPvzwQ33//fcEFQAA4P5bP0888YSmTJmS54VkZWVp2rRpOnXqlOrVq5drn8zMTKWlpbncAADAP5fbMyqnT5/W2LFjtXjxYkVHR8vX19dl+8iRI90ab9OmTapXr55Onz6toKAgzZ49W9WqVcu1b0JCgoYMGeJuyQAA4DrldlDZuHGjateuLUnavHmzyzaHw+F2AVWqVNH69et14sQJzZo1S506dVJycnKuYWXAgAHq27ev835aWpoiIiLcPiYAALg+uB1Uli1blqcF+Pn5ORfTxsbGavXq1XrnnXf00Ucf5ejr7+8vf3//PD0+AACwl9trVPKbMUaZmZmeLgMAAFjgsmZUHnjgASUmJiokJEQPPPDARft+8cUXl33wgQMHqmXLloqIiFB6erqmTZum5cuXa8GCBZc9BgAA+Oe6rKASGhrqXH8SEhJyRWtRcnPw4EE9+uijOnDggEJDQxUdHa0FCxaoadOmeTI+AAC4vl1WUPnkk0+c/05MTMyzg48fPz7PxgIAAP88bq9Rady4sU6cOJGjPS0tTY0bN86LmgAAACRdQVBZvny5zpw5k6P99OnTWrFiRZ4UBQAAILlxefLGjRud/966datSU1Od97OysrRgwQKVLVs2b6sDAAAF2mUHldq1a8vhcMjhcOT6Fk9gYKDee++9PC0OAAAUbJcdVHbt2iVjjCpUqKBVq1apePHizm1+fn4qUaKEvL2986VIAABQMF12UClfvrwkKTs7O9+KAQAA+Cu3P0L/vK1bt2rPnj05Ftbee++9V10UAACAdAVB5ddff9X999+vTZs2yeFwyBgj6X9fSJiVlZW3FQIAgALL7cuTe/XqpaioKB08eFCFChXSli1b9M033yg2NlbLly/PhxIBAEBB5faMSkpKipYuXarixYvLy8tLXl5euvPOO5WQkKD4+HitW7cuP+oEAAAFkNszKllZWQoKCpIkFStWTPv375f052Lb7du35211AACgQHN7RqVGjRrauHGjKlSooFtvvVVvvPGG/Pz8NHbsWFWoUCE/agQAAAWU20HlpZde0qlTpyRJr732mlq3bq277rpL4eHhmjZtWp4XCAAA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",
|
155 |
+
"text/plain": [
|
156 |
+
"<Figure size 640x480 with 1 Axes>"
|
157 |
+
]
|
158 |
+
},
|
159 |
+
"metadata": {},
|
160 |
+
"output_type": "display_data"
|
161 |
+
}
|
162 |
+
],
|
163 |
+
"source": [
|
164 |
+
"import glob\n",
|
165 |
+
"import matplotlib.pyplot as plt\n",
|
166 |
+
"\n",
|
167 |
+
"# Get the list of song files\n",
|
168 |
+
"songs = glob.glob(\"DataSet/srija/*.wav\")\n",
|
169 |
+
"\n",
|
170 |
+
"# Extract ratings and versions\n",
|
171 |
+
"ratings = [int(s.split(\"_\")[-1].split(\".\")[0]) for s in songs]\n",
|
172 |
+
"version = [s.split(\"_\")[1][-2:] for s in songs]\n",
|
173 |
+
"\n",
|
174 |
+
"# Create a dictionary to store ratings for each version\n",
|
175 |
+
"ratings_by_version = {}\n",
|
176 |
+
"\n",
|
177 |
+
"# Iterate over songs and populate ratings by version dictionary\n",
|
178 |
+
"for v, r in zip(version, ratings):\n",
|
179 |
+
" if v not in ratings_by_version:\n",
|
180 |
+
" ratings_by_version[v] = []\n",
|
181 |
+
" ratings_by_version[v].append(r)\n",
|
182 |
+
"\n",
|
183 |
+
"# Calculate average ratings for each version\n",
|
184 |
+
"avg_ratings = {v: sum(ratings) / len(ratings) for v, ratings in ratings_by_version.items()}\n",
|
185 |
+
"\n",
|
186 |
+
"# Plotting\n",
|
187 |
+
"plt.bar(avg_ratings.keys(), avg_ratings.values(), color='skyblue')\n",
|
188 |
+
"plt.xlabel('Version')\n",
|
189 |
+
"plt.ylabel('Average Rating')\n",
|
190 |
+
"plt.title('Average Rating by Version')\n",
|
191 |
+
"plt.xticks(list(avg_ratings.keys()))\n",
|
192 |
+
"plt.show()\n"
|
193 |
+
]
|
194 |
+
},
|
195 |
+
{
|
196 |
+
"cell_type": "code",
|
197 |
+
"execution_count": null,
|
198 |
+
"metadata": {},
|
199 |
+
"outputs": [],
|
200 |
+
"source": []
|
201 |
+
}
|
202 |
+
],
|
203 |
+
"metadata": {
|
204 |
+
"kernelspec": {
|
205 |
+
"display_name": "lmu310",
|
206 |
+
"language": "python",
|
207 |
+
"name": "python3"
|
208 |
+
},
|
209 |
+
"language_info": {
|
210 |
+
"codemirror_mode": {
|
211 |
+
"name": "ipython",
|
212 |
+
"version": 3
|
213 |
+
},
|
214 |
+
"file_extension": ".py",
|
215 |
+
"mimetype": "text/x-python",
|
216 |
+
"name": "python",
|
217 |
+
"nbconvert_exporter": "python",
|
218 |
+
"pygments_lexer": "ipython3",
|
219 |
+
"version": "3.10.9"
|
220 |
+
}
|
221 |
+
},
|
222 |
+
"nbformat": 4,
|
223 |
+
"nbformat_minor": 2
|
224 |
+
}
|
generation_utilities.py
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import torch
|
2 |
+
from IPython.display import Audio
|
3 |
+
from audiodiffusion import AudioDiffusion, AudioDiffusionPipeline
|
4 |
+
from audiodiffusion.audio_encoder import AudioEncoder
|
5 |
+
import librosa
|
6 |
+
import librosa.display
|
7 |
+
import numpy as np
|
8 |
+
import random
|
9 |
+
|
10 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
11 |
+
model_name = ["SAint7579/orpheus_ldm_model_v1-0", "teticio/audio-diffusion-ddim-256"]
|
12 |
+
|
13 |
+
audio_diffusion_v0 = AudioDiffusionPipeline.from_pretrained("teticio/latent-audio-diffusion-256").to(device)
|
14 |
+
audio_diffusion_v1 = AudioDiffusionPipeline.from_pretrained("SAint7579/orpheus_ldm_model_v1-0").to(device)
|
15 |
+
ddim = AudioDiffusionPipeline.from_pretrained("teticio/audio-diffusion-ddim-256").to(device)
|
16 |
+
|
17 |
+
### Add numpy docstring to generate_from_music
|
18 |
+
def generate_from_music(song_array, diffuser, start_step, total_steps=100, device="cuda"):
|
19 |
+
"""
|
20 |
+
Generates audio from a given song array using a given diffuser.
|
21 |
+
Parameters
|
22 |
+
----------
|
23 |
+
song_array : numpy.ndarray
|
24 |
+
The song array to use as the raw audio.
|
25 |
+
diffuser : AudioDiffusionPipeline
|
26 |
+
The diffuser to use to generate the audio.
|
27 |
+
start_step : int
|
28 |
+
The step to start generating from.
|
29 |
+
total_steps : int
|
30 |
+
The total number of steps to generate.
|
31 |
+
device : str
|
32 |
+
The device to use for generation.
|
33 |
+
Returns
|
34 |
+
-------
|
35 |
+
numpy.ndarray
|
36 |
+
The generated audio.
|
37 |
+
"""
|
38 |
+
generator = torch.Generator(device=device)
|
39 |
+
generator.seed()
|
40 |
+
output = diffuser(raw_audio=song_array, generator = generator, start_step=start_step, steps=total_steps)
|
41 |
+
return output.images[0], output.audios[0, 0]
|
42 |
+
|
43 |
+
def generate_from_music_long(song_array, diffuser, start_step, total_steps=100, device="cuda"):
|
44 |
+
"""
|
45 |
+
Generates a 10 second audio from a given song array using a given diffuser.
|
46 |
+
Parameters
|
47 |
+
----------
|
48 |
+
song_array : numpy.ndarray
|
49 |
+
The song array to use as the raw audio.
|
50 |
+
diffuser : AudioDiffusionPipeline
|
51 |
+
The diffuser to use to generate the audio.
|
52 |
+
start_step : int
|
53 |
+
The step to start generating from.
|
54 |
+
total_steps : int
|
55 |
+
The total number of steps to generate.
|
56 |
+
device : str
|
57 |
+
The device to use for generation.
|
58 |
+
Returns
|
59 |
+
-------
|
60 |
+
numpy.ndarray
|
61 |
+
The generated audio.
|
62 |
+
"""
|
63 |
+
generator = torch.Generator(device=device)
|
64 |
+
generator.seed()
|
65 |
+
output = diffuser(raw_audio=song_array, generator = generator, start_step=start_step, steps=total_steps)
|
66 |
+
|
67 |
+
# Get the track and use the diffuser again to create the continuation
|
68 |
+
track = output.audios[0, 0]
|
69 |
+
sample_rate = diffuser.mel.get_sample_rate()
|
70 |
+
overlap_secs = 2
|
71 |
+
overlap_samples = overlap_secs * sample_rate
|
72 |
+
|
73 |
+
continue_output = diffuser(raw_audio=track[-overlap_samples:],
|
74 |
+
generator=generator,
|
75 |
+
start_step=start_step,
|
76 |
+
mask_start_secs=overlap_secs)
|
77 |
+
# image2 = output.images[0]
|
78 |
+
audio2 = continue_output.audios[0, 0]
|
79 |
+
track = np.concatenate([track, audio2[overlap_samples:]])
|
80 |
+
|
81 |
+
return output.images[0], track
|
82 |
+
|
83 |
+
|
84 |
+
## Add docstring to iterative_slerp function in numpy format
|
85 |
+
def iterative_slerp(song_arrays, ddim, steps=10):
|
86 |
+
"""Iterative slerp function.
|
87 |
+
|
88 |
+
Parameters
|
89 |
+
----------
|
90 |
+
song_arrays : list
|
91 |
+
List of song arrays to slerp.
|
92 |
+
ddim : AudioDiffusion ddim model
|
93 |
+
AudioDiffusion object.
|
94 |
+
|
95 |
+
Returns
|
96 |
+
-------
|
97 |
+
slerp : torch.Tensor
|
98 |
+
Slerped tensor.
|
99 |
+
"""
|
100 |
+
noise = []
|
101 |
+
for arr in song_arrays:
|
102 |
+
ddim.mel.audio = arr
|
103 |
+
noise.append(ddim.encode([ddim.mel.audio_slice_to_image(0)], steps=steps))
|
104 |
+
|
105 |
+
slerp = noise[0]
|
106 |
+
for i in range(1, len(noise)):
|
107 |
+
slerp = ddim.slerp(slerp, noise[i], 0.5)
|
108 |
+
|
109 |
+
return slerp
|
110 |
+
|
111 |
+
def merge_songs(song_arrays, ddim, slerp_steps=10, diffusion_steps=100, device="cuda"):
|
112 |
+
"""Merge songs.
|
113 |
+
|
114 |
+
Parameters
|
115 |
+
----------
|
116 |
+
song_arrays : list
|
117 |
+
List of song arrays to merge.
|
118 |
+
ddim : AudioDiffusion ddim model
|
119 |
+
AudioDiffusion object.
|
120 |
+
|
121 |
+
Returns
|
122 |
+
-------
|
123 |
+
spectrogram : np.ndarray
|
124 |
+
Merged spectrogram.
|
125 |
+
audio : np.ndarray
|
126 |
+
Merged audio.
|
127 |
+
"""
|
128 |
+
generator = torch.Generator(device=device)
|
129 |
+
generator.manual_seed(7579)
|
130 |
+
slerp = iterative_slerp(song_arrays, ddim, slerp_steps)
|
131 |
+
merged = ddim(noise=slerp, generator=generator, steps=diffusion_steps)
|
132 |
+
return merged.images[0], merged.audios[0, 0]
|
133 |
+
|
134 |
+
## Write generate songs function with numpy docstring
|
135 |
+
def generate_songs(conditioning_songs, similarity=0.9, quality=500, merging_quality=100, device='cuda'):
|
136 |
+
"""Generate songs.
|
137 |
+
|
138 |
+
Parameters
|
139 |
+
----------
|
140 |
+
conditioning_songs : list
|
141 |
+
List of conditioning songs.
|
142 |
+
similarity : float
|
143 |
+
Similarity between conditioning songs.
|
144 |
+
quality : int
|
145 |
+
Quality of generated song.
|
146 |
+
|
147 |
+
Returns
|
148 |
+
-------
|
149 |
+
spec_generated : np.ndarray
|
150 |
+
Spectrogram of generated song.
|
151 |
+
generated : np.ndarray
|
152 |
+
Generated song.
|
153 |
+
"""
|
154 |
+
## Merging songs
|
155 |
+
print("Merging songs...")
|
156 |
+
if len(conditioning_songs)>1:
|
157 |
+
# print(conditioning_songs)
|
158 |
+
# for c in conditioning_songs:
|
159 |
+
# print(len(c))
|
160 |
+
spec_merged, merged = merge_songs(conditioning_songs, ddim, slerp_steps=merging_quality, diffusion_steps=merging_quality, device=device)
|
161 |
+
else:
|
162 |
+
merged = conditioning_songs[0]
|
163 |
+
|
164 |
+
## Take a random 10 second slice from the merged song
|
165 |
+
# sample_rate = ddim.mel.get_sample_rate()
|
166 |
+
# start = np.random.randint(0, len(merged) - 5 * sample_rate)
|
167 |
+
# merged = merged[start:start + 5 * sample_rate]
|
168 |
+
|
169 |
+
if random.random() < 0.5:
|
170 |
+
diffuser = audio_diffusion_v0
|
171 |
+
model_name = "v0"
|
172 |
+
else:
|
173 |
+
diffuser = audio_diffusion_v1
|
174 |
+
model_name = "v1"
|
175 |
+
print("Generating song...")
|
176 |
+
## quality = X - similarity*X
|
177 |
+
total_steps = min([1000, int(quality/(1-similarity))])
|
178 |
+
start_step = int(total_steps*similarity)
|
179 |
+
spec_generated, generated = generate_from_music(merged, diffuser, start_step=start_step, total_steps=total_steps, device=device)
|
180 |
+
|
181 |
+
return spec_generated, generated, model_name
|
182 |
+
|
183 |
+
# if __name__ == '__main__':
|
184 |
+
# song1 = "D:/Projects/Orpheus_ai/DataSet/Sep_Dataset/accompaniment/000010.mp3"
|
185 |
+
# song2 = "D:/Projects/Orpheus_ai/DataSet/Sep_Dataset/accompaniment/000002.mp3"
|
186 |
+
# song3 = "D:/Projects/Orpheus_ai/DataSet/Sep_Dataset/accompaniment/000003.mp3"
|
187 |
+
|
188 |
+
# song_array_1, sr = librosa.load(song1, sr=22050)
|
189 |
+
# song_array_1 = song_array_1[:sr*5]
|
190 |
+
|
191 |
+
# song_array_2, sr = librosa.load(song2, sr=22050)
|
192 |
+
# song_array_2 = song_array_2[:sr*10]
|
193 |
+
|
194 |
+
# song_array_3, sr = librosa.load(song3, sr=22050)
|
195 |
+
# song_array_3 = song_array_3[:sr*10]
|
196 |
+
|
197 |
+
# generator = torch.Generator(device=device)
|
198 |
+
|
199 |
+
# # seed = 239150437427
|
200 |
+
# image, audio = generate_songs([song_array_2, song_array_3], similarity=0.5, quality=10, device=device)
|
201 |
+
# Audio(audio, rate=sr)
|
requirements.txt
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
audiodiffusion==1.5.6
|
2 |
+
diffusers==0.17.1
|
3 |
+
librosa==0.10.1
|
4 |
+
numpy==1.26.2
|
5 |
+
torch==2.2.1+cu118
|
6 |
+
torchaudio==2.2.1+cu118
|
7 |
+
torchmetrics==1.3.1
|
8 |
+
torchvision==0.17.1
|
9 |
+
streamlit==1.32.2
|
10 |
+
st-star-rating==0.0.6
|
ui/app.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
st.set_page_config(initial_sidebar_state="collapsed")
|
3 |
+
import sys
|
4 |
+
sys.path.append('../')
|
5 |
+
import generation_utilities
|
6 |
+
import numpy as np
|
7 |
+
import librosa
|
8 |
+
from glob import glob
|
9 |
+
import soundfile as sf
|
10 |
+
import importlib
|
11 |
+
import numpy as np
|
12 |
+
importlib.reload(generation_utilities)
|
13 |
+
|
14 |
+
import os
|
15 |
+
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
|
16 |
+
|
17 |
+
|
18 |
+
if 'song_name' not in st.session_state:
|
19 |
+
st.session_state['song_name'] = None
|
20 |
+
if 'similarity' not in st.session_state:
|
21 |
+
st.session_state['similarity'] = None
|
22 |
+
if 'model_name' not in st.session_state:
|
23 |
+
st.session_state['model_name'] = None
|
24 |
+
if 'song_list' not in st.session_state:
|
25 |
+
st.session_state['song_list'] = None
|
26 |
+
|
27 |
+
|
28 |
+
form1 = st.form(key="form1")
|
29 |
+
song_default = np.random.choice(["22", "Anti-Hero", "Back-to-december","Blank-Space","Cardigan","Delicate","Lover","Love-Story","Willow","You-Belong-With-Me"])
|
30 |
+
similarity_default = np.random.uniform(0.8, 0.99).__round__(2)
|
31 |
+
song_options = form1.multiselect("Select songs from library",["22", "Anti-Hero", "Back-to-december","Blank-Space","Cardigan","Delicate","Lover","Love-Story","Willow","You-Belong-With-Me"], default=[song_default])
|
32 |
+
similarity = form1.slider("Similarity", 0.0, 1.0, similarity_default)
|
33 |
+
submit = form1.form_submit_button("Submit")
|
34 |
+
|
35 |
+
if submit:
|
36 |
+
song_list = [librosa.load(f"../input_songs/{song}.mp3", sr=22050)[0] for song in song_options]
|
37 |
+
print(song_options)
|
38 |
+
|
39 |
+
spectrogram, generated_song, model_name = generation_utilities.generate_songs(song_list, similarity=similarity, quality=500, merging_quality=100, device='cuda')
|
40 |
+
st.session_state['song_name'] = song_options[0]
|
41 |
+
st.session_state['song_list'] = [f"../input_songs/{song}.mp3" for song in song_options]
|
42 |
+
st.session_state['song_name'] = '_'.join(song_options)
|
43 |
+
st.session_state['similarity'] = similarity
|
44 |
+
st.session_state['model_name'] = model_name
|
45 |
+
|
46 |
+
# saving temps
|
47 |
+
sf.write(f"temp.wav", generated_song, 22050)
|
48 |
+
np.save("temp.npy", spectrogram)
|
49 |
+
st.switch_page("pages/rating.py")
|
50 |
+
# st.audio(generated_song, format='audio/wav',sample_rate=22050)
|
51 |
+
|
52 |
+
# generated_audio_path = "generated_audio.wav"
|
53 |
+
# sf.write(generated_audio_path, generated_song, 22050)
|
54 |
+
# st.audio(generated_audio_path, format='audio/wav')
|
55 |
+
# st.write("Generated!")
|
ui/pages/rating.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from streamlit_star_rating import st_star_rating
|
3 |
+
st.set_page_config(initial_sidebar_state="collapsed")
|
4 |
+
import glob
|
5 |
+
import shutil
|
6 |
+
import sys
|
7 |
+
sys.path.append('../../')
|
8 |
+
spectrograms = glob.glob("temp*.npy")
|
9 |
+
generated_songs = glob.glob("temp*.wav")
|
10 |
+
|
11 |
+
st.markdown("# Original Song")
|
12 |
+
for s in st.session_state['song_list']:
|
13 |
+
st.markdown(f"### {s.split('/')[-1].split('.')[0]}")
|
14 |
+
st.audio(s, format='audio/wav')
|
15 |
+
st.markdown("# Generated Song")
|
16 |
+
st.audio(generated_songs[0], format='audio/wav')
|
17 |
+
rating = st_star_rating(label="rating", maxValue=10, defaultValue=3)
|
18 |
+
|
19 |
+
|
20 |
+
submit_rating = st.button("Submit Rating")
|
21 |
+
|
22 |
+
if submit_rating:
|
23 |
+
shutil.copy(generated_songs[0],f"../DataSet/Song/srija_{st.session_state['model_name']}_{st.session_state['song_name']}_{st.session_state['similarity']}_{rating}.wav")
|
24 |
+
shutil.copy(spectrograms[0],f"../DataSet/Spec/srija_{st.session_state['model_name']}_{st.session_state['song_name']}_{st.session_state['similarity']}_{rating}.npy")
|
25 |
+
st.switch_page("app.py")
|