# Path: camp/core/note.py
# def note(st):
#     """
#     note('Db3') -> Note(name='Db', octave=3)
#     """
#     if type(st) == Note:
#         return st
#     match = NOTE_SHORTCUT_REGEX.match(st)
#     if not match:
#         raise Exception("cannot form note from: %s" % st)
#     name = match.group(1)
#     octave = match.group(2)
#     if octave == '' or octave is None:
#         octave = 4
#     octave = int(octave)
#     return Note(name=name, octave=octave)
# 
# class Note(object):
# 
#     def __init__(self, name=None, octave=None, velocity=127, duration=0.0625):
# 
#         """
#         Constructs a note.
#         note = Note(name='C', octave='4')
#         """
# 
#         assert name is not None
#         name = name.title()
#         assert name in NOTES or name in EQUIVALENCE
#         if octave is None:
#             octave = 4
#         assert octave is not None and type(octave) == int
# 
#         self.name = self._equivalence(name)
#         self.octave = octave
# 
#     def copy(self):
#         return Note(name=self.name, octave=self.octave)
# 
#     def _equivalence(self, name):
#         """
#         Normalize note names on input, C# -> Db, etc
#         Internally everything uses flats.
#         """
# 
#         if name in EQUIVALENCE:
#            return NOTES[EQUIVALENCE.index(name)]
#         return name
# 
#     def _scale_degrees_to_steps(self, input):
#         """
#         A 3rd "3" is 3 steps, but a "b3" (minor third) is 2.5 and a "#3" (augmented third) is 3.5
#         This is used in scale.py to make defining scales easier.
#         See https://en.wikipedia.org/wiki/List_of_musical_scales_and_modes
#         """
#         return SCALE_DEGREES_TO_STEPS[str(input)]
# 
#     def transpose(self, steps=0, semitones=0, degrees=None, octaves=0):
#         """
#         Returns a note a given number of steps or octaves or (other things) higher.
# 
#         steps -- half step as 0.5, whole step as 1, or any combination.  The most basic way to do things.
#         semitones - 1 semitone is simply a half step.  Provided to keep some implementations more music-literate.
#         octaves - 6 whole steps, or 12 half steps.  Easy enough.
#         degrees - scale degrees, to keep scale definition somewhat music literate.  "3" is a third, "b3" is a flat third, "3#" is an augmented third, etc.
# 
#         You can combine all of them at the same time if you really want (why?), in which case they are additive.
#         """
# 
# 
#         if degrees is not None:
#             degree_steps = self._scale_degrees_to_steps(degrees)
#         else:
#             degree_steps = 0
#         if steps is None:
#             steps = 0
#         if octaves is None:
#             octaves = 0
#         if semitones is None:
#             semitones = 0
# 
#         steps = steps + (octaves * 6) + (semitones * 0.5) + degree_steps
# 
#         note = self
#         if steps > 0:
#              while steps > 0:
#                  note = note.up_half_step()
#                  steps = steps - 0.5
#         else:
#              while steps < 0:
#                  note = note.down_half_step()
#                  steps = steps + 0.5
#         return note
# 
#     def _numeric_name(self):
#         """
#         Give a number for the note - used by internals only
#         """
#         return NOTES.index(self.name)
# 
#     def note_number(self):
#         """
#         What order is this note on the keyboard?
#         """
#         nn =  NOTES.index(self.name) + (12 * self.octave)
#         return nn
# 
#     def up_half_step(self):
#         """
#         What note is a half step up from this one?
#         """
#         number = self._numeric_name()
#         name = UP_HALF_STEP[number]
#         if self.name == 'B':
#             return Note(name=name, octave=self.octave+1)
#         return Note(name=name, octave=self.octave)
# 
#     def down_half_step(self):
#         """
#         What note is a half step down from this one?
#         """
#         number = self._numeric_name()
#         name = DOWN_HALF_STEP[number]
#         if self.name == 'C':
#             return Note(name=name, octave=self.octave-1)
#         return Note(name=name, octave=self.octave)
# 
#     def __eq__(self, other):
#         """
#         Are two notes the same?
#         """
#         return self.note_number() == other.note_number()
# 
#     def __lt__(self, other):
#         """
#         Are two notes the same?
#         """
#         return self.note_number() < other.note_number()
# 
#     def short_name(self):
#         """
#         Returns a string like Eb4
#         """
#         return "%s%s" % (self.name, self.octave)
# 
#     def __repr__(self):
#         return "Note<%s%s>" % (self.name, self.octave)


from camp.core.note import note, Note
        """
        Constructs a chord, in different ways:

        notes = [ note('C4'), note('E4'), note('G4') ]
	chord = Chord(notes=notes)

        OR:

        chord = Chord(root=note('C4'), type='major')

	OR:

	chord = Chord(root='C4', type='major')
        """

        self.notes = []

        if notes and root:
            raise Exception("notes= and root= are mutually exclusive")
        if notes is None and root is None:
            raise Exception("specify either notes= or root=")
        if root and typ is None:
            raise Exception("typ= is required when using root=")
        if typ and typ not in CHORD_TYPES:
            raise Exception("unknown chord type: %s, expecting one of: %s" % (typ, CHORD_TYPES))
        if isinstance(root, str):
            root = note(root)

        if notes is not None:
            for x in notes:

# Path: camp/core/note.py
# def note(st):
#     """
#     note('Db3') -> Note(name='Db', octave=3)
#     """
#     if type(st) == Note:
#         return st
#     match = NOTE_SHORTCUT_REGEX.match(st)
#     if not match:
#         raise Exception("cannot form note from: %s" % st)
#     name = match.group(1)
#     octave = match.group(2)
#     if octave == '' or octave is None:
#         octave = 4
#     octave = int(octave)
#     return Note(name=name, octave=octave)
# 
# class Note(object):
# 
#     def __init__(self, name=None, octave=None, velocity=127, duration=0.0625):
# 
#         """
#         Constructs a note.
#         note = Note(name='C', octave='4')
#         """
# 
#         assert name is not None
#         name = name.title()
#         assert name in NOTES or name in EQUIVALENCE
#         if octave is None:
#             octave = 4
#         assert octave is not None and type(octave) == int
# 
#         self.name = self._equivalence(name)
#         self.octave = octave
# 
#     def copy(self):
#         return Note(name=self.name, octave=self.octave)
# 
#     def _equivalence(self, name):
#         """
#         Normalize note names on input, C# -> Db, etc
#         Internally everything uses flats.
#         """
# 
#         if name in EQUIVALENCE:
#            return NOTES[EQUIVALENCE.index(name)]
#         return name
# 
#     def _scale_degrees_to_steps(self, input):
#         """
#         A 3rd "3" is 3 steps, but a "b3" (minor third) is 2.5 and a "#3" (augmented third) is 3.5
#         This is used in scale.py to make defining scales easier.
#         See https://en.wikipedia.org/wiki/List_of_musical_scales_and_modes
#         """
#         return SCALE_DEGREES_TO_STEPS[str(input)]
# 
#     def transpose(self, steps=0, semitones=0, degrees=None, octaves=0):
#         """
#         Returns a note a given number of steps or octaves or (other things) higher.
# 
#         steps -- half step as 0.5, whole step as 1, or any combination.  The most basic way to do things.
#         semitones - 1 semitone is simply a half step.  Provided to keep some implementations more music-literate.
#         octaves - 6 whole steps, or 12 half steps.  Easy enough.
#         degrees - scale degrees, to keep scale definition somewhat music literate.  "3" is a third, "b3" is a flat third, "3#" is an augmented third, etc.
# 
#         You can combine all of them at the same time if you really want (why?), in which case they are additive.
#         """
# 
# 
#         if degrees is not None:
#             degree_steps = self._scale_degrees_to_steps(degrees)
#         else:
#             degree_steps = 0
#         if steps is None:
#             steps = 0
#         if octaves is None:
#             octaves = 0
#         if semitones is None:
#             semitones = 0
# 
#         steps = steps + (octaves * 6) + (semitones * 0.5) + degree_steps
# 
#         note = self
#         if steps > 0:
#              while steps > 0:
#                  note = note.up_half_step()
#                  steps = steps - 0.5
#         else:
#              while steps < 0:
#                  note = note.down_half_step()
#                  steps = steps + 0.5
#         return note
# 
#     def _numeric_name(self):
#         """
#         Give a number for the note - used by internals only
#         """
#         return NOTES.index(self.name)
# 
#     def note_number(self):
#         """
#         What order is this note on the keyboard?
#         """
#         nn =  NOTES.index(self.name) + (12 * self.octave)
#         return nn
# 
#     def up_half_step(self):
#         """
#         What note is a half step up from this one?
#         """
#         number = self._numeric_name()
#         name = UP_HALF_STEP[number]
#         if self.name == 'B':
#             return Note(name=name, octave=self.octave+1)
#         return Note(name=name, octave=self.octave)
# 
#     def down_half_step(self):
#         """
#         What note is a half step down from this one?
#         """
#         number = self._numeric_name()
#         name = DOWN_HALF_STEP[number]
#         if self.name == 'C':
#             return Note(name=name, octave=self.octave-1)
#         return Note(name=name, octave=self.octave)
# 
#     def __eq__(self, other):
#         """
#         Are two notes the same?
#         """
#         return self.note_number() == other.note_number()
# 
#     def __lt__(self, other):
#         """
#         Are two notes the same?
#         """
#         return self.note_number() < other.note_number()
# 
#     def short_name(self):
#         """
#         Returns a string like Eb4
#         """
#         return "%s%s" % (self.name, self.octave)
# 
#     def __repr__(self):
#         return "Note<%s%s>" % (self.name, self.octave)


# Path: camp/core/chord.py
from camp.core.note import note, Note

        """
        Constructs a chord, in different ways:

        notes = [ note('C4'), note('E4'), note('G4') ]
	chord = Chord(notes=notes)

        OR:

        chord = Chord(root=note('C4'), type='major')

	OR:

	chord = Chord(root='C4', type='major')
        """

        self.notes = []

        if notes and root:
            raise Exception("notes= and root= are mutually exclusive")
        if notes is None and root is None:
            raise Exception("specify either notes= or root=")
        if root and typ is None:
            raise Exception("typ= is required when using root=")
        if typ and typ not in CHORD_TYPES:
            raise Exception("unknown chord type: %s, expecting one of: %s" % (typ, CHORD_TYPES))
        if isinstance(root, str):
            root = note(root)

        if notes is not None:
            for x in notes:

                assert type(x) == Note