Source code for sound.note

from . import SAMPLE_RATE
from .signal import ConstantSignal, Signal

__all__ = ('Note',)

numty = (int, float)

[docs] class Note(Signal): """ An abstraction over the signal base class to add timing information. The idea is that a note has a signal and then the value that that signal should be used as, in beats, in addition to the length of a beat. All the binary operators on Sample objects now work with beats instead of seconds. """ def __init__(self, src, value, beat): """ :param src: The signal to use as a source for the note :param value: The value of the note in beats :param beat: The length of a beat in samples """ self.src = ConstantSignal.wrap(src) self.value = value self.beat = beat self.duration = self.src.duration self.pure = self.src.pure def amplitude(self, frame): return self.src.amplitude(frame) def __add__(self, other): if other == 0: return self return Note(self.src + other.src, max(self.value, other.value), other.beat) def __mul__(self, other): if type(other) in numty: return Note(self.src * other, self.value, self.beat) if type(other) is not Note: return Note(self.src * other, self.value, self.beat) return Note(self.src * other.src, max(self.value, other.value), other.beat) def __neg__(self): return Note(-self.src, self.value, self.beat) def __rshift__(self, other): if type(other) not in numty: raise TypeError("Can't shift by %s" % repr(other)) realshift = other * self.beat / SAMPLE_RATE return Note(self.src >> realshift, self.value + other, self.beat) def __and__(self, other): return self + (other >> self.value) def __mod__(self, other): if type(other) not in numty: raise TypeError("Can't loop by %s" % repr(other)) if other == 0: other = self.value return Note(self.src % (other * self.beat / SAMPLE_RATE), float('inf'), self.beat)