Seems to be a limit on the number of pages? If I move a control to an 8th page, I don't see it.

Posts
-
RE: Please Increase parameter limit on Scriptnode custom nodes!
-
RE: Can I update a parameter on my node from inside the C++
Thanks ! I'll check it out.
-
Can I update a parameter on my node from inside the C++
Custom c++ node. I have loads of parameters. I have one parameter that changes a bunch of internal state variables, and also changes the values of the incoming UI parameters. Is there a way to update the scriptnode UI with the relevant new parameter?
-
RE: I wrote a bbd delay
@griffinboy said in I wrote a bbd delay:
It's not like the analog filters are the best ever
Oh yeah undoubtedly, but I reckon that's part of the magic and charm. I've got a few SVF models kicking around, and a Moog model too, that might be interesting to try too.
-
RE: I wrote a bbd delay
@griffinboy said in I wrote a bbd delay:
That's really comprehensive, more so than mine.
The only thing I noticed missing is possibly the fact that filters change shape in BBD delays depending on the delay time. They kind of warp into a lower order lower filter as time increases.If you take IR measurements from a real device you can recreate matching filters using vector fitting!
I'd love to hear more of your delay though. BBD delay is wonderful.
Interesting, I'll look into that! Right now my filters are biquads, and they do adjust based on what chip I select. I've also plumbed in more parameters this morning now, so I can actually select all my clipping types for each stage from the HISE UI. It is great!!
It runs in true stereo too. So I'm eventually going to add note selection options, and a spread control to offset the delay times by an amount.
-
RE: I wrote a bbd delay
I've tried to be as authentic as I can. The model can sound like a bunch of different styles, depending on the parameters.
This is what can be changed:
- Delay time (ms)
- Mix and Feedback
- Chip count
- Stage count (each chip)
- Input sample+hold
- Bit-depth (additional crunchy stage, optional)
- Feedback tone - lowpass, highpass, and two peak bands
- Compander - on/off, threshold, ratio, knee, time
- Input, feedback, output saturation types - none, hard, soft, asym, sym, tube, tape, exponential, and cubic curves.
- Noise level
- Clock whine level
- BBD Droop (level loss with longer times)
- Transient softener in the feedback path
- Micro blur effect in the feedback path
- Pre/De-emphasis on/off (shelving tilt)
- Chip voicing (MN3005, MN3205, MN3007, MN3207, SAD1024, R5106)
- wow rate and depth
- flutter rate and depth
- clock jitter
-
RE: Please Increase parameter limit on Scriptnode custom nodes!
@Christoph-Hart said in Please Increase parameter limit on Scriptnode custom nodes!:
@Orvillain have you tried the new pagination feature? That allows you to subgroup parameters into pages. It looks like this is just an UI problem and having a node with 100 knobs will look very ugly anyways.
Ahhh yeah, this seems like it will work. I did notice when you create a page, any hidden parameters end up going to it, rather than showing up on the unassigned page. But I can work with that.
-
RE: Please Increase parameter limit on Scriptnode custom nodes!
@Christoph-Hart said in Please Increase parameter limit on Scriptnode custom nodes!:
@Orvillain have you tried the new pagination feature? That allows you to subgroup parameters into pages. It looks like this is just an UI problem and having a node with 100 knobs will look very ugly anyways.
I haven't actually no. Maybe it will fix this issue. I'll check.
-
I wrote a bbd delay
Again, wasn't sure where to put this. But I created my own node.
Modelled analog bucket brigade delay. I'm starting to build up quite a nice collection of delay and reverb utilities now!
-
RE: Please Increase parameter limit on Scriptnode custom nodes!
@Allen said in Please Increase parameter limit on Scriptnode custom nodes!:
I just found out one of my node with about 100 parameters won't update the internal value and ready to increase this limit to 256
So it isn't an issue of there not being the ability to make a node super tall or anything. Actually, I simply don't know why HISE is not showing any more than 18 parameters on a custom c++ node. Quite annoying, coz I need another gajillion!
Well... at least another 16!
I don't want to use slider packs. I hate them.
-
RE: Please Increase parameter limit on Scriptnode custom nodes!
Huh.... I'm running into this now, whereas I'm reasonably sure I wasn't before??? Unless this modification is only relevant for the networks themselves, and not the nodes???
SnexSource::SnexParameter::SnexParameter(SnexSource* n, NodeBase* parent, ValueTree dataTree) : Parameter(parent, getTreeInNetwork(parent, dataTree)), pIndex(dataTree.getParent().indexOf(dataTree)), snexSource(n), treeInCodeMetadata(dataTree) { // Let's be very clear about this. jassert(!treeInCodeMetadata.isAChildOf(parent->getRootNetwork()->getValueTree())); auto& pHandler = n->getParameterHandler(); switch (pIndex) { case 0: p = parameter::inner<SnexSource::ParameterHandler, 0>(pHandler); break; case 1: p = parameter::inner<SnexSource::ParameterHandler, 1>(pHandler); break; case 2: p = parameter::inner<SnexSource::ParameterHandler, 2>(pHandler); break; case 3: p = parameter::inner<SnexSource::ParameterHandler, 3>(pHandler); break; case 4: p = parameter::inner<SnexSource::ParameterHandler, 4>(pHandler); break; case 5: p = parameter::inner<SnexSource::ParameterHandler, 5>(pHandler); break; case 6: p = parameter::inner<SnexSource::ParameterHandler, 6>(pHandler); break; case 7: p = parameter::inner<SnexSource::ParameterHandler, 7>(pHandler); break; case 8: p = parameter::inner<SnexSource::ParameterHandler, 8>(pHandler); break; case 9: p = parameter::inner<SnexSource::ParameterHandler, 9>(pHandler); break; case 10: p = parameter::inner<SnexSource::ParameterHandler, 10>(pHandler); break; case 11: p = parameter::inner<SnexSource::ParameterHandler, 11>(pHandler); break; case 12: p = parameter::inner<SnexSource::ParameterHandler, 12>(pHandler); break; case 13: p = parameter::inner<SnexSource::ParameterHandler, 13>(pHandler); break; case 14: p = parameter::inner<SnexSource::ParameterHandler, 14>(pHandler); break; case 15: p = parameter::inner<SnexSource::ParameterHandler, 15>(pHandler); break; case 16: p = parameter::inner<SnexSource::ParameterHandler, 16>(pHandler); break; case 17: p = parameter::inner<SnexSource::ParameterHandler, 17>(pHandler); break; case 18: p = parameter::inner<SnexSource::ParameterHandler, 18>(pHandler); break; case 19: p = parameter::inner<SnexSource::ParameterHandler, 19>(pHandler); break; case 20: p = parameter::inner<SnexSource::ParameterHandler, 20>(pHandler); break; case 21: p = parameter::inner<SnexSource::ParameterHandler, 21>(pHandler); break; case 22: p = parameter::inner<SnexSource::ParameterHandler, 22>(pHandler); break; case 23: p = parameter::inner<SnexSource::ParameterHandler, 23>(pHandler); break; case 24: p = parameter::inner<SnexSource::ParameterHandler, 24>(pHandler); break; case 25: p = parameter::inner<SnexSource::ParameterHandler, 25>(pHandler); break; case 26: p = parameter::inner<SnexSource::ParameterHandler, 26>(pHandler); break; case 27: p = parameter::inner<SnexSource::ParameterHandler, 27>(pHandler); break; case 28: p = parameter::inner<SnexSource::ParameterHandler, 28>(pHandler); break; case 29: p = parameter::inner<SnexSource::ParameterHandler, 29>(pHandler); break; case 30: p = parameter::inner<SnexSource::ParameterHandler, 30>(pHandler); break; case 31: p = parameter::inner<SnexSource::ParameterHandler, 31>(pHandler); break; case 32: p = parameter::inner<SnexSource::ParameterHandler, 32>(pHandler); break; case 33: p = parameter::inner<SnexSource::ParameterHandler, 33>(pHandler); break; case 34: p = parameter::inner<SnexSource::ParameterHandler, 34>(pHandler); break; case 35: p = parameter::inner<SnexSource::ParameterHandler, 35>(pHandler); break; case 36: p = parameter::inner<SnexSource::ParameterHandler, 36>(pHandler); break; case 37: p = parameter::inner<SnexSource::ParameterHandler, 37>(pHandler); break; case 38: p = parameter::inner<SnexSource::ParameterHandler, 38>(pHandler); break; case 39: p = parameter::inner<SnexSource::ParameterHandler, 39>(pHandler); break; case 40: p = parameter::inner<SnexSource::ParameterHandler, 40>(pHandler); break; case 41: p = parameter::inner<SnexSource::ParameterHandler, 41>(pHandler); break; case 42: p = parameter::inner<SnexSource::ParameterHandler, 42>(pHandler); break; case 43: p = parameter::inner<SnexSource::ParameterHandler, 43>(pHandler); break; case 44: p = parameter::inner<SnexSource::ParameterHandler, 44>(pHandler); break; case 45: p = parameter::inner<SnexSource::ParameterHandler, 45>(pHandler); break; case 46: p = parameter::inner<SnexSource::ParameterHandler, 46>(pHandler); break; case 47: p = parameter::inner<SnexSource::ParameterHandler, 47>(pHandler); break; case 48: p = parameter::inner<SnexSource::ParameterHandler, 48>(pHandler); break; case 49: p = parameter::inner<SnexSource::ParameterHandler, 49>(pHandler); break; case 50: p = parameter::inner<SnexSource::ParameterHandler, 50>(pHandler); break; case 51: p = parameter::inner<SnexSource::ParameterHandler, 51>(pHandler); break; case 52: p = parameter::inner<SnexSource::ParameterHandler, 52>(pHandler); break; case 53: p = parameter::inner<SnexSource::ParameterHandler, 53>(pHandler); break; case 54: p = parameter::inner<SnexSource::ParameterHandler, 54>(pHandler); break; case 55: p = parameter::inner<SnexSource::ParameterHandler, 55>(pHandler); break; case 56: p = parameter::inner<SnexSource::ParameterHandler, 56>(pHandler); break; case 57: p = parameter::inner<SnexSource::ParameterHandler, 57>(pHandler); break; case 58: p = parameter::inner<SnexSource::ParameterHandler, 58>(pHandler); break; case 59: p = parameter::inner<SnexSource::ParameterHandler, 59>(pHandler); break; case 60: p = parameter::inner<SnexSource::ParameterHandler, 60>(pHandler); break; case 61: p = parameter::inner<SnexSource::ParameterHandler, 61>(pHandler); break; case 62: p = parameter::inner<SnexSource::ParameterHandler, 62>(pHandler); break; case 63: p = parameter::inner<SnexSource::ParameterHandler, 63>(pHandler); break; default: jassertfalse; } auto ndb = new parameter::dynamic_base(p); setDynamicParameter(ndb); auto ids = RangeHelpers::getRangeIds(); ids.add(PropertyIds::ID); syncer.setPropertiesToSync(dataTree, data, ids, parent->getUndoManager()); parentValueUpdater.setCallback(data, { PropertyIds::Value }, valuetree::AsyncMode::Synchronously, BIND_MEMBER_FUNCTION_2(SnexSource::SnexParameter::sendValueChangeToParentListeners)); }
-
RE: The Sample Map of The Future: Escaping the 20th Century Sample Mapping Paradigm
Gotcha. Maybe I'm thinking about this all the wrong way, and the best approach for me is to use the classic method of handling all my RR logic inside a midi processor script.
I haven't got to implementing any of this yet. I'm still just thinking about it. But as I see it, and from experience, a hihat needs the following:
- Ability to trigger multiple articulations, with round robin functionality.
- Ability to fade out or "choke" earlier voices when a new voice of a different articulation is triggered (Open to closed)
- Ability to crossfade from one articulation to another, based on incoming midi CC (usually CC4)
- Some way to trigger the 'tail' of a 'more open' articulation when going quickly from closed to open.
- Instantly choke all voices when a pedal articulation is triggered.
I was hoping the complex group functionality would do a good chunk of this. But I suppose it is the wrong tool?
-
RE: The Sample Map of The Future: Escaping the 20th Century Sample Mapping Paradigm
@Christoph-Hart said in The Sample Map of The Future: Escaping the 20th Century Sample Mapping Paradigm:
@Orvillain I'm ignoring all the UX suggestions and minor glitches as I'm completely unsatisfied with how it behaves at the moment and I will have to do a third or fourth complete redesign of the UI of this thing.
The only glitch I see in this video is that if you have more than 2 groups (eg. 5 or 8) it still only performs 3 groups - probably it knows that there is no sample in the last group and then it resets the counter, but I'm not sure why it does that.
But in general it's expected that you use as much RR groups as you have RR variations, so you're already in weirdo land if you use more RR groups than samples.
Now if you have different amounts of round robin variations within a single samplemap you can achieve this by using multiple RR layers - which is where this complex system starts to show its strength, for simple RR stuff you don't need that in the first place.
So let's assume you have closed hi hats and open hi hats in the same sample map. For closed hi hats you have 8 RR variations, but for the open hi hat you only have 6 RR variations. You cannot setup a single RR layer to work with both types, instead you need to create 2 RR layers:
- One for the closed hi hat samples with 8 groups
- One for the open hi hat samples with 6 groups
And then we assign the closed hi hat samples to be cycled by the first layer and the open ones by the second. Now comes the important part: in order to tell HISE which samples are subject to which layer you can use the Ignore flag (so in this case both layers need to have the ignore flag enabled). This works like this:
- Assign the closed hi hats to their respective group in the first layer
- Assign the open hi hats to their respective group in the second layer
- Assign all closed hi hat samples to the ignore group in the second layer
- Assign all open hi hat samples to the ignore group in the first layer.
Note that this idea can be combined with any layer so you can create very complex group arrangements. If only the UX would make it easier to understand that stuff...
Okay, I think I get it. So hypothetical here:
A hihat with 20 articulations.
Each articulation has velocity ranges. For argument sake, let's say the velocity range is split into 10 for each articulation.
Each velocity range has a different number of RR layers. It isn't the case that each velocity split has the same number of RR's.So that means, a single hihat sample map will require 20x10 RR setups, each with its own number of groups.
Do I have that right?
In such a situation, yes, it would seem the existing UX is very much an issue. Especially considering that all samples need to also be in the ignore groups.
Personally, setting that kind of thing up, I'd rather script it than do a shed ton of mouse clicks; particularly when you consider a product might have 5-10 hihats, all with different recordings.
-
RE: The Sample Map of The Future: Escaping the 20th Century Sample Mapping Paradigm
I watched my last video back, and just thought I was confusing everything by having so many samples. So I did a new one:
I'm not sure if I am misunderstanding how this thing is supposed to work. But essentially... create 2 RR tokens... add a sample to group 1 and group 2 ... you get the correct RR cycling behaviour. Now create 3 RR tokens.... add a sample to group 1 and 2.... you end up with an empty sample being triggered.
I accept I could just be being a total silly face, but surely this isn't expected behaviour?
-
RE: VST3's and Reaper - anyone getting any weird UI locking behaviour???
@Christoph-Hart said in VST3's and Reaper - anyone getting any weird UI locking behaviour???:
FYI, if it's failing here:
operator bool() const { return (static_cast<bool>(*static_cast<const base_wrapper<Ts, Is>*>(this)) && ...); }
I'm already on it, there's some advanced meta template stuff that doesn't work out :)
Hey Chris, for avoidance of doubt, whatever you did, fixed the issue! Cheers!
-
RE: Ring Buffer design
@Christoph-Hart Ahh interesting!
Even on embedded systems like ARM Cortex (I'm using the DaisySeed chip) ??
Also yes, I enforce power of 2 buffer at all times.
-
RE: Ring Buffer design
So I was reading about mirrored ring buffers. For a normal ring delay, we have a circular buffer of size (n) - a write pointer advances and wraps back around when it reaches the end. A read pointer advances at an offset to the write pointer to create the delay amount. This creates the 1-tap delay effect.
Fractional reads require that sometimes the window of samples required for interpolation crosses the end of the buffer. That window not being contiguous in memory means we need to modulo to access all of the indexes required for the fractional read. This costs CPU for every read operation.
The mirror trick:
Instead of storing [0 ... n-1] we allow a buffer twice as large. Every time we write a sample into w, we also write it into w + N. This results in a mirrored copy of the entire signal.
Even though we allow twice the buffer, our real delay line is still only the single length. Meaning when we read, we read in a straight block. So the interpolator doesn't need to check the boundaries or even do an & mask operation for every tap.
I've not yet implemented it, but think I grok the theory behind it. Costs extra memory, but can be much faster for doing multi-tap fractional interpolation, because you avoid modulo and branching in the inner loop.
I'm going to implement it as a constructor boolean I think, so that my RingDelay class is flexible.