tools/testhost/ is a standalone CLI executable, not a JaySynth-specific tool: it drives any VST2 plugin offline (no audio device, no GUI event loop) via JUCE's own format-agnostic AudioPluginFormatManager / AudioPluginInstance hosting API, so adding another format later (VST3, LADSPA, eventually LV2) is just another addFormat() call - none of the host logic changes. - PluginHost: format-agnostic load/prepare/process/release, parameter get/set, and patch/bank state I/O, all delegating straight to AudioProcessor. Always queries the plugin's real input/output channel counts rather than assuming "0 in" (instrument) or a fixed channel layout - the same code path drives JaySynth (0 in/2 out, MIDI-driven) and a stereo/mono effect identically. - AudioInputSource: fills the plugin's input channels with silence (default, correct no-op for instruments), a sine tone, white/pink noise, or an impulse - what makes the host equally useful for effect plugins, which need a real input signal to do anything. - WavRecorder: records the plugin's actual output channel count to a WAV file via WavAudioFormat/AudioFormatWriter. - main.cpp: CLI (--plugin/--patch/--param/--note/--input/--duration/ --wav/--sampleRate/--blockSize), with basic NaN/Inf output detection. Has its own JuceLibraryCode-equivalent package that compiles only the module amalgams needed for hosting (not juce_audio_plugin_client, which is the plugin-side VST entry point and would collide with this executable's own main()), reusing the already-vendored sdk/juce/JUCE-3.1.1 rather than a second JUCE copy - the host and any plugin it loads are decoupled at the VST2 ABI, not the JUCE source level, so this doesn't need to track JaySynth's own future JUCE version bump. Verified: builds clean (no new warnings) via `MAKE_HOME=... make -C tools/testhost`. Smoke-tested against two very different real plugins: - build/linux/release/JaySynth.so (0 in/2 out, MIDI-driven): --note 60 100 --duration 2 --wav produces correct-length, non-silent, NaN-free stereo audio. - /usr/lib/vst/ZamDelay-vst.so (1 in/1 out, real third-party VST2 effect, no MIDI): --input pink --duration 2 --wav correctly sizes input/output to mono and produces non-silent, NaN-free audio - proof the host is generic, not JaySynth-shaped. - /usr/lib/vst/ZamEQ2-vst.so: the host's own NaN/Inf detection caught a real NaN in this plugin's default state on first render - exactly the kind of regression this tool exists to catch without a GUI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011dhtwRLARk4eiPngcQykLJ
59 lines
1.6 KiB
C++
59 lines
1.6 KiB
C++
#ifndef TESTHOST_AUDIOINPUTSOURCE_H_INCLUDED
|
|
#define TESTHOST_AUDIOINPUTSOURCE_H_INCLUDED
|
|
|
|
#include <JuceHeader.h>
|
|
|
|
/** Fills a plugin's input channels before each processBlock() call.
|
|
|
|
silence (the default) is the correct choice for MIDI-driven instruments
|
|
like JaySynth, which never read their input at all. sine/whiteNoise/
|
|
pinkNoise/impulse exist so the same host can also test audio-effect
|
|
plugins (reverbs, EQs, compressors) that need a real input signal to do
|
|
anything meaningful.
|
|
*/
|
|
class AudioInputSource
|
|
{
|
|
public:
|
|
enum Type
|
|
{
|
|
silence = 0,
|
|
sine,
|
|
whiteNoise,
|
|
pinkNoise,
|
|
impulse
|
|
};
|
|
|
|
AudioInputSource();
|
|
|
|
void setSilence();
|
|
void setSine (double frequencyHz, float amplitude);
|
|
void setWhiteNoise (float amplitude);
|
|
void setPinkNoise (float amplitude);
|
|
/** A single amplitude-1 sample at t=0 followed by silence - the standard
|
|
stimulus for capturing an effect's impulse response. */
|
|
void setImpulse (float amplitude);
|
|
|
|
void prepare (double sampleRateToUse);
|
|
|
|
/** Fills channels [0, numChannels) of buffer with the next numSamples of
|
|
signal, advancing internal phase/position state across calls. Leaves
|
|
buffer's content beyond numChannels untouched. */
|
|
void fillNextBlock (AudioSampleBuffer &buffer, int numChannels, int numSamples);
|
|
|
|
private:
|
|
Type type;
|
|
double frequencyHz;
|
|
float amplitude;
|
|
double sampleRate;
|
|
double phase;
|
|
Random random;
|
|
int64 samplePosition;
|
|
float pinkState[7];
|
|
|
|
float nextPinkSample (float whiteSample);
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioInputSource)
|
|
};
|
|
|
|
#endif // TESTHOST_AUDIOINPUTSOURCE_H_INCLUDED
|