Keyboard#
[1]:
from manimusic import *
config.media_embed = True; config.media_width = "100%"
_RV = "-v WARNING -qm --progress_bar None --disable_caching Example"
_RI = "-v WARNING -s --progress_bar None --disable_caching Example"
_RV_mid = "-v WARNING -qm -r 1600,400 --progress_bar None --disable_caching Example"
_RI_mid = "-v WARNING -s -r 1600,400 --progress_bar None --disable_caching Example"
NORMAL_RENDER = False
Manim Community v0.17.3
Creation#
[2]:
class Example(Scene):
def construct(self):
keyboard = Keyboard()
self.play(ShowKeyboard(keyboard))
self.wait()
%manim $_RV_mid
class ShowKeyboard(LaggedStart):
def __init__(self, keyboard: Keyboard, anim=GrowFromEdge, *args, lag_ratio=0.05, **kwargs):
self.keyboard = keyboard
if DOWN not in args and anim == GrowFromEdge and "edge" not in kwargs.keys():
args = [UP, *args]
super().__init__(*[
anim(key, *args, **kwargs)
for key in keyboard
],
lag_ratio=lag_ratio,
)
Warning
If you are going to manipulate the keyboard, it is advisable to move the black keys to the front.
[3]:
class Example(Scene):
def construct(self):
self.camera.background_color = WHITE
k = Keyboard(octaves=3)
k.save_state()
self.play(ShowKeyboard(k))
self.add_foreground_mobjects(*k.black_keys)
self.play(k.animate.arrange(RIGHT, aligned_edge=UP, buff=0))
# NOTE: Move keys like stairs
k.generate_target()
k.target.to_edge(DOWN)
for i in range(len(k)-1):
k.target[i+1].shift(UP * 0.15 * i)
self.play(MoveToTarget(k))
self.wait()
self.play(Restore(k))
self.wait()
%manim $_RV
Chords#
[4]:
class Example(Scene):
def construct(self):
keyboard = Keyboard(octaves=5, ref=1)
chord_1 = keyboard.get_chord(0, "C0", "E0", "G0", "C0").set_color(RED)
chord_2 = keyboard.get_chord(2, "C0", "E0", "G0", "C0").set_color(BLUE)
# octaves
chord_3 = keyboard.get_chord(3, "F0", "F1", "A0").set_color(YELLOW)
self.play(ShowKeyboard(keyboard))
self.add(chord_1, chord_2, chord_3)
%manim $_RI_mid

[5]:
class Example(Scene):
def construct(self):
keyboard = Keyboard(octaves=5, ref=1)
# C, D, F, G, A can have #
# D, E, G, A, B can have b
chord_1 = keyboard.get_chord(0, "C#0", "E0", "G0", "C0").set_color(RED)
chord_2 = keyboard.get_chord(2, "C0", "E0", "Gb0", "C0").set_color(BLUE)
# diminished octaves
chord_3 = keyboard.get_chord(3, "F#0", "F0", "Ab0").set_color(YELLOW)
self.play(ShowKeyboard(keyboard))
self.add(chord_1, chord_2, chord_3)
%manim $_RI_mid

[6]:
class Example(Scene):
def construct(self):
keyboard = Keyboard(octaves=3, ref=1, chord_colors=[PINK, RED])
chord_1 = keyboard.get_chord(0, *fm("Ab0|A#1|B0"))
self.play(ShowKeyboard(keyboard))
self.add(chord_1)
%manim $_RI_mid

Sounds function#
Remember that Jupyter Notebook does not support audio, so we will have to render the scenes using the render method.
[7]:
def render(scene):
with tempconfig({
"frame_rate": 30,
"quality": "medium_quality",
"preview": True,
"disable_caching": True, # <- For sounds
"verbosity": "WARNING"
}):
scene().render()
[8]:
class Example(Scene):
def construct(self):
keyboard = Keyboard(octaves=5, ref=1)
chord_1 = keyboard.get_chord(0, "C0", "E0", "G0", "C0")
chord_2 = keyboard.get_chord(2, "C0", "E0", "G0", "C0")
chord_3 = keyboard.get_chord(3, "F0", "F1", "A0")
self.add(keyboard, keyboard.black_keys)
self.play(
FadeIn(chord_1),
KeyboardSound(keyboard, chord_1)
)
self.play(
FadeIn(chord_2),
KeyboardSound(keyboard, chord_2)
)
self.play(
FadeIn(chord_3),
KeyboardSound(keyboard, chord_3, sound_kwargs={"gain":-18})
# Scene.add_sound(file, **sound_kwargs)
)
if NORMAL_RENDER:
render(Example)
%manim $_RV_mid
[9]:
class Example(Scene):
def construct(self):
keyboard = Keyboard(octaves=5, ref=1)
arpeggio = VGroup(*[
keyboard.get_chord(0, ch)
for ch in fm("C#0|F0|G#0|C#1")
])
self.add(keyboard, keyboard.black_keys)
sound_kwargs={
# "gain": -15
}
indexes = []
for ch in arpeggio:
self.play(
GrowFromCenter(ch),
KeyboardSound(keyboard, ch, sound_kwargs=sound_kwargs)
)
indexes += ch.indexes
self.play(
arpeggio.animate.set_color(YELLOW),
KeyboardSoundIndexes(keyboard, indexes, sound_kwargs=sound_kwargs)
)
self.wait()
if NORMAL_RENDER:
render(Example)
%manim $_RV_mid
All together#
[10]:
class Example(Scene):
def construct(self):
colors = [RED, TEAL, ORANGE, BLUE]
staff = Staff(clefs="gf", width=12, height=0.8).to_edge(UP)
k = Keyboard(octaves=4, chord_colors=colors, ref=1).to_edge(DOWN)
k_chords = VGroup(
k.get_chord(1, "C0", "G0", "Eb0", "C0"),
k.get_chord(0, "F0", "Ab1", "F0", "C0"),
k.get_chord(0, "G0", "G1", "D0", "Bb0"),
k.get_chord(0, "C0", "G1", "Eb0", "C0"),
)
chords = HarmonyProgression(
staff,
"c|Cd ,Gu |Ebd,C1u",
"c|F-1d,Abu|Fd ,C1u",
"c|G-1d,Gu |Dd ,Bbu",
"m|C-1d,Gu |Ebd,C1u",
colors=k.chord_colors
)
t_chords = VGroup(*[
MathTex("\\rm %s"%t_name)
.next_to(staff, DOWN, buff=0.6)
.match_x(c)
for c,t_name in zip(chords, "I-|IV-|V-|I-".split('|'))
])
self.play(
ShowStaff(staff),
ShowKeyboard(k),
run_time=2
)
self.play(
chords.show_chord(0, Write),
KeyboardSound(k, k_chords[0], pause=1),
LaggedStartMap(GrowFromCenter, k_chords[0]),
Write(t_chords[0])
)
for i in range(1,len(chords)):
self.play(
*chords.transform(i-1, i),
ReplacementTransform(k_chords[i-1], k_chords[i]),
Write(t_chords[i]),
run_time=2
)
self.play(KeyboardSound(k, k_chords[i]), run_time=0.1)
self.wait()
if NORMAL_RENDER:
render(Example)
%manim $_RV