'Finds the melodic interval between the action and the last note played.
Uses constants to represent special intervals like rests.
Args:
action: One-hot encoding of the chosen action
key: The numeric values of notes belonging to this key. Defaults to
C-major if not provided.
Returns:
An integer value representing the interval, or a constant value for
special intervals.'

def detect_sequential_interval(self, action, key=None):

    if (not self.composition):
        return (0, None, None)
    prev_note = self.composition[(-1)]
    action_note = np.argmax(action)
    c_major = False
    if (key is None):
        key = rl_tuner_ops.C_MAJOR_KEY
        c_notes = [2, 14, 26]
        g_notes = [9, 21, 33]
        e_notes = [6, 18, 30]
        c_major = True
        tonic_notes = [2, 14, 26]
        fifth_notes = [9, 21, 33]
    prev_note_index = (len(self.composition) - 1)
    while (((prev_note == NO_EVENT) or (prev_note == NOTE_OFF)) and (prev_note_index >= 0)):
        prev_note = self.composition[prev_note_index]
        prev_note_index -= 1
    if ((prev_note == NOTE_OFF) or (prev_note == NO_EVENT)):
        tf.logging.debug('Action_note:    %s,    prev_note:    %s', action_note, prev_note)
        return (0, action_note, prev_note)
    tf.logging.debug('Action_note:    %s,    prev_note:    %s', action_note, prev_note)
    if (action_note == NO_EVENT):
        if ((prev_note in tonic_notes) or (prev_note in fifth_notes)):
            return (rl_tuner_ops.HOLD_INTERVAL_AFTER_THIRD_OR_FIFTH, action_note, prev_note)
        else:
            return (rl_tuner_ops.HOLD_INTERVAL, action_note, prev_note)
    elif (action_note == NOTE_OFF):
        if ((prev_note in tonic_notes) or (prev_note in fifth_notes)):
            return (rl_tuner_ops.REST_INTERVAL_AFTER_THIRD_OR_FIFTH, action_note, prev_note)
        else:
            return (rl_tuner_ops.REST_INTERVAL, action_note, prev_note)
    interval = abs((action_note - prev_note))
    if (c_major and (interval == rl_tuner_ops.FIFTH) and ((prev_note in c_notes) or (prev_note in g_notes))):
        return (rl_tuner_ops.IN_KEY_FIFTH, action_note, prev_note)
    if (c_major and (interval == rl_tuner_ops.THIRD) and ((prev_note in c_notes) or (prev_note in e_notes))):
        return (rl_tuner_ops.IN_KEY_THIRD, action_note, prev_note)
    return (interval, action_note, prev_note)
