1 /* Copyright (C) 2009 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
3 /** \file amp_filter.c Paraslash's amplify filter. */
8 #include "filter_cmd.lsg.h"
12 #include "buffer_tree.h"
17 extern char *stat_item_values
[NUM_STAT_ITEMS
];
19 /** Data specific to the amplify filter. */
20 struct private_amp_data
{
21 /** Amplification factor. */
25 static void amp_close(struct filter_node
*fn
)
27 free(fn
->private_data
);
30 static void amp_open(struct filter_node
*fn
)
32 struct private_amp_data
*pad
= para_calloc(sizeof(*pad
));
33 unsigned given
= FILTER_CMD_OPT_GIVEN(AMP
, AMP
, fn
->lpr
);
34 uint32_t amp_arg
= FILTER_CMD_OPT_UINT32_VAL(AMP
, AMP
, fn
->lpr
);
36 fn
->private_data
= pad
;
38 if (!given
&& stat_item_values
[SI_amplification
])
39 sscanf(stat_item_values
[SI_amplification
], "%u", &pad
->amp
);
42 PARA_INFO_LOG("amplification: %u (scaling factor: %1.2f)\n",
43 pad
->amp
, pad
->amp
/ 64.0 + 1.0);
46 static int amp_post_select(__a_unused
struct sched
*s
, void *context
)
48 struct filter_node
*fn
= context
;
49 struct private_amp_data
*pad
= fn
->private_data
;
50 struct btr_node
*btrn
= fn
->btrn
;
51 int ret
, factor
= 64 + pad
->amp
;
52 size_t i
, in_bytes
, len
;
54 bool inplace
= btr_inplace_ok(btrn
);
56 if (pad
->amp
== 0) { /* no amplification */
57 btr_splice_out_node(&fn
->btrn
);
58 return -E_AMP_ZERO_AMP
;
61 ret
= btr_node_status(btrn
, fn
->min_iqs
, BTR_NT_INTERNAL
);
66 btr_merge(btrn
, fn
->min_iqs
);
67 in_bytes
= btr_next_buffer(btrn
, (char **)&in
);
69 if (len
== 0) { /* eof and in_bytes == 1 */
77 out
= para_malloc(len
* 2);
79 for (i
= 0; i
< len
; i
++) {
80 int x
= (in
[i
] * factor
) >> 6;
83 if (out
[i
] != x
) /* overflow, clip */
84 out
[i
] = (x
>= 0)? 32767 : -32768;
88 btr_pushdown_one(btrn
);
90 btr_consume(btrn
, len
* 2);
91 btr_add_output((char *)out
, len
* 2, btrn
);
96 btr_remove_node(&fn
->btrn
);
100 const struct filter lsg_filter_cmd_com_amp_user_data
= {
103 .pre_select
= generic_filter_pre_select
,
104 .post_select
= amp_post_select
,