Momentary backlight on toggle switch

I have a module I use strictly for testing, so I usually try make the thing I want separately, in that testing module, so there is less to be confused about. And then implement it in main module. But I see sometimes thats not enough and stronger tools needs to be used.

Which debugger do you suggest?

Thanks, that’s something to go off from.

First I want to ask, if it’s bad practice to do what I am trying todo? If it’s not a good idea, I don’t want to go too far out of that tangent.

My goal is to make the code in process simpler and also to make functions I can reuse again and again, including counter based functions. If you have a specific suggestion to achieve those goals, I’d appreciate it.

Some of this stuff is hard to look up on the web, if you are not sure what question to ask or what to search for.

The typical setup for Rack modules, I think is using VSCode as the code editor and debugger. There are other topics on the forums about setting up VSCode for building and debugging.

Building a library of helper classes and functions is a good practice. For something like a counter which requires persistent state, a struct (or class) with member functions is more suitable than standalone functions. To use such a class, you would make an instance of one a member variable of your module.

For a simple example of such a class, take a look at the PulseGenerator struct in Rack/include/dsp/digital.hpp. Note that Rack uses struct everywhere, rather than class, so simplest is to follow that style. In discussions in this forum, for most purposes the terms are pretty much interchangeable, but there are differences that are good to learn once you’ve learned more about C++.

In fact, the Rack source code has lots of good examples of building such functionality, and has many things that are ready to use, rather than building them yourself (although making them from scratch is a good way to learn).

Thanks :slight_smile:

I’ve been using c++ for years, coding objects for Axoloti, VCV Rack and more, but some of the structural stuff, I don’ tknow so much about, it’s been mostly about algorithms. I did take an online course on Udemy, but that course doesn’t really give very good practical examples. But I did learn a good deal from it anyway.

I will check the example, thanks!

I have downloaded a bunch source code from different developers, that I do look at to learn.

I usr Atom and build via terminal, on Mac. Maybe I’ll look into VSCode, to lears something new.

About structs and classes and so on, I only know a little bit of that side of coding, but surely want to learn about it :slight_smile:

Hey again :slight_smile:

Yeah there are a lot of example in the rack code for sure. Personally I think it has gotten a lot harder to understand the code since polyphony has been introduced. I mean I love then functionality. no doubt, but I think it gets a bit hard to understand at times.

But the thing is, I have the functionality I’d like. It works in the the process block, as I like. But I just can’t get it to work outside of the process block, in a function or a struct.

I managed to build a very simple struct/class, with a member function. I tested I can get in/output of the struct, by passing the gate trough, with nothing done to it. What comes in comes out of the member function.

But the issue is still the same with the counter, which is inside the member function. The counter just still wont count the same it does in process block. It just outputs 0 1 0 1 0 1, on each input gate, no matter what I do, instead of counting 1,2,3,4,5.etc… til i stop the gate input.

It’s nice that I learned how to make a struct/class, with members, but anything time based, like a counter, just don’t work. I am obviously missing something important.

My struct looks like this, in my functions.hpp file:

struct PulseG{
public:
bool Trigger;
int Count = 0;

    int Pulse(){
      if(Trigger > 0){
          Count = Count+1;
          }
          return Count; // Output of member function
       }

};

In the process block:

PulseG Pulse1; // Declare struct and create a version of PulseG
Pulse1.Trigger = inputs[TEST2_INPUT].getVoltage(); // Gate in
outputs[SINE_OUTPUT].setVoltage(Pulse1.Pulse()); // Return of Pulse member

This should make the counter go every time it get a gate high on the input. But counter just goes 1,0,1,0,1,0,etc, when it gets a gate input. Only changes on input change, it doesn’t go on, like in main process.

It’s almost like time doesn’t exists in the struct or function, it only does something when an input is applied, the counter doesn’t run same way, on it’s own, as in the process block.

So turning it into a struct didn’t do the trick either. Counter still doesn’t run at samplerate.

You’ve made Pulse1 a local variable of the process function. This means it lives only as long as the current call to process, and it gets re-created each time process is called. If you need state retained across process calls, then Pulse1 will need to be a member variable of your Module.

Other issues or nits with this code:

  • Trigger should be initialized. Also, since it’s a bool, it’s odd to test for greater than zero: better to say simply if (Trigger)....

  • Setting boolean Trigger to a float voltage is probably not going to be what you want in the long run (if this even compiles). Triggers usually need to be a Schmitt trigger, that watch for a value rising across a threshhold for a minimum period of time (typically 1ms). (Rack has a SchmittTrigger class you can use). What you have here is a switch, rather than a trigger, where the counter runs as long as the input voltage is nonzero. So better to call it something other than trigger. Also, most modules are built to tolerate some amounts of noise, so better to do something like Trigger = voltage > .01f.

  • public: isn’t needed because everything in a struct is public by default.

  • Initial cap for member variables (a.k.a. Pacal case) is an unusual naming convention that is likely to throw off people reviewing your code. It’s more typical to use camelCase or snake_case.

When I moved the declaration of PulseG Pulse1 to where I declare other variables, inside the module itself, the counter worked!

Thank you!!!

I don’t see any floats declared here?

Yes, I know it’s not a gate/pulse, I just needed to get the counter working before I could do the rest. Separating issues and take one at a time is the only way to go. I got the rest of the code working fine, just needed to get the counter working before I could go on and put in the rest of the code. I did that now and it works!

My problem was that when I stop my sequencer, sometimes a gate was left high, which means first step of the sequencer would not be played. With a pulse, with a fixed length that always turns of automatically, that issue should be solved now, no gates left hanging high and dry :slight_smile: I found out about the public/private thing after I looked up both class and struct. For class it’s private per default, for struct it’s public. So yes I need to remove that :slight_smile:

The formatting, yes still trying to figure out what makes most sense to me.

But this is awesome and I appreciate the help a lot. Now I can start cleaning my code and making some classes.

Once again, thank you :wink:

1 Like

Ahh I missed that float… You are right. Needs to be a bool instead. I did the float cause I was not sure of the counter would if it was a bool member. I guess it should work :slight_smile:

Also found better way to get data into members, this seems simpler and looks more like how everyone else is doing it. So all good, this is gonna be great :wink:

If you want pulses, then Rack has provided one for you: ::rack::dsp::PulseGenerator.

I prefer to make my own, to be honest. Then I understand what’s going on. I find it easier.

For algorithms and functions i use Axoloti library as source. The code is easier to understand, but the downside is, there is a lot of bit shifting and on Axoloti you also don’t learn about classes and structs and stuff. But for algorrithms, it’s very good inspiration and source :slight_smile: