예제 #1
0
class Flanger(Module):

    name = mtype = "Flanger"
    mgroup = "Effect"
    flags = 0x000451

    behaviors = {B.receives_audio, B.sends_audio}

    class LfoWaveform(Enum):
        hsin = 0
        sin = 1

    class LfoFreqUnit(Enum):
        hz_0_05 = 0  # hz * 0.05
        ms = 1
        hz = 2
        tick = 3
        line = 4
        line_2 = 5  # line / 2
        line_3 = 6  # line / 3

    dry = Controller((0, 256), 256)
    wet = Controller((0, 256), 128)
    feedback = Controller((0, 256), 128)
    delay = Controller((0, 1000), 200)
    response = Controller((0, 256), 2)
    lfo_freq = Controller((0, 512), 8)
    lfo_amp = Controller((0, 256), 32)
    lfo_waveform = Controller(LfoWaveform, LfoWaveform.hsin)
    set_lfo_phase = Controller((0, 256), 0)  # used to reset module
    lfo_freq_unit = Controller(LfoFreqUnit, LfoFreqUnit.hz_0_05)
예제 #2
0
class Generator(Module):

    name = mtype = "Generator"
    mgroup = "Synth"
    chnk = 1
    flags = 0x000059

    behaviors = {B.receives_notes, B.receives_modulator, B.sends_audio}

    class Waveform(Enum):
        triangle = 0
        saw = 1
        square = 2
        noise = 3
        dirty = 4
        sin = 5
        hsin = 6
        asin = 7
        psin = 8

    class Mode(Enum):
        stereo = 0
        mono = 1

    class DirtyWaveform(DirtyWaveformChunk):
        chnm = 0

    volume = Controller((0, 256), 128)
    waveform = Controller(Waveform, Waveform.triangle)
    panning = Controller((-128, 128), 0)
    attack = Controller((0, 512), 0)
    release = Controller((0, 512), 0)
    polyphony_ch = Controller((1, 16), 8)
    mode = Controller(Mode, Mode.stereo)
    sustain = Controller(bool, True)
    freq_modulation_input = Controller((0, 256), 0)
    duty_cycle = Controller((0, 1022), 511)

    def __init__(self, **kwargs):
        samples = kwargs.pop("samples", None)
        super(Generator, self).__init__(**kwargs)
        self.dirty_waveform = self.DirtyWaveform()
        if samples is not None:
            self.dirty_waveform.samples = samples

    def specialized_iff_chunks(self):
        for chunk in self.dirty_waveform.chunks():
            yield chunk
        for chunk in super(Generator, self).specialized_iff_chunks():
            yield chunk

    def load_chunk(self, chunk):
        if chunk.chnm == 0:
            self.load_dirty_waveform(chunk)

    def load_dirty_waveform(self, chunk):
        self.dirty_waveform.samples = chunk.chdt
        self.dirty_waveform.format = self.dirty_waveform.Format(chunk.chff or 1)
        self.dirty_waveform.freq = chunk.chfr
