Why do we need a header file? And why multiple ".cpp" files for every project?

I am still trying to understand the basic principle of making a synthesizer in JUCE. Why do we need a MainComponent.h header file at all? And why a Main.cpp and MainComponent.cpp?

Why not just put everything in one “Synth.cpp” file and then everything is in one place? I can’t understand what the point of this is.

Both Main.cpp and MainComponent.cpp are including the MainComponent.h header.

So why not just make one “Synth.cpp” and put the header information directly in there and simplify things? I can’t understand why I need to be juggling a minimum of three files or what I’m supposed to put in each of the three when it’s all just one thing anyway.

Because as soon as you go beyond trivial hello world stuff, the first thing you need to do is to separate UI and audio stuff so this is a friendly nudge in the right direction.

Why do you have to separate UI and audio stuff? Why can’t you still just have it all in one file? ie. Put the UI stuff in one place called

//=======================UI======================

and then put the audio stuff in another place below that called

//=======================AUDIO======================

?

Do I HAVE to have all these files? Or could I just make one “.cpp” file and if everything is in there it will still work?

You can certainly do that. All what happens is that the preprocessor copies the content of headers into the cpp files, whenever an include is called, the cpp is compiled into objects and the linker creates a binary out of that.
There are obviously memory limits you may hit.

But here is the reason, not to do that:
If your project grows, you need to be able to find problems, limit the side effects to everything etc.

So this approach scales very well. Imagine the whole JUCE modules all in your code file…
These are simple headers and cpp files as well, so these would go into your file as well…

Also, Object Orientation doesn’t exist. The processors have no idea about that. You can live without.
But the same reason: You want to limit side effects, if there is a problem, you want to know, what could possibly have caused that. So this is called encapsulation: have the data private and access it through a well defined interface, so you can easily spot, where a data was modified, without browsing the whole codebase for the error.

I suggest you read this:

http://www.cplusplus.com/articles/Gw6AC542/

and focus on things like scope and dependency.

Rail

1 Like

Another term to get background, google for “Design Patterns”, e.g.Design Patterns on Wikipedia

Well I definitely would want to include the basic JUCE header like this:

#include “…/JuceLibraryCode/JuceHeader.h”

I just don’t understand why if I’m creating a synthesizer with an oscillator, ADSR, control knobs, etc I need multiple further files for that or what each file is going to contain of the code.

I have read all the tutorials on the JUCE site and watched all these videos:

I ran through all these C++ tutorials:
https://www.tutorialspoint.com/cplusplus/

I can follow the basics of those tutorials and videos.

But I still don’t understand how to organize these projects among “.cpp” and “.h” files in terms of what goes in which or why. Or the distinction between what should be private or public.

Is there any resource you can suggest that explains all this? Or can you give me some basic pointers? ie. About organizing or structuring projects/code?

Matkat are the questions I’m asking general to all of C++ or specific to JUCE? Ie. Would all this be “common sense” to me if I knew C++ better but knew nothing of JUCE? Or are the answers to the questions I’m asking JUCE specific?

I don’t want to spend hundreds of hours reading minutia of C++ if it won’t answer these basic structural questions. ie. If the structural questions I’m asking are JUCE specific.

I already understand enough C++ to read the basic code.

When I watched the Youtube videos I linked which were made by an experienced programmer learning JUCE for the first time, I got the impression this is JUCE specific project organization, as he seemed to be having to “figure it out” as well as he went.

a Class represents an idea.
So put each idea in its own source file that encapsulates the idea.
Things that you want the outside world to be able to access in your idea should be public. Things that you don’t want the outside world to be able to access should be private.

This is probably the newbiest of any thread I’ve seen on the forum during my time on the forum lol

Your questions are ENTIRELY based on a lack of knowledge about C++.

It is definitely C++ in general. You asked why, that’s what I tried to answer.
The how is a different question, there are a lot of things, that can’t possibly put into one post.
It is also something, why people attend 2 or 5 years at university to learn how to do things and how to avoid mistakes from others.

But before you get discouraged: there is no right or wrong. There is stuff that works or stuff that doesn’t. There are always many ways to Rome. It’s best to try stuff out, and get your hands dirty.

There is only one thing: There is code you regret when you have to find bugs in it. Don’t worry, you always will, because you constantly learn new stuff. The more practice you get, the less painfull it will be to get back to old projects you wrote.

Good Luck!

It is not JUCE specific, it is just, that JUCE uses always the best concepts and advanced approaches, that are sometimes not known to the average C++ developer, but it is still C++…

