aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/music.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/music.py')
-rw-r--r--scripts/music.py40
1 files changed, 20 insertions, 20 deletions
diff --git a/scripts/music.py b/scripts/music.py
index a3aee16..2ab6ed2 100644
--- a/scripts/music.py
+++ b/scripts/music.py
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
-"""Cama musical original hecha con las muestras de piano de keysound.
+"""Original music bed made with the keysound piano samples.
-Muestra NN => nota MIDI NN+20 (01-A-大字2组 = A0 = MIDI 21)
-Las progresiones son propias, para que el audio sea libre de derechos.
+Sample NN => MIDI note NN+20 (01-A-大字2组 = A0 = MIDI 21)
+The progressions are original, so the audio is royalty free.
"""
import glob, os, wave
import numpy as np
-PIANO_DIR = "/mnt/Data/GitHub/keysound/audio/piano"
+PIANO_DIR = os.environ.get("PIANO_DIR", "/mnt/Data/GitHub/keysound/audio/piano") # keysound samples
SR = 44100
_paths, _cache = {}, {}
@@ -36,16 +36,16 @@ def load(m):
def chord(sym):
- """'Am' -> (bajo, triada). Soporta sostenidos y sufijo m."""
+ """'Am' -> (bass, triad). Supports sharps and the m suffix."""
q = "min" if sym.endswith("m") else "maj"
root = sym[:-1] if sym.endswith("m") else sym
r = NOTE[root]
- bass = 12 * (2 + 1) + r # octava 2
+ bass = 12 * (2 + 1) + r # octave 2
triad = [12 * (4 + 1) + r + i for i in TRIAD[q]]
return bass, triad
-# progresion + tempo por video
+# progression + tempo per video
BEDS = {
"montyhall": (["Am", "F", "C", "G"], 92),
"nueves": (["Em", "C", "G", "D"], 88),
@@ -73,8 +73,8 @@ BEDS = {
"domino": (["G", "D", "Em", "C"], 104, "motor"),
}
-# melodias propias: por compas, (tiempo en negras, nota MIDI, duracion en negras)
-MELODIAS = {
+# original melodies: per bar, (time in quarter notes, MIDI note, duration in quarter notes)
+MELODIES = {
"motor": [
[(0, 78, 1.5), (1.5, 74, 0.5), (2, 76, 1), (3, 78, 1)], # Bm
[(0, 79, 1.5), (1.5, 78, 0.5), (2, 76, 1), (3, 74, 1)], # G
@@ -86,7 +86,7 @@ MELODIAS = {
def bed(name, total_s, gain=0.30, seed=0):
prog, bpm = BEDS[name][:2]
- estilo = BEDS[name][2] if len(BEDS[name]) > 2 else None
+ style = BEDS[name][2] if len(BEDS[name]) > 2 else None
beat = 60.0 / bpm
measure = 4 * beat
eighth = beat / 2
@@ -111,17 +111,17 @@ def bed(name, total_s, gain=0.30, seed=0):
while t < total_s + 0.5:
sym = prog[k % len(prog)]
bass, triad = chord(sym)
- if estilo == "motor":
- # bajo en corcheas, como un motor; acorde en 1 y 3; melodia arriba
+ if style == "motor":
+ # bass in eighth notes, like an engine; chord on 1 and 3; melody on top
for j in range(8):
hit(bass + (12 if j % 2 else 0), t + j * eighth,
0.34 if j % 2 == 0 else 0.20, max_len=eighth * 0.9)
for b_ in (0, 2):
- for nota in triad:
- hit(nota - 12, t + b_ * beat, 0.13, max_len=beat * 1.8)
- vuelta = (k // 4) % 2 # la segunda vuelta, una octava arriba
- for (b_, nota, d) in MELODIAS[estilo][k % 4]:
- hit(nota + 12 * vuelta, t + b_ * beat, 0.30, max_len=d * beat * 1.05)
+ for note_txt in triad:
+ hit(note_txt - 12, t + b_ * beat, 0.13, max_len=beat * 1.8)
+ turn = (k // 4) % 2 # the second pass, an octave up
+ for (b_, note_txt, d) in MELODIES[style][k % 4]:
+ hit(note_txt + 12 * turn, t + b_ * beat, 0.30, max_len=d * beat * 1.05)
t += measure
k += 1
continue
@@ -132,7 +132,7 @@ def bed(name, total_s, gain=0.30, seed=0):
for j, note in enumerate(pattern):
g = 0.30 if j % 2 == 0 else 0.20
hit(note, t + j * eighth, g, max_len=beat * 1.15)
- if k % 4 == 3: # brillito al cerrar la vuelta
+ if k % 4 == 3: # a little sparkle when the pass closes
hit(triad[2] + 12, t + 3.5 * beat, 0.16, max_len=beat)
t += measure
k += 1
@@ -140,7 +140,7 @@ def bed(name, total_s, gain=0.30, seed=0):
buf = buf[:int(total_s * SR)]
peak = np.abs(buf).max() + 1e-9
buf *= gain / peak
- # entrada y salida suaves
+ # soft fade in and out
fi, fo = int(1.2 * SR), int(2.0 * SR)
buf[:fi] *= np.linspace(0, 1, fi)[:, None]
buf[-fo:] *= np.linspace(1, 0, fo)[:, None]
@@ -148,7 +148,7 @@ def bed(name, total_s, gain=0.30, seed=0):
def duck(music, speech, sr=SR, floor_db=-11.0, block=512, release=0.45):
- """Baja la musica cuando hay voz (sidechain simple)."""
+ """Lowers the music when there is voice (simple sidechain)."""
mono = np.abs(speech).mean(axis=1) if speech.ndim > 1 else np.abs(speech)
nb = len(mono) // block
env = mono[:nb * block].reshape(nb, block).max(axis=1)