summaryrefslogtreecommitdiff
path: root/src/capture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/capture.c')
-rw-r--r--src/capture.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/src/capture.c b/src/capture.c
new file mode 100644
index 0000000..e8ca2fd
--- /dev/null
+++ b/src/capture.c
@@ -0,0 +1,203 @@
+#include "capture.h"
+#include <pulse/pulseaudio.h>
+#include <gtk/gtk.h>
+
+#define APP_TITLE "Test 5 lpo"
+#define BUFSIZE 1024
+
+extern void my_process(float *data, size_t nsamples, size_t nchan);
+
+capture_sound_level_cb_t *capture_sound_level_cb=NULL;
+
+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);
+
+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, &c);
+ 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, pa_context **c) {
+ int res=0;
+
+ *m=pa_mainloop_new();
+ g_assert(*m);
+
+ *c = pa_context_new(pa_mainloop_get_api(*m), APP_TITLE);
+ g_assert(*c);
+
+ pa_context_set_state_callback(*c, context_state_callback, NULL);
+ res=pa_context_connect(*c, 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");
+// 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:
+ printf("PA_CONTEXT_FAILED\n");
+ break;
+
+ case PA_CONTEXT_TERMINATED:
+ printf("PA_CONTEXT_TERMINATED\n");
+ break;
+ }
+}
+
+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) {
+
+ if (is_last < 0) {
+ printf("Failed to get sink information\n");
+ return;
+ }
+
+ if (!si) {
+ return;
+ }
+
+ create_stream(c,si);
+}
+
+pa_stream *create_stream(pa_context *c, const pa_source_info *si) {
+ static const pa_buffer_attr ba={
+ .maxlength=-1,
+ .tlength=1024,
+ .prebuf=-1,
+ .minreq=-1,
+ // .minreq=256, //For FFT calculus
+ .fragsize=512
+ };
+
+ pa_sample_spec nss = {
+ .format = PA_SAMPLE_FLOAT32LE,
+ .rate = si->sample_spec.rate,
+ .channels = si->sample_spec.channels
+ };
+
+ 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), &nss));
+ 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, &nss, &(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("debug : before call capture_sound_level_cb==%p\n", capture_sound_level_cb);
+ my_process((float *)p,nbytes/sizeof(float), pa_stream_get_sample_spec(s)->channels);
+//printf("debug : after call capture_sound_level_cb==%p\n", capture_sound_level_cb);
+
+ pa_stream_drop(s);
+}
+