From: Andre Noll Date: Sat, 12 Jul 2008 10:22:54 +0000 (+0200) Subject: Add the new amp filter. X-Git-Tag: v0.3.3~50^2~2 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=6d213d3638eafeab4785e64decc7f4826a964c32;p=paraslash.git Add the new amp filter. Move the amplification code from compress.c to amp_filter.c --- 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 \