Compare commits

...

12 Commits

Author SHA1 Message Date
Tim
b5e63d3adf Tabbed editor 2025-11-09 05:28:02 +00:00
Tim
61bcef19aa Add Wavetable Editor 2025-11-08 15:18:05 +00:00
Tim
43b8670d4e Some splitting of code 2025-11-08 00:17:43 +00:00
Tim
c5105693a2 Fixes to the UI 2025-10-26 00:49:50 +01:00
ed
0785f6fedd Upload files to "Source" 2025-10-25 17:57:05 +00:00
ed
430ee53b98 Upload files to "Source" 2025-10-25 17:56:51 +00:00
ed
d9f672cd10 Upload files to "Source" 2025-10-25 17:56:37 +00:00
ed
a43db68120 Upload files to "Source" 2025-10-25 17:56:23 +00:00
ed
7231f66689 Upload files to "Source" 2025-10-25 17:56:12 +00:00
ed
d104e3882e Upload files to "Source" 2025-10-25 17:55:57 +00:00
Roboboffin
3ac2cc15b1 Fix line endings and some cleanup 2025-10-23 04:00:21 +01:00
Roboboffin
24eb354ace Normalize line endings per .gitattributes 2025-10-23 03:59:37 +01:00
144 changed files with 7824 additions and 2581 deletions

39
.gitattributes vendored Normal file
View File

@@ -0,0 +1,39 @@
# Auto-detect text files and normalize to LF in the repo
* text=auto
# Explicit text rules
*.md text
*.txt text
*.json text
*.yml text
*.yaml text
*.toml text
*.c text
*.cpp text
*.h text
*.hpp text
*.rs text
*.py text
*.go text
*.js text
*.ts text
*.css text
*.html text
*.sh text eol=lf # scripts on Unix must be LF
*.bash text eol=lf
# Windows-native scripts that should remain CRLF in working trees
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf
# Binary (never touch line endings)
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.pdf binary
*.zip binary
*.exe binary
*.dll binary
*.glb binary

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
Builds
NeuralSynth Installer.exe
AudioPluginHost
Projucer

19
AGENTS.md Normal file
View File

@@ -0,0 +1,19 @@
# Repository Guidelines
## Project Structure & Module Organization
NeuralSynth is a JUCE-based synthesizer plugin. Core runtime code lives in `Source/`, with `PluginProcessor.*` orchestrating audio/MIDI flow, `PluginEditor.*` driving the UI, `SynthVoice.*` implementing per-voice DSP, and helper headers such as `AudioEngine.h` and `NeuralSharedParams.h` exposing shared state. JUCE-generated scaffolding sits in `JuceLibraryCode/`; regenerate it through `NeuralSynth.jucer` rather than editing by hand. Platform build assets are under `Builds/` (for example `Builds/LinuxMakefile/`), and finished binaries default to `Builds/LinuxMakefile/build/`. Install scripting for Windows lives in `NeuralSynth.iss`.
## Build, Test, and Development Commands
- `cd Builds/LinuxMakefile && make CONFIG=Debug` compiles the standalone app and VST3 with debug symbols.
- `cd Builds/LinuxMakefile && make CONFIG=Release` builds optimized artefacts for distribution.
- `cd Builds/LinuxMakefile && make clean` removes intermediate objects when builds misbehave.
- `./Builds/LinuxMakefile/build/NeuralSynth` launches the standalone target; VST3 binaries appear in `Builds/LinuxMakefile/NeuralSynth.vst3` and copy into `~/.vst3` when the Makefile post-build step runs.
## Coding Style & Naming Conventions
C++ sources use 4-space indentation, brace-on-new-line functions, and JUCEs `juce::` namespace types. Prefer `PascalCase` for classes (e.g., `NeuralSynthAudioProcessor`), camelCase for methods and members (`prepareToPlay`, `audioEngine`), and suffix queues/collectors clearly (`AudioBufferQueue`, `ScopeDataCollector`). Match existing lambda formatting in `SynthVoice.cpp`, keep includes sorted locally, and avoid editing generated files under `JuceLibraryCode/`.
## Testing Guidelines
Automated tests are not yet configured; rely on manual validation in the standalone app or a DAW host. After each change, rebuild and audition key features: oscillator switching, chorus/delay/reverb chains, parameter automation, and MIDI input. For DSP tweaks, monitor the oscilloscope components linked to the buffer queues to confirm signal stability. Document ad-hoc test coverage in your pull request until formal tests are added.
## Commit & Pull Request Guidelines
Follow the existing concise, imperative commit style (`Add chorus modulation`, `Fix voice detune`). Scope each commit to a logical change and format messages as a single summary line. Pull requests should describe the motivation, outline testing performed, and link issues when relevant. Include platform notes (Linux, Windows installer) and screenshots or audio clips for UI-affecting or sonic changes so reviewers can assess impact quickly.

Binary file not shown.

View File

@@ -0,0 +1,52 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
This is the header file that your files should include in order to get all the
JUCE library headers. You should avoid including the JUCE headers directly in
your own source files, because that wouldn't pick up the correct configuration
options for your app.
*/
#pragma once
#include <juce_audio_basics/juce_audio_basics.h>
#include <juce_audio_devices/juce_audio_devices.h>
#include <juce_audio_formats/juce_audio_formats.h>
#include <juce_audio_processors/juce_audio_processors.h>
#include <juce_audio_utils/juce_audio_utils.h>
#include <juce_core/juce_core.h>
#include <juce_data_structures/juce_data_structures.h>
#include <juce_events/juce_events.h>
#include <juce_graphics/juce_graphics.h>
#include <juce_gui_basics/juce_gui_basics.h>
#include <juce_gui_extra/juce_gui_extra.h>
#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION
/** If you've hit this error then the version of the Projucer that was used to generate this project is
older than the version of the JUCE modules being included. To fix this error, re-save your project
using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,
remove the JUCE_PROJUCER_VERSION define.
*/
#error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."
#endif
#if ! DONT_SET_USING_JUCE_NAMESPACE
// If your code uses a lot of JUCE classes, then this will obviously save you
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.
using namespace juce;
#endif
#if ! JUCE_DONT_DECLARE_PROJECTINFO
namespace ProjectInfo
{
const char* const projectName = "MPEIntroductionTutorial";
const char* const companyName = "JUCE";
const char* const versionString = "1.0.0";
const int versionNumber = 0x10000;
}
#endif

View File

@@ -0,0 +1,12 @@
Important Note!!
================
The purpose of this folder is to contain files that are auto-generated by the Projucer,
and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
the Projucer saves your project.
Therefore, it's a bad idea to make any manual changes to the files in here, or to
put any of your own files in here if you don't want to lose them. (Of course you may choose
to add the folder's contents to your version-control system so that you can re-merge your own
modifications after the Projucer has saved its changes).

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_basics/juce_audio_basics.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_basics/juce_audio_basics.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_devices/juce_audio_devices.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_devices/juce_audio_devices.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_formats/juce_audio_formats.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_formats/juce_audio_formats.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors_ara.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors_lv2_libs.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_utils/juce_audio_utils.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_utils/juce_audio_utils.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_core/juce_core.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_core/juce_core.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_core/juce_core_CompilationTime.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_data_structures/juce_data_structures.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_data_structures/juce_data_structures.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_events/juce_events.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_events/juce_events.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_graphics/juce_graphics.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_graphics/juce_graphics.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_graphics/juce_graphics_Harfbuzz.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_graphics/juce_graphics_Sheenbidi.c>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_gui_basics/juce_gui_basics.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_gui_basics/juce_gui_basics.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_gui_extra/juce_gui_extra.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_gui_extra/juce_gui_extra.mm>

