summaryrefslogtreecommitdiff
path: root/src/utils
diff options
context:
space:
mode:
authorTanu Kaskinen <tanuk@iki.fi>2012-11-07 16:52:40 +0200
committerTanu Kaskinen <tanuk@iki.fi>2013-02-04 12:07:39 +0200
commit8cb34c69602e0e19c1a51bb9da5258f2fea9d4e6 (patch)
treec4b43352335c144ad44c429af4478e77fedbd838 /src/utils
parent94ac039b8779783dff979c76e093997bf754944a (diff)
pacat: Handle holes in recording streams.
pa_silence_memory() pulls sample-util as a dependency, so it had to be moved from libpulsecore to libpulsecommon. sample-util in turn pulls some more stuff.
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/pacat.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index 2cd8aa588..e7a425520 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -45,6 +45,7 @@
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include <pulsecore/sndfile-util.h>
+#include <pulsecore/sample-util.h>
#define TIME_EVENT_USEC 50000
@@ -59,6 +60,9 @@ static pa_mainloop_api *mainloop_api = NULL;
static void *buffer = NULL;
static size_t buffer_length = 0, buffer_index = 0;
+static void *silence_buffer = NULL;
+static size_t silence_buffer_length = 0;
+
static pa_io_event* stdio_event = NULL;
static pa_proplist *proplist = NULL;
@@ -257,18 +261,18 @@ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) {
return;
}
- pa_assert(data);
pa_assert(length > 0);
- if (buffer) {
+ /* If there is a hole in the stream, we generate silence, except
+ * if it's a passthrough stream in which case we skip the hole. */
+ if (data || !(flags & PA_STREAM_PASSTHROUGH)) {
buffer = pa_xrealloc(buffer, buffer_length + length);
- memcpy((uint8_t*) buffer + buffer_length, data, length);
+ if (data)
+ memcpy((uint8_t *) buffer + buffer_length, data, length);
+ else
+ pa_silence_memory((uint8_t *) buffer + buffer_length, length, &sample_spec);
+
buffer_length += length;
- } else {
- buffer = pa_xmalloc(length);
- memcpy(buffer, data, length);
- buffer_length = length;
- buffer_index = 0;
}
pa_stream_drop(s);
@@ -287,17 +291,27 @@ static void stream_read_callback(pa_stream *s, size_t length, void *userdata) {
return;
}
- pa_assert(data);
pa_assert(length > 0);
+ if (!data && (flags & PA_STREAM_PASSTHROUGH)) {
+ pa_stream_drop(s);
+ continue;
+ }
+
+ if (!data && length > silence_buffer_length) {
+ silence_buffer = pa_xrealloc(silence_buffer, length);
+ pa_silence_memory((uint8_t *) silence_buffer + silence_buffer_length, length - silence_buffer_length, &sample_spec);
+ silence_buffer_length = length;
+ }
+
if (writef_function) {
size_t k = pa_frame_size(&sample_spec);
- if ((bytes = writef_function(sndfile, data, (sf_count_t) (length/k))) > 0)
+ if ((bytes = writef_function(sndfile, data ? data : silence_buffer, (sf_count_t) (length/k))) > 0)
bytes *= (sf_count_t) k;
} else
- bytes = sf_write_raw(sndfile, data, (sf_count_t) length);
+ bytes = sf_write_raw(sndfile, data ? data : silence_buffer, (sf_count_t) length);
if (bytes < (sf_count_t) length)
quit(1);
@@ -1193,6 +1207,7 @@ quit:
pa_mainloop_free(m);
}
+ pa_xfree(silence_buffer);
pa_xfree(buffer);
pa_xfree(server);