예제 #3
0
class Lfo(Module):

    name = mtype = "LFO"
    mgroup = "Effect"
    flags = 0x000451

    behaviors = {B.sends_audio}

    class Type(Enum):
        amplitude = 0
        panning = 1

    class Waveform(Enum):
        sin = 0
        square = 1
        sin2 = 2
        saw = 3
        saw2 = 4
        random = 5
        triangle = 6
        random_interpolated = 7

    class Channels(Enum):
        stereo = 0
        mono = 1

    class FrequencyUnit(Enum):
        hz_64 = 0  # hz / 64
        ms = 1
        hz = 2
        tick = 3
        line = 4
        line_2 = 5  # line / 2
        line_3 = 6  # line / 3

    freq_ranges = {
        FrequencyUnit.hz_64: WarnOnlyRange(1, 2048),
        FrequencyUnit.ms: WarnOnlyRange(1, 4000),
        FrequencyUnit.hz: WarnOnlyRange(1, 16384),
        FrequencyUnit.tick: WarnOnlyRange(1, 256),
        FrequencyUnit.line: WarnOnlyRange(1, 256),
        FrequencyUnit.line_2: WarnOnlyRange(1, 256),
        FrequencyUnit.line_3: WarnOnlyRange(1, 256),
    }

    volume = Controller((0, 512), 256)
    type = Controller(Type, Type.amplitude)
    amplitude = Controller((0, 256), 256)
    freq = Controller(
        DependentRange("frequency_unit", freq_ranges, Range(1, 2048)), 256)
    waveform = Controller(Waveform, Waveform.sin)
    set_phase = Controller((0, 256), 0)  # used to reset module
    channels = Controller(Channels, Channels.stereo)
    frequency_unit = Controller(FrequencyUnit, FrequencyUnit.hz_64)
    duty_cycle = Controller((0, 256), 128)
    generator = Controller(bool, False)
예제 #4
0
class Sound2Ctl(Module):

    name = mtype = "Sound2Ctl"
    mgroup = "Misc"
    chnk = 1
    options_chnm = 0
    flags = 0x600051

    class Channels(Enum):
        mono = 0
        stereo = 1

    class Mode(Enum):
        lq = 0
        hq = 1

    behaviors = {B.receives_audio, B.sends_controls}

    sample_rate_hz = Controller((1, 32768), 50)
    channels = Controller(Channels, Channels.mono)
    absolute = Controller(bool, True)
    gain = Controller((0, 1024), 256)
    smooth = Controller((0, 256), 128)
    mode = Controller(Mode, Mode.hq)
    out_min = Controller((0, 32768), 0)
    out_max = Controller((0, 32768), 32768)
    out_controller = Controller((0, 32), 0)

    record_values = Option(False)

    def load_chunk(self, chunk):
        if chunk.chnm == self.options_chnm:
            self.load_options(chunk)
예제 #5
0
class Delay(Module):

    name = mtype = "Delay"
    mgroup = "Effect"
    flags = 0x000451

    behaviors = {B.receives_audio, B.sends_audio}

    class Channels(Enum):
        stereo = 0
        mono = 1

    class DelayUnits(Enum):
        sec_16384 = 0  # sec/16384
        ms = 1
        hz = 2
        tick = 3
        line = 4
        line_2 = 5  # line/2
        line_3 = 6  # line/3

    dry = Controller((0, 512), 256)
    wet = Controller((0, 512), 256)
    delay_l = Controller((0, 256), 128)
    delay_r = Controller((0, 256), 160)
    volume_l = Controller((0, 256), 256)
    volume_r = Controller((0, 256), 256)
    channels = Controller(Channels, Channels.stereo)
    inverse = Controller(bool, False)
    delay_units = Controller(DelayUnits, DelayUnits.sec_16384)
예제 #6
0
class Input(Module):

    name = mtype = "Input"
    mgroup = "Synth"
    flags = 0x000049

    behaviors = {B.sends_audio}

    class Channels(Enum):
        mono = 0
        stereo = 1

    volume = Controller((0, 1024), 256)
    channels = Controller(Channels, Channels.mono)
예제 #7
0
class Eq(Module):

    name = mtype = "EQ"
    mgroup = "Effect"
    flags = 0x000051

    behaviors = {B.receives_audio, B.sends_audio}

    class Channels(Enum):
        stereo = 0
        mono = 1

    low = Controller((0, 512), 256)
    middle = Controller((0, 512), 256)
    high = Controller((0, 512), 256)
    channels = Controller(Channels, Channels.stereo)
예제 #8
0
class Feedback(Module):

    name = mtype = "Feedback"
    mgroup = "Misc"
    flags = 0x600051

    behaviors = {
        B.receives_audio, B.receives_feedback, B.sends_audio, B.sends_feedback
    }

    class Channels(Enum):
        stereo = 0
        mono = 1

    volume = Controller((0, 10000), 1000)
    channels = Controller(Channels, Channels.stereo)