View File

@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<JUCERPROJECT name="MPEIntroductionTutorial" companyName="JUCE" version="1.0.0"
userNotes="Synthesiser using MPE specifications." companyWebsite="http://juce.com"
projectType="guiapp" useAppConfig="0" addUsingNamespaceToJuceHeader="1"
id="JGbUDb" jucerFormatVersion="1">
<MAINGROUP id="V9kDzX" name="MPEIntroductionTutorial">
<GROUP id="{DD17E4C5-2693-D5AD-A257-4695D52ED04A}" name="Source">
<FILE id="UcuJ7R" name="Main.cpp" compile="1" resource="0" file="Source/Main.cpp"/>
<FILE id="hNsrsX" name="MPEIntroductionTutorial.h" compile="0" resource="0"
file="Source/MPEIntroductionTutorial.h"/>
</GROUP>
</MAINGROUP>
<MODULES>
<MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_core" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_events" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
</MODULES>
<EXPORTFORMATS>
<LINUX_MAKE targetFolder="Builds/LinuxMakefile">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="MPEIntroductionTutorial"/>
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="MPEIntroductionTutorial"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path=""/>
<MODULEPATH id="juce_audio_devices" path=""/>
<MODULEPATH id="juce_audio_formats" path=""/>
<MODULEPATH id="juce_audio_processors" path=""/>
<MODULEPATH id="juce_audio_utils" path=""/>
<MODULEPATH id="juce_core" path=""/>
<MODULEPATH id="juce_data_structures" path=""/>
<MODULEPATH id="juce_events" path=""/>
<MODULEPATH id="juce_graphics" path=""/>
<MODULEPATH id="juce_gui_basics" path=""/>
<MODULEPATH id="juce_gui_extra" path=""/>
</MODULEPATHS>
</LINUX_MAKE>
</EXPORTFORMATS>
<JUCEOPTIONS/>
</JUCERPROJECT>

View File

