summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2012-06-01 20:21:08 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2012-06-01 20:21:08 +0000
commit70958d6e6d40802c0f6ac0ed55bf704fbe2c9fc3 (patch)
treecb73f0e4552b23eb988a8c3b12d442933f69113b
parentf84862993fca45ffb3190d8e3ca0ae73ad4f2942 (diff)
download2012-violon-leds-70958d6e6d40802c0f6ac0ed55bf704fbe2c9fc3.tar.gz
2012-violon-leds-70958d6e6d40802c0f6ac0ed55bf704fbe2c9fc3.tar.bz2
2012-violon-leds-70958d6e6d40802c0f6ac0ed55bf704fbe2c9fc3.zip
Ecriture du test5 : intégration de PulseAudio dans le code du test4.
Le squelette est là, l'initialisation du contexte pulse audio aussi. Reste : ouvrir les flux, écrire le callback pulse qui récupère le niveau sonore (avec timing si possible) et qui appelle le callback applicatif du test5.c git-svn-id: file:///var/svn/2012-violon-leds/trunk@9 6be1fa4d-33ac-4c33-becc-79fcb3794bb6
-rw-r--r--tests/test5/TOREAD2
-rw-r--r--tests/test5/capture.c82
-rw-r--r--tests/test5/capture.h9
-rwxr-xr-xtests/test5/compil.sh8
-rw-r--r--tests/test5/compute.c42
-rw-r--r--tests/test5/compute.h10
-rw-r--r--tests/test5/gtkvumeter.c261
-rw-r--r--tests/test5/gtkvumeter.h39
-rw-r--r--tests/test5/old/test5.c187
-rw-r--r--tests/test5/test5.c213
-rw-r--r--tests/test5/win_main.c65
-rw-r--r--tests/test5/win_main.h9
12 files changed, 759 insertions, 168 deletions
diff --git a/tests/test5/TOREAD b/tests/test5/TOREAD
new file mode 100644
index 0000000..e84ab7e
--- /dev/null
+++ b/tests/test5/TOREAD
@@ -0,0 +1,2 @@
+http://freedesktop.org/software/pulseaudio/doxygen/async.html#overv_sec
+
diff --git a/tests/test5/capture.c b/tests/test5/capture.c
new file mode 100644
index 0000000..6bc5afe
--- /dev/null
+++ b/tests/test5/capture.c
@@ -0,0 +1,82 @@
+#include "capture.h"
+#include <pulse/pulseaudio.h>
+#include <gtk/gtk.h>
+
+#define APP_TITLE "Test 5 lpo"
+#define BUFSIZE 1024
+
+pa_context *pa_ct=NULL;
+capture_sound_level_cb_t *capture_sound_level_cb=NULL;
+
+int capture_init(pa_mainloop **m);
+void context_state_callback(pa_context *c, void *userdata);
+
+void audio_thread(void *args) {
+ pa_mainloop *m;
+ int res, retval;
+
+ capture_sound_level_cb=(capture_sound_level_cb_t *)args;
+
+ res=capture_init(&m);
+ g_assert(res==0);
+
+ res=pa_mainloop_run(m,&retval);
+ g_assert(res==0);
+ g_assert(retval==0);
+
+// pa_context_disconnect(pa_ct);
+ pa_mainloop_free(m);
+}
+
+int capture_init(pa_mainloop **m) {
+ int res=0;
+
+ *m=pa_mainloop_new();
+ g_assert(*m);
+
+ pa_ct = pa_context_new(pa_mainloop_get_api(*m), APP_TITLE);
+ g_assert(pa_ct);
+
+ pa_context_set_state_callback(pa_ct, context_state_callback, NULL);
+ res=pa_context_connect(pa_ct, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
+
+ return res;
+}
+
+void context_state_callback(pa_context *c, void *userdata) {
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_UNCONNECTED:
+ printf("PA_CONTEXT_UNCONNECTED\n");
+ break;
+ case PA_CONTEXT_CONNECTING:
+ printf("PA_CONTEXT_CONNECTING\n");
+ break;
+ case PA_CONTEXT_AUTHORIZING:
+ printf("PA_CONTEXT_AUTHORIZING\n");
+ break;
+ case PA_CONTEXT_SETTING_NAME:
+ printf("PA_CONTEXT_SETTING_NAME\n");
+ break;
+ case PA_CONTEXT_READY:
+ printf("PA_CONTEXT_READY\n");
+ //g_assert(!stream);
+
+ //if (device_name && mode == RECORD)
+ //pa_operation_unref(pa_context_get_source_info_by_name(c, device_name, context_get_source_info_callback, NULL));
+ /*else if (device_name && mode == PLAYBACK)
+ pa_operation_unref(pa_context_get_sink_info_by_name(c, device_name, context_get_sink_info_callback, NULL));
+ else
+ pa_operation_unref(pa_context_get_server_info(c, context_get_server_info_callback, NULL));
+ */
+ break;
+
+ case PA_CONTEXT_FAILED:
+ printf("PA_CONTEXT_FAILED\n");
+ break;
+
+ case PA_CONTEXT_TERMINATED:
+ printf("PA_CONTEXT_TERMINATED\n");
+ break;
+ }
+}
+
diff --git a/tests/test5/capture.h b/tests/test5/capture.h
new file mode 100644
index 0000000..2acbe09
--- /dev/null
+++ b/tests/test5/capture.h
@@ -0,0 +1,9 @@
+#ifndef CAPTURE_H
+#define CAPTURE_H
+#include <gtk/gtk.h>
+
+typedef void(* capture_sound_level_cb_t)(gint sound_level, void *userdata);
+
+void audio_thread(void *args);
+
+#endif /*CAPTURE_H*/
diff --git a/tests/test5/compil.sh b/tests/test5/compil.sh
index 6ca9982..e69ee99 100755
--- a/tests/test5/compil.sh
+++ b/tests/test5/compil.sh
@@ -1,3 +1,7 @@
#!/bin/bash -ex
-gcc -Wall -g -c test5.c $(pkg-config --cflags gtk+-2.0 libpulse libpulse-mainloop-glib)
-gcc -Wall -o test5 test5.o $(pkg-config --libs gtk+-2.0 libpulse libpulse-mainloop-glib)
+gcc -Wall -g -c gtkvumeter.c $(pkg-config --cflags gtk+-2.0)
+gcc -Wall -g -c win_main.c $(pkg-config --cflags gtk+-2.0)
+gcc -Wall -g -c compute.c $(pkg-config --cflags gtk+-2.0)
+gcc -Wall -g -c capture.c $(pkg-config --cflags gtk+-2.0 libpulse)
+gcc -Wall -g -c test5.c $(pkg-config --cflags gtk+-2.0 gthread-2.0 libpulse)
+gcc -Wall -o test5 *.o $(pkg-config --libs gtk+-2.0 gthread-2.0 libpulse)
diff --git a/tests/test5/compute.c b/tests/test5/compute.c
new file mode 100644
index 0000000..11a7f81
--- /dev/null
+++ b/tests/test5/compute.c
@@ -0,0 +1,42 @@
+#include "compute.h"
+
+void audio2hsv_1(gint audio_level, gint *light_h, gint *light_s, gint *light_v) {
+ // Dummy code
+ *light_h=-audio_level;
+ *light_s=audio_level;
+ *light_v=65535;
+}
+
+
+void hsv2rgb(gint h, gint s, gint v, gint *r, gint *g, gint *b) {
+ /*
+ * Purpose:
+ * Convert HSV values to RGB values
+ * All values are in the range [0..65535]
+ */
+ float F, M, N, K;
+ int I;
+
+ if ( s == 0 ) {
+ /*
+ * Achromatic case, set level of grey
+ */
+ *r = v;
+ *g = v;
+ *b = v;
+ } else {
+ I = (int) h/(65535/6); /* should be in the range 0..5 */
+ F = h - I; /* fractional part */
+
+ M = v * (1 - s);
+ N = v * (1 - s * F);
+ K = v * (1 - s * (1 - F));
+
+ if (I == 0) { *r = v; *g = K; *b = M; }
+ if (I == 1) { *r = N; *g = v; *b = M; }
+ if (I == 2) { *r = M; *g = v; *b = K; }
+ if (I == 3) { *r = M; *g = N; *b = v; }
+ if (I == 4) { *r = K; *g = M; *b = v; }
+ if (I == 5) { *r = v; *g = M; *b = N; }
+ }
+}
diff --git a/tests/test5/compute.h b/tests/test5/compute.h
new file mode 100644
index 0000000..2454e56
--- /dev/null
+++ b/tests/test5/compute.h
@@ -0,0 +1,10 @@
+#ifndef COMPUTE_H
+#define COMPUTE_H
+
+#include <gtk/gtk.h>
+
+void audio2hsv_1(gint audio_level, gint *light_h, gint *light_s, gint *light_v);
+void hsv2rgb(gint h, gint s, gint v, gint *r, gint *g, gint *b);
+
+#endif
+
diff --git a/tests/test5/gtkvumeter.c b/tests/test5/gtkvumeter.c
new file mode 100644
index 0000000..cb0f9d7
--- /dev/null
+++ b/tests/test5/gtkvumeter.c
@@ -0,0 +1,261 @@
+#include <string.h>
+#include "gtkvumeter.h"
+
+#define MIN_HORIZONTAL_VUMETER_WIDTH 40
+#define HORIZONTAL_VUMETER_HEIGHT 20
+#define VERTICAL_VUMETER_WIDTH 20
+#define MIN_VERTICAL_VUMETER_HEIGHT 40
+
+G_DEFINE_TYPE (GtkVuMeter, gtk_vu_meter, GTK_TYPE_DRAWING_AREA);
+
+static GdkColor default_f_gradient_keys[3] = {{0,65535,0,0},{0,65535,65535,0},{0,0,65535,0}};
+static GdkColor default_b_gradient_keys[3] = {{0,49151,0,0},{0,49151,49151,0},{0,0,49151,0}};
+
+static gboolean gtk_vu_meter_expose (GtkWidget *vumeter, GdkEventExpose *event);
+static void gtk_vu_meter_setup_colors (GtkVuMeter *vumeter);
+static void gtk_vu_meter_free_colors (GtkVuMeter *vumeter);
+static void free_drawbuf(guchar *pixels, gpointer data);
+static void gtk_vu_meter_size_request (GtkWidget *widget, GtkRequisition *requisition);
+static void gtk_vu_meter_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
+static gint gtk_vu_meter_sound_level_to_draw_level (GtkVuMeter *vumeter);
+
+static void gtk_vu_meter_class_init (GtkVuMeterClass *class) {
+ GtkWidgetClass *widget_class;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->expose_event = gtk_vu_meter_expose;
+ widget_class->size_request = gtk_vu_meter_size_request;
+ widget_class->size_allocate = gtk_vu_meter_size_allocate;
+}
+
+static void gtk_vu_meter_init (GtkVuMeter *vumeter) {
+ vumeter->vertical=TRUE;
+ gtk_vu_meter_set_gradient(vumeter, 3, default_f_gradient_keys, 3, default_b_gradient_keys);
+ gtk_vu_meter_setup_colors(vumeter);
+}
+
+void gtk_vu_meter_set_gradient (GtkVuMeter *vumeter, gint f_gradient_key_count, GdkColor *f_gradient_keys, gint b_gradient_key_count, GdkColor *b_gradient_keys) {
+ //XXX : memdup is a bad idea ?
+ GdkColor *fgk = g_memdup(f_gradient_keys, f_gradient_key_count*sizeof(GdkColor));
+ GdkColor *bgk = g_memdup(b_gradient_keys, b_gradient_key_count*sizeof(GdkColor));
+ g_return_if_fail (fgk != NULL);
+ g_return_if_fail (bgk != NULL);
+
+ vumeter->f_gradient_keys = fgk;
+ vumeter->f_gradient_key_count=f_gradient_key_count;
+ vumeter->b_gradient_keys = bgk;
+ vumeter->b_gradient_key_count=b_gradient_key_count;
+}
+static void gtk_vu_meter_free_colors (GtkVuMeter *vumeter) {
+ // TODO : free pixmaps
+}
+
+static void gtk_vu_meter_setup_colors (GtkVuMeter *vumeter) {
+
+ gint i,j;
+ guchar *f_drawbuf, *b_drawbuf, f_r, f_g, f_b, b_r, b_g, b_b;
+ gint f_key_len, b_key_len;
+ gint f_key_i, b_key_i;
+ gdouble f_key_pos, b_key_pos;
+ GdkColor *fgk, *bgk;
+
+ gint h=GTK_WIDGET(vumeter)->allocation.height;
+ gint w=GTK_WIDGET(vumeter)->allocation.width;
+
+ // Clean every previous colors and buffers
+ gtk_vu_meter_free_colors (vumeter);
+
+ if (vumeter->vertical == TRUE) {
+ vumeter->colors = MAX(h, 0);
+ } else {
+ vumeter->colors = MAX(w, 0);
+ }
+
+ // Allocate a memory buffers to hold the gradients
+ f_drawbuf=g_malloc(h*w*3);
+ b_drawbuf=g_malloc(h*w*3);
+ g_return_if_fail (f_drawbuf != NULL);
+ g_return_if_fail (b_drawbuf != NULL);
+
+ // Compute some values before looping for gradient generation
+ f_key_len = vumeter->colors / (vumeter->f_gradient_key_count-1) + 1;
+ b_key_len = vumeter->colors / (vumeter->b_gradient_key_count-1) + 1;
+ fgk=vumeter->f_gradient_keys;
+ bgk=vumeter->b_gradient_keys;
+
+ for (i=0; i<vumeter->colors; i++) {
+ // Compute the current position in the gradient keys
+ f_key_i=i/f_key_len;
+ f_key_pos=((gdouble) (i%f_key_len)/f_key_len);
+ b_key_i=i/f_key_len;
+ b_key_pos=((gdouble) (i%b_key_len)/b_key_len);
+
+ /* Generate the Colours */
+ /* foreground */
+ f_r = ( fgk[f_key_i].red*(1.0-f_key_pos) + fgk[f_key_i+1].red*f_key_pos ) / 256;
+ f_g = ( fgk[f_key_i].green*(1.0-f_key_pos) + fgk[f_key_i+1].green*f_key_pos ) / 256;
+ f_b = ( fgk[f_key_i].blue*(1.0-f_key_pos) + fgk[f_key_i+1].blue*f_key_pos ) / 256;
+ /* background */
+ b_r = ( bgk[b_key_i].red*(1.0-b_key_pos) + bgk[b_key_i+1].red*b_key_pos ) / 256;
+ b_g = ( bgk[b_key_i].green*(1.0-b_key_pos) + bgk[b_key_i+1].green*b_key_pos ) / 256;
+ b_b = ( bgk[b_key_i].blue*(1.0-b_key_pos) + bgk[b_key_i+1].blue*b_key_pos ) / 256;
+
+ /* Apply the color in the drawbufs */
+ if (vumeter->vertical == TRUE) {
+ // Vertical mode : draw directly the whole line of identical color
+ for (j=3*w*i; j<3*w*(i+1); ) {
+ f_drawbuf[j++]=f_r;
+ f_drawbuf[j++]=f_g;
+ f_drawbuf[j++]=f_b;
+ }
+ for (j=3*w*i; j<3*w*(i+1); ) {
+ b_drawbuf[j++]=b_r;
+ b_drawbuf[j++]=b_g;
+ b_drawbuf[j++]=b_b;
+ }
+ } else {
+ // Horiziontal mode : draw only the first line (color change at each pixel)
+ // Others line will be duplicated at the end
+ f_drawbuf[i]=f_r;
+ f_drawbuf[i+1]=f_g;
+ f_drawbuf[i+2]=f_b;
+ b_drawbuf[i]=b_r;
+ b_drawbuf[i+1]=b_g;
+ b_drawbuf[i+2]=b_b;
+ }
+ }
+ if (vumeter->vertical != TRUE) {
+ // Duplicate the first line over the others
+ for (j=1; j<h; j++) {
+ memcpy(f_drawbuf, f_drawbuf+3*w*j, w);
+ }
+ }
+
+ vumeter->f_pixbuf = gdk_pixbuf_new_from_data(f_drawbuf, GDK_COLORSPACE_RGB, FALSE, 8, w, h, w*3, free_drawbuf, NULL);
+ vumeter->b_pixbuf = gdk_pixbuf_new_from_data(b_drawbuf, GDK_COLORSPACE_RGB, FALSE, 8, w, h, w*3, free_drawbuf, NULL);
+}
+
+static void gtk_vu_meter_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+ GtkVuMeter *vumeter;
+
+ g_return_if_fail (GTK_IS_VU_METER (widget));
+ g_return_if_fail (requisition != NULL);
+
+ vumeter = GTK_VU_METER (widget);
+
+ if (vumeter->vertical == TRUE) {
+ requisition->width = VERTICAL_VUMETER_WIDTH;
+ requisition->height = MIN_VERTICAL_VUMETER_HEIGHT;
+ } else {
+ requisition->width = MIN_HORIZONTAL_VUMETER_WIDTH;
+ requisition->height = HORIZONTAL_VUMETER_HEIGHT;
+ }
+}
+
+static void gtk_vu_meter_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+ GtkVuMeter *vumeter;
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_VU_METER (widget));
+ g_return_if_fail (allocation != NULL);
+
+ widget->allocation = *allocation;
+ vumeter = GTK_VU_METER (widget);
+
+ if (GTK_WIDGET_REALIZED (widget)) {
+ if (vumeter->vertical == TRUE) { /* veritcal */
+ gdk_window_move_resize (widget->window, allocation->x, allocation->y,
+ VERTICAL_VUMETER_WIDTH, MAX(allocation->height, MIN_VERTICAL_VUMETER_HEIGHT));
+ } else { /* horizontal */
+ gdk_window_move_resize (widget->window, allocation->x, allocation->y,
+ MAX(allocation->width, MIN_HORIZONTAL_VUMETER_WIDTH), HORIZONTAL_VUMETER_HEIGHT);
+ }
+ /* Fix the colours */
+ gtk_vu_meter_setup_colors (vumeter);
+ }
+}
+
+static void free_drawbuf(guchar *pixels, gpointer data) {
+ g_free(pixels);
+}
+
+static gboolean gtk_vu_meter_expose (GtkWidget *vumeter, GdkEventExpose *event) {
+ //gdk_pixbuf_render_to_drawable(pixbuf, dbuf_pixmap, app->style->fg_gc[GTK_STATE_NORMAL], 0, 0, 0, 0, WIDTH, HEIGHT, GDK_RGB_DITHER_NORMAL, 0, 0);
+ cairo_t *cr;
+ gint draw_level = gtk_vu_meter_sound_level_to_draw_level(GTK_VU_METER(vumeter));
+
+ cr = gdk_cairo_create (vumeter->window);
+
+ // set a clip region for the expose event
+ cairo_rectangle (cr,event->area.x, event->area.y, event->area.width, event->area.height);
+ cairo_clip(cr);
+
+ // Paint from the stored gradient
+ gdk_cairo_set_source_pixbuf(cr, GTK_VU_METER(vumeter)->b_pixbuf,0,0);
+ cairo_paint(cr);
+
+ // set a clip region for the expose event
+ if (GTK_VU_METER(vumeter)->vertical==TRUE) {
+ cairo_rectangle (cr,event->area.x, event->area.y+draw_level, event->area.width, event->area.height-draw_level);
+ } else {
+ //TODO
+ cairo_rectangle (cr,event->area.x, event->area.y, event->area.width, 12/*event->area.height*/);
+ }
+ cairo_clip(cr);
+
+ // Paint from the stored gradient
+ gdk_cairo_set_source_pixbuf(cr, GTK_VU_METER(vumeter)->f_pixbuf,0,0);
+ cairo_paint(cr);
+
+ cairo_destroy(cr);
+
+ return FALSE;
+}
+
+static gint gtk_vu_meter_sound_level_to_draw_level (GtkVuMeter *vumeter) {
+ gint draw_level;
+ gdouble level, min, max, height;
+
+ level = (gdouble)vumeter->level;
+ min = (gdouble)vumeter->min;
+ max = (gdouble)vumeter->max;
+ height = (gdouble)vumeter->colors;
+
+ draw_level = (1.0 - (level - min)/(max - min)) * height;
+
+ //printf("1.0 - (%lf - %lf)/(%lf - %lf)) * %lf => %i\n", level, min, max, min, height, draw_level);
+
+ return draw_level;
+}
+
+GtkWidget * gtk_vu_meter_new (gboolean vertical) {
+ GtkWidget *vumeter = g_object_new (GTK_TYPE_VU_METER, NULL);
+ GTK_VU_METER(vumeter)->vertical=vertical;
+ GTK_VU_METER(vumeter)->level=0;
+ GTK_VU_METER(vumeter)->min=-32767;
+ GTK_VU_METER(vumeter)->max=32767;
+}
+
+
+void gtk_vu_meter_set_min_max (GtkVuMeter *vumeter, gint min, gint max)
+{
+ g_return_if_fail (vumeter != NULL);
+
+ vumeter->max = MAX(max, min);
+ vumeter->min = MIN(min, max);
+ if (vumeter->max == vumeter->min) {
+ vumeter->max++;
+ }
+ vumeter->level = CLAMP (vumeter->level, vumeter->min, vumeter->max);
+ gtk_widget_queue_draw (GTK_WIDGET(vumeter));
+}
+
+void gtk_vu_meter_set_level(GtkVuMeter *vumeter, gint level)
+{
+ g_return_if_fail (vumeter != NULL);
+
+ vumeter->level = CLAMP (level, vumeter->min, vumeter->max);
+ gtk_widget_queue_draw (GTK_WIDGET(vumeter));
+}
+
diff --git a/tests/test5/gtkvumeter.h b/tests/test5/gtkvumeter.h
new file mode 100644
index 0000000..ec7ee67
--- /dev/null
+++ b/tests/test5/gtkvumeter.h
@@ -0,0 +1,39 @@
+#ifndef GTKVUMETER_H
+#define GTKVUMETER_H
+#include <gtk/gtk.h>
+
+#define GTK_TYPE_VU_METER (gtk_vu_meter_get_type ())
+#define GTK_VU_METER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_VU_METER, GtkVuMeter))
+#define GTK_VU_METER_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GTK_VU_METER, GtkVuMeterClass))
+#define GTK_IS_VU_METER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_VU_METER))
+#define GTK_IS_VU_METER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), GTK_TYPE_VU_METER))
+#define GTK_VU_METER_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_VU_METER, GtkVuMeterClass))
+
+typedef struct _GtkVuMeter GtkVuMeter;
+typedef struct _GtkVuMeterClass GtkVuMeterClass;
+
+struct _GtkVuMeter {
+ GtkDrawingArea parent;
+
+ /* private */
+ gboolean vertical;
+ gint level, min, max;
+
+ gint f_gradient_key_count, b_gradient_key_count;
+ GdkColor *f_gradient_keys, *b_gradient_keys;
+
+ gint colors;
+ GdkPixbuf *f_pixbuf, *b_pixbuf;
+};
+
+struct _GtkVuMeterClass {
+ GtkDrawingAreaClass parent_class;
+};
+
+
+GtkWidget * gtk_vu_meter_new (gboolean vertical);
+void gtk_vu_meter_set_gradient (GtkVuMeter *vumeter, gint f_gradient_key_count, GdkColor *f_gradient_keys, gint b_gradient_key_count, GdkColor *b_gradient_keys);
+void gtk_vu_meter_set_min_max (GtkVuMeter *vumeter, gint min, gint max);
+void gtk_vu_meter_set_level(GtkVuMeter *vumeter, gint level);
+
+#endif /*GTKVUMETER_H*/
diff --git a/tests/test5/old/test5.c b/tests/test5/old/test5.c
new file mode 100644
index 0000000..ae9b15f
--- /dev/null
+++ b/tests/test5/old/test5.c
@@ -0,0 +1,187 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <gtk/gtk.h>
+
+#include <pulse/pulseaudio.h>
+#include <pulse/glib-mainloop.h>
+
+#define APP_TITLE "Test 5 lpo"
+#define BUFSIZE 1024
+
+pa_context *context;
+
+void create_stream();
+
+static void stream_state_callback(pa_stream *s, void *unused) {
+ switch (pa_stream_get_state(s)) {
+ case PA_STREAM_UNCONNECTED:
+ case PA_STREAM_CREATING:
+ break;
+
+ case PA_STREAM_READY:
+ printf("PA_STREAM_READY\n");
+/*
+ g_assert(!mainWindow);
+ mainWindow = new MainWindow(*pa_stream_get_channel_map(s), device_name, device_description);
+
+ g_timeout_add(100, latency_func, NULL);
+ pa_operation_unref(pa_stream_update_timing_info(stream, stream_update_timing_info_callback, NULL));
+*/
+ break;
+
+ case PA_STREAM_FAILED:
+ printf("PA_STREAM_FAILED\n");
+ break;
+
+ case PA_STREAM_TERMINATED:
+ printf("PA_STREAM_TERMINATED\n");
+ //Gtk::Main::quit();
+ }
+}
+
+static void context_get_source_info_callback(pa_context *c, const pa_source_info *si, int is_last, void *unused) {
+ printf("context_get_source_info_callback\n");
+
+ if (is_last < 0) {
+ printf("Failed to get source information");
+ return;
+ }
+
+ if (!si)
+ return;
+
+ create_stream(si->name, si->description, si->sample_spec, si->channel_map);
+}
+
+static void context_get_sink_info_callback(pa_context *c, const pa_sink_info *si, int is_last, void *unused) {
+ printf("context_get_sink_info_callback\n");
+ if (is_last < 0) {
+ printf("Failed to get sink information");
+ return;
+ }
+
+ if (!si)
+ return;
+
+ create_stream(si->monitor_source_name, si->description, si->sample_spec, si->channel_map);
+}
+
+
+static void stream_read_callback(pa_stream *s, size_t l, void *unused) {
+ const void *p;
+
+ if (pa_stream_peek(s, &p, &l) < 0) {
+ printf("pa_stream_peek() failed: %s", pa_strerror(pa_context_errno(context)));
+ return;
+ }
+
+ printf("%f, %i\n", *((const float*)p), l/sizeof(float));
+
+ pa_stream_drop(s);
+}
+
+static void context_state_callback(pa_context *c, void *unused) {
+ switch (pa_context_get_state(c)) {
+ case PA_CONTEXT_UNCONNECTED:
+ printf("PA_CONTEXT_UNCONNECTED\n");
+ break;
+ case PA_CONTEXT_CONNECTING:
+ printf("PA_CONTEXT_CONNECTING\n");
+ break;
+ case PA_CONTEXT_AUTHORIZING:
+ printf("PA_CONTEXT_AUTHORIZING\n");
+ break;
+ case PA_CONTEXT_SETTING_NAME:
+ printf("PA_CONTEXT_SETTING_NAME\n");
+ break;
+
+ case PA_CONTEXT_READY:
+ printf("PA_CONTEXT_READY\n");
+ g_assert(!stream);
+
+ //if (device_name && mode == RECORD)
+ //pa_operation_unref(pa_context_get_source_info_by_name(c, device_name, context_get_source_info_callback, NULL));
+ /*else if (device_name && mode == PLAYBACK)
+ pa_operation_unref(pa_context_get_sink_info_by_name(c, device_name, context_get_sink_info_callback, NULL));
+ else
+ pa_operation_unref(pa_context_get_server_info(c, context_get_server_info_callback, NULL));
+ */
+ break;
+
+ case PA_CONTEXT_FAILED:
+ printf("PA_CONTEXT_FAILED\n");
+ break;
+
+ case PA_CONTEXT_TERMINATED:
+ printf("PA_CONTEXT_TERMINATED\n");
+ break;
+ }
+}
+
+void create_stream(const char *name, const char *description, const pa_sample_spec *ss, const pa_channel_map *cmap) {
+ /* The sample type to use */
+ static const pa_sample_spec nss = {
+ .format = PA_SAMPLE_S16LE,
+ .rate = 44100,
+ .channels = 1
+ };
+
+ pa_stream *stream=NULL;
+ char t[256];
+/*
+ g_free(device_name);
+ device_name = g_strdup(name);
+ g_free(device_description);
+ device_description = g_strdup(description);
+*/
+
+ printf("Using sample format: %s", pa_sample_spec_snprint(t, sizeof(t), &nss));
+ printf("Using channel map: %s", pa_channel_map_snprint(t, sizeof(t), cmap));
+
+ stream = pa_stream_new(context, APP_TITLE, &nss, cmap);
+ pa_stream_set_state_callback(stream, stream_state_callback, NULL);
+ pa_stream_set_read_callback(stream, stream_read_callback, NULL);
+ pa_stream_connect_record(stream, name, NULL, (enum pa_stream_flags) 0);
+}
+
+
+int main(int argc, char*argv[]) {
+ int res, retval;
+/*
+ int error;
+ int i,j;
+ float sum;
+ g_thread_init(NULL);
+ gdk_threads_init();
+ gdk_threads_enter();
+ gtk_init (&argc, &argv);
+*/
+
+/* pa_glib_mainloop *m;
+ m = pa_glib_mainloop_new(g_main_context_default()); g_assert(m);
+ context = pa_context_new(pa_glib_mainloop_get_api(m), APP_TITLE); g_assert(context);
+*/
+ pa_mainloop *m;
+ m=pa_mainloop_new(); g_assert(m);
+ context = pa_context_new(pa_mainloop_get_api(m), APP_TITLE); g_assert(context);
+
+ pa_context_set_state_callback(context, context_state_callback, NULL);
+ pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
+
+ res=pa_mainloop_run(m,&retval);
+ g_assert(res==0);
+ pa_mainloop_free(m);
+
+// gtk_main ();
+// gdk_threads_leave();
+
+ return 0;
+
+}
diff --git a/tests/test5/test5.c b/tests/test5/test5.c
index 373efb0..33ec53d 100644
--- a/tests/test5/test5.c
+++ b/tests/test5/test5.c
@@ -1,176 +1,57 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
#include <gtk/gtk.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include "gtkvumeter.h"
+#include "win_main.h"
+#include "compute.h"
+#include "capture.h"
+
+gint *audio_vumeter_val, *light_h, *light_s, *light_v, *light_r, *light_g, *light_b;
+
+int main (int argc, char **argv) {
+ GtkWidget *mainwin;
+ gint vals_for_vumeters[7]={0,0,0,0,0,0,0}; //sound,h,s,v,r,g,b
+ //Some handy references to the previous array items to make things clear whenever possible
+ audio_vumeter_val=vals_for_vumeters+0;
+ light_h=vals_for_vumeters+1;
+ light_s=vals_for_vumeters+2;
+ light_v=vals_for_vumeters+3;
+ light_r=vals_for_vumeters+4;
+ light_v=vals_for_vumeters+5;
+ light_b=vals_for_vumeters+6;
+
+ pthread_t audio_analyzer;
+
+ g_thread_init(NULL);
+ gdk_threads_init();
+ gdk_threads_enter();
+ gtk_init (&argc, &argv);
+
+ mainwin=win_main_build();
+ gtk_widget_show_all (mainwin);
+
+ pthread_create (&audio_analyzer, (void *)NULL, (void *)audio_thread, (void *)vals_for_vumeters);
+ g_timeout_add (10, win_main_update_vumeters, (gpointer)vals_for_vumeters);
+
+ gtk_main ();
+ gdk_threads_leave();
-#include <pulse/pulseaudio.h>
-#include <pulse/glib-mainloop.h>
-
-#define APP_TITLE "Test 5 lpo"
-#define BUFSIZE 1024
-
-pa_context *context;
-
-void create_stream();
-
-static void stream_state_callback(pa_stream *s, void *unused) {
- switch (pa_stream_get_state(s)) {
- case PA_STREAM_UNCONNECTED:
- case PA_STREAM_CREATING:
- break;
-
- case PA_STREAM_READY:
- printf("PA_STREAM_READY\n");
-/*
- g_assert(!mainWindow);
- mainWindow = new MainWindow(*pa_stream_get_channel_map(s), device_name, device_description);
-
- g_timeout_add(100, latency_func, NULL);
- pa_operation_unref(pa_stream_update_timing_info(stream, stream_update_timing_info_callback, NULL));
-*/
- break;
-
- case PA_STREAM_FAILED:
- printf("PA_STREAM_FAILED\n");
- break;
-
- case PA_STREAM_TERMINATED:
- printf("PA_STREAM_TERMINATED\n");
- //Gtk::Main::quit();
- }
-}
-
-static void context_get_source_info_callback(pa_context *c, const pa_source_info *si, int is_last, void *unused) {
- printf("context_get_source_info_callback\n");
-
- if (is_last < 0) {
- printf("Failed to get source information");
- return;
- }
-
- if (!si)
- return;
-
- create_stream(si->name, si->description, si->sample_spec, si->channel_map);
-}
-
-static void context_get_sink_info_callback(pa_context *c, const pa_sink_info *si, int is_last, void *unused) {
- printf("context_get_sink_info_callback\n");
- if (is_last < 0) {
- printf("Failed to get sink information");
- return;
- }
-
- if (!si)
- return;
-
- create_stream(si->monitor_source_name, si->description, si->sample_spec, si->channel_map);
-}
-
-
-static void stream_read_callback(pa_stream *s, size_t l, void *unused) {
- const void *p;
-
- if (pa_stream_peek(s, &p, &l) < 0) {
- printf("pa_stream_peek() failed: %s", pa_strerror(pa_context_errno(context)));
- return;
- }
-
- printf("%f, %i\n", *((const float*)p), l/sizeof(float));
-
- pa_stream_drop(s);
+ return 0;
}
-static void context_state_callback(pa_context *c, void *unused) {
- switch (pa_context_get_state(c)) {
- case PA_CONTEXT_UNCONNECTED:
- printf("PA_CONTEXT_UNCONNECTED\n");
- break;
- case PA_CONTEXT_CONNECTING:
- printf("PA_CONTEXT_CONNECTING\n");
- break;
- case PA_CONTEXT_AUTHORIZING:
- printf("PA_CONTEXT_AUTHORIZING\n");
- break;
- case PA_CONTEXT_SETTING_NAME:
- printf("PA_CONTEXT_SETTING_NAME\n");
- break;
+void process(gint sound_level, void *userdata) {
- case PA_CONTEXT_READY:
- printf("PA_CONTEXT_READY\n");
- //g_assert(!stream);
+ // Dummy code for audio capture
+ *audio_vumeter_val=sound_level;
- //if (device_name && mode == RECORD)
- //pa_operation_unref(pa_context_get_source_info_by_name(c, device_name, context_get_source_info_callback, NULL));
- /*else if (device_name && mode == PLAYBACK)
- pa_operation_unref(pa_context_get_sink_info_by_name(c, device_name, context_get_sink_info_callback, NULL));
- else
- pa_operation_unref(pa_context_get_server_info(c, context_get_server_info_callback, NULL));
- */
- break;
+ // Transfert Function
+ audio2hsv_1(*audio_vumeter_val,light_h,light_s,light_v);
- case PA_CONTEXT_FAILED:
- printf("PA_CONTEXT_FAILED\n");
- break;
+ // Conversion
+ hsv2rgb(*light_h,*light_s,*light_v,light_r,light_g,light_b);
+
+ // Send to DMX
+ //TODO
- case PA_CONTEXT_TERMINATED:
- printf("PA_CONTEXT_TERMINATED\n");
- break;
- }
}
-void create_stream(const char *name, const char *description, const pa_sample_spec *ss, const pa_channel_map *cmap) {
- /* The sample type to use */
- static const pa_sample_spec nss = {
- .format = PA_SAMPLE_S16LE,
- .rate = 44100,
- .channels = 1
- };
-
- pa_stream *stream=NULL;
- char t[256];
-/*
- g_free(device_name);
- device_name = g_strdup(name);
- g_free(device_description);
- device_description = g_strdup(description);
-*/
-
- printf("Using sample format: %s", pa_sample_spec_snprint(t, sizeof(t), &nss));
- printf("Using channel map: %s", pa_channel_map_snprint(t, sizeof(t), cmap));
-
- stream = pa_stream_new(context, APP_TITLE, &nss, cmap);
- pa_stream_set_state_callback(stream, stream_state_callback, NULL);
- pa_stream_set_read_callback(stream, stream_read_callback, NULL);
- pa_stream_connect_record(stream, name, NULL, (enum pa_stream_flags) 0);
-}
-
-
-int main(int argc, char*argv[]) {
-/*
- int ret = 1;
- int error;
- int i,j;
- float sum;
-*/
- pa_glib_mainloop *m;
-
- m = pa_glib_mainloop_new(g_main_context_default());
-// g_assert(m);
-
- context = pa_context_new(pa_glib_mainloop_get_api(m), APP_TITLE);
-// g_assert(context);
-
- pa_context_set_state_callback(context, context_state_callback, NULL);
- pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
-
- sleep(60);
-
- return 0;
-}
diff --git a/tests/test5/win_main.c b/tests/test5/win_main.c
new file mode 100644
index 0000000..4229c40
--- /dev/null
+++ b/tests/test5/win_main.c
@@ -0,0 +1,65 @@
+#include "win_main.h"
+#include "gtkvumeter.h"
+
+GtkWidget *vumeter_sound, *vumeter_r, *vumeter_g, *vumeter_b, *vumeter_h, *vumeter_s, *vumeter_v;
+
+GtkWidget *win_main_build() {
+ GtkWidget *win, *hbox1;
+
+ GdkColor f_gradient_red[2] = {{0,65535,0,0},{0,0,0,0}};
+ GdkColor b_gradient_red[2] = {{0,49151,0,0},{0,0,0,0}};
+ GdkColor f_gradient_green[2] = {{0,0,65535,0},{0,0,0,0}};
+ GdkColor b_gradient_green[2] = {{0,0,49151,0},{0,0,0,0}};
+ GdkColor f_gradient_blue[2] = {{0,0,0,65535},{0,0,0,0}};
+ GdkColor b_gradient_blue[2] = {{0,0,0,49151},{0,0,0,0}};
+ GdkColor f_gradient_hue[7] = {{0,65535,0,0},{0,65535,0,65535},{0,0,0,65535},{0,0,65535,65535},{0,0,65535,0},{0,65535,65535,0},{0,65535,0,0}};
+ GdkColor b_gradient_hue[7] = {{0,49151,0,0},{0,49151,0,49151},{0,0,0,49151},{0,0,49151,49151},{0,0,49151,0},{0,49151,49151,0},{0,49151,0,0}};
+
+ win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+
+ hbox1 = gtk_hbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(win), hbox1);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox1), 5);
+
+//TODO : gtk_vumeter_set_min_max (GTK_VU_METER(vumeter), min, max);
+ vumeter_sound = gtk_vu_meter_new (TRUE);
+ gtk_box_pack_start(GTK_BOX(hbox1), vumeter_sound, FALSE, FALSE, 0);
+
+ vumeter_h = gtk_vu_meter_new (TRUE);
+ gtk_vu_meter_set_gradient(GTK_VU_METER(vumeter_h), 7, f_gradient_hue, 7, b_gradient_hue);
+ gtk_box_pack_start(GTK_BOX(hbox1), vumeter_h, FALSE, FALSE, 0);
+
+ vumeter_s = gtk_vu_meter_new (TRUE);
+ gtk_vu_meter_set_gradient(GTK_VU_METER(vumeter_s), 2, f_gradient_red, 2, b_gradient_red);
+ gtk_box_pack_start(GTK_BOX(hbox1), vumeter_s, FALSE, FALSE, 0);
+
+ vumeter_v = gtk_vu_meter_new (TRUE);
+ gtk_vu_meter_set_gradient(GTK_VU_METER(vumeter_v), 2, f_gradient_red, 2, b_gradient_red);
+ gtk_box_pack_start(GTK_BOX(hbox1), vumeter_v, FALSE, FALSE, 0);
+
+
+ vumeter_r = gtk_vu_meter_new (TRUE);
+ gtk_vu_meter_set_gradient(GTK_VU_METER(vumeter_r), 2, f_gradient_red, 2, b_gradient_red);
+ gtk_box_pack_start(GTK_BOX(hbox1), vumeter_r, FALSE, FALSE, 0);
+
+ vumeter_g = gtk_vu_meter_new (TRUE);
+ gtk_vu_meter_set_gradient(GTK_VU_METER(vumeter_g), 2, f_gradient_green, 2, b_gradient_green);
+ gtk_box_pack_start(GTK_BOX(hbox1), vumeter_g, FALSE, FALSE, 0);
+
+ vumeter_b = gtk_vu_meter_new (TRUE);
+ gtk_vu_meter_set_gradient(GTK_VU_METER(vumeter_b), 2, f_gradient_blue, 2, b_gradient_blue);
+ gtk_box_pack_start(GTK_BOX(hbox1), vumeter_b, FALSE, FALSE, 0);
+
+ return win;
+}
+
+void win_main_update_vumeters(void *vals) {
+ gtk_vu_meter_set_level(GTK_VU_METER(vumeter_sound), ((gint*)vals)[0]);
+ gtk_vu_meter_set_level(GTK_VU_METER(vumeter_h), ((gint*)vals)[1]);
+ gtk_vu_meter_set_level(GTK_VU_METER(vumeter_s), ((gint*)vals)[2]);
+ gtk_vu_meter_set_level(GTK_VU_METER(vumeter_v), ((gint*)vals)[3]);
+ gtk_vu_meter_set_level(GTK_VU_METER(vumeter_r), ((gint*)vals)[4]);
+ gtk_vu_meter_set_level(GTK_VU_METER(vumeter_g), ((gint*)vals)[5]);
+ gtk_vu_meter_set_level(GTK_VU_METER(vumeter_b), ((gint*)vals)[6]);
+}
+
diff --git a/tests/test5/win_main.h b/tests/test5/win_main.h
new file mode 100644
index 0000000..4f0ee1d
--- /dev/null
+++ b/tests/test5/win_main.h
@@ -0,0 +1,9 @@
+#ifndef WIN_MAIN_H
+#define WIN_MAIN_H
+#include <gtk/gtk.h>
+
+GtkWidget *win_main_build();
+void win_main_update_vumeters(void *vals);
+
+#endif
+