예제 #9
0
class VocalFilter(Module):

    name = mtype = "Vocal filter"
    mgroup = "Effect"
    flags = 0x000051

    behaviors = {B.receives_audio, B.sends_audio}

    class VoiceType(Enum):
        soprano = 0
        alto = 1
        tenor = 2
        bass = 3

    class Channels(Enum):
        stereo = 0
        mono = 1

    volume = Controller((0, 512), 256)
    formant_width_hz = Controller((0, 256), 128)
    intensity = Controller((0, 256), 128)
    formants = Controller((1, 5), 5)
    vowel = Controller((0, 256), 0)
    voice_type = Controller(VoiceType, VoiceType.soprano)
    channels = Controller(Channels, Channels.stereo)
예제 #10
0
class VorbisPlayer(Module):

    name = mtype = "Vorbis player"
    mgroup = "Synth"
    chnk = 1
    flags = 0x008049

    behaviors = {B.sends_audio}

    data = None

    volume = Controller((0, 512), 256)
    original_speed = Controller(bool, True)
    finetune = Controller((-128, 128), 0)
    transpose = Controller((-128, 128), 0)
    interpolation = Controller(bool, True)
    polyphony_ch = Controller((1, 4), 1)
    repeat = Controller(bool, False)

    def __init__(self, **kwargs):
        data = kwargs.pop("data", None)
        super(VorbisPlayer, self).__init__(**kwargs)
        self.data = data

    def specialized_iff_chunks(self):
        yield (b"CHNM", pack("<I", 0))
        yield (b"CHDT", self.data or b"")
        yield from super(VorbisPlayer, self).specialized_iff_chunks()

    def load_chunk(self, chunk):
        if chunk.chnm == 0:
            self.data = chunk.chdt
예제 #11
0
class Velocity2Ctl(Module):

    name = mtype = "Velocity2Ctl"
    mgroup = "Misc"
    flags = 0x020049

    behaviors = {B.receives_notes, B.sends_controls}

    class NoteOffAction(Enum):
        do_nothing = 0
        vel_down = 1
        vel_up = 2

    note_off_action = Controller(NoteOffAction, NoteOffAction.do_nothing)
    out_min = Controller((0, 32768), 0)
    out_max = Controller((0, 32768), 32768)
    out_offset = Controller((-16384, 16384), 0)
    out_controller = Controller((0, 32), 0)
예제 #12
0
class Modulator(Module):

    name = mtype = "Modulator"
    mgroup = "Effect"
    flags = 0x002051

    behaviors = {B.receives_audio, B.receives_modulator, B.sends_audio}

    class ModulationType(Enum):
        amplitude = 0
        phase = 1
        phase_abs = 2

    class Channels(Enum):
        stereo = 0
        mono = 1

    volume = Controller((0, 512), 256)
    modulation_type = Controller(ModulationType, ModulationType.amplitude)
    channels = Controller(Channels, Channels.stereo)
예제 #13
0
class Loop(Module):

    name = mtype = "Loop"
    mgroup = "Effect"
    flags = 0x000451

    behaviors = {B.receives_audio, B.sends_audio}

    class Channels(Enum):
        mono = 0
        stereo = 1

    class Mode(Enum):
        normal = 0
        ping_pong = 1

    volume = Controller((0, 256), 256)
    delay = Controller((0, 256), 256)  # line / 128
    channels = Controller(Channels, Channels.stereo)
    repeats = Controller((0, 64), 0)
    mode = Controller(Mode, Mode.normal)
