From 1068de951585f796e8468bf346efa72c9ff84da9 Mon Sep 17 00:00:00 2001
From: Ludovic Pouzenc <ludovic@pouzenc.fr>
Date: Sun, 3 Jun 2012 18:46:30 +0000
Subject: Bientôt fini !! L'appel de la fonction"process" en callback segfaulte
 et je sais pas pourquoi...
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

git-svn-id: file:///var/svn/2012-violon-leds/trunk@10 6be1fa4d-33ac-4c33-becc-79fcb3794bb6
---
 tests/test5/capture.c    | 166 ++++++++++++++++++++++++++++++++++++++++++-----
 tests/test5/compil.sh    |   8 +--
 tests/test5/gtkvumeter.c |   2 +
 tests/test5/gtkvumeter.h |   2 +-
 tests/test5/test5.c      |   6 +-
 tests/test5/win_main.c   |   3 +-
 tests/test5/win_main.h   |   2 +-
 7 files changed, 165 insertions(+), 24 deletions(-)

(limited to 'tests/test5')

diff --git a/tests/test5/capture.c b/tests/test5/capture.c
index 6bc5afe..d003fe8 100644
--- a/tests/test5/capture.c
+++ b/tests/test5/capture.c
@@ -5,19 +5,30 @@
 #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);
+int capture_init(pa_mainloop **m, pa_context **c);
 void context_state_callback(pa_context *c, void *userdata);
+void context_get_server_info_callback(pa_context *c, const pa_server_info*si, void *userdata);
+void context_get_source_info_callback(pa_context *c, const pa_source_info *si, int is_last, void *userdata);
+pa_stream * create_stream(pa_context *c, const pa_source_info *si);
+void stream_state_callback(pa_stream *s, void *userdata);
+void stream_read_callback(pa_stream *s, size_t nbytes, void *userdata);
+gint compute_level(const void *data, size_t nbytes);
 
