#ifndef TESTHOST_TESTSCENARIO_H_INCLUDED #define TESTHOST_TESTSCENARIO_H_INCLUDED #include #include "AudioInputSource.h" /** A timed sequence of actions (MIDI events, parameter changes, patch/bank load & save) plus render/I-O configuration, parsed from a JSON file. This is what makes test runs repeatable and batchable instead of ad-hoc CLI invocations - e.g. one file per regression case, run unattended. Nothing in here is JaySynth-specific: events that don't apply to a given plugin (MIDI events sent to a plugin with no MIDI input, say) are simply harmless, since JUCE's MidiBuffer/AudioProcessor API already tolerates that generically. */ class TestScenario { public: TestScenario() {} struct Event { enum Type { noteOn = 0, noteOff, controller, param, loadPatch, loadBank, savePatch, saveBank }; int64 sample = 0; Type type = noteOn; // MIDI note/controller fields int channel = 1; int note = 60; int velocity = 100; int controllerNumber = 0; int controllerValue = 0; // Parameter-change fields int paramIndex = 0; float paramValue = 0.0f; // Patch/bank load & save fields String file; }; /** Parses jsonFile. Relative file paths named inside it (input.wavFile, loadPatch/loadBank, and any event's "file") are resolved relative to the JSON file's own directory, not the process's working directory, so a scenario file is portable regardless of where it's run from. */ bool loadFromFile (const File &jsonFile); double sampleRate = 44100.0; int blockSize = 512; int64 durationSamples = 0; AudioInputSource::Type inputType = AudioInputSource::silence; double inputFrequencyHz = 440.0; float inputAmplitude = 0.5f; String initialLoadPatchFile; String initialLoadBankFile; String recordWavFile; /** Sorted ascending by .sample. */ Array events; private: bool parseTopLevel (const var &root, const File &baseDir); bool parseInput (const var &inputVar); bool parseEvents (const var &eventsVar, const File &baseDir); static bool parseEventType (const String &typeName, Event::Type &outType); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TestScenario) }; #endif // TESTHOST_TESTSCENARIO_H_INCLUDED