예제 #14
0
class Echo(Module):

    name = mtype = "Echo"
    mgroup = "Effect"
    flags = 0x000451

    behaviors = {B.receives_audio, B.sends_audio}

    class Channels(Enum):
        mono = 0
        stereo = 1

    class DelayUnits(Enum):
        sec_256 = 0  # sec/256
        ms = 1
        hz = 2
        tick = 3
        line = 4
        line_2 = 5  # line/2
        line_3 = 6  # line/3

    dry = Controller((0, 256), 256)
    wet = Controller((0, 256), 128)
    feedback = Controller((0, 256), 128)
    delay = Controller((0, 256), 256)
    channels = Controller(Channels, Channels.stereo)
    delay_units = Controller(DelayUnits, DelayUnits.sec_256)
예제 #15
0
class DcBlocker(Module):

    name = mtype = "DC Blocker"
    mgroup = "Effect"
    flags = 0x000051

    behaviors = {B.receives_audio, B.sends_audio}

    class Channels(Enum):
        stereo = 0
        mono = 1

    channels = Controller(Channels, Channels.stereo)
예제 #16
0
class Reverb(Module):

    name = mtype = "Reverb"
    mgroup = "Effect"
    flags = 0x000051

    behaviors = {B.receives_audio, B.sends_audio}

    class Mode(Enum):
        hq = 0
        hq_mono = 1
        lq = 2
        lq_mono = 3

    dry = Controller((0, 256), 256)
    wet = Controller((0, 256), 64)
    feedback = Controller((0, 256), 256)
    damp = Controller((0, 256), 128)
    stereo_width = Controller((0, 256), 256)
    freeze = Controller(bool, False)
    mode = Controller(Mode, Mode.hq)
    all_pass_filter = Controller(bool, True)
    room_size = Controller((0, 128), 16)
    random_seed = Controller((0, 32768), 0)
예제 #17
0
class Kicker(Module):

    name = mtype = "Kicker"
    mgroup = "Synth"
    flags = 0x000049

    behaviors = {B.receives_notes, B.sends_audio}

    class Waveform(Enum):
        triangle = 0
        square = 1
        sin = 2

    volume = Controller((0, 256), 256)
    waveform = Controller(Waveform, Waveform.triangle)
    panning = Controller((-128, 128), 0)
    attack = Controller((0, 512), 0)
    release = Controller((0, 512), 32)
    boost = Controller((0, 1024), 0)
    env_acceleration = Controller((0, 1024), 256)
    polyphony_ch = Controller((1, 4), 1)
    anticlick = Controller(bool, False)
예제 #18
0
class Gpio(Module):

    name = mtype = "GPIO"
    mgroup = "Misc"
    flags = 0x000051

    behaviors = {B.receives_audio, B.sends_audio}

    out = Controller(bool, False)
    out_pin = Controller((0, 256), 0)
    out_threshold = Controller((0, 100), 50)
    in_ = Controller(bool, False)
    in_pin = Controller((0, 256), 0)
    in_note = Controller((0, 128), 0)
    in_amplitude = Controller((0, 100), 100)
예제 #19
0
class Glide(Module):

    name = mtype = "Glide"
    mgroup = "Misc"
    flags = 0x021049

    behaviors = {B.receives_notes, B.sends_notes}

    response = Controller((0, 1000), 500)
    sample_rate_hz = Controller((1, 32768), 150)
    offset_on_1st_note = Controller(bool, False)
    polyphony = Controller(bool, True)
    pitch = Controller((-600, 600), 0)
    pitch_scale = Controller((0, 200), 100)
    reset = Controller(bool, False)  # used to reset module
예제 #20
0
class Amplifier(Module):

    name = mtype = "Amplifier"
    mgroup = "Effect"
    flags = 0x000051

    behaviors = {B.receives_audio, B.sends_audio}

    receives_audio = True
    sends_audio = True

    volume = Controller((0, 1024), 256)
    panning = Controller((-128, 128), 0)
    dc_offset = Controller((-128, 128), 0)
    inverse = Controller(bool, False)
    stereo_width = Controller((0, 256), 128)
    absolute = Controller(bool, False)
    fine_volume = Controller((0, 32768), 32768)
    gain = Controller((0, 5000), 1)
