diff options
Diffstat (limited to 'src/capture.c')
-rw-r--r-- | src/capture.c | 62 |
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); } |