-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcreate_song.py
72 lines (59 loc) · 2.14 KB
/
create_song.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import re
import tempfile
import time
import subprocess
import curses
from curses.ascii import isdigit
import nltk
from nltk.corpus import cmudict
from beatmaps import BEATMAPS
cmu = cmudict.dict()
BREAK = re.compile('[a-zA-Z@#]+')
XML_HEADER = '''<?xml version="1.0"?>
<!DOCTYPE SINGING PUBLIC "-//SINGING//DTD SINGING mark up//EN"
"Singing.v0_1.dtd"
[]>
<SINGING>
'''
XML_FOOTER = '</SINGING>\n'
def nsyl(word):
pronounce = cmu.get(word.lower())
if pronounce:
pronounce = pronounce[0]
return len(list(y for y in pronounce if isdigit(y[-1])))
else:
return 3
def text_to_song_file(tweet_text, tweet_id=None):
if tweet_id is None:
tweet_id = time.time()
words = BREAK.findall(tweet_text)
print words
words_syls = [(word, nsyl(word)) for word in words if word]
# TODO randomize this, or decide on a beatmap based on the phrasing (would be nice)
beatmap = BEATMAPS[0]
with tempfile.NamedTemporaryFile() as xml_file:
xml_file.write(XML_HEADER)
bm_iter = iter(beatmap)
for word, syl in words_syls:
durs = []
notes = []
for _ in range(syl):
next_bm = bm_iter.next()
if next_bm is None:
# TODO handle the case where we are out of notes
break
durs.append(next_bm[0])
notes.append(next_bm[1])
cleaned_word = word.replace('@', '').replace('#', '')
xml_file.write('<DURATION BEATS="%s"><PITCH NOTE="%s">%s</PITCH></DURATION>\n' %
(','.join([str(x) for x in durs]), ','.join(notes), cleaned_word))
xml_file.write(XML_FOOTER)
xml_file.flush()
with open(xml_file.name) as f:
print f.read()
outfile_name = '/tmp/%s.wav' % tweet_id
subprocess.call(['/home/tweetsong/festival/bin/text2wave', '-mode', 'singing', xml_file.name, '-o', outfile_name])
return outfile_name
#text_to_song_file('Test this thing please')
#text_to_song_file('sing thing tweet please dont screw this up')
#text_to_song_file('singthingtweet please dont screw this up')