Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
validation_harness.hpp
Go to the documentation of this file.
1#pragma once
2
8
11#include <chrono>
12#include <filesystem>
13#include <functional>
14#include <string>
15#include <vector>
16
17namespace pulp::format {
18
21
23inline const char* to_string(ValidationStatus s) {
24 switch (s) {
25 case ValidationStatus::pass: return "pass";
26 case ValidationStatus::fail: return "fail";
27 case ValidationStatus::skip: return "skip";
28 case ValidationStatus::error: return "error";
29 }
30 return "error";
31}
32
35 std::string type; // screenshot, screenshot_diff, inspector, validator, sanitizer, test_suite
37 std::string target; // plugin name, test name, view ID
38 double duration_ms = 0;
39 std::string error_message;
40
41 // Type-specific payloads stored as pre-formatted JSON fragments.
42 // The harness populates these when generating entries.
43 std::string payload_json;
44};
45
48 std::filesystem::path output_dir; // Where to write artifacts
49 double sample_rate = 48000.0;
50 int buffer_size = 512;
53 uint32_t screenshot_width = 800;
54 uint32_t screenshot_height = 600;
55 float screenshot_scale = 2.0f;
56 std::string screenshot_backend = "default";
57
58 // Diff settings
59 uint8_t diff_tolerance = 32;
60 float diff_threshold = 0.85f;
61
62 // Git metadata (optional)
63 std::string git_ref;
64 std::string run_id;
65};
66
81public:
84
87
88 // ── Audio control surface ───────────────────────────────────────────
89
91 void prepare();
92
94 void set_param(state::ParamID id, float value);
95
97 float get_param(state::ParamID id) const;
98
100 void send_midi_note_on(int channel, int note, int velocity);
101
103 void send_midi_note_off(int channel, int note);
104
106 void send_midi_cc(int channel, int controller, int value);
107
110 std::vector<float> process_blocks(int num_blocks);
111
115 std::vector<float> process_buffer(const std::vector<float>& interleaved_input,
116 int num_channels, int num_samples);
117
121 std::vector<double> process_buffer_f64(
122 const std::vector<double>& interleaved_input,
123 int num_channels, int num_samples);
124
126 std::vector<uint8_t> save_state() const;
127
129 bool load_state(std::span<const uint8_t> data);
130
131 // ── Capture ─────────────────────────────────────────────────────────
132 //
133 // Screenshot and inspector capture are delegated to an external
134 // provider callback so the harness stays free of a direct view-
135 // library dependency. Register a provider before calling
136 // capture_screenshot()/capture_inspector() — without one, the
137 // entry is reported as `skip` with a clear "no provider attached"
138 // message. Callers must never confuse skip with pass.
139
142 using CaptureScreenshotProvider = std::function<bool(
143 const std::filesystem::path& output_path,
144 uint32_t width, uint32_t height, float scale,
145 const std::string& backend)>;
146
149 using CaptureInspectorProvider = std::function<std::string()>;
150
154
157
161 ReportEntry capture_screenshot(const std::filesystem::path& output_path);
162
167 ReportEntry compare_screenshots(const std::filesystem::path& reference,
168 const std::filesystem::path& rendered);
169
174
175 // ── External validators ─────────────────────────────────────────────
176
180 ReportEntry run_validator(const std::string& tool,
181 const std::filesystem::path& plugin_path,
182 const std::string& format = "");
183
195 const std::filesystem::path& plugin_path,
196 const std::string& expected_plugin_id = "");
197
201 std::uint64_t xrun_count,
202 const audio::AudioRuntimeOverloadPolicy& policy = {});
203
204 // ── Report generation ───────────────────────────────────────────────
205
208
210 std::string generate_report() const;
211
213 bool write_report(const std::filesystem::path& output_path) const;
214
216 const std::vector<ReportEntry>& entries() const { return entries_; }
217
219 void clear_entries() { entries_.clear(); }
220
222 HeadlessHost& host() { return host_; }
223 const HeadlessHost& host() const { return host_; }
224
226 const PluginDescriptor& descriptor() const { return host_.descriptor(); }
227
228private:
229 HeadlessHost host_;
231 std::vector<ReportEntry> entries_;
232 midi::MidiBuffer pending_midi_in_;
233 bool prepared_ = false;
234
235 // Capture delegation is unset by default; callers register a provider
236 // backed by the view layer (or a test fake) before invoking
237 // capture_screenshot / capture_inspector.
238 CaptureScreenshotProvider screenshot_provider_;
239 CaptureInspectorProvider inspector_provider_;
240
241 std::string platform_string() const;
242 std::string iso_timestamp() const;
243 std::string escape_json(const std::string& s) const;
244 std::string json_string_array(const std::vector<std::string>& values) const;
245};
246
247} // namespace pulp::format
Headless plugin host for testing and offline processing.
Definition headless.hpp:29
std::function< std::string()> CaptureInspectorProvider
Callback that produces a JSON snapshot of the view tree.
Definition validation_harness.hpp:149
void send_midi_cc(int channel, int controller, int value)
Send MIDI CC into the next process() call.
ReportEntry run_validator(const std::string &tool, const std::filesystem::path &plugin_path, const std::string &format="")
Run an external validator tool on a plugin bundle.
std::vector< uint8_t > save_state() const
Save current plugin state to a binary blob.
ReportEntry record_runtime_overload(const audio::AudioProcessLoadSnapshot &load, std::uint64_t xrun_count, const audio::AudioRuntimeOverloadPolicy &policy={})
Record runtime load/xrun telemetry using the shared overload policy.
std::string generate_report() const
Generate the full validation report as JSON (conforming to schema v1).
std::vector< float > process_buffer(const std::vector< float > &interleaved_input, int num_channels, int num_samples)
Process a single block of audio from the given input buffer.
std::function< bool( const std::filesystem::path &output_path, uint32_t width, uint32_t height, float scale, const std::string &backend)> CaptureScreenshotProvider
Callback that captures a screenshot of the current view/render state into output_path.
Definition validation_harness.hpp:142
void send_midi_note_on(int channel, int note, int velocity)
Send MIDI note-on into the next process() call.
ReportEntry compare_screenshots(const std::filesystem::path &reference, const std::filesystem::path &rendered)
Compare two screenshot files and generate a diff entry.
ReportEntry capture_screenshot(const std::filesystem::path &output_path)
Capture a screenshot to the given path.
void configure(const ValidationRunOptions &opts)
Configure the harness with run options.
const HeadlessHost & host() const
Definition validation_harness.hpp:223
void prepare()
Prepare the processor for audio. Uses options from configure().
std::vector< double > process_buffer_f64(const std::vector< double > &interleaved_input, int num_channels, int num_samples)
Process a single double-precision block from the given input buffer.
const std::vector< ReportEntry > & entries() const
Get all accumulated report entries.
Definition validation_harness.hpp:216
void send_midi_note_off(int channel, int note)
Send MIDI note-off into the next process() call.
ReportEntry capture_inspector()
Capture the view inspector tree as JSON.
ValidationHarness(ProcessorFactory factory)
Construct from a processor factory.
float get_param(state::ParamID id) const
Get a parameter value by ID.
bool write_report(const std::filesystem::path &output_path) const
Write the report JSON to a file.
void set_capture_screenshot_provider(CaptureScreenshotProvider p)
Install the screenshot capture provider.
void clear_entries()
Clear all accumulated entries.
Definition validation_harness.hpp:219
void set_param(state::ParamID id, float value)
Set a parameter value by ID.
void add_entry(ReportEntry entry)
Add a report entry to the accumulator.
HeadlessHost & host()
Access the underlying HeadlessHost for advanced use.
Definition validation_harness.hpp:222
const PluginDescriptor & descriptor() const
Access the plugin descriptor.
Definition validation_harness.hpp:226
std::vector< float > process_blocks(int num_blocks)
Process N blocks of silence, returning the final output buffer contents.
bool load_state(std::span< const uint8_t > data)
Load plugin state from a binary blob.
ReportEntry validate_plugin_runtime_manifest(const std::filesystem::path &plugin_path, const std::string &expected_plugin_id="")
Validate the embedded plugin runtime manifest for content-pack support.
void set_capture_inspector_provider(CaptureInspectorProvider p)
Install the inspector capture provider.
Collection of timestamped MIDI events within a single audio buffer period.
Definition buffer.hpp:31
Headless processing adapter for programmatic plugin use without UI or audio device.
Real-time CPU load measurement for audio callbacks.
What the product grants a device: the quota table indexed by capability tier and live thermal state.
Definition aax_editor.hpp:31
std::string_view to_string(PulpIosAudioEvent event)
Human-readable label for an event type (for logs and tests).
ValidationStatus
Result status for individual validation steps.
Definition validation_harness.hpp:20
@ skip
Definition validation_harness.hpp:20
@ pass
Definition validation_harness.hpp:20
@ error
Definition validation_harness.hpp:20
@ fail
Definition validation_harness.hpp:20
std::unique_ptr< Processor >(*)() ProcessorFactory
Factory function type — plugins provide this to create processor instances.
Definition processor.hpp:1416
uint32_t ParamID
Unique parameter identifier, stable across plugin versions.
Definition parameter.hpp:55
Snapshot published by AudioProcessLoadMeasurer.
Definition load_measurer.hpp:25
Definition load_measurer.hpp:42
Plugin metadata — declared once, immutable.
Definition plugin_descriptor.hpp:245
One entry in the validation report (matches report schema).
Definition validation_harness.hpp:34
ValidationStatus status
Definition validation_harness.hpp:36
std::string error_message
Definition validation_harness.hpp:39
double duration_ms
Definition validation_harness.hpp:38
std::string type
Definition validation_harness.hpp:35
std::string target
Definition validation_harness.hpp:37
std::string payload_json
Definition validation_harness.hpp:43
Options for a validation run.
Definition validation_harness.hpp:47
std::string screenshot_backend
Definition validation_harness.hpp:56
float diff_threshold
Definition validation_harness.hpp:60
uint8_t diff_tolerance
Definition validation_harness.hpp:59
std::filesystem::path output_dir
Definition validation_harness.hpp:48
int output_channels
Definition validation_harness.hpp:52
uint32_t screenshot_width
Definition validation_harness.hpp:53
double sample_rate
Definition validation_harness.hpp:49
int input_channels
Definition validation_harness.hpp:51
std::string git_ref
Definition validation_harness.hpp:63
float screenshot_scale
Definition validation_harness.hpp:55
int buffer_size
Definition validation_harness.hpp:50
uint32_t screenshot_height
Definition validation_harness.hpp:54
std::string run_id
Definition validation_harness.hpp:64