Code Monkey home page Code Monkey logo

advancedaudiotemplate's Introduction

AdvancedAudioTemplate

A template for quick development of audio plugins on a semi-professional level.

Dependencies: This template is based on JUCE. So you need to clone JUCE and you need one more CMakeLists.txt file from the repository AudioDevOrga.

Your directory structure should look like this

YourDevDir CMakeLists.txt (from AudioDevOrga) JUCE (directory) YourNewProjectDir (see Usage section of this ReadMe) CMakeLists.txt (from this template) tools (template dir) PluginEditor.cpp PluginEditor.h PluginProcessor.cpp PluginProcessor.h PluginSettings.h YourPluginName.cpp (keep this name for the file, it will be renamed later) YourPluginName.h (keep this name for the file, it will be renamed later)

Purpose

This template provides some basic features for effects and synth, like:

  • synchron block processing for arbitrary block sizes
  • preset handler
  • resizable GUI
  • saving/loading of plugin state (with GUI size)
  • keyboard + pitch-wheel and modulation-wheel (midi insert and display)
  • Access to Version Number given in CMakeLists.txt
  • a template plugin cpp and h for easy start (named YourPluginName.cpp and h).

Usage

  1. Create a new directory (better create a new repository in GitHub)
  2. (if Github): Checkout your new project
  3. copy template files (https://github.com/JoergBitzer/AdvancedAudioTemplate)
  4. rename all instances of "YourPluginName" in the Files with something appropriate (use a renaming-tool like
    sed -i 's/YourPluginName/YourNewProjectName/g' *.*

for MacOS (https://stackoverflow.com/questions/4247068/sed-command-with-i-option-failing-on-mac-but-works-on-linux) for Windows: (https://stackoverflow.com/questions/17144355/how-can-i-replace-every-occurrence-of-a-string-in-a-file-with-powershell)

 Get-ChildItem '*.*' -Recurse | ForEach {
      (Get-Content $_ | ForEach  { $_ -replace 'YourPluginName', 'YourNewProjectName' }) |
      Set-Content $_ }

or start the windows subsystem for linux

or use the tools given by visual studio code.

  1. Rename YourPluginName.cpp and YourPluginName.h into YourNewProjectName.cpp and YourNewProjectName.h (e.g. Linux:
    rename 's/YourPluginName/YourNewProjectName/' *.*     

and Windows (cmd, not PS)

ren YourPluginName.* YourNewProjectName.*
  1. Add your new subdiretory to the main CMakeLists.txt (in main directory YourDevDir (e.g. AudioDev)) file
  2. add or remove add_compile_definitions to your intention (Do you need a preset manager (default is yes), Do you need a midi-keyboard display (default is no))
  3. Test if the template builds (should without error) and start coding your plugin

Example to use the template

Gain plugin (of course)

source code at. I would use it only as a backup, if something goes wrong.

  1. Think about a name: Here, GainPlugin

  2. Apply Usage for the 4th step: sed -i 's/YourPluginName/GainPlugin/g' . for MacOS, see (https://stackoverflow.com/questions/4247068/sed-command-with-i-option-failing-on-mac-but-works-on-linux) for Windows: (https://stackoverflow.com/questions/17144355/how-can-i-replace-every-occurrence-of-a-string-in-a-file-with-powershell)

  Get-ChildItem '*.*' -Recurse | ForEach {
      (Get-Content $_ | ForEach  { $_ -replace 'YourPluginName', 'YourNewProjectName' }) |
      Set-Content $_ }

or use the tools given in Visual Studio Code

for the 5th step: rename 's/YourPluginName/GainPlugin/' . or by hand (just 2 files)

for the 7th step switch off PresetHandlerGUI (for a simple gain not necessary)

  1. Change the size in PluginSettings.h to something useful for a gain plugin
const int g_minGuiSize_x(200);
const int g_maxGuiSize_x(500);
const int g_minGuiSize_y(400);

In GainPLugin.h add the parameter definition (delete the example)

const struct
{
	const std::string ID = "gain";
	const std::string name = "Gain";
	const std::string unitName = "dB";
	const float minValue = -80.f;
	const float maxValue = 20.f;
	const float defaultValue = 0.f;
}g_paramGain;
  1. Add the support for a smoothed parameter
private:
    float m_gain = 1.f;
    std::atomic<float>* m_gainParam = nullptr; 
    float m_gainParamOld = std::numeric_limits<float>::min(); //smallest possible number, will change in the first block
    juce::SmoothedValue<float,juce::ValueSmoothingTypes::Multiplicative> m_smoothedGain;
  1. change addParameter (delete the example code)
    paramVector.push_back(std::make_unique<juce::AudioParameterFloat>(g_paramGain.ID,            // parameterID
                                                        g_paramGain.name,            // parameter name
                                                        g_paramGain.minValue,              // minimum value
                                                        g_paramGain.maxValue,              // maximum value
                                                        g_paramGain.defaultValue));
  1. change prepareParameter (delete the ignore method)
    m_gainParam = vts->getRawParameterValue(g_paramGain.ID);
  1. change the smoothing time for the SmoothedValues in prepareToPlay
    // here your code
    m_smoothedGain.reset(sampleRate,0.0015); // 50ms is enough for a smooth gain, 
  1. Change the processSynchronBlock method (delete ignore method)
    // check parameter update
    if (*m_gainParam != m_gainParamOld)
    {
        m_gainParamOld = *m_gainParam;
        m_gain = powf(10.f,m_gainParamOld/20.f);
    }

    int NrOfSamples = buffer.getNumSamples();
    int chns = buffer.getNumChannels();

    //m_smoothedGain.setTargetValue(m_gain);
    m_smoothedGain.setTargetValue(m_gain);
    float curGain;
    for (int channel = 0; channel < chns; ++channel)
    {
        auto* channelData = buffer.getWritePointer (channel);
        // ..do something to the data...
        for (int kk = 0; kk < NrOfSamples; ++kk)
        {
            if (channel == 0)
                curGain = m_smoothedGain.getNextValue();
            channelData[kk] *= curGain;
        }
    }
  1. Component adjustment (add one slider)

In the header add the necessary variables it should read like this

private:
    AudioProcessorValueTreeState& m_apvts; 
    juce::Slider m_GainSlider;
    std::unique_ptr<juce::AudioProcessorValueTreeState::SliderAttachment> m_GainAttachment;

In the cpp file change the constructor

    m_GainSlider.setRange (g_paramGain.minValue, g_paramGain.maxValue);         
    m_GainSlider.setTextValueSuffix (g_paramGain.unitName);    
    m_GainSlider.setSliderStyle(juce::Slider::LinearVertical);
    m_GainSlider.setTextBoxStyle(juce::Slider::TextEntryBoxPosition::TextBoxAbove, true, 60, 20);
    m_GainSlider.setValue(g_paramGain.defaultValue);
	m_GainAttachment = std::make_unique<juce::AudioProcessorValueTreeState::SliderAttachment>(apvts, g_paramGain.ID, m_GainSlider);
	addAndMakeVisible(m_GainSlider);

and the setbounds method

	auto r = getLocalBounds();
	m_GainSlider.setBounds(r);
  1. compile and you have your gain plugin

Some remarks For most parameter it is better to use small synchron blocks (e.g. 2ms) and smooth the update. If you need smoothing on a sample base (like for gains) use applyRamp from the buffer (it is linear, but faster compared to a sample-based smoothing).

(a german video exist to build the Gain)

Second Example EQ (Peak, one band)

The description of this example is very short. You will find the source code on Github (AAT_EQ1)

  1. Solve your math first. You will find the formulas for Equalizer by searching for the "RBJ cookbook".
  2. Understand what a second order section filter is. (LTI System, with 3 transversal (b0,b1,b2) and 2 recursive coefficients (a1,a2))
  3. Build the audio class (3 parameter (Gain, Freq, Q))
  4. Build the GUI (3 rotary knobs)
  5. Done

(videos exist to build the EQ (in German only))

Remarks

For a general solution with more possibilities for Equalizer (cut, shelf), use the given TGMLib / TGMStaticLib

advancedaudiotemplate's People

Contributors

joergbitzer avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.