Source code for dspy.note

import numpy as np

from dspy.envelope import ADSREnvelope
from dspy.generator import Generator
from dspy import config
from dspy.lib import t2f, pitch_to_frequency


SAMPLING_RATE = config['SAMPLING_RATE']


[docs]class Note(Generator): def __new__(cls, pitch=60, overtones=[(1, 1, 0)], detune=0, duration=0.5, envelope=None): t = Tone(pitch, overtones, detune) if envelope is None: envelope = ADSREnvelope(duration=duration) gen = t * envelope return gen
[docs]class FM(Generator): def __init__(self, pitch, modulator, detune=0): self.modulator = modulator self.freq = pitch_to_frequency(pitch + detune/100.) self._factor = self.freq * 2.0 * np.pi / SAMPLING_RATE Generator.__init__(self) def _reset(self): self.modulator.reset() def _generate(self, frame_count): domain = np.arange(self.frame, self.frame + frame_count) modulation, cf = self.modulator.generate(frame_count) signal = np.sin(self._factor * domain + modulation, dtype=np.float32) return signal
[docs]class Tone(Generator): def __init__(self, pitch, overtones=[(1, 1, 0)], detune=0): self.freq = pitch_to_frequency(pitch + detune/100.) def nyquist(overtone): return overtone[0] * self.freq < SAMPLING_RATE/2 self.overtones = filter(nyquist, overtones) self._factor = self.freq * 2.0 * np.pi / SAMPLING_RATE Generator.__init__(self) def _generate(self, frame_count): domain = np.arange(self.frame, self.frame + frame_count) signal = np.zeros(frame_count, dtype=np.float32) for order, amp, phase in self.overtones: sine = np.sin(order * self._factor * domain + phase, dtype=np.float32) signal += amp * sine return signal