예제 #21
0
class WaveShaper(Module):

    name = mtype = "WaveShaper"
    mgroup = "Effect"
    chnk = 1
    flags = 0x000051

    behaviors = {B.receives_audio, B.sends_audio}

    class Mode(Enum):
        hq = 0
        hq_mono = 1
        lq = 2
        lq_mono = 3

    class Curve(ArrayChunk):
        chnm = 0
        length = 256
        type = "H"
        element_size = 2
        min_value = 0
        max_value = 0xFFFF

        def default(self, x):
            return x * 0x100

    input_volume = Controller((0, 512), 256)
    mix = Controller((0, 256), 256)
    output_volume = Controller((0, 512), 256)
    symmetric = Controller(bool, True)
    mode = Controller(Mode, Mode.hq)
    dc_blocker = Controller(bool, True)

    def __init__(self, **kwargs):
        values = kwargs.pop("values", None)
        super(WaveShaper, self).__init__(**kwargs)
        self.curve = self.Curve()
        if values is not None:
            self.curve.values = values

    def specialized_iff_chunks(self):
        for chunk in self.curve.chunks():
            yield chunk
        for chunk in super(WaveShaper, self).specialized_iff_chunks():
            yield chunk

    def load_chunk(self, chunk):
        if chunk.chnm == 0:
            self.curve.bytes = chunk.chdt
예제 #22
0
class Compressor(Module):

    name = mtype = "Compressor"
    mgroup = "Effect"
    flags = 0x002051

    behaviors = {B.receives_audio, B.sends_audio}

    class Mode(Enum):
        peak = 0
        rms = 1
        peak_zero_latency = 2

    volume = Controller((0, 512), 256)
    threshold = Controller((0, 512), 256)
    slope_pct = Controller((0, 200), 100)
    attack_ms = Controller((0, 500), 1)
    release_ms = Controller((1, 1000), 300)
    mode = Controller(Mode, Mode.peak)
    sidechain_input = Controller((0, 32), 0)
예제 #23
0
class Vibrato(Module):

    name = mtype = "Vibrato"
    mgroup = "Effect"
    flags = 0x000451

    behaviors = {B.receives_audio, B.sends_audio}

    class Channels(Enum):
        stereo = 0
        mono = 1

    class FrequencyUnit(Enum):
        hz_64 = 0  # hz / 64
        ms = 1
        hz = 2
        tick = 3
        line = 4
        line_2 = 5  # line / 2
        line_3 = 6  # line / 3

    freq_ranges = {
        FrequencyUnit.hz_64: WarnOnlyRange(1, 2048),
        FrequencyUnit.ms: WarnOnlyRange(1, 4000),
        FrequencyUnit.hz: WarnOnlyRange(1, 16384),
        FrequencyUnit.tick: WarnOnlyRange(1, 2048),
        FrequencyUnit.line: WarnOnlyRange(1, 2048),
        FrequencyUnit.line_2: WarnOnlyRange(1, 2048),
        FrequencyUnit.line_3: WarnOnlyRange(1, 2048),
    }

    volume = Controller((0, 256), 256)
    amplitude = Controller((0, 256), 16)
    freq = Controller(
        DependentRange("frequency_unit", freq_ranges, Range(1, 2048)), 256)
    channels = Controller(Channels, Channels.stereo)
    set_phase = Controller((0, 256), 0)  # used to reset module
    frequency_unit = Controller(FrequencyUnit, FrequencyUnit.hz_64)
    exponential_amplitude = Controller(bool, False)
