import collections import random import pandas as pd import matplotlib.pyplot as plt import matplotlib.colors as mcolors 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") colors = [mcolors.CSS4_COLORS[name] for i, name in enumerate(list(mcolors.CSS4_COLORS))] random.shuffle(colors) colordict = {inst: colors[i] for i, inst 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