From: Andre Noll Date: Sat, 19 Jul 2008 15:24:52 +0000 (+0200) Subject: Merge commit 'meins/master' X-Git-Tag: v0.3.3~50 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=2b8ac364a9ad11f67bfc1cdd01c113bde30baaf7;hp=415a84f1c06c5779dfbfa140e876852c89abdc38 Merge commit 'meins/master' --- diff --git a/NEWS b/NEWS index 7404ab1d..684485cf 100644 --- a/NEWS +++ b/NEWS @@ -5,17 +5,18 @@ NEWS 0.3.3 (to be announced) "axiomatic perspectivity" ------------------------------------------------- -Internal code cleanups, improved tag handling and the new -amplification feature. +Internal code cleanups, bug fixes, improved tag handling and the new +amplification filter. - para_server uses the generic scheduling code. - overhaul of the virtual streaming system. - mp3: id3 version 2 support via libid3tag (optional) - ogg: vorbis comment support. - mp3 audio format handler cleanups. + - new filter: "amp" to amplify the amplitude of the audio stream - new status item/database entry: amplification. It is - used by the compress filter to pre-amplify the amplitude of the - audio stream. + used by the amp filter to pre-amplify the audio stream. + - fix a close-without-open bug in para_write. ----------------------------------------- 0.3.2 (2008-04-11) "probabilistic parity" diff --git a/amp_filter.c b/amp_filter.c new file mode 100644 index 00000000..392fff65 --- /dev/null +++ b/amp_filter.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2008 Andre Noll + * + * Licensed under the GPL v2. For licencing details see COPYING. + */ + +/** \file amp.c Paraslash's amplify filter. */ + +#include "para.h" +#include "amp_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 AMP_CHUNK_SIZE 40960 + +extern char *stat_item_values[NUM_STAT_ITEMS]; + +/** Data specific to the amplify filter. */ +struct private_amp_data { + /** Points to the configuration data for this instance of this filter. */ + struct amp_filter_args_info *conf; + /** Amplification factor. */ + unsigned amp; +}; + +static ssize_t amp_convert(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_amp_data *pad = fn->private_data; + int16_t *ip = (int16_t *)inbuf, *op = (int16_t *)(fn->buf + fn->loaded); + + if (!length) + return 0; + for (i = 0; i < length / 2; i++) { + int x = (PARA_ABS(*ip) * (64 + pad->amp)) >> 6; + *op++ = *ip++ > 0? PARA_MIN(x, 32767) : PARA_MAX(-x, -32768); + } + fn->loaded += length; + return length; +} + +static void amp_close(struct filter_node *fn) +{ + free(fn->private_data); + free(fn->buf); +} + +static void *amp_parse_config(int argc, char **argv) +{ + struct amp_filter_args_info *conf = para_calloc(sizeof(*conf)); + + if (amp_cmdline_parser(argc, argv, conf)) + goto err; + if (conf->amp_arg < 0) + goto err; + PARA_NOTICE_LOG("amplification: %u (scaling factor: %1.2f)\n", conf->amp_arg, + conf->amp_arg / 64.0 + 1.0); + return conf; +err: + free(conf); + return NULL; +} + +static void amp_open(struct filter_node *fn) +{ + struct private_amp_data *pad = para_calloc(sizeof(*pad)); + + pad->conf = fn->conf; + fn->private_data = pad; + if (!pad->conf->amp_given && stat_item_values[SI_AMPLIFICATION]) { + int i = SI_AMPLIFICATION; + char *s = stat_item_values[i] + strlen(status_item_list[i]) + 1; + sscanf(s, "%u", &pad->amp); + } else + pad->amp = pad->conf->amp_arg; + fn->bufsize = AMP_CHUNK_SIZE; + fn->buf = para_malloc(fn->bufsize); +} + +/** + * The init function of the amplify filter. + * + * \param f Pointer to the struct to initialize. + */ +void amp_init(struct filter *f) +{ + f->open = amp_open; + f->close = amp_close; + f->convert = amp_convert; + f->print_help = amp_cmdline_parser_print_help; + f->parse_config = amp_parse_config; +} diff --git a/amp_filter.ggo b/amp_filter.ggo new file mode 100644 index 00000000..1849dc3a --- /dev/null +++ b/amp_filter.ggo @@ -0,0 +1,21 @@ +section "The amplify filter" + +option "amp" a +"amplification value" +int typestr="number" +default="32" +optional +details=" + The amplification value determines the scaling factor by + which the amplitude of the audio stream is multiplied. The + formula for the scaling factor is + + factor = 1 + amp / 64 + + amp value scaling factor + ~~~~~~~~~ ~~~~~~~~~~~~~~ + 0 1 + 32 1.5 + 64 2 + 128 3 +" diff --git a/compress.c b/compress.c index 8e2f07c9..c30c998a 100644 --- a/compress.c +++ b/compress.c @@ -16,7 +16,6 @@ #include "sched.h" #include "filter.h" #include "string.h" -#include "audiod.h" /** The size of the output data buffer. */ #define COMPRESS_CHUNK_SIZE 40960 @@ -35,8 +34,6 @@ struct private_compress_data { unsigned num_samples; /** Absolute value of the maximal sample in the current block. */ unsigned peak; - /** Amplification factor. */ - unsigned amp; }; static ssize_t compress(char *inbuf, size_t inbuf_len, struct filter_node *fn) @@ -52,9 +49,8 @@ static ssize_t compress(char *inbuf, size_t inbuf_len, struct filter_node *fn) return 0; for (i = 0; i < length / 2; i++) { /* be careful in that heat, my dear */ - int sample = *ip++, adjusted_sample = (PARA_ABS(sample) * (64 + pcd->amp)) >> 6; - - adjusted_sample = (adjusted_sample * pcd->current_gain) >> gain_shift; + 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); @@ -106,13 +102,6 @@ static void open_compress(struct filter_node *fn) 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); - if (stat_item_values[SI_AMPLIFICATION]) { - int i = SI_AMPLIFICATION; - char *s = stat_item_values[i] + strlen(status_item_list[i]) + 1; - sscanf(s, "%u", &pcd->amp); - } - PARA_NOTICE_LOG("amplification: %u (scaling factor: %1.2f)\n", pcd->amp, - pcd->amp / 64.0 + 1.0); } /** diff --git a/configure.ac b/configure.ac index 79d930de..63cbdc97 100644 --- a/configure.ac +++ b/configure.ac @@ -79,12 +79,12 @@ AC_CHECK_FUNCS([atexit dup2 memchr memmove memset \ [AC_MSG_ERROR([function not found, cannot live without it])]) 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 +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 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" -all_executables="server recv filter audioc write client fsck afh" +all_executables="server recv filter audioc write client fsck afh amp_filter" recv_cmdline_objs="recv.cmdline http_recv.cmdline dccp_recv.cmdline" recv_errlist_objs="http_recv recv_common recv time string net dccp_recv @@ -94,10 +94,10 @@ recv_ldflags="" receivers=" http dccp" senders=" http dccp" -filter_cmdline_objs="filter.cmdline compress_filter.cmdline" -filter_errlist_objs="filter_chain wav compress filter string stdin stdout sched fd" +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_ldflags="" -filters=" compress wav" +filters=" compress wav amp" audioc_cmdline_objs="audioc.cmdline" audioc_errlist_objs="audioc string net fd" @@ -105,9 +105,9 @@ audioc_ldflags="" audiod_cmdline_objs="audiod.cmdline grab_client.cmdline compress_filter.cmdline http_recv.cmdline dccp_recv.cmdline file_write.cmdline client.cmdline - audiod_command_list" + audiod_command_list amp_filter.cmdline" audiod_errlist_objs="audiod signal string daemon stat net - time grab_client filter_chain wav compress http_recv dccp_recv + time grab_client filter_chain wav compress amp_filter http_recv dccp_recv recv_common fd sched write_common file_write audiod_command crypt client_common" audiod_ldflags="" diff --git a/error.h b/error.h index bbe72bdc..4674ec04 100644 --- a/error.h +++ b/error.h @@ -28,6 +28,8 @@ DEFINE_ERRLIST_OBJECT_ENUM; #define SEND_COMMON_ERRORS #define STDOUT_ERRORS #define IPC_ERRORS +#define AMP_FILTER_ERRORS + extern const char **para_errlist[]; diff --git a/filter.h b/filter.h index 550c68d6..500a8537 100644 --- a/filter.h +++ b/filter.h @@ -233,6 +233,7 @@ extern struct filter filters[]; /* filters that are always present */ DECLARE_EXTERN_FILTER_INIT(wav); DECLARE_EXTERN_FILTER_INIT(compress); +DECLARE_EXTERN_FILTER_INIT(amp); /* next the optional filters */ #ifdef HAVE_MAD @@ -261,6 +262,7 @@ DECLARE_EXTERN_FILTER_INIT(oggdec); #define DEFINE_FILTER_ARRAY(filters) struct filter filters[] = { \ FILTER_INIT(wav) \ FILTER_INIT(compress) \ + FILTER_INIT(amp) \ MP3DEC_FILTER \ AACDEC_FILTER \ OGGDEC_FILTER \ diff --git a/write.h b/write.h index a73ada5d..091f8c77 100644 --- a/write.h +++ b/write.h @@ -113,6 +113,8 @@ struct writer_node_group { unsigned int *samplerate; /** the task associated to this group */ struct task task; + /** Whether the group is open, i.e. wng_open() was called. */ + int open; }; /** loop over each writer node in a writer group */ diff --git a/write_common.c b/write_common.c index 70a9a015..3bf5d119 100644 --- a/write_common.c +++ b/write_common.c @@ -90,6 +90,7 @@ int wng_open(struct writer_node_group *g) } sprintf(g->task.status, "%s", "writer node group"); register_task(&g->task); + g->open = 1; return 1; err_out: PARA_ERROR_LOG("%s\n", para_strerror(-ret)); @@ -112,7 +113,7 @@ void wng_close(struct writer_node_group *g) { int i; - if (!g) + if (!g || !g->open) return; PARA_NOTICE_LOG("closing wng with %d writer(s)\n", g->num_writers); FOR_EACH_WRITER_NODE(i, g) {