1# utilities.py
2# -*- coding: utf-8 -*-
3#
4# This file is part of LilyPond, the GNU music typesetter.
5#
6# Copyright (C) 2016--2020 John Gourlay <john@weathervanefarm.net>
7#
8# LilyPond is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# LilyPond is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
20
21
22import re
23
24
25def string_to_number(s):
26    try:
27        return int(s)
28    except ValueError:
29        return float(s)
30
31
32def string_to_integer(s):
33    num = string_to_number(s)
34    if isinstance(num, int):
35        return num
36    else:
37        return int(num)
38
39
40def escape_ly_output_string(input_string):
41    return_string = input_string
42    needs_quotes = not re.match("^[a-zA-ZäöüÜÄÖßñ]*$", return_string)
43    if needs_quotes:
44        return_string = "\"" + return_string.replace("\"", "\\\"") + "\""
45    return return_string
46
47
48def interpret_alter_element(alter_elm):
49    alter = 0
50    if alter_elm:
51        val = eval(alter_elm.get_text())
52        if type(val) in (int, float):
53            alter = val
54    return alter
55
56
57def musicxml_duration_to_log(dur):
58    return {'256th': 8,
59            '128th': 7,
60            '64th': 6,
61            '32nd': 5,
62            '16th': 4,
63            'eighth': 3,
64            'quarter': 2,
65            'half': 1,
66            'whole': 0,
67            'breve': -1,
68            'longa': -2,
69            'long': -2}.get(dur, 0)
70
71
72def hexcolorval_to_nr(hex_val):
73    try:
74        v = int(hex_val, 16)
75        if v == 255:
76            v = 256
77        return v / 256.
78    except ValueError:
79        return 0.
80
81
82def hex_to_color(hex_val):
83    res = re.match(
84        r'#([0-9a-f][0-9a-f]|)([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$',
85        hex_val,
86        re.IGNORECASE)
87    if res:
88        return [hexcolorval_to_nr(x) for x in res.group(2, 3, 4)]
89    else:
90        return None
91
92
93def split_string_and_preserve_doublequoted_substrings(value):
94    import shlex
95    lex = shlex.shlex(value)
96    lex.quotes = '"'
97    lex.whitespace_split = True
98    lex.commenters = ''
99    return list(lex)
100
101
102def musicxml_sound_to_lilypond_midi_instrument(sound):
103    sounds = {
104        "brass.french-horn": 'french horn',
105        "brass.group": 'brass section',
106        "brass.group.synth": 'synthbrass 1',
107        "brass.trombone": 'trombone',
108        "brass.trombone.alto": 'trombone',
109        "brass.trombone.bass": 'trombone',
110        "brass.trombone.contrabass": 'trombone',
111        "brass.trombone.tenor": 'trombone',
112        "brass.trumpet": 'trumpet',
113        "brass.trumpet.baroque": 'trumpet',
114        "brass.trumpet.bass": 'trumpet',
115        "brass.trumpet.bflat": 'trumpet',
116        "brass.trumpet.c": 'trumpet',
117        "brass.trumpet.d": 'trumpet',
118        "brass.trumpet.piccolo": 'trumpet',
119        "brass.trumpet.pocket": 'trumpet',
120        "brass.trumpet.slide": 'trumpet',
121        "brass.trumpet.tenor": 'trumpet',
122        "brass.tuba": 'tuba',
123        "brass.tuba.bass": 'tuba',
124        "brass.tuba.subcontrabass": 'tuba',
125        "brass.wagner-tuba": 'french horn',
126        "drum.timpani": 'timpani',
127        "drum.tom-tom": 'melodic tom',
128        "drum.tom-tom.synth": 'synth drum',
129        "effect.applause": 'applause',
130        "effect.bass-string-slap": 'slap bass 1',
131        "effect.bird": 'bird tweet',
132        "effect.bird.tweet": 'bird tweet',
133        "effect.breath": 'breath noise',
134        "effect.guitar-fret": 'guitar fret noise',
135        "effect.gunshot": 'gunshot',
136        "effect.helicopter": 'helicopter',
137        "effect.metronome-click": 'woodblock',
138        "effect.rain": 'fx1 (rain)',
139        "effect.seashore": 'seashore',
140        "effect.telephone-ring": 'telephone ring',
141        "keyboard.accordion": 'accordion',
142        "keyboard.bandoneon": 'accordion',
143        "keyboard.celesta": 'celesta',
144        "keyboard.clavichord": 'clav',
145        "keyboard.concertina": 'concertina',
146        "keyboard.harpsichord": 'harpsichord',
147        "keyboard.ondes-martenot": 'ocarina',
148        "keyboard.organ": 'church organ',
149        "keyboard.organ.drawbar": 'drawbar organ',
150        "keyboard.organ.percussive": 'percussive organ',
151        "keyboard.organ.pipe": 'church organ',
152        "keyboard.organ.reed": 'reed organ',
153        "keyboard.piano": 'acoustic grand',
154        "keyboard.piano.electric": 'electric piano 1',
155        "keyboard.piano.grand": 'acoustic grand',
156        "keyboard.piano.honky-tonk": 'honky-tonk',
157        "metal.bells.agogo": 'agogo',
158        "metal.bells.tinklebell": 'tinkle bell',
159        "metal.cymbal.reverse": 'reverse cymbal',
160        "pitched-percussion.glockenspiel": 'glockenspiel',
161        "pitched-percussion.glockenspiel.alto": 'glockenspiel',
162        "pitched-percussion.glockenspiel.soprano": 'glockenspiel',
163        "pitched-percussion.hammer-dulcimer": 'dulcimer',
164        "pitched-percussion.kalimba": 'kalimba',
165        "pitched-percussion.marimba": 'marimba',
166        "pitched-percussion.marimba.bass": 'marimba',
167        "pitched-percussion.music-box": 'music box',
168        "pitched-percussion.tubular-bells": 'tubular bells',
169        "pitched-percussion.vibraphone": 'vibraphone',
170        "pitched-percussion.xylophone": 'xylophone',
171        "pitched-percussion.xylophone.alto": 'xylophone',
172        "pitched-percussion.xylophone.bass": 'xylophone',
173        "pitched-percussion.xylophone.soprano": 'xylophone',
174        "pitched-percussion.xylorimba": 'xylophone',
175        "pluck.banjo": 'banjo',
176        "pluck.banjo.tenor": 'banjo',
177        "pluck.bass": 'acoustic bass',
178        "pluck.bass.acoustic": 'acoustic bass',
179        "pluck.bass.electric": 'electric bass',
180        "pluck.bass.fretless": 'fretless bass',
181        "pluck.bass.synth": 'synth bass 1',
182        "pluck.dulcimer": 'dulcimer',
183        "pluck.guitar": 'acoustic guitar (nylon)',
184        "pluck.guitar.acoustic": 'acoustic guitar (nylon)',
185        "pluck.guitar.electric": 'electric guitar (jazz)',
186        "pluck.guitar.nylon-string": 'acoustic guitar (nylon)',
187        "pluck.guitar.steel-string": 'acoustic guitar (steel)',
188        "pluck.harp": 'orchestral harp',
189        "pluck.lute": 'acoustic guitar (nylon)',
190        "pluck.shamisen": 'shamisen',
191        "pluck.sitar": 'sitar',
192        "strings.cello": 'cello',
193        "strings.cello.piccolo": 'cello',
194        "strings.contrabass": 'contrabass',
195        "strings.fiddle": 'fiddle',
196        "strings.group.synth": 'synth strings 1',
197        "strings.viola": 'viola',
198        "strings.violin": 'violin',
199        "synth.effects.atmosphere": 'fx 4 (atmosphere)',
200        "synth.effects.brightness": 'fx 5 (brightness)',
201        "synth.effects.crystal": 'fx 3 (crystal)',
202        "synth.effects.echoes": 'fx 7 echoes',
203        "synth.effects.goblins": 'fx 6 goblins',
204        "synth.effects.rain": 'fx 1 rain',
205        "synth.effects.sci-fi": 'fx 8 sci-fi',
206        "synth.effects.soundtrack": 'fx 2 (soundtrack)',
207        "synth.pad.bowed": 'pad 5 bowed',
208        "synth.pad.choir": 'pad 4 choir',
209        "synth.pad.halo": 'pad 7 halo',
210        "synth.pad.metallic": 'pad 6 metallic',
211        "synth.pad.polysynth": 'pad 3 polysynth',
212        "synth.pad.sweep": 'pad 8 sweep',
213        "synth.pad.warm": 'pad 2 warm',
214        "synth.tone.sawtooth": 'lead 1 (square)',
215        "synth.tone.square": 'lead 2 (sawtooth)',
216        "voice.aa": 'choir aahs',
217        "voice.alto": 'choir aahs',
218        "voice.aw": 'choir aahs',
219        "voice.baritone": 'choir aahs',
220        "voice.bass": 'choir aahs',
221        "voice.child": 'choir aahs',
222        "voice.countertenor": 'choir aahs',
223        "voice.doo": 'choir aahs',
224        "voice.ee": 'choir aahs',
225        "voice.female": 'choir aahs',
226        "voice.kazoo": 'choir aahs',
227        "voice.male": 'choir aahs',
228        "voice.mezzo-soprano": 'choir aahs',
229        "voice.mm": 'choir aahs',
230        "voice.oo": 'voice oohs',
231        "voice.soprano": 'choir aahs',
232        "voice.synth": 'synth voice',
233        "wind.flutes.blown-bottle": 'blown bottle',
234        "wind.flutes.calliope": 'lead 3 (calliope)',
235        "wind.flutes.flute": 'flute',
236        "wind.flutes.flute.alto": 'flute',
237        "wind.flutes.flute.bass": 'flute',
238        "wind.flutes.flute.contra-alto": 'flute',
239        "wind.flutes.flute.contrabass": 'flute',
240        "wind.flutes.flute.double-contrabass": 'flute',
241        "wind.flutes.flute.piccolo": 'flute',
242        "wind.flutes.flute.subcontrabass": 'flute',
243        "wind.flutes.ocarina": 'ocarina',
244        "wind.flutes.recorder": 'recorder',
245        "wind.flutes.recorder.alto": 'recorder',
246        "wind.flutes.recorder.bass": 'recorder',
247        "wind.flutes.recorder.contrabass": 'recorder',
248        "wind.flutes.recorder.descant": 'recorder',
249        "wind.flutes.recorder.garklein": 'recorder',
250        "wind.flutes.recorder.great-bass": 'recorder',
251        "wind.flutes.recorder.sopranino": 'recorder',
252        "wind.flutes.recorder.soprano": 'recorder',
253        "wind.flutes.recorder.tenor": 'recorder',
254        "wind.flutes.shakuhachi": 'shakuhachi',
255        "wind.flutes.whistle": 'whistle',
256        "wind.flutes.whistle.alto": 'whistle',
257        "wind.pipes.bagpipes": 'bagpipe',
258        "wind.reed.basset-horn": 'clarinet',
259        "wind.reed.bassoon": 'bassoon',
260        "wind.reed.clarinet": 'clarinet',
261        "wind.reed.clarinet.a": 'clarinet',
262        "wind.reed.clarinet.alto": 'clarinet',
263        "wind.reed.clarinet.bass": 'clarinet',
264        "wind.reed.clarinet.basset": 'clarinet',
265        "wind.reed.clarinet.bflat": 'clarinet',
266        "wind.reed.clarinet.contra-alto": 'clarinet',
267        "wind.reed.clarinet.contrabass": 'clarinet',
268        "wind.reed.clarinet.eflat": 'clarinet',
269        "wind.reed.clarinet.piccolo.aflat": 'clarinet',
270        "wind.reed.contrabass": 'contrabass',
271        "wind.reed.contrabassoon": 'bassoon',
272        "wind.reed.english-horn": 'oboe',
273        "wind.reed.harmonica": 'harmonica',
274        "wind.reed.harmonica.bass": 'harmonica',
275        "wind.reed.oboe": 'oboe',
276        "wind.reed.oboe.bass": 'oboe',
277        "wind.reed.oboe.piccolo": 'oboe',
278        "wind.reed.oboe-da-caccia": 'oboe',
279        "wind.reed.oboe-damore": 'oboe',
280        "wind.reed.saxophone": 'alto sax',
281        "wind.reed.saxophone.alto": 'alto sax',
282        "wind.reed.saxophone.baritone": 'baritone sax',
283        "wind.reed.saxophone.bass": 'baritone sax',
284        "wind.reed.saxophone.contrabass": 'baritone sax',
285        "wind.reed.saxophone.melody": 'soprano sax',
286        "wind.reed.saxophone.mezzo-soprano": 'soprano sax',
287        "wind.reed.saxophone.sopranino": 'soprano sax',
288        "wind.reed.saxophone.sopranissimo": 'soprano sax',
289        "wind.reed.saxophone.soprano": 'soprano, sax',
290        "wind.reed.saxophone.subcontrabass": 'baritone sax',
291        "wind.reed.saxophone.tenor": 'tenor sax',
292        "wind.reed.shenai": 'shanai',
293        "wood.temple-block": 'wood block',
294        "wood.wood-block": 'wood block',
295    }
296    return sounds.get(sound, 'acoustic grand')
297