From bd608eb3b01596e36390f7f40ac4f8d70fe9d602 Mon Sep 17 00:00:00 2001 From: Dnechita Date: Mon, 17 Feb 2014 13:24:09 +0000 Subject: [PATCH] PLUGINS: Allow plugins to get access to the markers (functional now) --- datatypes.h | 2 + osc.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++-- oscplot.c | 76 ++++++++++++++++++ oscplot.h | 10 ++- 4 files changed, 310 insertions(+), 6 deletions(-) diff --git a/datatypes.h b/datatypes.h index e7f77d0fa..293e8ca3b 100644 --- a/datatypes.h +++ b/datatypes.h @@ -125,6 +125,8 @@ struct _fft_settings { gfloat fft_pwr_off; struct _fft_alg_data fft_alg_data; struct marker_type *markers; + struct marker_type *markers_copy; + GMutex *marker_lock; enum marker_types *marker_type; }; diff --git a/osc.c b/osc.c index 1e201365f..fef23531d 100644 --- a/osc.c +++ b/osc.c @@ -311,6 +311,12 @@ static void do_fft(Transform *tr) } } + if (settings->markers_copy) { + memcpy(settings->markers_copy, settings->markers, + sizeof(struct marker_type) * MAX_MARKERS); + settings->markers_copy = NULL; + g_mutex_unlock(settings->marker_lock); + } } } @@ -854,6 +860,21 @@ static void detach_plugin(GtkToolButton *btn, gpointer data) gtk_widget_show_all(vbox); } +const char * device_name_check(const char *device_name) +{ + int i; + + if (!device_name) + return NULL; + + for (i = 0; i < num_devices; i++) { + if (strcmp(device_name, device_list[i].device_name) == 0) + return device_list[i].device_name; + } + + return NULL; +} + void * find_device_by_name(const char *device_name) { int i; @@ -869,27 +890,71 @@ void * find_device_by_name(const char *device_name) return NULL; } +static OscPlot * find_a_fft_plot(GList *list) +{ + OscPlot *plot; + GList *node; + + for (node = list; node; node = g_list_next(node)) { + plot = node->data; + if (osc_plot_get_plot_domain(plot) == FFT_PLOT) + return plot; + } + + return NULL; +} + /* * helper functions for plugins which want to look at data */ const void * plugin_get_device_by_reference(const char * device_name) { - return find_device_by_name(device_name); + return device_name_check(device_name); } enum marker_types plugin_get_marker_type(const char *device) { - return MARKER_NULL; + OscPlot *fft_plot; + + if (!device) + return 0; + fft_plot = find_a_fft_plot(plot_list); + if (!fft_plot) + return MARKER_NULL; + if (!strcmp(osc_plot_get_active_device(fft_plot), device)) + return MARKER_NULL; + + return osc_plot_get_marker_type(fft_plot); } void plugin_set_marker_type(const char *device, enum marker_types type) { + OscPlot *fft_plot; + + if (!device) + return; + fft_plot = find_a_fft_plot(plot_list); + if (!fft_plot) + return; + if (!strcmp(osc_plot_get_active_device(fft_plot), device)) + return; + osc_plot_set_marker_type(fft_plot, type); } gdouble plugin_get_fft_avg(const char *device) { - return 1; + OscPlot *fft_plot; + + if (!device) + return 0; + fft_plot = find_a_fft_plot(plot_list); + if (!fft_plot) + return 0; + if (!strcmp(osc_plot_get_active_device(fft_plot), device)) + return 0; + + return osc_plot_get_fft_avg(fft_plot); } int plugin_data_capture_size(const char *device) @@ -928,7 +993,160 @@ int plugin_data_capture_bytes_per_sample(const char *device) int plugin_data_capture(const char *device, void **buf, gfloat ***cooked_data, struct marker_type **markers_cp) { - return 0; + OscPlot *fft_plot; + struct _device_list *dev, *tmp_dev = NULL; + struct marker_type *markers_copy; + GMutex *markers_lock; + bool is_fft_mode; + int i, j; + bool new = FALSE; + char *tmp = NULL; + + dev = find_device_by_name(device); + fft_plot = find_a_fft_plot(plot_list); + if (fft_plot) { + tmp = osc_plot_get_active_device(fft_plot); + tmp_dev = find_device_by_name(tmp); + } + + /* if there isn't anything to send, clear everything */ + if (dev == NULL || dev->data_buffer.size == 0) { + if (buf && *buf) { + g_free(*buf); + *buf = NULL; + } + if (cooked_data && *cooked_data) { + if (tmp_dev) + for (i = 0; i < tmp_dev->num_active_channels; i++) + if ((*cooked_data)[i]) + g_free((*cooked_data)[i]); + g_free(*cooked_data); + *cooked_data = NULL; + } + if (markers_cp && *markers_cp) { + if (*markers_cp) + g_free(*markers_cp); + *markers_cp = NULL; + } + return -ENXIO; + } + + if (!dev) + return -ENXIO; + + if (buf) { + /* One consumer at a time */ + if (dev->data_buffer.data_copy) + return -EBUSY; + + /* make sure space is allocated */ + if (*buf) + *buf = g_renew(int8_t, *buf, dev->data_buffer.size); + else + *buf = g_new(int8_t, dev->data_buffer.size); + + if (!*buf) + goto capture_malloc_fail; + + /* where to put the copy */ + dev->data_buffer.data_copy = *buf; + + /* Wait til the buffer is full */ + G_LOCK(buffer_full); + + /* if the lock is released, but the copy is still there + * that's because someone else broke the lock + */ + if (dev->data_buffer.data_copy) { + dev->data_buffer.data_copy = NULL; + return -EINTR; + } + + if (cooked_data) { + /* make sure space is allocated */ + if (*cooked_data) { + *cooked_data = g_renew(gfloat *, *cooked_data, + dev->num_active_channels); + new = false; + } else { + *cooked_data = g_new(gfloat *, dev->num_active_channels); + new = true; + } + + if (!*cooked_data) + goto capture_malloc_fail; + + for (i = 0; i < dev->num_active_channels; i++) { + if (new) + (*cooked_data)[i] = g_new(gfloat, + dev->data_buffer.size / dev->bytes_per_sample); + else + (*cooked_data)[i] = g_renew(gfloat, + (*cooked_data)[i], + dev->data_buffer.size / dev->bytes_per_sample); + if (!(*cooked_data)[i]) + goto capture_malloc_fail; + + for (j = 0; j < dev->data_buffer.size / dev->bytes_per_sample; j++) + (*cooked_data)[i][j] = 0.0f; + } + + /* Now that we have the space, process it */ + demux_data_stream(*buf, *cooked_data, + dev->data_buffer.size / 4, 0, dev->data_buffer.size / 4, + dev->channel_list, dev->num_active_channels); + } + } + + if (!fft_plot) { + is_fft_mode = false; + } else { + markers_copy = (struct marker_type *)osc_plot_get_markers_copy(fft_plot); + markers_lock = osc_plot_get_marker_lock(fft_plot); + } + + if (markers_cp) { + if (!is_fft_mode) { + if (*markers_cp) { + g_free(*markers_cp); + *markers_cp = NULL; + } + return 0; + + } + + /* One consumer at a time */ + if (markers_copy) + return -EBUSY; + + /* make sure space is allocated */ + if (*markers_cp) + *markers_cp = g_renew(struct marker_type, *markers_cp, MAX_MARKERS + 2); + else + *markers_cp = g_new(struct marker_type, MAX_MARKERS + 2); + + if (!*markers_cp) + goto capture_malloc_fail; + + /* where to put the copy */ + osc_plot_set_markers_copy(fft_plot, *markers_cp); + + /* Wait til the copy is complete */ + g_mutex_lock(markers_lock); + + /* if the lock is released, but the copy is still here + * that's because someone else broke the lock + */ + if (markers_copy) { + osc_plot_set_markers_copy(fft_plot, NULL); + return -EINTR; + } + } + return 0; + +capture_malloc_fail: + printf("%s:%s malloc failed\n", __FILE__, __func__); + return -ENOMEM; } static bool force_plugin(const char *name) @@ -1180,6 +1398,7 @@ static void resize_device_data(struct _device_list *device) device->data_buffer.size = device->sample_count * device->bytes_per_sample; device->data_buffer.data = g_renew(int8_t, device->data_buffer.data, device->data_buffer.size); device->data_buffer.available = 0; + device->data_buffer.data_copy = NULL; device->current_sample = 0; k = 0; for (i = 0; i < device->num_channels; i++) { @@ -1235,7 +1454,6 @@ static void start(OscPlot *plot, gboolean start_event) close_active_buffers(); /* Start the capture process */ - G_UNLOCK(buffer_full); capture_setup(); capture_start(); restart_all_running_plots(); diff --git a/oscplot.c b/oscplot.c index 2c342beb0..290b69b72 100644 --- a/oscplot.c +++ b/oscplot.c @@ -214,6 +214,7 @@ struct _OscPlotPrivate /* The set of markers */ struct marker_type markers[MAX_MARKERS + 2]; + struct marker_type *markers_copy; enum marker_types marker_type; /* Settings list of all channel */ @@ -245,6 +246,8 @@ struct _OscPlotPrivate gfloat plot_top; gfloat plot_bottom; int read_scale_params; + + GMutex g_marker_copy_lock; }; struct channel_settings { @@ -384,6 +387,62 @@ void osc_plot_save_as (OscPlot *plot, char *filename, int type) save_as(plot, filename, type); } +char * osc_plot_get_active_device (OscPlot *plot) +{ + OscPlotPrivate *priv = plot->priv; + GtkTreeModel *model; + GtkTreeIter iter; + gboolean next_iter; + gboolean active; + struct _device_list *device; + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(priv->channel_list_view)); + next_iter = gtk_tree_model_get_iter_first(model, &iter); + while (next_iter) { + gtk_tree_model_get(model, &iter, ELEMENT_REFERENCE, &device, DEVICE_ACTIVE, &active, -1); + if (active) + return device->device_name; + next_iter = gtk_tree_model_iter_next(model, &iter); + } + + return NULL; +} + +int osc_plot_get_fft_avg (OscPlot *plot) +{ + return gtk_spin_button_get_value(GTK_SPIN_BUTTON(plot->priv->fft_avg_widget)); +} + +int osc_plot_get_marker_type (OscPlot *plot) +{ + return plot->priv->marker_type; +} + +void osc_plot_set_marker_type (OscPlot *plot, int mtype) +{ + plot->priv->marker_type = mtype; +} + +void * osc_plot_get_markers_copy(OscPlot *plot) +{ + return plot->priv->markers_copy; +} + +void osc_plot_set_markers_copy (OscPlot *plot, void *value) +{ + plot->priv->markers_copy = value; +} + +int osc_plot_get_plot_domain (OscPlot *plot) +{ + return gtk_combo_box_get_active(GTK_COMBO_BOX(plot->priv->plot_domain)); +} + +GMutex * osc_plot_get_marker_lock (OscPlot *plot) +{ + return &plot->priv->g_marker_copy_lock; +} + static void osc_plot_dispose(GObject *object) { G_OBJECT_CLASS(osc_plot_parent_class)->dispose(object); @@ -607,6 +666,8 @@ static void update_transform_settings(OscPlot *plot, Transform *transform, else FFT_SETTINGS(transform)->fft_alg_data.num_active_channels = 1; FFT_SETTINGS(transform)->markers = NULL; + FFT_SETTINGS(transform)->markers_copy = NULL; + FFT_SETTINGS(transform)->marker_lock = NULL; FFT_SETTINGS(transform)->marker_type = NULL; } else if (plot_type == TIME_PLOT) { TIME_SETTINGS(transform)->num_samples = gtk_spin_button_get_value(GTK_SPIN_BUTTON(priv->sample_count_widget)); @@ -731,7 +792,9 @@ static void add_markers(OscPlot *plot, Transform *transform) transform->has_the_marker = true; priv->tr_with_marker = transform; FFT_SETTINGS(transform)->markers = priv->markers; + FFT_SETTINGS(transform)->markers_copy = priv->markers_copy; FFT_SETTINGS(transform)->marker_type = &priv->marker_type; + FFT_SETTINGS(transform)->marker_lock = &priv->g_marker_copy_lock; } static unsigned int plot_sample_count_get(OscPlot *plot) @@ -1022,6 +1085,8 @@ static void plot_setup(OscPlot *plot) if (priv->tbuf) gtk_text_buffer_set_text(priv->tbuf, empty_text, -1); + priv->markers_copy = NULL; + for (i = 0; i < tr_list->size; i++) { transform = tr_list->transforms[i]; Transform_setup(transform); @@ -1070,6 +1135,9 @@ static void capture_button_clicked_cb(GtkToggleToolButton *btn, gpointer data) collect_parameters_from_plot(plot); remove_all_transforms(plot); devices_transform_assignment(plot); + + g_mutex_trylock(&priv->g_marker_copy_lock); + g_signal_emit(plot, oscplot_signals[CAPTURE_EVENT_SIGNAL], 0, button_state); plot_setup(plot); @@ -1081,6 +1149,10 @@ static void capture_button_clicked_cb(GtkToggleToolButton *btn, gpointer data) } else { priv->stop_redraw = TRUE; dispose_parameters_from_plot(plot); + + g_mutex_trylock(&priv->g_marker_copy_lock); + g_mutex_unlock(&priv->g_marker_copy_lock); + g_signal_emit(plot, oscplot_signals[CAPTURE_EVENT_SIGNAL], 0, button_state); } } @@ -1607,6 +1679,9 @@ static void plot_destroyed (GtkWidget *object, OscPlot *plot) dispose_parameters_from_plot(plot); remove_all_transforms(plot); g_slist_free_full(plot->priv->ch_settings_list, *free); + g_mutex_trylock(&plot->priv->g_marker_copy_lock); + g_mutex_unlock(&plot->priv->g_marker_copy_lock); + if (plot->priv->redraw_function) { g_signal_emit(plot, oscplot_signals[CAPTURE_EVENT_SIGNAL], 0, FALSE); } @@ -3187,6 +3262,7 @@ static void create_plot(OscPlot *plot) gtk_tree_selection_set_mode(tree_selection, GTK_SELECTION_SINGLE); add_grid(plot); check_valid_setup(plot); + g_mutex_init(&priv->g_marker_copy_lock); if (MAX_MARKERS) { priv->marker_type = MARKER_OFF; diff --git a/oscplot.h b/oscplot.h index f653ae383..96c00091c 100644 --- a/oscplot.h +++ b/oscplot.h @@ -32,7 +32,7 @@ struct _OscPlot struct _OscPlotClass { GtkWidgetClass parent_class; - + void (* capture_event) (OscPlot *plot, gboolean start_event); void (* destroy_event) (OscPlot *plot); }; @@ -47,6 +47,14 @@ void osc_plot_draw_stop (OscPlot *plot); void osc_plot_save_to_ini (OscPlot *plot, char *filename); int osc_plot_ini_read_handler (OscPlot *plot, const char *section, const char *name, const char *value); void osc_plot_save_as (OscPlot *plot, char *filename, int type); +char * osc_plot_get_active_device(OscPlot *plot); +int osc_plot_get_fft_avg (OscPlot *plot); +int osc_plot_get_marker_type (OscPlot *plot); +void osc_plot_set_marker_type (OscPlot *plot, int mtype); +void * osc_plot_get_markers_copy (OscPlot *plot); +void osc_plot_set_markers_copy (OscPlot *plot, void *value); +int osc_plot_get_plot_domain (OscPlot *plot); +GMutex * osc_plot_get_marker_lock (OscPlot *plot); G_END_DECLS