542
542
log.exception('Could not remove directory: {path}'.format(path=save_path))
543
543
song_plugin.manager.delete_object(Song, song_id)
546
def transpose_lyrics(lyrics, transepose_value):
550
:param lyrcs: The lyrics to be transposed
551
:param transepose_value: The value to transpose the lyrics with
552
:return: The transposed lyrics
554
# Split text by verse delimiter - both normal and optional
555
verse_list = re.split('(---\[.+?:.+?\]---|\[---\])', lyrics)
556
transposed_lyrics = ''
557
notation = Settings().value('songs/chord notation')
558
for verse in verse_list:
559
if verse.startswith('---[') or verse == '[---]':
560
transposed_lyrics += verse
562
transposed_lyrics += transpose_verse(verse, transepose_value, notation)
563
return transposed_lyrics
566
def transpose_verse(verse_text, transepose_value, notation):
570
:param lyrcs: The lyrics to be transposed
571
:param transepose_value: The value to transpose the lyrics with
572
:return: The transposed lyrics
574
if '[' not in verse_text:
576
# Split the lyrics based on chord tags
577
lyric_list = re.split('(\[|\]|/)', verse_text)
578
transposed_lyrics = ''
580
for word in lyric_list:
582
transposed_lyrics += word
588
transposed_lyrics += word
590
transposed_lyrics += word
592
# This MUST be a chord
593
transposed_lyrics += transpose_chord(word, transepose_value, notation)
594
# If still inside a chord tag something is wrong!
598
return transposed_lyrics
601
def transpose_chord(chord, transpose_value, notation):
603
Transpose chord according to the notation used.
604
NOTE: This function has a javascript equivalent in chords.js - make sure to update both!
606
:param chord: The chord to transpose.
607
:param transpose_value: The value the chord should be transposed.
608
:param notation: The notation to use when transposing.
609
:return: The transposed chord.
611
# See https://en.wikipedia.org/wiki/Musical_note#12-tone_chromatic_scale
612
notes_sharp_notation = {}
613
notes_flat_notation = {}
614
notes_sharp_notation['german'] = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'H']
615
notes_flat_notation['german'] = ['C', 'Db', 'D', 'Eb', 'Fb', 'F', 'Gb', 'G', 'Ab', 'A', 'B', 'H']
616
notes_sharp_notation['english'] = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
617
notes_flat_notation['english'] = ['C', 'Db', 'D', 'Eb', 'Fb', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B']
618
notes_sharp_notation['neo-latin'] = ['Do', 'Do#', 'Re', 'Re#', 'Mi', 'Fa', 'Fa#', 'Sol', 'Sol#', 'La', 'La#', 'Si']
619
notes_flat_notation['neo-latin'] = ['Do', 'Reb', 'Re', 'Mib', 'Fab', 'Fa', 'Solb', 'Sol', 'Lab', 'La', 'Sib', 'Si']
620
chord_split = chord.replace('♭', 'b').split('/')
621
transposed_chord = ''
623
notes_sharp = notes_sharp_notation[notation]
624
notes_flat = notes_flat_notation[notation]
625
notes_preferred = ['b', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#']
626
for i in range(0, len(chord_split)):
628
transposed_chord += '/'
629
currentchord = chord_split[i]
630
if currentchord and currentchord[0] == '(':
631
transposed_chord += '('
632
if len(currentchord) > 1:
633
currentchord = currentchord[1:]
636
if len(currentchord) > 0:
637
if len(currentchord) > 1:
638
if '#b'.find(currentchord[1]) == -1:
639
note = currentchord[0:1]
640
rest = currentchord[1:]
642
note = currentchord[0:2]
643
rest = currentchord[2:]
647
notenumber = notes_flat.index(note) if note not in notes_sharp else notes_sharp.index(note)
648
notenumber += transpose_value
649
while notenumber > 11:
651
while notenumber < 0:
654
current_chord = notes_sharp[notenumber] if notes_preferred[notenumber] == '#' else notes_flat[
656
last_chord = current_chord
658
current_chord = notes_flat[notenumber] if last_chord not in notes_sharp else notes_sharp[notenumber]
659
if not (note not in notes_flat and note not in notes_sharp):
660
transposed_chord += current_chord + rest
662
transposed_chord += note + rest
663
return transposed_chord