예제 #24
0
class PitchShifter(Module):

    name = mtype = "Pitch shifter"
    mgroup = "Effect"
    flags = 0x000051

    behaviors = {B.receives_audio, B.sends_audio}

    class Mode(Enum):
        hq = 0
        hq_mono = 1
        lq = 2
        lq_mono = 3

    volume = Controller((0, 512), 256)
    pitch = Controller((-600, 600), 0)
    pitch_scale = Controller((0, 200), 100)
    feedback = Controller((0, 256), 0)
    grain_size = Controller((0, 256), 64)
    mode = Controller(Mode, Mode.hq)
예제 #25
0
class Pitch2Ctl(Module):

    name = mtype = "Pitch2Ctl"
    mgroup = "Misc"
    flags = 0x020049

    behaviors = {B.receives_notes, B.sends_controls}

    class Mode(Enum):
        frequency_hz = 0
        pitch = 1

    class NoteOffAction(Enum):
        do_nothing = 0
        pitch_down = 1
        pitch_up = 2

    mode = Controller(Mode, Mode.frequency_hz)
    note_off_action = Controller(NoteOffAction, NoteOffAction.do_nothing)
    first_note = Controller((0, 256), 0)
    number_of_semitones = Controller((0, 256), 120)
    out_min = Controller((0, 32768), 0)
    out_max = Controller((0, 32768), 32768)
    out_controller = Controller((0, 32), 0)
예제 #26
0
class Distortion(Module):

    name = mtype = "Distortion"
    mgroup = "Effect"
    flags = 0x000051

    behaviors = {B.receives_audio, B.sends_audio}

    class Type(Enum):
        lim = 0
        clipping = 0
        sat = 1
        foldback = 1
        foldback2 = 2
        foldback3 = 3
        overflow = 4

    volume = Controller((0, 256), 128)
    type = Controller(Type, Type.lim)
    power = Controller((0, 256), 0)
    bit_depth = Controller((1, 16), 16)
    freq_hz = Controller((0, 44100), 44100)
    noise = Controller((0, 256), 0)
예제 #27
0
class MultiCtl(Module):

    name = mtype = "MultiCtl"
    mgroup = "Misc"
    chnk = 2
    flags = 0x020051

    behaviors = {B.sends_controls}

    class Mapping:
        def __init__(self, value):
            self.min, self.max, self.controller = value[:3]

    class MappingArray(ArrayChunk):
        chnm = 0
        length = 16
        type = "IIIIIIII"
        element_size = 4 * 8

        def default(self, _):
            return MultiCtl.Mapping((0, 0x8000, 0))

        @property
        def encoded_values(self):
            return list(
                chain.from_iterable((x.min, x.max, x.controller, 0, 0, 0, 0, 0)
                                    for x in self.values))

        @property
        def python_type(self):
            return MultiCtl.Mapping

    class Curve(ArrayChunk):
        chnm = 1
        length = 257
        type = "H"
        element_size = 2
        min_value = 0
        max_value = 0x8000

        def default(self, x):
            return x * 0x80

    value = Controller((0, 32768), 0)
    gain = Controller((0, 1024), 256)
    quantization = Controller((0, 32768), 32768)
    out_offset = Controller((-16384, 16384), 0)
    response = Controller((0, 1000), 1000)
    sample_rate_hz = Controller((1, 32768), 150)

    def __init__(self, **kwargs):
        curve = kwargs.pop("curve", None)
        mappings = kwargs.pop("mappings", [])
        super(MultiCtl, self).__init__(**kwargs)
        self.curve = self.Curve()
        if curve is not None:
            self.curve.values = curve
        self.mappings = self.MappingArray()
        for i, mapping in enumerate(mappings):
            self.mappings.values[i] = self.Mapping(mapping)

    def on_value_changed(self, value, down, up):
        if self.parent is None or not down:
            return
        downstream_mods = []
        for to_mod in range(256):
            from_mods = self.parent.module_connections[to_mod]
            if self.index in from_mods:
                downstream_mods.append(to_mod)
        for i, to_mod in enumerate(downstream_mods):
            mapping = self.mappings.values[i]
            mod = self.parent.modules[to_mod]
            ctl = list(mod.controllers.values())[mapping.controller - 1]
            vt = ctl.value_type
            if isinstance(vt, Range):
                vmax = None if isinstance(vt,
                                          CompactRange) else vt.max - vt.min
                smin, smax = mapping.min, mapping.max
                dmin, dmax = 0, vt.max - vt.min
                if smin > smax:
                    smin, smax = smax, smin
                    dmin, dmax = dmax, dmin
                converted = convert_value(
                    self.gain,
                    self.quantization,
                    smin,
                    smax,
                    dmin,
                    dmax,
                    vmax,
                    self.value,
                    self.curve.values,
                )
                final_value = converted + vt.min
                setattr(mod, ctl.name, final_value)
                # TODO: apply out_offset
                # TODO: what should we do if it's not a range?

    def reflect(self, index=0, propagate=True):
        """Reflect the value of the controller mapped at the given index; inverse of setting value"""
        downstream_mods = []
        for to_mod in range(256):
            from_mods = self.parent.module_connections[to_mod]
            if self.index in from_mods:
                downstream_mods.append(to_mod)
                if len(downstream_mods) == index + 1:
                    break
        else:
            raise IndexError(
                "No destination module mapped at index {}".format(index))
        mapping = self.mappings.values[index]
        if mapping.controller == 0:
            raise IndexError(
                "No destination controller mapped at index {}".format(index))
        reflect_mod = self.parent.modules[downstream_mods[-1]]
        reflect_ctl_name = list(reflect_mod.controllers)[mapping.controller -
                                                         1]
        reflect_ctl = reflect_mod.controllers[reflect_ctl_name]
        reflect_value = getattr(reflect_mod, reflect_ctl_name)
        if hasattr(reflect_value, "value"):
            reflect_value = reflect_value.value
        t = reflect_ctl.value_type
        if isinstance(t, Range):
            dmin = t.min
            dmax = t.max
        elif t is bool:
            dmin = 0
            dmax = 1
        elif isinstance(t, type) and issubclass(t, Enum):
            dmin = 0
            dmax = len(t)
        else:
            dmin = 0
            dmax = 32768
        inverted = invert_value(
            gain=self.gain,
            smin=mapping.min,
            smax=mapping.max,
            dmin=dmin,
            dmax=dmax,
            vmax=dmax - dmin if dmax > dmin else dmin - dmax,
            value=reflect_value,
        )
        if propagate:
            self.value = inverted
        else:
            self.controller_values["value"] = inverted

    def specialized_iff_chunks(self):
        yield from self.mappings.chunks()
        yield from self.curve.chunks()
        yield from super(MultiCtl, self).specialized_iff_chunks()

    def load_chunk(self, chunk):
        if chunk.chnm == 0:
            self.mappings.bytes = chunk.chdt
        elif chunk.chnm == 1:
            self.curve.bytes = chunk.chdt

    @staticmethod
    def macro(project,
              *mod_ctl_pairs,
              name=None,
              layer=0,
              x=0,
              y=0,
              initial=None):
        if len(mod_ctl_pairs) > 16:
            raise MappingError("MultiCtl supports max of 16 destinations")
        mappings = []
        mods = []
        gains = set()
        for mod, ctl in mod_ctl_pairs:
            if not isinstance(ctl, Controller):
                ctl = mod.controllers[ctl]
            t = ctl.instance_value_type(mod)
            if isinstance(t, type) and issubclass(t, Enum):
                mapmin, mapmax = 0, len(t) - 1
                gains.add(256 + int(256 / mapmax))
            elif t is bool:
                mapmin, mapmax = 0, 1
                gains.add(512)
            elif t.min == 1:
                mapmin, mapmax = t.min, t.max
                gains.add(256 + int(256 / mapmax))
            elif isinstance(t, CompactRange):
                mapmin, mapmax = 0, (t.max - t.min)
                gains.add(256)
            else:
                mapmin, mapmax = 0, 0x8000
                gains.add(256)
            mappings.append((mapmin, mapmax, ctl.number))
            mods.append(project.modules[mod.index])
        if len(mods) != len(set(mods)):
            raise MappingError(
                "Only one MultiCtl mapping per destination module allowed")
        gain = list(gains).pop() if gains and len(gains) == 1 else 256
        bundle = project.new_module(MultiCtl,
                                    name=name,
                                    layer=layer,
                                    x=x,
                                    y=y,
                                    gain=gain,
                                    mappings=mappings)
        bundle >> mods
        if initial is not None:
            bundle.value = initial
        return bundle
