ortp_send.o: ortp_send.c
$(CC) -c $(CPPFLAGS) $(DEBUG_CPPFLAGS) @ortp_cppflags@ $<
-oggdec.o: oggdec.c
+oggdec_filter.o: oggdec_filter.c
$(CC) -c $(CPPFLAGS) $(DEBUG_CPPFLAGS) @oggvorbis_cppflags@ $<
ogg_afh.o: ogg_afh.c
$(CC) -c $(CPPFLAGS) $(DEBUG_CPPFLAGS) @oggvorbis_cppflags@ $<
-mp3dec.o: mp3dec.c
+mp3dec_filter.o: mp3dec_filter.c
$(CC) -c $(CPPFLAGS) $(DEBUG_CPPFLAGS) @mad_cppflags@ $<
-aacdec.o: aacdec.c
+aacdec_filter.o: aacdec_filter.c
$(CC) -c $(CPPFLAGS) $(DEBUG_CPPFLAGS) @faad_cppflags@ $<
aac_common.o: aac_common.c
+++ /dev/null
-/*
- * Copyright (C) 2006-2008 Andre Noll <maan@systemlinux.org>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
-/*
- * based in parts on libfaad, Copyright (C) 2003-2005 M. Bakker,
- * Ahead Software AG
- */
-
-/** \file aacdec.c paraslash's aac (m4a) decoder */
-
-#include "para.h"
-
-#include "list.h"
-#include "sched.h"
-#include "filter.h"
-#include "error.h"
-#include "string.h"
-#include "aac.h"
-
-/** the output buffer size */
-#define AAC_OUTBUF_SIZE (32 * 1024)
-
-/** give up decoding after that many errors */
-#define MAX_ERRORS 20
-
-/**
- * data specific to the aacdec filter
- *
- * \sa filter, filter_node
- */
-struct private_aacdec_data {
- /** the return value of aac_open */
- NeAACDecHandle handle;
- /** info about the currently decoded frame */
- NeAACDecFrameInfo frame_info;
- /** whether this instance of the aac decoder is already initialized */
- int initialized;
- /**
- * return value of aac_find_esds(). Used to call the right aacdec
- * init function
- */
- unsigned long decoder_length;
- /** number of times the decoder returned an error */
- unsigned error_count;
- /** number of bytes already consumed from the imput stream */
- size_t consumed_total;
- /** return value of aac_find_entry_point */
- size_t entry;
-};
-
-static ssize_t aacdec(char *input_buffer, size_t len, struct filter_node *fn)
-{
- struct private_aacdec_data *padd = fn->private_data;
- struct filter_chain *fc = fn->fc;
- int i, ret;
- unsigned char *p, *outbuffer;
- unsigned char *inbuf = (unsigned char*)input_buffer;
- size_t skip, consumed = 0;
-
- if (fn->loaded > fn->bufsize * 3 / 5)
- return 0;
- if (len < 2048 && !*fc->input_error)
- return 0;
-
- if (!padd->initialized) {
- unsigned long rate = 0;
- unsigned char channels = 0;
- ret = aac_find_esds(inbuf, len, &skip, &padd->decoder_length);
- if (ret < 0) {
- PARA_INFO_LOG("%s\n", para_strerror(-ret));
- ret = NeAACDecInit(padd->handle, inbuf,
- len, &rate, &channels);
- PARA_INFO_LOG("decoder init: %d\n", ret);
- if (ret < 0) {
- ret = -E_AACDEC_INIT;
- goto out;
- }
- consumed = ret;
- } else {
- PARA_INFO_LOG("decoder len: %lu\n",
- padd->decoder_length);
- consumed += skip;
- p = inbuf + consumed;
- ret = -E_AACDEC_INIT;
- if (NeAACDecInit2(padd->handle, p,
- padd->decoder_length, &rate,
- &channels) < 0)
- goto out;
- }
- fc->samplerate = rate;
- fc->channels = channels;
- PARA_INFO_LOG("rate: %u, channels: %d\n",
- fc->samplerate, fc->channels);
- padd->initialized = 1;
- }
- if (padd->decoder_length > 0) {
- consumed = 0;
- if (!padd->entry) {
- ret = aac_find_entry_point(inbuf + consumed,
- len - consumed, &skip);
- if (ret < 0) {
- ret = len;
- goto out;
- }
- consumed += skip;
- padd->entry = ret;
- PARA_INFO_LOG("entry: %zu\n", padd->entry);
- }
- ret = len;
- if (padd->consumed_total + len < padd->entry)
- goto out;
- if (padd->consumed_total < padd->entry)
- consumed = padd->entry - padd->consumed_total;
- }
- for (; consumed < len; consumed++)
- if ((inbuf[consumed] & 0xfe) == 0x20)
- break;
- if (consumed >= len)
- goto success;
- p = inbuf + consumed;
- outbuffer = NeAACDecDecode(padd->handle, &padd->frame_info, p,
- len - consumed);
- if (padd->frame_info.error) {
- ret = -E_AAC_DECODE;
- if (padd->error_count++ > MAX_ERRORS)
- goto out;
- PARA_ERROR_LOG("frame_error: %d, consumed: %zu + %zd + %lu\n",
- padd->frame_info.error, padd->consumed_total,
- consumed, padd->frame_info.bytesconsumed);
- PARA_ERROR_LOG("%s\n", NeAACDecGetErrorMessage(
- padd->frame_info.error));
- consumed++; /* catch 21 */
- goto success;
- }
- padd->error_count = 0;
- consumed += padd->frame_info.bytesconsumed;
- ret = consumed;
- if (!padd->frame_info.samples)
- goto out;
- ret = -E_AAC_OVERRUN;
- if (padd->frame_info.samples * 2 + fn->loaded > fn->bufsize)
- goto out;
- for (i = 0; i < padd->frame_info.samples; i++) {
- short *s = (short *)outbuffer;
- write_int16_host_endian(fn->buf + fn->loaded, s[i]);
- fn->loaded += 2;
- }
-success:
- ret = consumed;
-out:
- if (ret > 0)
- padd->consumed_total += ret;
- return ret;
-}
-
-static void aacdec_open(struct filter_node *fn)
-{
- struct private_aacdec_data *padd = para_calloc(sizeof(*padd));
-
- fn->private_data = padd;
- fn->bufsize = AAC_OUTBUF_SIZE;
- fn->buf = para_calloc(fn->bufsize);
- padd->handle = aac_open();
-}
-
-static void aacdec_close(struct filter_node *fn)
-{
- struct private_aacdec_data *padd = fn->private_data;
-
- NeAACDecClose(padd->handle);
- free(fn->buf);
- fn->buf = NULL;
- free(padd);
- fn->private_data = NULL;
-}
-
-/**
- * the init function of the aacdec filter
- *
- * \param f pointer to the filter struct to initialize
- *
- * \sa filter::init
- */
-void aacdec_filter_init(struct filter *f)
-{
- f->open = aacdec_open;
- f->convert = aacdec;
- f->close = aacdec_close;
-}
--- /dev/null
+/*
+ * Copyright (C) 2006-2008 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+/*
+ * based in parts on libfaad, Copyright (C) 2003-2005 M. Bakker,
+ * Ahead Software AG
+ */
+
+/** \file aacdec_filter.c paraslash's aac (m4a) decoder. */
+
+#include "para.h"
+
+#include "list.h"
+#include "sched.h"
+#include "filter.h"
+#include "error.h"
+#include "string.h"
+#include "aac.h"
+
+/** the output buffer size */
+#define AAC_OUTBUF_SIZE (32 * 1024)
+
+/** give up decoding after that many errors */
+#define MAX_ERRORS 20
+
+/**
+ * data specific to the aacdec filter
+ *
+ * \sa filter, filter_node
+ */
+struct private_aacdec_data {
+ /** the return value of aac_open */
+ NeAACDecHandle handle;
+ /** info about the currently decoded frame */
+ NeAACDecFrameInfo frame_info;
+ /** whether this instance of the aac decoder is already initialized */
+ int initialized;
+ /**
+ * return value of aac_find_esds(). Used to call the right aacdec
+ * init function
+ */
+ unsigned long decoder_length;
+ /** number of times the decoder returned an error */
+ unsigned error_count;
+ /** number of bytes already consumed from the imput stream */
+ size_t consumed_total;
+ /** return value of aac_find_entry_point */
+ size_t entry;
+};
+
+static ssize_t aacdec(char *input_buffer, size_t len, struct filter_node *fn)
+{
+ struct private_aacdec_data *padd = fn->private_data;
+ struct filter_chain *fc = fn->fc;
+ int i, ret;
+ unsigned char *p, *outbuffer;
+ unsigned char *inbuf = (unsigned char*)input_buffer;
+ size_t skip, consumed = 0;
+
+ if (fn->loaded > fn->bufsize * 3 / 5)
+ return 0;
+ if (len < 2048 && !*fc->input_error)
+ return 0;
+
+ if (!padd->initialized) {
+ unsigned long rate = 0;
+ unsigned char channels = 0;
+ ret = aac_find_esds(inbuf, len, &skip, &padd->decoder_length);
+ if (ret < 0) {
+ PARA_INFO_LOG("%s\n", para_strerror(-ret));
+ ret = NeAACDecInit(padd->handle, inbuf,
+ len, &rate, &channels);
+ PARA_INFO_LOG("decoder init: %d\n", ret);
+ if (ret < 0) {
+ ret = -E_AACDEC_INIT;
+ goto out;
+ }
+ consumed = ret;
+ } else {
+ PARA_INFO_LOG("decoder len: %lu\n",
+ padd->decoder_length);
+ consumed += skip;
+ p = inbuf + consumed;
+ ret = -E_AACDEC_INIT;
+ if (NeAACDecInit2(padd->handle, p,
+ padd->decoder_length, &rate,
+ &channels) < 0)
+ goto out;
+ }
+ fc->samplerate = rate;
+ fc->channels = channels;
+ PARA_INFO_LOG("rate: %u, channels: %d\n",
+ fc->samplerate, fc->channels);
+ padd->initialized = 1;
+ }
+ if (padd->decoder_length > 0) {
+ consumed = 0;
+ if (!padd->entry) {
+ ret = aac_find_entry_point(inbuf + consumed,
+ len - consumed, &skip);
+ if (ret < 0) {
+ ret = len;
+ goto out;
+ }
+ consumed += skip;
+ padd->entry = ret;
+ PARA_INFO_LOG("entry: %zu\n", padd->entry);
+ }
+ ret = len;
+ if (padd->consumed_total + len < padd->entry)
+ goto out;
+ if (padd->consumed_total < padd->entry)
+ consumed = padd->entry - padd->consumed_total;
+ }
+ for (; consumed < len; consumed++)
+ if ((inbuf[consumed] & 0xfe) == 0x20)
+ break;
+ if (consumed >= len)
+ goto success;
+ p = inbuf + consumed;
+ outbuffer = NeAACDecDecode(padd->handle, &padd->frame_info, p,
+ len - consumed);
+ if (padd->frame_info.error) {
+ ret = -E_AAC_DECODE;
+ if (padd->error_count++ > MAX_ERRORS)
+ goto out;
+ PARA_ERROR_LOG("frame_error: %d, consumed: %zu + %zd + %lu\n",
+ padd->frame_info.error, padd->consumed_total,
+ consumed, padd->frame_info.bytesconsumed);
+ PARA_ERROR_LOG("%s\n", NeAACDecGetErrorMessage(
+ padd->frame_info.error));
+ consumed++; /* catch 21 */
+ goto success;
+ }
+ padd->error_count = 0;
+ consumed += padd->frame_info.bytesconsumed;
+ ret = consumed;
+ if (!padd->frame_info.samples)
+ goto out;
+ ret = -E_AAC_OVERRUN;
+ if (padd->frame_info.samples * 2 + fn->loaded > fn->bufsize)
+ goto out;
+ for (i = 0; i < padd->frame_info.samples; i++) {
+ short *s = (short *)outbuffer;
+ write_int16_host_endian(fn->buf + fn->loaded, s[i]);
+ fn->loaded += 2;
+ }
+success:
+ ret = consumed;
+out:
+ if (ret > 0)
+ padd->consumed_total += ret;
+ return ret;
+}
+
+static void aacdec_open(struct filter_node *fn)
+{
+ struct private_aacdec_data *padd = para_calloc(sizeof(*padd));
+
+ fn->private_data = padd;
+ fn->bufsize = AAC_OUTBUF_SIZE;
+ fn->buf = para_calloc(fn->bufsize);
+ padd->handle = aac_open();
+}
+
+static void aacdec_close(struct filter_node *fn)
+{
+ struct private_aacdec_data *padd = fn->private_data;
+
+ NeAACDecClose(padd->handle);
+ free(fn->buf);
+ fn->buf = NULL;
+ free(padd);
+ fn->private_data = NULL;
+}
+
+/**
+ * the init function of the aacdec filter
+ *
+ * \param f pointer to the filter struct to initialize
+ *
+ * \sa filter::init
+ */
+void aacdec_filter_init(struct filter *f)
+{
+ f->open = aacdec_open;
+ f->convert = aacdec;
+ f->close = aacdec_close;
+}
+++ /dev/null
-/*
- * Copyright (C) 2005-2008 Andre Noll <maan@systemlinux.org>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
-
-/** \file compress.c Paraslash's dynamic audio range compressor. */
-
-/*
- * Uses ideas of AudioCompress, (C) 2002-2004 M. Hari Nezumi <magenta@trikuare.cx>
- */
-
-#include "para.h"
-#include "compress_filter.cmdline.h"
-#include "list.h"
-#include "sched.h"
-#include "filter.h"
-#include "string.h"
-#include "error.h"
-
-/** The size of the output data buffer. */
-#define COMPRESS_CHUNK_SIZE 40960
-
-extern char *stat_item_values[NUM_STAT_ITEMS];
-
-/** Data specific to the compress filter. */
-struct private_compress_data {
- /** The current multiplier. */
- unsigned current_gain;
- /** Points to the configuration data for this instance of the compress filter. */
- struct compress_filter_args_info *conf;
- /** Maximal admissible gain. */
- unsigned max_gain;
- /** Number of samples already seen. */
- unsigned num_samples;
- /** Absolute value of the maximal sample in the current block. */
- unsigned peak;
-};
-
-static ssize_t compress(char *inbuf, size_t inbuf_len, struct filter_node *fn)
-{
- size_t i, length = PARA_MIN((inbuf_len / 2) * 2,
- (fn->bufsize - fn->loaded) / 2 * 2);
- struct private_compress_data *pcd = fn->private_data;
- int16_t *ip = (int16_t *)inbuf, *op = (int16_t *)(fn->buf + fn->loaded);
- unsigned gain_shift = pcd->conf->inertia_arg + pcd->conf->damp_arg,
- mask = (1 << pcd->conf->blocksize_arg) - 1;
-
- if (!length)
- return 0;
- for (i = 0; i < length / 2; i++) {
- /* be careful in that heat, my dear */
- int sample = *ip++, adjusted_sample = (PARA_ABS(sample) *
- pcd->current_gain) >> gain_shift;
- if (unlikely(adjusted_sample > 32767)) { /* clip */
- PARA_NOTICE_LOG("clip: sample: %d, adjusted sample: %d\n",
- sample, adjusted_sample);
- adjusted_sample = 32767;
- pcd->current_gain = (3 * pcd->current_gain +
- (1 << pcd->conf->inertia_arg)) / 4;
- pcd->peak = 0;
- } else
- pcd->peak = PARA_MAX(pcd->peak, adjusted_sample);
- *op++ = sample >= 0? adjusted_sample : -adjusted_sample;
- if (likely(++pcd->num_samples & mask))
- continue;
-// PARA_DEBUG_LOG("gain: %u, peak: %u\n", pcd->current_gain,
-// pcd->peak);
- if (pcd->peak < pcd->conf->target_level_arg) {
- if (pcd->current_gain < pcd->max_gain)
- pcd->current_gain++;
- } else
- pcd->current_gain = PARA_MAX(pcd->current_gain - 2,
- 1 << pcd->conf->inertia_arg);
- pcd->peak = 0;
- }
- fn->loaded += length;
- return length;
-}
-
-static void close_compress(struct filter_node *fn)
-{
- free(fn->private_data);
- free(fn->buf);
-}
-
-/** TODO: Add sanity checks */
-static int compress_parse_config(int argc, char **argv, void **config)
-{
- int ret;
- struct compress_filter_args_info *compress_conf
- = para_calloc(sizeof(*compress_conf));
-
- ret = -E_COMPRESS_SYNTAX;
- if (compress_cmdline_parser(argc, argv, compress_conf))
- goto err;
- *config = compress_conf;
- return 1;
-err:
- free(compress_conf);
- return ret;
-}
-
-static void open_compress(struct filter_node *fn)
-{
- struct private_compress_data *pcd = para_calloc(
- sizeof(struct private_compress_data));
- pcd->conf = fn->conf;
- fn->private_data = pcd;
- fn->bufsize = COMPRESS_CHUNK_SIZE;
- fn->buf = para_malloc(fn->bufsize);
- pcd->current_gain = 1 << pcd->conf->inertia_arg;
- pcd->max_gain = 1 << (pcd->conf->inertia_arg + pcd->conf->aggressiveness_arg);
-}
-
-/**
- * The init function of the compress filter.
- *
- * \param f Pointer to the struct to initialize.
- */
-void compress_filter_init(struct filter *f)
-{
- f->open = open_compress;
- f->close = close_compress;
- f->convert = compress;
- f->print_help = compress_cmdline_parser_print_help;
- f->parse_config = compress_parse_config;
-}
--- /dev/null
+/*
+ * Copyright (C) 2005-2008 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
+/** \file compress_filter.c Paraslash's dynamic audio range compressor. */
+
+/*
+ * Uses ideas of AudioCompress, (C) 2002-2004 M. Hari Nezumi <magenta@trikuare.cx>
+ */
+
+#include "para.h"
+#include "compress_filter.cmdline.h"
+#include "list.h"
+#include "sched.h"
+#include "filter.h"
+#include "string.h"
+#include "error.h"
+
+/** The size of the output data buffer. */
+#define COMPRESS_CHUNK_SIZE 40960
+
+extern char *stat_item_values[NUM_STAT_ITEMS];
+
+/** Data specific to the compress filter. */
+struct private_compress_data {
+ /** The current multiplier. */
+ unsigned current_gain;
+ /** Points to the configuration data for this instance of the compress filter. */
+ struct compress_filter_args_info *conf;
+ /** Maximal admissible gain. */
+ unsigned max_gain;
+ /** Number of samples already seen. */
+ unsigned num_samples;
+ /** Absolute value of the maximal sample in the current block. */
+ unsigned peak;
+};
+
+static ssize_t compress(char *inbuf, size_t inbuf_len, struct filter_node *fn)
+{
+ size_t i, length = PARA_MIN((inbuf_len / 2) * 2,
+ (fn->bufsize - fn->loaded) / 2 * 2);
+ struct private_compress_data *pcd = fn->private_data;
+ int16_t *ip = (int16_t *)inbuf, *op = (int16_t *)(fn->buf + fn->loaded);
+ unsigned gain_shift = pcd->conf->inertia_arg + pcd->conf->damp_arg,
+ mask = (1 << pcd->conf->blocksize_arg) - 1;
+
+ if (!length)
+ return 0;
+ for (i = 0; i < length / 2; i++) {
+ /* be careful in that heat, my dear */
+ int sample = *ip++, adjusted_sample = (PARA_ABS(sample) *
+ pcd->current_gain) >> gain_shift;
+ if (unlikely(adjusted_sample > 32767)) { /* clip */
+ PARA_NOTICE_LOG("clip: sample: %d, adjusted sample: %d\n",
+ sample, adjusted_sample);
+ adjusted_sample = 32767;
+ pcd->current_gain = (3 * pcd->current_gain +
+ (1 << pcd->conf->inertia_arg)) / 4;
+ pcd->peak = 0;
+ } else
+ pcd->peak = PARA_MAX(pcd->peak, adjusted_sample);
+ *op++ = sample >= 0? adjusted_sample : -adjusted_sample;
+ if (likely(++pcd->num_samples & mask))
+ continue;
+// PARA_DEBUG_LOG("gain: %u, peak: %u\n", pcd->current_gain,
+// pcd->peak);
+ if (pcd->peak < pcd->conf->target_level_arg) {
+ if (pcd->current_gain < pcd->max_gain)
+ pcd->current_gain++;
+ } else
+ pcd->current_gain = PARA_MAX(pcd->current_gain - 2,
+ 1 << pcd->conf->inertia_arg);
+ pcd->peak = 0;
+ }
+ fn->loaded += length;
+ return length;
+}
+
+static void close_compress(struct filter_node *fn)
+{
+ free(fn->private_data);
+ free(fn->buf);
+}
+
+/** TODO: Add sanity checks */
+static int compress_parse_config(int argc, char **argv, void **config)
+{
+ int ret;
+ struct compress_filter_args_info *compress_conf
+ = para_calloc(sizeof(*compress_conf));
+
+ ret = -E_COMPRESS_SYNTAX;
+ if (compress_cmdline_parser(argc, argv, compress_conf))
+ goto err;
+ *config = compress_conf;
+ return 1;
+err:
+ free(compress_conf);
+ return ret;
+}
+
+static void open_compress(struct filter_node *fn)
+{
+ struct private_compress_data *pcd = para_calloc(
+ sizeof(struct private_compress_data));
+ pcd->conf = fn->conf;
+ fn->private_data = pcd;
+ fn->bufsize = COMPRESS_CHUNK_SIZE;
+ fn->buf = para_malloc(fn->bufsize);
+ pcd->current_gain = 1 << pcd->conf->inertia_arg;
+ pcd->max_gain = 1 << (pcd->conf->inertia_arg + pcd->conf->aggressiveness_arg);
+}
+
+/**
+ * The init function of the compress filter.
+ *
+ * \param f Pointer to the struct to initialize.
+ */
+void compress_filter_init(struct filter *f)
+{
+ f->open = open_compress;
+ f->close = close_compress;
+ f->convert = compress;
+ f->print_help = compress_cmdline_parser_print_help;
+ f->parse_config = compress_parse_config;
+}
all_errlist_objs="server mp3_afh afh_common vss command net string signal time
daemon stat crypt http_send close_on_fork ipc acl afh fade amp_filter
dccp_send fd user_list chunk_queue afs osl aft mood score attribute blob ringbuffer
-playlist sha1 rbtree sched audiod grab_client filter_chain wav compress
+playlist sha1 rbtree sched audiod grab_client filter_chain wav_filter compress_filter
http_recv dccp_recv recv_common write_common file_write audiod_command
client_common recv stdout filter stdin audioc write client fsck exec send_common"
senders=" http dccp"
filter_cmdline_objs="filter.cmdline compress_filter.cmdline amp_filter.cmdline"
-filter_errlist_objs="filter_chain wav compress filter string stdin stdout sched fd amp_filter"
+filter_errlist_objs="filter_chain wav_filter compress_filter filter string stdin stdout sched fd amp_filter"
filter_ldflags=""
filters=" compress wav amp"
http_recv.cmdline dccp_recv.cmdline file_write.cmdline client.cmdline
audiod_command_list amp_filter.cmdline"
audiod_errlist_objs="audiod signal string daemon stat net
- time grab_client filter_chain wav compress amp_filter http_recv dccp_recv
+ time grab_client filter_chain wav_filter compress_filter amp_filter http_recv dccp_recv
recv_common fd sched write_common file_write audiod_command crypt
client_common"
audiod_ldflags=""
AC_CHECK_LIB([vorbis], [vorbis_info_init], [], [ have_ogg="no" ])
AC_CHECK_HEADERS([ogg/ogg.h vorbis/codec.h], [], [ have_ogg="no" ])
if test "$have_ogg" = "yes"; then
- all_errlist_objs="$all_errlist_objs oggdec ogg_afh"
+ all_errlist_objs="$all_errlist_objs oggdec_filter ogg_afh"
AC_DEFINE(HAVE_OGGVORBIS, 1, define to 1 to turn on ogg vorbis support)
filters="$filters oggdec"
if test "$OSTYPE" = "Darwin"; then
audiod_cmdline_objs="$audiod_cmdline_objs oggdec_filter.cmdline"
server_errlist_objs="$server_errlist_objs ogg_afh"
- filter_errlist_objs="$filter_errlist_objs oggdec"
- audiod_errlist_objs="$audiod_errlist_objs oggdec"
+ filter_errlist_objs="$filter_errlist_objs oggdec_filter"
+ audiod_errlist_objs="$audiod_errlist_objs oggdec_filter"
afh_errlist_objs="$afh_errlist_objs ogg_afh"
audiod_audio_formats="ogg"
AC_CHECK_LIB([faad], [NeAACDecOpen], [], have_faad=no)
if test "$have_faad" = "yes"; then
AC_DEFINE(HAVE_FAAD, 1, define to 1 if you want to build the aacdec filter)
- all_errlist_objs="$all_errlist_objs aac_common aacdec aac_afh"
- filter_errlist_objs="$filter_errlist_objs aacdec aac_common"
+ all_errlist_objs="$all_errlist_objs aac_common aacdec_filter aac_afh"
+ filter_errlist_objs="$filter_errlist_objs aacdec_filter aac_common"
afh_errlist_objs="$afh_errlist_objs aac_common aac_afh"
- audiod_errlist_objs="$audiod_errlist_objs aacdec aac_common"
+ audiod_errlist_objs="$audiod_errlist_objs aacdec_filter aac_common"
server_errlist_objs="$server_errlist_objs aac_afh aac_common"
server_ldflags="$server_ldflags $faad_libs -lfaad"
filter_ldflags="$filter_ldflags $faad_libs -lfaad"
])
if test "$have_mad" = "yes"; then
AC_DEFINE(HAVE_MAD, 1, define to 1 if you want to build the mp3dec filter)
- all_errlist_objs="$all_errlist_objs mp3dec"
- filter_errlist_objs="$filter_errlist_objs mp3dec"
- audiod_errlist_objs="$audiod_errlist_objs mp3dec"
+ all_errlist_objs="$all_errlist_objs mp3dec_filter"
+ filter_errlist_objs="$filter_errlist_objs mp3dec_filter"
+ audiod_errlist_objs="$audiod_errlist_objs mp3dec_filter"
filter_ldflags="$filter_ldflags $mad_libs -lmad"
audiod_ldflags="$audiod_ldflags $mad_libs -lmad"
audiod_audio_formats="$audiod_audio_formats mp3"
/* these do not need error handling (yet) */
#define SERVER_ERRORS
-#define WAV_ERRORS
+#define WAV_FILTER_ERRORS
#define TIME_ERRORS
#define CLOSE_ON_FORK_ERRORS
#define DAEMON_ERRORS
extern const char **para_errlist[];
-#define COMPRESS_ERRORS \
+#define COMPRESS_FILTER_ERRORS \
PARA_ERROR(COMPRESS_SYNTAX, "syntax error in compress filter config"), \
PARA_ERROR(UNKNOWN_STAT_ITEM, "status item not recognized"), \
-#define OGGDEC_ERRORS \
+#define OGGDEC_FILTER_ERRORS \
PARA_ERROR(OGGDEC_READ, "read from media returned an error"), \
PARA_ERROR(OGGDEC_NOTVORBIS, "bitstream is not vorbis data"), \
PARA_ERROR(OGGDEC_VERSION, "vorbis version mismatch"), \
PARA_ERROR(GC_VERSION_GIVEN, ""), /* not really an error */ \
-#define MP3DEC_ERRORS \
+#define MP3DEC_FILTER_ERRORS \
PARA_ERROR(MAD_FRAME_DECODE, "mad frame decode error"), \
PARA_ERROR(MP3DEC_OVERRUN, "mp3 output buffer overrun"), \
PARA_ERROR(WRITE_COMMON_SYNTAX, "syntax error in write option"), \
-#define AACDEC_ERRORS \
+#define AACDEC_FILTER_ERRORS \
PARA_ERROR(AACDEC_INIT, "failed to init aac decoder"), \
PARA_ERROR(AAC_DECODE, "aac decode error"), \
PARA_ERROR(AAC_OVERRUN, "aac output buffer overrun"), \
* Note: As several instances of the same filter may be running at the same
* time, all these filter functions must be reentrant; no static non-constant
* variables may be used.
- * \sa mp3dec.c, oggdec.c, wav.c, compress.c, filter_node
+ * \sa mp3dec_filter.c, oggdec_filter.c, wav_filter.c, compress_filter.c, filter_node
*/
struct filter {
/** The name of the filter. */
+++ /dev/null
-/*
- * Copyright (C) 2005-2008 Andre Noll <maan@systemlinux.org>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
-
-/** \file mp3dec.c Paraslash's mp3 decoder. */
-
-#include "para.h"
-#include "list.h"
-#include "sched.h"
-#include "filter.h"
-#include "error.h"
-#include <mad.h>
-#include "string.h"
-
-/** The output buffer size. */
-#define MP3_OUTBUF_SIZE (128 * 1024)
-
-/** Convert a sample value from libmad to a signed short. */
-#define MAD_TO_SHORT(f) (f) >= MAD_F_ONE? SHRT_MAX :\
- (f) <= -MAD_F_ONE? -SHRT_MAX : (signed short) ((f) >> (MAD_F_FRACBITS - 15))
-
-/** Data specific to the mp3dec filter. */
-struct private_mp3dec_data {
- /** Information on the current mp3 stream. */
- struct mad_stream stream;
- /** Information about the frame which is currently decoded. */
- struct mad_frame frame;
- /** Contains the PCM output. */
- struct mad_synth synth;
-};
-
-static ssize_t mp3dec(char *inbuffer, size_t len, struct filter_node *fn)
-{
- int i, ret;
- struct private_mp3dec_data *pmd = fn->private_data;
- size_t copy = PARA_MIN(len, 4096);
-
- if (fn->loaded > fn->bufsize * 4 / 5)
- return 0;
- mad_stream_buffer(&pmd->stream, (unsigned char *) inbuffer, copy);
- pmd->stream.error = 0;
-next_frame:
- ret = mad_header_decode(&pmd->frame.header, &pmd->stream);
- if (ret < 0) {
- if (pmd->stream.error != MAD_ERROR_BUFLEN &&
- pmd->stream.error != MAD_ERROR_LOSTSYNC)
- PARA_DEBUG_LOG("header decode: %s\n",
- mad_stream_errorstr(&pmd->stream));
- goto out;
- }
- fn->fc->samplerate = pmd->frame.header.samplerate;
- fn->fc->channels = MAD_NCHANNELS(&pmd->frame.header);
- ret = mad_frame_decode(&pmd->frame, &pmd->stream);
- if (ret) {
- if (MAD_RECOVERABLE(pmd->stream.error) ||
- pmd->stream.error == MAD_ERROR_BUFLEN) {
- PARA_DEBUG_LOG("frame decode: %s\n",
- mad_stream_errorstr(&pmd->stream));
- goto out;
- }
- PARA_ERROR_LOG("frame decode: %s\n",
- mad_stream_errorstr(&pmd->stream));
- return -E_MAD_FRAME_DECODE;
- }
- mad_synth_frame(&pmd->synth, &pmd->frame);
-
- for (i = 0; i < pmd->synth.pcm.length; i++) {
- int s = MAD_TO_SHORT(pmd->synth.pcm.samples[0][i]);
- write_int16_host_endian(fn->buf + fn->loaded, s);
- fn->loaded += 2;
- if (MAD_NCHANNELS(&pmd->frame.header) == 2) { /* stereo */
- s = MAD_TO_SHORT(pmd->synth.pcm.samples[1][i]);
- write_int16_host_endian(fn->buf + fn->loaded, s);
- fn->loaded += 2;
- }
- if (fn->loaded != fn->bufsize) /* output buffer not full */
- continue;
- PARA_ERROR_LOG("output buffer full: %zd\n", fn->loaded);
- return -E_MP3DEC_OVERRUN;
- }
- if (fn->loaded <= fn->bufsize * 4 / 5)
- goto next_frame;
-out:
- if (pmd->stream.next_frame) { /* we still have some data */
- size_t off = pmd->stream.bufend - pmd->stream.next_frame;
-// PARA_INFO_LOG("off: %zd, rate: %u, returning %zd\n", off,
-// fn->fc->samplerate, copy - off);
- return copy - off;
- }
- return copy;
-}
-
-static void mp3dec_close(struct filter_node *fn)
-{
- struct private_mp3dec_data *pmd = fn->private_data;
-
- mad_synth_finish(&pmd->synth);
- mad_frame_finish(&pmd->frame);
- mad_stream_finish(&pmd->stream);
-
- free(fn->buf);
- fn->buf = NULL;
- free(pmd);
- fn->private_data = NULL;
-}
-
-static void mp3dec_open(struct filter_node *fn)
-{
- struct private_mp3dec_data *pmd = para_calloc(sizeof(*pmd));
-
- fn->private_data = pmd;
- mad_stream_init(&pmd->stream);
- mad_frame_init(&pmd->frame);
- mad_synth_init(&pmd->synth);
- fn->loaded = 0;
- fn->bufsize = MP3_OUTBUF_SIZE;
- fn->buf = para_calloc(fn->bufsize);
-}
-
-/**
- * The init function of the mp3dec filter.
- *
- * \param f Pointer to the filter struct to initialize.
- *
- * \sa filter::init.
- */
-void mp3dec_filter_init(struct filter *f)
-{
- f->open = mp3dec_open;
- f->convert = mp3dec;
- f->close = mp3dec_close;
-}
--- /dev/null
+/*
+ * Copyright (C) 2005-2008 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
+/** \file mp3dec_filter.c Paraslash's mp3 decoder. */
+
+#include "para.h"
+#include "list.h"
+#include "sched.h"
+#include "filter.h"
+#include "error.h"
+#include <mad.h>
+#include "string.h"
+
+/** The output buffer size. */
+#define MP3_OUTBUF_SIZE (128 * 1024)
+
+/** Convert a sample value from libmad to a signed short. */
+#define MAD_TO_SHORT(f) (f) >= MAD_F_ONE? SHRT_MAX :\
+ (f) <= -MAD_F_ONE? -SHRT_MAX : (signed short) ((f) >> (MAD_F_FRACBITS - 15))
+
+/** Data specific to the mp3dec filter. */
+struct private_mp3dec_data {
+ /** Information on the current mp3 stream. */
+ struct mad_stream stream;
+ /** Information about the frame which is currently decoded. */
+ struct mad_frame frame;
+ /** Contains the PCM output. */
+ struct mad_synth synth;
+};
+
+static ssize_t mp3dec(char *inbuffer, size_t len, struct filter_node *fn)
+{
+ int i, ret;
+ struct private_mp3dec_data *pmd = fn->private_data;
+ size_t copy = PARA_MIN(len, 4096);
+
+ if (fn->loaded > fn->bufsize * 4 / 5)
+ return 0;
+ mad_stream_buffer(&pmd->stream, (unsigned char *) inbuffer, copy);
+ pmd->stream.error = 0;
+next_frame:
+ ret = mad_header_decode(&pmd->frame.header, &pmd->stream);
+ if (ret < 0) {
+ if (pmd->stream.error != MAD_ERROR_BUFLEN &&
+ pmd->stream.error != MAD_ERROR_LOSTSYNC)
+ PARA_DEBUG_LOG("header decode: %s\n",
+ mad_stream_errorstr(&pmd->stream));
+ goto out;
+ }
+ fn->fc->samplerate = pmd->frame.header.samplerate;
+ fn->fc->channels = MAD_NCHANNELS(&pmd->frame.header);
+ ret = mad_frame_decode(&pmd->frame, &pmd->stream);
+ if (ret) {
+ if (MAD_RECOVERABLE(pmd->stream.error) ||
+ pmd->stream.error == MAD_ERROR_BUFLEN) {
+ PARA_DEBUG_LOG("frame decode: %s\n",
+ mad_stream_errorstr(&pmd->stream));
+ goto out;
+ }
+ PARA_ERROR_LOG("frame decode: %s\n",
+ mad_stream_errorstr(&pmd->stream));
+ return -E_MAD_FRAME_DECODE;
+ }
+ mad_synth_frame(&pmd->synth, &pmd->frame);
+
+ for (i = 0; i < pmd->synth.pcm.length; i++) {
+ int s = MAD_TO_SHORT(pmd->synth.pcm.samples[0][i]);
+ write_int16_host_endian(fn->buf + fn->loaded, s);
+ fn->loaded += 2;
+ if (MAD_NCHANNELS(&pmd->frame.header) == 2) { /* stereo */
+ s = MAD_TO_SHORT(pmd->synth.pcm.samples[1][i]);
+ write_int16_host_endian(fn->buf + fn->loaded, s);
+ fn->loaded += 2;
+ }
+ if (fn->loaded != fn->bufsize) /* output buffer not full */
+ continue;
+ PARA_ERROR_LOG("output buffer full: %zd\n", fn->loaded);
+ return -E_MP3DEC_OVERRUN;
+ }
+ if (fn->loaded <= fn->bufsize * 4 / 5)
+ goto next_frame;
+out:
+ if (pmd->stream.next_frame) { /* we still have some data */
+ size_t off = pmd->stream.bufend - pmd->stream.next_frame;
+// PARA_INFO_LOG("off: %zd, rate: %u, returning %zd\n", off,
+// fn->fc->samplerate, copy - off);
+ return copy - off;
+ }
+ return copy;
+}
+
+static void mp3dec_close(struct filter_node *fn)
+{
+ struct private_mp3dec_data *pmd = fn->private_data;
+
+ mad_synth_finish(&pmd->synth);
+ mad_frame_finish(&pmd->frame);
+ mad_stream_finish(&pmd->stream);
+
+ free(fn->buf);
+ fn->buf = NULL;
+ free(pmd);
+ fn->private_data = NULL;
+}
+
+static void mp3dec_open(struct filter_node *fn)
+{
+ struct private_mp3dec_data *pmd = para_calloc(sizeof(*pmd));
+
+ fn->private_data = pmd;
+ mad_stream_init(&pmd->stream);
+ mad_frame_init(&pmd->frame);
+ mad_synth_init(&pmd->synth);
+ fn->loaded = 0;
+ fn->bufsize = MP3_OUTBUF_SIZE;
+ fn->buf = para_calloc(fn->bufsize);
+}
+
+/**
+ * The init function of the mp3dec filter.
+ *
+ * \param f Pointer to the filter struct to initialize.
+ *
+ * \sa filter::init.
+ */
+void mp3dec_filter_init(struct filter *f)
+{
+ f->open = mp3dec_open;
+ f->convert = mp3dec;
+ f->close = mp3dec_close;
+}
+++ /dev/null
-/*
- * Copyright (C) 2005-2008 Andre Noll <maan@systemlinux.org>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
-
-/** \file oggdec.c Paraslash's ogg vorbis decoder. */
-
-#include "para.h"
-
-#include "oggdec_filter.cmdline.h"
-#include "list.h"
-#include "sched.h"
-#include "filter.h"
-#include "error.h"
-#include "string.h"
-
-#include <vorbis/vorbisfile.h>
-
-/** Determine byte sex. */
-#ifdef WORDS_BIGENDIAN
-#define ENDIAN 1
-#else
-#define ENDIAN 0
-#endif
-
-/** Data specific to the oggdec filter. */
-struct private_oggdec_data {
- /** Describes an ogg vorbis file. */
- OggVorbis_File *vf;
- /** The input buffer. */
- char *inbuf;
- /** The length of \a inbuf. */
- size_t inbuf_len;
- /** The number of bytes consumed from the input buffer. */
- size_t converted;
-};
-
-static size_t cb_read(void *buf, size_t size, size_t nmemb, void *datasource)
-{
- struct filter_node *fn = datasource;
- struct private_oggdec_data *pod = fn->private_data;
- size_t ret, have = pod->inbuf_len - pod->converted;
- char *p = pod->inbuf + pod->converted;
-
-// PARA_DEBUG_LOG("pod = %p\n", pod);
-// PARA_DEBUG_LOG("vorbis requests %d bytes, have %d\n", size * nmemb, have);
- if (pod->inbuf_len < size) {
- if (*fn->fc->input_error)
- return 0;
- errno = EAGAIN;
- return (size_t)-1;
- }
- ret = PARA_MIN(nmemb, have / size) * size;
- memcpy(buf, p, ret);
- pod->converted += ret;
- return ret;
-}
-
-/*
- * Custom data seeking function.
- *
- * Since we want the data source to be treated as unseekable at all
- * times, the provided seek callback always returns -1 (failure).
- */
-static int cb_seek(__a_unused void *datasource, __a_unused ogg_int64_t offset,
- __a_unused int whence)
-{
- return -1;
-}
-
-static int cb_close(__a_unused void *datasource)
-{
- return 0;
-}
-
-static const ov_callbacks ovc = {
- .read_func = cb_read,
- .seek_func = cb_seek,
- .close_func = cb_close,
- /*
- * The tell function need not be provided if the data IO abstraction is
- * not seekable
- */
- .tell_func = NULL
-};
-
-static void ogg_open(struct filter_node *fn)
-{
- struct private_oggdec_data *pod = para_calloc(
- sizeof(struct private_oggdec_data));
- struct oggdec_filter_args_info *conf = fn->conf;
-
- fn->private_data = pod;
- fn->bufsize = conf->bufsize_arg * 1024;
- fn->buf = para_malloc(fn->bufsize);
-}
-
-static void ogg_close(struct filter_node *fn)
-{
- struct private_oggdec_data *pod = fn->private_data;
- if (pod->vf) {
- PARA_DEBUG_LOG("ov_clearing %p, pod = %p\n", pod->vf, pod);
- ov_clear(pod->vf);
- free(pod->vf);
- pod->vf = NULL;
- } else
- PARA_DEBUG_LOG("nothing to close in fc %p, pod = %p\n", pod->vf, pod);
- free(fn->buf);
- fn->buf = NULL;
- free(fn->private_data);
- fn->private_data = NULL;
-}
-
-static ssize_t ogg_convert(char *inbuffer, size_t len, struct filter_node *fn)
-{
- ssize_t ret;
- struct private_oggdec_data *pod = fn->private_data;
- struct oggdec_filter_args_info *conf = fn->conf;
- /* make the buffer known to the read callback cb_read() */
- pod->inbuf = inbuffer;
- pod->inbuf_len = len;
- pod->converted = 0;
-
- if (!pod->vf) {
- int ib = 1024 * conf->initial_buffer_arg; /* initial buffer */
- if (len <ib && !*fn->fc->input_error) {
- PARA_DEBUG_LOG("initial input buffer %zd/%d, "
- "waiting for more data\n", len, ib);
- return 0;
- }
- pod->vf = para_malloc(sizeof(struct OggVorbis_File));
- PARA_NOTICE_LOG("input buffer: %zd, opening ov callbacks\n", len);
- ret = ov_open_callbacks(fn, pod->vf,
- NULL, /* no initial buffer */
- 0, /* no initial bytes */
- ovc); /* the ov_open_callbacks */
- if (ret == OV_EREAD)
- return -E_OGGDEC_READ;
- if (ret == OV_ENOTVORBIS)
- return -E_OGGDEC_NOTVORBIS;
- if (ret == OV_EVERSION)
- return -E_OGGDEC_VERSION;
- if (ret == OV_EBADHEADER)
- return -E_OGGDEC_BADHEADER;
- if (ret < 0)
- return -E_OGGDEC_FAULT;
- fn->fc->channels = ov_info(pod->vf, 0)->channels;
- fn->fc->samplerate = ov_info(pod->vf, 0)->rate;
- PARA_NOTICE_LOG("%d channels, %d Hz\n", fn->fc->channels,
- fn->fc->samplerate);
- }
- while (fn->loaded < fn->bufsize) {
- int length = fn->bufsize - fn->loaded;
- long read_ret = ov_read(pod->vf, fn->buf + fn->loaded, length,
- ENDIAN, 2 /* 16 bit */, 1 /* signed */, NULL);
- if (read_ret == OV_HOLE || !read_ret)
- return pod->converted;
- if (read_ret < 0)
- return -E_OGGDEC_BADLINK;
- fn->loaded += read_ret;
- }
- return pod->converted;
-}
-
-static int oggdec_parse_config(int argc, char **argv, void **config)
-{
- int ret;
- struct oggdec_filter_args_info *ogg_conf;
-
- ogg_conf = para_calloc(sizeof(*ogg_conf));
- ret = -E_OGGDEC_SYNTAX;
- if (oggdec_cmdline_parser(argc, argv, ogg_conf))
- goto err;
- ret = -ERRNO_TO_PARA_ERROR(EINVAL);
- if (ogg_conf->bufsize_arg < 0)
- goto err;
- if (ogg_conf->bufsize_arg >= INT_MAX / 1024)
- goto err;
- if (ogg_conf->initial_buffer_arg < 0)
- goto err;
- if (ogg_conf->initial_buffer_arg >= INT_MAX / 1024)
- goto err;
- *config = ogg_conf;
- return 1;
-err:
- free(ogg_conf);
- return ret;
-}
-
-/**
- * The init function of the ogg vorbis decoder.
- *
- * \param f Its fields are filled in by the function.
- */
-void oggdec_filter_init(struct filter *f)
-{
- f->open = ogg_open;
- f->close = ogg_close;
- f->convert = ogg_convert;
- f->print_help = oggdec_cmdline_parser_print_help;
- f->parse_config = oggdec_parse_config;
-}
--- /dev/null
+/*
+ * Copyright (C) 2005-2008 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
+/** \file oggdec_filter.c Paraslash's ogg vorbis decoder. */
+
+#include "para.h"
+
+#include "oggdec_filter.cmdline.h"
+#include "list.h"
+#include "sched.h"
+#include "filter.h"
+#include "error.h"
+#include "string.h"
+
+#include <vorbis/vorbisfile.h>
+
+/** Determine byte sex. */
+#ifdef WORDS_BIGENDIAN
+#define ENDIAN 1
+#else
+#define ENDIAN 0
+#endif
+
+/** Data specific to the oggdec filter. */
+struct private_oggdec_data {
+ /** Describes an ogg vorbis file. */
+ OggVorbis_File *vf;
+ /** The input buffer. */
+ char *inbuf;
+ /** The length of \a inbuf. */
+ size_t inbuf_len;
+ /** The number of bytes consumed from the input buffer. */
+ size_t converted;
+};
+
+static size_t cb_read(void *buf, size_t size, size_t nmemb, void *datasource)
+{
+ struct filter_node *fn = datasource;
+ struct private_oggdec_data *pod = fn->private_data;
+ size_t ret, have = pod->inbuf_len - pod->converted;
+ char *p = pod->inbuf + pod->converted;
+
+// PARA_DEBUG_LOG("pod = %p\n", pod);
+// PARA_DEBUG_LOG("vorbis requests %d bytes, have %d\n", size * nmemb, have);
+ if (pod->inbuf_len < size) {
+ if (*fn->fc->input_error)
+ return 0;
+ errno = EAGAIN;
+ return (size_t)-1;
+ }
+ ret = PARA_MIN(nmemb, have / size) * size;
+ memcpy(buf, p, ret);
+ pod->converted += ret;
+ return ret;
+}
+
+/*
+ * Custom data seeking function.
+ *
+ * Since we want the data source to be treated as unseekable at all
+ * times, the provided seek callback always returns -1 (failure).
+ */
+static int cb_seek(__a_unused void *datasource, __a_unused ogg_int64_t offset,
+ __a_unused int whence)
+{
+ return -1;
+}
+
+static int cb_close(__a_unused void *datasource)
+{
+ return 0;
+}
+
+static const ov_callbacks ovc = {
+ .read_func = cb_read,
+ .seek_func = cb_seek,
+ .close_func = cb_close,
+ /*
+ * The tell function need not be provided if the data IO abstraction is
+ * not seekable
+ */
+ .tell_func = NULL
+};
+
+static void ogg_open(struct filter_node *fn)
+{
+ struct private_oggdec_data *pod = para_calloc(
+ sizeof(struct private_oggdec_data));
+ struct oggdec_filter_args_info *conf = fn->conf;
+
+ fn->private_data = pod;
+ fn->bufsize = conf->bufsize_arg * 1024;
+ fn->buf = para_malloc(fn->bufsize);
+}
+
+static void ogg_close(struct filter_node *fn)
+{
+ struct private_oggdec_data *pod = fn->private_data;
+ if (pod->vf) {
+ PARA_DEBUG_LOG("ov_clearing %p, pod = %p\n", pod->vf, pod);
+ ov_clear(pod->vf);
+ free(pod->vf);
+ pod->vf = NULL;
+ } else
+ PARA_DEBUG_LOG("nothing to close in fc %p, pod = %p\n", pod->vf, pod);
+ free(fn->buf);
+ fn->buf = NULL;
+ free(fn->private_data);
+ fn->private_data = NULL;
+}
+
+static ssize_t ogg_convert(char *inbuffer, size_t len, struct filter_node *fn)
+{
+ ssize_t ret;
+ struct private_oggdec_data *pod = fn->private_data;
+ struct oggdec_filter_args_info *conf = fn->conf;
+ /* make the buffer known to the read callback cb_read() */
+ pod->inbuf = inbuffer;
+ pod->inbuf_len = len;
+ pod->converted = 0;
+
+ if (!pod->vf) {
+ int ib = 1024 * conf->initial_buffer_arg; /* initial buffer */
+ if (len <ib && !*fn->fc->input_error) {
+ PARA_DEBUG_LOG("initial input buffer %zd/%d, "
+ "waiting for more data\n", len, ib);
+ return 0;
+ }
+ pod->vf = para_malloc(sizeof(struct OggVorbis_File));
+ PARA_NOTICE_LOG("input buffer: %zd, opening ov callbacks\n", len);
+ ret = ov_open_callbacks(fn, pod->vf,
+ NULL, /* no initial buffer */
+ 0, /* no initial bytes */
+ ovc); /* the ov_open_callbacks */
+ if (ret == OV_EREAD)
+ return -E_OGGDEC_READ;
+ if (ret == OV_ENOTVORBIS)
+ return -E_OGGDEC_NOTVORBIS;
+ if (ret == OV_EVERSION)
+ return -E_OGGDEC_VERSION;
+ if (ret == OV_EBADHEADER)
+ return -E_OGGDEC_BADHEADER;
+ if (ret < 0)
+ return -E_OGGDEC_FAULT;
+ fn->fc->channels = ov_info(pod->vf, 0)->channels;
+ fn->fc->samplerate = ov_info(pod->vf, 0)->rate;
+ PARA_NOTICE_LOG("%d channels, %d Hz\n", fn->fc->channels,
+ fn->fc->samplerate);
+ }
+ while (fn->loaded < fn->bufsize) {
+ int length = fn->bufsize - fn->loaded;
+ long read_ret = ov_read(pod->vf, fn->buf + fn->loaded, length,
+ ENDIAN, 2 /* 16 bit */, 1 /* signed */, NULL);
+ if (read_ret == OV_HOLE || !read_ret)
+ return pod->converted;
+ if (read_ret < 0)
+ return -E_OGGDEC_BADLINK;
+ fn->loaded += read_ret;
+ }
+ return pod->converted;
+}
+
+static int oggdec_parse_config(int argc, char **argv, void **config)
+{
+ int ret;
+ struct oggdec_filter_args_info *ogg_conf;
+
+ ogg_conf = para_calloc(sizeof(*ogg_conf));
+ ret = -E_OGGDEC_SYNTAX;
+ if (oggdec_cmdline_parser(argc, argv, ogg_conf))
+ goto err;
+ ret = -ERRNO_TO_PARA_ERROR(EINVAL);
+ if (ogg_conf->bufsize_arg < 0)
+ goto err;
+ if (ogg_conf->bufsize_arg >= INT_MAX / 1024)
+ goto err;
+ if (ogg_conf->initial_buffer_arg < 0)
+ goto err;
+ if (ogg_conf->initial_buffer_arg >= INT_MAX / 1024)
+ goto err;
+ *config = ogg_conf;
+ return 1;
+err:
+ free(ogg_conf);
+ return ret;
+}
+
+/**
+ * The init function of the ogg vorbis decoder.
+ *
+ * \param f Its fields are filled in by the function.
+ */
+void oggdec_filter_init(struct filter *f)
+{
+ f->open = ogg_open;
+ f->close = ogg_close;
+ f->convert = ogg_convert;
+ f->print_help = oggdec_cmdline_parser_print_help;
+ f->parse_config = oggdec_parse_config;
+}
* The gory details, listed by topic:
*
* - Audio format handlers: \ref send_common.c \ref mp3_afh.c, \ref ogg_afh.c, \ref aac_afh.c,
- * - Decoders: \ref mp3dec.c, \ref oggdec.c, \ref aacdec.c,
- * - Volume normalizer: \ref compress.c,
+ * - Decoders: \ref mp3dec_filter.c, \ref oggdec_filter.c, \ref aacdec_filter.c,
+ * - Volume normalizer: \ref compress_filter.c,
* - Output: \ref alsa_write.c, \ref osx_write.c,
* - http: \ref http_recv.c, \ref http_send.c,
* - ortp: \ref ortp_recv.c, \ref ortp_send.c,
+++ /dev/null
-/*
- * Copyright (C) 2005-2008 Andre Noll <maan@systemlinux.org>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
-
-/** \file wav.c a filter that inserts a wave header */
-
-#include "para.h"
-
-#include "list.h"
-#include "sched.h"
-#include "filter.h"
-#include "string.h"
-
-/** size of the output buffer */
-#define WAV_OUTBUF_SIZE 81920
-/** a wav header is always 44 bytes */
-#define WAV_HEADER_LEN 44
-/** always write 16 bit header */
-#define BITS 16
-
-/**
- * write a 32 bit unsigned value to a buffer
- *
- * \param buf the buffer to write to
- * \param x the value to write
- */
-#define WRITE_U32(buf, x) (buf)[0] = (unsigned char)((x) & 0xff);\
- (buf)[1] = (unsigned char)(((x) >> 8) & 0xff);\
- (buf)[2] = (unsigned char)(((x) >> 16) & 0xff);\
- (buf)[3] = (unsigned char)(((x) >> 24) & 0xff);
-
-/**
- * write a 16 bit unsigned value to a buffer
- *
- * \param buf the buffer to write to
- * \param x the value to write
- */
-#define WRITE_U16(buf, x) (buf)[0] = (unsigned char)((x) & 0xff);
-
-static void make_wav_header(unsigned int channels, unsigned int samplerate,
- struct filter_node *fn)
-{
-
- char *headbuf = fn->buf;
- unsigned int size = 0x7fffffff;
- int bytespersec = channels * samplerate * BITS / 8;
- int align = channels * BITS / 8;
-
- assert(channels);
- PARA_DEBUG_LOG("writing wave header: %d channels, %d KHz\n", channels, samplerate);
- memset(headbuf, 0, WAV_HEADER_LEN);
- memcpy(headbuf, "RIFF", 4);
- WRITE_U32(headbuf + 4, size - 8);
- memcpy(headbuf + 8, "WAVE", 4);
- memcpy(headbuf + 12, "fmt ", 4);
- WRITE_U32(headbuf + 16, 16);
- WRITE_U16(headbuf + 20, 1); /* format */
- WRITE_U16(headbuf + 22, channels);
- WRITE_U32(headbuf + 24, samplerate);
- WRITE_U32(headbuf + 28, bytespersec);
- WRITE_U16(headbuf + 32, align);
- WRITE_U16(headbuf + 34, BITS);
- memcpy(headbuf + 36, "data", 4);
- WRITE_U32(headbuf + 40, size - 44);
-}
-
-static ssize_t wav_convert(char *inbuf, size_t len, struct filter_node *fn)
-{
- size_t copy;
- int *bof = fn->private_data;
-
- if (*bof) {
- if (!len)
- return 0;
- make_wav_header(fn->fc->channels, fn->fc->samplerate, fn);
- fn->loaded = WAV_HEADER_LEN;
- *bof = 0;
-// return 0;
- }
- copy = PARA_MIN(len, fn->bufsize - fn->loaded);
- memmove(fn->buf + fn->loaded, inbuf, copy);
- fn->loaded += copy;
-// PARA_DEBUG_LOG("len = %d, copy = %d\n", len, copy);
- return copy;
-}
-
-static void wav_close(struct filter_node *fn)
-{
- free(fn->buf);
- fn->buf = NULL;
- free(fn->private_data);
- fn->private_data = NULL;
-}
-
-static void wav_open(struct filter_node *fn)
-{
- int *bof;
-
- fn->bufsize = WAV_OUTBUF_SIZE;
- fn->buf = para_malloc(fn->bufsize);
- fn->private_data = para_malloc(sizeof(int));
- bof = fn->private_data;
- fn->loaded = 0;
- *bof = 1;
- PARA_INFO_LOG("wav filter node: %p, output buffer: %p, loaded: %zd\n",
- fn, fn->buf, fn->loaded);
-}
-
-/**
- * the init function of the wav filter
- *
- * \param f struct to initialize
- */
-void wav_filter_init(struct filter *f)
-{
- f->convert = wav_convert;
- f->close = wav_close;
- f->open = wav_open;
-}
--- /dev/null
+/*
+ * Copyright (C) 2005-2008 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
+/** \file wav_filter.c A filter that inserts a wave header. */
+
+#include "para.h"
+
+#include "list.h"
+#include "sched.h"
+#include "filter.h"
+#include "string.h"
+
+/** size of the output buffer */
+#define WAV_OUTBUF_SIZE 81920
+/** a wav header is always 44 bytes */
+#define WAV_HEADER_LEN 44
+/** always write 16 bit header */
+#define BITS 16
+
+/**
+ * write a 32 bit unsigned value to a buffer
+ *
+ * \param buf the buffer to write to
+ * \param x the value to write
+ */
+#define WRITE_U32(buf, x) (buf)[0] = (unsigned char)((x) & 0xff);\
+ (buf)[1] = (unsigned char)(((x) >> 8) & 0xff);\
+ (buf)[2] = (unsigned char)(((x) >> 16) & 0xff);\
+ (buf)[3] = (unsigned char)(((x) >> 24) & 0xff);
+
+/**
+ * write a 16 bit unsigned value to a buffer
+ *
+ * \param buf the buffer to write to
+ * \param x the value to write
+ */
+#define WRITE_U16(buf, x) (buf)[0] = (unsigned char)((x) & 0xff);
+
+static void make_wav_header(unsigned int channels, unsigned int samplerate,
+ struct filter_node *fn)
+{
+
+ char *headbuf = fn->buf;
+ unsigned int size = 0x7fffffff;
+ int bytespersec = channels * samplerate * BITS / 8;
+ int align = channels * BITS / 8;
+
+ assert(channels);
+ PARA_DEBUG_LOG("writing wave header: %d channels, %d KHz\n", channels, samplerate);
+ memset(headbuf, 0, WAV_HEADER_LEN);
+ memcpy(headbuf, "RIFF", 4);
+ WRITE_U32(headbuf + 4, size - 8);
+ memcpy(headbuf + 8, "WAVE", 4);
+ memcpy(headbuf + 12, "fmt ", 4);
+ WRITE_U32(headbuf + 16, 16);
+ WRITE_U16(headbuf + 20, 1); /* format */
+ WRITE_U16(headbuf + 22, channels);
+ WRITE_U32(headbuf + 24, samplerate);
+ WRITE_U32(headbuf + 28, bytespersec);
+ WRITE_U16(headbuf + 32, align);
+ WRITE_U16(headbuf + 34, BITS);
+ memcpy(headbuf + 36, "data", 4);
+ WRITE_U32(headbuf + 40, size - 44);
+}
+
+static ssize_t wav_convert(char *inbuf, size_t len, struct filter_node *fn)
+{
+ size_t copy;
+ int *bof = fn->private_data;
+
+ if (*bof) {
+ if (!len)
+ return 0;
+ make_wav_header(fn->fc->channels, fn->fc->samplerate, fn);
+ fn->loaded = WAV_HEADER_LEN;
+ *bof = 0;
+// return 0;
+ }
+ copy = PARA_MIN(len, fn->bufsize - fn->loaded);
+ memmove(fn->buf + fn->loaded, inbuf, copy);
+ fn->loaded += copy;
+// PARA_DEBUG_LOG("len = %d, copy = %d\n", len, copy);
+ return copy;
+}
+
+static void wav_close(struct filter_node *fn)
+{
+ free(fn->buf);
+ fn->buf = NULL;
+ free(fn->private_data);
+ fn->private_data = NULL;
+}
+
+static void wav_open(struct filter_node *fn)
+{
+ int *bof;
+
+ fn->bufsize = WAV_OUTBUF_SIZE;
+ fn->buf = para_malloc(fn->bufsize);
+ fn->private_data = para_malloc(sizeof(int));
+ bof = fn->private_data;
+ fn->loaded = 0;
+ *bof = 1;
+ PARA_INFO_LOG("wav filter node: %p, output buffer: %p, loaded: %zd\n",
+ fn, fn->buf, fn->loaded);
+}
+
+/**
+ * the init function of the wav filter
+ *
+ * \param f struct to initialize
+ */
+void wav_filter_init(struct filter *f)
+{
+ f->convert = wav_convert;
+ f->close = wav_close;
+ f->open = wav_open;
+}