In [1]:
import waloviz as wv
wv.extension()
In [2]:
# Utilities for playing music
import numpy as np
sr = 8000
notes = {"G": 392.00, "A": 440.00, "B": 493.88, "C": 523.25, "D": 587.33, "E": 659.26, "F": 698.46}
def pause(seconds: float):
return np.zeros(int(seconds*sr))
def play(note: str, seconds: float):
pause_seconds = 0.1
note_seconds = seconds - pause_seconds
time = np.linspace(0, 2*np.pi*note_seconds, int(sr*note_seconds))
freq = notes[note]
sound = np.sin(time*freq)
pause_samples = int(pause_seconds*sr)
sound[:pause_samples] = sound[:pause_samples] * np.linspace(0, 1, pause_samples)
sound[-pause_samples:] = sound[-pause_samples:] * np.linspace(1, 0, pause_samples)
return np.concatenate([sound, pause(pause_seconds)], axis=-1)
In [3]:
# Playing a happy little melody for a happy little star!
twinkle_melody = np.concatenate([
play("G", 0.25), play("G", 0.25),
play("D", 0.25), play("D", 0.25),
play("E", 0.25), play("E", 0.25),
play("D", 0.40), pause(0.1),
play("C", 0.25), play("C", 0.25),
play("B", 0.25), play("B", 0.25),
play("A", 0.25), play("A", 0.25),
play("G", 0.40), pause(0.1),
])
wv.Audio(
(twinkle_melody, sr),
{note: np.ones(2)*freq for note, freq in reversed(notes.items())},
over_curve_axes={note: "Hz" for note in notes.keys()},
axes_limits=dict(Hz=(350, 750)),
minimal=True
)
Out[3]: