Numuse Documentation

numuse.music

Source code for numuse.music

from __future__ import annotations
from typing import List, Type
from fractions import Fraction
from .notation import NoteCollection


[docs]class Music: """Represents notes that are played over time"""
[docs] def __init__(self, measures: List[Measure], BPM: int, beats_in_a_measure: int = 4): self.measures = measures # TODO this only works for music with only single line measures # Otherwise we need to specify that lines need to come in the same order # in each measure, but that becomes complicated when # of lines change self.continuous = [moment for measure in measures for line in measure.lines for moment in line.moments] # Assumes a song stays at a constant tempo # TODO: make it dynamic self.BPM = BPM self.beats_in_a_measure = beats_in_a_measure self.measure_length = self.bpm_to_measure_length()
def bpm_to_measure_length(self, beats_in_a_measure: int = 4) -> float: # TODO this doesn't make sense if you have a change of meter # but we can do that later # returns in seconds beats_per_second = self.BPM * 1 / 60 seconds_per_beat = 1 / beats_per_second measure_length = seconds_per_beat * beats_in_a_measure return measure_length def __repr__(self): return str(self.__class__) + ": " + str(self.__dict__)
[docs]class Measure:
[docs] def __init__( self, lines: List[Line], beats_in_a_measure: int = 4, beat_duration: Fraction = 1, ): self.lines = lines self.beats_in_a_measure = beats_in_a_measure self.beat_duration = beat_duration self.measure_duration = sum(m_l.line_duration for m_l in lines)
def __repr__(self): return str(self.__class__) + ": " + str(self.__dict__)
[docs]class Moment:
[docs] def __init__(self, time: float, notes: Type[NoteCollection], duration: Fraction): self.time = time self.notes = notes self.duration = duration
def __str__(self): return f"Notes: {self.notes}, Held for: {self.duration}, At time: {self.time}" def __repr__(self): return str(self.__class__) + ": " + str(self.__dict__)
[docs]class Line: """Due to the way we write music notes follow consecutively In order to write ideas like this: Note 1: ========================== Note 2: ======== Then one solution is to have two different clefs This class represents such a clef Note this is required because of the way we notate things sequentially in music """
[docs] def __init__(self, moments: List[Moment]): self.moments = moments self.line_duration = sum(m_m.duration for m_m in self.moments)
def __repr__(self): return str(self.__class__) + ": " + str(self.__dict__)
[docs]class StructuredMusic(Music): """Represents notes played over time that are related to an underlying structure In this case the structure is a set of notes which have a higher probability of being played than other notes. The structure is a note collection and can be specified using a RIC music_data is now allowed to use a special type of syntax on top of the previous method """ pass
Free document hosting provided by Read the Docs.