1. IMPORTANT:
    We launched a new online community and this space is now closed. This community will be available as a read-only resources until further notice.
    JOIN US HERE

Building BLOCKS: where do i start?

Discussion in 'REAKTOR' started by Peter Bols, Jan 29, 2021.

  1. Brett Lavallee

    Brett Lavallee NI Product Owner

    Messages:
    1,024
  2. Peter Bols

    Peter Bols NI Product Owner

    Messages:
    90
    Thank you so much, Brett!

    At the moment, i'm trying to recreate the exact same conditions for the Drive control in Core.
    It involves maths. :D
    I also gave the control knob some weird values (min 0.9, max 2.5) in the Primary version.
    But i think it sounds and behaves great this way so i'll probably just recreate it exactly. We'll see.

    This is a very very simple module. Both in its build and in its functionality.
    But i think there is something about an overdrive combined with a filter and Dry/Wet controls.
    You can set it to destroy, but still keep an audible part of the original signal.
    All i have to to is make it sound exactly right. o_O

    The "original" is in the User Library here: https://www.native-instruments.com/en/reaktor-community/reaktor-user-library/entry/show/13987/
    Listen to the sound demo i uploaded to get an idea of what i'm after.

    Grts,
    Peter
     
  3. Philippe

    Philippe Well-Known Member

    Messages:
    1,553
    May. be also separate GUI tasks from processing ?
     
  4. Big Gnome

    Big Gnome NI Product Owner

    Messages:
    574
    There is all that, and it's also very important to the format that all the I/O be strictly audio rate--one of the key distinctions between core and primary is that the former doesn't distinguish between audio signals and control signals (and some of the primary logic relating to how event streams are handled gets waaaay into the weeds). It's a fundamental part of the framework that any input be connectable to any output without slewing to control rate or otherwise degrading the signal, or incurring any unexpected behavior emerging from how events are handled in primary. Of course primary necessarily handles graphical elements and potentially a few odds 'n ends that aren't part of core (e.g., iteration, voice handling), but all the processing really should be handled in core.

    Plus, most of the basic primary modules are pretty long in the tooth--that is, predating some big strides in DSP and designed to run respectably on processors clocking in at the paltry hundreds of MHz with all the attendant compromises that implies--and all too often I'm afraid it shows. ;)
    There are not really hard, fast rules about that sort of thing, but you'd generally want to use logarithmic curves when it's important to have greater resolution at the lower end of a control's range. A few typical examples would be things like filter cutoff or oscillator pitch (since frequency is exponential vis a vis pitch), LFO rates (for much the same reason, and it's usually desirable to have a finer degree of control over slower "wiggles" than faster ones, especially if it goes into the audio range where modulation is just kind of different flavors of clangorous whereas below 10Hz or so, minute changes in rate have a really big impact on how the modulation feels); likewise it usually sounds more natural to amplify audio signals logarithmically (i.e., by dB) whereas control signals are more often scaled as a linear percentage.

    Do please note that signals should be constrained to -1–1 (modulation signals by convention stick to 0–1 for unipolar, -0.5–0.5 for bipolar, although this is more a guideline than a rule). I see you're using some ladder filters in your design--for example, for logarithmic control over cutoff in keeping with the blocks standard, you'd probably use one of the framework's prefab controls and patch that up within the Panel macro; then in the Process core cell, patch its associated input through a smooth + A/B Mod macro (also a part of the blocks framework), and scale that to the desired cutoff range (in midi pitch)--let's say for the sake of illustration 30–130, which is loosely about 50Hz–15kHz, a pretty sensible range for a lowpass filter. Scaling 0–1 values is ridiculously easy: you could do that manually by multiplying the output of the smooth + A/B Mod macro by 100 and adding 30; or you could do it even easier by using an [x,y]->[u,v] module (in the Library > Math submenu) to automatically remap the control to your chosen min and max values; or you could be lazier still--like me--and use a modified version thereof that assumes a 0-1 input from the get go (attached). Then you'd just pop that through a P2F macro (under the Library > Convert submenu), and there you have your cutoff frequency you can patch into your filters, which sweeps with a "natural", "musical" logarithmic response.
     

    Attached Files:

    • Like Like x 4
    • Informative Informative x 1
  5. Big Gnome

    Big Gnome NI Product Owner

    Messages:
    574
    If you don't intend to be able to modulate the control knob, then hey, no harm no foul; but if you do, the control really needs to be 0-1, and this is as good an opportunity as any to get used to best practices. :)
    The generic formula to map 0-1 to an arbitrary range is y = x * (max-min) + min, like so:

    Untitled-1.png

    (But seriously, just use the [0,1]->[u,v] macro I posted instead. Huge time saver, I promise.)
     
    • Like Like x 1
  6. bolabo

    bolabo NI Product Owner

    Messages:
    402
    When you come to build the block, if you use the NI template:

    https://www.native-instruments.com/en/reaktor-community/reaktor-user-library/entry/show/8705/

    Then the knob values will always be 'normalised' from 0 to 1. So you would need to scale the incoming knob values for the different parameters (frequency, pitch, drive etc) you are controlling in your block's core cell.

    You can use the XFade macro easily to scale values from 0 to 1 to the range you need.

    For frequency values it's usually best to set the minimum and maximum values as 'pitch values' and then convert these 'pitch values' to 'frequency values' using the 'P2F' macro. The 'P2F' macro will handle the "logarithmic versus linear" issue you mentioned.

    Pitch values are the same as MIDI note values, with 60 being the same as 'C3' on the keyboard. A pitch range of 30 to 130 is a good range for a filter control.

    See the screenshot below for an example of a core cell for a simple filter block with some additional overdrive / distortion, the XFade macro scales the normalised (0 to 1) values from the knobs to the correct ranges for the filter and overdrive parameters.

    Here is some info on the 'smooth + A/B Mod' macros that you can see in the screenshot, this macro is used by most blocks for smoothing and adding the A/B modulation to knobs:

    The 'smooth + A/B Mod' macro is connected to each knob. This macro first 'de-multiplexes' the events coming from the knob. This sounds complicated but it just means that the blocks framework that is used by the NI template puts each of the block's knobs and that knob's corresponding A/B modulation sliders into a single primary macro, and then sends the values for these 3 controls (knob, A slider and B slider) to the core macro using a single wire. It combines the values of the 3 controls into a single connection using a method called 'multiplexing', which just means that the macro always sends 3 events at a time down the connection, one event for each of the 3 controls: the knob, it's A slider and it's B slider.

    The '{' and '}' characters that NI have used in the port names, eg "{C1}" indicates that these ports are expecting a multiplexed signal.

    So the 'smooth + A/B Mod' macro first 'de-multiplexes' the multiplexed events from the knob macro, so that it has the values of the knob and also the values for the A and B modulation sliders. It then smoothes these 3 values to remove 'zipper noise' caused by using the mouse, and then uses these values to apply modulation from the A and B input ports.

    There are 2 wireless 'pickups' for the A and B input ports inside the 'smooth + A/B Mod' macro, and this is how it applies the modulation. This wireless connection is possible because The A and B input ports are connected to 2 'distributors' (the small rectangles with the green LEDs). See screenshot.

    Once the A and B modulation signal is applied, the modulated signal is clipped between 0 and 1 (so that even with modulation applied it never goes above 1 or below 0), and is then sent to the output of the 'smooth + A/B Mod' macro.

    The signal is coming out of the 'smooth + A/B Mod' macro at 'audio-rate', this signal, with A/B modulation applied, is also then immediately sent out of the core cell to drive the little triangular modulation indicators that show up when you apply A/B modulation to a knob. On it's way out the signal passes through the 'Latch' macro, which is simply re-clocking the signal using the 'Display Clk' (Display Clock) distributor that you can see at the top of the core cell. As the modulation indicators are just for display purposes they don't need to be driven at audio-rate so 'latching' them to the Display Clock saves CPU.

    All this sounds a bit complicated but it's not that tricky once you get your head around it, these are the important things that you need to know when building a block:

    • The events coming into the block from the primary knob macros are 'multiplexed' so you need to use the 'smooth + A/B Mod' macro to de-multiplex them, and this is also where the the A and B modulation is applied.
    • The values coming out of the 'smooth + A/B Mod' macro are 'normalised' between 0 and 1, so you will need to scale these values to the range needed for your parameters. You can use XFade macros to do this easily.
    • The modulated signal coming from the 'smooth + A/B Mod' macros is immediately sent back out of the core cell, via a Display Clock latch, to drive the small triangular modulation indicators.

    The REAKTOR Blocks Framework Manual, found here:

    https://www.native-instruments.com/en/products/komplete/synths/reaktor-6/downloads/

    has a much more in depth explanation of all this, so definitely worth reading through that a couple of times! :)


    Screenshot 2021-02-01 at 11.53.57.png
     
    Last edited: Feb 2, 2021
    • Like Like x 2
    • Informative Informative x 2
  7. bolabo

    bolabo NI Product Owner

    Messages:
    402
    Oops looks like our posts just crossed :) Yep this is a good way to go too, some great info!
     
    • Like Like x 1
  8. Peter Bols

    Peter Bols NI Product Owner

    Messages:
    90
    I think my head just exploded. :D #Core

    Thank you so much for your input!
    I really appreciate it.

    OK. One step at a time.
    Step 1: get the Drive control where i want it to be.
    I will be doing a lot of reading, editing and testing.

    Grtz,
    Peter
     
    • Like Like x 1
  9. Paule

    Paule NI Product Owner

    Messages:
    7,555
    Core is the heart - not the head.
     
  10. Peter Bols

    Peter Bols NI Product Owner

    Messages:
    90
    OK

    I'm starting to realize that i can't just start with building the "process" cell and go from there, but that i have to build everything all at once in order to keep oversight and to make sure everything plays nice together.

    So, here's a quick mock-up of how it could look eventually. This is going into designing the Panel cell.

    BWB.jpg

    Once again, thank you all so much for your generous input.
    This turned out far more complex than i thought it would be, for a hack like me, but i'll give it a good try.

    Grtz,
    Peter
     
    • Like Like x 2
  11. Big Gnome

    Big Gnome NI Product Owner

    Messages:
    574
    Looks nice! I really dig the graphical work I've seen in your projects by the way. If it's helpful, I usually find it easiest to mock up the basic workings first (sans framework stuff like mod busses and whatnot), and then when I'm satisfied, insert that into the framework, leaving skinning and other little GUI niceties for last such that I'm not having to juggle a bunch of diverse tasks all at once. At least that's the workflow that's the most productive for me.

    Anyway, I think this is a terrific choice of a "Hello world" project--not overly ambitious, nor too trivial to bother with--and I for one am looking forward to the result. Good luck, and ask away if you find yourself stuck. :)

    P.S., since this is a distortion effect, don't overlook Efflam Le Bivic's excellent ILO macros. They do a very respectable job of reducing aliasing with very little CPU overhead (relative to oversampling); albeit at the expense of tending to 'soften' the sound >10kHz or so, but for a distortion, that's probably desirable in its own right.
     
    Last edited: Feb 2, 2021
    • Like Like x 1
    • Informative Informative x 1
  12. colB

    colB NI Product Owner

    Messages:
    3,969
    I find that the 'ILO' approach works very well when combined with oversampling, particularly in the context of guitar style distortion. Even low level aliasing can be a problem when there are multiple aggressive gain stages ;)
     
  13. Peter Bols

    Peter Bols NI Product Owner

    Messages:
    90
    Short update: processing is going well.

    But doing the panel layout is driving me nuts.
    I should not run into this many problems, just replacing images and moving stuff around.
    IMO, Reaktor has too much of a mind of its own when it comes to GUI editing.

    Grtz,
    Peter
     
    • Like Like x 1
  14. bolabo

    bolabo NI Product Owner

    Messages:
    402
    It can get tricky with all the layers, as each layer has it's own 'bounding box' and so that can cause confusion where there are multiple graphic items (shadows, modulation indicators etc) in different layers in nested folders, especially when moving things with the mouse.

    The best technique for moving things around is to select the object not by clicking on it with the mouse but by selecting it's 'highest level' macro (for example the macro containing the control knob inside the main 'Panel' macro), then unlock the panel and use your keyboard's arrow keys to move it around. To be honest I never use the mouse to move panel elements for this reason. I alway select the objects or macros and then move them using the keyboard arrow keys. Just one of the quirks of working in Reaktor.

    There's a function in the inspector to 'Group Panel Elements', and if you apply this to a panel item's macro and all it's nested macros, you can move it around with the mouse, but then it becomes more of a hassle if you need to go in to it and edit stuff later.
     
    Last edited: Feb 5, 2021
  15. bolabo

    bolabo NI Product Owner

    Messages:
    402
    Yeah ILO is pretty cool! I have a small library of macros using ILO techniques for low aliasing wavetables, samplers, wave-shapers etc. I need to organize it and upload to user library, but can send it to anyone if interested.
     
    • Like Like x 1
  16. Catman Dude

    Catman Dude NI Product Owner

    Messages:
    761
    Love to have that, David! Here or U/L. THANKS
     
  17. Peter Bols

    Peter Bols NI Product Owner

    Messages:
    90
    Well, since working on the version with modulation was giving me such a headache, i decided to work on finishing the simple version first.

    But i've run into a problem that i just can't figure out how to fix.
    Please have a look at this.

    With the Dry/Wet control all the way WET, i'm not getting any signal passed the filter apart from some inaudible low frequencies when i crank up the resonance.
    All the knobs have 0...1 values.
    I've run up and down the chain multiple times and everything looks right to me. I've cut the filter out of the equation and that worked, so it's definitely the filter.

    Oh god.jpg

    This is going to be something super silly that i've overlooked.
    So frustrating!

    Grtz,
    Peter
     
    Last edited: Feb 6, 2021
  18. colB

    colB NI Product Owner

    Messages:
    3,969
    You have to post the ensemble, or post pics that let us see the code. You problem could be in the DRY/WET macro, or in the AMP macro, or some thing external, or one of the other macros, or some combination. It's not possible to debug code without being about to look at the code.
     
  19. Peter Bols

    Peter Bols NI Product Owner

    Messages:
    90
  20. nanotable

    nanotable NI Product Owner

    Messages:
    44
    Peter, thank you for all your work, I’m looking forward to the finished version.

    I can load and use the Block successfully in Rack mode, using the latest version of Reaktor. The knob behavior probably needs some fine tuning, I guess, but otherwise it’s working fine.