def filter_intervals_within_range(lowest, highest, irange): assert isinstance(lowest, basestring) assert isinstance(highest, basestring) lowest = mpd.notename_to_int(lowest) highest = mpd.notename_to_int(highest) i = highest - lowest return [x for x in irange if abs(x) <= i]
def __init__(self, spin_low, spin_high, lowest_value, highest_value): self.g_spin_low = spin_low self.g_spin_low.connect('value-changed', self.on_low_changed) self.g_spin_high = spin_high self.g_spin_high.connect('value-changed', self.on_high_changed) self.m_lowest_value = mpd.notename_to_int(lowest_value) self.m_highest_value = mpd.notename_to_int(highest_value)
def random_tonika_and_interval(lowest, highest, irange): """ Return a tuple (tonika, interval) of types (MusicalPitch, int). Return (None, None) if it is not possible to make an interval because of a conflict between the lowest/highest and the available intervals lowest highest an integer or a string representing a notename irange list of integers representing intervals. 1 is minor second up, -2 is major second down """ assert type(lowest) == type(highest) if isinstance(lowest, basestring): lowest = mpd.notename_to_int(lowest) if isinstance(highest, basestring): highest = mpd.notename_to_int(highest) assert isinstance(lowest, int) assert isinstance(highest, int) assert lowest <= highest assert isinstance(irange, list) # first we find out what is the largest interval we can have i = highest - lowest # then filter irange to only use intervals <= i v = [x for x in irange if abs(x) <= i] if not v: return None, None interval = random.choice(v) # then, using that interval, make a list of possible tonikas tl = [] for t in range(lowest, highest + 1): if lowest <= t + interval <= highest: tl.append(t) tonika = mpd.MusicalPitch.new_from_int(random.choice(tl)) return tonika, interval
def random_tonika_and_interval(lowest, highest, irange): """ Return a tuple (tonika, interval) of types (MusicalPitch, int). lowest notename string highest notename string irange list of integers representing intervals. 1 is minor second up, -2 is major second down Raise NoPossibleIntervals if we cannot create an interval within the given range of tones. """ assert isinstance(lowest, str) assert isinstance(highest, str) lowest = mpd.notename_to_int(lowest) highest = mpd.notename_to_int(highest) assert lowest <= highest assert isinstance(irange, list) # first we find out what is the largest interval we can have i = highest - lowest # then filter irange to only use intervals that fit within that range v = [x for x in irange if abs(x) <= i] if not v: raise NoPossibleIntervals(_("No random interval can be selected within the allowed range of tones.")) interval = random.choice(v) # then, using that interval, make a list of possible tonikas tl = [] for t in range(lowest, highest + 1): if lowest <= t + interval <= highest: tl.append(t) tonika = mpd.MusicalPitch.new_from_int(random.choice(tl)) return tonika, interval
def __init__(self, spin_low, spin_high, lowest_value, highest_value, exname, name_low, name_high): NotenameRangeController.__init__(self, spin_low, spin_high, lowest_value, highest_value) cfg.ConfigUtils.__init__(self, exname) self.m_name_low = name_low self.m_name_high = name_high low = mpd.notename_to_int(self.get_string(self.m_name_low)) high = mpd.notename_to_int(self.get_string(self.m_name_high)) if low > high: low = high self.g_spin_low.set_value(low) self.g_spin_high.set_value(high)
def play_rhythm(self, rhythm): """ rhythm is a string. Example: 'c4 c8 c8 c4' """ # FIXME can we use lessonfile.Rhythm insted of this? score = mpd.parser.parse_to_score_object(rhythm) track = mpd.score_to_tracks(score)[0] track.prepend_bpm(self.get_int("bpm")) track.prepend_volume(cfg.get_int('config/preferred_instrument_volume')) track.replace_note(mpd.notename_to_int("c"), self.get_int("config/rhythm_perc")) track.replace_note(mpd.notename_to_int("d"), self.get_int("config/countin_perc")) soundcard.synth.play_track(track)
def set_range(self, lowest_value, highest_value): """ Set the lowest and highest tone allowed. make a separate function for NotenameRangeController if we need it. """ assert mpd.compare_notenames(lowest_value, highest_value) <= 0 self.m_lowest_value = mpd.notename_to_int(lowest_value) self.m_highest_value = mpd.notename_to_int(highest_value) if self.m_lowest_value > self.g_spin_low.get_value(): self.set_string(self.m_name_low, lowest_value) self.g_spin_low.set_value(self.m_lowest_value) if self.m_highest_value < self.g_spin_high.get_value(): self.set_string(self.m_name_high, highest_value) self.g_spin_high.set_value(self.m_highest_value)
def random_tonic_and_interval_in_key(lowest, highest, irange, tonic, keytype): """ Find a random interval that belongs to a key specified by the arguments tonic and keytype. Return a tuple (MusicalPitch, int) where the musical pitch is the lowest tone and the integer is the size of the interval. Arguments: lowest the name of the lowest possible tone, as a unicode string highest the name of the highest possible tone, as a unicode string tonika MusicalPitch, the key the tones should be taken from keytype "major", "natural-minor" or "harmonic-minor" It is not possible to make this function truly random, since it is possible that some of the keys in irange does not exist in a given keytype. There are no minor seconds in a whole tone scale. I descided that it is better to be less random than giving the user lots of error messages and complaining about bad configuration. """ lowest = mpd.notename_to_int(lowest) highest = mpd.notename_to_int(highest) # We allow str because it simplifies writing the tests if isinstance(tonic, str): tonic = mpd.MusicalPitch.new_from_notename(tonic) # Make a list of all MIDI pitches that belong to the key that # are with the range of tones we can use all_tones = pitches_in_key(tonic, keytype, lowest, highest) # Then make a list of which of the intervals in irange that # can be played with the available tones possible_intervals = [] for i in irange: for tone in all_tones: if tone + i in all_tones: possible_intervals.append(i) break if not possible_intervals: raise NoPossibleIntervals(_("None of the selected intervals can be created in the selected key.")) interval = random.choice(possible_intervals) solutions = [] for tone in all_tones: if (tone + interval in all_tones and lowest <= tone <= highest and lowest <= tone + interval <= highest): solutions.append(tone) return (mpd.MusicalPitch.new_from_int(random.choice(solutions)), interval)
def __init__(self, default_value): gtk.HBox.__init__(self) self.m_value = mpd.notename_to_int(default_value) self.g_label = gtk.Label(mpd.int_to_user_octave_notename(self.m_value)) self.g_label.set_use_markup(1) frame = gtk.Frame() e = gtk.EventBox() frame.add(e) self.pack_start(frame, False) self.g_label.set_size_request(60, -1)#FIXME hardcoded value frame.set_shadow_type(gtk.SHADOW_IN) e.add(self.g_label) vbox = gtk.VBox() self.pack_start(vbox, False) # up self.g_up = gtk.Arrow(gtk.ARROW_UP, gtk.SHADOW_OUT) eb1 = gtk.EventBox() eb1.connect('button-press-event', self.on_up_press) eb1.connect('button-release-event', self.on_up_release) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_OUT) frame.add(self.g_up) eb1.add(frame) vbox.pack_start(eb1) # down self.g_down = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_ETCHED_IN) eb2 = gtk.EventBox() eb2.connect('button-press-event', self.on_down_press) eb2.connect('button-release-event', self.on_down_release) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_OUT) frame.add(self.g_down) eb2.add(frame) vbox.pack_start(eb2) self.m_timeout = None
def _on_button_press(self, drawingarea, event): # This is only set if set_first_note is called x, y = self.event_to_button_pos(event) if x == None: return midi_int = mpd.notename_to_int(self.m_notenames[y][x]) self._handle_tone_clicked(midi_int, event.button)
def __init__(self, default_value): gtk.HBox.__init__(self) self.m_value = mpd.notename_to_int(default_value) self.g_label = gtk.Label(mpd.int_to_user_notename(self.m_value)) self.g_label.set_use_markup(1) frame = gtk.Frame() e = gtk.EventBox() frame.add(e) self.pack_start(frame, False) self.g_label.set_size_request(60, -1)#FIXME hardcoded value frame.set_shadow_type(gtk.SHADOW_IN) e.add(self.g_label) vbox = gtk.VBox() self.pack_start(vbox, False) # up self.g_up = gtk.Arrow(gtk.ARROW_UP, gtk.SHADOW_OUT) eb1 = gtk.EventBox() eb1.connect('button-press-event', self.on_up_press) eb1.connect('button-release-event', self.on_up_release) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_OUT) frame.add(self.g_up) eb1.add(frame) vbox.pack_start(eb1) # down self.g_down = gtk.Arrow(gtk.ARROW_DOWN, gtk.SHADOW_ETCHED_IN) eb2 = gtk.EventBox() eb2.connect('button-press-event', self.on_down_press) eb2.connect('button-release-event', self.on_down_release) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_OUT) frame.add(self.g_down) eb2.add(frame) vbox.pack_start(eb2) self.m_timeout = None
def spank_me_play_question(self): t1 = utils.new_percussion_track() t1.note(8, 71) t2 = utils.new_track() t2.notelen_time(4) t2.note(4, mpd.notename_to_int(self.m_question) + self.m_octave * 12) soundcard.synth.play_track(t1, t2)
def adjust_low_high_to_irange(lowest, highest, irange): """ lowest highest string representing a notename irange list of integers representing intervals. 1 is minor second up, -2 is major second down return tuple with two integers """ assert isinstance(lowest, basestring) assert isinstance(highest, basestring) L = mpd.notename_to_int(lowest) H = mpd.notename_to_int(highest) # find the largest interval that can be asked for r = max(abs(max(irange)), abs(min(irange))) # adjust the lowest and highest note, if the intervals are larger than # the range we should try to stay within if H - L < r: H = H + (r - (H - L)) / 2 L = L - (r - (H - L)) return L, H
def guess_voicing(self, tones): """ return 1 if correct, None if not. Gui should not call this function if the question is already solved. """ v = self.m_P.get_music_as_notename_list('music') v.sort(mpd.compare_notenames) question_i = [] for n in v: while n[-1] in ",'": n = n[:-1] question_i.append(mpd.notename_to_int(n)) answer_i = [] for n in tones: while n[-1] in ",'": n = n[:-1] answer_i.append(mpd.notename_to_int(n)) if answer_i == question_i: self.q_status = self.QSTATUS_VOICING_SOLVED return 1 self.q_status = self.QSTATUS_VOICING_WRONG
def random_interval(tonika, lowest, highest, irange): """ tonika MusicalPitch lowest int with the MIDI integer value of the lowest tone highest int with the MIDI interger value of the higest tone irange list of integer values representing the intervals to choose from Return an int representing the interval. Return None if it is not possible to create an interval. """ tonika = tonika.semitone_pitch() lowest = mpd.notename_to_int(lowest) highest = mpd.notename_to_int(highest) assert lowest <= highest assert isinstance(irange, list) v = [] for i in irange: if lowest <= tonika + i <= highest: v.append(i) if not v: return None return random.choice(v)
def random_interval_in_key(first, lowest, highest, irange, tonic, keytype): """ Return an int representing the interval. Return None if it is not possible to create an interval. Arguments: first The MusicalPitch of the first tone lowest highest integer representing the MIDI pitch of the tone tonic MusicalPitch, the key the tones should be taken from keytype "major", "natural-minor" or "harmonic-minor" """ assert isinstance(lowest, str) assert isinstance(highest, str) lowest = mpd.notename_to_int(lowest) highest = mpd.notename_to_int(highest) assert isinstance(first, mpd.MusicalPitch) tones = pitches_in_key(tonic, keytype, lowest, highest) intervals = [] for i in irange: if (first + i).semitone_pitch() in tones: intervals.append(i) if intervals: return random.choice(intervals)
def random_interval(tonika, lowest, highest, irange): """ Return an int representing the interval. Return None if it is not possible to create an interval. """ if isinstance(tonika, mpd.MusicalPitch): tonika = tonika.semitone_pitch() assert isinstance(tonika, int) assert type(lowest) == type(highest) if isinstance(lowest, basestring): lowest = mpd.notename_to_int(lowest) if isinstance(highest, basestring): highest = mpd.notename_to_int(highest) assert isinstance(lowest, int) assert isinstance(highest, int) assert lowest <= highest assert isinstance(irange, list) v = [] for i in irange: if lowest <= tonika + i <= highest: v.append(i) if not v: return None return random.choice(v)
def show_music(self): self.clear_stacking_frame() md = mpd.MusicDisplayer() self.g_source.pack_start(md, True, True, 0) md.show() md.display(r"\staff{ \clef %s < %s >}" % ( mpd.select_clef(self.m_t.m_P.get_music_as_notename_string('music')), self.m_t.m_P.get_music_as_notename_string('music')), 20) # display the notenames on the buttons with octave info v = self.m_t.m_P.get_music_as_notename_list('music') v.sort(key=lambda n: mpd.notename_to_int(n)) for n in v: b = Gtk.Button(mpd.MusicalPitch.new_from_notename(n).get_user_octave_notename()) b.get_children()[0].set_use_markup(1) b.show() self.g_answer.pack_end(b, False, False, 0)
def __init__(self, default_value): Gtk.Box.__init__(self) self.m_value = mpd.notename_to_int(default_value) self.g_entry = Gtk.Entry() self.g_entry.set_editable(False) self.g_entry.set_text(mpd.int_to_user_octave_notename(self.m_value)) self.pack_start(self.g_entry, False, False, 0) # up eb1 = Gtk.Button() eb1.add(Gtk.Arrow(Gtk.ArrowType.UP, Gtk.ShadowType.OUT)) eb1.connect('button-press-event', self.on_up_press) eb1.connect('button-release-event', self.on_up_release) self.pack_start(eb1, True, True, 0) # down eb2 = Gtk.Button() eb2.add(Gtk.Arrow(Gtk.ArrowType.DOWN, Gtk.ShadowType.IN)) eb2.connect('button-press-event', self.on_down_press) eb2.connect('button-release-event', self.on_down_release) self.pack_start(eb2, True, True, 0) self.m_timeout = None
def __init__(self, default_value): Gtk.Box.__init__(self) self.m_value = mpd.notename_to_int(default_value) self.g_label = Gtk.Label() self.g_label.set_width_chars(6) self.g_label.set_use_markup(True) self.g_label.set_markup(mpd.int_to_user_octave_notename(self.m_value)) self.g_label.props.xalign = 1.0 self.pack_start(self.g_label, False, False, 6) # up eb1 = Gtk.Button() eb1.add(Gtk.Arrow(Gtk.ArrowType.UP, Gtk.ShadowType.OUT)) eb1.connect('button-press-event', self.on_up_press) eb1.connect('button-release-event', self.on_up_release) self.pack_start(eb1, False, False, 0) # down eb2 = Gtk.Button() eb2.add(Gtk.Arrow(Gtk.ArrowType.DOWN, Gtk.ShadowType.IN)) eb2.connect('button-press-event', self.on_down_press) eb2.connect('button-release-event', self.on_down_release) self.pack_start(eb2, False, False, 0) self.m_timeout = None
def play_last_note(self): if self.q_status == self.QSTATUS_NO: return utils.play_note(4, mpd.notename_to_int(self.m_question[-1]))
def check_rcfile(): """See default.config for rcfileversion values, meanings and a description of how to add config variables. """ rcfileversion = 21 if cfg.get_int("app/rcfileversion") > rcfileversion: cfg.drop_user_config() return if cfg.get_int("app/rcfileversion") <= 1: if not "example-files" in cfg.get_string('config/lessoncollections'): cfg.set_string('config/lessoncollections', "%s example-files" % cfg.get_string('config/lessoncollections')) if cfg.get_int("app/rcfileversion") <= 5: # This is more complicated that necessary to fix an old # error. if cfg.get_string("sound/commandline"): cfg.del_key("sound/commandline") if cfg.get_int("app/rcfileversion") <= 3: cfg.set_list("config/lessoncollections", cfg.get_string("config/lessoncollections").split()) if cfg.get_int("app/rcfileversion") <= 4: cfg.del_key("config/web_browser") if sys.platform == 'win32': if cfg.get_string('sound/wav_player'): cfg.del_key('sound/wav_player') if cfg.get_int("app/rcfileversion") <= 5: cfg.set_string("mainwin/history_back_ak", "<alt>Left") cfg.set_string("mainwin/history_forward_ak", "<alt>Right") cfg.set_string("mainwin/history_reload_ak", "<ctrl>r") if cfg.get_int("app/rcfileversion") <= 6: cfg.set_list("config/lessoncollections", ['solfege', 'user']) if cfg.get_int("app/rcfileversion") <= 7: cfg.set_int("rhythm/countin_perc", 80) if cfg.get_int("app/rcfileversion") <= 8: cfg.del_key("singinterval/highest_tone") cfg.del_key("singinterval/lowest_tone") cfg.del_key("melodicinterval/highest_tone") cfg.del_key("melodicinterval/lowest_tone") cfg.del_key("harmonicinterval/highest_tone") cfg.del_key("harmonicinterval/lowest_tone") if cfg.get_int("app/rcfileversion") <= 9: cfg.del_section("mainwin") if cfg.get_int("app/rcfileversion") <= 10: cfg.del_section("lessoncollections") cfg.del_key("config/lessoncollections") for n in cfg.iterate_sections(): cfg.del_key("%s/lessoncollection" % n) cfg.del_key("%s/lessonfile" % n) if cfg.get_int("app/rcfileversion") <= 11: for s in ('rhythm', 'rhythmtapping2'): cfg.del_key("%s/countin_perc" % s) cfg.del_key("%s/rhythm_perc" % s) if cfg.get_int("app/rcfileversion") <= 12: cfg.del_key("sound/card_info") if cfg.get_int("app/rcfileversion") <= 13: cfg.del_key("config/lowest_instrument_velocity") cfg.del_key("config/middle_instrument_velocity") cfg.del_key("config/highest_instrument_velocity") cfg.del_key("config/preferred_instrument_velocity") if cfg.get_int("app/rcfileversion") <= 14: # We have to split the midi_to_wav_cmd into two strings, and # moving the options to *_options, so that midi_to_wav_cmd only # have the name of the binary. This to allow binaries in dirs # with spaces. for k in ("midi_to_wav", "wav_to_mp3", "wav_to_ogg"): v = cfg.get_string("app/%s_cmd" % k).split(" ") cfg.set_string("app/%s_cmd" % k, v[0]) cfg.set_string("app/%s_cmd_options" % k, " ".join(v[1:])) if cfg.get_int("app/rcfileversion") <= 15: for k in ("midi", "wav", "mp3", "ogg"): v = cfg.get_string("sound/%s_player" % k).split(" ") cfg.set_string("sound/%s_player" % k, v[0]) cfg.set_string("sound/%s_player_options" % k, " ".join(v[1:])) if cfg.get_int("app/rcfileversion") < 17: v = cfg.get_string("app/frontpage").split("/") if v[0] == "exercises" and v[1] != "standard": cfg.set_string("app/frontpage", "/".join([v[0], "standard"] + v[1:])) if cfg.get_int("app/rcfileversion") < 18: cfg.del_key("gui/web_browser_as_help_browser") if cfg.get_int("app/rcfileversion") < 19: for ex in ('singinterval', 'melodicinterval'): if cfg.get_int("%s/maximum_number_of_intervals" % ex) == 10: cfg.set_int("%s/maximum_number_of_intervals" % ex, 12) if cfg.get_int("app/rcfileversion") < 20: cfg.del_key("gui/reserved_vspace") if cfg.get_int("app/rcfileversion") < 21: for ex in ("melodicinterval", "harmonicinterval"): i = cfg.get_int("%s/inputwidget" % ex) if i > 0: cfg.set_int("%s/inputwidget" % ex, i + 1) cfg.set_int("app/rcfileversion", rcfileversion) try: a = mpd.notename_to_int(cfg.get_string("user/lowest_pitch")) b = mpd.notename_to_int(cfg.get_string("user/highest_pitch")) except mpd.InvalidNotenameException: if cfg.get_string("user/sex") == "male": cfg.set_string("user/highest_pitch", "e'") cfg.set_string("user/lowest_pitch", "c") else: cfg.set_string("user/highest_pitch", "e''") cfg.set_string("user/lowest_pitch", "c'")
def play_question(self): if self.q_status == self.QSTATUS_NO: return utils.play_note( 4, mpd.notename_to_int(self.m_question) + self.m_octave * 12)
def draw(self, widget, context): # number of buttons, horiz and vertic. self.m_bx = bx = len(self.m_notenames[0]) self.m_by = by = len(self.m_notenames) # how much space between buttons and border self.m_bb = bb = 16 # w = bx * self.m_button_xdist + bb * 2 h = by * self.m_button_ydist + bb * 2 self.m_posx = posx = int((self.get_allocated_width() - w) / 2) + 0.5 self.m_posy = posy = int((self.get_allocated_height() - h) / 2) + 0.5 context.set_line_width(1.2) context.save() context.move_to(posx, posy) for x, y in ((w, 0), (0, self.m_button_ydist * by), # right btn (-self.m_button_xdist, self.m_button_ydist), #right btn (-w + self.m_button_xdist * 2, 0), (-self.m_button_xdist, -self.m_button_ydist), (0, -self.m_button_ydist * by), ): context.rel_line_to(x, y) context.close_path() context.set_source_rgb(0, 0, 0) context.fill_preserve() context.stroke() context.restore() # buttons context.save() for row_idx, row in enumerate(self.m_notenames): for col_idx, notename in enumerate(row): context.arc(bb + posx + col_idx * self.m_button_xdist + (row_idx+1) % 2 * self.m_button_radius, bb + posy + row_idx * self.m_button_ydist, self.m_button_radius, 0, 2 * math.pi) if notename[1:][:2] in ('is', 'es'): context.set_source_rgb(0.4, 0.4, 0.4) else: context.set_source_rgb(1, 1, 1) context.fill_preserve() context.stroke() context.restore() context.save() for row_idx, row in enumerate(self.m_notenames): for col_idx, notename in enumerate(row): try: mark_idx = [m[0] for m in self.m_marks].index(mpd.notename_to_int(notename)) except ValueError: mark_idx = -1 if mark_idx != -1: context.arc(bb + posx + col_idx * self.m_button_xdist + (row_idx+1) % 2 * self.m_button_radius, bb + posy + row_idx * self.m_button_ydist, 5, 0, 2 * math.pi) context.set_source_rgb(*self.mark_color[self.m_marks[mark_idx][1]]) context.fill_preserve() context.stroke() context.restore() self.set_size_request(500, self.m_by * self.m_button_ydist + 2 * self.m_bb)
def play_question(self): if self.q_status == self.QSTATUS_NO: return utils.play_note(4, mpd.notename_to_int(self.m_question) + self.m_octave * 12)
def ff(first, count): i = mpd.notename_to_int(first) return [mpd.int_to_octave_notename(i + x * 3) for x in range(count)]
def play_440hz(self): utils.play_note(4, mpd.notename_to_int("a'"))
def check_rcfile(): """See default.config for rcfileversion values, meanings and a description of how to add config variables. """ rcfileversion = 21 if cfg.get_int("app/rcfileversion") > rcfileversion: cfg.drop_user_config() return if cfg.get_int("app/rcfileversion") <= 1: if not "example-files" in cfg.get_string('config/lessoncollections'): cfg.set_string( 'config/lessoncollections', "%s example-files" % cfg.get_string('config/lessoncollections')) if cfg.get_int("app/rcfileversion") <= 5: # This is more complicated that necessary to fix an old # error. if cfg.get_string("sound/commandline"): cfg.del_key("sound/commandline") if cfg.get_int("app/rcfileversion") <= 3: cfg.set_list("config/lessoncollections", cfg.get_string("config/lessoncollections").split()) if cfg.get_int("app/rcfileversion") <= 4: cfg.del_key("config/web_browser") if sys.platform == 'win32': if cfg.get_string('sound/wav_player'): cfg.del_key('sound/wav_player') if cfg.get_int("app/rcfileversion") <= 5: cfg.set_string("mainwin/history_back_ak", "<alt>Left") cfg.set_string("mainwin/history_forward_ak", "<alt>Right") cfg.set_string("mainwin/history_reload_ak", "<ctrl>r") if cfg.get_int("app/rcfileversion") <= 6: cfg.set_list("config/lessoncollections", ['solfege', 'user']) if cfg.get_int("app/rcfileversion") <= 7: cfg.set_int("rhythm/countin_perc", 80) if cfg.get_int("app/rcfileversion") <= 8: cfg.del_key("singinterval/highest_tone") cfg.del_key("singinterval/lowest_tone") cfg.del_key("melodicinterval/highest_tone") cfg.del_key("melodicinterval/lowest_tone") cfg.del_key("harmonicinterval/highest_tone") cfg.del_key("harmonicinterval/lowest_tone") if cfg.get_int("app/rcfileversion") <= 9: cfg.del_section("mainwin") if cfg.get_int("app/rcfileversion") <= 10: cfg.del_section("lessoncollections") cfg.del_key("config/lessoncollections") for n in cfg.iterate_sections(): cfg.del_key("%s/lessoncollection" % n) cfg.del_key("%s/lessonfile" % n) if cfg.get_int("app/rcfileversion") <= 11: for s in ('rhythm', 'rhythmtapping2'): cfg.del_key("%s/countin_perc" % s) cfg.del_key("%s/rhythm_perc" % s) if cfg.get_int("app/rcfileversion") <= 12: cfg.del_key("sound/card_info") if cfg.get_int("app/rcfileversion") <= 13: cfg.del_key("config/lowest_instrument_velocity") cfg.del_key("config/middle_instrument_velocity") cfg.del_key("config/highest_instrument_velocity") cfg.del_key("config/preferred_instrument_velocity") if cfg.get_int("app/rcfileversion") <= 14: # We have to split the midi_to_wav_cmd into two strings, and # moving the options to *_options, so that midi_to_wav_cmd only # have the name of the binary. This to allow binaries in dirs # with spaces. for k in ("midi_to_wav", "wav_to_mp3", "wav_to_ogg"): v = cfg.get_string("app/%s_cmd" % k).split(" ") cfg.set_string("app/%s_cmd" % k, v[0]) cfg.set_string("app/%s_cmd_options" % k, " ".join(v[1:])) if cfg.get_int("app/rcfileversion") <= 15: for k in ("midi", "wav", "mp3", "ogg"): v = cfg.get_string("sound/%s_player" % k).split(" ") cfg.set_string("sound/%s_player" % k, v[0]) cfg.set_string("sound/%s_player_options" % k, " ".join(v[1:])) if cfg.get_int("app/rcfileversion") < 17: v = cfg.get_string("app/frontpage").split("/") if v[0] == u"exercises" and v[1] != u"standard": cfg.set_string("app/frontpage", u"/".join([v[0], u"standard"] + v[1:])) if cfg.get_int("app/rcfileversion") < 18: cfg.del_key("gui/web_browser_as_help_browser") if cfg.get_int("app/rcfileversion") < 19: for ex in ('singinterval', 'melodicinterval'): if cfg.get_int("%s/maximum_number_of_intervals" % ex) == 10: cfg.set_int("%s/maximum_number_of_intervals" % ex, 12) if cfg.get_int("app/rcfileversion") < 20: cfg.del_key("gui/reserved_vspace") if cfg.get_int("app/rcfileversion") < 21: for ex in ("melodicinterval", "harmonicinterval"): i = cfg.get_int("%s/inputwidget" % ex) if i > 0: cfg.set_int("%s/inputwidget" % ex, i + 1) cfg.set_int("app/rcfileversion", rcfileversion) try: a = mpd.notename_to_int(cfg.get_string("user/lowest_pitch")) b = mpd.notename_to_int(cfg.get_string("user/highest_pitch")) except mpd.InvalidNotenameException: if cfg.get_string("user/sex") == "male": cfg.set_string("user/highest_pitch", "e'") cfg.set_string("user/lowest_pitch", "c") else: cfg.set_string("user/highest_pitch", "e''") cfg.set_string("user/lowest_pitch", "c'")
def ff(first, count): i = mpd.notename_to_int(first) return [ mpd.int_to_octave_notename(i + x * 3) for x in range(count) ]
def draw(self, context): # number of buttons, horiz and vertic. self.m_bx = bx = len(self.m_notenames[0]) self.m_by = by = len(self.m_notenames) # how much space between buttons and border self.m_bb = bb = 16 # w = bx * self.m_button_xdist + bb * 2 h = by * self.m_button_ydist + bb * 2 self.m_posx = posx = int((self.allocation.width - w) / 2) + 0.5 self.m_posy = posy = int((self.allocation.height - h) / 2) + 0.5 context.set_line_width(1.2) context.save() context.move_to(posx, posy) for x, y in ( (w, 0), (0, self.m_button_ydist * by), # right btn (-self.m_button_xdist, self.m_button_ydist), #right btn (-w + self.m_button_xdist * 2, 0), (-self.m_button_xdist, -self.m_button_ydist), (0, -self.m_button_ydist * by), ): context.rel_line_to(x, y) context.close_path() context.set_source_rgb(0, 0, 0) context.fill_preserve() context.stroke() context.restore() # buttons context.save() for row_idx, row in enumerate(self.m_notenames): for col_idx, notename in enumerate(row): context.arc( bb + posx + col_idx * self.m_button_xdist + (row_idx + 1) % 2 * self.m_button_radius, bb + posy + row_idx * self.m_button_ydist, self.m_button_radius, 0, 2 * math.pi) if notename[1:][:2] in ('is', 'es'): context.set_source_rgb(0.4, 0.4, 0.4) else: context.set_source_rgb(1, 1, 1) context.fill_preserve() context.stroke() context.restore() context.save() for row_idx, row in enumerate(self.m_notenames): for col_idx, notename in enumerate(row): try: mark_idx = [m[0] for m in self.m_marks ].index(mpd.notename_to_int(notename)) except ValueError: mark_idx = -1 if mark_idx != -1: context.arc( bb + posx + col_idx * self.m_button_xdist + (row_idx + 1) % 2 * self.m_button_radius, bb + posy + row_idx * self.m_button_ydist, 5, 0, 2 * math.pi) context.set_source_rgb( *self.mark_color[self.m_marks[mark_idx][1]]) context.fill_preserve() context.stroke() context.restore() self.set_size_request(500, self.m_by * self.m_button_ydist + 2 * self.m_bb)