@@ -0,0 +1,536 @@
/*
==============================================================================
This file is part of the JUCE tutorials.
Copyright (c) 2020 - Raw Material Software Limited
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,
WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR
PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
/*******************************************************************************
The block below describes the properties of this PIP. A PIP is a short snippet
of code that can be read by the Projucer and used to generate a JUCE project.
BEGIN_JUCE_PIP_METADATA
name: MPEIntroductionTutorial
version: 1.0.0
vendor: JUCE
website: http://juce.com
description: Synthesiser using MPE specifications.
dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats,
juce_audio_processors, juce_audio_utils, juce_core,
juce_data_structures, juce_events, juce_graphics,
juce_gui_basics, juce_gui_extra
exporters: xcode_mac, vs2019, linux_make
type: Component
mainClass: MainComponent
useLocalCopy: 1
END_JUCE_PIP_METADATA
*******************************************************************************/
#pragma once
//==============================================================================
class NoteComponent : public juce::Component
{
public:
NoteComponent (const juce::MPENote& n)
: note (n), colour (juce::Colours::white)
{}
//==============================================================================
void update (const juce::MPENote& newNote, juce::Point<float> newCentre)
{
note = newNote;
centre = newCentre;
setBounds (getSquareAroundCentre (juce::jmax (getNoteOnRadius(), getNoteOffRadius(), getPressureRadius()))
.getUnion (getTextRectangle())
.getSmallestIntegerContainer()
.expanded (3));
repaint();
}
//==============================================================================
void paint (juce::Graphics& g) override
{
if (note.keyState == juce::MPENote::keyDown || note.keyState == juce::MPENote::keyDownAndSustained)
drawPressedNoteCircle (g, colour);
else if (note.keyState == juce::MPENote::sustained)
drawSustainedNoteCircle (g, colour);
else
return;
drawNoteLabel (g, colour);
}
//==============================================================================
juce::MPENote note;
juce::Colour colour;
juce::Point<float> centre;
private:
//==============================================================================
void drawPressedNoteCircle (juce::Graphics& g, juce::Colour zoneColour)
{
g.setColour (zoneColour.withAlpha (0.3f));
g.fillEllipse (translateToLocalBounds (getSquareAroundCentre (getNoteOnRadius())));
g.setColour (zoneColour);
g.drawEllipse (translateToLocalBounds (getSquareAroundCentre (getPressureRadius())), 2.0f);
}
//==============================================================================
void drawSustainedNoteCircle (juce::Graphics& g, juce::Colour zoneColour)
{
g.setColour (zoneColour);
juce::Path circle, dashedCircle;
circle.addEllipse (translateToLocalBounds (getSquareAroundCentre (getNoteOffRadius())));
const float dashLengths[] = { 3.0f, 3.0f };
juce::PathStrokeType (2.0, juce::PathStrokeType::mitered).createDashedStroke (dashedCircle, circle, dashLengths, 2);
g.fillPath (dashedCircle);
}
//==============================================================================
void drawNoteLabel (juce::Graphics& g, juce::Colour)
{
auto textBounds = translateToLocalBounds (getTextRectangle()).getSmallestIntegerContainer();
g.drawText ("+", textBounds, juce::Justification::centred);
g.drawText (juce::MidiMessage::getMidiNoteName (note.initialNote, true, true, 3), textBounds, juce::Justification::centredBottom);
g.setFont (juce::Font (22.0f, juce::Font::bold));
g.drawText (juce::String (note.midiChannel), textBounds, juce::Justification::centredTop);
}
//==============================================================================
juce::Rectangle<float> getSquareAroundCentre (float radius) const noexcept
{
return juce::Rectangle<float> (radius * 2.0f, radius * 2.0f).withCentre (centre);
}
juce::Rectangle<float> translateToLocalBounds (juce::Rectangle<float> r) const noexcept
{
return r - getPosition().toFloat();
}
juce::Rectangle<float> getTextRectangle() const noexcept
{
return juce::Rectangle<float> (30.0f, 50.0f).withCentre (centre);
}
float getNoteOnRadius() const noexcept { return note.noteOnVelocity.asUnsignedFloat() * maxNoteRadius; }
float getNoteOffRadius() const noexcept { return note.noteOffVelocity.asUnsignedFloat() * maxNoteRadius; }
float getPressureRadius() const noexcept { return note.pressure.asUnsignedFloat() * maxNoteRadius; }
static constexpr auto maxNoteRadius = 100.0f;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NoteComponent)
};
//==============================================================================
class Visualiser : public juce::Component,
public juce::MPEInstrument::Listener,
private juce::AsyncUpdater
{
public:
//==============================================================================
Visualiser() {}
//==============================================================================
void paint (juce::Graphics& g) override
{
g.fillAll (juce::Colours::black);
auto noteDistance = float (getWidth()) / 128;
for (auto i = 0; i < 128; ++i)
{
auto x = noteDistance * (float) i;
auto noteHeight = int (juce::MidiMessage::isMidiNoteBlack (i) ? 0.7 * getHeight() : getHeight());
g.setColour (juce::MidiMessage::isMidiNoteBlack (i) ? juce::Colours::white : juce::Colours::grey);
g.drawLine (x, 0.0f, x, (float) noteHeight);
if (i > 0 && i % 12 == 0)
{
g.setColour (juce::Colours::grey);
auto octaveNumber = (i / 12) - 2;
g.drawText ("C" + juce::String (octaveNumber), (int) x - 15, getHeight() - 30, 30, 30, juce::Justification::centredBottom);
}
}
}
//==============================================================================
void noteAdded (juce::MPENote newNote) override
{
const juce::ScopedLock sl (lock);
activeNotes.add (newNote);
triggerAsyncUpdate();
}
void notePressureChanged (juce::MPENote note) override { noteChanged (note); }
void notePitchbendChanged (juce::MPENote note) override { noteChanged (note); }
void noteTimbreChanged (juce::MPENote note) override { noteChanged (note); }
void noteKeyStateChanged (juce::MPENote note) override { noteChanged (note); }
void noteChanged (juce::MPENote changedNote)
{
const juce::ScopedLock sl (lock);
for (auto& note : activeNotes)
if (note.noteID == changedNote.noteID)
note = changedNote;
triggerAsyncUpdate();
}
void noteReleased (juce::MPENote finishedNote) override
{
const juce::ScopedLock sl (lock);
for (auto i = activeNotes.size(); --i >= 0;)
if (activeNotes.getReference(i).noteID == finishedNote.noteID)
activeNotes.remove (i);
triggerAsyncUpdate();
}
private:
//==============================================================================
const juce::MPENote* findActiveNote (int noteID) const noexcept
{
for (auto& note : activeNotes)
if (note.noteID == noteID)
return &note;
return nullptr;
}
NoteComponent* findNoteComponent (int noteID) const noexcept
{
for (auto& noteComp : noteComponents)
if (noteComp->note.noteID == noteID)
return noteComp;
return nullptr;
}
//==============================================================================
void handleAsyncUpdate() override
{
const juce::ScopedLock sl (lock);
for (auto i = noteComponents.size(); --i >= 0;)
if (findActiveNote (noteComponents.getUnchecked(i)->note.noteID) == nullptr)
noteComponents.remove (i);
for (auto& note : activeNotes)
if (findNoteComponent (note.noteID) == nullptr)
addAndMakeVisible (noteComponents.add (new NoteComponent (note)));
for (auto& noteComp : noteComponents)
if (auto* noteInfo = findActiveNote (noteComp->note.noteID))
noteComp->update (*noteInfo, getCentrePositionForNote (*noteInfo));
}
//==============================================================================
juce::Point<float> getCentrePositionForNote (juce::MPENote note) const
{
auto n = float (note.initialNote) + float (note.totalPitchbendInSemitones);
auto x = (float) getWidth() * n / 128;
auto y = (float) getHeight() * (1 - note.timbre.asUnsignedFloat());
return { x, y };
}
//==============================================================================
juce::OwnedArray<NoteComponent> noteComponents;
juce::CriticalSection lock;
juce::Array<juce::MPENote> activeNotes;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Visualiser)
};
//==============================================================================
class MPEDemoSynthVoice : public juce::MPESynthesiserVoice
{
public:
//==============================================================================
MPEDemoSynthVoice() {}
//==============================================================================
void noteStarted() override
{
jassert (currentlyPlayingNote.isValid());
jassert (currentlyPlayingNote.keyState == juce::MPENote::keyDown
|| currentlyPlayingNote.keyState == juce::MPENote::keyDownAndSustained);
// get data from the current MPENote
level .setTargetValue (currentlyPlayingNote.pressure.asUnsignedFloat());
frequency.setTargetValue (currentlyPlayingNote.getFrequencyInHertz());
timbre .setTargetValue (currentlyPlayingNote.timbre.asUnsignedFloat());
phase = 0.0;
auto cyclesPerSample = frequency.getNextValue() / currentSampleRate;
phaseDelta = 2.0 * juce::MathConstants<double>::pi * cyclesPerSample;
tailOff = 0.0;
}
void noteStopped (bool allowTailOff) override
{
jassert (currentlyPlayingNote.keyState == juce::MPENote::off);
if (allowTailOff)
{
// start a tail-off by setting this flag. The render callback will pick up on
// this and do a fade out, calling clearCurrentNote() when it's finished.
if (tailOff == 0.0) // we only need to begin a tail-off if it's not already doing so - the
// stopNote method could be called more than once.
tailOff = 1.0;
}
else
{
// we're being told to stop playing immediately, so reset everything..
clearCurrentNote();
phaseDelta = 0.0;
}
}
void notePressureChanged() override
{
level.setTargetValue (currentlyPlayingNote.pressure.asUnsignedFloat());
}
void notePitchbendChanged() override
{
frequency.setTargetValue (currentlyPlayingNote.getFrequencyInHertz());
}
void noteTimbreChanged() override
{
timbre.setTargetValue (currentlyPlayingNote.timbre.asUnsignedFloat());
}
void noteKeyStateChanged() override {}
void setCurrentSampleRate (double newRate) override
{
if (! juce::approximatelyEqual (currentSampleRate, newRate))
{
noteStopped (false);
currentSampleRate = newRate;
level .reset (currentSampleRate, smoothingLengthInSeconds);
timbre .reset (currentSampleRate, smoothingLengthInSeconds);
frequency.reset (currentSampleRate, smoothingLengthInSeconds);
}
}
//==============================================================================
void renderNextBlock (juce::AudioBuffer<float>& outputBuffer,
int startSample,
int numSamples) override
{
if (phaseDelta != 0.0)
{
if (tailOff > 0.0)
{
while (--numSamples >= 0)
{
auto currentSample = getNextSample() * (float) tailOff;
for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
outputBuffer.addSample (i, startSample, currentSample);
++startSample;
tailOff *= 0.99;
if (tailOff <= 0.005)
{
clearCurrentNote();
phaseDelta = 0.0;
break;
}
}
}
else
{
while (--numSamples >= 0)
{
auto currentSample = getNextSample();
for (auto i = outputBuffer.getNumChannels(); --i >= 0;)
outputBuffer.addSample (i, startSample, currentSample);
++startSample;
}
}
}
}
private:
//==============================================================================
float getNextSample() noexcept
{
auto levelDb = (level.getNextValue() - 1.0) * maxLevelDb;
auto amplitude = std::pow (10.0f, 0.05f * levelDb) * maxLevel;
// timbre is used to blend between a sine and a square.
auto f1 = std::sin (phase);
auto f2 = std::copysign (1.0, f1);
auto a2 = timbre.getNextValue();
auto a1 = 1.0 - a2;
auto nextSample = float (amplitude * ((a1 * f1) + (a2 * f2)));
auto cyclesPerSample = frequency.getNextValue() / currentSampleRate;
phaseDelta = 2.0 * juce::MathConstants<double>::pi * cyclesPerSample;
phase = std::fmod (phase + phaseDelta, 2.0 * juce::MathConstants<double>::pi);
return nextSample;
}
//==============================================================================
juce::SmoothedValue<double> level, timbre, frequency;
double phase = 0.0;
double phaseDelta = 0.0;
double tailOff = 0.0;
// some useful constants
static constexpr auto maxLevel = 0.05;
static constexpr auto maxLevelDb = 31.0;
static constexpr auto smoothingLengthInSeconds = 0.01;
};
//==============================================================================
class MainComponent : public juce::Component,
private juce::AudioIODeviceCallback, // [1]
private juce::MidiInputCallback // [2]
{
public:
//==============================================================================
MainComponent()
: audioSetupComp (audioDeviceManager, 0, 0, 0, 256,
true, // showMidiInputOptions must be true
true, true, false)
{
audioDeviceManager.initialise (0, 2, nullptr, true, {}, nullptr);
audioDeviceManager.addMidiInputDeviceCallback ({}, this); // [6]
audioDeviceManager.addAudioCallback (this);
addAndMakeVisible (audioSetupComp);
addAndMakeVisible (visualiserViewport);
visualiserViewport.setScrollBarsShown (false, true);
visualiserViewport.setViewedComponent (&visualiserComp, false);
visualiserViewport.setViewPositionProportionately (0.5, 0.0);
visualiserInstrument.addListener (&visualiserComp);
for (auto i = 0; i < 15; ++i)
synth.addVoice (new MPEDemoSynthVoice());
synth.enableLegacyMode (24);
synth.setVoiceStealingEnabled (false);
visualiserInstrument.enableLegacyMode (24);
setSize (650, 560);
}
~MainComponent() override
{
audioDeviceManager.removeMidiInputDeviceCallback ({}, this);
audioDeviceManager.removeAudioCallback (this);
}
//==============================================================================
void resized() override
{
auto visualiserCompWidth = 2800;
auto visualiserCompHeight = 300;
auto r = getLocalBounds();
visualiserViewport.setBounds (r.removeFromBottom (visualiserCompHeight));
visualiserComp.setBounds ({ visualiserCompWidth,
visualiserViewport.getHeight() - visualiserViewport.getScrollBarThickness() });
audioSetupComp.setBounds (r);
}
//==============================================================================
void audioDeviceIOCallbackWithContext (const float* const* /*inputChannelData*/,
int /*numInputChannels*/,
float* const* outputChannelData,
int numOutputChannels,
int numSamples,
const juce::AudioIODeviceCallbackContext& /*context*/) override
{
// make buffer
juce::AudioBuffer<float> buffer (outputChannelData, numOutputChannels, numSamples);
// clear it to silence
buffer.clear();
juce::MidiBuffer incomingMidi;
// get the MIDI messages for this audio block
midiCollector.removeNextBlockOfMessages (incomingMidi, numSamples);
// synthesise the block
synth.renderNextBlock (buffer, incomingMidi, 0, numSamples);
}
void audioDeviceAboutToStart (juce::AudioIODevice* device) override
{
auto sampleRate = device->getCurrentSampleRate();
midiCollector.reset (sampleRate);
synth.setCurrentPlaybackSampleRate (sampleRate);
}
void audioDeviceStopped() override {}
private:
//==============================================================================
void handleIncomingMidiMessage (juce::MidiInput* /*source*/,
const juce::MidiMessage& message) override
{
visualiserInstrument.processNextMidiEvent (message);
midiCollector.addMessageToQueue (message);
}
//==============================================================================
juce::AudioDeviceManager audioDeviceManager; // [3]
juce::AudioDeviceSelectorComponent audioSetupComp; // [4]
Visualiser visualiserComp;
juce::Viewport visualiserViewport;
juce::MPEInstrument visualiserInstrument;
juce::MPESynthesiser synth;
juce::MidiMessageCollector midiCollector; // [5]
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};

