示例#1
0
def _fret_string_combos(note):
    r"""
    Given a (theoretical) `note`, return all supported fret/string combos,
    along with flags indicating whether the returned values are usable.

    This assumes that a note can occur in no more than six locations.

    To ease testing, entries go from low strings to high strings.
    >>> _fret_string_combos(('E', 3))
    (12, 5, 1, 7, 4, 1, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
    """
    result_builder = []
    for location in frets(note):
        result_builder.append(location[0])
        result_builder.append(STANDARD_STRINGS.index(location[1]))
        result_builder.append(1)
    missing_values = 18 - len(result_builder)
    result_builder.extend([0] * missing_values)
    return tuple(result_builder)
 def test_not_too_high(self):
     results = list(notemappings.frets(('A', 5)))
     for result in results:
         self.assertTrue(result[0] <= 24)
 def test_g_5_all_occurrences(self, mock_lowest_string):
     mock_lowest_string.return_value = ('B', 3)
     expected = [(20, ('B', 3)), (15, ('E', 4))]
     for pair in zip(expected, notemappings.frets(('G', 5))):
         self.assertEqual(pair[0], pair[1])
 def test_d_4_all_occurrences(self, mock_lowest_string):
     mock_lowest_string.return_value = ('E', 2)
     expected = [(22, ('E', 2)), (17, ('A', 2)), (12, ('D', 3)),
                 (7, ('G', 3)), (3, ('B', 3))]
     for pair in zip(expected, notemappings.frets(('D', 4))):
         self.assertEqual(pair[0], pair[1])
 def test_middle_c_all_occurrences(self, mock_lowest_string):
     mock_lowest_string.return_value = ('E', 2)
     expected = [(8, ('E', 2)), (3, ('A', 2))]
     for pair in zip(expected, notemappings.frets(('C', 3))):
         self.assertEqual(pair[0], pair[1])
