Add dots to notes duration
This commit is contained in:
@@ -203,6 +203,7 @@ def createEnvironment():
|
|||||||
'changeOctave': changeOctave,
|
'changeOctave': changeOctave,
|
||||||
'wait': waitForSound,
|
'wait': waitForSound,
|
||||||
'read': read,
|
'read': read,
|
||||||
|
'debug': lambda args, env: print(args),
|
||||||
'exit': exit
|
'exit': exit
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
26
Note.py
26
Note.py
@@ -55,16 +55,14 @@ class NotePitch(Enum):
|
|||||||
raise SyntaxException(None, f"Note '{string}' does not exist")
|
raise SyntaxException(None, f"Note '{string}' does not exist")
|
||||||
|
|
||||||
class Note:
|
class Note:
|
||||||
def __init__(self, note, octave = 4, duration = 4):
|
def __init__(self, note, octave = 4, duration = 4, dot = False):
|
||||||
if type(note) == str:
|
if type(note) == str:
|
||||||
self.note = NotePitch.toPitch(note)
|
self.note = NotePitch.toPitch(note)
|
||||||
else:
|
else:
|
||||||
self.note = note
|
self.note = note
|
||||||
self.octave = octave
|
self.octave = octave
|
||||||
self.duration = duration
|
self.duration = duration
|
||||||
|
self.dot = dot
|
||||||
def hash(self):
|
|
||||||
return f"{self.note.value}{self.octave}{self.duration}"
|
|
||||||
|
|
||||||
def toFrequency(self):
|
def toFrequency(self):
|
||||||
return self.note.toFrequency() * 2 ** self.octave
|
return self.note.toFrequency() * 2 ** self.octave
|
||||||
@@ -72,28 +70,34 @@ class Note:
|
|||||||
def transpose(self, interval):
|
def transpose(self, interval):
|
||||||
origIntRepr = self._intRepr()
|
origIntRepr = self._intRepr()
|
||||||
transposedIntRepr = origIntRepr + interval
|
transposedIntRepr = origIntRepr + interval
|
||||||
return Note._fromIntRepr(transposedIntRepr, self.duration)
|
return Note._fromIntRepr(transposedIntRepr, self.duration, self.dot)
|
||||||
|
|
||||||
def withDuration(self, duration):
|
def withDuration(self, duration):
|
||||||
return Note(self.note, self.octave, duration)
|
return Note(self.note, self.octave, duration, self.dot)
|
||||||
|
|
||||||
def withOctave(self, octave):
|
def withOctave(self, octave):
|
||||||
return Note(self.note, octave, self.duration)
|
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):
|
def _intRepr(self):
|
||||||
return self.octave * len(NotePitch) + self.note.value
|
return self.octave * len(NotePitch) + self.note.value
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.note}({self.octave}')[{self.duration}]"
|
return f"{self.note}({self.octave}')[{self.duration}{'.' if self.dot else ''}]"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.__str__()
|
return self.__str__()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _fromIntRepr(intRepr, duration=4):
|
def _fromIntRepr(intRepr, duration = 4, dot = False):
|
||||||
note = NotePitch(intRepr % len(NotePitch))
|
note = NotePitch(intRepr % len(NotePitch))
|
||||||
octave = int(intRepr / len(NotePitch))
|
octave = int(intRepr / len(NotePitch))
|
||||||
return Note(note, octave, duration)
|
return Note(note, octave, duration, dot)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -102,7 +106,7 @@ class Note:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def range(a, b):
|
def range(a, b):
|
||||||
return [Note._fromIntRepr(x, 4) for x in range(a._intRepr(), b._intRepr()+1)]
|
return [Note._fromIntRepr(x) for x in range(a._intRepr(), b._intRepr()+1)]
|
||||||
|
|
||||||
def intervalToString(interval):
|
def intervalToString(interval):
|
||||||
octaveInterval = int(abs(interval) / len(NotePitch))
|
octaveInterval = int(abs(interval) / len(NotePitch))
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ def parseNote(input, parent):
|
|||||||
consumedChars += 1
|
consumedChars += 1
|
||||||
octave = 4
|
octave = 4
|
||||||
duration = 4
|
duration = 4
|
||||||
|
dot = False
|
||||||
if consumedChars < len(value) and value[consumedChars] in ('b', '#'):
|
if consumedChars < len(value) and value[consumedChars] in ('b', '#'):
|
||||||
notePitch += value[consumedChars]
|
notePitch += value[consumedChars]
|
||||||
consumedChars += 1
|
consumedChars += 1
|
||||||
@@ -35,8 +36,11 @@ def parseNote(input, parent):
|
|||||||
durationString += value[consumedChars]
|
durationString += value[consumedChars]
|
||||||
consumedChars += 1
|
consumedChars += 1
|
||||||
duration = int(durationString)
|
duration = int(durationString)
|
||||||
|
if consumedChars < len(value) and value[consumedChars] == '.':
|
||||||
|
dot = True
|
||||||
|
consumedChars += 1
|
||||||
|
|
||||||
return NoteLiteralNode(Note(notePitch, octave, duration), token.pos)
|
return NoteLiteralNode(Note(notePitch, octave, duration, dot), token.pos)
|
||||||
|
|
||||||
def parseComma(input, parent):
|
def parseComma(input, parent):
|
||||||
token = input.pop(0)
|
token = input.pop(0)
|
||||||
|
|||||||
1
Synth.py
1
Synth.py
@@ -26,6 +26,7 @@ def playList(notes, env):
|
|||||||
def playNote(note, bpm):
|
def playNote(note, bpm):
|
||||||
frequency = note.toFrequency()
|
frequency = note.toFrequency()
|
||||||
duration = 60 * 4 / note.duration / bpm
|
duration = 60 * 4 / note.duration / bpm
|
||||||
|
duration *= 1.5 if note.dot else 1
|
||||||
sine(frequency, duration)
|
sine(frequency, duration)
|
||||||
|
|
||||||
def sine(frequency, duration):
|
def sine(frequency, duration):
|
||||||
|
|||||||
@@ -138,6 +138,9 @@ def tokenizeNote(input, current, line):
|
|||||||
while current+consumedChars < len(input) and re.match(r'\d', input[current+consumedChars]):
|
while current+consumedChars < len(input) and re.match(r'\d', input[current+consumedChars]):
|
||||||
value += input[current+consumedChars]
|
value += input[current+consumedChars]
|
||||||
consumedChars += 1
|
consumedChars += 1
|
||||||
|
if current+consumedChars < len(input) and input[current+consumedChars] == '.':
|
||||||
|
value += input[current+consumedChars]
|
||||||
|
consumedChars += 1
|
||||||
return (consumedChars, Token(TokenType.NOTE, value, (line, current)))
|
return (consumedChars, Token(TokenType.NOTE, value, (line, current)))
|
||||||
return (0, None)
|
return (0, None)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user