In [448]:
# song = list(open('有一天.txt', 'r').readlines())
def read_song(filename):
import codecs
song = codecs.open(filename, 'r', 'utf-8').readlines()
key = ''
modifier = ''
title = None
arrangement = []
parts = dict()
for line in song:
# Parse the title
if line[0:7] == '>>Title':
title = line.split(': ')[1].strip('\n')
# Parse the current key of the arrangement
if line[0:5] == '>>Key':
current_key = line.split(':')[1].strip('\n').strip(' ').split(';')
key = current_key[0]
if len(current_key) > 1:
modifier = current_key[1]
else:
modifier = ''
# Parse the arrangement
if line[0:13] == '>>Arrangement':
arrangement = [part.strip('\n').strip(' ') for part in line.split(': ')[1].split(',')]
# Parse out each part
if line[0:3] == '>>>':
part = line[3:].strip('\n')
parts[part] = dict()
line_counter = 0
# This variable checks to make sure that we are parsing the correct part
part_is_correct = False
for line2 in song:
# Make sure that the part variable is correct, then we can proceed
if line2[0:3] == '>>>' and line2[3:].strip('\n') == part:
part_is_correct = True
# Grab each chord and its position in the chord progression
if line2[0:2] == 'C:' and part_is_correct:
line_counter += 1
parts[part][line_counter] = dict()
parts[part][line_counter]['chords'] = dict()
chords = [c for c in line2.strip('\n').split(':')[1].split(' ') if c != '']
for chord in chords:
position = line2[2:].index(chord)
parts[part][line_counter]['chords'][position] = chord
# Grab out the lyrics
if line2[0:2] == 'L:' and part_is_correct:
parts[part][line_counter]['lyrics'] = line2.strip('\n').split(':')[1]
# End parsing
if line2[0:3] == '<<<' and part_is_correct:
break
return title, key, modifier, arrangement, parts
In [449]:
def get_transpose_delta(oldkey, newkey):
keys = ['A', 'Bb', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'Ab']
old_idx = keys.index(oldkey)
new_idx = keys.index(newkey)
return (new_idx - old_idx)
def transpose_parts(parts, transpose_delta):
from copy import deepcopy
transposed_parts = deepcopy(parts)
for part, lines in transposed_parts.items():
for line, contents in lines.items():
for position, chord in contents['chords'].items():
contents['chords'][position] = get_transposed_chord(chord, transpose_delta)
return transposed_parts
In [454]:
title, key, modifier, arrangement, parts = read_song(u'有一天_input.txt')
# print(transpose_parts(parts, transpose_delta))
print(modifier)
In [471]:
# Prototyped code for output
def write_chords(filename, title, key, modifier, arrangement, parts, new_key):
newkey = new_key.split(';')[0]
if len(new_key.split(';')) > 1:
newmodifier = new_key.split(';')[1]
else:
newmodifier = ''
if newmodifier != modifier:
raise Exception('New key does not have the same modifier as old key.')
import codecs
with codecs.open(filename, "w+", "utf-8") as f:
keys = ['A', 'Bb', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'Ab']
f.write(u'Title: {0}\n'.format(title))
f.write(u'Key: {0}{1}\n'.format(newkey, modifier))
f.write(u'Arrangement: ')
for part in arrangement:
f.write('{0} '.format(part))
f.write('\n\n')
transpose_delta = get_transpose_delta(key, newkey)
parts = transpose_parts(parts, transpose_delta)
for part in arrangement:
f.write(u'{0}\n'.format(part))
lines = parts[part]
for line, contents in lines.items():
chordstring = ' '
maxchordpos = max(contents['chords'].keys())
i = 1
while i < maxchordpos + 1:
if i not in contents['chords'].keys():
chordstring += ' '
i += 1
else:
for s in contents['chords'][i].split(';'):
chordstring += s
i += len(s)
f.write(u'{0}\n'.format(chordstring))
f.write(u'{0}\n'.format(contents['lyrics']))
f.write('\n')
In [472]:
print(title)
In [473]:
# transpose_delta = get_transpose_delta('A', 'C')
print(write_chords('有一天 Dmaj.txt', title, key, modifier, arrangement, parts, 'D'))
In [329]:
# Function for doing chord transposition
def get_transposed_key(current_key, transpose_delta):
"""
Note: only handles the base key and chord key, no modifiers allowed!
"""
current_idx = keys.index(current_key)
new_idx = current_idx + transpose_delta
if new_idx >= len(keys):
new_idx = new_idx % len(keys)
# print(new_idx)
return keys[new_idx]
In [247]:
# Prototype code for computing transposition
chord_progression = ['D', 'A', 'C;m', 'G;m7', 'G/C']
def get_transposed_chord(current_chord, transpose_delta):
# Get the base key
if len(current_chord.split('/')) > 1:
basekey = current_chord.split('/')[1]
else:
basekey = ''
# Get the chord key
chordkey = current_chord.split('/')[0].split(';')[0]
# Get any modifiers
if len(current_chord.split(';')) > 1:
modifier = current_chord.split(';')[1]
else:
modifier = ''
# Transpose the chord key:
new_chordkey = get_transposed_key(chordkey, transpose_delta)
# Transpose the base key:
if basekey != '':
new_basekey = get_transposed_key(basekey, transpose_delta)
return(new_chordkey + modifier + '/' + new_basekey)
else:
return(new_chordkey + modifier)
In [ ]:
In [1]:
from transpose import SheetMusic
In [2]:
sm = SheetMusic()
sm.read_song('有一天_input.txt')
sm.parse_song()
sm.set_new_key('E')
# sm.set_transpose_delta()
# sm.set_transposed_parts()
# print(sm.transposed_parts)
print(sm.arrangement)
sm.write_chords('有一天_output.txt')
In [5]:
In [ ]: