#include "processor.h"
#include "processor-def.h"
-#ifdef __DEBUG__
+#ifdef __PROCESSOR_DEBUG__
#include <stdio.h>
#include <sys/time.h>
#include <sys/stat.h>
#define MEMBLOCKQ_MAXLENGTH (16 * 1024 * 1024)
-#ifdef __DEBUG__
-static void debug_open_file(pa_processor *processor);
-static void debug_timestamp_begin(pa_processor *processor);
-static void debug_timestamp_end(pa_processor *processor);
-static void debug_write_file(pa_processor *processor, int8_t *rec, int8_t *ref, int8_t *out);
-static void debug_close_file(pa_processor *processor);
+#ifdef __PROCESSOR_DEBUG__
+static void pa_processor_debug_open(pa_processor *processor);
+static void pa_processor_debug_write(pa_processor *processor, int8_t *rec, int8_t *ref, int8_t *out);
+static void pa_processor_debug_close(pa_processor *processor);
+static void pa_processor_debug_timestamp_begin(pa_processor *processor);
+static void pa_processor_debug_timestamp_end(pa_processor *processor);
#else
-#define debug_open_file(x)
-#define debug_timestamp_begin(x)
-#define debug_timestamp_end(x)
-#define debug_write_file(x, a, b, c)
-#define debug_close_file(x)
+#define pa_processor_debug_open(x)
+#define pa_processor_debug_write(x, a, b, c)
+#define pa_processor_debug_close(x)
+#define pa_processor_debug_timestamp_begin(x)
+#define pa_processor_debug_timestamp_end(x)
#endif
struct method_info {
pa_usec_to_bytes(processor->process_usec, &processor->ss),
pa_processor_method_str(method));
- debug_open_file(processor);
+ pa_processor_debug_open(processor);
return processor;
if (processor->reference)
pa_processor_reference_free(processor->reference);
- debug_close_file(processor);
+ pa_processor_debug_close(processor);
pa_xfree(processor);
}
return p->process_usec;
}
+bool pa_processor_is_available(pa_processor *processor) {
+ pa_assert(processor);
+
+ if (!processor->reference)
+ return true;
+
+ /* processor will use a silence memblock when bypass is set. */
+ if (pa_processor_reference_get_bypass(processor->reference))
+ return true;
+
+ return pa_processor_reference_is_available(processor->reference);
+}
+
/* Do not touch chunk value */
int pa_processor_process(pa_processor *processor, pa_memchunk *chunk) {
int8_t *recording = NULL;
int8_t *output = NULL;
pa_memchunk rchunk, ochunk;
+ bool use_silence = false;
pa_assert(processor);
pa_assert(processor->result_memblockq);
if (processor->reference) {
if (pa_processor_reference_get_bypass(processor->reference)) {
- if (pa_memblockq_push(processor->result_memblockq, chunk) < 0)
- pa_log_error("Bypass failed to push out chunk to result memblockq");
-
- pa_log_debug("Bypass method(%d:%s). because reference sink isn't working now",
- processor->method, pa_processor_method_str(processor->method));
- return 0;
- }
-
- if (pa_processor_reference_pull(processor->reference, &rchunk) < 0) {
- pa_log_debug("Underrun the reference memblock during a fall duplex situation. Buffering more reference memblocks.");
- return -PROCESSOR_ERR_BUFFERING;
+ /* use silence memblock */
+ use_silence = true;
+ pa_processor_reference_pull_silence(processor->reference, &rchunk);
+ } else {
+ pa_assert(pa_processor_reference_pull(processor->reference, &rchunk) == 0);
}
reference = pa_memblock_acquire_chunk(&rchunk);
recording = (int8_t *)pa_memblock_acquire_chunk(chunk);
output = (int8_t *)pa_memblock_acquire_chunk(&ochunk);
- debug_timestamp_begin(processor);
+ pa_processor_debug_timestamp_begin(processor);
if (audio_effect_process_reference(processor->audio_effect, recording, reference, output) < 0) {
pa_log_warn("Failed to process memchunk");
goto fail;
}
- debug_timestamp_end(processor);
- debug_write_file(processor, recording, reference, output);
+ pa_processor_debug_timestamp_end(processor);
+ pa_processor_debug_write(processor, recording, reference, output);
pa_memblock_release(chunk->memblock);
pa_memblock_release(ochunk.memblock);
if (processor->reference) {
pa_memblock_release(rchunk.memblock);
- pa_processor_reference_drop(processor->reference, &rchunk);
+ pa_processor_reference_drop(processor->reference, &rchunk, use_silence);
}
/* Keep this memchunk for next processor */
if (processor->reference) {
pa_memblock_release(rchunk.memblock);
- pa_processor_reference_drop(processor->reference, &rchunk);
+ pa_processor_reference_drop(processor->reference, &rchunk, use_silence);
}
pa_memblock_unref(ochunk.memblock);
return processor->reference;
}
-#ifdef __DEBUG__
-static void debug_open_file(pa_processor *processor) {
- static int n = 1;
+#ifdef __PROCESSOR_DEBUG__
+static void pa_processor_debug_open(pa_processor *processor) {
char rec[64], ref[64], out[64];
const char *method = pa_processor_method_str(processor->method);
+ int flags = O_CREAT | O_WRONLY | O_TRUNC;
- snprintf(rec, sizeof(rec), "/tmp/processor-%s-rec-%d.raw", method, n);
- snprintf(ref, sizeof(ref), "/tmp/processor-%s-ref-%d.raw", method, n);
- snprintf(out, sizeof(out), "/tmp/processor-%s-out-%d.raw", method, n);
- n += 1;
+ snprintf(rec, sizeof(rec), "/tmp/processor-%s-rec.raw", method);
+ snprintf(ref, sizeof(ref), "/tmp/processor-%s-ref.raw", method);
+ snprintf(out, sizeof(out), "/tmp/processor-%s-out.raw", method);
unlink(rec);
unlink(ref);
unlink(out);
- processor->fdrec = open(rec, O_RDWR | O_CREAT | O_TRUNC, 777);
- processor->fdref = open(ref, O_RDWR | O_CREAT | O_TRUNC, 777);
- processor->fdout = open(out, O_RDWR | O_CREAT | O_TRUNC, 777);
-}
-
-static void debug_timestamp_begin(pa_processor *processor) {
- gettimeofday(&processor->before, NULL);
-}
+ processor->fd_rec = open(rec, flags, 777);
+ if (processor->fd_rec < 0) {
+ pa_log_error("Failed to open an rec dump file");
+ return;
+ }
-static void debug_timestamp_end(pa_processor *processor) {
- gettimeofday(&processor->after, NULL);
+ processor->fd_ref = open(ref, flags, 777);
+ if (processor->fd_ref < 0) {
+ pa_log_error("Failed to open an ref dump file");
+ return;
+ }
- pa_log_debug("It takes time (%ld)ms.",
- 1000 * (processor->after.tv_sec - processor->before.tv_sec)
- + (processor->after.tv_usec - processor->before.tv_usec) / 1000);
+ processor->fd_out = open(out, flags, 777);
+ if (processor->fd_out < 0) {
+ pa_log_error("Failed to open an out dump file");
+ return;
+ }
}
-static void debug_write_file(pa_processor *processor, int8_t *rec, int8_t *ref, int8_t *out) {
- if (rec && write(processor->fdrec, rec, processor->process_bytes) <= 0)
+static void pa_processor_debug_write(pa_processor *processor, int8_t *rec, int8_t *ref, int8_t *out) {
+ pa_assert(processor);
+ pa_assert(rec);
+ pa_assert(out);
+
+ if (write(processor->fd_rec, rec, processor->process_bytes) <= 0)
pa_log_error("Failed to write recording buffer");
- if (ref && write(processor->fdref, ref, pa_processor_reference_process_usec_to_bytes(processor->reference)) <= 0)
+ if (ref && write(processor->fd_ref, ref, pa_processor_reference_process_usec_to_bytes(processor->reference)) <= 0)
pa_log_error("Failed to write reference buffer");
- if (out && write(processor->fdout, out, processor->process_bytes) <= 0)
+ if (write(processor->fd_out, out, processor->process_bytes) <= 0)
pa_log_error("Failed to write ref buffer");
}
-static void debug_close_file(pa_processor *processor) {
- if (processor->fdrec) {
- close(processor->fdrec);
- processor->fdrec = -1;
+static void pa_processor_debug_close(pa_processor *processor) {
+ if (processor->fd_rec) {
+ close(processor->fd_rec);
+ processor->fd_rec = -1;
}
- if (processor->fdref) {
- close(processor->fdref);
- processor->fdref = -1;
+ if (processor->fd_ref) {
+ close(processor->fd_ref);
+ processor->fd_ref = -1;
}
- if (processor->fdout) {
- close(processor->fdout);
- processor->fdout = -1;
+ if (processor->fd_out) {
+ close(processor->fd_out);
+ processor->fd_out = -1;
}
}
+
+static void pa_processor_debug_timestamp_begin(pa_processor *processor) {
+ gettimeofday(&processor->before, NULL);
+}
+
+static void pa_processor_debug_timestamp_end(pa_processor *processor) {
+ gettimeofday(&processor->after, NULL);
+
+ pa_log_debug("It takes time (%ld)ms.",
+ 1000 * (processor->after.tv_sec - processor->before.tv_sec)
+ + (processor->after.tv_usec - processor->before.tv_usec) / 1000);
+}
+
#endif
#define MEMBLOCKQ_MAXLENGTH (16*1024*1024)
#define DEFAULT_PREBUFFER_MSEC (50)
+#ifdef __PROCESSOR_HOLDER_DEBUG__
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+enum debug_target {
+ PA_PROCESSOR_HOLDER_DEBUG_INPUT_BUFFER,
+ PA_PROCESSOR_HOLDER_DEBUG_OUTPUT_BUFFER,
+ PA_PROCESSOR_HOLDER_DEBUG_REFERENCE_BUFFER,
+ PA_PROCESSOR_HOLDER_DEBUG_BUFFER_MAX
+};
+
+static void pa_processor_holder_debug_open_file(pa_processor_holder *holder);
+static void pa_processor_holder_debug_write_buffer(pa_processor_holder *holder, int target, pa_memchunk *chunk);
+static void pa_processor_holder_debug_close_fd(pa_processor_holder *holder);
+
+#define pa_processor_holder_debug_write_input_buffer(x, y) \
+ pa_processor_holder_debug_write_buffer(x, PA_PROCESSOR_HOLDER_DEBUG_INPUT_BUFFER, y)
+#define pa_processor_holder_debug_write_output_buffer(x, y) \
+ pa_processor_holder_debug_write_buffer(x, PA_PROCESSOR_HOLDER_DEBUG_OUTPUT_BUFFER, y)
+#define pa_processor_holder_debug_write_reference_buffer(x, y) \
+ pa_processor_holder_debug_write_buffer(x, PA_PROCESSOR_HOLDER_DEBUG_REFERENCE_BUFFER, y)
+
+#else
+#define pa_processor_holder_debug_open_file(x)
+#define pa_processor_holder_debug_write_input_buffer(x, y)
+#define pa_processor_holder_debug_write_output_buffer(x, y)
+#define pa_processor_holder_debug_write_reference_buffer(x, y)
+#define pa_processor_holder_debug_close_fd(x)
+#endif
+
pa_processor_holder *pa_processor_holder_new(pa_core *core, pa_sample_spec *ss) {
pa_processor_holder *holder;
pa_memchunk silence;
pa_memblock_unref(silence.memblock);
+ pa_processor_holder_debug_open_file(holder);
+
return holder;
}
ret = pa_memblockq_push(holder->input, chunk);
+ pa_processor_holder_debug_write_input_buffer(holder, chunk);
+
pa_log_debug("push data to the input queue. chunk length(%zu), memblockq length(%zu)",
chunk->length, pa_memblockq_get_length(holder->input));
pa_assert(chunk);
pa_assert(holder->reference);
+ pa_processor_holder_debug_write_reference_buffer(holder, chunk);
+
return pa_processor_reference_push(holder->reference, chunk);
}
if ((r = pa_memblockq_peek_fixed_size(holder->output, length, chunk)) < 0)
pa_log_error("Failed to get memblock from output memblockq");
+ pa_processor_holder_debug_write_output_buffer(holder, chunk);
+
/* chunk ref count must be one after dropping */
pa_memblockq_drop(holder->output, chunk->length);
}
while (length >= process_size) {
+ /* the length of the reference must be checked before calling by pa_processor_reference_is_available */
+ if (!pa_processor_is_available(p)) {
+ pa_log_error("reference need to be pushed");
+ return -PROCESSOR_ERR_BUFFERING;
+ }
+
ret = pa_memblockq_peek_fixed_size(pull_queue, process_size, &chunk);
pa_assert(!ret);
if ((ret = pa_processor_process(p, &chunk)) < 0) {
pa_memblock_unref(chunk.memblock);
- pa_memblockq_drop(pull_queue, chunk.length);
- if (ret == -PROCESSOR_ERR_BUFFERING)
- pa_log_debug("Buffering reference memblocks.");
- else
- pa_log_warn("Failed to process memblock. ret(%d)", ret);
-
+ pa_log_warn("Failed to process memblock. ret(%d)", ret);
return ret;
}
pa_memblockq_get_write_index(pull_queue),
pa_memblockq_get_write_index(pull_queue));
}
+
+#ifdef __PROCESSOR_HOLDER_DEBUG__
+static void pa_processor_holder_debug_open_file(pa_processor_holder *holder) {
+ pa_assert(holder);
+
+ char filename[64];
+ int flags = O_CREAT | O_WRONLY | O_TRUNC;
+
+ snprintf(filename, sizeof(filename), "/tmp/processor-holder-in-buffer.raw");
+ unlink(filename);
+ holder->fd_in = open(filename, flags, 777);
+ if (holder->fd_in < 0) {
+ pa_log_error("Failed to open an input buffer debug file");
+ return;
+ }
+
+ snprintf(filename, sizeof(filename), "/tmp/processor-holder-out-buffer.raw");
+ unlink(filename);
+ holder->fd_out = open(filename, flags, 777);
+ if (holder->fd_out < 0) {
+ pa_log_error("Failed to open an output buffer debug file");
+ return;
+ }
+
+ snprintf(filename, sizeof(filename), "/tmp/processor-holder-ref-buffer.raw");
+ unlink(filename);
+ holder->fd_ref = open(filename, flags, 777);
+ if (holder->fd_ref < 0) {
+ pa_log_error("Failed to open an reference buffer debug file");
+ return;
+ }
+}
+
+static void pa_processor_holder_debug_write_buffer(pa_processor_holder *holder, int target, pa_memchunk *chunk) {
+ int8_t *p;
+ int fd;
+
+ pa_assert(holder);
+ pa_assert(chunk);
+
+ switch (target) {
+ case PA_PROCESSOR_HOLDER_DEBUG_INPUT_BUFFER:
+ fd = holder->fd_in;
+ break;
+ case PA_PROCESSOR_HOLDER_DEBUG_OUTPUT_BUFFER:
+ fd = holder->fd_out;
+ break;
+ case PA_PROCESSOR_HOLDER_DEBUG_REFERENCE_BUFFER:
+ fd = holder->fd_ref;
+ break;
+ default:
+ pa_assert_not_reached();
+ }
+
+ p = (int8_t *)pa_memblock_acquire_chunk(chunk);
+
+ if (write(fd, p, chunk->length) < 0)
+ pa_log_error("Failed to write debug buffer. fd(%d), target(%d)", fd, target);
+
+ pa_memblock_release(chunk->memblock);
+}
+
+static void pa_processor_holder_debug_close_fd(pa_processor_holder *holder) {
+ if (holder->fd_in > 0) {
+ close(holder->fd_in);
+ holder->fd_in = -1;
+ }
+
+ if (holder->fd_out > 0) {
+ close(holder->fd_out);
+ holder->fd_out = -1;
+ }
+
+ if (holder->fd_ref > 0) {
+ close(holder->fd_ref);
+ holder->fd_ref = -1;
+ }
+}
+#endif
+