예제 #1
0
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]
예제 #2
0
 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)
예제 #3
0
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
예제 #4
0
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
예제 #5
0
 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)
예제 #6
0
 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)
예제 #7
0
 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)
예제 #8
0
 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)
예제 #9
0
 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)
예제 #10
0
 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)
예제 #11
0
 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)
예제 #12
0
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)
예제 #13
0
 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
예제 #14
0
 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)
예제 #15
0
 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
예제 #16
0
 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)
예제 #17
0
 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)
예제 #18
0
 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)
예제 #19
0
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
예제 #20
0
 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
예제 #21
0
 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
예제 #22
0
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)
예제 #23
0
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)
예제 #24
0
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)
예제 #25
0
 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)
예제 #26
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
예제 #27
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
예제 #28
0
 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
예제 #29
0
 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]))
예제 #30
0
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'")
예제 #31
0
 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)
예제 #32
0
 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]))
예제 #33
0
    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)
예제 #34
0
 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)
예제 #35
0
 def ff(first, count):
     i = mpd.notename_to_int(first)
     return [mpd.int_to_octave_notename(i + x * 3) for x in range(count)]
예제 #36
0
 def play_440hz(self):
     utils.play_note(4, mpd.notename_to_int("a'"))
예제 #37
0
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'")
예제 #38
0
 def ff(first, count):
     i = mpd.notename_to_int(first)
     return [
         mpd.int_to_octave_notename(i + x * 3) for x in range(count)
     ]
예제 #39
0
    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)