# Path: moonlight/music/constants.py
# MAJOR_SCALE = [0, 2, 4, 5, 7, 9, 11]
# NUM_SEMITONES_PER_OCTAVE = 12
# NUM_SEMITONES_IN_PERFECT_FIFTH = 7
# NUM_NOTES_IN_DIATONIC_SCALE = 7
# CIRCLE_OF_FIFTHS = [0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5]


import librosa
from moonlight.music import constants
from moonlight.protobuf import musicscore_pb2


class BassClef(Clef):
  """Represents a bass clef."""

  def __init__(self):
    self.center_line_pitch = _ScalePitch(constants.MAJOR_SCALE,
                                         librosa.note_to_midi('D3'))
    self.glyph = musicscore_pb2.Glyph.CLEF_BASS


class _ScalePitch(object):
  """A natural note which can be offset to get another note.

  Attributes:
    scale: The scale which this pitch is based on. A list of MIDI pitch values
      spanning one octave.
    index: The index of the pitch's pitch class within the scale.
    octave: The index of the octave that the pitch is in, relative to the octave
      spanning the scale notes.
  """

  def __init__(self, scale, midi):
    self.scale = scale
    self.index = scale.index(midi % constants.NUM_SEMITONES_PER_OCTAVE)
    self.octave = (midi - scale[0]) // 12

  @property
  def midi(self):
    """The MIDI value for the pitch."""

# Path: moonlight/music/constants.py
# MAJOR_SCALE = [0, 2, 4, 5, 7, 9, 11]
# NUM_SEMITONES_PER_OCTAVE = 12
# NUM_SEMITONES_IN_PERFECT_FIFTH = 7
# NUM_NOTES_IN_DIATONIC_SCALE = 7
# CIRCLE_OF_FIFTHS = [0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5]


# Path: moonlight/score/elements/clef.py
import librosa
from moonlight.music import constants
from moonlight.protobuf import musicscore_pb2



class BassClef(Clef):
  """Represents a bass clef."""

  def __init__(self):
    self.center_line_pitch = _ScalePitch(constants.MAJOR_SCALE,
                                         librosa.note_to_midi('D3'))
    self.glyph = musicscore_pb2.Glyph.CLEF_BASS


class _ScalePitch(object):
  """A natural note which can be offset to get another note.

  Attributes:
    scale: The scale which this pitch is based on. A list of MIDI pitch values
      spanning one octave.
    index: The index of the pitch's pitch class within the scale.
    octave: The index of the octave that the pitch is in, relative to the octave
      spanning the scale notes.
  """

  def __init__(self, scale, midi):
    self.scale = scale
    self.index = scale.index(midi % constants.NUM_SEMITONES_PER_OCTAVE)
    self.octave = (midi - scale[0]) // 12

  @property
  def midi(self):
    """The MIDI value for the pitch."""

    notes_per_octave = constants.NUM_SEMITONES_PER_OCTAVE