332 lines
21 KiB
C++
332 lines
21 KiB
C++
#pragma once
|
|
#include <JuceHeader.h>
|
|
#include <array>
|
|
#include <map>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace PresetsCode
|
|
{
|
|
struct Preset { juce::String name; std::map<juce::String, float> values; };
|
|
struct Category{ juce::String name; std::vector<Preset> presets; };
|
|
|
|
namespace detail
|
|
{
|
|
constexpr int presetsPerCategory = 30;
|
|
constexpr int modeVariantCount = presetsPerCategory / 2;
|
|
|
|
using SlotSet = std::array<int, 3>;
|
|
using SlotTriplet = std::array<SlotSet, 3>;
|
|
|
|
struct GMProfile
|
|
{
|
|
juce::String name;
|
|
float master;
|
|
float morph;
|
|
float cutoff;
|
|
float attack;
|
|
float decay;
|
|
float sustain;
|
|
float release;
|
|
float lfoRate;
|
|
float lfoDepth;
|
|
float fEnvAmount;
|
|
float fxMix;
|
|
SlotTriplet slotSets;
|
|
};
|
|
|
|
struct CategoryNameSet
|
|
{
|
|
std::array<const char*, modeVariantCount> solo;
|
|
std::array<const char*, modeVariantCount> layered;
|
|
};
|
|
|
|
static constexpr std::array<CategoryNameSet, 16> nameSets
|
|
{{
|
|
CategoryNameSet{
|
|
{ "Concert Grand", "Studio Upright", "Warm Parlor", "Bright Stage", "Dusty Keys",
|
|
"Midnight Felt", "Glass Hammer", "Sunlit Room", "Jazz Touch", "Ringing Octaves",
|
|
"Soft Pedal", "Pop Punch", "Wide Hammer", "Twilight Piano", "Crystal Keys" },
|
|
{ "Grand Stack", "Hammer Chorus", "Layered Uprights", "Glassy Spread", "Warm Hall Blend",
|
|
"Hybrid Grand", "Bright Layer", "Felt Cloud", "Cinema Piano", "Dream Keys",
|
|
"Bell Piano", "Wide Hammered", "Velvet Layers", "Studio Swirl", "Concert Bloom" }
|
|
}, // Piano
|
|
CategoryNameSet{
|
|
{ "Solo Vibraphone", "Celesta Light", "Glassy Chimes", "Soft Mallets", "Toy Box",
|
|
"Crystal Bars", "Marimba Glow", "Bell Cascade", "Clav Accent", "Metal Steps",
|
|
"Trem Vibra", "Dry Mallet", "Shimmer Keys", "Clockwork", "Glass Struck" },
|
|
{ "Mallet Ensemble", "Celesta Pad", "Chime Stack", "Bell Layers", "Crystal Curtain",
|
|
"Hybrid Mallets", "Wide Glock", "Mallet Dream", "Spectral Bells", "Golden Bars",
|
|
"Bright Resonance", "Airy Mallets", "Wide Celesta", "Fantasy Chimes", "Silver Rain" }
|
|
}, // Chromatic Percussion
|
|
CategoryNameSet{
|
|
{ "Pure Drawbar", "Chapel Soft", "Perc Click", "Full Stops", "Hollow Tone",
|
|
"Jazz Wheel", "Old Console", "Far Bar", "Vox Accent", "Tremolo Pipes",
|
|
"Slow Leslie", "Rock Bars", "Warm Console", "Combo Organ", "Ancient Reed" },
|
|
{ "Twin Drawbars", "Cathedral Stack", "Rotary Blend", "Organ Swell", "Thick Console",
|
|
"Wide Vox", "Dual Chapel", "Gospel Layers", "Airy Pipes", "Hybrid Harm",
|
|
"Bright Rotary", "Deep Drawbar", "Vintage Stack", "Layered Stops", "Electric Chapel" }
|
|
}, // Organ
|
|
CategoryNameSet{
|
|
{ "Clean Pluck", "Bright Strum", "Muted Pick", "Hollow Body", "Steel Shimmer",
|
|
"Warm Nylon", "Slide Touch", "Jazz Octave", "Edge Pluck", "Dry Funk",
|
|
"Airy Harmonics", "Silver Strings", "Wooden Pick", "Folk Finger", "Soft Trem" },
|
|
{ "Guitar Stack", "Stereo Strum", "Pluck Ensemble", "Wide Harmonics", "Chorus Nylon",
|
|
"Electric Blend", "Picked Layers", "Dream Guitar", "Shimmer Strings", "Deep Strummer",
|
|
"Twin Slides", "Wide Trem", "Hybrid Pluck", "Sparkle Guitar", "Ambient Strum" }
|
|
}, // Guitar
|
|
CategoryNameSet{
|
|
{ "Fingered Bass", "Picked Attack", "Deep Sub", "Warm Round", "Clav Bass",
|
|
"Snappy Slap", "Muted Thump", "Synth Pluck", "Punchy Low", "Airless Bass",
|
|
"Moog Tone", "Dry Root", "Soft Sub", "Acoustic Body", "Neo Bass" },
|
|
{ "Layered Low", "Sub Stack", "Punch Blend", "Bass Split", "Wide Slap",
|
|
"Deep Synth", "Hybrid Bass", "Chorus Low", "Twin Thump", "Boom Texture",
|
|
"Bass Ensemble", "Stereo Sub", "Growl Stack", "Fundamental Wall", "Airy Sub" }
|
|
}, // Bass
|
|
CategoryNameSet{
|
|
{ "Solo Violin", "Warm Viola", "Cello Bow", "Silk Section", "Muted Strings",
|
|
"Spiccato", "Wide Legato", "Bright Ensemble", "Soft Layer", "Orchestral Pad",
|
|
"Tremolo Lace", "Vintage Strings", "Glass Harmonics", "Warm Stack", "Solo Cello" },
|
|
{ "String Layers", "Cinematic Swell", "Wide Arcs", "Orchestral Cloud", "Hybrid Strings",
|
|
"Chamber Blend", "Symphonic Rise", "Dream Swell", "Shimmer Strings", "Soft Orchestra",
|
|
"Glass Orchestra", "Air Ensemble", "Epic Layer", "Velvet Section", "Neo Strings" }
|
|
}, // Strings
|
|
CategoryNameSet{
|
|
{ "Light Ensemble", "Soft Choir", "Mixed Section", "Warm Stack", "Bright Choir",
|
|
"Octave Layers", "Air Voices", "Analog Ensemble", "Voiced Pad", "Stacked Strings",
|
|
"Gentle Chorus", "Full Section", "Ethereal Group", "Pop Chorus", "Glass Ensemble" },
|
|
{ "Cathedral Ensemble", "Choir Spread", "Hybrid Voices", "Epic Stack", "Layered Choir",
|
|
"Wide Ensemble", "Dream Choir", "Symphonic Pad", "Lush Assembly", "Stereo Ensemble",
|
|
"Glorious Layer", "Angelic Swell", "Velvet Choir", "Bright Assembly", "Atmos Ensemble" }
|
|
}, // Ensemble
|
|
CategoryNameSet{
|
|
{ "Solo Trumpet", "Muted Brass", "Warm Horn", "Bright Brass", "Soft Flugel",
|
|
"Tenor Bones", "Sharp Brass", "French Stack", "Hero Lead", "Vintage Brass",
|
|
"Orchestral Horn", "Fan Brass", "Soft Cornet", "Bold Bones", "Hybrid Brass" },
|
|
{ "Brass Wall", "Epic Horns", "Stadium Brass", "Layered Trumpets", "Octave Brass",
|
|
"Brass Ensemble", "Hero Stack", "Warm Brass Pad", "Cinema Brass", "Wide Brass",
|
|
"Glory Brass", "Tone Tower", "Bright Brass Pad", "Deep Horn Stack", "Hybrid Fanfare" }
|
|
}, // Brass
|
|
CategoryNameSet{
|
|
{ "Solo Clarinet", "Warm Sax", "Bright Reed", "Soft Oboe", "Jazz Alto",
|
|
"Bassoon Tone", "Smooth Tenor", "Piercing Reed", "Dry Clar", "Wide Reed",
|
|
"Dark Oboe", "Airy Bassoon", "Pop Sax", "Velvet Reed", "Vintage Clar" },
|
|
{ "Reed Ensemble", "Twin Sax", "Clarinet Choir", "Hybrid Reed", "Smooth Section",
|
|
"Layered Oboes", "Wide Reed Pad", "Cinema Reed", "Stacked Sax", "Woodwind Wall",
|
|
"Airy Reed", "Jazz Stack", "Bright Reeds", "Shadow Reed", "Velvet Woodwind" }
|
|
}, // Reed
|
|
CategoryNameSet{
|
|
{ "Concert Flute", "Breathy Flute", "Piccolo Star", "Soft Recorder", "Glass Flute",
|
|
"Warm Alto", "Fife Tone", "Wind Whisper", "Sharp Pipe", "Native Flute",
|
|
"Bright Piccolo", "Calm Pipes", "Open Whistle", "Night Flute", "Ancient Pipe" },
|
|
{ "Pipe Ensemble", "Choir Flutes", "Layered Wind", "Dream Flutes", "Wide Pipes",
|
|
"Ethereal Flutes", "Airy Stack", "Silver Cascade", "Mystic Flutes", "Breath Layers",
|
|
"Stereo Pipes", "Hybrid Flutes", "Clouded Pipes", "Shining Wind", "Sky Columns" }
|
|
}, // Pipe
|
|
CategoryNameSet{
|
|
{ "Blade Lead", "Sync Razor", "Analog Sizzle", "Digital Edge", "Saw Glide",
|
|
"Pulse Sprint", "FM Piercer", "Reso Runner", "Mono Glide", "Square Force",
|
|
"Acid Beam", "Metal Lead", "Chiptone", "Warm Solo", "Vox Glide" },
|
|
{ "Twin Blades", "Stereo Lead", "Octave Runner", "Layered Saw", "Wide Screamer",
|
|
"Poly Stack", "Hybrid Rush", "Air Lead", "Reso Layers", "Arena Solo",
|
|
"Neon Drive", "Cosmic Lead", "Lucid Glide", "Turbo Layers", "Sky Blade" }
|
|
}, // Synth Lead
|
|
CategoryNameSet{
|
|
{ "Warm Blanket", "Glass Pad", "Analog Mist", "Digital Halo", "Soft Spread",
|
|
"Bright Pad", "Choral Sweep", "Nocturne Pad", "Vintage Pad", "FM Veil",
|
|
"Dusty Pad", "Air Sweep", "Silk Bed", "Calm Horizon", "Wide Prism" },
|
|
{ "Pad Cathedral", "Luminous Pad", "Dream Orbit", "Velvet Layers", "Motion Cloud",
|
|
"Evolving Pad", "Glass Ensemble", "Solar Drift", "Shimmer Sky", "Deep Nebula",
|
|
"Aurora Pad", "Liquid Glow", "Expanse Pad", "Twin Horizons", "Ethereal Bloom" }
|
|
}, // Synth Pad
|
|
CategoryNameSet{
|
|
{ "Rise Sweep", "Noise Hit", "Circuit Zap", "Reso Drop", "Granular Wash",
|
|
"Bit Spark", "Gated Rush", "Pulse Radar", "Morph Click", "Glitch Line",
|
|
"Bleed Pad", "Searing Rise", "Swarm FX", "Vapor Hit", "Spectra Pop" },
|
|
{ "FX Cascade", "Binary Storm", "Shimmer FX", "Impact Stack", "Laser Field",
|
|
"Wave Crash", "Dual Sweep", "Horizon FX", "Voltage Rain", "Sky Burst",
|
|
"Nebula FX", "Falling Stars", "Circuit Bloom", "Phase Impact", "Aurora FX" }
|
|
}, // Synth Effects
|
|
CategoryNameSet{
|
|
{ "Sitar Pluck", "Shamisen Tone", "Kalimba Bell", "Gamelan Fan", "Erhu Bow",
|
|
"Santur Ring", "Kora Waves", "Baglama Run", "Oud Mellow", "Bansuri Air",
|
|
"Tin Whistle", "Didgeridoo Drone", "Taiko Rim", "Ngoni Pulse", "Guqin Flow" },
|
|
{ "World Layers", "Tribal Echo", "Desert Wind", "Eastern Stack", "Cultural Bloom",
|
|
"Panorama Folk", "Nomad Chorus", "Festival Mix", "Temple Air", "Jungle Drift",
|
|
"Azure Bazaar", "Wide Kalimba", "Storm Ritual", "Mystic Caravan", "Earth Ensemble" }
|
|
}, // Ethnic
|
|
CategoryNameSet{
|
|
{ "Analog Kick", "Tight Snare", "Electro Tom", "Clack Hit", "Wood Block",
|
|
"Glass Ping", "Tribal Drum", "Metal Knock", "Click Perc", "Pop Rim",
|
|
"Snap Clap", "Deep Boom", "Air Hit", "Short Noise", "Soft Knock" },
|
|
{ "Perc Stack", "Rhythm Wall", "Hybrid Drum", "Layered Hit", "Wide Impact",
|
|
"Perc Texture", "Motion Perc", "Tribal Layers", "Circuit Beat", "Wide Clap",
|
|
"Perc Storm", "Drum Machine", "Stage Impact", "Thunder Perc", "Break Stack" }
|
|
}, // Percussive
|
|
CategoryNameSet{
|
|
{ "Wind Rush", "Ocean Drone", "Metallic Fall", "SciFi Ping", "Air Sweep",
|
|
"Machine Loop", "Space Beep", "Rumble FX", "Glass Growl", "Signal Warp",
|
|
"Foley Hit", "Distant Boom", "Echo Drops", "Industrial Spin", "Night Noise" },
|
|
{ "FX Universe", "Storm Front", "Space Layers", "Dread Drones", "Cinematic Field",
|
|
"Signal Swarm", "Nightscape", "Future Machine", "Thunder Field", "Layered Noise",
|
|
"Alien Atmos", "Mystery Floor", "Flash Impact", "Vortex FX", "Deep Horizon" }
|
|
} // Sound Effects
|
|
}};
|
|
|
|
inline juce::String makePresetName (const GMProfile& profile,
|
|
size_t profileIndex,
|
|
int variantIndex,
|
|
bool bitimbral)
|
|
{
|
|
const int localIndex = bitimbral ? (variantIndex - modeVariantCount) : variantIndex;
|
|
const auto& descriptorSet = bitimbral ? nameSets[(size_t) profileIndex].layered
|
|
: nameSets[(size_t) profileIndex].solo;
|
|
const size_t clamped = (size_t) juce::jlimit (0, (int) descriptorSet.size() - 1, localIndex);
|
|
return profile.name + " " + juce::String (descriptorSet[clamped]);
|
|
}
|
|
|
|
inline Preset makePreset (const juce::String& name,
|
|
const GMProfile& profile,
|
|
int variantIndex,
|
|
bool bitimbral)
|
|
{
|
|
const float spread = static_cast<float> ((variantIndex % 5) - 2);
|
|
|
|
const float master = juce::jlimit (0.50f, 0.95f, profile.master + spread * 0.01f);
|
|
const float morph = juce::jlimit (0.00f, 1.00f, profile.morph + spread * 0.02f + (bitimbral ? 0.06f : -0.04f));
|
|
const float cutoff = juce::jlimit (250.0f, 18000.0f, profile.cutoff + 320.0f * static_cast<float> ((variantIndex % 7) - 3));
|
|
const float attack = juce::jlimit (0.001f, 4.000f, profile.attack * (1.0f + spread * 0.03f));
|
|
const float decay = juce::jlimit (0.050f, 3.500f, profile.decay * (1.0f + spread * 0.04f));
|
|
const float sustain = juce::jlimit (0.00f, 1.00f, profile.sustain + spread * 0.02f);
|
|
const float release = juce::jlimit (0.050f, 4.000f, profile.release * (1.0f + spread * 0.05f));
|
|
const float lfoRate = juce::jlimit (0.050f, 8.000f, profile.lfoRate + 0.12f * static_cast<float> ((variantIndex % 8) - 3));
|
|
const float lfoDepth = juce::jlimit (0.00f, 1.00f, profile.lfoDepth + spread * 0.03f);
|
|
const float fEnvAmt = juce::jlimit (0.10f, 0.90f, profile.fEnvAmount + spread * 0.02f);
|
|
const float fxMix = juce::jlimit (0.00f, 1.00f, profile.fxMix + spread * 0.04f);
|
|
|
|
const float chRate = juce::jlimit (0.20f, 1.80f, 0.55f + fxMix * 0.80f + spread * 0.03f);
|
|
const float chDepth = juce::jlimit (0.00f, 1.00f, 0.18f + fxMix * 0.55f);
|
|
const float chDelay = juce::jlimit (5.00f, 20.00f, 8.0f + fxMix * 6.5f + (bitimbral ? 1.5f : -1.0f));
|
|
const float chFb = juce::jlimit (0.00f, 0.60f, 0.04f + fxMix * 0.14f);
|
|
const float chMix = juce::jlimit (0.00f, 0.60f, fxMix * 0.45f);
|
|
|
|
const float rvRoom = juce::jlimit (0.00f, 1.00f, 0.28f + fxMix * 0.62f);
|
|
const float rvDamp = juce::jlimit (0.00f, 1.00f, 0.20f + fxMix * 0.40f);
|
|
const float rvWidth = juce::jlimit (0.00f, 1.00f, 0.82f + fxMix * 0.15f);
|
|
const float rvWet = juce::jlimit (0.00f, 1.00f, 0.12f + fxMix * 0.36f);
|
|
|
|
const auto& slotChoice = profile.slotSets[(size_t) (variantIndex % profile.slotSets.size())];
|
|
|
|
std::map<juce::String, float> values
|
|
{
|
|
{ "MASTER", master },
|
|
{ "MORPH", morph },
|
|
{ "MORPH_LOOP_ON", (bitimbral || (variantIndex % 3 == 0)) ? 1.0f : 0.0f },
|
|
{ "MORPH_LOOP_MODE", static_cast<float> ((variantIndex / 5) % 3) },
|
|
{ "CUTOFF", cutoff },
|
|
{ "ATTACK", attack },
|
|
{ "DECAY", decay },
|
|
{ "SUSTAIN", sustain },
|
|
{ "RELEASE", release },
|
|
{ "LFO_RATE", lfoRate },
|
|
{ "LFO_DEPTH", lfoDepth },
|
|
{ "FENV_A", juce::jlimit (0.001f, 2.000f, attack * 0.55f) },
|
|
{ "FENV_D", juce::jlimit (0.050f, 2.400f, decay * 1.05f) },
|
|
{ "FENV_S", juce::jlimit (0.00f, 1.00f, sustain * 0.48f) },
|
|
{ "FENV_R", juce::jlimit (0.050f, 2.800f, release * 1.15f) },
|
|
{ "FENV_AMT", fEnvAmt },
|
|
{ "OSC2_MUTE", bitimbral ? 0.0f : 1.0f },
|
|
{ "CHORUS_ON", fxMix > 0.32f ? 1.0f : 0.0f },
|
|
{ "REVERB_ON", fxMix > 0.18f ? 1.0f : 0.0f },
|
|
{ "CH_RATE", chRate },
|
|
{ "CH_DEPTH", chDepth },
|
|
{ "CH_DELAY", chDelay },
|
|
{ "CH_FB", chFb },
|
|
{ "CH_MIX", chMix },
|
|
{ "RV_ROOM", rvRoom },
|
|
{ "RV_DAMP", rvDamp },
|
|
{ "RV_WIDTH", rvWidth },
|
|
{ "RV_WET", rvWet },
|
|
{ "SLOT_A", (float) slotChoice[0] },
|
|
{ "SLOT_B", (float) slotChoice[1] },
|
|
{ "SLOT_C", (float) slotChoice[2] }
|
|
};
|
|
|
|
return { name, std::move (values) };
|
|
}
|
|
} // namespace detail
|
|
|
|
// ----------------------- Library -----------------------------------------
|
|
inline std::vector<Category> getCategories()
|
|
{
|
|
using namespace detail;
|
|
|
|
const std::array<GMProfile, 16> gmProfiles
|
|
{{
|
|
{ "Piano", 0.72f, 0.18f, 6800.0f, 0.020f, 0.280f, 0.65f, 0.320f, 0.40f, 0.22f, 0.35f, 0.28f,
|
|
SlotTriplet{ SlotSet{ 0, 3, 11 }, SlotSet{ 0, 9, 15 }, SlotSet{ 0, 3, 19 } } },
|
|
{ "Chromatic Percussion",0.68f, 0.22f, 7200.0f, 0.012f, 0.240f, 0.50f, 0.300f, 0.45f, 0.30f, 0.42f, 0.24f,
|
|
SlotTriplet{ SlotSet{ 11, 12, 14 }, SlotSet{ 11, 9, 13 }, SlotSet{ 11, 12, 5 } } },
|
|
{ "Organ", 0.70f, 0.55f, 8400.0f, 0.040f, 0.480f, 0.80f, 0.600f, 0.90f, 0.40f, 0.28f, 0.35f,
|
|
SlotTriplet{ SlotSet{ 10, 7, 0 }, SlotSet{ 10, 1, 2 }, SlotSet{ 10, 5, 8 } } },
|
|
{ "Guitar", 0.66f, 0.32f, 6200.0f, 0.015f, 0.450f, 0.55f, 0.450f, 0.65f, 0.35f, 0.40f, 0.30f,
|
|
SlotTriplet{ SlotSet{ 3, 4, 12 }, SlotSet{ 3, 6, 1 }, SlotSet{ 3, 4, 9 } } },
|
|
{ "Bass", 0.75f, 0.25f, 2800.0f, 0.008f, 0.300f, 0.78f, 0.220f, 0.30f, 0.25f, 0.55f, 0.18f,
|
|
SlotTriplet{ SlotSet{ 0, 6, 4 }, SlotSet{ 0, 5, 12 }, SlotSet{ 0, 6, 14 } } },
|
|
{ "Strings", 0.72f, 0.48f, 5600.0f, 0.180f, 0.850f, 0.70f, 1.100f, 0.28f, 0.60f, 0.36f, 0.45f,
|
|
SlotTriplet{ SlotSet{ 3, 11, 15 }, SlotSet{ 3, 9, 18 }, SlotSet{ 3, 11, 0 } } },
|
|
{ "Ensemble", 0.74f, 0.50f, 5400.0f, 0.200f, 0.900f, 0.72f, 1.400f, 0.32f, 0.58f, 0.40f, 0.48f,
|
|
SlotTriplet{ SlotSet{ 11, 1, 0 }, SlotSet{ 11, 18, 15 }, SlotSet{ 11, 7, 3 } } },
|
|
{ "Brass", 0.70f, 0.42f, 7800.0f, 0.060f, 0.550f, 0.68f, 0.500f, 0.45f, 0.30f, 0.50f, 0.30f,
|
|
SlotTriplet{ SlotSet{ 2, 10, 15 }, SlotSet{ 2, 11, 1 }, SlotSet{ 2, 9, 13 } } },
|
|
{ "Reed", 0.68f, 0.34f, 7600.0f, 0.050f, 0.480f, 0.65f, 0.580f, 0.52f, 0.38f, 0.44f, 0.28f,
|
|
SlotTriplet{ SlotSet{ 8, 10, 0 }, SlotSet{ 8, 9, 3 }, SlotSet{ 8, 5, 11 } } },
|
|
{ "Pipe", 0.67f, 0.38f, 7200.0f, 0.100f, 0.600f, 0.70f, 0.900f, 0.40f, 0.32f, 0.36f, 0.32f,
|
|
SlotTriplet{ SlotSet{ 0, 9, 11 }, SlotSet{ 0, 9, 18 }, SlotSet{ 0, 9, 5 } } },
|
|
{ "Synth Lead", 0.73f, 0.62f, 12800.0f, 0.015f, 0.320f, 0.78f, 0.260f, 1.20f, 0.55f, 0.48f, 0.38f,
|
|
SlotTriplet{ SlotSet{ 1, 2, 5 }, SlotSet{ 1, 14, 6 }, SlotSet{ 1, 2, 13 } } },
|
|
{ "Synth Pad", 0.76f, 0.58f, 6500.0f, 0.350f, 1.100f, 0.75f, 2.100f, 0.22f, 0.60f, 0.40f, 0.55f,
|
|
SlotTriplet{ SlotSet{ 15, 18, 11 }, SlotSet{ 15, 19, 0 }, SlotSet{ 15, 9, 3 } } },
|
|
{ "Synth Effects", 0.68f, 0.70f, 9000.0f, 0.080f, 1.400f, 0.40f, 1.800f, 0.90f, 0.70f, 0.62f, 0.60f,
|
|
SlotTriplet{ SlotSet{ 5, 11, 1 }, SlotSet{ 14, 19, 2 }, SlotSet{ 6, 11, 12 } } },
|
|
{ "Ethnic", 0.69f, 0.40f, 6800.0f, 0.030f, 0.650f, 0.58f, 0.700f, 0.58f, 0.36f, 0.42f, 0.34f,
|
|
SlotTriplet{ SlotSet{ 11, 3, 12 }, SlotSet{ 11, 9, 4 }, SlotSet{ 11, 3, 0 } } },
|
|
{ "Percussive", 0.71f, 0.28f, 5200.0f, 0.012f, 0.420f, 0.30f, 0.380f, 0.75f, 0.44f, 0.60f, 0.26f,
|
|
SlotTriplet{ SlotSet{ 5, 12, 14 }, SlotSet{ 5, 13, 4 }, SlotSet{ 5, 9, 6 } } },
|
|
{ "Sound Effects", 0.65f, 0.75f, 9900.0f, 0.050f, 1.600f, 0.35f, 2.400f, 1.10f, 0.80f, 0.70f, 0.65f,
|
|
SlotTriplet{ SlotSet{ 11, 5, 1 }, SlotSet{ 11, 6, 2 }, SlotSet{ 19, 14, 1 } } }
|
|
}};
|
|
|
|
std::vector<Category> cats;
|
|
cats.reserve (gmProfiles.size());
|
|
|
|
for (size_t profileIndex = 0; profileIndex < gmProfiles.size(); ++profileIndex)
|
|
{
|
|
const auto& profile = gmProfiles[(size_t) profileIndex];
|
|
Category category;
|
|
category.name = profile.name;
|
|
category.presets.reserve (presetsPerCategory);
|
|
|
|
for (int variant = 0; variant < presetsPerCategory; ++variant)
|
|
{
|
|
const bool bitimbral = variant >= modeVariantCount;
|
|
const auto presetName = makePresetName (profile, profileIndex, variant, bitimbral);
|
|
|
|
category.presets.push_back (makePreset (presetName, profile, variant, bitimbral));
|
|
}
|
|
|
|
cats.push_back (std::move (category));
|
|
}
|
|
|
|
return cats;
|
|
}
|
|
|
|
// Apply a preset to the APVTS (safe: uses convertTo0to1)
|
|
inline void loadPreset (juce::AudioProcessorValueTreeState& apvts, const Preset& p)
|
|
{
|
|
for (const auto& kv : p.values)
|
|
if (auto* prm = apvts.getParameter (kv.first))
|
|
prm->setValueNotifyingHost (prm->convertTo0to1 (kv.second));
|
|
}
|
|
} // namespace PresetsCode
|