Okay thanks. That’s good to know. I only know of C++ what I linked above.

I know how to design complex synths in Reaktor Core but I have no idea how to write them in C++ and I’m trying to learn.

I still don’t understand though why I can’t put all the classes in one file or why this would be a bad idea. I get that daniel has said keeping things separate improves debugging or efficiency but it just seems like you’re making things much more complicated.

ie. If I have a super basic synth, I would need:

sinewave.cpp
sinewave.h
ADSR.cpp
ADSR.h
LFO.cpp
LFO.h
LPF.cpp
LPF.h
overdrive.cpp
overdrive.h
Main.cpp
MainComponent.h

Is that the intention of designing a synth in JUCE?

This is going to get crazy very fast to juggle and I can’t see how much more helpful it will be.

Did you even bother to read the page I linked to? It has all the answers you’re looking for… unless you’re trolling us.

Rail

1 Like

I am certainly not trolling. I’m just confused as fuck and trying to figure out how to organize things so I can get started in rebuilding my projects in JUCE. This is a frustrating process.

I read your link and it was helpful on a few points. But I still don’t feel it explains what I’m asking. ie. Specifically with synthesizer design, does it really make more sense to have 30+ separate “.cpp” and “.h” files with a “.cpp” and “.h” file for every synth component, or would it not make more sense to just do it all in one file?

Having all those separate files might improve compiling time, but by how much? How critical is that? Is the mental cost of organizing and keeping track of dozens of files that all interlink not greater?

Am I correct, that the “idea” of organization for this approach would be to have files as follows:

sinewave.cpp
sinewave.h
ADSR.cpp
ADSR.h
LFO.cpp
LFO.h
LPF.cpp
LPF.h
overdrive.cpp
overdrive.h
delay.cpp
delay.h
Main.cpp
MainComponent.h
etc.

?

In a truly complex synth I can see myself needing 50+ “.cpp” and “.h” files if this is how I’m supposed to do it.

Do you really find that easier to work with?

Have you even bothered to google for “Open Source Synth”?

just LOOKING at the number of source files in JUCE or one of these synths should tell you that YES YOU WILL NEED TO MAKE LOTS OF SOURCE FILES.

Nothing about this question is specific to synths or even JUCE, it’s just a general C++ thing… And yes, my preference these days tends to be to use header-only classes where possible, and to keep the number of CPPs down to the correct number - where that number is not necessarily obvious. It’s probably not 1 file, and probably not too many, but depends on many factors.

That’s not very good advice.

Looking at other people’s projects is certainly useful but they haven’t necessarily used best practices, and what works in their case isn’t necessarily best for your own project.

And yes, you will probably need to make a bunch of files, but you need to make sure it’s neither too few or too many, and that’s generally a skill that comes with experience and refactoring.

1 Like

lol so we shouldn’t look at JUCE’s examples as models for how to organize our projects? ok, good to know :stuck_out_tongue:

I have tried to learn from the tutorials on the JUCE site and the Youtube links I provided. I have also tried to learn from Vanilla JUCE, which is a basic JUCE synth that unfortunately no longer works as is, but I presume I can still learn some basic things from:

http://getdunne.net/wiki/doku.php?id=vanillajuce

The trouble I see in his file structure here:

Is most of the files are absolutely tiny, and the include structure starts becoming complicated. For example here:

he has:

#include “…/JuceLibraryCode/JuceHeader.h”
#include “SynthSound.h”
#include “SynthOscillator.h”
#include “SynthEnvelopeGenerator.h”

Why?

Almost every file has less than 40 lines of code in his project. Many less than 20. So the argument that this is for the efficiency of reducing compiling time is less convincing to me. Our computers are incredibly fast nowadays, and we aren’t talking about 100,000+ lines of code for a synthesizer of any kind (I don’t think).

Browsing through all the files of Vanilla JUCE I can’t help but get the impression this would have been much simpler in just a few files. Maybe one for the GUI elements and one for the audio for example. And I highly doubt reducing it to that would cripple a i7 or higher processor to compile.

I obviously don’t have the experience or knowledge you guys do, which is why I am asking. I understand enough that I can get started on making some things. But knowing how you want to structure things is important and why to get started properly.

Am I crazy? Does it really make sense to have dozens of 15-40 line files like Vanilla JUCE does, each with their own specific “includes” that you must keep organized and properly linked together? Or is this not overcomplicating the structure for a primarily theoretical benefit?

Always question your leaders! Use your brain, Luke! :wink:

1 Like