import collections import pandas as pd import plotly.express as px import matplotlib.pyplot as plt from matplotlib.patches import Rectangle from PIL import Image import note_seq class AudioIOReadError(BaseException): # pylint:disable=g-bad-exception-name pass def upload_audio(audio, sample_rate): return note_seq.audio_io.wav_data_to_samples_librosa(audio, sample_rate=sample_rate) # Generate piano_roll def sequence_to_pandas_dataframe(sequence): pd_dict = collections.defaultdict(list) for note in sequence.notes: pd_dict["start_time"].append(note.start_time) pd_dict["end_time"].append(note.end_time) pd_dict["duration"].append(note.end_time - note.start_time) pd_dict["pitch"].append(note.pitch) pd_dict['instrument'].append(note.instrument) return pd.DataFrame(pd_dict) def dataframe_to_pianoroll_img(df): fig = plt.figure(figsize=(8, 5)) ax = fig.add_subplot(111) ax.scatter(df.start_time, df.pitch, c="white") n_colors = len(df.instrument.unique()) colorscale = px.colors.sample_colorscale("viridis", [n/(n_colors -1) for n in range(n_colors)]) colordict = {f:colorscale[i] for i, f in enumerate(df.instrument.unique())} for _, row in df.iterrows(): ax.add_patch(Rectangle((row["start_time"], row["pitch"]-0.4), row["duration"], 0.4, color=colordict[row["instrument"]])) plt.xlabel('time (sec.)', fontsize=18) plt.ylabel('pitch (MIDI)', fontsize=16) return fig def fig2img(fig): """Convert a Matplotlib figure to a PIL Image and return it""" import io buf = io.BytesIO() fig.savefig(buf, format="png") buf.seek(0) img = Image.open(buf) return img def create_image_from_note_sequence(sequence): df_sequence = sequence_to_pandas_dataframe(sequence) fig = dataframe_to_pianoroll_img(df_sequence) img = fig2img(fig) return img