Advertisement
Guest User

Gooey :P

a guest
May 3rd, 2025
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Sure! I'll message you it in a sec, I am making cup noodle atm :P
  2.  
  3. EDIT: I can't message u :(
  4.  
  5. Lol it's ok, I think I can paste it here, here you go :)
  6.  
  7.    MIDIClient.init;
  8.    MIDIIn.connectAll;
  9.    
  10.    // BECAUSE YOU KEEP COMPLAINING WHEN I UNPLUG MY HEADPHONES
  11.    Server.default.options.numInputBusChannels = 0;
  12.    
  13.    s.waitForBoot {
  14.    
  15.        var win, rootDropdown, scaleDropdown, notes, scaleNames, minOct, maxOct, synthTypeDropdown, relKnob, relKnobValue, atkKnob, atkKnobValue, highNoteKnob, highVolKnobValue, lowNoteKnob, lowVolKnobValue, highPanKnob, highPanValue, lowPanKnob, lowPanValue, scaleSnappingButton, recordButton;
  16.    
  17.    var font, fontbold, fontboldlarge, maincolor, titlecolor, pink;
  18.    
  19.        // Initial Settings
  20.        ~rootNote = 0;  // C
  21.        ~scale = Scale.major;
  22.        ~minOctave = 4;
  23.        ~maxOctave = 6;
  24.    ~lowNoteVol = 0.05;
  25.        ~highNoteVol = 0.05;
  26.    ~attack = 0.0;
  27.        ~release = 3.0;
  28.    ~lowNotePan = 0;
  29.        ~highNotePan = 0;
  30.    ~isScaleSnappingEnabled = true;
  31.    
  32.        // Scale Snapping and Octave Clamping
  33.    ~snapToScale = { |midiNote|
  34.            if (~isScaleSnappingEnabled, {
  35.                var baseNote, snapped, octave, minNote, maxNote;
  36.    
  37.                // Snap to scale
  38.                octave = midiNote.div(12);
  39.                baseNote = midiNote % 12;
  40.                snapped = ~scale.degrees.collect { |deg| (octave * 12 + deg + (~rootNote % 12)) };
  41.                snapped = snapped ++ snapped.collect { |n| n + 12 }; // add octave above
  42.    
  43.                snapped = snapped.sort({ |a, b| (a - midiNote).abs < (b - midiNote).abs }).first;
  44.    
  45.                minNote = ~minOctave * 12;
  46.                maxNote = (~maxOctave + 1) * 12 - 1;
  47.    
  48.                while { snapped < minNote } {
  49.                    snapped = snapped + 12;
  50.                };
  51.                while { snapped > maxNote } {
  52.                    snapped = snapped - 12;
  53.                };
  54.    
  55.                snapped;
  56.            }, {
  57.                midiNote;
  58.            });
  59.           };
  60.    
  61.    ~volumeForNote = { |note|
  62.    var minNote = ~minOctave * 12;
  63.    var maxNote = ((~maxOctave + 1) * 12) - 1;
  64.    
  65.    var normalized = (note - minNote) / (maxNote - minNote);
  66.    normalized = normalized.clip(0, 1);
  67.    
  68.    ~lowNoteVol + (normalized * (~highNoteVol - ~lowNoteVol));
  69.    };
  70.    
  71.    ~panForNote = { |note|
  72.    var minNote = ~minOctave * 12;
  73.    var maxNote = ((~maxOctave + 1) * 12) - 1;
  74.    
  75.    var normalized = (note - minNote) / (maxNote - minNote);
  76.    normalized = normalized.clip(0, 1);
  77.    
  78.    ~lowNotePan + (normalized * (~highNotePan - ~lowNotePan));
  79.    };
  80.    
  81.        // Recording
  82.        ~recordingPath = nil;
  83.    ~isRecording = false;
  84.    
  85.        // Output folder on Desktop
  86.        ~recordingFolder = Platform.userHomeDir +/+ "Desktop/Supercollider/Recs";
  87.        File.mkdir(~recordingFolder);
  88.    
  89.    ~makeTimestampedPath = {
  90.    var timestamp = Date.localtime.stamp;
  91.    ~recordingFolder +/+ ("recording_" ++ timestamp ++ ".wav");
  92.    };
  93.    
  94.    ~stopRecording = {
  95.    if (~isRecording) {
  96.    "Stopping recording".postln;
  97.    s.stopRecording;
  98.    };
  99.    };
  100.    
  101.    // Synth
  102.    
  103.    SynthDef(\simpleSynth, {
  104.    |freq=440, amp=0.2, dur=1, atk=0.01, rel=0.3, out=0, waveType=0, pan=0|
  105.    var env = EnvGen.kr(Env.perc(atk, rel), doneAction: 2);
  106.    var sig;
  107.    
  108.    sig = Select.ar(waveType, [
  109.    SinOsc.ar(freq),
  110.    Saw.ar(freq),
  111.    Pulse.ar(freq),
  112.    LFTri.ar(freq),
  113.    WhiteNoise.ar,
  114.    PinkNoise.ar
  115.    ]) * amp * env;
  116.    
  117.    Out.ar(out, Pan2.ar(sig, pan));
  118.    }).add;
  119.    
  120.        s.sync;
  121.    
  122.        // MIDI source debugging
  123.        MIDIClient.sources.do({ |src, i|
  124.            ("[" ++ i ++ "] " ++ src.device).postln;
  125.        });
  126.    
  127.        // MIDI Note Handler
  128.        MIDIdef.noteOn(\fromIanniX, { |vel, note, chan, src|
  129.            var snapped = ~snapToScale.(note);
  130.    var amp = ~volumeForNote.(snapped);
  131.        var pan = ~panForNote.(snapped);
  132.    
  133.    if (~isScaleSnappingEnabled){
  134.    ("MIDI Note: " ++ note ++ " → Snapped: " ++ snapped ++ " | Amp: " ++ amp ++ " | Pan: " ++ pan).postln;
  135.    } {
  136.    ("MIDI Note: " ++ note ++ " | Amp: " ++ amp ++ " | Pan: " ++ pan).postln;
  137.    };
  138.    
  139.    Synth(\simpleSynth, [
  140.    \freq, snapped.midicps,
  141.    \amp, amp,
  142.    \atk, ~attack,
  143.    \rel, ~release,
  144.    \out, 0,
  145.    \waveType, ~currentWaveType,
  146.    \pan, pan
  147.    ]);
  148.    
  149.        });
  150.    
  151.    // GUI (Gooeyyyy)
  152.    win = Window("Control Suite", Rect(100, 100, 380, 720), false);
  153.    win.background = Color.white;
  154.    win.alwaysOnTop = true;
  155.    
  156.    font = Font("Courier New", 12);
  157.        fontbold = Font("Courier New", 12, true);
  158.    fontboldlarge = Font("Courier New", 20, true);
  159.    maincolor = Color(0.4, 0.404, 0.569);
  160.    titlecolor = Color(0.749, 0.392, 0.471);
  161.    pink = Color(0.941, 0.631, 0.694);
  162.    
  163.    y = 10;
  164.    
  165.    // Wavetype Section
  166.    StaticText(win, Rect(10, y, 360, 20))
  167.    .string_("Wave Type")
  168.    .background_(Color(0.922, 0.682, 0.733))
  169.    .stringColor_(Color.white)
  170.    .align_(\center)
  171.    .font_(fontbold);
  172.    
  173.    y = y + 25;
  174.    
  175.    StaticText(win, Rect(10, y, 100, 20))
  176.    .string_("Synth Type:")
  177.    .background_(Color.clear)
  178.    .stringColor_(maincolor)
  179.        .font_(font);
  180.    
  181.    synthTypeDropdown = PopUpMenu(win, Rect(110, y, 150, 20));
  182.    synthTypeDropdown.items = ["Sine", "Saw", "Square", "Triangle", "White Noise", "Pink Noise"];
  183.    synthTypeDropdown.font = font;
  184.    synthTypeDropdown.value = 0;
  185.    synthTypeDropdown.action = {
  186.    ~currentWaveType = synthTypeDropdown.value;
  187.    };
  188.    
  189.    y = y + 40;
  190.    
  191.    // Scale Section
  192.    StaticText(win, Rect(10, y, 360, 20))
  193.    .string_("Scale")
  194.    .background_(Color(0.682, 0.808, 0.922))
  195.    .stringColor_(Color.white)
  196.    .align_(\center)
  197.    .font_(fontbold);
  198.    
  199.        // Scale Snap Toggle
  200.    scaleSnappingButton = Button(win, Rect(320, y, 50, 20));
  201.    scaleSnappingButton.states = [["Off", maincolor, Color.white], ["On", Color.white, Color(0.682, 0.808, 0.922)]];
  202.    scaleSnappingButton.value = ~isScaleSnappingEnabled.binaryValue;
  203.    scaleSnappingButton.font = fontbold;
  204.    scaleSnappingButton.action = {
  205.    ~isScaleSnappingEnabled = ~isScaleSnappingEnabled.not;
  206.    scaleSnappingButton.value = ~isScaleSnappingEnabled.binaryValue;
  207.    };
  208.    
  209.    y = y + 25;
  210.    
  211.    StaticText(win, Rect(10, y, 100, 20))
  212.    .string_("Root Note:")
  213.    .background_(Color.clear)
  214.    .stringColor_(maincolor)
  215.    .font_(font);
  216.    
  217.    rootDropdown = PopUpMenu(win, Rect(110, y, 150, 20));
  218.    rootDropdown.items = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
  219.    rootDropdown.value = 0;
  220.    rootDropdown.font = font;
  221.    rootDropdown.action = { ~rootNote = rootDropdown.value; };
  222.    
  223.    y = y + 30;
  224.    
  225.    StaticText(win, Rect(10, y, 100, 20))
  226.    .string_("Scale:")
  227.    .background_(Color.clear)
  228.    .stringColor_(maincolor)
  229.    .font_(font);
  230.    
  231.    scaleDropdown = PopUpMenu(win, Rect(110, y, 150, 20));
  232.    scaleDropdown.items = Scale.names.asArray;
  233.    scaleDropdown.value = scaleDropdown.items.indexOf("major");
  234.    scaleDropdown.action = {
  235.    ~scale = Scale.at(scaleDropdown.items[scaleDropdown.value]);
  236.    };
  237.    scaleDropdown.font = font;
  238.    
  239.    y = y + 40;
  240.    
  241.    // Octave Clamp Section
  242.    StaticText(win, Rect(10, y, 360, 20))
  243.    .string_("Octave Clamp")
  244.    .background_(Color(0.69, 0.682, 0.922))
  245.    .stringColor_(Color.white)
  246.    .align_(\center)
  247.    .font_(fontbold);
  248.    
  249.    y = y + 25;
  250.    
  251.    StaticText(win, Rect(10, y, 100, 20))
  252.    .string_("Min Octave:")
  253.    .background_(Color.clear)
  254.    .stringColor_(maincolor)
  255.    .font_(font);
  256.    minOct = NumberBox(win, Rect(110, y, 50, 20))
  257.    .value_(~minOctave)
  258.    .font_(font)
  259.    .action_({ |nb|
  260.    ~minOctave = nb.value.round.clip(0, 9);
  261.    if (~minOctave > ~maxOctave) {
  262.    ~minOctave = ~maxOctave; nb.value = ~minOctave;
  263.    };
  264.    });
  265.    
  266.    StaticText(win, Rect(180, y, 100, 20))
  267.    .string_("Max Octave:")
  268.    .background_(Color.clear)
  269.    .stringColor_(maincolor)
  270.    .font_(font);
  271.    maxOct = NumberBox(win, Rect(280, y, 50, 20))
  272.    .value_(~maxOctave)
  273.    .font_(font)
  274.    .action_({ |nb|
  275.    ~maxOctave = nb.value.round.clip(0, 9);
  276.    if (~maxOctave < ~minOctave) {
  277.    ~maxOctave = ~minOctave; nb.value = ~maxOctave;
  278.    };
  279.    });
  280.    
  281.    y = y + 40;
  282.    
  283.    // Linear Volume Control Section
  284.    StaticText(win, Rect(10, y, 360, 20))
  285.    .string_("Linear Volume Control")
  286.    .background_(Color(0.631, 0.89, 0.812))
  287.    .stringColor_(Color.white)
  288.    .align_(\center)
  289.    .font_(fontbold);
  290.    
  291.    y = y + 25;
  292.    
  293.    // Low Note Volume
  294.    StaticText(win, Rect(40, y, 120, 20))
  295.    .string_("Lowest Note Vol:")
  296.    .font_(font)
  297.    .background_(Color.clear)
  298.    .stringColor_(maincolor);
  299.    lowNoteKnob = Knob(win, Rect(80, y + 20, 40, 40))
  300.    .value_(0.25)
  301.    .font_(font)
  302.    .action_({ |knob|
  303.    ~lowNoteVol = knob.value * 0.2;
  304.        lowVolKnobValue.value = ~lowNoteVol;
  305.    });
  306.    lowVolKnobValue = NumberBox(win, Rect(75, y + 65, 50, 20))
  307.    .value_(~lowNoteVol)
  308.    .enabled_(false)
  309.    .font_(font);
  310.    
  311.    // High Note Volume
  312.    StaticText(win, Rect(200, y, 140, 20))
  313.    .string_("Highest Note Vol:")
  314.    .background_(Color.clear)
  315.    .font_(font)
  316.    .stringColor_(maincolor);
  317.    highNoteKnob = Knob(win, Rect(240, y + 20, 40, 40))
  318.    .value_(0.25)
  319.    .font_(font)
  320.    .action_({ |knob|
  321.    ~highNoteVol = knob.value * 0.2;
  322.    highVolKnobValue.value = ~highNoteVol;
  323.    });
  324.    highVolKnobValue = NumberBox(win, Rect(235, y + 65, 50, 20))
  325.    .value_(~highNoteVol)
  326.    .font_(font)
  327.    .enabled_(false);
  328.    
  329.    y = y + 100;
  330.    
  331.    // Envelope Section
  332.    StaticText(win, Rect(10, y, 360, 20))
  333.    .string_("Envelope")
  334.    .background_(Color(0.949, 0.831, 0.596))
  335.    .stringColor_(Color.white)
  336.    .align_(\center)
  337.    .font_(fontbold);
  338.    
  339.    y = y + 25;
  340.    
  341.    // Attack
  342.    StaticText(win, Rect(75, y, 100, 20))
  343.    .string_("Attack:")
  344.    .font_(font)
  345.    .background_(Color.clear)
  346.    .stringColor_(maincolor);
  347.    atkKnob = Knob(win, Rect(80, y + 20, 40, 40))
  348.    .value_(~attack)
  349.    .font_(font)
  350.    .action_({ |knob|
  351.    ~attack = knob.value.clip(0,1);
  352.    atkKnobValue.value = ~attack;
  353.    });
  354.    atkKnobValue = NumberBox(win, Rect(75, y + 65, 50, 20))
  355.    .value_(~attack)
  356.    .font_(font)
  357.    .enabled_(false);
  358.    
  359.    // Release
  360.    StaticText(win, Rect(230, y, 100, 20))
  361.    .string_("Release:")
  362.    .font_(font)
  363.    .background_(Color.clear)
  364.    .stringColor_(maincolor);
  365.    relKnob = Knob(win, Rect(240, y + 20, 40, 40))
  366.    .value_(0.6)
  367.    .font_(font)
  368.    .action_({ |knob|
  369.    ~release = knob.value * 5;
  370.    relKnobValue.value = ~release;
  371.    });
  372.    relKnobValue = NumberBox(win, Rect(235, y + 65, 50, 20))
  373.    .value_(~release)
  374.    .font_(font)
  375.    .enabled_(false);
  376.    
  377.       y = y + 108;
  378.    
  379.        // Pan Control Section
  380.        StaticText(win, Rect(10, y, 360, 20))
  381.    .string_("Linear Panning Control")
  382.    .background_(Color(0.643, 0.706, 0.871))
  383.    .stringColor_(Color.white)
  384.    .align_(\center)
  385.    .font_(fontbold);
  386.    
  387.         y = y + 25;
  388.    
  389.        // Low Note Pan
  390.         StaticText(win, Rect(40, y, 120, 20))
  391.    .string_("Lowest Note Pan:")
  392.    .font_(font)
  393.    .background_(Color.clear)
  394.    .stringColor_(maincolor);
  395.         lowPanKnob = Knob(win, Rect(80, y + 20, 40, 40))
  396.    .value_(0.5)
  397.    .action_({ |knob|
  398.    ~lowNotePan = (knob.value * 2) - 1;
  399.    lowPanValue.value = ~lowNotePan;
  400.    });
  401.         lowPanValue = NumberBox(win, Rect(75, y + 65, 50, 20))
  402.    .value_(~lowNotePan)
  403.    .enabled_(false)
  404.    .font_(font);
  405.    
  406.        // High Note Pan
  407.        StaticText(win, Rect(200, y, 140, 20))
  408.    .string_("Highest Note Pan:")
  409.    .background_(Color.clear)
  410.    .font_(font)
  411.    .stringColor_(maincolor);
  412.         highPanKnob = Knob(win, Rect(240, y + 20, 40, 40))
  413.    .value_(0.5)
  414.    .action_({ |knob|
  415.    ~highNotePan = (knob.value * 2) - 1;
  416.    highPanValue.value = ~highNotePan;
  417.    });
  418.        highPanValue = NumberBox(win, Rect(235, y + 65, 50, 20))
  419.    .value_(~highNotePan)
  420.    .font_(font)
  421.    .enabled_(false);
  422.    
  423.    y = y + 108;
  424.    
  425.    // Recording Button Section
  426.    StaticText(win, Rect(10, y, 360, 30))
  427.    .string_("Recording Control")
  428.    .background_(Color.clear)
  429.    .stringColor_(titlecolor)
  430.    .align_(\top, \center)
  431.    .font_(fontboldlarge);
  432.    
  433.    y = y + 28;
  434.    
  435.    recordButton = Button(win, Rect(140, y, 100, 40));
  436.    recordButton.states = [["REC", maincolor, Color.white], ["STOP", Color.white, pink]];
  437.    recordButton.font = fontbold;
  438.    recordButton.action = {
  439.            if (~isRecording.not) {
  440.                ~recordingPath = ~makeTimestampedPath.();
  441.                ("Starting recording to: " ++ ~recordingPath).postln;
  442.    
  443.                s.record(
  444.                    path: ~recordingPath,
  445.                    headerFormat: "wav",
  446.                    sampleFormat: "int16"
  447.                );
  448.    
  449.    ~isRecording = true;
  450.            } {
  451.    ~stopRecording.();
  452.    ~isRecording = false;
  453.    };
  454.    };
  455.    
  456.    //Knob Colors
  457.        lowNoteKnob.color = [Color.white, Color(0.639, 0.651, 0.89), Color.white, Color(0.639, 0.651, 0.89)];
  458.        highNoteKnob.color = [Color.white, Color(0.639, 0.773, 0.89), Color.white, Color(0.639, 0.773, 0.89)];
  459.    atkKnob.color = [Color.white, Color(0.89, 0.643, 0.678), Color.white, Color(0.89, 0.643, 0.678)];
  460.    relKnob.color = [Color.white, Color(0.639, 0.89, 0.824), Color.white, Color(0.639, 0.89, 0.824)];
  461.    lowPanKnob.color = [Color.white, Color(0.643, 0.706, 0.871), Color(0.714, 0.643, 0.871), Color(0.643, 0.706, 0.871)];
  462.    highPanKnob.color = [Color.white, Color(0.714, 0.643, 0.871), Color(0.643, 0.706, 0.871), Color(0.643, 0.706, 0.871)];
  463.    
  464.    win.front;
  465.    
  466.        "Setup complete, GUI should appear".postln;
  467.    };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement