From 458603b06dff7d7742629d0c79050aa8a5ee501d Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 15 Jan 2024 12:19:37 +0200 Subject: [PATCH] osc: Implement a way to provide custom algorithm for XY plot Usage example: /* define the routine with the algorithm */ static void my_xy_transform(gfloat *x_in, gfloat *y_in, gfloat *x_out, gfloat *y_out, unsigned int length, void *user_data) { unsigned int i; for (i = 0; i < length; ++i) { x_out[i] = some_custom_algorithm(x_in[i]); y_out[i] = some_custom_algorithm(y_in[i]); } } /* Look for an already created plot instance that is configured to display XY data. Then, configure it to call your routine. Make sure that the plot is stopped the first time you set the routine. This is to tell the plot to create some internal buffers first. */ bool plot_is_running = false; OscPlot *xy_plot = plugin_find_plot_with_domain(XY_PLOT); if (xy_plot) { plot_is_running = osc_plot_running_state(xy_plot); if (!plot_is_running) { osc_plot_set_xy_transform(xy_plot, my_xy_transform, NULL); } } Signed-off-by: Dan --- datatypes.h | 3 +++ oscplot.c | 34 +++++++++++++++++++++++++++++++--- oscplot.h | 2 ++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/datatypes.h b/datatypes.h index 55de12310..f533d0cc1 100644 --- a/datatypes.h +++ b/datatypes.h @@ -150,6 +150,9 @@ struct _constellation_settings { gfloat *x_source; gfloat *y_source; unsigned int num_samples; + void (*xy_transform)(gfloat *x_in, gfloat *y_in, gfloat *x_out, gfloat *y_out, + unsigned int length, void *user_data); /* optional */ + void *xy_transform_user_data; /* optional */ }; struct _cross_correlation_settings { diff --git a/oscplot.c b/oscplot.c index ac01c51bb..ab95c8d3f 100644 --- a/oscplot.c +++ b/oscplot.c @@ -418,6 +418,9 @@ struct _OscPlotPrivate void (*quit_callback)(void *user_data); void *qcb_user_data; + void (*xy_transform)(gfloat *x_in, gfloat *y_in, gfloat *x_out, + gfloat *y_out, unsigned int length, void *user_data); + void *xy_transform_user_data; }; G_DEFINE_TYPE_WITH_PRIVATE(OscPlot, osc_plot, GTK_TYPE_WIDGET) @@ -869,6 +872,16 @@ void osc_plot_spect_set_filter_bw(OscPlot *plot, double bw) plot->priv->filter_bw = bw; } +void osc_plot_set_xy_transform(OscPlot *plot, void (*xy_transform)(gfloat *x_in, + gfloat *y_in, gfloat *x_out, gfloat *y_out, unsigned int length, + void *user_data), void *user_data) +{ + g_return_if_fail(plot); + + plot->priv->xy_transform = xy_transform; + plot->priv->xy_transform_user_data = user_data; +} + static void osc_plot_dispose(GObject *object) { G_OBJECT_CLASS(osc_plot_parent_class)->dispose(object); @@ -1862,20 +1875,30 @@ bool constellation_transform_function(Transform *tr, gboolean init_transform) /* Initialize axis */ tr->x_axis_size = axis_length; tr->y_axis_size = axis_length; - tr->x_axis = settings->x_source; - tr->y_axis = settings->y_source; + if (settings->xy_transform) { + Transform_resize_x_axis(tr, axis_length); + Transform_resize_y_axis(tr, axis_length); + } else { + tr->x_axis = settings->x_source; + tr->y_axis = settings->y_source; + } return true; } GSList *node; - if (tr->plot_channels_type == PLOT_MATH_CHANNEL) + if (tr->plot_channels_type == PLOT_MATH_CHANNEL) { for (node = tr->plot_channels; node; node = g_slist_next(node)) { PlotMathChn *m = node->data; m->math_expression(m->iio_channels_data, m->data_ref, settings->num_samples); } + } else if (settings->xy_transform) { + settings->xy_transform( + plot_channels_get_nth_data_ref(tr->plot_channels, 0), plot_channels_get_nth_data_ref(tr->plot_channels, 1), + tr->x_axis, tr->y_axis, settings->num_samples, settings->xy_transform_user_data); + } return true; } @@ -2457,6 +2480,8 @@ static void update_transform_settings(OscPlot *plot, Transform *transform) } } else if (plot_type == XY_PLOT){ CONSTELLATION_SETTINGS(transform)->num_samples = gtk_spin_button_get_value(GTK_SPIN_BUTTON(priv->sample_count_widget)); + CONSTELLATION_SETTINGS(transform)->xy_transform = priv->xy_transform; + CONSTELLATION_SETTINGS(transform)->xy_transform_user_data = priv->xy_transform_user_data; } else if (plot_type == XCORR_PLOT){ int dev_samples = plot_get_sample_count_for_transform(plot, transform); if (dev_samples < 0) @@ -7427,6 +7452,9 @@ static void create_plot(OscPlot *plot) priv->line_thickness = 1; + priv->xy_transform = NULL; + priv->xy_transform_user_data = NULL; + gtk_window_set_modal(GTK_WINDOW(priv->saveas_dialog), FALSE); gtk_widget_show_all(priv->capture_graph); } diff --git a/oscplot.h b/oscplot.h index 70136a72b..0b099d46f 100644 --- a/oscplot.h +++ b/oscplot.h @@ -76,6 +76,8 @@ void osc_plot_spect_mode (OscPlot *plot, bool enable); void osc_plot_spect_set_start_f(OscPlot *plot, double freq_mhz); void osc_plot_spect_set_len (OscPlot *plot, unsigned fft_count); void osc_plot_spect_set_filter_bw(OscPlot *plot, double bw); +void osc_plot_set_xy_transform (OscPlot *plot, void (*xy_transform)(gfloat *x_in, gfloat *y_in, + gfloat *x_out, gfloat *y_out, unsigned int length, void *user_data), void *user_data); G_END_DECLS