示例#6
0
def _sample_data(preceding, current_chord, following, recent_notes,
                 current_chord_index, limiting_note):
    r"""
    Transform a given chord context into an input-output pair for an ANN.

    Given a dataset and a chord context, this function yields pairs of
    input and output values *for each note in the current chord*.

    `recent_notes` is a dict-like object which, for each (theoretical)
    note, specifies the most recent fret and string values (bundled in
    an indexed sequence).

    `limiting_note`, if any value, is a tuple whose elements are:
    
       #. the next (theoretical) limiting note,
          i.e. the first note that comes after `current_chord` and
          which imposes strict constraints on where it can be played
       #. the chord index of that note

    Chords belonging to the chord context are specified in their physical
    form. This includes the current chord and successor chords.
    """

    LOG.debug('Current chord: {current}'.format(current=current_chord))
    highest_note_chord = _highest_note_chord(current_chord)
    lowest_note_chord = _lowest_note_chord(current_chord)
    avg_frets = _avg_frets(preceding)
    preceding_notes = _pad_physical_notes(_adjacent_notes(preceding, 4), 4)
    following_notes = _pad_physical_notes(_adjacent_notes(following, 6, fwd=True), 6)
    LOG.debug('Following notes: {f}'.format(f=following_notes))
    following_notes = [fret2note(phys[1], phys[0]) for phys in list(following_notes)]
    if limiting_note:
        to_limiting_note = limiting_note[1] - current_chord_index
        minimal_fret_limiting_note = None
        for fret in frets(limiting_note[0]):
            if minimal_fret_limiting_note is None or fret[0] < minimal_fret_limiting_note:
                minimal_fret_limiting_note = fret[0]
                minimal_string_limiting_note = STANDARD_STRINGS.index(fret[1])
        limiting_note_flag = 1
    else:
        to_limiting_note = 1000 # just use something so big it is irrelevant
        minimal_fret_limiting_note = 0
        minimal_string_limiting_note = 0
        limiting_note_flag = 0
    if preceding:
        num_notes_prev_chord = len(preceding[-1])
    else:
        num_notes_prev_chord = 0
    if len(preceding) > 1:
        num_notes_prev_chord_2 = len(preceding[-2])
    else:
        num_notes_prev_chord_2 = 0
    if following:
        num_notes_next_chord = len(following[0])
    else:
        num_notes_next_chord = 0
    if len(following) > 1:
        num_notes_next_chord_2 = len(following[1])
    else:
        num_notes_next_chord_2 = 0
    for string_num in sorted(current_chord.keys()):
        note = fret2note(current_chord[string_num], string_num)
        recent_note = recent_notes.get(note, (0, 0))
        fret_string_combos = _fret_string_combos(note)
        bits = [0] * SUPPORTED_FRETS
        bits[current_chord[string_num]] = 1  # fret alone is fine
        inputs = (# 1: notes in current chord
                  len(current_chord.keys()),
                  # 2-3: current note octave and value
                  int(note[1]),
                  NOTE_SEQUENCE.index(note[0]),
                  # 4-5: highest note in chord's octave and value
                  highest_note_chord[1],
                  NOTE_SEQUENCE.index(highest_note_chord[0]),
                  # 6-7: lowest note in chord's octave and value
                  lowest_note_chord[1],
                  NOTE_SEQUENCE.index(lowest_note_chord[0]),
                  # 8-10: average fret for three most recent chords
                  avg_frets[0],
                  avg_frets[1],
                  avg_frets[2],
                  # 11-12: fret and string for most recent occurrence note
                  recent_note[0],
                  recent_note[1],
                  # 13-20: string and fret for four most recent notes
                  preceding_notes[0][0],
                  preceding_notes[0][1],
                  preceding_notes[1][0],
                  preceding_notes[1][1],
                  preceding_notes[2][0],
                  preceding_notes[2][1],
                  preceding_notes[3][0],
                  preceding_notes[3][1],
                  # 21: number of chords played since last four notes
                  _chords_for_notes(4, preceding, fwd=False),
                  # 22-23: number of notes in previous two chords
                  num_notes_prev_chord,
                  num_notes_prev_chord_2,
                  # 24-29: booleans indicating whether string are in use
                  int(0 in current_chord),
                  int(1 in current_chord),
                  int(2 in current_chord),
                  int(3 in current_chord),
                  int(4 in current_chord),
                  int(5 in current_chord),
                  # 30-47: all string/fret combinations for the current note
                  # **ADDED** each third entry indicates whether combo is real
                  # **ADDED** supports up to 24 real frets, so 6 locations
                  fret_string_combos[0],
                  fret_string_combos[1],
                  fret_string_combos[2],
                  fret_string_combos[3],
                  fret_string_combos[4],
                  fret_string_combos[5],
                  fret_string_combos[6],
                  fret_string_combos[7],
                  fret_string_combos[8],
                  fret_string_combos[9],
                  fret_string_combos[10],
                  fret_string_combos[11],
                  fret_string_combos[12],
                  fret_string_combos[13],
                  fret_string_combos[14],
                  fret_string_combos[15],
                  fret_string_combos[16],
                  fret_string_combos[17],
                  # 48-49: number of notes in next two chords
                  num_notes_next_chord,
                  num_notes_next_chord_2,
                  # 50-61: octave and note for next six notes
                  NOTE_SEQUENCE.index(following_notes[0][0]),
                  following_notes[0][1],
                  NOTE_SEQUENCE.index(following_notes[1][0]),
                  following_notes[1][1],
                  NOTE_SEQUENCE.index(following_notes[2][0]),
                  following_notes[2][1],
                  NOTE_SEQUENCE.index(following_notes[3][0]),
                  following_notes[3][1],
                  NOTE_SEQUENCE.index(following_notes[4][0]),
                  following_notes[4][1],
                  NOTE_SEQUENCE.index(following_notes[5][0]),
                  following_notes[5][1],
                  # 62: number of chords between current note and next six notes
                  _chords_for_notes(6, following, fwd=True),
                  # 63-65: fret/string furthest from body for limiting note
                  minimal_fret_limiting_note,
                  minimal_string_limiting_note,
                  limiting_note_flag,
                  # 66: number of chords until next limiting note
                  to_limiting_note,
               )
        sample = (inputs, tuple(bits))
        LOG.debug('Yielding sample: {sample}'.format(sample=sample))
        yield sample