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 /** Amplification factor. */
30 static void amp_close(struct filter_node
*fn
)
32 free(fn
->private_data
);
35 static int amp_parse_config(int argc
, char **argv
, void **config
)
37 struct amp_filter_args_info
*amp_conf
= para_calloc(sizeof(*amp_conf
));
38 int ret
= -E_AMP_SYNTAX
;
40 if (amp_filter_cmdline_parser(argc
, argv
, amp_conf
))
42 ret
= -ERRNO_TO_PARA_ERROR(EINVAL
);
43 if (amp_conf
->amp_arg
< 0)
52 static void amp_open(struct filter_node
*fn
)
54 struct private_amp_data
*pad
= para_calloc(sizeof(*pad
));
55 struct amp_filter_args_info
*conf
= fn
->conf
;
57 fn
->private_data
= pad
;
59 if (!conf
->amp_given
&& stat_item_values
[SI_AMPLIFICATION
])
60 sscanf(stat_item_values
[SI_AMPLIFICATION
], "%u", &pad
->amp
);
62 pad
->amp
= conf
->amp_arg
;
63 PARA_NOTICE_LOG("amplification: %u (scaling factor: %1.2f)\n",
64 pad
->amp
, pad
->amp
/ 64.0 + 1.0);
67 static void amp_post_select(__a_unused
struct sched
*s
, struct task
*t
)
69 struct filter_node
*fn
= container_of(t
, struct filter_node
, task
);
70 struct private_amp_data
*pad
= fn
->private_data
;
71 struct btr_node
*btrn
= fn
->btrn
;
72 int ret
, factor
= 64 + pad
->amp
;
73 size_t i
, in_bytes
, len
;
75 bool inplace
= btr_inplace_ok(btrn
);
77 if (pad
->amp
== 0) { /* no amplification */
78 t
->error
= -E_AMP_ZERO_AMP
;
79 btr_splice_out_node(btrn
);
83 ret
= btr_node_status(btrn
, fn
->min_iqs
, BTR_NT_INTERNAL
);
88 btr_merge(btrn
, fn
->min_iqs
);
89 in_bytes
= btr_next_buffer(btrn
, (char **)&in
);
91 if (len
== 0) { /* eof and in_bytes == 1 */
99 out
= para_malloc(len
* 2);
101 for (i
= 0; i
< len
; i
++) {
102 int x
= (in
[i
] * factor
) >> 6;
105 if (out
[i
] != x
) /* overflow, clip */
106 out
[i
] = (x
>= 0)? 32767 : -32768;
110 btr_pushdown_one(btrn
);
112 btr_consume(btrn
, len
* 2);
113 btr_add_output((char *)out
, len
* 2, btrn
);
120 btr_remove_node(&fn
->btrn
);
123 static void amp_free_config(void *conf
)
125 amp_filter_cmdline_parser_free(conf
);
129 * The init function of the amplify filter.
131 * \param f Pointer to the struct to initialize.
133 void amp_filter_init(struct filter
*f
)
135 struct amp_filter_args_info dummy
;
137 amp_filter_cmdline_parser_init(&dummy
);
139 f
->close
= amp_close
;
140 f
->pre_select
= generic_filter_pre_select
;
141 f
->post_select
= amp_post_select
;
142 f
->parse_config
= amp_parse_config
;
143 f
->free_config
= amp_free_config
;
144 f
->help
= (struct ggo_help
) {
145 .short_help
= amp_filter_args_info_help
,
146 .detailed_help
= amp_filter_args_info_detailed_help