예제 #28
0
class Fm(Module):

    name = mtype = "FM"
    mgroup = "Synth"
    flags = 0x000049

    behaviors = {B.receives_notes, B.sends_audio}

    class Mode(Enum):
        hq = 0
        hq_mono = 1
        lq = 2
        lq_mono = 3

    c_volume = Controller((0, 256), 128)
    m_volume = Controller((0, 256), 48)
    panning = Controller((-128, 128), 0)
    c_freq_ratio = Controller((0, 16), 1)
    m_freq_ratio = Controller((0, 16), 1)
    m_feedback = Controller((0, 256), 0)
    c_attack = Controller((0, 512), 32)
    c_decay = Controller((0, 512), 32)
    c_sustain = Controller((0, 256), 128)
    c_release = Controller((0, 512), 64)
    m_attack = Controller((0, 512), 32)
    m_decay = Controller((0, 512), 32)
    m_sustain = Controller((0, 256), 128)
    m_release = Controller((0, 512), 64)
    m_scaling_per_key = Controller((0, 4), 0)
    polyphony_ch = Controller((1, 16), 4)
    mode = Controller(Mode, Mode.hq)
예제 #29
0
class SpectraVoice(Module):

    name = mtype = "SpectraVoice"
    mgroup = "Synth"
    chnk = 4
    flags = 0x000049

    behaviors = {B.receives_notes, B.sends_audio}

    class Mode(Enum):
        hq = 0
        hq_mono = 1
        lq = 2
        lq_mono = 3
        hq_spline = 4

    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
예제 #30
0
class Filter(Module):

    name = mtype = "Filter"
    mgroup = "Effect"
    flags = 0x000451

    behaviors = {B.receives_audio, B.sends_audio}

    class Type(Enum):
        lp = 0
        hp = 1
        bp = 2
        notch = 3

    class Mode(Enum):
        hq = 0
        hq_mono = 1
        lq = 2
        lq_mono = 3

    class RollOff(Enum):
        db_12 = 0
        db_24 = 1
        db_36 = 2
        db_48 = 3

    class LfoFreqUnit(Enum):
        hz_0_02 = 0  # hz * 0.02
        ms = 1
        hz = 2
        tick = 3
        line = 4
        line_2 = 5  # line / 2
        line_3 = 6  # line / 3

    class LfoWaveform(Enum):
        sin = 0
        saw = 1
        saw2 = 2
        square = 3
        random = 4

    volume = Controller((0, 256), 256)
    freq = Controller((0, 14000), 14000)
    resonance = Controller((0, 1530), 0)
    type = Controller(Type, Type.lp)
    response = Controller((0, 256), 8)
    mode = Controller(Mode, Mode.hq)
    impulse = Controller((0, 14000), 0)
    mix = Controller((0, 256), 256)
    lfo_freq = Controller((0, 1024), 8)
    lfo_amp = Controller((0, 256), 0)
    set_lfo_phase = Controller((0, 256), 0)  # used to reset module
    exponential_freq = Controller(bool, False)
    roll_off = Controller(RollOff, RollOff.db_12)
    lfo_freq_unit = Controller(LfoFreqUnit, LfoFreqUnit.hz_0_02)
    lfo_waveform = Controller(LfoWaveform, LfoWaveform.sin)