Solannin commited on
Commit
810e364
1 Parent(s): 507a554

Upload 3 files

Browse files
Files changed (4) hide show
  1. .gitattributes +1 -0
  2. 16.5mg_gm_gs_mt32_v2.51_bank.sf2 +3 -0
  3. app.py +186 -0
  4. requirements.txt +9 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ 16.5mg_gm_gs_mt32_v2.51_bank.sf2 filter=lfs diff=lfs merge=lfs -text
16.5mg_gm_gs_mt32_v2.51_bank.sf2 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c5971c61f49f749837b0bcf7e2b5d17d5bd6d2b60df19f98da320315a029813f
3
+ size 16944892
app.py ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import collections
2
+ #import datetime
3
+ #import glob
4
+ import numpy as np
5
+ #import pathlib
6
+ import pandas as pd
7
+ import pretty_midi
8
+ import seaborn as sns
9
+
10
+ from matplotlib import pyplot as plt
11
+ from typing import Optional
12
+
13
+ import tensorflow as tf
14
+
15
+ import keras
16
+
17
+ from tensorflow.keras.utils import custom_object_scope
18
+
19
+ import streamlit as st
20
+
21
+ from midi2audio import FluidSynth
22
+ import tempfile
23
+ import os
24
+ import base64
25
+
26
+ def midi_to_notes(midi_file: str) -> pd.DataFrame:
27
+ pm = pretty_midi.PrettyMIDI(midi_file)
28
+ instrument = pm.instruments[0]
29
+ notes = collections.defaultdict(list)
30
+
31
+ sorted_notes = sorted(instrument.notes, key=lambda note: note.start)
32
+ prev_start = sorted_notes[0].start
33
+
34
+ for note in sorted_notes:
35
+ start = note.start
36
+ end = note.end
37
+ notes['pitch'].append(note.pitch)
38
+ notes['start'].append(start)
39
+ notes['end'].append(end)
40
+ notes['step'].append(start - prev_start)
41
+ notes['duration'].append(end - start)
42
+ prev_start = start
43
+
44
+ return pd.DataFrame({name: np.array(value) for name, value in notes.items()})
45
+
46
+ def notes_to_midi(
47
+ notes: pd.DataFrame,
48
+ out_file: str,
49
+ instrument_name: str,
50
+ velocity: int = 100,
51
+ ) -> pretty_midi.PrettyMIDI:
52
+
53
+ pm = pretty_midi.PrettyMIDI()
54
+ instrument = pretty_midi.Instrument(
55
+ program=pretty_midi.instrument_name_to_program(
56
+ instrument_name))
57
+
58
+ prev_start = 0
59
+ for i, note in notes.iterrows():
60
+ start = float(prev_start + note['step'])
61
+ end = float(start + note['duration'])
62
+ note = pretty_midi.Note(
63
+ velocity=velocity,
64
+ pitch=int(note['pitch']),
65
+ start=start,
66
+ end=end,
67
+ )
68
+ instrument.notes.append(note)
69
+ prev_start = start
70
+
71
+ pm.instruments.append(instrument)
72
+ pm.write(out_file)
73
+ return pm
74
+
75
+ def plot_roll(notes: pd.DataFrame, count: Optional[int] = None):
76
+ if count:
77
+ title = f'First {count} notes'
78
+ else:
79
+ title = f'Whole track'
80
+ count = len(notes['pitch'])
81
+ plt.figure(figsize=(20, 4))
82
+ plot_pitch = np.stack([notes['pitch'], notes['pitch']], axis=0)
83
+ plot_start_stop = np.stack([notes['start'], notes['end']], axis=0)
84
+ plt.plot(
85
+ plot_start_stop[:, :count], plot_pitch[:, :count], color="b", marker=".")
86
+ plt.xlabel('Time [s]')
87
+ plt.ylabel('Pitch')
88
+ _ = plt.title(title)
89
+
90
+ def plot_distributions(notes: pd.DataFrame, drop_percentile=2.5):
91
+ plt.figure(figsize=[15, 5])
92
+ plt.subplot(1, 3, 1)
93
+ sns.histplot(notes, x="pitch", bins=20)
94
+
95
+ plt.subplot(1, 3, 2)
96
+ max_step = np.percentile(notes['step'], 100 - drop_percentile)
97
+ sns.histplot(notes, x="step", bins=np.linspace(0, max_step, 21))
98
+
99
+ def predict_next_note(
100
+ notes: np.ndarray,
101
+ model: tf.keras.Model,
102
+ temperature: float = 1.0) -> tuple[int, float, float]:
103
+
104
+ assert temperature > 0
105
+
106
+ inputs = tf.expand_dims(notes, 0)
107
+
108
+ predictions = model.predict(inputs)
109
+ pitch_logits = predictions['pitch']
110
+ step = predictions['step']
111
+ duration = predictions['duration']
112
+
113
+ pitch_logits /= temperature
114
+ pitch = tf.random.categorical(pitch_logits, num_samples=1)
115
+ pitch = tf.squeeze(pitch, axis=-1)
116
+ duration = tf.squeeze(duration, axis=-1)
117
+ step = tf.squeeze(step, axis=-1)
118
+
119
+ step = tf.maximum(0, step)
120
+ duration = tf.maximum(0, duration)
121
+
122
+ return int(pitch), float(step), float(duration)
123
+
124
+ def mse_with_positive_pressure(y_true: tf.Tensor, y_pred: tf.Tensor):
125
+ mse = (y_true - y_pred) ** 2
126
+ positive_pressure = 10 * tf.maximum(-y_pred, 0.0)
127
+ return tf.reduce_mean(mse + positive_pressure)
128
+
129
+ def main():
130
+ seed = 42
131
+ tf.random.set_seed(seed)
132
+ np.random.seed(seed)
133
+
134
+ # Rutas de archivos
135
+ sample_file = '732628744bb532074f4993acfa07c718.mid'
136
+ out_file = 'output.mid'
137
+
138
+ # Cargar modelo y pesos
139
+ with custom_object_scope({'mse_with_positive_pressure': mse_with_positive_pressure}):
140
+ model = keras.models.load_model("mi_modelo_music.h5")
141
+
142
+ model.load_weights("mi_pesos_music.h5", skip_mismatch=False, by_name=False, options=None)
143
+
144
+ # Convertir MIDI generado por el modelo a archivo WAV
145
+ pm = pretty_midi.PrettyMIDI(sample_file)
146
+ instrument_name = pretty_midi.program_to_instrument_name(pm.instruments[0].program)
147
+ raw_notes = midi_to_notes(sample_file)
148
+ key_order = ['pitch', 'step', 'duration']
149
+ seq_length = 25
150
+ vocab_size = 128
151
+ temperature = 2.0
152
+ num_predictions = 120
153
+ sample_notes = np.stack([raw_notes[key] for key in key_order], axis=1)
154
+ input_notes = (sample_notes[:seq_length] / np.array([vocab_size, 1, 1]))
155
+ generated_notes = []
156
+ prev_start = 0
157
+ for _ in range(num_predictions):
158
+ pitch, step, duration = predict_next_note(input_notes, model, temperature)
159
+ start = prev_start + step
160
+ end = start + duration
161
+ input_note = (pitch, step, duration)
162
+ generated_notes.append((*input_note, start, end))
163
+ input_notes = np.delete(input_notes, 0, axis=0)
164
+ input_notes = np.append(input_notes, np.expand_dims(input_note, 0), axis=0)
165
+ prev_start = start
166
+
167
+ generated_notes = pd.DataFrame(
168
+ generated_notes, columns=(*key_order, 'start', 'end'))
169
+
170
+ notes_to_midi(
171
+ generated_notes, out_file=out_file, instrument_name=instrument_name)
172
+
173
+ # Interfaz de Streamlit
174
+ st.title("Generador de notas musicales")
175
+
176
+ archivo_midi = open(out_file, 'rb').read()
177
+
178
+ st.download_button(
179
+ label="Descargar MIDI",
180
+ data=archivo_midi,
181
+ file_name=out_file, # Nombre del archivo que se descargará
182
+ mime='audio/midi'
183
+ )
184
+
185
+ if __name__ == "__main__":
186
+ main()
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
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==2.15.0
7
+ keras==2.15.0
8
+
9
+ midi2audio