2 * Copyright (C) 2009-2012 Andre Noll <maan@systemlinux.org>
4 * Licensed under the GPL v2. For licencing details see COPYING.
7 /** \file amp_filter.c Paraslash's amplify filter. */
12 #include "amp_filter.cmdline.h"
16 #include "buffer_tree.h"
21 extern char *stat_item_values
[NUM_STAT_ITEMS
];
23 /** Data specific to the amplify filter. */
24 struct private_amp_data
{
25 /** Points to the configuration data for this instance of this filter. */
26 struct amp_filter_args_info
*conf
;
27 /** Amplification factor. */
31 static void amp_close(struct filter_node
*fn
)
33 free(fn
->private_data
);
36 static int amp_parse_config(int argc
, char **argv
, void **config
)
38 struct amp_filter_args_info
*amp_conf
= para_calloc(sizeof(*amp_conf
));
39 int ret
= -E_AMP_SYNTAX
;
41 if (amp_filter_cmdline_parser(argc
, argv
, amp_conf
))
43 ret
= -ERRNO_TO_PARA_ERROR(EINVAL
);
44 if (amp_conf
->amp_arg
< 0)
53 static void amp_open(struct filter_node
*fn
)
55 struct private_amp_data
*pad
= para_calloc(sizeof(*pad
));
58 fn
->private_data
= pad
;
60 if (!pad
->conf
->amp_given
&& stat_item_values
[SI_AMPLIFICATION
])
61 sscanf(stat_item_values
[SI_AMPLIFICATION
], "%u", &pad
->amp
);
63 pad
->amp
= pad
->conf
->amp_arg
;
64 PARA_NOTICE_LOG("amplification: %u (scaling factor: %1.2f)\n",
65 pad
->amp
, pad
->amp
/ 64.0 + 1.0);
68 static void amp_post_select(__a_unused
struct sched
*s
, struct task
*t
)
70 struct filter_node
*fn
= container_of(t
, struct filter_node
, task
);
71 struct private_amp_data
*pad
= fn
->private_data
;
72 struct btr_node
*btrn
= fn
->btrn
;
73 int ret
, factor
= 64 + pad
->amp
;
74 size_t i
, in_bytes
, len
;
76 bool inplace
= btr_inplace_ok(btrn
);
78 if (pad
->amp
== 0) { /* no amplification */
79 t
->error
= -E_AMP_ZERO_AMP
;
80 btr_splice_out_node(btrn
);
84 ret
= btr_node_status(btrn
, fn
->min_iqs
, BTR_NT_INTERNAL
);
89 btr_merge(btrn
, fn
->min_iqs
);
90 in_bytes
= btr_next_buffer(btrn
, (char **)&in
);
92 if (len
== 0) { /* eof and in_bytes == 1 */
100 out
= para_malloc(len
* 2);
102 for (i
= 0; i
< len
; i
++) {
103 int x
= (in
[i
] * factor
) >> 6;
106 if (out
[i
] != x
) /* overflow, clip */
107 out
[i
] = (x
>= 0)? 32767 : -32768;
111 btr_pushdown_one(btrn
);
113 btr_consume(btrn
, len
* 2);
114 btr_add_output((char *)out
, len
* 2, btrn
);
121 btr_remove_node(&fn
->btrn
);
124 static void amp_free_config(void *conf
)
126 amp_filter_cmdline_parser_free(conf
);
130 * The init function of the amplify filter.
132 * \param f Pointer to the struct to initialize.
134 void amp_filter_init(struct filter
*f
)
136 struct amp_filter_args_info dummy
;
138 amp_filter_cmdline_parser_init(&dummy
);
140 f
->close
= amp_close
;
141 f
->pre_select
= generic_filter_pre_select
;
142 f
->post_select
= amp_post_select
;
143 f
->parse_config
= amp_parse_config
;
144 f
->free_config
= amp_free_config
;
145 f
->help
= (struct ggo_help
) {
146 .short_help
= amp_filter_args_info_help
,
147 .detailed_help
= amp_filter_args_info_detailed_help