33 plugin_name_ = desc.
name;
40 param_snapshot_.clear();
47 snap.default_value = p.range.default_value;
48 snap.min = p.range.min;
49 snap.max = p.range.max;
51 param_snapshot_.push_back(snap);
58 int input_channels,
int output_channels) {
59 sample_rate_ = sample_rate;
60 buffer_size_ = buffer_size;
61 input_channels_ = input_channels;
62 output_channels_ = output_channels;
78 custom_entries_.push_back({key, value});
85 std::ostringstream ss;
86 ss << std::fixed << std::setprecision(2);
88 ss <<
"=== Pulp Diagnostic Report ===\n";
89 ss <<
"Generated: " << timestamp() <<
"\n\n";
92 ss <<
"--- System ---\n";
93 ss <<
"Platform: " << os_name() <<
"\n";
94 ss <<
"Architecture: " << arch() <<
"\n\n";
97 ss <<
"--- Plugin ---\n";
98 ss <<
"Name: " << plugin_name_ <<
"\n";
99 ss <<
"Manufacturer: " << plugin_manufacturer_ <<
"\n";
100 ss <<
"Version: " << plugin_version_ <<
"\n";
101 ss <<
"Bundle ID: " << plugin_bundle_id_ <<
"\n";
102 ss <<
"Type: " << (is_instrument_ ?
"Instrument" :
"Effect") <<
"\n";
103 if (!format_name_.empty()) ss <<
"Format: " << format_name_ <<
"\n";
104 if (!host_name_.empty()) ss <<
"Host: " << host_name_ <<
"\n";
108 ss <<
"--- Audio Configuration ---\n";
109 ss <<
"Sample Rate: " << sample_rate_ <<
" Hz\n";
110 ss <<
"Buffer Size: " << buffer_size_ <<
" samples\n";
111 ss <<
"Input Channels: " << input_channels_ <<
"\n";
112 ss <<
"Output Channels: " << output_channels_ <<
"\n";
113 if (cpu_load_ >= 0) {
114 ss <<
"CPU Load: " << (cpu_load_ * 100.0f) <<
"%\n";
115 ss <<
"CPU Peak: " << (cpu_peak_ * 100.0f) <<
"%\n";
120 ss <<
"--- Parameters (" << param_snapshot_.size() <<
") ---\n";
121 for (
const auto& p : param_snapshot_) {
122 ss <<
" [" << p.id <<
"] " << p.name <<
": "
124 if (!p.unit.empty()) ss <<
" " << p.unit;
125 ss <<
" (norm=" << p.normalized
126 <<
", range=" << p.min <<
".." << p.max
127 <<
", default=" << p.default_value <<
")\n";
132 if (!custom_entries_.empty()) {
133 ss <<
"--- Custom ---\n";
134 for (
const auto& [key, value] : custom_entries_) {
135 ss << key <<
": " << value <<
"\n";
140 ss <<
"=== End Report ===\n";
146 std::ostringstream ss;
147 ss << std::fixed << std::setprecision(4);
150 ss <<
" \"timestamp\": \"" << json_escape(timestamp()) <<
"\",\n";
151 ss <<
" \"platform\": \"" << json_escape(os_name()) <<
"\",\n";
152 ss <<
" \"arch\": \"" << json_escape(arch()) <<
"\",\n";
153 ss <<
" \"plugin\": {\n";
154 ss <<
" \"name\": \"" << json_escape(plugin_name_) <<
"\",\n";
155 ss <<
" \"manufacturer\": \"" << json_escape(plugin_manufacturer_) <<
"\",\n";
156 ss <<
" \"version\": \"" << json_escape(plugin_version_) <<
"\",\n";
157 ss <<
" \"type\": \"" << (is_instrument_ ?
"instrument" :
"effect") <<
"\"\n";
159 ss <<
" \"audio\": {\n";
160 ss <<
" \"sampleRate\": " << sample_rate_ <<
",\n";
161 ss <<
" \"bufferSize\": " << buffer_size_ <<
",\n";
162 ss <<
" \"inputChannels\": " << input_channels_ <<
",\n";
163 ss <<
" \"outputChannels\": " << output_channels_ <<
"\n";
165 ss <<
" \"parameters\": [\n";
166 for (
size_t i = 0; i < param_snapshot_.size(); ++i) {
167 const auto& p = param_snapshot_[i];
168 ss <<
" {\"id\": " << p.id
169 <<
", \"name\": \"" << json_escape(p.name)
170 <<
"\", \"value\": " << p.value
171 <<
", \"normalized\": " << p.normalized <<
"}";
172 if (i + 1 < param_snapshot_.size()) ss <<
",";
181 std::string plugin_name_;
182 std::string plugin_manufacturer_;
183 std::string plugin_version_;
184 std::string plugin_bundle_id_;
185 bool is_instrument_ =
false;
186 std::string format_name_;
187 std::string host_name_;
189 double sample_rate_ = 0;
190 int buffer_size_ = 0;
191 int input_channels_ = 0;
192 int output_channels_ = 0;
193 float cpu_load_ = -1;
194 float cpu_peak_ = -1;
196 struct ParamSnapshot {
200 float normalized = 0;
201 float default_value = 0;
202 float min = 0, max = 0;
205 std::vector<ParamSnapshot> param_snapshot_;
206 std::vector<std::pair<std::string, std::string>> custom_entries_;
208 static std::string timestamp() {
209 auto now = std::time(
nullptr);
212 std::strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &local);
216 static std::string json_escape(
const std::string& text) {
218 out.reserve(text.size());
219 for (
unsigned char c : text) {
221 case '\"': out +=
"\\\"";
break;
222 case '\\': out +=
"\\\\";
break;
223 case '\b': out +=
"\\b";
break;
224 case '\f': out +=
"\\f";
break;
225 case '\n': out +=
"\\n";
break;
226 case '\r': out +=
"\\r";
break;
227 case '\t': out +=
"\\t";
break;
230 static constexpr char hex[] =
"0123456789abcdef";
232 out += hex[(c >> 4) & 0x0f];
233 out += hex[c & 0x0f];
235 out.push_back(
static_cast<char>(c));
243 static std::string os_name() {
250 default:
return "Unknown";
254 static std::string arch() {
255#if defined(__aarch64__) || defined(_M_ARM64)
257#elif defined(__x86_64__) || defined(_M_X64)
259#elif defined(__i386__) || defined(_M_IX86)
Centralized parameter storage with lock-free value access.
Definition store.hpp:164
float get_value(ParamID id) const
Read a parameter's base value (lock-free).
Definition store.hpp:186
float get_normalized(ParamID id) const
Read a parameter's value mapped to [0, 1] (lock-free).
std::span< const ParamInfo > all_params() const
View of all registered parameters (in registration order).
Definition store.hpp:439
std::tm localtime_local(std::time_t value)
Definition system.hpp:44
uint32_t ParamID
Unique parameter identifier, stable across plugin versions.
Definition parameter.hpp:55