Assignment JUCE: Welcome to the JUCE World

Due: Start of Week 2
Deliverables: None

In this assignment, we welcome you to the world of JUCE.

  1. Goals
    1. Install JUCE
    2. Build and Run a JUCE Standalone Plugin
    3. Load the Audio Plugin into your Digital Audio Workstation (DAW)

  2. Prerequisites
  3. You will need:

    Early in the class we will learn who is using which OS, IDE, and DAW. Students are encouraged to work together and help each other solve problems that arise.
    The instructor (JOS) is most comfortable with MacOS and Xcode, but also experienced with Linux and Makefiles, and having some CMake and CLion experience.

  4. Installing JUCE
  5. cd to wherever you like to collect git repos and say
    git clone https://github.com/juce-framework/JUCE.git
    You should now have a new JUCE subdirectory.
    If JUCE is not in your home directory, please make a symlink to it there:
    ln -s /path/to/JUCE ~/JUCE
    With this symlink, you will not need to modify JUCE module paths when they come up in the 320c starter code.
    Another reason is that you can easily switch among JUCE versions by changing the link.

  6. Build Projucer
  7. The Projucer is a convenient application that allows you to create and manage JUCE projects in conjuction with your preferred IDE, such as Xcode on the Mac.
    Most people start out with the Projucer and graduate later to CMake (which is well supported by JUCE).

    Following ~/JUCE/README.md, the Projucer can be built as follows:

    cd ~/JUCE
    cmake . -B cmake-build -DJUCE_BUILD_EXAMPLES=ON -DJUCE_BUILD_EXTRAS=ON
    cmake --build cmake-build --target Projucer
    The app can then be found as ~/JUCE/cmake-build/extras/Projucer/Projucer_artefacts/Projucer.app on the Mac, and on Linux, there is no .app extension, as it's a plain executable file in that case.

    Alternatively to using CMake, find the IDE project file you need in ~/JUCE/extras/Projucer/Builds/. These IDE projects were generated by Projucer itself. You should see subdirectories for MacOSX, VisualStudio2017* (Windows), and LinuxMakefile. cd to the folder for your operating system, open the IDE project file in your C++ IDE, and do a build. For Mac OS using Xcode, e.g., the app is created as ~/JUCE/extras/Projucer/Builds/MacOSX/build/Debug/Projucer.app.

    However you build the Projucer, it is convenient to link to it as ~/JUCE/Projucer.app and launch it via the link, such as in a shell alias. A symbolic link ("symlink") can be created at the command line like this:

    ln -s ~/JUCE/.../Projucer.app ~/JUCE/Projucer.app
    and it works as desired when the JUCE symlink changes. A shell alias for launching Projucer from the command line on a Mac, using the shell csh or the like can be defined like this (normally in your ~/.cshrc or ~/.tcshrc file):
    alias opj open -a '~/JUCE/Projucer.app \!:*'
    Then, typing opj at the shell command line opens the desired Projucer. That way, if you switch to using another JUCE distribution by modifying the ~/JUCE symlink, the associated Projucer version will be switched along with it.

    As discussed in the 320C starter-code README.md, Projucer project files (extension .jucer) will contain paths to modules provided by the JUCE distribution (and next week the PGM distribution). As described there, the starter code will have .jucer files that expect JUCE and PGM modules under ~/JUCE and ~/PGM, respectively.

  8. Test Projucer
  9. As a test of Projucer and your ~/JUCE symlink, let's see if Projucer can regenerate its own IDE project files:

      Launch the Projucer you just built
    1. Choose the best exporter for you and export the project. This will replace the IDE project file originally found in ~/JUCE/extras/Projucer/Builds/.
      (Note that for Linux Makefile, you must go to the Projucer menu and select File / Save Project, which saves out all IDE project files.)
    2. Rebuild and launch Projucer as in your IDE

    As another symlink test and code cleaning:

    1. Edit ~/JUCE/extras/Projucer/Projucer.jucer and change ../../modules to ~/JUCE/modules everywhere it occurs
    2. When you bring Projucer to the foreground, it will notice that its .jucer file has been changed externally. Confirm that you accept.
    3. Export, build, and run Projucer again. If it fails to find modules, fix your symlink.

  10. Create a Project in Projucer
  11. Launch Projucer and create a new Basic Plug-In project. Give your project a fun name like HW0HelloWorld.

    Note that Path to Modules is set to ~/JUCE/modules already by default. If your ~/JUCE symlink is in place, you shouldn't encounter any errors regarding your JUCE modules now. However, for the foleys_gui_magic module (also in the JUCE module format, but distributed separately, as we'll encounter next week), it is nice to add ~/PGM/modules to your User Modules path, by selecting the menu item Projucer / Global Paths ..., and setting User Modules as shown below:

    (If you later need more modules, such as your own modules [highly recommended for all finished and reusable code], you can set User Modules to ~/modules and populate ~/modules with symlinks to foleys_gui_magic and any other modules you ever use.)

    Now hit Projucer's image-button (near the top-right) that means "Build-IDE-Project-File-and-Launch-IDE", after making sure that your Selected exporter is what you really want. This should generate your IDE-format project files and launch your IDE. Set the active IDE scheme to build a Standalone Plugin and hit (Build and) Run in your IDE. This should automatically launch a standalone version of the demo "Hello World" plugin:

  12. Build an Audio Plugin for your DAW
  13. Standalone Plugins are great for debugging and testing, but the whole point of a plug-in is that it plugs into other applications such as your favorite DAW. Change your active IDE scheme to be either VST3 (for most DAWs) or AU (for Apple DAWs such as Logic Pro). After building, launch your DAW and you should be able to load your "Hello World" plugin inside your DAW.

    The JUCE platform is great for allowing you to build applications for many different platforms.
    Right now your plugin doesn't do much, but we'll soon change that!

