• 13 Votes
    11 Posts
    1k Views
    StraticahS

    GUI Kit link has been updated. Knobs start with the off state. Sliders have been adjusted.
    Another free filmstrip kit is coming soon.

  • Free HISE Filmstrips! Analog Knob-Kit 01 by Noisehead

    31
    21 Votes
    31 Posts
    4k Views
    clevername27C

    @orange That's incredible.

  • 0 Votes
    1 Posts
    79 Views
    No one has replied
  • Named Pipe idea

    21
    0 Votes
    21 Posts
    587 Views
    A

    @Christoph-Hart

    This is my entire class. It works great. I have a value change broadcaster for all my controls, and it checks for the condition (key modifiers) before setting a canPush variable for the component.

    If that's true, it simply calls pushValueChange which stores the JSON file. If crosstalk is enabled in an instance, it has a listener timer that checks the appdata folder for new files. I described the properties in the previous post.

    The setting of groupId isn't implemented, but it would likely be an argument of the pushValueChange function.

    That's pretty much the only user facing method needed: sending the data and being able to specify targets (groups).

    If string operations are an issue, you can add a method setInstanceGroupName or something like that that will take in a string or an int, and if it's a string, it'll convert it to an int code. This would be called when the user is doing label edits in the GUI for naming the instance.

    namespace Crosstalk { // Crosstalk system using timers and a local JSON file // Instance ID is randomly generated using system time and randomization // Instances check themselves in by creating a file with their id and stamping it with signin time // They continuously update the file to let everyone know they're still here // After 5 seconds of inactivity, the file gets deleted // =========================================================================================== // System time + random 0-999 int inline function generateInstanceId() { return ((Date.getSystemTimeMs()*1000) + Math.randInt(0, 999)); } reg i = 0; reg obj = 0; reg enabled = true; const var instanceId = generateInstanceId(); const var groupId = ""; const var TIMEOUT_MS = 1600; const var LISTENER_MS = 400; const var CLEANUP_MS = 1000; const var lastExecutedInstruction = {}; // the main directory for crosstalk stuff const var DIR = FileSystem.getFolder(FileSystem.AppData).createDirectory("Sharing"); // =========================================================================================== // Write id and time to a check in file used for checking if instance is online inline function checkIn() { local f = DIR.getChildFile("id_" + instanceId); f.writeObject( { "id": instanceId, "group": groupId, "time": Date.getSystemTimeMs(), }); if (UI.DEBUG_CROSSTALK) Console.print(instanceId + "checking in... || " + Date.getSystemTimeISO8601(true)); return f; } // Get all check-in files from the directory inline function getInstances() { return FileSystem.findFiles(DIR, "id_*", true); } // Get all value changes from the directory inline function getValueChanges() { return FileSystem.findFiles(DIR, "vc_*", true); } // Check write time for each file and clean up inline function cleanUp(fileList) { local time = Date.getSystemTimeMs(); local obj = 0; for (x in fileList) { obj = x.loadAsObject(); if (obj.id != instanceId) // obviosuly this one is active { if (Math.abs(time - obj.time) > TIMEOUT_MS) { x.deleteFileOrDirectory(); if (UI.DEBUG_CROSSTALK) Console.print("Deleted: " + obj.id); } } } } // Push changes for crosstalking // Call this in control callbacks, broadcasters, etc. inline function pushValueChange(componentId, value) { local f = DIR.getChildFile("vc_" + componentId); f.writeObject( { "sentBy": instanceId, "targetGroup": groupId, "time": Date.getSystemTimeMs(), "componentId": componentId, "value": value, "changeId": generateInstanceId(), }); } // Find and evaluate value change files inline function pullAllValueChanges() { local list = FileSystem.findFiles(DIR, "vc_*", true); local obj = {}; local component = 0; for (x in list) { obj = x.loadAsObject(); component = Content.getComponent(obj.componentId); if (obj.sentBy != instanceId && obj.value != component.getValue() && groupId == obj.targetGroup && obj.changeId != lastExecutedInstruction[obj.componentId]) { if (isDefined(Animation.valueChangeAnimators[obj.componentId])) { Animation.startValueChangeAnimator(component, obj.value); } else { component.setValue(obj.value); component.changed(); } lastExecutedInstruction[obj.componentId] = obj.changeId; } } } // =========================================================================================== // create a file with the instance id and sign in time // write it once on startup checkIn(); cleanUp(getInstances()); // clean up old files on launch // =========================================================================================== // Timer that loads the shared data file periodically and executes the crosstalk logic const var listener = Engine.createTimerObject(); listener.setTimerCallback(function() { if (TransportHandler.isOffline == false) { checkIn(); pullAllValueChanges(); } if (UI.DEBUG_CROSSTALK) Console.print(instanceId + ": Listening... || " + Date.getSystemTimeISO8601(true)); }); //listener.startTimer(LISTENER_MS); // Timer that cleans up inactive check-in files const var cleaner = Engine.createTimerObject(); cleaner.setTimerCallback(function() { if (TransportHandler.isOffline == false) { cleanUp(getInstances()); cleanUp(getValueChanges()); } if (UI.DEBUG_CROSSTALK) Console.print(instanceId + ": Cleanup... || " + Date.getSystemTimeISO8601(true)); }); //cleaner.startTimer(CLEANUP_MS); // =========================================================================================== // Transport and Crosstalk interaction inline function setTimersOnTransport(playing) { if (playing) { listener.stopTimer(); cleaner.stopTimer(); } else if (enabled) { listener.startTimer(LISTENER_MS); cleaner.startTimer(CLEANUP_MS); } }; TransportHandler.transportBroadcaster.addListener(TransportHandler.transportHandler, "Start/Stop Crosstalk Timers on Transport", setTimersOnTransport); // =========================================================================================== // Call this when enabling or disabling crosstalk. inline function enableCrosstalk(shouldBeEnabled) { enabled = shouldBeEnabled; if (shouldBeEnabled) { cleanUp(getInstances()); cleanUp(getValueChanges()); checkIn(); listener.startTimer(LISTENER_MS); cleaner.startTimer(CLEANUP_MS); } else { listener.stopTimer(); cleaner.stopTimer(); } } // =========================================================================================== // Store Key Modifiers for Execution Evaluation // Store modifiers with the broadcaster. Attach to component in control helpers. // In the Value Change Broadcaster for Controls, check for key modifier combination before pushing value to crosstalk const var mouseStatus = {}; const var keyModifiers = {}; const var canPush = {}; // Broadcaster definition const var mouseBroadcaster = Engine.createBroadcaster({ "id": "mouseBroadcaster", "args": ["component", "event"], "tags": [], "comment": "Store key modifier status for evaluating crosstalk execution." }); mouseBroadcaster.addListener(keyModifiers, "Store Modifiers", function(component, event) { if ((event.clicked || event.drag) && !event.rightClick && event.altDown && (event.ctrlDown || event.cmdDown)) { mouseStatus[component.get("id")] = true; canPush[component.get("id")] = true; } else if (event.mouseUp) { mouseStatus[component.get("id")] = false; Content.callAfterDelay(100, function[component]() { if (mouseStatus[component.get("id")] == false) canPush[component.get("id")] = false; // because value change gets executed after mouseUp }); } }); inline function attachToKeyModifierBroadcaster(component) { mouseBroadcaster.attachToComponentMouseEvents(component, "Clicks, Hover & Dragging", ""); } // =========================================================================================== }
  • Browsable Snippet: [Clocksynced Arpeggiator]

    7
    7 Votes
    7 Posts
    493 Views
    M_HollowayM

    @ulrik Thanks for this, definitely a pointer in the right direction. I'll have a proper play around with it tomorrow :)

  • search buttons in viewpoart

    8
    0 Votes
    8 Posts
    230 Views
    G

    @d-healey thank you

  • Preset System Questions…

    Solved
    5
    0 Votes
    5 Posts
    239 Views
    clevername27C

    @Christoph-Hart Thank you - and this is fantastic, will save so much time -

    The post callback will be executed asynchronously on the scripting thread after the preset has been loaded and each control callback has been executed (and the module states have been restored and the MIDI learn config has been changed).

  • Restoring State in a DAW

    Solved
    5
    0 Votes
    5 Posts
    194 Views
    clevername27C

    @Christoph-Hart Thank you.

  • Group Project: Reverse Delay

    16
    2 Votes
    16 Posts
    843 Views
    WaterSpoonW

    d7fa58f3-328e-4c60-a6b8-566b7dea2b6f-image.png

    This is the Max Patch level. just a sound for testing and i referenced the buffer to see what was going on.

    2abf5da5-1d87-48b0-ab1d-1b0c6a86fc60-image.png

    this is the Rainbow patch (same as above) - Note the "Loadbang" as this will build the window to the buffer automatically when the plugin is Init.

    c39cf7a0-16de-4d2e-838e-8a0f2e12ca24-image.png

    This is the Gen~ folder. i highlighted the changes mentioned above.

    i believe the no sound issue you are describing is that the effect is technically not on when exported. i did it this way to be able to add all that in HISE. Best Success hope this helps.

  • User Preset Label - DAW Session

    5
    0 Votes
    5 Posts
    216 Views
    pelleP

    @Lindon I've solved, I'll publish the solution tomorrow.
    Thanks for your help

  • Export and Install User Presets

    1
    0 Votes
    1 Posts
    136 Views
    No one has replied
  • Free delay notations time filmstrip!

    1
    3 Votes
    1 Posts
    144 Views
    No one has replied
  • Disappearing Panel with Preset Browser

    Solved
    5
    0 Votes
    5 Posts
    212 Views
    WaterSpoonW

    @d-healey You my friend, are the man!!! This was it!!! Blessings!!!

  • Convolution Reverb embed one IR question.

    Solved
    9
    0 Votes
    9 Posts
    326 Views
    WaterSpoonW

    @d-healey perfect thank you!

  • How should I save my Sampler Presets and how can I access them later?

    28
    1 Votes
    28 Posts
    1k Views
    T

    @d-healey Ok this line was the problem ```
    code_text

    const var Sampler1 = Synth.getChildSynth("Sampler1");
  • Preset Browser "Rename" and "Delete" buttons are missing now.

    Solved
    5
    0 Votes
    5 Posts
    193 Views
    WaterSpoonW

    You are the GOAT and Legend!!! Thank you!!!

  • For You: Soft Saturation in ScriptNode

    1
    5 Votes
    1 Posts
    443 Views
    No one has replied
  • For You: Hard Saturation in ScriptNode

    1
    2 Votes
    1 Posts
    304 Views
    No one has replied
  • Shortcut and NodeScript for Mono Multi-Mic Samples

    1
    1 Votes
    1 Posts
    148 Views
    No one has replied
  • Dynamic Panel Order

    1
    9 Votes
    1 Posts
    195 Views
    No one has replied

13

Online

1.9k

Users

10.7k

Topics

93.2k

Posts