Files
smnp-py/smnp/note/model.py
Bartłomiej Pluta 24bcb25bee Enable tuning
2019-09-06 22:59:09 +02:00

67 lines
2.0 KiB
Python

from smnp.note.pitch import NotePitch
class Note:
def __init__(self, note, octave, duration, dot = False):
if octave is None:
octave = 4
if duration is None:
duration = 4
if type(note) == str:
self.note = NotePitch.toPitch(note)
else:
self.note = note
self.octave = octave
self.duration = duration
self.dot = dot
def toFrequency(self, tuning):
return tuning[self.note] * 2 ** self.octave
def transpose(self, interval):
origIntRepr = self._intRepr()
transposedIntRepr = origIntRepr + interval
return Note._fromIntRepr(transposedIntRepr, self.duration, self.dot)
def withDuration(self, duration):
return Note(self.note, self.octave, duration, self.dot)
def withOctave(self, octave):
return Note(self.note, octave, self.duration, self.dot)
def withDot(self):
return Note(self.note, self.octave, self.duration, True)
def withoutDot(self):
return Note(self.note, self.octave, self.duration, False)
def _intRepr(self):
return self.octave * len(NotePitch) + self.note.value
def __str__(self):
return f"{self.note}({self.octave}')[{self.duration}{'.' if self.dot else ''}]"
def __repr__(self):
return self.__str__()
def __eq__(self, other):
return self.note == other.note and self.octave == other.octave and self.duration == other.duration and self.dot == other.dot
def __hash__(self):
return hash(self.__str__())
@staticmethod
def checkInterval(a, b):
return b._intRepr() - a._intRepr()
@staticmethod
def range(a, b):
return [Note._fromIntRepr(x) for x in range(a._intRepr(), b._intRepr()+1)]
@staticmethod
def _fromIntRepr(intRepr, duration = 4, dot = False):
note = NotePitch(intRepr % len(NotePitch))
octave = int(intRepr / len(NotePitch))
return Note(note, octave, duration, dot)