• Bug: Wavetable only imports to left channel

    Bug Reports
    3
    0 Votes
    3 Posts
    3 Views
    P

    Update: also happens the other way around, so essentially only one channel gets converted sometimes (left or right)

    Screenshot 2026-06-16 at 16.08.55.png

  • 0 Votes
    2 Posts
    15 Views
    ustkU

    @brucerothwell Yep, I use it everyday (26.5)

  • waveform: draw loop position/crossfade

    General Questions
    2
    0 Votes
    2 Posts
    21 Views
  • Which version of faust works fine for HISE?

    Faust Development
    2
    0 Votes
    2 Posts
    31 Views
    David HealeyD

    @Sawatakashi said in Which version of faust works fine for HISE?:

    it crashed after i loaded a faust scriptnode.

    A blank node or are you copying in a script?

  • Testers Needed for Rhapsody v3

    General Questions
    34
    1 Votes
    34 Posts
    900 Views
    David HealeyD

    @jeffd Yeah I always say the same thing to FL Studio users. Let me know if you get the crashing issue @Bart reported.

  • 0 Votes
    3 Posts
    80 Views
    griffinboyG

    @Phelan-Kane

    Here's a real life example of c++ modslots.

    It's not minimal i'm afraid but it shows it in use.
    If you'd like to see the minimal example, it's just as @ustk said, have a look at this post:
    https://forum.hise.audio/topic/14270/how-do-you-set-up-external-modulation-slots-c

    // ==============================| Griffin Poly EQ Filter |=================================== // // File: Griffin_EQFilter_Poly.h // Node: Griffin_EQFilter_Poly // Package: Griffin DSP Essentials for HISE // Author: Griffinboy // HISE Forum: https://forum.hise.audio/user/griffinboy // Copyright: Copyright (c) 2026 Griffinboy // // Description: // Minimum-phase EQ filter with per-voice state and frame processing. // Designed for sample-accurate modulation in synthesis contexts. // Uses more CPU than the block-rate Griffin_EQFilter. // // Has Mod slots for frequency, Q, and gain. // // License: // GNU General Public License v3.0 or later (GPL-3.0-or-later). // // This file is part of Griffin DSP Essentials for HISE. // // This program is free software: you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A // PARTICULAR PURPOSE. See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along with this // program. If not, see <https://www.gnu.org/licenses/>. // // ================================================================================================ #pragma once #include <algorithm> #include <cmath> #include <JuceHeader.h> #include "src/griffinboy/modules/essentials/eq_filter/eq_filter.h" namespace project { using namespace juce; using namespace hise; using namespace scriptnode; template <int NV> struct Griffin_EQFilter_Poly: public data::filter_node_base { using VoiceState = griffin::modules::essentials::eq_filter::EQFilterFrameProcessor; using PlotModel = griffin::modules::essentials::eq_filter::EQPlotModel; using Defaults = griffin::modules::essentials::eq_filter::EQFilterDefaults; PolyData<VoiceState, NV> voices; PlotModel plotModel; SimpleReadWriteLock topologyLock; double plotSampleRate = 44100.0; SNEX_NODE(Griffin_EQFilter_Poly); struct MetadataClass { SN_NODE_ID("Griffin_EQFilter_Poly"); }; static constexpr bool isModNode() { return false; }; static constexpr bool isPolyphonic() { return NV > 1; }; static constexpr bool hasTail() { return true; }; static constexpr bool isSuspendedOnSilence() { return true; }; static constexpr int getFixChannelAmount() { return 2; }; static constexpr int NumTables = 0; static constexpr int NumSliderPacks = 0; static constexpr int NumAudioFiles = 0; static constexpr int NumFilters = 1; static constexpr int NumDisplayBuffers = 0; void prepare(PrepareSpecs specs) { SimpleReadWriteLock::ScopedWriteLock sl(topologyLock); voices.prepare(specs); for (auto& voice : voices) voice.prepare(specs.sampleRate, specs.blockSize); plotModel.prepare(specs.sampleRate); plotSampleRate = specs.sampleRate > 0.0 ? specs.sampleRate : 44100.0; if (auto fd = dynamic_cast<FilterDataObject*>(this->externalData.obj)) fd->setSampleRate(plotSampleRate); sendCoefficientUpdateMessage(); voiceManager.prepare(specs); voiceManager.setActive(1.0); } void reset() { SimpleReadWriteLock::ScopedWriteLock sl(topologyLock); for (auto& voice : voices) voice.reset(); voiceManager.reset(); } void handleHiseEvent(HiseEvent& e) { voiceManager.handleHiseEvent(e); } template <typename T> void process(T& data) { if (auto sl = SimpleReadWriteLock::ScopedTryReadLock(topologyLock)) { static constexpr int NumChannels = getFixChannelAmount(); auto& fixData = data.template as<ProcessData<NumChannels>>(); auto& voice = voices.get(); auto fd = fixData.toFrameData(); while (fd.next()) voice.processFrame(fd.toSpan()); voiceManager.process(data); } } template <typename T> void processFrame(T& data) { if (auto sl = SimpleReadWriteLock::ScopedTryReadLock(topologyLock)) voices.get().processFrame(data); } int handleModulation(double& value) { ignoreUnused(value); return 0; } double getPlotValue(int getMagnitude, double freqNorm) override { if (getMagnitude == 0) return 0.0; const auto frequency = std::clamp(freqNorm, 0.0, 0.5) * plotSampleRate; return plotModel.getMagnitudeAtFrequency(frequency); } void setExternalData(const ExternalData& data, int index) { data::filter_node_base::setExternalData(data, index); ignoreUnused(index); if (auto fd = dynamic_cast<FilterDataObject*>(data.obj)) fd->setSampleRate(plotSampleRate); sendCoefficientUpdateMessage(); } void createExternalModulationInfo(OpaqueNode::ModulationProperties& info) { modulation::ParameterProperties::ConnectionList list; auto addParameterSlot = [&list](int parameterIndex) { modulation::ConnectionInfo slot; slot.connectedParameterIndex = parameterIndex; slot.modColour = HiseModulationColours::ColourId::FX; slot.connectionMode = modulation::ConnectionMode::Parameter; slot.modulationMode = modulation::ParameterMode::ScaleAdd; list.push_back(slot); }; addParameterSlot(2); addParameterSlot(3); addParameterSlot(4); info.fromConnectionList(list); info.setModulationBlockSize(Defaults::modulationBlockSize); } template <int P> void setParameter(double v) { if constexpr (P == 0) { SimpleReadWriteLock::ScopedWriteLock sl(topologyLock); const auto nextShape = (int)std::round(v); applyToVoices( [nextShape](VoiceState& filter) { filter.setType(nextShape); }); updatePlotFromFirstVoice( [this, nextShape] { plotModel.setType(nextShape); }); } else if constexpr (P == 1) { SimpleReadWriteLock::ScopedWriteLock sl(topologyLock); const auto nextSlope = (int)std::round(v); applyToVoices( [nextSlope](VoiceState& filter) { filter.setSlopeMode(nextSlope); }); updatePlotFromFirstVoice( [this, nextSlope] { plotModel.setSlopeMode(nextSlope); }); } else if constexpr (P == 2) { const auto value = (float)v; applyToVoices( [value](VoiceState& filter) { filter.setFrequencyHz(value); }); updatePlotFromFirstVoice( [this, value] { plotModel.setFrequencyHz(value); }); } else if constexpr (P == 3) { const auto value = (float)v; applyToVoices( [value](VoiceState& filter) { filter.setQ(value); }); updatePlotFromFirstVoice( [this, value] { plotModel.setQ(value); }); } else if constexpr (P == 4) { const auto value = (float)v; applyToVoices( [value](VoiceState& filter) { filter.setGainDb(value); }); updatePlotFromFirstVoice( [this, value] { plotModel.setGainDb(value); }); } } void createParameters(ParameterDataList& data) { { parameter::data p("Shape", { 0.0, 6.0, 1.0 }); StringArray names; addTypeLabels(names); p.setParameterValueNames(names); registerCallback<0>(p); p.setDefaultValue((double)Defaults::type); data.add(std::move(p)); } { parameter::data p("Slope", { 0.0, 3.0, 1.0 }); StringArray names; addSlopeLabels(names); p.setParameterValueNames(names); registerCallback<1>(p); p.setDefaultValue((double)Defaults::slopeMode); data.add(std::move(p)); } { parameter::data p("Frequency", { 20.0, 20000.0, 0.01 }); p.setSkewForCentre(1000.0); p.info.textConverter = parameter::pod::TextValueConverters::Frequency; registerCallback<2>(p); p.setDefaultValue(Defaults::frequencyHz); data.add(std::move(p)); } { parameter::data p("Q", { 0.025, 25.0, 0.001 }); p.setSkewForCentre(0.70710678); registerCallback<3>(p); p.setDefaultValue(Defaults::q); data.add(std::move(p)); } { parameter::data p("Gain", { -30.0, 30.0, 0.01 }); p.info.textConverter = parameter::pod::TextValueConverters::Decibel; registerCallback<4>(p); p.setDefaultValue(Defaults::gainDb); data.add(std::move(p)); } } private: static constexpr int getNumTypes() noexcept { return griffin::modules::essentials::eq_filter::EQFilterDesign::getNumTypes(); } template <typename Function> void applyToVoices(Function&& function) { // PolyData iteration follows HISE's poly callback. // Each active voice receives the parameter update in its own DSP state. for (auto& voice : voices) function(voice); } template <typename Function> void updatePlotFromFirstVoice(Function&& function) { // The plot is shared UI state. The first HISE voice owns graph updates // so voices do not compete for the displayed response. if (! voices.isVoiceRenderingActive() || voices.isFirst()) { function(); sendCoefficientUpdateMessage(); } } static void addTypeLabels(StringArray& names) { names.add("Lowpass"); names.add("Highpass"); names.add("Bandpass"); names.add("Notch"); names.add("Bell"); names.add("Low Shelf"); names.add("High Shelf"); } static void addSlopeLabels(StringArray& names) { names.add("12 dB/oct"); names.add("24 dB/oct"); names.add("48 dB/oct"); names.add("96 dB/oct"); } envelope::silent_killer<NV> voiceManager; }; } // namespace project
  • Animated modulation

    General Questions
    23
    0 Votes
    23 Posts
    353 Views
    ustkU

    @dannytaurus Yeah, keeping the colours tidy in your code is easier in the end. Then you can set the component colours from script when needed and everything updates automatically if you adjust something instead of copy/paste in all components...

    I tend to to everything I can in paint routines, the less components in the tree, the happier I am!
    That being said... In order to reduce CPU load, I still tend to keep fixed drawing (bg, mask, etc...) in separate panels so the LAF function job is only constrained to what is really necessary. I also keep all the math constants externally, unlike the example...

    Other issue with the "multiple panel masking technique" is that when you want to move it, it can be very annoying, unless adding them all in an holder panel, which is one more component... 😬

  • Trading DSP's!

    Scripting
    10
    1 Votes
    10 Posts
    186 Views
    C

    @Chazrox Have got a Glitch FX and a Granular Pitch Delay. Would be interested in the pitch and varispeed!

  • The Legato between samplers

    General Questions
    6
    0 Votes
    6 Posts
    159 Views
    David HealeyD

    @Felix-W Break it down. Make a minimal project with one sampler where notes only trigger during legato transitions. Once you get that working you can start to incorporate it into your project.

  • Get, post API Hise language.

    General Questions
    7
    0 Votes
    7 Posts
    84 Views
    Y

    @David-Healey Ok,

    Is it possible to discuss in private?

  • Stop pruning default values from XML?

    General Questions
    4
    0 Votes
    4 Posts
    128 Views
    David HealeyD

    @dannytaurus said in Stop pruning default values from XML?:

    because I'm setting some values in script that happen to be default values.

    Hmm this might be the source of an issue I was having too, I might try it.

  • One shared Script Voice Start Modulator for many Samplers?

    Scripting
    5
    0 Votes
    5 Posts
    137 Views
    observantsoundO

    @David-Healey Yes the Global Modulator Container worked beautifully for this.
    Thanks to your video I've now also understood the global modulator container better.

    Regarding the body + release in one sampler:
    That's what I've tried first, but it's bugged when using together with loop regions.
    It's what I described in this earlier post you commented on:
    https://forum.hise.audio/topic/14799/loud-click-artifact-when-using-releasestart-with-looping-enabled/14?_=1781354181861

    I haven't gotten around to testing it with 48kHz samples yet.
    But by now I've found enough use cases to split apart the sections into dedicated samplers.

  • 0 Votes
    3 Posts
    54 Views
    dannytaurusD

    @chimaera_09 Make the button show/hide a panel. Use the panel to house all your extra controls.

    const pnlSettings = Content.getComponent("pnlSettings"); const btnSettings = Content.getComponent("btnSettings"); btnSettings.setControlCallback(btnSettingsControl); inline function btnSettingsControl(component, value) { pnlSettings.showControl(value); // button shows/hides the panel }

    You can add a button in the panel to close it too:

    const btnSettingsClose = Content.getComponent("btnSettingsClose"); btnSettingsClose.setControlCallback(btnSettingsCloseControl); inline function btnSettingsCloseControl(component, value) { if (value) { pnlSettings.showControl(false); btnSettings.setValue(0); // sets the 'off' state of the button } }
  • 1 Votes
    1 Posts
    43 Views
    No one has replied
  • 0 Votes
    11 Posts
    211 Views
    ustkU

    Speaking of which...

    https://github.com/christophhart/HISE/pull/984

    I can't believe the math were wrong the whole time
    -> upDecayTime was inverted...

  • Set order of parameters as listed for automation

    General Questions
    25
    0 Votes
    25 Posts
    835 Views
    ustkU

    @dannytaurus Good job detective!
    I agree to the WTF, seems that developing new protocols of all sorts but there's still no agreement whatsoever in the way DAWs handle such a simple task... Shame...

  • 0 Votes
    8 Posts
    175 Views
    ChazroxC

    @dannytaurus said in Anyone doing factory presets only, with no Save button?:

    power-user feature

    It for sure is a power-move and not as intuitive as a user preset.

  • Linux

    General Questions
    9
    0 Votes
    9 Posts
    295 Views
    David HealeyD

    @zachhealy1005 said in Linux:

    so compiling hise on my laptop is in fact impossible.

    If you reduce the number of compile threads to 1 or 2 it might still compile.
    make CONFIG=Release -j 2

  • Logic crashes on startInternalDrag

    Scripting
    22
    0 Votes
    22 Posts
    378 Views
    Oli UllmannO

    @David-Healey
    @ustk
    @HISEnberg
    @ulrik

    I've created my own little drag-and-drop implementation. Any suggestions for improvements?

    HiseSnippet 1697.3ocuXE0aSbDD9tjbsXWPsHwOfE+P3bIXrSbRHJPaRbR.qRBVj.kHDBs4t02sMm205t0IwBgT+o0eR809T6L6dm8cN1zRDTKPw6Nyry2Ly2N6ttSrzikjHisrKe7v9LK6a5bzPgJrUHkKrZuqk8sbFDE0iJD6FSCr1YXeZRBy2x1d9mhpXWZAK8m+7m2gFQEdrwSYY8ZI2i8bdOtZ7rc15W3QQ6S8YGy6kS6la01SJZIijC.3LuScq9TuynArConZy4X8LZRnk8O5rd2UnqsZ2U7Vm0bYFk5e5pqsg+oqzXs0W4QrldT5iVsoWyMrr+l874JY7QJphkXYuvNR+gGEJuPXbvq4I7SiX3fFVGAd1L89xHeLDwYsZExi76jkmRrfUoy3r17lr1cbNf6yGM+3r2OnEPFaQ9Dn8bEg27EfWi7vqdN3MEHYmCRKXfzscNxKl2WMVBhmuyosPwh6Rg5TdnXz0Zt+pjyCeH4EQ76kPvB98D2a2XY+xsjfYBUsdzyX6GCCFsLtqTu9RjkWsd0MKWFrEClAIjWSi4T.7IkiYAjjKn8Ay5YTAW3.THoCUvhRJC08DE4bZLoudBxSHuMyiALUKYu9RALvsh1fFUptTYxT97IrY4qgMqbMroYkpuChxtxX29DtHMfpV9CkK0uVBS0AXFpWJGn3BlqQXmWBoNizCjCRXsnQQmBT+TwGzZBwChgpI3NIrRbQvynBeybUVhX19jT6hPthsDAKJebTNmzV3y8n.iyj3ym2EQ5pBKFx8SO7FqREXUGOpVBvXQShkQtcoQIrIDCAsLgq3RgKvTPxh9+o7kmSOs.RziaLSTXDiHv7Mb4cqnXWpfnuRkpSmgQzocRZduLWDA+gzcfvCgEIqN3FnKTA05Bcn1NJxsP5DKCAn+LyNR3oQPwxHzOldw1Q7.Ay+X.RtpPdBF.s8cqtDIazykdzncjCD9It0g4q3AgVLyuhoZgAPqPl2Yjiowf5WAtdnPiL2fH4ozn2rDw7kSv..onHAjCYw5aR3jGmFg0hXh.UHL08ueUsZeXD+NBAEQoWUvNiAukij4hpbIH0nFFKOU61rB7abgPnn5C+DpexUU+hBp+qbeU3UUJrfROiwCBUnVSnFWjv8YftoIIxO8D.8Kt3nwOFGeevmKt3T2mCeRSqnoCGa5InoCASCy4TdWWiGqVXwhYpAwBB2DDezne5jOnQ98mEXr585jrdAyfxdPKW14.4QSawUg0E0B5AGqLKDwMq2a0xk.DpUulWD26LlOFP20LSLlCagSC5AKVoYs8pTorEbDKoFW3yt7Ec0zc8N7FnherbIMnvSzln+SNn.aYBRcoopEnIXoaUtB8Bx4F6tbywVLblVbRNKFhV.+aF8l.+9.RC.7vxY9xn9TWwrbc7TwCXoQqIb6.mKJi6Yh3sE9D7.Tx1lxFN9kLvsj8NmEOD.sHHWxnGVzeU++eyGf2KzQ4RLETkb2m.zSjgLCg43USmsnS.zrDPWjwTAbdZmkLyeWV+QPTEhRlWmo34BpWyPHAUYyBDGJI9Y3vGwgrOKlpqEJo7LRen4MKccJxsEv8d2b108rS5lIeZhy5.BB1aezFXo3Poh8BgqduKHiLontcmprT.DwhmpX7R0weJCcEC5cJKdI3z1Hf5loHbwwh2F0Y12FM+kk8LGSmSQonsfqdQelXVWg1J8rc3aup8tTEEuBa5bfdPERwQHXuK6b3ADlKzVxYWVxYJYeK6uczEB.XpzRuU10cQliEGtT6MbLWVz5x7uHY33As2BZtBEzzVrf+9dG3Pex3Ir9L7yx48CequZ9YkYEO+N8KpeZNq34yzOeSQ+n2il5Gy90YEOa8aacAd7+nI9i3svc05mBl2CklUjbSmwaMQu3Xm5AyWRWcG66.CB0WhHaDbaudYuD8lNMWdilaTuw5qUOmfkmPx4YaOrm+yI7WdlzyQ.bxv20QeNcZKMn2F3JSGS3aPCTpPpBglQvSsuxqBg2iJ8GDgmAm+Qp3S4SE.8JJ7xP7gdvsZTCy+T+uXub8+JDusSGtxKb5XbtofQnixWCLl9d+a4rW2tLO0X.tfy9u4qyi6sLuZI3.pJlir3CGz6Hf.5w.uKvyIQV6bXWUy35YD7iXBe8f+F9jJrAN1NUXiLgV8ndwx26YNg.+EEtgdF.SB8u9RImCvwjFV5SMxmm6w84u2yq3RcECW95Z3JWWCadcMb0qqgqccMb8qqgO5e2P72eZ6AJYOy1FKqC5rm9HWa68D3CNzrUq+AfuNwBB
  • 0 Votes
    23 Posts
    491 Views
    LindonL

    @David-Healey well done...for now I might stick to my "Load Request File" based appraoch...