Audulus Fundamentals: Signal Type Values & Resolution/Rate

Btw I think that having an educational onboarding patch which explains + shows examples of the 4 different [expected] signal types in use will be incredibly beneficial to first time users. It would be the first thing I would like to see.

I might make it myself as my contribution to the onboarding part of the project :), but I’m also a bit slow rn… someone else could probably make it x10 faster than me… In any case if anyone volunteers to do this, I will work with them to make sure it has all the detail that would be helpful to a first time user wondering about these things.

P.S. A large chunk of my current “day job” consists of improving the usability of applications. :slight_smile:

1 Like

You might find this useful:


FWIW, if one doesn’t exist already, a ‘tutorial’ patch that summarizes (with simple examples) best practices for rounding, re-scaling (such as rescaling and stepping knobs) would probably be useful to a lot of people.


You should use clock signals or other gate signals for envelope gate inputs. To modulate the parameters of the envelope, you can use whatever modulation signal you want.

Triangle, Saw, and Sine waves only hit 0 for an infinitesimally small period during their periods. Square hits 0 for longer, and that was just an illustration of it. In general it makes more sense to use a clock (which is basically a square LFO) to trigger envelopes.

Yes, but it’s only necessary when to get the result you want you need it to process like that. If something doesn’t work the way you expect it to, then z-1 might help, but if you don’t know what you’re doing, we can always help here on the forum. In general, when working at the level of modules, you won’t need it.

Yeah maybe at some point Taylor will reconsider, but he says it’s a really tough undertaking that would require a lot of time to figure out.

1 Like

That would be great! We’re always looking for more user-created tutorials. Each example of the new modules in the library comes with 2-4 examples as well, so that should help.

If you go to that post and download the examples, they go along with the modules I’ve documented there.

Rounding is easy:

Rounding.audulus (4.1 KB)

Rescaling is also easy - multiply by the range you want the knob to cover, and add whatever offset you want. If you want something that is -4 to 4, you multiply the knob by 8 and “add” -4.

“Stepping” would just be rounding the output of the knob into whatever range you want it to cover.

1 Like

The expression I use when I want a range of integer values from a knob is floor(k*maximum + 0.5) where maximum is the highest integer value I want. The 0.5 offsets the knob so the the maximum occurs before the knob reaches the very end. So floor(k*8+0.5) will give you a range of 0 - 8. If you need a range starting from a different value just add the offset at the end, floor(k*7+0.5)+1 gives you a 1 - 8 range.

1 Like

Yeah a scaling tutorial could be useful.

@biminiroad: i am pretty conversant in the scaling/rounding stuff. So, I am not mentioning this so much for myself as I know some folks that are daunted by even these seemingly simple things.

Rounding is an interesting thing in that in some situations, it isn’t obvious (unless you have done this a lot or are kinda mathy) when it is useful to floor it or ceiling it.

With some knob types (I use them as integer selectors instead of counters because that it is the only way to have the values persist between launches), for instance, I’ve recently realized that I should scale to a larger range than I want and then clamp the knob output to make it less annoying to get the value you want. So, if I want a knob to select 1 through 5, it can be useful to scale the knob’s output for 0 through 6 and then clamp that to 1 through 5 – as it allows you to get 1 and 5 without turning the knob to its extreme.


This is clear. What is the easiest way to debug/measure the clock rate/bpm? My question is: if I have a signal alternating between 0 and 1, what is the easiest way for me to measure how many times it goes between 0 and 1 per minute? Also, is the full cycle (1 then 0) considered one beat or the half is (0 is a beat and 1 is a 2nd beat)?

Got it. Thanks!

I think I will make this tutorial for myself [as a kind of simplistic reminder/debugger for when I’m way deep and need a simple reference point] and post it here, so others can improve it.

I downloaded the examples that go with the docs. I will start going through some of them today.

1 Like

ah also @biminiroad so it’s okay for me to run Audulus at 96kHZ on my Mac (as long as I’m okay with the CPU trade off)?

what about the “16-bit Integer” vs “24-bit Integer” vs “32-bit Float” (see screenshot above) << Audulus will work with any of them or… ?


It should work with all of them. Audulus uses 32 bit float internally.

BPM is beats per minute, and clocks operate at Hz speeds, so 1Hz = 1 beat per second = 60 beats per minute.

A beat is one full on/off cycle.

You can see a lot of translation modules under the building section:

@stschoen showed me recently that you really only have to use floor(x) - check out the example I posted above.

As for building stuff in general and tutorials like this, I plan on making a building manual for Audulus after I get the module library done that illustrates common questions like this :slight_smile:

The problem with that is if the knob is turned all the way down, you get 0 - 5 (that is, if it’s a problem for your application). The easiest way to do what you’re describing is do floor(x*range+0.999) - so in your case, floor(x*4+0.999)+1 to get 1-5.

If you want to dial in something with a large number of digits accurately, like 0-999, it helps to split up each place into a separate knob and combine them together (so dial in 100s, then 10s, then 1s, and those 3 numbers get summed together for final number).

Awesome. Thanks!

1 Like

This makes sense. Thanks for the thorough explanation and for pointing me in the correct place in the modules library!

1 Like

@espiegel123’s using a clamp() expression to force the minimum value to 1 and the maximum to 5, so the output of the expression would be 1 to 5. This is probably not as efficient as simply using an offset. I prefer using 0.5 as the offset because it make the transitions even on each end. If you use 0.999 then the expression will output 0 only when the knob is between 0 and 0.001 and the limit 0.001 after the limit -1 is passed. Using 0.5 make the ranges at the low and high end equal.


Oh I misread that - thought they were flooring it. Clamping uses x2 the CPU that flooring does.

The case @espiegel123 is describing is for creating integers, so you need to floor it at some point. Doing floor(x*4.999)+1 (which is what I meant to write, not 4+0.999) will make the knob start at 1 and end at 5 with ample space in between.

1 Like

Great tip. It makes me realize that when I was going through examples before I was sensitive to this issue, I didn’t appreciate why people why people set up floors this way. Elegant solution.