View File

@@ -0,0 +1,96 @@
/*
==============================================================================
This file contains the startup code for a PIP.
==============================================================================
*/
#include <JuceHeader.h>
#include "MPEIntroductionTutorial.h"
class Application : public juce::JUCEApplication
{
public:
//==============================================================================
Application() = default;
const juce::String getApplicationName() override { return "MPEIntroductionTutorial"; }
const juce::String getApplicationVersion() override { return "1.0.0"; }
void initialise (const juce::String&) override
{
mainWindow.reset (new MainWindow ("MPEIntroductionTutorial", std::make_unique<MainComponent>(), *this));
}
void shutdown() override { mainWindow = nullptr; }
private:
class MainWindow : public juce::DocumentWindow
{
public:
MainWindow (const juce::String& name, std::unique_ptr<juce::Component> c, JUCEApplication& a)
: DocumentWindow (name, juce::Desktop::getInstance().getDefaultLookAndFeel()
.findColour (ResizableWindow::backgroundColourId),
juce::DocumentWindow::allButtons),
app (a)
{
setUsingNativeTitleBar (true);
#if JUCE_ANDROID || JUCE_IOS
setContentOwned (new SafeAreaComponent { std::move (c) }, true);
setFullScreen (true);
#else
setContentOwned (c.release(), true);
setResizable (true, false);
setResizeLimits (300, 250, 10000, 10000);
centreWithSize (getWidth(), getHeight());
#endif
setVisible (true);
}
void closeButtonPressed() override
{
app.systemRequestedQuit();
}
#if JUCE_ANDROID || JUCE_IOS
class SafeAreaComponent : public juce::Component
{
public:
explicit SafeAreaComponent (std::unique_ptr<Component> c)
: content (std::move (c))
{
addAndMakeVisible (*content);
}
void resized() override
{
if (const auto* d = Desktop::getInstance().getDisplays().getDisplayForRect (getLocalBounds()))
content->setBounds (d->safeAreaInsets.subtractedFrom (getLocalBounds()));
}
private:
std::unique_ptr<Component> content;
};
void parentSizeChanged() override
{
if (auto* c = getContentComponent())
c->resized();
}
#endif
private:
JUCEApplication& app;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
};
std::unique_ptr<MainWindow> mainWindow;
};
//==============================================================================
START_JUCE_APPLICATION (Application)

Binary file not shown.

View File

@@ -0,0 +1,52 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
This is the header file that your files should include in order to get all the
JUCE library headers. You should avoid including the JUCE headers directly in
your own source files, because that wouldn't pick up the correct configuration
options for your app.
*/
#pragma once
#include <juce_audio_basics/juce_audio_basics.h>
#include <juce_audio_devices/juce_audio_devices.h>
#include <juce_audio_formats/juce_audio_formats.h>
#include <juce_audio_processors/juce_audio_processors.h>
#include <juce_audio_utils/juce_audio_utils.h>
#include <juce_core/juce_core.h>
#include <juce_data_structures/juce_data_structures.h>
#include <juce_events/juce_events.h>
#include <juce_graphics/juce_graphics.h>
#include <juce_gui_basics/juce_gui_basics.h>
#include <juce_gui_extra/juce_gui_extra.h>
#if defined (JUCE_PROJUCER_VERSION) && JUCE_PROJUCER_VERSION < JUCE_VERSION
/** If you've hit this error then the version of the Projucer that was used to generate this project is
older than the version of the JUCE modules being included. To fix this error, re-save your project
using the latest version of the Projucer or, if you aren't using the Projucer to manage your project,
remove the JUCE_PROJUCER_VERSION define.
*/
#error "This project was last saved using an outdated version of the Projucer! Re-save this project with the latest version to fix this error."
#endif
#if ! DONT_SET_USING_JUCE_NAMESPACE
// If your code uses a lot of JUCE classes, then this will obviously save you
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE.
using namespace juce;
#endif
#if ! JUCE_DONT_DECLARE_PROJECTINFO
namespace ProjectInfo
{
const char* const projectName = "WavetableSynthTutorial";
const char* const companyName = "JUCE";
const char* const versionString = "1.0.0";
const int versionNumber = 0x10000;
}
#endif

View File

@@ -0,0 +1,12 @@
Important Note!!
================
The purpose of this folder is to contain files that are auto-generated by the Projucer,
and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
the Projucer saves your project.
Therefore, it's a bad idea to make any manual changes to the files in here, or to
put any of your own files in here if you don't want to lose them. (Of course you may choose
to add the folder's contents to your version-control system so that you can re-merge your own
modifications after the Projucer has saved its changes).

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_basics/juce_audio_basics.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_basics/juce_audio_basics.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_devices/juce_audio_devices.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_devices/juce_audio_devices.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_formats/juce_audio_formats.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_formats/juce_audio_formats.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors_ara.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors_lv2_libs.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_utils/juce_audio_utils.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_utils/juce_audio_utils.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_core/juce_core.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_core/juce_core.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_core/juce_core_CompilationTime.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_data_structures/juce_data_structures.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_data_structures/juce_data_structures.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_events/juce_events.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_events/juce_events.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_graphics/juce_graphics.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_graphics/juce_graphics.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_graphics/juce_graphics_Harfbuzz.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_graphics/juce_graphics_Sheenbidi.c>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_gui_basics/juce_gui_basics.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_gui_basics/juce_gui_basics.mm>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_gui_extra/juce_gui_extra.cpp>

