summaryrefslogtreecommitdiff
path: root/src/capture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/capture.c')
-rw-r--r--src/capture.c62
1 files changed, 53 insertions, 9 deletions
diff --git a/src/capture.c b/src/capture.c
index f9bb8f5..347cc4c 100644
--- a/src/capture.c
+++ b/src/capture.c
@@ -1,6 +1,6 @@
/*
Instru2Light - Illumine un instrument de musique en temps réel
- Copyright (C) 2012 Ludovic Pouzenc <lpouzenc@gmail.com>
+ Copyright (C) 2012-2013 Ludovic Pouzenc <lpouzenc@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
#include "capture.h"
#include <pulse/pulseaudio.h>
#include <gtk/gtk.h>
+#include <string.h> // memcpy()
#define APP_TITLE "Test 5 lpo"
#define BUFSIZE 1024
@@ -64,7 +65,7 @@ int capture_init(pa_mainloop **m, pa_context **c) {
*m=pa_mainloop_new();
g_assert(*m);
- *c = pa_context_new(pa_mainloop_get_api(*m), APP_TITLE);
+ *c = pa_context_new(pa_mainloop_get_api(*m), APP_TITLE);
g_assert(*c);
pa_context_set_state_callback(*c, context_state_callback, NULL);
@@ -158,11 +159,11 @@ void context_get_source_info_callback(pa_context *c, const pa_source_info *si, i
pa_stream *create_stream(pa_context *c, const pa_source_info *si) {
static const pa_buffer_attr ba={
+ //.maxlength=-1,
.maxlength=-1,
.tlength=1024,
.prebuf=-1,
.minreq=-1,
- //.minreq=256, //For FFT calculus
.fragsize=512
};
@@ -223,19 +224,62 @@ void stream_state_callback(pa_stream *s, void *userdata) {
}
}
-void stream_read_callback(pa_stream *s, size_t nbytes, void *userdata) {
- const void *p;
+void stream_read_callback(pa_stream *s, size_t bytes_new, void *userdata) {
+ const void *pa_data=NULL;
+ void *buf=NULL, *process_data=NULL;
+ size_t bytes_readable, bytes_read, process_size, buf_index=0;
//printf("stream_read_callback %i\n", nbytes);
- if (pa_stream_peek(s, &p, &nbytes) < 0) {
+ bytes_readable = pa_stream_readable_size(s);
+ if (bytes_readable/sizeof(float) < 256) {
+ // If buffer is too small for FFT analysis, wait next time
+ printf("s"); fflush(stdout);
+ return;
+ }
+
+ bytes_read=bytes_readable;
+ if (pa_stream_peek(s, &pa_data, &bytes_read) < 0) {
printf("pa_stream_peek() failed\n");//: %s", pa_strerror(pa_context_errno(context)));
return;
}
+ assert(pa_data);
+ assert(bytes_read>0);
+
+ if (bytes_read == bytes_readable) {
+ // If all is catched at once, no malloc, no memcpy
+ process_data=(void *)pa_data; // FIXME : loss of const modifier is problematic
+ process_size=bytes_read;
+
+ //printf("o"); fflush(stdout);
+ } else {
+ // Need to concatenate buffers
+ printf("M"); fflush(stdout);
+ do {
+ printf("."); fflush(stdout);
+ if (!buf) {
+ buf_index=0;
+ buf = pa_xmalloc(bytes_read);
+ } else {
+ buf = pa_xrealloc(buf, buf_index + bytes_read);
+ }
+
+ memcpy(buf+buf_index, pa_data, bytes_read);
+ buf_index += bytes_read;
+
+ pa_stream_drop(s);
+ if (pa_stream_peek(s, &pa_data, &bytes_read) < 0) {
+ bytes_read=0;
+ printf("!"); fflush(stdout);
+ }
+ } while (bytes_read>0);
+
+ process_data=buf;
+ process_size=buf_index;
+ }
-//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);
+ my_process((float *)process_data, process_size/sizeof(float), pa_stream_get_sample_spec(s)->channels);
+ if (buf) pa_xfree(buf);
pa_stream_drop(s);
}