Spaces:
Sleeping
Sleeping
Upload 6 files
Browse files- app.py +205 -0
- mi_modelo03_music.h5 +3 -0
- mi_modelo_music.h5 +3 -0
- mi_pesos03_music.h5 +3 -0
- mi_pesos_music.h5 +3 -0
- requirements.txt +8 -0
app.py
ADDED
@@ -0,0 +1,205 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
import os
|
3 |
+
os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
|
4 |
+
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
|
5 |
+
os.environ["TF_FORCE_CPU"] = '1'
|
6 |
+
|
7 |
+
|
8 |
+
|
9 |
+
import collections
|
10 |
+
#import datetime
|
11 |
+
#import glob
|
12 |
+
import numpy as np
|
13 |
+
#import pathlib
|
14 |
+
import pandas as pd
|
15 |
+
import pretty_midi
|
16 |
+
import seaborn as sns
|
17 |
+
|
18 |
+
from matplotlib import pyplot as plt
|
19 |
+
from typing import Optional
|
20 |
+
|
21 |
+
import tensorflow as tf
|
22 |
+
|
23 |
+
|
24 |
+
import datetime
|
25 |
+
import os
|
26 |
+
|
27 |
+
import keras
|
28 |
+
|
29 |
+
from tensorflow.keras.utils import custom_object_scope
|
30 |
+
|
31 |
+
import gradio as st
|
32 |
+
|
33 |
+
|
34 |
+
|
35 |
+
|
36 |
+
def midi_to_notes(midi_file: str) -> pd.DataFrame:
|
37 |
+
pm = pretty_midi.PrettyMIDI(midi_file)
|
38 |
+
instrument = pm.instruments[0]
|
39 |
+
notes = collections.defaultdict(list)
|
40 |
+
|
41 |
+
sorted_notes = sorted(instrument.notes, key=lambda note: note.start)
|
42 |
+
prev_start = sorted_notes[0].start
|
43 |
+
|
44 |
+
for note in sorted_notes:
|
45 |
+
start = note.start
|
46 |
+
end = note.end
|
47 |
+
notes['pitch'].append(note.pitch)
|
48 |
+
notes['start'].append(start)
|
49 |
+
notes['end'].append(end)
|
50 |
+
notes['step'].append(start - prev_start)
|
51 |
+
notes['duration'].append(end - start)
|
52 |
+
prev_start = start
|
53 |
+
|
54 |
+
return pd.DataFrame({name: np.array(value) for name, value in notes.items()})
|
55 |
+
|
56 |
+
def notes_to_midi(
|
57 |
+
notes: pd.DataFrame,
|
58 |
+
out_file: str,
|
59 |
+
instrument_name: str,
|
60 |
+
velocity: int = 100,
|
61 |
+
) -> pretty_midi.PrettyMIDI:
|
62 |
+
|
63 |
+
pm = pretty_midi.PrettyMIDI()
|
64 |
+
instrument = pretty_midi.Instrument(
|
65 |
+
program=pretty_midi.instrument_name_to_program(
|
66 |
+
instrument_name))
|
67 |
+
|
68 |
+
prev_start = 0
|
69 |
+
for i, note in notes.iterrows():
|
70 |
+
start = float(prev_start + note['step'])
|
71 |
+
end = float(start + note['duration'])
|
72 |
+
note = pretty_midi.Note(
|
73 |
+
velocity=velocity,
|
74 |
+
pitch=int(note['pitch']),
|
75 |
+
start=start,
|
76 |
+
end=end,
|
77 |
+
)
|
78 |
+
instrument.notes.append(note)
|
79 |
+
prev_start = start
|
80 |
+
|
81 |
+
pm.instruments.append(instrument)
|
82 |
+
pm.write(out_file)
|
83 |
+
return pm
|
84 |
+
|
85 |
+
def plot_roll(notes: pd.DataFrame, count: Optional[int] = None):
|
86 |
+
if count:
|
87 |
+
title = f'First {count} notes'
|
88 |
+
else:
|
89 |
+
title = f'Whole track'
|
90 |
+
count = len(notes['pitch'])
|
91 |
+
plt.figure(figsize=(20, 4))
|
92 |
+
plot_pitch = np.stack([notes['pitch'], notes['pitch']], axis=0)
|
93 |
+
plot_start_stop = np.stack([notes['start'], notes['end']], axis=0)
|
94 |
+
plt.plot(
|
95 |
+
plot_start_stop[:, :count], plot_pitch[:, :count], color="b", marker=".")
|
96 |
+
plt.xlabel('Time [s]')
|
97 |
+
plt.ylabel('Pitch')
|
98 |
+
_ = plt.title(title)
|
99 |
+
|
100 |
+
def plot_distributions(notes: pd.DataFrame, drop_percentile=2.5):
|
101 |
+
plt.figure(figsize=[15, 5])
|
102 |
+
plt.subplot(1, 3, 1)
|
103 |
+
sns.histplot(notes, x="pitch", bins=20)
|
104 |
+
|
105 |
+
plt.subplot(1, 3, 2)
|
106 |
+
max_step = np.percentile(notes['step'], 100 - drop_percentile)
|
107 |
+
sns.histplot(notes, x="step", bins=np.linspace(0, max_step, 21))
|
108 |
+
|
109 |
+
def predict_next_note(
|
110 |
+
notes: np.ndarray,
|
111 |
+
model: tf.keras.Model,
|
112 |
+
temperature: float = 1.0) -> tuple[int, float, float]:
|
113 |
+
|
114 |
+
assert temperature > 0
|
115 |
+
|
116 |
+
inputs = tf.expand_dims(notes, 0)
|
117 |
+
|
118 |
+
predictions = model.predict(inputs)
|
119 |
+
pitch_logits = predictions['pitch']
|
120 |
+
step = predictions['step']
|
121 |
+
duration = predictions['duration']
|
122 |
+
|
123 |
+
pitch_logits /= temperature
|
124 |
+
pitch = tf.random.categorical(pitch_logits, num_samples=1)
|
125 |
+
pitch = tf.squeeze(pitch, axis=-1)
|
126 |
+
duration = tf.squeeze(duration, axis=-1)
|
127 |
+
step = tf.squeeze(step, axis=-1)
|
128 |
+
|
129 |
+
step = tf.maximum(0, step)
|
130 |
+
duration = tf.maximum(0, duration)
|
131 |
+
|
132 |
+
return int(pitch), float(step), float(duration)
|
133 |
+
|
134 |
+
def mse_with_positive_pressure(y_true: tf.Tensor, y_pred: tf.Tensor):
|
135 |
+
mse = (y_true - y_pred) ** 2
|
136 |
+
positive_pressure = 10 * tf.maximum(-y_pred, 0.0)
|
137 |
+
return tf.reduce_mean(mse + positive_pressure)
|
138 |
+
|
139 |
+
def main():
|
140 |
+
# AQUI EN EL MAIN DEBERIA INCLUIRSE STREAMLIT
|
141 |
+
description = st.Textbox(label="Description", placeholder="acoustic, guitar, melody, trap, d minor, 90 bpm")
|
142 |
+
melody_audio = st.Audio(label="Melody Audio (optional)", type="filepath")
|
143 |
+
output_path = st.Audio(label="Generated Music", type="filepath")
|
144 |
+
|
145 |
+
seed = 42
|
146 |
+
tf.random.set_seed(seed)
|
147 |
+
np.random.seed(seed)
|
148 |
+
|
149 |
+
_SAMPLING_RATE = 16000
|
150 |
+
|
151 |
+
# LEER ARCHIVO
|
152 |
+
sample_file = "Preludes 2 Through Major keys 39.mid"
|
153 |
+
pm = pretty_midi.PrettyMIDI(sample_file)
|
154 |
+
|
155 |
+
print('Número de instrumentos:', len(pm.instruments))
|
156 |
+
for i in range(len(pm.instruments)):
|
157 |
+
instrument = pm.instruments[i]
|
158 |
+
instrument_name = pretty_midi.program_to_instrument_name(instrument.program)
|
159 |
+
print('Nombre del instrumento:', instrument_name)
|
160 |
+
|
161 |
+
raw_notes = midi_to_notes(sample_file)
|
162 |
+
|
163 |
+
key_order = ['pitch', 'step', 'duration']
|
164 |
+
|
165 |
+
seq_length = 25
|
166 |
+
vocab_size = 128
|
167 |
+
|
168 |
+
temperature = 2.0
|
169 |
+
#num_predictions = input("Ingrese el número de notas: ")
|
170 |
+
num_predictions = 120#int(num_predictions)
|
171 |
+
|
172 |
+
sample_notes = np.stack([raw_notes[key] for key in key_order], axis=1)
|
173 |
+
|
174 |
+
input_notes = (
|
175 |
+
sample_notes[:seq_length] / np.array([vocab_size, 1, 1]))
|
176 |
+
|
177 |
+
with custom_object_scope({'mse_with_positive_pressure': mse_with_positive_pressure}):
|
178 |
+
model = keras.saving.load_model("mi_modelo_music.h5")
|
179 |
+
|
180 |
+
model.load_weights("mi_pesos_music.h5", skip_mismatch=False, by_name=False, options=None)
|
181 |
+
|
182 |
+
generated_notes = []
|
183 |
+
prev_start = 0
|
184 |
+
for _ in range(num_predictions):
|
185 |
+
pitch, step, duration = predict_next_note(input_notes, model, temperature)
|
186 |
+
start = prev_start + step
|
187 |
+
end = start + duration
|
188 |
+
input_note = (pitch, step, duration)
|
189 |
+
generated_notes.append((*input_note, start, end))
|
190 |
+
input_notes = np.delete(input_notes, 0, axis=0)
|
191 |
+
input_notes = np.append(input_notes, np.expand_dims(input_note, 0), axis=0)
|
192 |
+
prev_start = start
|
193 |
+
|
194 |
+
generated_notes = pd.DataFrame(
|
195 |
+
generated_notes, columns=(*key_order, 'start', 'end'))
|
196 |
+
|
197 |
+
out_file = 'output.mid'
|
198 |
+
|
199 |
+
out_pm = notes_to_midi(
|
200 |
+
generated_notes, out_file=out_file, instrument_name=instrument_name)
|
201 |
+
|
202 |
+
# Reproducir audio
|
203 |
+
|
204 |
+
if __name__ == "__main__":
|
205 |
+
main()
|
mi_modelo03_music.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:a456d332ce0b5617e258db48a24ffc56910ef4ba228f66c1642d42c7dc08b5d4
|
3 |
+
size 1059128
|
mi_modelo_music.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:e6c7b349a19e94cdf0429f0986b909c9bd120a2311591411def479e824806dbc
|
3 |
+
size 1058096
|
mi_pesos03_music.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:d21bf784a6b7ea000de799930bb5990f060a3746943cbead7bf7f7210a783725
|
3 |
+
size 357608
|
mi_pesos_music.h5
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:dc1813143fe96939597c7a03ff9c8dcc6aa94e820676dd3cb5c98f5f8c01f8e6
|
3 |
+
size 357608
|
requirements.txt
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
numpy==1.25.2
|
2 |
+
pandas==2.0.3
|
3 |
+
pretty_midi==0.2.10
|
4 |
+
seaborn==0.13.1
|
5 |
+
matplotlib==3.7.1
|
6 |
+
tensorflow
|
7 |
+
keras==2.15.0
|
8 |
+
|