View File

@@ -0,0 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_gui_extra/juce_gui_extra.mm>

View File

@@ -0,0 +1,96 @@
/*
==============================================================================
This file contains the startup code for a PIP.
==============================================================================
*/
#include <JuceHeader.h>
#include "WavetableSynthTutorial_01.h"
class Application : public juce::JUCEApplication
{
public:
//==============================================================================
Application() = default;
const juce::String getApplicationName() override { return "WavetableSynthTutorial"; }
const juce::String getApplicationVersion() override { return "1.0.0"; }
void initialise (const juce::String&) override
{
mainWindow.reset (new MainWindow ("WavetableSynthTutorial", std::make_unique<MainContentComponent>(), *this));
}
void shutdown() override { mainWindow = nullptr; }
private:
class MainWindow : public juce::DocumentWindow
{
public:
MainWindow (const juce::String& name, std::unique_ptr<juce::Component> c, JUCEApplication& a)
: DocumentWindow (name, juce::Desktop::getInstance().getDefaultLookAndFeel()
.findColour (ResizableWindow::backgroundColourId),
juce::DocumentWindow::allButtons),
app (a)
{
setUsingNativeTitleBar (true);
#if JUCE_ANDROID || JUCE_IOS
setContentOwned (new SafeAreaComponent { std::move (c) }, true);
setFullScreen (true);
#else
setContentOwned (c.release(), true);
setResizable (true, false);
setResizeLimits (300, 250, 10000, 10000);
centreWithSize (getWidth(), getHeight());
#endif
setVisible (true);
}
void closeButtonPressed() override
{
app.systemRequestedQuit();
}
#if JUCE_ANDROID || JUCE_IOS
class SafeAreaComponent : public juce::Component
{
public:
explicit SafeAreaComponent (std::unique_ptr<Component> c)
: content (std::move (c))
{
addAndMakeVisible (*content);
}
void resized() override
{
if (const auto* d = Desktop::getInstance().getDisplays().getDisplayForRect (getLocalBounds()))
content->setBounds (d->safeAreaInsets.subtractedFrom (getLocalBounds()));
}
private:
std::unique_ptr<Component> content;
};
void parentSizeChanged() override
{
if (auto* c = getContentComponent())
c->resized();
}
#endif
private:
JUCEApplication& app;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
};
std::unique_ptr<MainWindow> mainWindow;
};
//==============================================================================
START_JUCE_APPLICATION (Application)

View File