Exporter Notes

Visual Studio Code ("VS Code") is a cross-platform IDE written in Electron that is quite different from the Visual Studio IDE app which runs only on Windows and Mac. VS Code therefore does not open any of the "Visual Studio 20xx" exports generated by Projucer. However, there are many paths to VS Code from Projucer. Here are two:

Normally your CMake files (or Makefiles) will diverge from your Projucer project file, but once in a while you can edit the .jucer file and update it (usually just adding references to new files), or simply delete it and use only CMake from then on. (I do this on the Mac where I use both Projucer and CMake.)

Handy References

Appendix: What is a "Module" Exactly?

The word module is at least quadruply overloaded in Music 320c:
  1. The JUCE module format uses what is sometimes called the unity build style (not related to the Unity game development platform).
    A module in this context is many related C++ utilities combined into one rather large compilable unit (.cpp file and associated .h file).
    All modules are compiled and added to a shared code library for your project in your IDE. This speeds development because you normally compile only new code, and link that with the library of modules created by your IDE.
    Even when developing modules, only the module that changes needs to be compiled. We will say "JUCE-format modules" for clarity when needed.
  2. In the Doxygen documentation for JUCE modules, each subdirectory is referred to as a module, e.g., see the juce_core JUCE module. It would be nice if we could configure Doxygen to say "subgroup" or "subdirectory" here instead of "module".
  3. There are also git submodules, which are unrelated except of course that JUCE-format modules [more often module collections such as the JUCE Distribution] may be distributed in git submodules.
  4. We often speak of Faust DSP modules, which are block diagrams specified in the Faust language.
    Each Faust compilation creates a single process function that defines the block diagram and compiles to a single C++ class.
    Instances of that class may be called DSP modules in your C++ program.
  5. Let's face it: The term "module" is highly modular. In any tree structure, for example, the nodes can be thought of as modules, or submodules, etc. We can always prepend enough adjectives to make it clear what we're talking about.