133 halp_meta(name,
"Audio scope")
134 halp_meta(c_name,
"AudioScope")
135 halp_meta(category,
"Monitoring/Audio")
136 halp_meta(author,
"ossia score")
137 halp_meta(manual_url,
"")
140 "Oscilloscope with edge and pitch triggers, XY display, goniometer and "
141 "phase correlation meter")
142 halp_meta(uuid,
"57966fbd-574f-48cc-9e26-74397352f3dd")
143 halp_flag(fully_custom_item);
148 halp::dynamic_audio_bus<
"Audio",
double> audio;
150 struct : halp::combobox_t<
"Mode", Mode>
154 std::string_view values[4]{
155 mode_names[0], mode_names[1], mode_names[2], mode_names[3]};
156 Mode init{Mode::Oscilloscope};
159 struct : halp::spinbox_f32<
"Window", halp::range{0.1, max_window_ms, 20.}>
161 halp_meta(description,
"Milliseconds shown across the oscilloscope")
163 struct : halp::combobox_t<
"Trigger", Trigger>
167 "Free running, on a rising or falling edge of the first channel, or "
168 "synchronized to its period, two periods across")
171 std::string_view values[4]{
172 trigger_names[0], trigger_names[1], trigger_names[2], trigger_names[3]};
173 Trigger init{Trigger::Rising};
176 struct : halp::spinbox_f32<
"Level", halp::range{-1., 1., 0.}>
178 halp_meta(description,
"Value the trigger edge crosses")
180 struct : halp::hslider_f32<
"Persistence", halp::range{0., 0.98, 0.}>
182 halp_meta(description,
"How long traces linger, as on a phosphor screen")
184 struct : halp::spinbox_f32<
"Gain", halp::range{-24., 48., 0.}>
186 halp_meta(description,
"Vertical gain, in dB")
188 struct : halp::toggle<
"Auto gain">
190 halp_meta(description,
"Scale to the signal's recent peak")
192 struct : halp::spinbox_i32<
"X channel", halp::range{0, 63, 0}>
194 halp_meta(description,
"Channel on the horizontal axis of XY, left channel of the goniometer and correlation")
196 struct : halp::spinbox_i32<
"Y channel", halp::range{0, 63, 1}>
198 halp_meta(description,
"Channel on the vertical axis of XY, right channel of the goniometer and correlation")
200 struct : halp::combobox_t<
"Goniometer", Polar>
204 std::string_view values[3]{polar_names[0], polar_names[1], polar_names[2]};
205 Polar init{Polar::Lissajous};
212 struct : halp::val_port<
"Correlation",
float>
214 halp_meta(description,
"Phase correlation of the two channels, -1 to 1")
216 struct : halp::val_port<
"Balance",
float>
218 halp_meta(description,
"Right minus left RMS level, in dB")
222 std::shared_ptr<ScopeMonitor> monitor = std::make_shared<ScopeMonitor>();
223 ossia::meters::correlation corr;
224 ossia::meters::rms rms_l, rms_r;
231 const double r = s.rate > 0 ? s.rate : 48000.;
235 monitor->ring.set_rate(rate);
236 corr.prepare(rate, 0.3);
237 rms_l.prepare(rate, 0.3);
238 rms_r.prepare(rate, 0.3);
241 void operator()(
int frames)
243 const int nch = inputs.audio.channels;
244 if(nch <= 0 || frames <= 0)
247 if(monitor->watched())
248 monitor->ring.write(nch, frames, [&](
int c) {
return inputs.audio[c]; });
250 const int xc = std::clamp(inputs.x_channel.value, 0, nch - 1);
251 const int yc = std::clamp(inputs.y_channel.value, 0, nch - 1);
252 corr.process(inputs.audio[xc], inputs.audio[yc], frames);
253 rms_l.process(inputs.audio[xc], frames);
254 rms_r.process(inputs.audio[yc], frames);
255 const float k = float(corr.value());
256 monitor->correlation.store(k, std::memory_order_relaxed);
257 outputs.correlation.value = k;
258 outputs.balance.value = float(
259 ossia::detail::LinearGainToDecibels(std::max(rms_r.level(), 1e-6))
260 - ossia::detail::LinearGainToDecibels(std::max(rms_l.level(), 1e-6)));
266 static constexpr int max_shown_channels = 8;
272 QGraphicsItem* parent);
274 void paint_impl(QPainter* p)
const override;
280 Trigger trigger()
const;
283 bool autoGain()
const;
284 float persistence()
const;
291 double currentGain()
const;
292 static void traceInto(
296 QRectF scopeRect()
const;
297 QRectF squareRect()
const;
298 void paintScope(QPainter* p)
const;
299 static void drawTrace(
300 QPainter* p,
const QRectF& r,
const std::vector<float>& x,
double g, QColor col);
301 void paintDots(QPainter* p,
bool gonio)
const;
302 void paintCorrelation(QPainter* p,
const QRectF& area,
bool history =
true)
const;
319 std::vector<std::vector<float>> m_trace;
320 std::vector<float> m_search;
321 double m_window_ms{};
325 std::vector<Ui::Monitor::DensityImage> m_phosphor;
329 std::vector<float> m_xs, m_ys;
332 std::array<float, 90> m_polar_level{};
334 std::array<float, 300> m_corr_history{};
336 uint64_t m_corr_written{};
338 double m_rate{48000.};
Definition ProcessContext.hpp:12