@@ -0,0 +1,163 @@
/*
==============================================================================
This file is part of the JUCE tutorials.
Copyright (c) 2020 - Raw Material Software Limited
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,
WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR
PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
/*******************************************************************************
The block below describes the properties of this PIP. A PIP is a short snippet
of code that can be read by the Projucer and used to generate a JUCE project.
BEGIN_JUCE_PIP_METADATA
name: WavetableSynthTutorial
version: 1.0.0
vendor: JUCE
website: http://juce.com
description: Wavetable synthesiser.
dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats,
juce_audio_processors, juce_audio_utils, juce_core,
juce_data_structures, juce_events, juce_graphics,
juce_gui_basics, juce_gui_extra
exporters: xcode_mac, vs2019, linux_make
type: Component
mainClass: MainContentComponent
useLocalCopy: 1
END_JUCE_PIP_METADATA
*******************************************************************************/
#pragma once
//==============================================================================
class SineOscillator
{
public:
SineOscillator() {}
void setFrequency (float frequency, float sampleRate)
{
auto cyclesPerSample = frequency / sampleRate;
angleDelta = cyclesPerSample * juce::MathConstants<float>::twoPi;
}
forcedinline void updateAngle() noexcept
{
currentAngle += angleDelta;
if (currentAngle >= juce::MathConstants<float>::twoPi)
currentAngle -= juce::MathConstants<float>::twoPi;
}
forcedinline float getNextSample() noexcept
{
auto currentSample = std::sin (currentAngle);
updateAngle();
return currentSample;
}
private:
float currentAngle = 0.0f, angleDelta = 0.0f;
};
//==============================================================================
class MainContentComponent : public juce::AudioAppComponent,
public juce::Timer
{
public:
MainContentComponent()
{
cpuUsageLabel.setText ("CPU Usage", juce::dontSendNotification);
cpuUsageText.setJustificationType (juce::Justification::right);
addAndMakeVisible (cpuUsageLabel);
addAndMakeVisible (cpuUsageText);
setSize (400, 200);
setAudioChannels (0, 2); // no inputs, two outputs
startTimer (50);
}
~MainContentComponent() override
{
shutdownAudio();
}
void resized() override
{
cpuUsageLabel.setBounds (10, 10, getWidth() - 20, 20);
cpuUsageText .setBounds (10, 10, getWidth() - 20, 20);
}
void timerCallback() override
{
auto cpu = deviceManager.getCpuUsage() * 100;
cpuUsageText.setText (juce::String (cpu, 6) + " %", juce::dontSendNotification);
}
void prepareToPlay (int, double sampleRate) override
{
auto numberOfOscillators = 200; // [1]
for (auto i = 0; i < numberOfOscillators; ++i)
{
auto* oscillator = new SineOscillator(); // [2]
auto midiNote = juce::Random::getSystemRandom().nextDouble() * 36.0 + 48.0; // [3]
auto frequency = 440.0 * pow (2.0, (midiNote - 69.0) / 12.0); // [4]
oscillator->setFrequency ((float) frequency, (float) sampleRate); // [5]
oscillators.add (oscillator);
}
level = 0.25f / (float) numberOfOscillators; // [6]
}
void releaseResources() override {}
void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override
{
auto* leftBuffer = bufferToFill.buffer->getWritePointer (0, bufferToFill.startSample); // [7]
auto* rightBuffer = bufferToFill.buffer->getWritePointer (1, bufferToFill.startSample);
bufferToFill.clearActiveBufferRegion();
for (auto oscillatorIndex = 0; oscillatorIndex < oscillators.size(); ++oscillatorIndex)
{
auto* oscillator = oscillators.getUnchecked (oscillatorIndex); // [8]
for (auto sample = 0; sample < bufferToFill.numSamples; ++sample)
{
auto levelSample = oscillator->getNextSample() * level; // [9]
leftBuffer[sample] += levelSample; // [10]
rightBuffer[sample] += levelSample;
}
}
}
private:
juce::Label cpuUsageLabel;
juce::Label cpuUsageText;
float level = 0.0f;
juce::OwnedArray<SineOscillator> oscillators;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

View File

@@ -0,0 +1,196 @@
/*
==============================================================================
This file is part of the JUCE tutorials.
Copyright (c) 2020 - Raw Material Software Limited
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,
WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR
PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
/*******************************************************************************
The block below describes the properties of this PIP. A PIP is a short snippet
of code that can be read by the Projucer and used to generate a JUCE project.
BEGIN_JUCE_PIP_METADATA
name: WavetableSynthTutorial
version: 2.0.0
vendor: JUCE
website: http://juce.com
description: Wavetable synthesiser.
dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats,
juce_audio_processors, juce_audio_utils, juce_core,
juce_data_structures, juce_events, juce_graphics,
juce_gui_basics, juce_gui_extra
exporters: xcode_mac, vs2019, linux_make
type: Component
mainClass: MainContentComponent
useLocalCopy: 1
END_JUCE_PIP_METADATA
*******************************************************************************/
#pragma once
//==============================================================================
class WavetableOscillator
{
public:
WavetableOscillator (const juce::AudioSampleBuffer& wavetableToUse)
: wavetable (wavetableToUse)
{
jassert (wavetable.getNumChannels() == 1);
}
void setFrequency (float frequency, float sampleRate)
{
auto tableSizeOverSampleRate = (float) wavetable.getNumSamples() / sampleRate;
tableDelta = frequency * tableSizeOverSampleRate;
}
forcedinline float getNextSample() noexcept
{
auto tableSize = (unsigned int) wavetable.getNumSamples();
auto index0 = (unsigned int) currentIndex; // [6]
auto index1 = index0 == (tableSize - 1) ? (unsigned int) 0 : index0 + 1;
auto frac = currentIndex - (float) index0; // [7]
auto* table = wavetable.getReadPointer (0); // [8]
auto value0 = table[index0];
auto value1 = table[index1];
auto currentSample = value0 + frac * (value1 - value0); // [9]
if ((currentIndex += tableDelta) > (float) tableSize) // [10]
currentIndex -= (float) tableSize;
return currentSample;
}
private:
const juce::AudioSampleBuffer& wavetable;
float currentIndex = 0.0f, tableDelta = 0.0f;
};
//==============================================================================
class MainContentComponent : public juce::AudioAppComponent,
public juce::Timer
{
public:
MainContentComponent()
{
cpuUsageLabel.setText ("CPU Usage", juce::dontSendNotification);
cpuUsageText.setJustificationType (juce::Justification::right);
addAndMakeVisible (cpuUsageLabel);
addAndMakeVisible (cpuUsageText);
createWavetable();
setSize (400, 200);
setAudioChannels (0, 2); // no inputs, two outputs
startTimer (50);
}
~MainContentComponent() override
{
shutdownAudio();
}
void resized() override
{
cpuUsageLabel.setBounds (10, 10, getWidth() - 20, 20);
cpuUsageText .setBounds (10, 10, getWidth() - 20, 20);
}
void timerCallback() override
{
auto cpu = deviceManager.getCpuUsage() * 100;
cpuUsageText.setText (juce::String (cpu, 6) + " %", juce::dontSendNotification);
}
void createWavetable()
{
sineTable.setSize (1, (int) tableSize);
auto* samples = sineTable.getWritePointer (0); // [3]
auto angleDelta = juce::MathConstants<double>::twoPi / (double) (tableSize - 1); // [4]
auto currentAngle = 0.0;
for (unsigned int i = 0; i < tableSize; ++i)
{
auto sample = std::sin (currentAngle); // [5]
samples[i] = (float) sample;
currentAngle += angleDelta;
}
}
void prepareToPlay (int, double sampleRate) override
{
auto numberOfOscillators = 200;
for (auto i = 0; i < numberOfOscillators; ++i)
{
auto* oscillator = new WavetableOscillator (sineTable);
auto midiNote = juce::Random::getSystemRandom().nextDouble() * 36.0 + 48.0;
auto frequency = 440.0 * pow (2.0, (midiNote - 69.0) / 12.0);
oscillator->setFrequency ((float) frequency, (float) sampleRate);
oscillators.add (oscillator);
}
level = 0.25f / (float) numberOfOscillators;
}
void releaseResources() override {}
void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override
{
auto* leftBuffer = bufferToFill.buffer->getWritePointer (0, bufferToFill.startSample);
auto* rightBuffer = bufferToFill.buffer->getWritePointer (1, bufferToFill.startSample);
bufferToFill.clearActiveBufferRegion();
for (auto oscillatorIndex = 0; oscillatorIndex < oscillators.size(); ++oscillatorIndex)
{
auto* oscillator = oscillators.getUnchecked (oscillatorIndex);
for (auto sample = 0; sample < bufferToFill.numSamples; ++sample)
{
auto levelSample = oscillator->getNextSample() * level;
leftBuffer[sample] += levelSample;
rightBuffer[sample] += levelSample;
}
}
}
private:
juce::Label cpuUsageLabel;
juce::Label cpuUsageText;
const unsigned int tableSize = 1 << 7; // [2]
float level = 0.0f;
juce::AudioSampleBuffer sineTable; // [1]
juce::OwnedArray<WavetableOscillator> oscillators;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

View File

@@ -0,0 +1,198 @@
/*
==============================================================================
This file is part of the JUCE tutorials.
Copyright (c) 2020 - Raw Material Software Limited
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,
WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR
PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
/*******************************************************************************
The block below describes the properties of this PIP. A PIP is a short snippet
of code that can be read by the Projucer and used to generate a JUCE project.
BEGIN_JUCE_PIP_METADATA
name: WavetableSynthTutorial
version: 3.0.0
vendor: JUCE
website: http://juce.com
description: Wavetable synthesiser.
dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats,
juce_audio_processors, juce_audio_utils, juce_core,
juce_data_structures, juce_events, juce_graphics,
juce_gui_basics, juce_gui_extra
exporters: xcode_mac, vs2019, linux_make
type: Component
mainClass: MainContentComponent
useLocalCopy: 1
END_JUCE_PIP_METADATA
*******************************************************************************/
#pragma once
//==============================================================================
class WavetableOscillator
{
public:
WavetableOscillator (const juce::AudioSampleBuffer& wavetableToUse)
: wavetable (wavetableToUse),
tableSize (wavetable.getNumSamples() - 1)
{
jassert (wavetable.getNumChannels() == 1);
}
void setFrequency (float frequency, float sampleRate)
{
auto tableSizeOverSampleRate = (float) tableSize / sampleRate;
tableDelta = frequency * tableSizeOverSampleRate;
}
forcedinline float getNextSample() noexcept
{
auto index0 = (unsigned int) currentIndex;
auto index1 = index0 + 1;
auto frac = currentIndex - (float) index0;
auto* table = wavetable.getReadPointer (0);
auto value0 = table[index0];
auto value1 = table[index1];
auto currentSample = value0 + frac * (value1 - value0);
if ((currentIndex += tableDelta) > (float) tableSize)
currentIndex -= (float) tableSize;
return currentSample;
}
private:
const juce::AudioSampleBuffer& wavetable;
const int tableSize;
float currentIndex = 0.0f, tableDelta = 0.0f;
};
//==============================================================================
class MainContentComponent : public juce::AudioAppComponent,
public juce::Timer
{
public:
MainContentComponent()
{
cpuUsageLabel.setText ("CPU Usage", juce::dontSendNotification);
cpuUsageText.setJustificationType (juce::Justification::right);
addAndMakeVisible (cpuUsageLabel);
addAndMakeVisible (cpuUsageText);
createWavetable();
setSize (400, 200);
setAudioChannels (0, 2); // no inputs, two outputs
startTimer (50);
}
~MainContentComponent() override
{
shutdownAudio();
}
void resized() override
{
cpuUsageLabel.setBounds (10, 10, getWidth() - 20, 20);
cpuUsageText .setBounds (10, 10, getWidth() - 20, 20);
}
void timerCallback() override
{
auto cpu = deviceManager.getCpuUsage() * 100;
cpuUsageText.setText (juce::String (cpu, 6) + " %", juce::dontSendNotification);
}
void createWavetable()
{
sineTable.setSize (1, (int) tableSize + 1);
auto* samples = sineTable.getWritePointer (0);
auto angleDelta = juce::MathConstants<double>::twoPi / (double) (tableSize - 1);
auto currentAngle = 0.0;
for (unsigned int i = 0; i < tableSize; ++i)
{
auto sample = std::sin (currentAngle);
samples[i] = (float) sample;
currentAngle += angleDelta;
}
samples[tableSize] = samples[0];
}
void prepareToPlay (int, double sampleRate) override
{
auto numberOfOscillators = 200;
for (auto i = 0; i < numberOfOscillators; ++i)
{
auto* oscillator = new WavetableOscillator (sineTable);
auto midiNote = juce::Random::getSystemRandom().nextDouble() * 36.0 + 48.0;
auto frequency = 440.0 * pow (2.0, (midiNote - 69.0) / 12.0);
oscillator->setFrequency ((float) frequency, (float) sampleRate);
oscillators.add (oscillator);
}
level = 0.25f / (float) numberOfOscillators;
}
void releaseResources() override {}
void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override
{
auto* leftBuffer = bufferToFill.buffer->getWritePointer (0, bufferToFill.startSample);
auto* rightBuffer = bufferToFill.buffer->getWritePointer (1, bufferToFill.startSample);
bufferToFill.clearActiveBufferRegion();
for (auto oscillatorIndex = 0; oscillatorIndex < oscillators.size(); ++oscillatorIndex)
{
auto* oscillator = oscillators.getUnchecked (oscillatorIndex);
for (auto sample = 0; sample < bufferToFill.numSamples; ++sample)
{
auto levelSample = oscillator->getNextSample() * level;
leftBuffer[sample] += levelSample;
rightBuffer[sample] += levelSample;
}
}
}
private:
juce::Label cpuUsageLabel;
juce::Label cpuUsageText;
const unsigned int tableSize = 1 << 7;
float level = 0.0f;
juce::AudioSampleBuffer sineTable;
juce::OwnedArray<WavetableOscillator> oscillators;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

View File

@@ -0,0 +1,208 @@
/*
==============================================================================
This file is part of the JUCE tutorials.
Copyright (c) 2020 - Raw Material Software Limited
The code included in this file is provided under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license. Permission
To use, copy, modify, and/or distribute this software for any purpose with or
without fee is hereby granted provided that the above copyright notice and
this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES,
WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR
PURPOSE, ARE DISCLAIMED.
==============================================================================
*/
/*******************************************************************************
The block below describes the properties of this PIP. A PIP is a short snippet
of code that can be read by the Projucer and used to generate a JUCE project.
BEGIN_JUCE_PIP_METADATA
name: WavetableSynthTutorial
version: 4.0.0
vendor: JUCE
website: http://juce.com
description: Wavetable synthesiser.
dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats,
juce_audio_processors, juce_audio_utils, juce_core,
juce_data_structures, juce_events, juce_graphics,
juce_gui_basics, juce_gui_extra
exporters: xcode_mac, vs2019, linux_make
type: Component
mainClass: MainContentComponent
useLocalCopy: 1
END_JUCE_PIP_METADATA
*******************************************************************************/
#pragma once
//==============================================================================
class WavetableOscillator
{
public:
WavetableOscillator (const juce::AudioSampleBuffer& wavetableToUse)
: wavetable (wavetableToUse),
tableSize (wavetable.getNumSamples() - 1)
{
jassert (wavetable.getNumChannels() == 1);
}
void setFrequency (float frequency, float sampleRate)
{
auto tableSizeOverSampleRate = (float) tableSize / sampleRate;
tableDelta = frequency * tableSizeOverSampleRate;
}
forcedinline float getNextSample() noexcept
{
auto index0 = (unsigned int) currentIndex;
auto index1 = index0 + 1;
auto frac = currentIndex - (float) index0;
auto* table = wavetable.getReadPointer (0);
auto value0 = table[index0];
auto value1 = table[index1];
auto currentSample = value0 + frac * (value1 - value0);
if ((currentIndex += tableDelta) > (float) tableSize)
currentIndex -= (float) tableSize;
return currentSample;
}
private:
const juce::AudioSampleBuffer& wavetable;
const int tableSize;
float currentIndex = 0.0f, tableDelta = 0.0f;
};
//==============================================================================
class MainContentComponent : public juce::AudioAppComponent,
public juce::Timer
{
public:
MainContentComponent()
{
cpuUsageLabel.setText ("CPU Usage", juce::dontSendNotification);
cpuUsageText.setJustificationType (juce::Justification::right);
addAndMakeVisible (cpuUsageLabel);
addAndMakeVisible (cpuUsageText);
createWavetable();
setSize (400, 200);
setAudioChannels (0, 2); // no inputs, two outputs
startTimer (50);
}
~MainContentComponent() override
{
shutdownAudio();
}
void resized() override
{
cpuUsageLabel.setBounds (10, 10, getWidth() - 20, 20);
cpuUsageText .setBounds (10, 10, getWidth() - 20, 20);
}
void timerCallback() override
{
auto cpu = deviceManager.getCpuUsage() * 100;
cpuUsageText.setText (juce::String (cpu, 6) + " %", juce::dontSendNotification);
}
void createWavetable()
{
sineTable.setSize (1, (int) tableSize + 1);
sineTable.clear();
auto* samples = sineTable.getWritePointer (0);
int harmonics[] = { 1, 3, 5, 6, 7, 9, 13, 15 };
float harmonicWeights[] = { 0.5f, 0.1f, 0.05f, 0.125f, 0.09f, 0.005f, 0.002f, 0.001f }; // [1]
jassert (juce::numElementsInArray (harmonics) == juce::numElementsInArray (harmonicWeights));
for (auto harmonic = 0; harmonic < juce::numElementsInArray (harmonics); ++harmonic)
{
auto angleDelta = juce::MathConstants<double>::twoPi / (double) (tableSize - 1) * harmonics[harmonic]; // [2]
auto currentAngle = 0.0;
for (unsigned int i = 0; i < tableSize; ++i)
{
auto sample = std::sin (currentAngle);
samples[i] += (float) sample * harmonicWeights[harmonic]; // [3]
currentAngle += angleDelta;
}
}
samples[tableSize] = samples[0];
}
void prepareToPlay (int, double sampleRate) override
{
auto numberOfOscillators = 10;
for (auto i = 0; i < numberOfOscillators; ++i)
{
auto* oscillator = new WavetableOscillator (sineTable);
auto midiNote = juce::Random::getSystemRandom().nextDouble() * 36.0 + 48.0;
auto frequency = 440.0 * pow (2.0, (midiNote - 69.0) / 12.0);
oscillator->setFrequency ((float) frequency, (float) sampleRate);
oscillators.add (oscillator);
}
level = 0.25f / (float) numberOfOscillators;
}
void releaseResources() override {}
void getNextAudioBlock (const juce::AudioSourceChannelInfo& bufferToFill) override
{
auto* leftBuffer = bufferToFill.buffer->getWritePointer (0, bufferToFill.startSample);
auto* rightBuffer = bufferToFill.buffer->getWritePointer (1, bufferToFill.startSample);
bufferToFill.clearActiveBufferRegion();
for (auto oscillatorIndex = 0; oscillatorIndex < oscillators.size(); ++oscillatorIndex)
{
auto* oscillator = oscillators.getUnchecked (oscillatorIndex);
for (auto sample = 0; sample < bufferToFill.numSamples; ++sample)
{
auto levelSample = oscillator->getNextSample() * level;
leftBuffer[sample] += levelSample;
rightBuffer[sample] += levelSample;
}
}
}
private:
juce::Label cpuUsageLabel;
juce::Label cpuUsageText;
const unsigned int tableSize = 1 << 7;
float level = 0.0f;
juce::AudioSampleBuffer sineTable;
juce::OwnedArray<WavetableOscillator> oscillators;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
};

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<JUCERPROJECT name="WavetableSynthTutorial" companyName="JUCE" version="1.0.0"
userNotes="Wavetable synthesiser." companyWebsite="http://juce.com"
projectType="guiapp" useAppConfig="0" addUsingNamespaceToJuceHeader="1"
id="dBFoEo" jucerFormatVersion="1">
<MAINGROUP id="auHq7A" name="WavetableSynthTutorial">
<GROUP id="{45834796-7C04-D188-9F98-9AE7211B6CF5}" name="Source">
<FILE id="iPmvtR" name="Main.cpp" compile="1" resource="0" file="Source/Main.cpp"/>
<FILE id="EKiEzl" name="WavetableSynthTutorial_01.h" compile="0" resource="0"
file="Source/WavetableSynthTutorial_01.h"/>
</GROUP>
</MAINGROUP>
<MODULES>
<MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_core" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_events" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
<MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="0" useGlobalPath="1"/>
</MODULES>
<EXPORTFORMATS>
<XCODE_MAC targetFolder="Builds/MacOSX">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="WavetableSynthTutorial"/>
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="WavetableSynthTutorial"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path=""/>
<MODULEPATH id="juce_audio_devices" path=""/>
<MODULEPATH id="juce_audio_formats" path=""/>
<MODULEPATH id="juce_audio_processors" path=""/>
<MODULEPATH id="juce_audio_utils" path=""/>
<MODULEPATH id="juce_core" path=""/>
<MODULEPATH id="juce_data_structures" path=""/>
<MODULEPATH id="juce_events" path=""/>
<MODULEPATH id="juce_graphics" path=""/>
<MODULEPATH id="juce_gui_basics" path=""/>
<MODULEPATH id="juce_gui_extra" path=""/>
</MODULEPATHS>
</XCODE_MAC>
<VS2019 targetFolder="Builds/VisualStudio2019">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="WavetableSynthTutorial"/>
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="WavetableSynthTutorial"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path=""/>
<MODULEPATH id="juce_audio_devices" path=""/>
<MODULEPATH id="juce_audio_formats" path=""/>
<MODULEPATH id="juce_audio_processors" path=""/>
<MODULEPATH id="juce_audio_utils" path=""/>
<MODULEPATH id="juce_core" path=""/>
<MODULEPATH id="juce_data_structures" path=""/>
<MODULEPATH id="juce_events" path=""/>
<MODULEPATH id="juce_graphics" path=""/>
<MODULEPATH id="juce_gui_basics" path=""/>
<MODULEPATH id="juce_gui_extra" path=""/>
</MODULEPATHS>
</VS2019>
<LINUX_MAKE targetFolder="Builds/LinuxMakefile">
<CONFIGURATIONS>
<CONFIGURATION name="Debug" isDebug="1" optimisation="1" targetName="WavetableSynthTutorial"/>
<CONFIGURATION name="Release" isDebug="0" optimisation="3" targetName="WavetableSynthTutorial"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path=""/>
<MODULEPATH id="juce_audio_devices" path=""/>
<MODULEPATH id="juce_audio_formats" path=""/>
<MODULEPATH id="juce_audio_processors" path=""/>
<MODULEPATH id="juce_audio_utils" path=""/>
<MODULEPATH id="juce_core" path=""/>
<MODULEPATH id="juce_data_structures" path=""/>
<MODULEPATH id="juce_events" path=""/>
<MODULEPATH id="juce_graphics" path=""/>
<MODULEPATH id="juce_gui_basics" path=""/>
<MODULEPATH id="juce_gui_extra" path=""/>
</MODULEPATHS>
</LINUX_MAKE>
</EXPORTFORMATS>
<JUCEOPTIONS/>
</JUCERPROJECT>

View File

@@ -43,7 +43,7 @@ namespace ProjectInfo
{
const char* const projectName = "NeuralSynth";
const char* const companyName = "Samedi Dimanche";
const char* const versionString = "0.0.1";
const int versionNumber = 0x1;
const char* const versionString = "1.0.0";
const int versionNumber = 0x10000;
}
#endif

View File

@@ -17,7 +17,7 @@
#define JucePlugin_Build_VST3 1
#endif
#ifndef JucePlugin_Build_AU
#define JucePlugin_Build_AU 1
#define JucePlugin_Build_AU 0
#endif
#ifndef JucePlugin_Build_AUv3
#define JucePlugin_Build_AUv3 0
@@ -26,7 +26,7 @@
#define JucePlugin_Build_AAX 0
#endif
#ifndef JucePlugin_Build_Standalone
#define JucePlugin_Build_Standalone 1
#define JucePlugin_Build_Standalone 0
#endif
#ifndef JucePlugin_Build_Unity
#define JucePlugin_Build_Unity 0
@@ -77,13 +77,13 @@
#define JucePlugin_EditorRequiresKeyboardFocus 0
#endif
#ifndef JucePlugin_Version
#define JucePlugin_Version 0.0.1
#define JucePlugin_Version 1.0.0
#endif
#ifndef JucePlugin_VersionCode
#define JucePlugin_VersionCode 0x1
#define JucePlugin_VersionCode 0x10000
#endif
#ifndef JucePlugin_VersionString
#define JucePlugin_VersionString "0.0.1"
#define JucePlugin_VersionString "1.0.0"
#endif
#ifndef JucePlugin_VSTUniqueID
#define JucePlugin_VSTUniqueID JucePlugin_PluginCode
@@ -155,7 +155,7 @@
#define JucePlugin_ARAFactoryID "com.SamediDimanche.NeuralSynth.factory"
#endif
#ifndef JucePlugin_ARADocumentArchiveID
#define JucePlugin_ARADocumentArchiveID "com.SamediDimanche.NeuralSynth.aradocumentarchive.0.0.1"
#define JucePlugin_ARADocumentArchiveID "com.SamediDimanche.NeuralSynth.aradocumentarchive.1.0.0"
#endif
#ifndef JucePlugin_ARACompatibleArchiveIDs
#define JucePlugin_ARACompatibleArchiveIDs ""

View File

@@ -1,12 +1,12 @@
Important Note!!
================
The purpose of this folder is to contain files that are auto-generated by the Projucer,
and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
the Projucer saves your project.
Therefore, it's a bad idea to make any manual changes to the files in here, or to
put any of your own files in here if you don't want to lose them. (Of course you may choose
to add the folder's contents to your version-control system so that you can re-merge your own
modifications after the Projucer has saved its changes).
Important Note!!
================
The purpose of this folder is to contain files that are auto-generated by the Projucer,
and ALL files in this folder will be mercilessly DELETED and completely re-written whenever
the Projucer saves your project.
Therefore, it's a bad idea to make any manual changes to the files in here, or to
put any of your own files in here if you don't want to lose them. (Of course you may choose
to add the folder's contents to your version-control system so that you can re-merge your own
modifications after the Projucer has saved its changes).

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_basics/juce_audio_basics.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_basics/juce_audio_basics.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_basics/juce_audio_basics.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_basics/juce_audio_basics.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_devices/juce_audio_devices.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_devices/juce_audio_devices.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_devices/juce_audio_devices.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_devices/juce_audio_devices.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_formats/juce_audio_formats.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_formats/juce_audio_formats.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_formats/juce_audio_formats.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_formats/juce_audio_formats.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AAX.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AAX.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AAX.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AAX_utils.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AAX_utils.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_ARA.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_ARA.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AU_2.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_AUv3.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_LV2.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_LV2.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_LV2.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_LV2.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_Standalone.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_Unity.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_Unity.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST2.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST2.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST2.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST3.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_plugin_client/juce_audio_plugin_client_VST3.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors.mm>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors.mm>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors_ara.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors_ara.cpp>

View File

@@ -1,8 +1,8 @@
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors_lv2_libs.cpp>
/*
IMPORTANT! This file is auto-generated each time you save your
project - if you alter its contents, your changes may be overwritten!
*/
#include <juce_audio_processors/juce_audio_processors_lv2_libs.cpp>

Some files were not shown because too many files have changed in this diff Show More