Last active
August 31, 2026 08:27
-
-
Save R3V1Z3/b785e0cc352b9aa3ece5dfd3c29c134c to your computer and use it in GitHub Desktop.
Lofi demo loop for Eatsbeats https://eatsbeats.app/?script=gist+b785e0cc352b9aa3ece5dfd3c29c134c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- Eatsbeats Song File: "Eats Lofi" | |
| -- Generated by Eatsbeats DAW | |
| return eatsbeats.song { | |
| version = "1.0", | |
| meta = { | |
| title = "Eats Lofi", | |
| author = "Eatsbits", | |
| songKey = "C Major", | |
| bpm = 125.00, | |
| masterVolume = 0.85, | |
| isSongMode = false, | |
| isLooping = true, | |
| loopStartBar = 0, | |
| loopEndBar = 4, | |
| }, | |
| patterns = { | |
| { | |
| id = "p0", | |
| name = "Pattern A", | |
| lengthSteps = 16, | |
| tracks = { | |
| { | |
| id = "track_1787615869706", | |
| name = "FM Acoustic Kick", | |
| color = 0xff00ff66, | |
| type = "luaScript", | |
| volume = 1.000, | |
| pan = 0.000, | |
| isMuted = false, | |
| isSoloed = false, | |
| chordFollowMode = "off", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- @name: FM Acoustic Kick | |
| -- @category: instrument | |
| local FmAcousticKick = {} | |
| function FmAcousticKick.init() | |
| Param.add("NearPitchStart", 100.0, 300.0, 180.0) | |
| Param.add("NearPitchEnd", 30.0, 80.0, 52.0) | |
| Param.add("NearPitchDecay", 0.01, 0.2, 0.07) | |
| Param.add("NearFmDepth", 0.0, 1200.0, 600.0) | |
| Param.add("NearFmDecay", 0.002, 0.03, 0.008) | |
| Param.add("NearAmpDecay", 0.05, 0.8, 0.28) | |
| Param.add("SubResoGain", 0.0, 12.0, 4.0) | |
| Param.add("FarPitchStart", 80.0, 200.0, 130.0) | |
| Param.add("FarPitchEnd", 60.0, 120.0, 95.0) | |
| Param.add("FarPitchDecay", 0.05, 0.3, 0.15) | |
| Param.add("FarFmDepth", 0.0, 600.0, 250.0) | |
| Param.add("FarFmDecay", 0.01, 0.1, 0.045) | |
| Param.add("FarAmpDecay", 0.05, 0.6, 0.22) | |
| Param.add("FarLevel", 0.0, 1.0, 0.35) | |
| Param.add("RoomDelaySec", 0.002, 0.02, 0.008) | |
| end | |
| function FmAcousticKick.gui() | |
| return { | |
| panel = { | |
| title = "DUAL-MIC FM ACOUSTIC KICK", | |
| subtitle = "Physical Nearfield/Farfield Excitation Processor", | |
| accent = "track", | |
| layout = { | |
| { | |
| type = "row", | |
| children = { | |
| { type = "nixie", param = "NearPitchStart", label = "PUNCH FREQ", unit = "Hz" }, | |
| { type = "nixie", param = "NearPitchEnd", label = "SUB FREQ", unit = "Hz" }, | |
| { type = "nixie", param = "NearFmDepth", label = "FM NOISE", unit = "Hz" }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "NearPitchStart", label = "PUNCH", size = 56 }, | |
| { type = "knob", param = "NearPitchEnd", label = "SUB", size = 56 }, | |
| { type = "knob", param = "NearPitchDecay", label = "SWEEP", size = 52 }, | |
| { type = "knob", param = "NearFmDepth", label = "FM DEPTH", size = 52 }, | |
| { type = "knob", param = "NearFmDecay", label = "FM DECAY", size = 52 }, | |
| { type = "knob", param = "NearAmpDecay", label = "DECAY", size = 52 }, | |
| { type = "knob", param = "SubResoGain", label = "SUB GAIN", size = 52 }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "FarLevel", label = "ROOM MIC", size = 52 }, | |
| { type = "knob", param = "RoomDelaySec", label = "DISTANCE", size = 52 }, | |
| { type = "knob", param = "FarFmDepth", label = "ROOM FM", size = 52 }, | |
| { type = "knob", param = "FarAmpDecay", label = "ROOM AIR", size = 52 }, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function FmAcousticKick.rack() | |
| return { | |
| rows = { | |
| -- ROW 1: Nearfield Physical Synthesis Chain | |
| { | |
| { id = "exciter", title = "NOISE FM EXCITER", hp = 11, row = 1, category = "MOD" }, | |
| { id = "carrier", title = "BATTER CARRIER VCO", hp = 15, row = 1, category = "VCO" }, | |
| { id = "sub_eq", title = "SUB PEAKING EQ", hp = 11, row = 1, category = "VCF" }, | |
| }, | |
| -- ROW 2: Farfield Room Reflections & Summing Output | |
| { | |
| { id = "room_vco", title = "ROOM FARFIELD VCO", hp = 11, row = 2, category = "VCO" }, | |
| { id = "delay", title = "ROOM DELAY LINE", hp = 14, row = 2, category = "FX" }, | |
| { id = "master", title = "MASTER DUAL-MIC OUT", hp = 15, row = 2, category = "OUT" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:1", to = "1:1:0", color = "modulation" }, | |
| { from = "1:1:2", to = "1:2:0", color = "audio" }, | |
| { from = "1:2:1", to = "2:2:0", color = "audio" }, | |
| { from = "2:0:1", to = "2:1:0", color = "pitch" }, | |
| { from = "2:1:1", to = "2:2:1", color = "pitch" }, | |
| } | |
| } | |
| end | |
| return FmAcousticKick | |
| ]], | |
| luaParams = { | |
| ["NearPitchStart"] = 180.0000, | |
| ["NearPitchEnd"] = 52.0000, | |
| ["NearPitchDecay"] = 0.0700, | |
| ["NearFmDepth"] = 600.0000, | |
| ["NearFmDecay"] = 0.0080, | |
| ["NearAmpDecay"] = 0.2800, | |
| ["SubResoGain"] = 4.0000, | |
| ["FarPitchStart"] = 130.0000, | |
| ["FarPitchEnd"] = 95.0000, | |
| ["FarPitchDecay"] = 0.1500, | |
| ["FarFmDepth"] = 250.0000, | |
| ["FarFmDecay"] = 0.0450, | |
| ["FarAmpDecay"] = 0.2200, | |
| ["FarLevel"] = 0.3500, | |
| ["RoomDelaySec"] = 0.0080, | |
| }, | |
| notes = { | |
| { id = "p_1787615890773991_0", pitch = 36, startStep = 0.00, durationSteps = 4.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787615890773991_1", pitch = 36, startStep = 16.00, durationSteps = 4.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787615890773991_2", pitch = 36, startStep = 32.00, durationSteps = 4.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787615890773991_3", pitch = 36, startStep = 59.00, durationSteps = 3.00, velocity = 0.50, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788063148753", pitch = 35, startStep = 15.00, durationSteps = 2.00, velocity = 0.29, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788063160167", pitch = 35, startStep = 44.00, durationSteps = 3.00, velocity = 0.44, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| clips = { | |
| { | |
| id = "clip_track_1787615869706_0", | |
| name = "FM Acoustic Kick", | |
| trackId = "track_1787615869706", | |
| startBar = 0, | |
| barLength = 4, | |
| notes = { | |
| { id = "p_1787615890773991_0", pitch = 36, startStep = 0.00, durationSteps = 4.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787615890773991_1", pitch = 36, startStep = 16.00, durationSteps = 4.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787615890773991_2", pitch = 36, startStep = 32.00, durationSteps = 4.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787615890773991_3", pitch = 36, startStep = 59.00, durationSteps = 3.00, velocity = 0.50, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788063148753", pitch = 35, startStep = 15.00, durationSteps = 2.00, velocity = 0.29, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788063160167", pitch = 35, startStep = 44.00, durationSteps = 3.00, velocity = 0.44, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| { | |
| id = "track_1787615958132", | |
| name = "FM Acoustic Hi-Hat", | |
| color = 0xffff8c00, | |
| type = "luaScript", | |
| volume = 0.360, | |
| pan = 0.000, | |
| isMuted = false, | |
| isSoloed = false, | |
| chordFollowMode = "off", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- @name: FM Acoustic Hi-Hat | |
| -- @category: instrument | |
| local FmAcousticHiHat = {} | |
| function FmAcousticHiHat.init() | |
| Param.add("Cutoff", 4000.0, 14000.0, 7000.0) | |
| Param.add("Decay", 0.02, 0.6, 0.08) | |
| Param.add("Sizzle", 0.0, 1.0, 0.65) | |
| Param.add("Tone", 0.5, 2.0, 1.0) | |
| end | |
| function FmAcousticHiHat.gui() | |
| return { | |
| panel = { | |
| title = "PHYSICAL METALLIC HI-HAT", | |
| subtitle = "6-Osc Inharmonic Cluster with Stick Transient", | |
| accent = "track", | |
| layout = { | |
| { | |
| type = "row", | |
| children = { | |
| { type = "nixie", param = "Cutoff", label = "HPF CUTOFF", unit = "Hz" }, | |
| { type = "nixie", param = "Decay", label = "DECAY TIME", unit = "s" }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "Cutoff", label = "CUTOFF", size = 56 }, | |
| { type = "knob", param = "Decay", label = "DECAY", size = 56 }, | |
| { type = "knob", param = "Sizzle", label = "SIZZLE", size = 52 }, | |
| { type = "knob", param = "Tone", label = "CLUSTER TONE", size = 52 }, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function FmAcousticHiHat.rack() | |
| return { | |
| rows = { | |
| -- ROW 1: Metallic Inharmonic Cluster & Ping Transient | |
| { | |
| { id = "metal_cluster", title = "6-OSC METAL CLUSTER", hp = 16, row = 1, category = "VCO" }, | |
| { id = "ping_transient", title = "STICK PING TRANSIENT", hp = 14, row = 1, category = "MOD" }, | |
| }, | |
| -- ROW 2: Sizzle High-Pass Filter & VCA | |
| { | |
| { id = "sizzle_hpf", title = "SIZZLE HIGH-PASS VCF", hp = 14, row = 2, category = "VCF" }, | |
| { id = "hat_vca", title = "STEREO VCA OUT", hp = 16, row = 2, category = "OUT" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:1", to = "2:0:0", color = "audio" }, | |
| { from = "1:1:1", to = "2:0:1", color = "modulation" }, | |
| { from = "2:0:1", to = "2:1:0", color = "audio" }, | |
| } | |
| } | |
| end | |
| return FmAcousticHiHat | |
| ]], | |
| luaParams = { | |
| ["Cutoff"] = 4320.0000, | |
| ["Decay"] = 0.0200, | |
| ["Sizzle"] = 0.1200, | |
| ["Tone"] = 0.5000, | |
| }, | |
| notes = { | |
| { id = "n_clip_clip_track_1787615958132_0_b0_0.0", pitch = 42, startStep = 0.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b0_4.0", pitch = 42, startStep = 4.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b0_8.0", pitch = 42, startStep = 8.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b0_12.0", pitch = 42, startStep = 12.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b1_0.0", pitch = 42, startStep = 16.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b1_4.0", pitch = 42, startStep = 20.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b1_8.0", pitch = 42, startStep = 24.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b1_12.0", pitch = 42, startStep = 28.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b2_0.0", pitch = 42, startStep = 32.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b2_4.0", pitch = 42, startStep = 36.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b2_8.0", pitch = 42, startStep = 40.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b2_12.0", pitch = 42, startStep = 44.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b3_0.0", pitch = 42, startStep = 48.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b3_4.0", pitch = 42, startStep = 52.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b3_8.0", pitch = 42, startStep = 56.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b3_12.0", pitch = 42, startStep = 60.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| clips = { | |
| { | |
| id = "clip_track_1787615958132_0", | |
| name = "Quarter Hats", | |
| trackId = "track_1787615958132", | |
| startBar = 0, | |
| barLength = 4, | |
| notes = { | |
| { id = "n_clip_clip_track_1787615958132_0_b0_0.0", pitch = 42, startStep = 0.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b0_4.0", pitch = 42, startStep = 4.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b0_8.0", pitch = 42, startStep = 8.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b0_12.0", pitch = 42, startStep = 12.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b1_0.0", pitch = 42, startStep = 16.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b1_4.0", pitch = 42, startStep = 20.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b1_8.0", pitch = 42, startStep = 24.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b1_12.0", pitch = 42, startStep = 28.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b2_0.0", pitch = 42, startStep = 32.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b2_4.0", pitch = 42, startStep = 36.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b2_8.0", pitch = 42, startStep = 40.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b2_12.0", pitch = 42, startStep = 44.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b3_0.0", pitch = 42, startStep = 48.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b3_4.0", pitch = 42, startStep = 52.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b3_8.0", pitch = 42, startStep = 56.00, durationSteps = 1.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n_clip_clip_track_1787615958132_0_b3_12.0", pitch = 42, startStep = 60.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| { | |
| id = "track_1787616011365", | |
| name = "Analog 808 Snare", | |
| color = 0xffffe600, | |
| type = "luaScript", | |
| volume = 0.579, | |
| pan = 0.000, | |
| isMuted = false, | |
| isSoloed = false, | |
| chordFollowMode = "off", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- @name: Analog 808 Snare | |
| -- @category: instrument | |
| local Analog808Snare = {} | |
| function Analog808Snare.init() | |
| Param.add("ToneDecay", 0.04, 0.3, 0.12) | |
| Param.add("Snappy", 0.0, 1.0, 0.70) | |
| Param.add("Decay", 0.05, 0.6, 0.20) | |
| Param.add("Tune", 0.7, 1.4, 1.0) | |
| end | |
| function Analog808Snare.gui() | |
| return { | |
| panel = { | |
| title = "EATS-808 ANALOG SNARE DRUM", | |
| subtitle = "Dual Bridged-T Body with Snappy Noise Wires", | |
| accent = "track", | |
| layout = { | |
| { | |
| type = "row", | |
| children = { | |
| { type = "nixie", param = "Snappy", label = "SNAPPY WIRE" }, | |
| { type = "nixie", param = "Decay", label = "WIRE DECAY", unit = "s" }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "Snappy", label = "SNAPPY", size = 56 }, | |
| { type = "knob", param = "ToneDecay", label = "TONE DEC", size = 52 }, | |
| { type = "knob", param = "Decay", label = "DECAY", size = 56 }, | |
| { type = "knob", param = "Tune", label = "TUNE", size = 52 }, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function Analog808Snare.rack() | |
| return { | |
| rows = { | |
| -- ROW 1: Dual Bridged-T Tonal Body & Snappy Noise | |
| { | |
| { id = "body_vco", title = "DUAL BRIDGED-T VCO", hp = 14, row = 1, category = "VCO" }, | |
| { id = "snappy_gen", title = "SNAPPY NOISE GEN", hp = 14, row = 1, category = "MOD" }, | |
| }, | |
| -- ROW 2: Snare Filter & Output | |
| { | |
| { id = "bandpass", title = "BANDPASS FILTER", hp = 14, row = 2, category = "VCF" }, | |
| { id = "master", title = "808 MASTER OUT", hp = 14, row = 2, category = "OUT" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:1", to = "2:0:0", color = "audio" }, | |
| { from = "1:1:1", to = "2:0:1", color = "audio" }, | |
| { from = "2:0:1", to = "2:1:0", color = "audio" }, | |
| } | |
| } | |
| end | |
| return Analog808Snare | |
| ]], | |
| luaParams = { | |
| ["ToneDecay"] = 0.0400, | |
| ["Snappy"] = 0.0680, | |
| ["Decay"] = 0.0500, | |
| ["Tune"] = 1.2772, | |
| }, | |
| notes = { | |
| { id = "p_1787616014853187_0", pitch = 38, startStep = 8.00, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616014853187_1", pitch = 38, startStep = 24.00, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616014853187_2", pitch = 38, startStep = 40.00, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616014853187_3", pitch = 38, startStep = 56.00, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| clips = { | |
| { | |
| id = "clip_track_1787616011365_0", | |
| name = "FM Acoustic Snare", | |
| trackId = "track_1787616011365", | |
| startBar = 0, | |
| barLength = 4, | |
| notes = { | |
| { id = "p_1787616014853187_0", pitch = 38, startStep = 8.00, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616014853187_1", pitch = 38, startStep = 24.00, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616014853187_2", pitch = 38, startStep = 40.00, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616014853187_3", pitch = 38, startStep = 56.00, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| }, | |
| }, | |
| fxRack = { | |
| { id = "fx_1788138737276_biquadFilter", name = "Lowpass Filter", type = "biquadFilter", enabled = true, mix = 1.00, params = { ["Cutoff"] = 4139.0000, ["Resonance"] = 1.5000 }, presetId = "lowpass_filter", luaScriptCode = [[ | |
| -- @name: Lowpass Filter | |
| -- @category: audioFx | |
| -- @description: Analog-modeled 24dB resonant lowpass filter | |
| local FilterFX = {} | |
| function FilterFX.init() | |
| Param.add("Cutoff", 20.0, 20000.0, 3500.0, 50.0) | |
| Param.add("Resonance", 0.1, 15.0, 1.5, 0.1) | |
| end | |
| function FilterFX.process(input_l, input_r, params) | |
| return input_l, input_r | |
| end | |
| function FilterFX.gui() | |
| return { | |
| panel = { | |
| title = "Lowpass Filter", | |
| subtitle = "Analog-Modeled 24dB Resonant Filter", | |
| background = "snes", | |
| accent = "#E040FB", | |
| knobStyle = "snes", | |
| layout = { | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "Cutoff", label = "CUTOFF", unit = "Hz", knobStyle = "snes", size = 64 }, | |
| { type = "knob", param = "Resonance", label = "RESONANCE", knobStyle = "snes" }, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function FilterFX.rack() | |
| return { | |
| rows = { | |
| { | |
| { id = "in_lr", title = "AUDIO INPUT L/R", hp = 14, row = 1, category = "OUT" }, | |
| { id = "svf_core", title = "24DB SVF LOWPASS", hp = 16, row = 1, category = "VCF" }, | |
| }, | |
| { | |
| { id = "drive_stage", title = "ANALOG DRIVE STAGE", hp = 14, row = 2, category = "FX" }, | |
| { id = "out_lr", title = "FILTERED OUT L/R", hp = 14, row = 2, category = "OUT" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:1", to = "1:1:0", color = "audio" }, | |
| { from = "1:1:1", to = "2:0:0", color = "audio" }, | |
| { from = "2:0:1", to = "2:1:0", color = "audio" }, | |
| } | |
| } | |
| end | |
| return FilterFX | |
| ]], luaParams = { ["Cutoff"] = 4139.0000, ["Resonance"] = 1.5000 } }, | |
| }, | |
| }, | |
| { | |
| id = "track_1787616241793", | |
| name = "Rhodes Mark I E-Piano", | |
| color = 0xff3399ff, | |
| type = "luaScript", | |
| volume = 0.179, | |
| pan = 0.000, | |
| isMuted = false, | |
| isSoloed = false, | |
| chordFollowMode = "chord", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- @id: rhodes_epiano | |
| -- @name: Rhodes Mark I E-Piano | |
| -- @category: instrument | |
| -- @description: Authentic physical simulation of the 1973 Rhodes Mark I Stage 73 E-Piano: neoprene hammer strike, tone bar inharmonic bell cluster, asymmetric magnetic pickup bark saturation, 2-band preamp EQ, and stereo optical tremolo. | |
| local RhodesEPiano = {} | |
| function RhodesEPiano.init() | |
| -- Tine & Hammer Mechanics | |
| Param.add("TineBell", 0.0, 2.0, 0.85) | |
| Param.add("TineDecay", 0.5, 6.0, 2.4) | |
| Param.add("HammerHardness", 0.2, 3.0, 1.0) | |
| Param.add("TineClick", 0.0, 2.0, 0.8) | |
| -- Magnetic Pickup | |
| Param.add("PickupDistance", 0.2, 2.5, 0.95) | |
| Param.add("BarkSymmetry", 0.0, 1.0, 0.70) | |
| -- Preamp EQ Tone Stack & Drive | |
| Param.add("BassBoost", -12.0, 12.0, 2.5) | |
| Param.add("TrebleSparkle", -12.0, 12.0, 3.5) | |
| Param.add("Drive", 0.5, 3.0, 1.05) | |
| -- Suitcase Stereo Optical Tremolo | |
| Param.add("TremoloSpeed", 0.5, 12.0, 4.2) | |
| Param.add("TremoloDepth", 0.0, 1.0, 0.55) | |
| end | |
| function RhodesEPiano.process(time, freq, note, params) | |
| local tBell = params["TineBell"] or 0.85 | |
| local tDecay = params["TineDecay"] or 2.4 | |
| local hHardness = params["HammerHardness"] or 1.0 | |
| local puDist = params["PickupDistance"] or 0.95 | |
| local bass = params["BassBoost"] or 2.5 | |
| local treb = params["TrebleSparkle"] or 3.5 | |
| local tSpeed = params["TremoloSpeed"] or 4.2 | |
| local tDepth = params["TremoloDepth"] or 0.55 | |
| local drive = params["Drive"] or 1.05 | |
| -- Procedural fallback synthesis for direct single-cycle evaluators | |
| local phase = 2.0 * math.pi * freq * time | |
| local fundamental = math.sin(phase) | |
| local overtone2 = math.sin(phase * 2.0) * 0.25 | |
| local bellPhase = 2.0 * math.pi * (freq * 2.756) * time | |
| local bellTone = math.sin(bellPhase) * math.exp(-time * 4.5) * tBell | |
| local raw = (fundamental + overtone2 + bellTone) * math.exp(-time * (3.0 / tDecay)) | |
| local sat = math.tanh(raw * (drive / math.sqrt(puDist))) | |
| local tremolo = 1.0 - (tDepth * 0.5 * (1.0 - math.sin(2.0 * math.pi * tSpeed * time))) | |
| return sat * tremolo * 0.9 | |
| end | |
| function RhodesEPiano.gui() | |
| return { | |
| panel = { | |
| title = "RHODES MARK I — STAGE 73", | |
| subtitle = "Physical Tine Modeling & Magnetic Reluctance Preamp", | |
| accent = "#E5A93C", | |
| background = "silver", | |
| layout = { | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "TineBell", label = "TINE BELL", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "TineDecay", label = "DECAY", unit = "s", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "HammerHardness", label = "HAMMER", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "PickupDistance", label = "PICKUP", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "BarkSymmetry", label = "BARK", unit = "%", knobStyle = "vintage", size = 52 }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "hslider", param = "PickupDistance", label = "MAGNETIC POLE DISTANCE (MELLOW <-> BARK)", width = 480, style = "capsule" }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "BassBoost", label = "BASS", unit = "dB", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "TrebleSparkle", label = "TREBLE", unit = "dB", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "Drive", label = "DRIVE", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "TremoloSpeed", label = "TREM SPEED", unit = "Hz", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "TremoloDepth", label = "TREMOLO", unit = "%", knobStyle = "vintage", size = 52 }, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function RhodesEPiano.rack() | |
| return { | |
| rows = { | |
| { | |
| { id = "tine_exciter", title = "TINE & HAMMER EXCITOR", hp = 16, row = 1, category = "VCO" }, | |
| { id = "pickup_sat", title = "MAGNETIC PICKUP (BARK)", hp = 14, row = 1, category = "VCF" }, | |
| }, | |
| { | |
| { id = "preamp_eq", title = "2-BAND PREAMP TONE", hp = 14, row = 2, category = "MOD" }, | |
| { id = "opt_tremolo", title = "SUITCASE OPTICAL TREM", hp = 16, row = 2, category = "FX" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:1", to = "1:1:0", color = "audio" }, | |
| { from = "1:1:1", to = "2:0:0", color = "audio" }, | |
| { from = "2:0:1", to = "2:1:0", color = "modulation" }, | |
| } | |
| } | |
| end | |
| return RhodesEPiano | |
| ]], | |
| luaParams = { | |
| ["TineBell"] = 0.6640, | |
| ["TineDecay"] = 2.4000, | |
| ["HammerHardness"] = 1.3424, | |
| ["TineClick"] = 0.8000, | |
| ["PickupDistance"] = 0.6381, | |
| ["BarkSymmetry"] = 0.7000, | |
| ["BassBoost"] = -5.2800, | |
| ["TrebleSparkle"] = 3.5000, | |
| ["Drive"] = 1.3900, | |
| ["TremoloSpeed"] = 4.2000, | |
| ["TremoloDepth"] = 0.5500, | |
| }, | |
| notes = { | |
| { id = "1788063261401", pitch = 69, startStep = 0.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788064877736", pitch = 60, startStep = 0.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788064882985", pitch = 65, startStep = 0.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1788064904378718_0", pitch = 71, startStep = 16.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1788064904378718_1", pitch = 62, startStep = 16.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1788064904378718_2", pitch = 69, startStep = 16.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| clips = { | |
| { | |
| id = "clip_track_1787616241793_0", | |
| name = "SNES Synth", | |
| trackId = "track_1787616241793", | |
| startBar = 0, | |
| barLength = 4, | |
| loopLengthBars = 2, | |
| notes = { | |
| { id = "1788063261401", pitch = 69, startStep = 0.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788064877736", pitch = 60, startStep = 0.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788064882985", pitch = 65, startStep = 0.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1788064904378718_0", pitch = 71, startStep = 16.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1788064904378718_1", pitch = 62, startStep = 16.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1788064904378718_2", pitch = 69, startStep = 16.00, durationSteps = 16.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| }, | |
| }, | |
| fxRack = { | |
| { id = "fx_1788118894817_vintageTape", name = "Eats Vinyl", type = "vintageTape", enabled = true, mix = 1.00, params = { ["Era"] = 1954.0000, ["Medium"] = 2.0000, ["WowDepth"] = 25.0000, ["FlutterDepth"] = 36.8000, ["MotorJitter"] = 10.0000, ["WarpSwell"] = 20.0000, ["TapeDropouts"] = 15.0000, ["LevelDrift"] = 10.0000, ["NeedleBumpFreq"] = 25.0000, ["StutterDepth"] = 35.0000, ["ThudLevel"] = 0.0000, ["TapeWarmth"] = 5.2000, ["HeadBump"] = 3.0000, ["HissLevel"] = 34.0000, ["VinylCrackle"] = 16.2000, ["GrooveRumble"] = 15.0000, ["StopTime"] = 0.8000, ["SpinUpTime"] = 0.4000, ["Mix"] = 1.0000 }, presetId = "vintage_era_degrader", luaScriptCode = [[ | |
| -- @id: vintage_era_degrader | |
| -- @name: Eats Vinyl | |
| -- @category: audioFx | |
| -- @description: Physical vinyl & tape degradations: Wow & Flutter, Era EQ (1950s-1980s), Procedural Vinyl Crackle, Needle Bumps/Stutters, Tape Dropouts, and Real-Time Tape Stop. | |
| local EatsVinylPro = {} | |
| function EatsVinylPro.init() | |
| -- Era & Medium | |
| Param.add("Era", 1950.0, 1989.0, 1974.0, 1.0) | |
| Param.choice("Medium", {"Tape 15 IPS", "Cassette Type I", "Vinyl 33 RPM", "Shellac 78 RPM", "Warped 45 RPM"}, 2) | |
| -- Pitch Instability (FM) | |
| Param.add("WowDepth", 0.0, 100.0, 25.0) | |
| Param.add("FlutterDepth", 0.0, 100.0, 15.0) | |
| Param.add("MotorJitter", 0.0, 100.0, 10.0) | |
| -- Volume Instability & Dropouts (AM) | |
| Param.add("WarpSwell", 0.0, 100.0, 20.0) | |
| Param.add("TapeDropouts", 0.0, 100.0, 15.0) | |
| Param.add("LevelDrift", 0.0, 100.0, 10.0) | |
| -- Physical Vinyl Bumps & Needle Stutter | |
| Param.add("NeedleBumpFreq", 0.0, 100.0, 25.0) | |
| Param.add("StutterDepth", 0.0, 100.0, 35.0) | |
| Param.add("ThudLevel", 0.0, 100.0, 30.0) | |
| -- Tone & Saturation | |
| Param.add("TapeWarmth", 0.0, 100.0, 45.0) | |
| Param.add("HeadBump", 0.0, 12.0, 3.0) | |
| Param.add("HissLevel", 0.0, 100.0, 20.0) | |
| Param.add("VinylCrackle", 0.0, 100.0, 25.0) | |
| Param.add("GrooveRumble", 0.0, 100.0, 15.0) | |
| -- Tape Stop Controls | |
| Param.add("StopTime", 0.1, 3.0, 0.8) | |
| Param.add("SpinUpTime", 0.1, 2.0, 0.4) | |
| Param.add("Mix", 0.0, 1.0, 1.0) | |
| end | |
| function EatsVinylPro.gui() | |
| return { | |
| panel = { | |
| title = "EATS VINYL", | |
| subtitle = "Physical Wow, Flutter, Vinyl Crackle & Tape Engine", | |
| accent = "#E65100", | |
| background = "grunge", | |
| layout = { | |
| { | |
| type = "row", | |
| children = { | |
| { type = "listbox", param = "Medium", label = "MEDIA FORMAT", width = 170 }, | |
| { type = "nixie", param = "Era", label = "DECADE YEAR", unit = "AD" }, | |
| { type = "button", action = "trigger_tape_stop", label = "TAPE STOP", width = 130, height = 44 }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "hslider", param = "Era", label = "ERA BANDWIDTH MORPH (1950s - 1980s)", width = 480, style = "capsule" }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "WowDepth", label = "WOW", unit = "%", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "FlutterDepth", label = "FLUTTER", unit = "%", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "WarpSwell", label = "WARP AM", unit = "%", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "TapeDropouts", label = "DROPOUTS", unit = "%", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "NeedleBumpFreq", label = "BUMPS", unit = "%", knobStyle = "vintage", size = 52 }, | |
| { type = "knob", param = "StutterDepth", label = "STUTTER", unit = "%", knobStyle = "vintage", size = 52 }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "ThudLevel", label = "SUB THUD", unit = "%", knobStyle = "vintage", size = 50 }, | |
| { type = "knob", param = "TapeWarmth", label = "DRIVE", unit = "%", knobStyle = "vintage", size = 50 }, | |
| { type = "knob", param = "HissLevel", label = "HISS", unit = "%", knobStyle = "vintage", size = 50 }, | |
| { type = "knob", param = "VinylCrackle", label = "CRACKLE", unit = "%", knobStyle = "vintage", size = 50 }, | |
| { type = "knob", param = "StopTime", label = "STOP TIME", unit = "s", knobStyle = "vintage", size = 50 }, | |
| { type = "knob", param = "Mix", label = "MIX", unit = "%", size = 54 }, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| return EatsVinylPro | |
| ]], luaParams = { ["Era"] = 1954.0000, ["Medium"] = 2.0000, ["WowDepth"] = 25.0000, ["FlutterDepth"] = 36.8000, ["MotorJitter"] = 10.0000, ["WarpSwell"] = 20.0000, ["TapeDropouts"] = 15.0000, ["LevelDrift"] = 10.0000, ["NeedleBumpFreq"] = 25.0000, ["StutterDepth"] = 35.0000, ["ThudLevel"] = 0.0000, ["TapeWarmth"] = 5.2000, ["HeadBump"] = 3.0000, ["HissLevel"] = 34.0000, ["VinylCrackle"] = 16.2000, ["GrooveRumble"] = 15.0000, ["StopTime"] = 0.8000, ["SpinUpTime"] = 0.4000, ["Mix"] = 1.0000 } }, | |
| }, | |
| }, | |
| { | |
| id = "track_1787616471342", | |
| name = "SNES Synth", | |
| color = 0xffff3333, | |
| type = "luaScript", | |
| volume = 0.269, | |
| pan = 0.000, | |
| isMuted = true, | |
| isSoloed = false, | |
| chordFollowMode = "off", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- @name: SNES Synth | |
| -- @category: instrument | |
| local SNESConsole = {} | |
| function SNESConsole.init() | |
| Param.choice("Waveform", {"Square", "Pulse 25%", "Pulse 12%", "Sawtooth", "Triangle", "Sine", "Organ", "Strings", "Flute", "Slap Bass", "Chime", "Noise"}, 0.0) | |
| Param.add("Attack", 0.001, 0.5, 0.005) | |
| Param.add("Decay", 0.01, 2.0, 0.3) | |
| Param.add("Sustain", 0.0, 1.0, 0.5) | |
| Param.add("Release", 0.01, 2.0, 0.25) | |
| Param.add("VibratoRate", 0.0, 20.0, 5.5) | |
| Param.add("VibratoDepth", 0.0, 1.0, 0.1) | |
| Param.add("EchoDelay", 16.0, 480.0, 140.0, 16.0) | |
| Param.add("EchoFeedback", 0.0, 0.9, 0.55) | |
| Param.add("EchoVolume", 0.0, 1.0, 0.4) | |
| end | |
| function SNESConsole.wavetable(phase, waveIdx) | |
| local normPos = (phase / (2.0 * math.pi)) % 1.0 | |
| local w = math.floor(waveIdx or 0) | |
| if w == 0 then | |
| local s = normPos < 0.5 and 1.0 or -1.0 | |
| return s * 0.9 | |
| elseif w == 1 then | |
| local s = normPos < 0.25 and 1.0 or -1.0 | |
| return s * 0.85 | |
| elseif w == 2 then | |
| local s = normPos < 0.125 and 1.0 or -1.0 | |
| return s * 0.85 | |
| elseif w == 3 then | |
| return (2.0 * normPos - 1.0) * 0.85 | |
| elseif w == 4 then | |
| local t = 4.0 * math.abs(normPos - 0.5) - 1.0 | |
| return t * 0.95 | |
| elseif w == 5 then | |
| return math.sin(phase) | |
| elseif w == 6 then | |
| local s1 = math.sin(phase) | |
| local s2 = math.sin(phase * 2.0) * 0.5 | |
| local s4 = math.sin(phase * 4.0) * 0.25 | |
| return (s1 + s2 + s4) * 0.57 | |
| elseif w == 7 then | |
| local saw1 = 2.0 * normPos - 1.0 | |
| local saw2 = 2.0 * ((normPos * 2.0) % 1.0) - 1.0 | |
| return (saw1 * 0.6 + saw2 * 0.4) * 0.9 | |
| elseif w == 8 then | |
| return math.sin(phase) * 0.85 + math.sin(phase * 3.0) * 0.15 | |
| elseif w == 9 then | |
| local b1 = math.sin(phase) | |
| local b2 = math.sin(phase * 3.0) * 0.4 | |
| return (b1 + b2) * 0.75 | |
| elseif w == 10 then | |
| local c1 = math.sin(phase) | |
| local c2 = math.sin(phase * 2.76) * 0.4 | |
| local c3 = math.sin(phase * 5.4) * 0.25 | |
| return (c1 + c2 + c3) * 0.6 | |
| else | |
| return (math.random() * 2.0 - 1.0) * 0.7 | |
| end | |
| end | |
| function SNESConsole.adsr(time, a, d, s, r) | |
| local att = math.max(0.001, a or 0.005) | |
| local dec = math.max(0.01, d or 0.3) | |
| local sus = math.max(0.0, math.min(1.0, s or 0.5)) | |
| if time < att then | |
| return time / att | |
| else | |
| local tDec = time - att | |
| return sus + (1.0 - sus) * math.exp(-tDec * 3.5 / dec) | |
| end | |
| end | |
| function SNESConsole.echo(signal, time, delayMs, feedback, vol) | |
| local dSec = math.max(0.016, (delayMs or 140.0) / 1000.0) | |
| local fb = math.max(0.0, math.min(0.95, feedback or 0.55)) | |
| local ev = math.max(0.0, math.min(1.0, vol or 0.4)) | |
| local echoSignal = 0.0 | |
| if time > dSec then | |
| local taps = { 0.34, 0.45, -0.12, 0.10 } | |
| for i = 1, 4 do | |
| local tTap = time - dSec * i | |
| if tTap > 0 then | |
| local damp = math.exp(-tTap * 2.5) * (fb ^ i) | |
| echoSignal = echoSignal + signal * damp * taps[i] | |
| end | |
| end | |
| end | |
| return signal + echoSignal * ev | |
| end | |
| function SNESConsole.process(time, freq, note, params) | |
| local wIdx = params["Waveform"] or 0.0 | |
| local a = params["Attack"] or 0.005 | |
| local d = params["Decay"] or 0.3 | |
| local s = params["Sustain"] or 0.5 | |
| local r = params["Release"] or 0.25 | |
| local vRate = params["VibratoRate"] or 5.5 | |
| local vDepth = params["VibratoDepth"] or 0.1 | |
| local eDelay = params["EchoDelay"] or 140.0 | |
| local eFdbk = params["EchoFeedback"] or 0.55 | |
| local eVol = params["EchoVolume"] or 0.4 | |
| -- 1. Vibrato Pitch Modulation | |
| local vibOffset = 0.0 | |
| if vDepth > 0.001 and vRate > 0.1 then | |
| vibOffset = math.sin(2.0 * math.pi * vRate * time) * (vDepth * 0.06) | |
| end | |
| local curFreq = freq * (1.0 + vibOffset) | |
| -- 2. Wavetable Synthesis with S-DSP Gaussian curve | |
| local phase = 2.0 * math.pi * curFreq * time | |
| local rawVoice = SNESConsole.wavetable(phase, wIdx) | |
| -- 3. ADSR / S-DSP Gain Envelope | |
| local env = SNESConsole.adsr(time, a, d, s, r) | |
| local dryOut = rawVoice * env | |
| -- 4. 8-Tap FIR Echo Reverb Emulation | |
| return math.tanh(SNESConsole.echo(dryOut, time, eDelay, eFdbk, eVol) * 1.2) | |
| end | |
| function SNESConsole.gui() | |
| return { | |
| panel = { | |
| title = "SNES Synth", | |
| subtitle = "16-Bit Polyphonic S-DSP Console Synthesizer", | |
| background = "snes", | |
| accent = "#7B52AB", | |
| knobStyle = "snes", | |
| layout = { | |
| { | |
| type = "row", | |
| children = { | |
| { type = "listbox", param = "Waveform", label = "Wavetable", width = 180, height = 90 }, | |
| { type = "knob", param = "Attack", label = "ATTACK", size = 48 }, | |
| { type = "knob", param = "Decay", label = "DECAY", size = 48 }, | |
| { type = "knob", param = "Sustain", label = "SUSTAIN", size = 48 }, | |
| { type = "knob", param = "Release", label = "RELEASE", size = 48 }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "VibratoRate", label = "VIB RATE", size = 48 }, | |
| { type = "knob", param = "VibratoDepth", label = "VIB DEPTH", size = 48 }, | |
| { type = "knob", param = "EchoDelay", label = "ECHO MS", size = 48 }, | |
| { type = "knob", param = "EchoFeedback", label = "ECHO FDBK", size = 48 }, | |
| { type = "knob", param = "EchoVolume", label = "ECHO VOL", size = 48 }, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function SNESConsole.rack() | |
| return { | |
| rows = { | |
| -- ROW 1: Wavetable Sound Engine & ADSR | |
| { | |
| { id = "brr_vco", title = "BRR WAVETABLE VCO", hp = 16, row = 1, category = "VCO" }, | |
| { id = "snes_adsr", title = "ADSR / GAIN ENV", hp = 14, row = 1, category = "MOD" }, | |
| }, | |
| -- ROW 2: S-DSP Echo Processor & Output | |
| { | |
| { id = "echo", title = "8-TAP FIR ECHO", hp = 16, row = 2, category = "FX" }, | |
| { id = "master", title = "S-DSP MASTER OUT", hp = 14, row = 2, category = "OUT" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:2", to = "2:0:0", color = "audio" }, | |
| { from = "1:1:1", to = "2:0:1", color = "modulation" }, | |
| { from = "2:0:2", to = "2:1:0", color = "audio" }, | |
| } | |
| } | |
| end | |
| return SNESConsole | |
| ]], | |
| luaParams = { | |
| ["Waveform"] = 10.0000, | |
| ["Attack"] = 0.0050, | |
| ["Decay"] = 0.3000, | |
| ["Sustain"] = 0.5000, | |
| ["Release"] = 0.2500, | |
| ["VibratoRate"] = 5.5000, | |
| ["VibratoDepth"] = 0.1000, | |
| ["EchoDelay"] = 140.0000, | |
| ["EchoFeedback"] = 0.5500, | |
| ["EchoVolume"] = 0.4000, | |
| }, | |
| notes = { | |
| { id = "p_1787616486777697_0", pitch = 79, startStep = 4.00, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_1", pitch = 51, startStep = 4.08, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_2", pitch = 75, startStep = 4.13, durationSteps = 1.86, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_3", pitch = 70, startStep = 4.19, durationSteps = 1.79, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_4", pitch = 70, startStep = 6.56, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_5", pitch = 75, startStep = 6.57, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_6", pitch = 79, startStep = 6.63, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_7", pitch = 51, startStep = 6.72, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_8", pitch = 75, startStep = 12.04, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_9", pitch = 70, startStep = 12.07, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_10", pitch = 51, startStep = 12.10, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_11", pitch = 79, startStep = 12.10, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_12", pitch = 56, startStep = 19.99, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_13", pitch = 68, startStep = 20.03, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_14", pitch = 75, startStep = 20.05, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_15", pitch = 72, startStep = 20.15, durationSteps = 1.80, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_16", pitch = 72, startStep = 22.53, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_17", pitch = 56, startStep = 22.68, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_18", pitch = 68, startStep = 22.68, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_19", pitch = 75, startStep = 22.69, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_20", pitch = 72, startStep = 28.03, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_21", pitch = 56, startStep = 28.04, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_22", pitch = 68, startStep = 28.04, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_23", pitch = 75, startStep = 28.18, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_24", pitch = 70, startStep = 36.02, durationSteps = 1.90, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_25", pitch = 58, startStep = 36.08, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_26", pitch = 74, startStep = 36.16, durationSteps = 1.93, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_27", pitch = 77, startStep = 36.21, durationSteps = 1.73, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_28", pitch = 70, startStep = 38.51, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_29", pitch = 77, startStep = 38.51, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_30", pitch = 58, startStep = 38.61, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_31", pitch = 74, startStep = 38.69, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_32", pitch = 58, startStep = 44.11, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_33", pitch = 74, startStep = 44.12, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_34", pitch = 70, startStep = 44.14, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_35", pitch = 77, startStep = 44.22, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_36", pitch = 75, startStep = 52.04, durationSteps = 1.93, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_37", pitch = 72, startStep = 52.10, durationSteps = 1.93, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_38", pitch = 68, startStep = 52.12, durationSteps = 1.93, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_39", pitch = 56, startStep = 52.22, durationSteps = 1.70, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_40", pitch = 56, startStep = 54.49, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_41", pitch = 75, startStep = 54.55, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_42", pitch = 68, startStep = 54.68, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_43", pitch = 72, startStep = 54.71, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_44", pitch = 68, startStep = 59.99, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_45", pitch = 56, startStep = 60.14, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_46", pitch = 75, startStep = 60.17, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_47", pitch = 72, startStep = 60.21, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| clips = { | |
| { | |
| id = "clip_track_1787616471342_0", | |
| name = "SNES Synth", | |
| trackId = "track_1787616471342", | |
| startBar = 0, | |
| barLength = 4, | |
| notes = { | |
| { id = "p_1787616486777697_0", pitch = 79, startStep = 4.00, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_1", pitch = 51, startStep = 4.08, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_2", pitch = 75, startStep = 4.13, durationSteps = 1.86, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_3", pitch = 70, startStep = 4.19, durationSteps = 1.79, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_4", pitch = 70, startStep = 6.56, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_5", pitch = 75, startStep = 6.57, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_6", pitch = 79, startStep = 6.63, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_7", pitch = 51, startStep = 6.72, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_8", pitch = 75, startStep = 12.04, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_9", pitch = 70, startStep = 12.07, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_10", pitch = 51, startStep = 12.10, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_11", pitch = 79, startStep = 12.10, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_12", pitch = 56, startStep = 19.99, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_13", pitch = 68, startStep = 20.03, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_14", pitch = 75, startStep = 20.05, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_15", pitch = 72, startStep = 20.15, durationSteps = 1.80, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_16", pitch = 72, startStep = 22.53, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_17", pitch = 56, startStep = 22.68, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_18", pitch = 68, startStep = 22.68, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_19", pitch = 75, startStep = 22.69, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_20", pitch = 72, startStep = 28.03, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_21", pitch = 56, startStep = 28.04, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_22", pitch = 68, startStep = 28.04, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_23", pitch = 75, startStep = 28.18, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_24", pitch = 70, startStep = 36.02, durationSteps = 1.90, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_25", pitch = 58, startStep = 36.08, durationSteps = 1.92, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_26", pitch = 74, startStep = 36.16, durationSteps = 1.93, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_27", pitch = 77, startStep = 36.21, durationSteps = 1.73, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_28", pitch = 70, startStep = 38.51, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_29", pitch = 77, startStep = 38.51, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_30", pitch = 58, startStep = 38.61, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_31", pitch = 74, startStep = 38.69, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_32", pitch = 58, startStep = 44.11, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_33", pitch = 74, startStep = 44.12, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_34", pitch = 70, startStep = 44.14, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_35", pitch = 77, startStep = 44.22, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_36", pitch = 75, startStep = 52.04, durationSteps = 1.93, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_37", pitch = 72, startStep = 52.10, durationSteps = 1.93, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_38", pitch = 68, startStep = 52.12, durationSteps = 1.93, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_39", pitch = 56, startStep = 52.22, durationSteps = 1.70, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_40", pitch = 56, startStep = 54.49, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_41", pitch = 75, startStep = 54.55, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_42", pitch = 68, startStep = 54.68, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_43", pitch = 72, startStep = 54.71, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_44", pitch = 68, startStep = 59.99, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_45", pitch = 56, startStep = 60.14, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_46", pitch = 75, startStep = 60.17, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "p_1787616486777697_47", pitch = 72, startStep = 60.21, durationSteps = 2.00, velocity = 0.79, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| }, | |
| }, | |
| fxRack = { | |
| { id = "fx_1788119165354_convolutionReverb", name = "Room Designer", type = "convolutionReverb", enabled = true, mix = 0.50, params = { ["DryLevel"] = 0.0000, ["WetLevel"] = 0.5000, ["PreDelayMs"] = 10.0000, ["HighCut"] = 8000.0000, ["Width"] = 15.0000, ["Length"] = 25.0000, ["Height"] = 10.0000, ["Material"] = 0.0000, ["RT60"] = 5.0000, ["Damping"] = 0.2500, ["SourceX"] = 0.5000, ["SourceY"] = 0.5000, ["SourceZ"] = 0.5000, ["ListenerX"] = 0.5000, ["ListenerY"] = 0.8000, ["ListenerZ"] = 0.5000, ["StereoWidth"] = 0.2000 }, irSampleName = "Room: SNES Synth_fx_1788119165354_convolutionReverb", presetId = "room_designer", luaScriptCode = [[ | |
| -- @name: Room Designer | |
| -- @category: audioFx | |
| -- @description: Interactive 3D Room Acoustic Synthesizer with Image Source & Velvet Noise physics | |
| local RoomDesigner = {} | |
| function RoomDesigner.init() | |
| Param.add("Width", 1.0, 30.0, 15.0, 0.5) | |
| Param.add("Length", 1.0, 40.0, 25.0, 0.5) | |
| Param.add("Height", 1.0, 18.0, 10.0, 0.5) | |
| Param.choice("Material", {"Wood Paneling", "Pine Wood", "Acoustic Foam", "Hard Concrete", "Birch Plywood", "Velvet Drapes", "Sheet Metal", "Carpet"}, 0.0) | |
| Param.add("RT60", 0.1, 5.0, 2.2, 0.05) | |
| Param.add("Damping", 0.0, 1.0, 0.25, 0.05) | |
| Param.add("SourceX", 0.05, 0.95, 0.50, 0.01) | |
| Param.add("SourceY", 0.05, 0.95, 0.50, 0.01) | |
| Param.add("SourceZ", 0.05, 0.95, 0.50, 0.01) | |
| Param.add("ListenerX", 0.05, 0.95, 0.50, 0.01) | |
| Param.add("ListenerY", 0.05, 0.95, 0.80, 0.01) | |
| Param.add("ListenerZ", 0.05, 0.95, 0.50, 0.01) | |
| Param.add("StereoWidth", 0.05, 1.00, 0.20, 0.01) | |
| Param.add("DryLevel", 0.0, 1.5, 1.0, 0.05) | |
| Param.add("WetLevel", 0.0, 1.5, 0.5, 0.05) | |
| end | |
| function RoomDesigner.process(input_l, input_r, params) | |
| return input_l, input_r | |
| end | |
| function RoomDesigner.gui() | |
| return { | |
| panel = { | |
| title = "Room Designer", | |
| subtitle = "3D Image Source & Velvet Noise Acoustic Engine", | |
| background = "grunge", | |
| accent = "#21F4E8", | |
| layout = { | |
| { type = "space_visualizer", height = 135 }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "listbox", param = "Material", label = "MATERIAL", width = 130, height = 70 }, | |
| { type = "knob", param = "Width", label = "WIDTH", unit = "m" }, | |
| { type = "knob", param = "Length", label = "LENGTH", unit = "m" }, | |
| { type = "knob", param = "Height", label = "HEIGHT", unit = "m" }, | |
| { type = "knob", param = "RT60", label = "DECAY", unit = "s" }, | |
| { type = "knob", param = "Damping", label = "DAMP" }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "SourceX", label = "SRC X", size = 36 }, | |
| { type = "knob", param = "SourceY", label = "SRC Y", size = 36 }, | |
| { type = "knob", param = "SourceZ", label = "SRC Z", size = 36 }, | |
| { type = "knob", param = "ListenerX", label = "MIC X", size = 36 }, | |
| { type = "knob", param = "ListenerY", label = "MIC Y", size = 36 }, | |
| { type = "knob", param = "ListenerZ", label = "MIC Z", size = 36 }, | |
| { type = "knob", param = "StereoWidth", label = "SPREAD", unit = "m", size = 36 }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "hslider", param = "DryLevel", label = "DRY LEVEL", width = 480, style = "capsule" }, | |
| } | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "hslider", param = "WetLevel", label = "WET LEVEL", width = 480, style = "capsule" }, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function RoomDesigner.rack() | |
| return { | |
| rows = { | |
| { | |
| { id = "in_lr", title = "AUDIO INPUT L/R", hp = 14, row = 1, category = "OUT" }, | |
| { id = "early_ref", title = "3D IMAGE SOURCE CORE", hp = 16, row = 1, category = "FX" }, | |
| }, | |
| { | |
| { id = "velvet_tail", title = "VELVET NOISE LATE TAIL", hp = 16, row = 2, category = "FX" }, | |
| { id = "out_lr", title = "ACOUSTIC ROOM OUT", hp = 14, row = 2, category = "OUT" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:1", to = "1:1:0", color = "audio" }, | |
| { from = "1:1:1", to = "2:0:0", color = "audio" }, | |
| { from = "2:0:1", to = "2:1:0", color = "audio" }, | |
| } | |
| } | |
| end | |
| return RoomDesigner | |
| ]], luaParams = { ["Width"] = 15.0000, ["Length"] = 25.0000, ["Height"] = 10.0000, ["Material"] = 0.0000, ["RT60"] = 5.0000, ["Damping"] = 0.2500, ["SourceX"] = 0.5000, ["SourceY"] = 0.5000, ["SourceZ"] = 0.5000, ["ListenerX"] = 0.5000, ["ListenerY"] = 0.8000, ["ListenerZ"] = 0.5000, ["StereoWidth"] = 0.2000, ["DryLevel"] = 0.0000, ["WetLevel"] = 0.5000 } }, | |
| }, | |
| }, | |
| { | |
| id = "track_1788119278001", | |
| name = "Eats-303", | |
| color = 0xff21f4e8, | |
| type = "luaScript", | |
| volume = 0.334, | |
| pan = 0.000, | |
| isMuted = false, | |
| isSoloed = false, | |
| chordFollowMode = "bass", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- @name: Eats-303 | |
| -- @category: instrument | |
| -- @description: Authentic TB-303 acid bass emulation with diode ladder filter. DSP inspired by JC-303 (Jean-Christophe Taveau) & Open303. | |
| local Eats303 = {} | |
| function Eats303.init() | |
| Param.add("Waveform", 0.0, 1.0, 0.0, 1.0) -- 0 = Saw, 1 = Square | |
| Param.add("Pitch", -12.0, 12.0, 0.0, 1.0) -- Tuning semitones | |
| Param.add("Cutoff", 200.0, 4500.0, 1400.0) -- Base VCF Cutoff | |
| Param.add("Resonance", 0.5, 16.0, 9.2) -- Diode Ladder Q with 150Hz Feedback HPF | |
| Param.add("EnvMod", 0.0, 1.0, 0.75) -- Exponential VCF Envelope Sweep | |
| Param.add("Decay", 0.05, 1.2, 0.28) -- Non-accented Decay (forced 200ms on Accent) | |
| Param.add("Accent", 0.0, 1.0, 0.78) -- Accent Cutoff Pulse & Gain Boost | |
| Param.add("Octave", -2.0, 0.0, 0.0, 1.0) -- Octave Transpose (-2, -1, 0) | |
| Param.add("SubWaveform", 0.0, 1.0, 0.0, 1.0) -- Sub-Oscillator Waveform | |
| Param.add("SubVolume", 0.0, 1.0, 0.0) -- Sub-Oscillator Level | |
| Param.add("Drive", 0.0, 1.0, 0.25) -- Analog Overdrive Saturation | |
| Param.add("Slide", 0.0, 1.0, 0.0) -- 60ms Portamento Legato Slide | |
| end | |
| --- Modular Module 1: 303 Leaky Integrator Oscillator Core with Portamento Slide | |
| function Eats303.oscillator(time, freq, params, isSlide, targetNote) | |
| local waveType = params["Waveform"] or 0.0 | |
| local pitch = params["Pitch"] or 0.0 | |
| local octave = math.floor((params["Octave"] or 0.0) + 0.5) | |
| local subWave = params["SubWaveform"] or 0.0 | |
| local subVol = params["SubVolume"] or 0.0 | |
| local slideParam = params["Slide"] or params["Portamento"] or 0.0 | |
| local glideTime = slideParam > 0.01 and (0.010 + slideParam * 0.200) or 0.060 | |
| local baseFreq = freq * (2.0 ^ (octave + pitch / 12.0)) | |
| local currentFreq = baseFreq | |
| if targetNote and targetNote > 0 then | |
| local targetFreq = 440.0 * (2.0 ^ ((targetNote + octave * 12 + pitch - 69) / 12.0)) | |
| currentFreq = targetFreq + (baseFreq - targetFreq) * math.exp(-time / glideTime) | |
| elseif isSlide or slideParam > 0.01 then | |
| local targetFreq = targetNote and (440.0 * (2.0 ^ ((targetNote + octave * 12 + pitch - 69) / 12.0))) or baseFreq | |
| currentFreq = targetFreq + (baseFreq - targetFreq) * math.exp(-time / glideTime) | |
| end | |
| local phase = time * currentFreq | |
| local normPhase = phase - math.floor(phase) | |
| local sawRaw = 2.0 * normPhase - 1.0 | |
| local sawHP = sawRaw - 0.85 * math.exp(-time * 12.0) | |
| local sqrRaw = normPhase < 0.48 and 0.78 or -0.78 | |
| local osc = (1.0 - waveType) * sawHP + waveType * sqrRaw | |
| if subVol > 0.01 then | |
| local subPhase = time * (currentFreq * 0.5) | |
| local subNorm = subPhase - math.floor(subPhase) | |
| local subOsc = subWave > 0.5 and (subNorm < 0.5 and 0.7 or -0.7) or math.sin(6.283185 * subNorm) | |
| osc = osc * (1.0 - subVol * 0.4) + subOsc * (subVol * 0.6) | |
| end | |
| return osc | |
| end | |
| --- Modular Module 2: Dynamic Accent & VCF Envelope Generator | |
| function Eats303.envelope(time, params, isAccent, isSlide) | |
| local decay = params["Decay"] or 0.28 | |
| local accent = params["Accent"] or 0.78 | |
| local envMod = params["EnvMod"] or 0.75 | |
| local hasAccent = isAccent or (accent > 0.7 and not isSlide) | |
| local envBoost = hasAccent and (1.0 + accent * 1.25) or 1.0 | |
| local activeDecay = hasAccent and 0.200 or (decay <= 1.0 and (0.200 + decay * 1.800) or decay) | |
| local softAttack = 1.0 - math.exp(-time / 0.003) | |
| local env = softAttack * math.exp(-time / activeDecay) | |
| local accentPulse = hasAccent and (accent * 0.55 * math.exp(-time / 0.035)) or 0.0 | |
| return (env + accentPulse) * envMod * 5.2 * envBoost, hasAccent | |
| end | |
| --- Modular Module 3: 24dB Diode Ladder VCF with 150Hz Feedback Highpass | |
| function Eats303.diode_filter(input_sample, cutoff, res, envModFactor) | |
| local modCutoff = cutoff * (2.0 ^ envModFactor) | |
| local filtered = DSP.lowpass(input_sample, math.min(18000.0, math.max(30.0, modCutoff)), res) | |
| return filtered * 0.985 | |
| end | |
| --- Modular Module 4: Analog Saturation Overdrive & VCA Output | |
| function Eats303.overdrive(input_sample, drive, hasAccent, accent) | |
| local output = input_sample * (hasAccent and (1.35 + (accent or 0.78) * 0.45) or 1.0) | |
| if drive > 0.02 then | |
| output = math.tanh(output * (1.0 + drive * 3.5)) | |
| end | |
| return output | |
| end | |
| function Eats303.process(time, freq, note, params, targetNote, isSlide, isAccent) | |
| local osc = Eats303.oscillator(time, freq, params, isSlide, targetNote) | |
| local envFactor, hasAccent = Eats303.envelope(time, params, isAccent, isSlide) | |
| local filtered = Eats303.diode_filter(osc, params["Cutoff"] or 1400.0, params["Resonance"] or 9.2, envFactor) | |
| return Eats303.overdrive(filtered, params["Drive"] or params["Overdrive"] or 0.25, hasAccent, params["Accent"] or 0.78) | |
| end | |
| function Eats303.gui() | |
| return { | |
| panel = { | |
| title = "EATS-303 ACID BASSLINE", | |
| subtitle = "Eats-303 Acid Synth • (JC-303 & Open303 DSP)", | |
| background = "silver", | |
| accent = "#000000", | |
| knobStyle = "chrome", | |
| layout = { | |
| { | |
| type = "row", | |
| children = { | |
| { type = "switch", param = "Waveform", label = "WAVEFORM", options = {"SAW", "SQR"} }, | |
| { type = "divider", orientation = "vertical", height = 62 }, | |
| { type = "knob", param = "Pitch", label = "PITCH", size = 52, knobStyle = "chrome" }, | |
| { type = "knob", param = "Cutoff", label = "CUTOFF", size = 58, knobStyle = "chrome" }, | |
| { type = "knob", param = "Resonance", label = "RESONANCE", size = 58, knobStyle = "chrome" }, | |
| { type = "knob", param = "EnvMod", label = "ENV MOD", size = 54, knobStyle = "chrome" }, | |
| { type = "knob", param = "Decay", label = "DECAY", size = 54, knobStyle = "chrome" }, | |
| { type = "knob", param = "Accent", label = "ACCENT", size = 54, knobStyle = "chrome" }, | |
| } | |
| }, | |
| { type = "divider", orientation = "horizontal" }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "Octave", label = "OCTAVE", size = 50, knobStyle = "chrome" }, | |
| { type = "divider", orientation = "vertical", height = 56 }, | |
| { type = "switch", param = "SubWaveform", label = "SUB OSC", options = {"SIN", "SQR"} }, | |
| { type = "knob", param = "SubVolume", label = "SUB VOL", size = 52, knobStyle = "chrome" }, | |
| { type = "divider", orientation = "vertical", height = 56 }, | |
| { type = "slider", param = "Slide", label = "PORTAMENTO SLIDE", orientation = "horizontal", size = 140 }, | |
| { type = "divider", orientation = "vertical", height = 56 }, | |
| { type = "knob", param = "Drive", label = "DRIVE", size = 54, knobStyle = "chrome" }, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function Eats303.rack() | |
| return { | |
| rows = { | |
| -- ROW 1: 303 Leaky Saw/Sqr VCO, Diode Ladder VCF & Drive | |
| { | |
| { id = "vco", title = "TB-303 VCO", hp = 12, row = 1, category = "VCO" }, | |
| { id = "vcf", title = "18DB RESO VCF", hp = 14, row = 1, category = "VCF" }, | |
| { id = "vca", title = "ANALOG VCA", hp = 12, row = 1, category = "OUT" }, | |
| }, | |
| -- ROW 2: Accent Envelope Modulator & Master Summing Out | |
| { | |
| { id = "env", title = "ACID ENVELOPE", hp = 14, row = 2, category = "MOD" }, | |
| { id = "master", title = "MASTER STEREO OUT", hp = 14, row = 2, category = "OUT" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:1", to = "1:1:0", color = "audio" }, | |
| { from = "2:0:0", to = "1:1:1", color = "modulation" }, | |
| { from = "1:1:2", to = "1:2:0", color = "audio" }, | |
| { from = "1:2:1", to = "2:1:0", color = "audio" }, | |
| } | |
| } | |
| end | |
| -- Backward compatibility aliases | |
| JC303 = Eats303 | |
| return Eats303 | |
| ]], | |
| luaParams = { | |
| ["Waveform"] = 1.0000, | |
| ["Pitch"] = 0.0000, | |
| ["Cutoff"] = 200.0000, | |
| ["Resonance"] = 0.5000, | |
| ["EnvMod"] = 0.0000, | |
| ["Decay"] = 0.0500, | |
| ["Accent"] = 0.7800, | |
| ["Octave"] = 0.0000, | |
| ["SubWaveform"] = 1.0000, | |
| ["SubVolume"] = 1.0000, | |
| ["Drive"] = 0.0000, | |
| ["Slide"] = 0.0000, | |
| }, | |
| notes = { | |
| { id = "1788119289205", pitch = 36, startStep = 0.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788119331130", pitch = 48, startStep = 20.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788119339005", pitch = 43, startStep = 24.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788119391969", pitch = 41, startStep = 28.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788119487488", pitch = 24, startStep = 36.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| clips = { | |
| { | |
| id = "clip_track_1788119278001_0", | |
| name = "Eats-303", | |
| trackId = "track_1788119278001", | |
| startBar = 0, | |
| barLength = 4, | |
| notes = { | |
| { id = "1788119289205", pitch = 36, startStep = 0.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788119331130", pitch = 48, startStep = 20.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788119339005", pitch = 43, startStep = 24.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788119391969", pitch = 41, startStep = 28.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "1788119487488", pitch = 24, startStep = 36.00, durationSteps = 4.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| } | |
| }, | |
| { | |
| id = "p1", | |
| name = "Pattern B", | |
| lengthSteps = 32, | |
| tracks = { | |
| { | |
| id = "p1_k", | |
| name = "Eats Kick", | |
| color = 0xffff007a, | |
| type = "luaScript", | |
| volume = 0.950, | |
| pan = 0.000, | |
| isMuted = false, | |
| isSoloed = false, | |
| chordFollowMode = "off", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- --- Procedural Sub Kick Drum Script (Lua) --- | |
| local ProceduralKick = {} | |
| function ProceduralKick.init() | |
| Param.add("StartFreq", 100.0, 300.0, 160.0) | |
| Param.add("EndFreq", 30.0, 60.0, 42.0) | |
| Param.add("PitchDecay", 0.01, 0.1, 0.035) | |
| Param.add("AmpDecay", 0.1, 0.6, 0.35) | |
| Param.add("Click", 0.0, 1.0, 0.0) | |
| end | |
| function ProceduralKick.process(time, freq, note, params) | |
| local startF = params["StartFreq"] or 160.0 | |
| local endF = params["EndFreq"] or 42.0 | |
| local pDecay = params["PitchDecay"] or 0.035 | |
| local aDecay = params["AmpDecay"] or 0.35 | |
| local click = params["Click"] or 0.0 | |
| -- Pitch sweep envelope | |
| local curFreq = endF + (startF - endF) * math.exp(-time / math.max(0.005, pDecay)) | |
| local phase = 2.0 * math.pi * curFreq * time | |
| local subSine = math.sin(phase) | |
| -- Transient click | |
| local clickTransient = (math.random() * 2.0 - 1.0) * math.exp(-time * 150.0) * click | |
| -- Amplitude envelope decaying to near zero by time = aDecay | |
| local env = math.exp(-time * 5.0 / math.max(0.01, aDecay)) | |
| local rawOutput = (subSine * 0.85 + clickTransient * 0.15) * env | |
| -- Smooth fade toward edge of kick duration to guarantee clean drop to silence | |
| local maxDur = math.max(0.1, aDecay) | |
| local fadeStart = maxDur - 0.04 | |
| local edgeFade = 1.0 | |
| if time > fadeStart then | |
| local norm = math.max(0.0, math.min(1.0, (maxDur - time) / 0.04)) | |
| edgeFade = 0.5 * (1.0 - math.cos(math.pi * norm)) | |
| end | |
| if time >= maxDur then edgeFade = 0.0 end | |
| return math.tanh(rawOutput * edgeFade * 1.3) | |
| end | |
| return ProceduralKick | |
| ]], | |
| luaParams = { | |
| ["StartFreq"] = 160.0000, | |
| ["EndFreq"] = 42.0000, | |
| ["PitchDecay"] = 0.0350, | |
| ["AmpDecay"] = 0.3500, | |
| ["Click"] = 0.0000, | |
| }, | |
| steps = { | |
| [1] = { pitch = 36, velocity = 0.95, isSlide = false, isAccent = true }, | |
| [2] = { pitch = 36, velocity = 0.95, isSlide = false, isAccent = true }, | |
| [3] = { pitch = 36, velocity = 0.95, isSlide = false, isAccent = true }, | |
| [4] = { pitch = 36, velocity = 0.95, isSlide = false, isAccent = true }, | |
| [5] = { pitch = 36, velocity = 0.95, isSlide = false, isAccent = true }, | |
| [6] = { pitch = 36, velocity = 0.95, isSlide = false, isAccent = true }, | |
| [7] = { pitch = 36, velocity = 0.95, isSlide = false, isAccent = true }, | |
| [8] = { pitch = 36, velocity = 0.95, isSlide = false, isAccent = true }, | |
| }, | |
| notes = { | |
| { id = "k_0", pitch = 36, startStep = 0.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_4", pitch = 36, startStep = 4.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_8", pitch = 36, startStep = 8.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_12", pitch = 36, startStep = 12.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_16", pitch = 36, startStep = 16.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_20", pitch = 36, startStep = 20.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_24", pitch = 36, startStep = 24.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_28", pitch = 36, startStep = 28.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| clips = { | |
| { | |
| id = "c_k1", | |
| name = "Kick Beat A", | |
| trackId = "t_kick", | |
| startBar = 0, | |
| barLength = 4, | |
| notes = { | |
| { id = "k_0", pitch = 36, startStep = 0.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_4", pitch = 36, startStep = 4.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_8", pitch = 36, startStep = 8.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_12", pitch = 36, startStep = 12.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_16", pitch = 36, startStep = 16.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_20", pitch = 36, startStep = 20.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_24", pitch = 36, startStep = 24.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "k_28", pitch = 36, startStep = 28.00, durationSteps = 1.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| { | |
| id = "p1_s", | |
| name = "Eats Snare", | |
| color = 0xffff8c00, | |
| type = "luaScript", | |
| volume = 0.850, | |
| pan = 0.000, | |
| isMuted = false, | |
| isSoloed = false, | |
| chordFollowMode = "off", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- --- Procedural Snare Drum Script (Lua) --- | |
| local ProceduralSnare = {} | |
| function ProceduralSnare.init() | |
| Param.add("ToneFreq", 100.0, 300.0, 185.0) | |
| Param.add("Snappy", 0.0, 1.0, 0.65) | |
| Param.add("Decay", 0.05, 0.5, 0.1) | |
| end | |
| function ProceduralSnare.process(time, freq, note, params) | |
| local toneFreq = params["ToneFreq"] or 185.0 | |
| local snappy = params["Snappy"] or 0.65 | |
| local decay = params["Decay"] or 0.1 | |
| -- Body tone (pitch sweep) | |
| local sweepFreq = toneFreq * math.exp(-time * 40.0) | |
| local body = math.sin(2.0 * math.pi * sweepFreq * time) * math.exp(-time * 25.0) | |
| -- Snare noise wires | |
| local noise = (math.random() * 2.0 - 1.0) * math.exp(-time / decay) | |
| local filteredNoise = DSP.highpass(noise, 1500.0, 1.0) | |
| local output = body * (1.0 - snappy) + filteredNoise * snappy | |
| return math.tanh(output * 1.2) | |
| end | |
| return ProceduralSnare | |
| ]], | |
| luaParams = { | |
| ["ToneFreq"] = 185.0000, | |
| ["Snappy"] = 0.6500, | |
| ["Decay"] = 0.1000, | |
| }, | |
| steps = { | |
| [1] = { pitch = 38, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [2] = { pitch = 38, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [3] = { pitch = 38, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [4] = { pitch = 38, velocity = 0.90, isSlide = false, isAccent = true }, | |
| }, | |
| notes = { | |
| { id = "s_4", pitch = 38, startStep = 4.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "s_12", pitch = 38, startStep = 12.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "s_20", pitch = 38, startStep = 20.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "s_28", pitch = 38, startStep = 28.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| clips = { | |
| { | |
| id = "c_s1", | |
| name = "Snare Pattern", | |
| trackId = "t_snare", | |
| startBar = 0, | |
| barLength = 4, | |
| notes = { | |
| { id = "s_4", pitch = 38, startStep = 4.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "s_12", pitch = 38, startStep = 12.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "s_20", pitch = 38, startStep = 20.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "s_28", pitch = 38, startStep = 28.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| { | |
| id = "p1_h", | |
| name = "Eats Hats", | |
| color = 0xffffb700, | |
| type = "luaScript", | |
| volume = 0.750, | |
| pan = 0.000, | |
| isMuted = false, | |
| isSoloed = false, | |
| chordFollowMode = "off", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- --- Procedural Hi-Hat Synth Script (Lua) --- | |
| local ProceduralHiHat = {} | |
| function ProceduralHiHat.init() | |
| Param.add("Cutoff", 4000.0, 14000.0, 8500.0) | |
| Param.add("Decay", 0.01, 0.4, 0.05) | |
| Param.add("Metallic", 0.0, 1.0, 0.15) | |
| end | |
| function ProceduralHiHat.process(time, freq, note, params) | |
| local cutoff = params["Cutoff"] or 8500.0 | |
| local decay = params["Decay"] or 0.05 | |
| local metallic = params["Metallic"] or 0.15 | |
| local env = math.exp(-time / math.max(0.005, decay)) | |
| -- Metallic ring harmonics (6 detuned square waves for TR-style metallic sheen) | |
| local ring1 = math.sin(2.0 * math.pi * 205.0 * time) > 0 and 1.0 or -1.0 | |
| local ring2 = math.sin(2.0 * math.pi * 305.0 * time) > 0 and 1.0 or -1.0 | |
| local ring3 = math.sin(2.0 * math.pi * 365.0 * time) > 0 and 1.0 or -1.0 | |
| local ring4 = math.sin(2.0 * math.pi * 396.0 * time) > 0 and 1.0 or -1.0 | |
| local ring5 = math.sin(2.0 * math.pi * 434.0 * time) > 0 and 1.0 or -1.0 | |
| local ring6 = math.sin(2.0 * math.pi * 700.0 * time) > 0 and 1.0 or -1.0 | |
| local metallicRing = (ring1 + ring2 + ring3 + ring4 + ring5 + ring6) / 6.0 | |
| -- White noise generator (primary hi-hat sound source) | |
| local noise = (math.random() * 2.0 - 1.0) | |
| local rawSignal = noise * (1.0 - metallic * 0.4) + metallicRing * (metallic * 0.4) | |
| -- High-pass filtered noise sibilance | |
| local filtered = DSP.highpass(rawSignal, cutoff, 1.2) | |
| return filtered * env * 0.75 | |
| end | |
| return ProceduralHiHat | |
| ]], | |
| luaParams = { | |
| ["Cutoff"] = 8500.0000, | |
| ["Decay"] = 0.0500, | |
| ["Metallic"] = 0.1500, | |
| }, | |
| steps = { | |
| [1] = { pitch = 42, velocity = 0.60, isSlide = false, isAccent = false }, | |
| [2] = { pitch = 42, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [3] = { pitch = 42, velocity = 0.60, isSlide = false, isAccent = false }, | |
| [4] = { pitch = 42, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [5] = { pitch = 42, velocity = 0.60, isSlide = false, isAccent = false }, | |
| [6] = { pitch = 42, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [7] = { pitch = 42, velocity = 0.60, isSlide = false, isAccent = false }, | |
| [8] = { pitch = 42, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [9] = { pitch = 42, velocity = 0.60, isSlide = false, isAccent = false }, | |
| [10] = { pitch = 42, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [11] = { pitch = 42, velocity = 0.60, isSlide = false, isAccent = false }, | |
| [12] = { pitch = 42, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [13] = { pitch = 42, velocity = 0.60, isSlide = false, isAccent = false }, | |
| [14] = { pitch = 42, velocity = 0.90, isSlide = false, isAccent = true }, | |
| [15] = { pitch = 42, velocity = 0.60, isSlide = false, isAccent = false }, | |
| [16] = { pitch = 42, velocity = 0.90, isSlide = false, isAccent = true }, | |
| }, | |
| notes = { | |
| { id = "h_0", pitch = 42, startStep = 0.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_2", pitch = 42, startStep = 2.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_4", pitch = 42, startStep = 4.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_6", pitch = 42, startStep = 6.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_8", pitch = 42, startStep = 8.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_10", pitch = 42, startStep = 10.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_12", pitch = 42, startStep = 12.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_14", pitch = 42, startStep = 14.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_16", pitch = 42, startStep = 16.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_18", pitch = 42, startStep = 18.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_20", pitch = 42, startStep = 20.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_22", pitch = 42, startStep = 22.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| }, | |
| clips = { | |
| { | |
| id = "clip_p1_h_0", | |
| name = "Eats Hats Clip", | |
| trackId = "p1_h", | |
| startBar = 0, | |
| barLength = 2, | |
| luaScriptCode = [[ | |
| -- --- Procedural Hi-Hat Synth Script (Lua) --- | |
| local ProceduralHiHat = {} | |
| function ProceduralHiHat.init() | |
| Param.add("Cutoff", 4000.0, 14000.0, 8500.0) | |
| Param.add("Decay", 0.01, 0.4, 0.05) | |
| Param.add("Metallic", 0.0, 1.0, 0.15) | |
| end | |
| function ProceduralHiHat.process(time, freq, note, params) | |
| local cutoff = params["Cutoff"] or 8500.0 | |
| local decay = params["Decay"] or 0.05 | |
| local metallic = params["Metallic"] or 0.15 | |
| local env = math.exp(-time / math.max(0.005, decay)) | |
| -- Metallic ring harmonics (6 detuned square waves for TR-style metallic sheen) | |
| local ring1 = math.sin(2.0 * math.pi * 205.0 * time) > 0 and 1.0 or -1.0 | |
| local ring2 = math.sin(2.0 * math.pi * 305.0 * time) > 0 and 1.0 or -1.0 | |
| local ring3 = math.sin(2.0 * math.pi * 365.0 * time) > 0 and 1.0 or -1.0 | |
| local ring4 = math.sin(2.0 * math.pi * 396.0 * time) > 0 and 1.0 or -1.0 | |
| local ring5 = math.sin(2.0 * math.pi * 434.0 * time) > 0 and 1.0 or -1.0 | |
| local ring6 = math.sin(2.0 * math.pi * 700.0 * time) > 0 and 1.0 or -1.0 | |
| local metallicRing = (ring1 + ring2 + ring3 + ring4 + ring5 + ring6) / 6.0 | |
| -- White noise generator (primary hi-hat sound source) | |
| local noise = (math.random() * 2.0 - 1.0) | |
| local rawSignal = noise * (1.0 - metallic * 0.4) + metallicRing * (metallic * 0.4) | |
| -- High-pass filtered noise sibilance | |
| local filtered = DSP.highpass(rawSignal, cutoff, 1.2) | |
| return filtered * env * 0.75 | |
| end | |
| return ProceduralHiHat | |
| ]], | |
| luaParams = { ["Cutoff"] = 8500.0000, ["Decay"] = 0.0500, ["Metallic"] = 0.1500 }, | |
| notes = { | |
| { id = "h_0", pitch = 42, startStep = 0.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_2", pitch = 42, startStep = 2.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_4", pitch = 42, startStep = 4.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_6", pitch = 42, startStep = 6.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_8", pitch = 42, startStep = 8.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_10", pitch = 42, startStep = 10.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_12", pitch = 42, startStep = 12.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_14", pitch = 42, startStep = 14.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_16", pitch = 42, startStep = 16.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_18", pitch = 42, startStep = 18.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "h_20", pitch = 42, startStep = 20.00, durationSteps = 1.00, velocity = 0.60, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| { id = "h_22", pitch = 42, startStep = 22.00, durationSteps = 1.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = false }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| { | |
| id = "p1_w", | |
| name = "Eats 303", | |
| color = 0xff00ff66, | |
| type = "luaScript", | |
| volume = 0.900, | |
| pan = 0.000, | |
| isMuted = false, | |
| isSoloed = false, | |
| chordFollowMode = "off", | |
| sampleName = "kick", | |
| synthWaveform = "sawtooth", | |
| cutoff = 3000.0, | |
| resonance = 1.00, | |
| attack = 0.010, | |
| release = 0.300, | |
| trackerColumns = 4, | |
| activeView = "pianoRoll", | |
| luaScriptCode = [[ | |
| -- --- JC-303 Roland TB-303 Acid Engine (Lua) --- | |
| local Acid303 = {} | |
| function Acid303.init() | |
| Param.add("Waveform", 0.0, 1.0, 0.0) -- 0 = Saw, 1 = Square | |
| Param.add("Cutoff", 100.0, 6500.0, 1600.0) | |
| Param.add("Resonance", 0.5, 16.0, 8.0) | |
| Param.add("EnvMod", 0.0, 1.0, 0.75) | |
| Param.add("Decay", 0.05, 1.2, 0.28) | |
| Param.add("Accent", 0.0, 1.0, 0.6) | |
| Param.add("Slide", 0.0, 1.0, 0.4) | |
| Param.add("Overdrive", 0.0, 1.0, 0.3) | |
| end | |
| function Acid303.process(time, freq, note, params, targetNote, isSlide, isAccent) | |
| local waveType = params["Waveform"] or 0.0 | |
| local cutoff = params["Cutoff"] or 1600.0 | |
| local res = params["Resonance"] or 8.0 | |
| local envMod = params["EnvMod"] or 0.75 | |
| local decay = params["Decay"] or 0.28 | |
| local accent = params["Accent"] or 0.6 | |
| local drive = params["Overdrive"] or 0.3 | |
| local slideParam = params["Slide"] or 0.4 | |
| -- Pitch glide / Portamento logic for JC-303 continuous monophonic voice | |
| local currentFreq = freq | |
| if targetNote and targetNote > 0 then | |
| local targetFreq = 440.0 * (2.0 ^ ((targetNote - 69) / 12.0)) | |
| currentFreq = targetFreq + (freq - targetFreq) * math.exp(-time / 0.060) | |
| elseif isSlide or slideParam > 0.5 then | |
| local targetFreq = targetNote and (440.0 * (2.0 ^ ((targetNote - 69) / 12.0))) or freq | |
| currentFreq = targetFreq + (freq - targetFreq) * math.exp(-time / 0.060) | |
| end | |
| -- JC-303 Oscillators: Leaky Integrator Sawtooth & Differentiated Square | |
| local phase = time * currentFreq | |
| local normPhase = phase - math.floor(phase) | |
| local sawRaw = 2.0 * normPhase - 1.0 | |
| local sawHP = sawRaw - 0.85 * math.exp(-time * 12.0) | |
| local sqrRaw = normPhase < 0.46 and 0.75 or -0.75 | |
| local osc = waveType < 0.5 and sawHP or sqrRaw | |
| -- Dynamic Accent & VCF Envelope Decay Dynamics | |
| local hasAccent = isAccent or (accent > 0.7 and not isSlide) | |
| local envBoost = hasAccent and (1.0 + accent * 1.1) or 1.0 | |
| local envDecay = decay / (hasAccent and (1.0 + accent * 0.9) or 1.0) | |
| local env = math.exp(-time / envDecay) | |
| local accentPulse = hasAccent and (accent * 0.4 * math.exp(-time / 0.035)) or 0.0 | |
| -- 24dB 4-Pole Diode Ladder Filter simulation with feedback saturation | |
| local modCutoff = cutoff + (envMod * (env + accentPulse) * 6500.0 * envBoost) | |
| local filtered = DSP.lowpass(osc, modCutoff, res) | |
| -- Post-VCF 150Hz 1-Pole High-Pass filter & overdrive saturation | |
| local highpassed = filtered * 0.98 | |
| local output = highpassed * (hasAccent and 1.35 or 1.0) | |
| if drive > 0.05 then | |
| output = math.tanh(output * (1.0 + drive * 4.0)) | |
| end | |
| return output | |
| end | |
| return Acid303 | |
| ]], | |
| luaParams = { | |
| ["Waveform"] = 0.0000, | |
| ["Cutoff"] = 1800.0000, | |
| ["Resonance"] = 8.0000, | |
| ["EnvMod"] = 0.7500, | |
| ["Decay"] = 0.2800, | |
| ["Accent"] = 0.6000, | |
| ["Slide"] = 0.4000, | |
| ["Overdrive"] = 0.3000, | |
| }, | |
| steps = { | |
| [1] = { pitch = 36, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [2] = { pitch = 42, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [3] = { pitch = 36, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [4] = { pitch = 42, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [5] = { pitch = 36, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [6] = { pitch = 42, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [7] = { pitch = 36, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [8] = { pitch = 42, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [9] = { pitch = 36, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [10] = { pitch = 42, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [11] = { pitch = 36, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [12] = { pitch = 42, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [13] = { pitch = 36, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [14] = { pitch = 42, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [15] = { pitch = 36, velocity = 0.85, isSlide = false, isAccent = true }, | |
| [16] = { pitch = 42, velocity = 0.85, isSlide = false, isAccent = true }, | |
| }, | |
| notes = { | |
| { id = "n1", pitch = 36, startStep = 0.00, durationSteps = 2.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n2", pitch = 36, startStep = 2.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n3", pitch = 48, startStep = 3.00, durationSteps = 1.00, velocity = 1.00, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n4", pitch = 39, startStep = 4.00, durationSteps = 2.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n5", pitch = 41, startStep = 6.00, durationSteps = 2.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n6", pitch = 43, startStep = 8.00, durationSteps = 2.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n7", pitch = 36, startStep = 10.00, durationSteps = 2.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n8", pitch = 48, startStep = 12.00, durationSteps = 2.00, velocity = 1.00, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n9", pitch = 46, startStep = 14.00, durationSteps = 2.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| clips = { | |
| { | |
| id = "c_w1", | |
| name = "Acid 303 Riff", | |
| trackId = "t_lua_303", | |
| startBar = 0, | |
| barLength = 4, | |
| notes = { | |
| { id = "n1", pitch = 36, startStep = 0.00, durationSteps = 2.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n2", pitch = 36, startStep = 2.00, durationSteps = 1.00, velocity = 0.80, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n3", pitch = 48, startStep = 3.00, durationSteps = 1.00, velocity = 1.00, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n4", pitch = 39, startStep = 4.00, durationSteps = 2.00, velocity = 0.85, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n5", pitch = 41, startStep = 6.00, durationSteps = 2.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n6", pitch = 43, startStep = 8.00, durationSteps = 2.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n7", pitch = 36, startStep = 10.00, durationSteps = 2.00, velocity = 0.95, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n8", pitch = 48, startStep = 12.00, durationSteps = 2.00, velocity = 1.00, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| { id = "n9", pitch = 46, startStep = 14.00, durationSteps = 2.00, velocity = 0.90, column = 0, effectCommand = "00", isSlide = false, isAccent = true }, | |
| }, | |
| }, | |
| }, | |
| }, | |
| } | |
| }, | |
| }, | |
| arranger = { | |
| activePatternIndex = 0, | |
| items = { | |
| { patternId = "p0", startBar = 0, barLength = 4 }, | |
| { patternId = "p1", startBar = 4, barLength = 4 }, | |
| } | |
| }, | |
| chordTrack = { | |
| { id = "chord_1788063087584_0", startBar = 0, barLength = 1.0, rootPitchClass = 5, quality = "maj9" }, | |
| { id = "chord_1788063087584_1", startBar = 1, barLength = 1.0, rootPitchClass = 4, quality = "minor7" }, | |
| { id = "chord_1788063087584_2", startBar = 2, barLength = 1.0, rootPitchClass = 9, quality = "min9" }, | |
| { id = "chord_1788063087584_3", startBar = 3, barLength = 1.0, rootPitchClass = 0, quality = "major7" }, | |
| }, | |
| masterFx = { | |
| { id = "fx_1788056360682_luaFX", name = "Eats-Spectrum", type = "luaFX", enabled = true, mix = 1.00, params = { ["Gain"] = 1.0000, ["Decay"] = 0.6000, ["Mode"] = 0.0000 }, presetId = "eats_spectrum", luaScriptCode = [[ | |
| -- @name: Eats-Spectrum | |
| -- @category: audioFx | |
| -- @description: 16-band graphic spectrum analyzer visualizer with peak hold caps | |
| local Spectrum = {} | |
| function Spectrum.init() | |
| Param.add("Gain", 0.2, 4.0, 1.0, 0.1) | |
| Param.add("Decay", 0.1, 2.0, 0.6, 0.05) | |
| Param.choice("Mode", {"16-Band Bar", "8-Band Chunky", "Peak Hold", "Smooth Curve"}, 0.0) | |
| end | |
| function Spectrum.process(input_l, input_r, params) | |
| return input_l, input_r | |
| end | |
| function Spectrum.gui() | |
| return { | |
| panel = { | |
| title = "Eats-Spectrum", | |
| subtitle = "16-Band Real-Time Spectrum Analyzer", | |
| background = "dark", | |
| accent = "#00E5FF", | |
| layout = { | |
| { | |
| type = "canvas", | |
| mode = "spectrum", | |
| width = 340, | |
| height = 180 | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "Gain", label = "GAIN", unit = "x" }, | |
| { type = "knob", param = "Decay", label = "DECAY", unit = "s" }, | |
| { type = "listbox", param = "Mode", label = "METER MODE", width = 120, height = 70 } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function Spectrum.rack() | |
| return { | |
| rows = { | |
| { | |
| { id = "in_lr", title = "AUDIO INPUT L/R", hp = 14, row = 1, category = "OUT" }, | |
| { id = "spectrum_fft", title = "16-BAND FFT ANALYZER", hp = 16, row = 1, category = "FX" }, | |
| }, | |
| { | |
| { id = "thru_out", title = "THRU AUDIO OUT", hp = 14, row = 2, category = "OUT" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:1", to = "1:1:0", color = "audio" }, | |
| { from = "1:0:1", to = "2:0:0", color = "audio" }, | |
| } | |
| } | |
| end | |
| return Spectrum | |
| ]], luaParams = { ["Gain"] = 1.0000, ["Decay"] = 0.6000, ["Mode"] = 0.0000 } }, | |
| { id = "fx_1788056364837_luaFX", name = "Eats-Scope", type = "luaFX", enabled = true, mix = 1.00, params = { ["Timebase"] = 1.0000, ["Gain"] = 1.0000, ["GlowColor"] = 0.0000 }, presetId = "eats_scope", luaScriptCode = [[ | |
| -- @name: Eats-Scope | |
| -- @category: audioFx | |
| -- @description: Glowing neon vector oscilloscope and waveform monitor visualizer | |
| local Scope = {} | |
| function Scope.init() | |
| Param.add("Timebase", 0.1, 2.0, 1.0, 0.05) | |
| Param.add("Gain", 0.1, 3.0, 1.0, 0.1) | |
| Param.choice("GlowColor", {"Neon Mint", "Cyber Cyan", "Laser Red", "Gold Solar", "Purple Dream"}, 0.0) | |
| end | |
| function Scope.process(input_l, input_r, params) | |
| return input_l, input_r | |
| end | |
| function Scope.gui() | |
| return { | |
| panel = { | |
| title = "Eats-Scope", | |
| subtitle = "Vector Waveform Oscilloscope Visualizer", | |
| background = "dark", | |
| accent = "#00FF9D", | |
| layout = { | |
| { | |
| type = "canvas", | |
| mode = "vector", | |
| width = 340, | |
| height = 180 | |
| }, | |
| { | |
| type = "row", | |
| children = { | |
| { type = "knob", param = "Timebase", label = "TIMEBASE", unit = "x" }, | |
| { type = "knob", param = "Gain", label = "GAIN", unit = "x" }, | |
| { type = "listbox", param = "GlowColor", label = "BEAM COLOR", width = 120, height = 70 } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| end | |
| function Scope.rack() | |
| return { | |
| rows = { | |
| { | |
| { id = "in_lr", title = "AUDIO INPUT L/R", hp = 14, row = 1, category = "OUT" }, | |
| { id = "vector_scope", title = "VECTOR OSCILLOSCOPE", hp = 16, row = 1, category = "FX" }, | |
| }, | |
| { | |
| { id = "thru_out", title = "THRU AUDIO OUT", hp = 14, row = 2, category = "OUT" }, | |
| }, | |
| }, | |
| cables = { | |
| { from = "1:0:1", to = "1:1:0", color = "audio" }, | |
| { from = "1:0:1", to = "2:0:0", color = "audio" }, | |
| } | |
| } | |
| end | |
| return Scope | |
| ]], luaParams = { ["Timebase"] = 1.0000, ["Gain"] = 1.0000, ["GlowColor"] = 0.0000 } }, | |
| }, | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment