Source code for rv.modules.spectravoice

from enum import Enum

from rv.chunks import ArrayChunk
from rv.controller import Controller
from rv.modules import Behavior as B, Module


[docs]class SpectraVoice(Module): name = mtype = 'SpectraVoice' mgroup = 'Synth' chnk = 0x10 behaviors = {B.receives_notes, B.sends_audio}
[docs] class Mode(Enum): hq = 0 hq_mono = 1 lq = 2 lq_mono = 3 hq_spline = 4
[docs] class HarmonicType(Enum): hsin = 0 rect = 1 org1 = 2 org2 = 3 org3 = 4 org4 = 5 sin = 6 random = 7 triangle1 = 8 triangle2 = 9 overtones1 = 10 overtones2 = 11 overtones3 = 12 overtones4 = 13
class HarmonicValueArray(ArrayChunk): length = 16 class HarmonicFreqArray(HarmonicValueArray): chnm = 0 type = 'H' default = [1098] + [0] * 15 element_size = 2 min_value = 0 max_value = 0x8000 class HarmonicVolumeArray(HarmonicValueArray): chnm = 1 type = 'B' default = [255] + [0] * 15 element_size = 1 min_value = 0 max_value = 0xff class HarmonicWidthArray(HarmonicValueArray): chnm = 2 type = 'B' default = [3] + [0] * 15 element_size = 1 min_value = 0 max_value = 0xff class HarmonicTypeArray(HarmonicValueArray): chnm = 3 type = 'B' element_size = 1 @property def default(self): return [SpectraVoice.HarmonicType.hsin] * 16 @property def encoded_values(self): return [x.value for x in self.values] @property def python_type(self): return SpectraVoice.HarmonicType volume = Controller((0, 256), 128) panning = Controller((-128, 128), 0) attack = Controller((0, 512), 10) release = Controller((0, 512), 512) polyphony_ch = Controller((1, 32), 8) mode = Controller(Mode, Mode.hq_spline) sustain = Controller(bool, True) spectrum_resolution = Controller((0, 5), 1) # Note: These are controllers used to program the module while it's loaded. # When scripting, use the objects in `self.harmonics` instead. harmonic = Controller((0, 15), 0) h_freq_hz = Controller((0, 22050), 1098) h_volume = Controller((0, 255), 255) h_width = Controller((0, 255), 3) h_type = Controller(HarmonicType, HarmonicType.hsin) def __init__(self, **kwargs): harmonics = kwargs.pop('harmonics', []) super(SpectraVoice, self).__init__(**kwargs) self.harmonic_freqs = self.HarmonicFreqArray() self.harmonic_volumes = self.HarmonicVolumeArray() self.harmonic_widths = self.HarmonicWidthArray() self.harmonic_types = self.HarmonicTypeArray() # Initialize harmonics from 'harmonics' kwarg. self.harmonics = [Harmonic(self, index) for index in range(16)] for i, (freq, volume, width, type) in enumerate(harmonics): h = self.harmonics[i] h.freq_hz, h.volume, h.width, h.type = freq, volume, width, type h = self.harmonics[self.harmonic] self.h_freq_hz = h.freq_hz self.h_volume = h.volume self.h_width = h.width self.h_type = h.type def specialized_iff_chunks(self): for chunk in self.harmonic_freqs.chunks(): yield chunk for chunk in self.harmonic_volumes.chunks(): yield chunk for chunk in self.harmonic_widths.chunks(): yield chunk for chunk in self.harmonic_types.chunks(): yield chunk for chunk in super(SpectraVoice, self).specialized_iff_chunks(): yield chunk def load_chunk(self, chunk): if chunk.chnm == 0: self.harmonic_freqs.bytes = chunk.chdt for h, freq in zip(self.harmonics, self.harmonic_freqs.values): h.freq_hz = freq elif chunk.chnm == 1: self.harmonic_volumes.bytes = chunk.chdt for h, volume in zip(self.harmonics, self.harmonic_volumes.values): h.volume = volume elif chunk.chnm == 2: self.harmonic_widths.bytes = chunk.chdt for h, width in zip(self.harmonics, self.harmonic_widths.values): h.width = width elif chunk.chnm == 3: self.harmonic_types.bytes = chunk.chdt for h, type in zip(self.harmonics, self.harmonic_types.values): h.type = type
class Harmonic(object): def __init__(self, module, index): self.module = module self.index = index self._freq_hz = 0 self._volume = 0 self._width = 0 self._type = SpectraVoice.HarmonicType.hsin @property def freq_hz(self): return self._freq_hz @freq_hz.setter def freq_hz(self, value): self._freq_hz = value self.module.harmonic_freqs.values[self.index] = value @property def volume(self): return self._volume @volume.setter def volume(self, value): self._volume = value self.module.harmonic_volumes.values[self.index] = value @property def width(self): return self._width @width.setter def width(self, value): self._width = value self.module.harmonic_widths.values[self.index] = value @property def type(self): return self._type @type.setter def type(self, value): self._type = value if isinstance(value, str): value = SpectraVoice.HarmonicType[value] self.module.harmonic_types.values[self.index] = value