freedom
Makefile
.PHONY: wav mp3 clean
.PRECIOUS: %.wav
wav: freedom.wav
mp3: freedom.mp3
clean:
git clean -Xdf
%.mp3: %.wav %.id3
tz tag $<
ffmpeg -y -i $< $@
%.wav: def.mel %.mel
cat $^ | tz mel $@
%_fitted.wav: %.wav def.mel %_fit.mel
cat $(filter-out $<, $^) | tz mel $< - $@
url = https://janberges.de/freedom
%.wav: speak.py %.txt
wget -O $@ $(url)/$(@F) || curl -o $@ $(url)/$(@F) || python3 $< $*
touch $@
parts/b_hi.wav: melody/b_hi1.wav melody/b_hi1.wav melody/b_hi2.wav melody/b_hi1.wav
tz stick $+ $@
parts/chords_a.wav: chords/g.wav chords/g.wav chords/g.wav chords/a.wav
tz stick $+ $@
parts/chords_c.wav: chords/e.wav chords/e.wav chords/e.wav chords/a.wav
tz stick $+ $@
parts/a1.wav: drums/hihat.wav parts/chords_a.wav
tz stack $^ $@
parts/a2.wav: parts/a1.wav drums/bass.wav
tz stack $^ $@
parts/a3.wav: parts/a2.wav melody/a_lo.wav
tz stack $^ $@
parts/a4.wav: parts/a3.wav melody/a_mi.wav melody/a_hi.wav
tz stack $^ $@
parts/b.wav: drums/bass.wav drums/hihat.wav chords/e.wav melody/b_lo.wav melody/b_mi.wav parts/b_hi.wav
tz stack $^ $@
parts/c.wav: drums/bass.wav parts/chords_c.wav
tz stack $^ $@
parts/intro.wav: parts/a1.wav parts/a2.wav
tz stick $+ $@
parts/verse1.wav: parts/a3.wav lyrics/verse1_fitted.wav
tz stack $^ $@
parts/verse2.wav: parts/a3.wav lyrics/verse2_fitted.wav
tz stack $^ $@
parts/verse3.wav: parts/a3.wav lyrics/verse3_fitted.wav
tz stack $^ $@
parts/chorus.wav: parts/a4.wav parts/a4.wav parts/b.wav
tz stick $+ $@
parts/outro.wav: parts/c.wav lyrics/outro_fitted.wav
tz stack $^ $@
freedom.wav: parts/intro.wav parts/verse1.wav parts/chorus.wav parts/c.wav parts/verse2.wav parts/chorus.wav parts/c.wav parts/verse3.wav parts/chorus.wav parts/outro.wav
tz stick $+ $@
chords/a.mel
~ water
&0.3849
M P0 C5 (20 <25 '8
W P0 E5 (00 <25 '8
W P0 A5 )20 <25 '8
chords/e.mel
~ water
&0.3849
M P0 G5 (20 <25 '8
W P0 B5 (00 <25 '8
W P0 E6 )20 <25 '8
chords/g.mel
~ water
&0.3849
M P0 D5 (20 <25 '8
W P0 G5 (00 <25 '8
W P0 B5 )20 <25 '8
def.mel
$44100 O2
|1:4 T equal G
N smooth 0.025
drums/bass.mel
~ harmonic
N smooth 0.001
!25
E3 \30 ,0 '1 \0 ,25 ''
B3 \30 ,0 '1 \0 ,25 '
G3 \30 ,0 '1 \0 ,25 ''
drums/hihat.mel
&0.7071 ,25
N smooth 0.0025
M %1:1000 I
~ random @
!3 ' !8 ' !13 '
W ]1000:1 J
freedom.id3
TIT2 Freiheit ist Sklaverei
TALB Tonbandfetzen
TPE1 Jan Berges
APIC ../../logo/Tonbandfetzen.png
lyrics/outro.txt
Heute ist mein ganzes Leben dadurch bestimmt,
mein unstillbares Verlangen zu besänftigen.
Du hast mich ganz in der Hand.
lyrics/outro_fit.mel
~ #1
N smooth 0
&75 @1:16 '64
lyrics/verse1.txt
Manchmal erinnere ich mich noch an die Zeit,
als ich mit der Welt tief verwurzelt und im Reinen war.
Ich war nie weit gekommen,
doch selbst das Fremde erschien mir vertraut.
lyrics/verse1_fit.mel
~ #1
N smooth 0
&75 @1:16 '64
lyrics/verse2.txt
Eines Tages hast du mich gefunden und mir Geschichten von der Freiheit erzählt,
die in mir eine Sehnsucht geweckt haben,
die so stark war,
dass ich dich meine Wurzeln freilegen und mich mit auf deine Reise nehmen ließ.
Ich war davon verzaubert,
jeden Tag so viel Neues zu sehen,
dass ich wünschte,
wir hielten nie wieder an.
lyrics/verse2_fit.mel
~ #1
N smooth 0
&75 @1:32 '128
lyrics/verse3.txt
Ich wollte mehr.
Irgendwann spürte ich dann erstmals diesen Durst aufkommen,
der mich immer öfter dazu zwang,
dich um etwas zu trinken zu bitten.
Dem bist du auch immer mit einem Lächeln auf den Lippen nachgekommen.
lyrics/verse3_fit.mel
~ #1
N smooth 0
&75 @1:16 '64
melody/a_hi.mel
~ circular
&1:2 !20 [20 }40
E4 ' G4 ' E4 ' B3 ' E4 ' G4 ' E4 ' B3 '
E4 ' F#4 ' E4 ' B3 ' E4 ' F#4 ' E4 ' D4 '
B3 ' C4 ' B3 ' D4 ' B3 ' C4 ' B3 ' D4 '
B3 ' C4 ' B3 ' D4 ' B3 ' C4 ' B3 ' D4 '
melody/a_lo.mel
~ circular
M1
&1:2 !20 [00 {00
E2 ' E2 ' E2 ' E2 ' E2 ' E2 ' E2 ' E2 '
E2 ' E2 ' E2 ' E2 ' E2 ' E2 ' E2 ' E2 '
G2 ' G2 ' G2 ' G2 ' G2 ' G2 ' G2 ' G2 '
A2 ' A2 ' A2 ' A2 ' A2 ' A2 ' A2 ' A2 '
M2
~ harmonic
X flanger 1 2 0.0125 2
melody/a_mi.mel
~ circular
&1:2 !20 ]20 {40
E3 ' G3 ' D3 ' F#3 ' D4 ' C4 ' B3 ' A3 '
G3 ' C4 ' F#3 ' B3 ' E3 ' G3 ' D3 ' F#3 '
G3 ' F#3 ' B3 ' F#3 ' G3 ' F#3 ' D4 ' F#3 '
A3 ' G3 ' F#3 ' G3 ' A3 ' G3 ' F#3 ' B3 '
melody/b_hi1.mel
~ circular
&1:2 !20 [20 }40
G4 ' E4 ' D4 ' E4 ' G4 ' E4 ' D4 ' E4 '
melody/b_hi2.mel
~ circular
&1:2 !20 [20 }40
A4 ' E4 ' D4 ' E4 ' A4 ' E4 ' D4 ' E4 '
melody/b_lo.mel
~ circular
M1
&1:2 !20 [00 {00
C3 ' C3 ' C3 ' C3 ' C3 ' C3 ' D3 ' C3 '
E3 ' E3 ' E3 ' E3 ' E3 ' E3 ' A2 ' B2 '
M2
~ harmonic
X flanger 1 2 0.00625 2
melody/b_mi.mel
~ circular
&1:2 !20 ]20 {40
E3 ' G3 ' C4 ' D4 ' C4 ' A3 ' B3 ' G3 '
E3 ' B3 ' G3 ' F#3 ' E3 ' D3 ' E3 ' G3 '
speak.py
import re
import subprocess
import sys
job = sys.argv[1]
def speak(speed):
subprocess.call(['espeak-ng', '-vde+f5', '-s%g' % speed,
'-f%s.txt' % job, '-w%s.wav' % job])
time = float(re.search(r'Duration:\s*(\S+)\s*s\b',
str(subprocess.check_output(['inspect', '%s.wav' % job]))).group(1))
print('%s takes %g seconds at %g words per minute' % (job, time, speed))
return time
with open('%s.fit' % job) as lines:
for line in lines:
for match in re.findall(r'@1:([\d.]+)', line):
t = float(match)
s0 = 120.0
t0 = speak(s0)
speak(s0 * t0 / t)