Hi all!
I’m new here, so hello. I’m totally new to programming real-time stuff. I have a dynamic library that needs to be called many times per second to process audio frames. I’m (trying) to use JUCE as a GUI to control the model parameters. So far I have managed to get JUCE to load and call my lib with no problems. My library works fine if it is called in a loop like so:
while(1){
mdl_step(pointers to parameters and stuff);
}
. . . but then everything locks up and I can’t change any parameters or do anything else. I’d like to be able to change parameters while my loops is running. If anyone could point me in the direction of some reading material or provide any clues I’d be massively grateful.
Use the Thread-Class for your processing, be sure to be thread-safe. If your sharing parameters between the GUI and the processing, use a Critical Section, and lock as short as possible.
Great. Thanks for the reply. I have never multi-threaded anything before so I can see this being quite a challenge. I just have a few sliders and I’d like to pass the values from the sliders into my lib that is running in an infinite loop. Something like
But I guess if I set param in one thread, the other thread just has to loop calling the step function. I’m guessing this kind of design must be fairly common? If anyone could post a really simple source code or even pseudo code example of that would be great. Could I skip threads all together and use a loop to just update parameters and check for an exit signal? Sorry to be an (enthusiastic) moron.
Ok, I’m failing quite badly at this. Let me tell you where I am. So far I have gone through haydxn’s wonderful JUCE tutorial and am able to make the basic interface that I need for my application. I have a cursory knowledge of C and know very little about C++ (I’m working on this) but am generally able to cobble bits of code together to do what I want.
At the moment I have a:
class MainComponent : public Component,
public SliderListener
With all of the gui components in that I need and have tried to make a thread class based on the provided pseudocode:
. . . but I have absolutely no idea how to strap this all together into a working application. Does my main component need to be a Thread subclass? How do I set the separate threads off and running? So sorry to be asking all these abstract questions. Once I have something simple up and running I’m sure I’ll be able to improve my knowledge and get ideas from the documentation and source code, but until I can get something running it is hard to learn by tweaking.
chkn you are a legend! Thanks for taking the time to respond yet again. I’ll plough onwards.
I had a little look but it doesn’t use ScopedLock. I’ll have a harder little look and try to figure out exactly what it’s doing.
guilty as charged :). I actually own about 4 different recommended C++, but as soon as the examples switch to a payroll or employee class, my eyes glaze over. I always go back to the warm fuzzy comfort of a scripting language because I don’t like going back to square one. Now that I’m working with real-time processing and want to lean JUCE it will force me to finally learn C++ properly.
Thanks again for the info . . . . . .I’ll see what I can do!
Thanks again for the help. I’m learning a lot as I go. I have something that compiles and runs but I’m not totally sure I got the criticalsection and scoped lock stuff correct. This is because I can comment out the scopedlock calls and everything still runs fine. Therefore, I don’t know If I’ve got the right end of the stick here. Anyway, I’m happy that a thread is going, so yippee on that front.
class myThread : public Thread
{
private:
CriticalSection myCriticalSection;
double local_param_copy;
public:
myThread () : Thread (“superThreadLikeSuperTed”)
{
CriticalSection myCriticalSection;
local_param_copy = 1.0; // give it a start val so it’s not all wacky
//All the DLL loading and initalisation in here
}
~myThread ()
{
//All of the DLL unloading
}
CriticalSection& getCriticalSection()
{
return myCriticalSection;
}
void setParam(double param)
{
local_param_copy = param;
}
void run()
{
while (! threadShouldExit())
{
DBG(T("Produce this message once per 200 ms and show a random int beteen 0 and 50 ->")+String(Random::getSystemRandom().nextInt(50)));
DBG(T("local_param_copy = ")+ String(local_param_copy));
wait(200);
}
}
yes, it will run without the locks (in this case). i mentioned the CriticalSections, because you have to care that you have no undefined states, for example when two threads accessing the same data-structure at the same time, this can happen every time! If you lock one CriticalSection, the other thread can’t get into it.
You can remove “CriticalSection myCriticalSection” in the Constructor, you already defined it in the class (its not a pointer)…
OK. Is there a simple modification that I can make to the code that will result in a nasty error if I don’t use the locks? This is so that I can compare lock-on versus lock-off behaviour.
[quote]You can remove “CriticalSection myCriticalSection” in the Constructor, you already defined it in the class (its not a pointer)…
[/quote]
Ooops, spot the newbie.
Anyway, I’m very happy that with your help so far that I’m able to get some sort of application up and running.It’s good for the motivation!