2 * Copyright (C) 2009-2013 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 /** Amplification factor. */
29 static void amp_close(struct filter_node
*fn
)
31 free(fn
->private_data
);
34 static int amp_parse_config(int argc
, char **argv
, void **config
)
36 struct amp_filter_args_info
*conf
= para_calloc(sizeof(*conf
));
37 int ret
= -E_AMP_SYNTAX
;
39 amp_filter_cmdline_parser(argc
, argv
, conf
);
40 ret
= -ERRNO_TO_PARA_ERROR(EINVAL
);
41 if (conf
->amp_arg
< 0)
50 static void amp_open(struct filter_node
*fn
)
52 struct private_amp_data
*pad
= para_calloc(sizeof(*pad
));
53 struct amp_filter_args_info
*conf
= fn
->conf
;
55 fn
->private_data
= pad
;
57 if (!conf
->amp_given
&& stat_item_values
[SI_AMPLIFICATION
])
58 sscanf(stat_item_values
[SI_AMPLIFICATION
], "%u", &pad
->amp
);
60 pad
->amp
= conf
->amp_arg
;
61 PARA_NOTICE_LOG("amplification: %u (scaling factor: %1.2f)\n",
62 pad
->amp
, pad
->amp
/ 64.0 + 1.0);
65 static void amp_post_select(__a_unused
struct sched
*s
, struct task
*t
)
67 struct filter_node
*fn
= container_of(t
, struct filter_node
, task
);
68 struct private_amp_data
*pad
= fn
->private_data
;
69 struct btr_node
*btrn
= fn
->btrn
;
70 int ret
, factor
= 64 + pad
->amp
;
71 size_t i
, in_bytes
, len
;
73 bool inplace
= btr_inplace_ok(btrn
);
75 if (pad
->amp
== 0) { /* no amplification */
76 t
->error
= -E_AMP_ZERO_AMP
;
77 btr_splice_out_node(btrn
);
81 ret
= btr_node_status(btrn
, fn
->min_iqs
, BTR_NT_INTERNAL
);
86 btr_merge(btrn
, fn
->min_iqs
);
87 in_bytes
= btr_next_buffer(btrn
, (char **)&in
);
89 if (len
== 0) { /* eof and in_bytes == 1 */
97 out
= para_malloc(len
* 2);
99 for (i
= 0; i
< len
; i
++) {
100 int x
= (in
[i
] * factor
) >> 6;
103 if (out
[i
] != x
) /* overflow, clip */
104 out
[i
] = (x
>= 0)? 32767 : -32768;
108 btr_pushdown_one(btrn
);
110 btr_consume(btrn
, len
* 2);
111 btr_add_output((char *)out
, len
* 2, btrn
);
118 btr_remove_node(&fn
->btrn
);
121 static void amp_free_config(void *conf
)
123 amp_filter_cmdline_parser_free(conf
);
127 * The init function of the amplify filter.
129 * \param f Pointer to the struct to initialize.
131 void amp_filter_init(struct filter
*f
)
133 struct amp_filter_args_info dummy
;
135 amp_filter_cmdline_parser_init(&dummy
);
137 f
->close
= amp_close
;
138 f
->pre_select
= generic_filter_pre_select
;
139 f
->post_select
= amp_post_select
;
140 f
->parse_config
= amp_parse_config
;
141 f
->free_config
= amp_free_config
;
142 f
->help
= (struct ggo_help
) {
143 .short_help
= amp_filter_args_info_help
,
144 .detailed_help
= amp_filter_args_info_detailed_help