+char *device_name=NULL;
+
+// Main procedure of this thread
 void audio_thread(void *args) {
+	pa_context *c;
 	pa_mainloop *m;
 	int res, retval;
 
 	capture_sound_level_cb=(capture_sound_level_cb_t *)args;
+
+	printf("debug : args==%p capture_sound_level_cb==%p\n", args, capture_sound_level_cb);
 	
-	res=capture_init(&m);
+	res=capture_init(&m, &c);
 	g_assert(res==0);
 
 	res=pa_mainloop_run(m,&retval);
@@ -28,17 +39,17 @@ void audio_thread(void *args) {
 	pa_mainloop_free(m);
 }
 
-int capture_init(pa_mainloop **m) {
+int capture_init(pa_mainloop **m, pa_context **c) {
 	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);
+        *c = pa_context_new(pa_mainloop_get_api(*m), APP_TITLE);
+	g_assert(*c);
 
-	pa_context_set_state_callback(pa_ct, context_state_callback, NULL);
-	res=pa_context_connect(pa_ct, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
+	pa_context_set_state_callback(*c, context_state_callback, NULL);
+	res=pa_context_connect(*c, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
 
 	return res;
 }
@@ -59,15 +70,12 @@ void context_state_callback(pa_context *c, void *userdata) {
 			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
+//			if (!device_name) {
 				pa_operation_unref(pa_context_get_server_info(c, context_get_server_info_callback, NULL));
-			*/
+/*			} else {
+				pa_operation_unref(pa_context_get_source_info_by_name(c, device_name, context_get_source_info_callback, NULL));
+			}
+*/
 			break;
 
 		case PA_CONTEXT_FAILED:
@@ -80,3 +88,129 @@ void context_state_callback(pa_context *c, void *userdata) {
 	}
 }
 
+void context_get_server_info_callback(pa_context *c, const pa_server_info*si, void *userdata) {
+	if (!si) {
+		printf("Failed to get server information\n");
+		return;
+	}
+
+	if (!si->default_source_name) {
+		printf("No default source set\n");
+		return;
+	}
+
+	pa_operation_unref(pa_context_get_source_info_by_name(c, si->default_source_name, context_get_source_info_callback, NULL));
+
+}
+
+void context_get_source_info_callback(pa_context *c, const pa_source_info *si, int is_last, void *userdata) {
+	static pa_stream* pa_st=NULL;
+
+	if (is_last < 0) {
+		printf("Failed to get sink information\n");
+		return;
+	}
+
+	if (!si) {
+		return;
+	}
+
+	pa_st=create_stream(c,si);
+	g_assert(pa_st);
+}
+
+pa_stream *create_stream(pa_context *c, const pa_source_info *si) {
+	/* The sample type to use 
+	static const pa_sample_spec nss = {
+		.format = PA_SAMPLE_S16LE,
+		.rate = 44100,
+		.channels = 1
+	};
+*/
+	static const pa_buffer_attr ba={
+		.maxlength=-1,
+		.tlength=1024,
+		.prebuf=-1,
+		.minreq=-1,
+		.fragsize=512
+	};
+
+	pa_stream *stream=NULL;
+	//pa_proplist *pl=NULL;
+	char t[256];
+
+/*
+	pa_channel_map cmap;
+	pa_channel_map_init_mono(&cmap);
+	//pa_channel_map_init_stereo(&cmap);
+*/
+
+	printf("Source : %s (%s)\n", si->name, si->description);
+	printf("Using sample format: %s\n", pa_sample_spec_snprint(t, sizeof(t), &(si->sample_spec)));
+	printf("Using channel map: %s\n", pa_channel_map_snprint(t, sizeof(t), &(si->channel_map)));
+/*
+	pl=pa_proplist_new();
+	pa_proplist_set(pl, "maxlength", &pl_maxlength, sizeof(pl_maxlength));
+	pa_proplist_set(pl, "tlength", &pl_tlength, sizeof(pl_tlength));
+	pa_proplist_set(pl, "fragsize", &pl_fragsize, sizeof(pl_fragsize));
+*/
+	stream=pa_stream_new(c, APP_TITLE, &(si->sample_spec), &(si->channel_map));
+	//stream=pa_stream_new_with_proplist(c, APP_TITLE, &(si->sample_spec), &(si->channel_map), pl);
+	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, APP_TITLE, NULL, (enum pa_stream_flags) 0);
+	pa_stream_connect_record(stream, si->name, &ba, PA_STREAM_ADJUST_LATENCY);
+
+	return stream;
+}
+
+void stream_state_callback(pa_stream *s, void *userdata) {
+	switch (pa_stream_get_state(s)) {
+		case PA_STREAM_UNCONNECTED:
+			printf("PA_STREAM_UNCONNECTED\n");
+			break;
+		case PA_STREAM_CREATING:
+			printf("PA_STREAM_CREATING\n");
+			break;
+		case PA_STREAM_READY:
+			printf("PA_STREAM_READY\n");
+			//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");
+			break;
+	}
+}
+
+void stream_read_callback(pa_stream *s, size_t nbytes, void *userdata) {
+	const void *p;
+	//printf("stream_read_callback %i\n", nbytes);
+
+	if (pa_stream_peek(s, &p, &nbytes) < 0) {
+		printf("pa_stream_peek() failed\n");//: %s", pa_strerror(pa_context_errno(context)));
+		return;
+	}
+	printf("level : %i\n", compute_level(p,nbytes));
+
+printf("debug : before call capture_sound_level_cb==%p\n", capture_sound_level_cb);
+	(*capture_sound_level_cb)(compute_level(p,nbytes), NULL);
+printf("debug : after call capture_sound_level_cb==%p\n", capture_sound_level_cb);
+
+	pa_stream_drop(s);
+}
+
+gint compute_level(const void *data, size_t nbytes) {
+	size_t i;
+	gint val, level=0;
+	for (i=0;i<nbytes/2;i++) {
+		val=((int16_t *)data)[i];
+		if (val<0) val=-val;
+		if (level<val) level=val;
+	}
+	return level;
+}
+
diff --git a/tests/test5/compil.sh b/tests/test5/compil.sh
index e69ee99..4875cc1 100755
--- a/tests/test5/compil.sh
+++ b/tests/test5/compil.sh
@@ -1,7 +1,7 @@
 #!/bin/bash -ex
-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 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 test5.c $(pkg-config --cflags gtk+-2.0 gthread-2.0 libpulse)
+gcc -Wall -g -c capture.c $(pkg-config --cflags gtk+-2.0 libpulse)
 gcc -Wall -o test5 *.o $(pkg-config --libs gtk+-2.0 gthread-2.0 libpulse)
diff --git a/tests/test5/gtkvumeter.c b/tests/test5/gtkvumeter.c
index cb0f9d7..d57cc62 100644
--- a/tests/test5/gtkvumeter.c
+++ b/tests/test5/gtkvumeter.c
@@ -235,6 +235,8 @@ GtkWidget * gtk_vu_meter_new (gboolean vertical) {
 	GTK_VU_METER(vumeter)->level=0;
 	GTK_VU_METER(vumeter)->min=-32767;
 	GTK_VU_METER(vumeter)->max=32767;
+
+	return vumeter;
 }
 
 
diff --git a/tests/test5/gtkvumeter.h b/tests/test5/gtkvumeter.h
index ec7ee67..07eb7c5 100644
--- a/tests/test5/gtkvumeter.h
+++ b/tests/test5/gtkvumeter.h
@@ -30,7 +30,7 @@ struct _GtkVuMeterClass {
 	GtkDrawingAreaClass parent_class;
 };
 
-
+GtkType    gtk_vu_meter_get_type (void) G_GNUC_CONST;
 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);
diff --git a/tests/test5/test5.c b/tests/test5/test5.c
index 33ec53d..25dae23 100644
--- a/tests/test5/test5.c
+++ b/tests/test5/test5.c
@@ -7,6 +7,7 @@
 #include "capture.h"
 
 gint *audio_vumeter_val, *light_h, *light_s, *light_v, *light_r, *light_g, *light_b; 
+void process(gint sound_level, void *userdata);
 
 int main (int argc, char **argv) {
 	GtkWidget *mainwin;
@@ -30,7 +31,9 @@ int main (int argc, char **argv) {
 	mainwin=win_main_build();
 	gtk_widget_show_all (mainwin);
 
-	pthread_create (&audio_analyzer, (void *)NULL, (void *)audio_thread, (void *)vals_for_vumeters);
+printf("debug : process==%p\n", process);
+
+	pthread_create (&audio_analyzer, (void *)NULL, (void *)audio_thread, (void *)process);
 	g_timeout_add (10, win_main_update_vumeters, (gpointer)vals_for_vumeters);
 
 	gtk_main ();
@@ -41,6 +44,7 @@ int main (int argc, char **argv) {
 
 void process(gint sound_level, void *userdata) {
 
+	printf("process(%i, %p)\n", sound_level, userdata);
 	// Dummy code for audio capture
 	*audio_vumeter_val=sound_level;
 
diff --git a/tests/test5/win_main.c b/tests/test5/win_main.c
index 4229c40..a139bc9 100644
--- a/tests/test5/win_main.c
+++ b/tests/test5/win_main.c
@@ -53,7 +53,7 @@ GtkWidget *win_main_build() {
 	return win;
 }
 
-void win_main_update_vumeters(void *vals) {
+gboolean win_main_update_vumeters(gpointer 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]);
@@ -61,5 +61,6 @@ void win_main_update_vumeters(void *vals) {
 	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]);
+	return TRUE;
 }
 
diff --git a/tests/test5/win_main.h b/tests/test5/win_main.h
index 4f0ee1d..5068c89 100644
--- a/tests/test5/win_main.h
+++ b/tests/test5/win_main.h
@@ -3,7 +3,7 @@
 #include <gtk/gtk.h>
 
 GtkWidget *win_main_build();
-void win_main_update_vumeters(void *vals);
+gboolean win_main_update_vumeters(gpointer vals);
 
 #endif
 
-- 
cgit v1.2.3