summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/gtkui/widgets.c65
-rw-r--r--streamer.c32
2 files changed, 68 insertions, 29 deletions
diff --git a/plugins/gtkui/widgets.c b/plugins/gtkui/widgets.c
index 73432d82..9eee7ea8 100644
--- a/plugins/gtkui/widgets.c
+++ b/plugins/gtkui/widgets.c
@@ -137,6 +137,8 @@ typedef struct {
#endif
float *samples;
int nsamples;
+ int resized;
+ intptr_t mutex;
} w_scope_t;
// spectrum analyzer based on cairo-spectrum from audacious
@@ -2265,6 +2267,10 @@ w_scope_destroy (ddb_gtkui_widget_t *w) {
free (s->samples);
s->samples = NULL;
}
+ if (s->mutex) {
+ deadbeef->mutex_free (s->mutex);
+ s->mutex = 0;
+ }
}
gboolean
@@ -2277,6 +2283,26 @@ w_scope_draw_cb (void *data) {
static void
scope_wavedata_listener (void *ctx, int type, ddb_waveformat_t *fmt, const float *data, int in_samples) {
w_scope_t *w = ctx;
+ if (w->nsamples != w->resized) {
+ deadbeef->mutex_lock (w->mutex);
+ float *oldsamples = w->samples;
+ int oldnsamples = w->nsamples;
+ w->samples = NULL;
+ w->nsamples = w->resized;
+ if (w->nsamples > 0) {
+ w->samples = malloc (sizeof (float) * w->nsamples);
+ memset (w->samples, 0, sizeof (float) * w->nsamples);
+ if (oldsamples) {
+ int n = min (oldnsamples, w->nsamples);
+ memcpy (w->samples + w->nsamples - n, oldsamples + oldnsamples - n, n * sizeof (float));
+ }
+ }
+ if (oldnsamples) {
+ free (oldsamples);
+ }
+ deadbeef->mutex_unlock (w->mutex);
+ }
+
if (w->samples) {
// append
float ratio = fmt->samplerate / 44100.f;
@@ -2303,36 +2329,33 @@ scope_draw_cairo (GtkWidget *widget, cairo_t *cr, gpointer user_data) {
w_scope_t *w = user_data;
- float spp = 1;
- int nsamples = a.width / spp;
+ int nsamples = a.width;
if (w->nsamples != nsamples) {
- float *oldsamples = w->samples;
- int oldnsamples = w->nsamples;
- w->samples = NULL;
- w->nsamples = nsamples;
- if (nsamples > 0) {
- w->samples = malloc (sizeof (float) * nsamples);
- memset (w->samples, 0, sizeof (float) * nsamples);
- if (oldsamples) {
- int n = min (oldnsamples, w->nsamples);
- memcpy (w->samples + w->nsamples - n, oldsamples + oldnsamples - n, n * sizeof (float));
- free (oldsamples);
- }
- }
- else {
- return FALSE;
- }
+ w->resized = nsamples;
+ return FALSE;
}
cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_set_line_width (cr, 1);
- cairo_move_to (cr, 0, ftoi(w->samples[0] * a.height/2 + a.height/2));
+ deadbeef->mutex_lock (w->mutex);
float incr = a.width / (float)w->nsamples;
+ float h = a.height;
+ if (h > 50) {
+ h -= 20;
+ }
+ if (h > 100) {
+ h -= 40;
+ }
+ h /= 2;
+ float hh = a.height/2.f;
+
+ cairo_move_to (cr, 0, ftoi(w->samples[0] * h + hh));
for (int i = 1; i < w->nsamples; i += 2) {
- float y = w->samples[i] * a.height/2 + a.height/2;
+ float y = w->samples[i] * h + hh;
cairo_line_to (cr, i, y);
}
+ deadbeef->mutex_unlock (w->mutex);
cairo_stroke (cr);
return FALSE;
@@ -2450,6 +2473,8 @@ w_scope_create (void) {
GDK_GL_MODE_DOUBLE));
gboolean cap = gtk_widget_set_gl_capability (w->drawarea, conf, NULL, TRUE, GDK_GL_RGBA_TYPE);
#endif
+
+ w->mutex = deadbeef->mutex_create ();
gtk_widget_show (w->drawarea);
gtk_container_add (GTK_CONTAINER (w->base.widget), w->drawarea);
#if !GTK_CHECK_VERSION(3,0,0)
diff --git a/streamer.c b/streamer.c
index 694b587f..5db60e7a 100644
--- a/streamer.c
+++ b/streamer.c
@@ -105,6 +105,7 @@ static char streambuffer[STREAM_BUFFER_SIZE];
static int bytes_until_next_song = 0;
static uintptr_t mutex;
static uintptr_t decodemutex;
+static uintptr_t wdl_mutex; // wavedata listener
static int nextsong = -1;
static int nextsong_pstate = -1;
static int badsong = -1;
@@ -1890,6 +1891,7 @@ streamer_init (void) {
#endif
mutex = mutex_create ();
decodemutex = mutex_create ();
+ wdl_mutex = mutex_create ();
ringbuf_init (&streamer_ringbuf, streambuffer, STREAM_BUFFER_SIZE);
@@ -1915,7 +1917,6 @@ streamer_free (void) {
streamer_abort_files ();
streaming_terminate = 1;
thread_join (streamer_tid);
- mutex_free (decodemutex);
if (streaming_track) {
pl_item_unref (streaming_track);
@@ -1936,9 +1937,12 @@ streamer_free (void) {
ctmap_free ();
ctmap_free_mutex ();
+ mutex_free (decodemutex);
decodemutex = 0;
mutex_free (mutex);
mutex = 0;
+ mutex_free (wdl_mutex);
+ wdl_mutex = 0;
streamer_dsp_chain_save();
@@ -2291,11 +2295,13 @@ streamer_read (char *bytes, int size) {
float temp_audio_data[in_frames * out_fmt.channels];
pcm_convert (&output->fmt, bytes, &out_fmt, (char *)temp_audio_data, sz);
+ mutex_lock (wdl_mutex);
for (wavedata_listener_t *l = wavedata_listeners; l; l = l->next) {
if (l->type == DDB_AUDIO_WAVEFORM) {
l->callback (l->ctx, l->type, &out_fmt, temp_audio_data, in_frames);
}
}
+ mutex_unlock (wdl_mutex);
int remaining = in_frames;
do {
@@ -2306,11 +2312,13 @@ streamer_read (char *bytes, int size) {
remaining -= sz;
if (audio_data_fill == DDB_FREQ_BANDS) {
calc_freq (audio_data, freq_data);
+ mutex_lock (wdl_mutex);
for (wavedata_listener_t *l = wavedata_listeners; l; l = l->next) {
if (l->type == DDB_AUDIO_FREQ) {
l->callback (l->ctx, l->type, &out_fmt, freq_data, DDB_FREQ_BANDS);
}
}
+ mutex_unlock (wdl_mutex);
audio_data_fill = 0;
}
} while (remaining > 0);
@@ -2588,6 +2596,7 @@ streamer_notify_order_changed (int prev_order, int new_order) {
void
register_continuous_wavedata_listener (void *ctx, int type, void (*callback)(void *ctx, int type, ddb_waveformat_t *fmt, const float *data, int nsamples)) {
+ mutex_lock (wdl_mutex);
wavedata_listener_t *l = malloc (sizeof (wavedata_listener_t));
memset (l, 0, sizeof (wavedata_listener_t));
l->ctx = ctx;
@@ -2595,21 +2604,26 @@ register_continuous_wavedata_listener (void *ctx, int type, void (*callback)(voi
l->callback = callback;
l->next = wavedata_listeners;
wavedata_listeners = l;
+ mutex_unlock (wdl_mutex);
}
void
unregister_continuous_wavedata_listener (void *ctx, int type) {
+ mutex_lock (wdl_mutex);
wavedata_listener_t *l, *prev = NULL;
- for (l = wavedata_listeners; l && l->ctx != ctx && l->type != type; prev = l, l = l->next);
- if (l) {
- if (prev) {
- prev->next = l->next;
- }
- else {
- wavedata_listeners = l->next;
+ for (l = wavedata_listeners; l; prev = l, l = l->next) {
+ if (l->ctx == ctx && l->type == type) {
+ if (prev) {
+ prev->next = l->next;
+ }
+ else {
+ wavedata_listeners = l->next;
+ }
+ free (l);
+ break;
}
- free (l);
}
+ mutex_unlock (wdl_mutex);
}
void