2 * Copyright (C) 2009-2010 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. */
13 #include "amp_filter.cmdline.h"
17 #include "buffer_tree.h"
22 extern char *stat_item_values
[NUM_STAT_ITEMS
];
24 /** Data specific to the amplify filter. */
25 struct private_amp_data
{
26 /** Points to the configuration data for this instance of this filter. */
27 struct amp_filter_args_info
*conf
;
28 /** Amplification factor. */
32 static void amp_close(struct filter_node
*fn
)
34 free(fn
->private_data
);
37 static int amp_parse_config(int argc
, char **argv
, void **config
)
39 struct amp_filter_args_info
*amp_conf
= para_calloc(sizeof(*amp_conf
));
40 int ret
= -E_AMP_SYNTAX
;
42 if (amp_cmdline_parser(argc
, argv
, amp_conf
))
44 ret
= -ERRNO_TO_PARA_ERROR(EINVAL
);
45 if (amp_conf
->amp_arg
< 0)
54 static void amp_open(struct filter_node
*fn
)
56 struct private_amp_data
*pad
= para_calloc(sizeof(*pad
));
59 fn
->private_data
= pad
;
61 if (!pad
->conf
->amp_given
&& stat_item_values
[SI_AMPLIFICATION
])
62 sscanf(stat_item_values
[SI_AMPLIFICATION
], "%u", &pad
->amp
);
64 pad
->amp
= pad
->conf
->amp_arg
;
65 PARA_NOTICE_LOG("amplification: %u (scaling factor: %1.2f)\n",
66 pad
->amp
, pad
->amp
/ 64.0 + 1.0);
69 static void amp_post_select(__a_unused
struct sched
*s
, struct task
*t
)
71 struct filter_node
*fn
= container_of(t
, struct filter_node
, task
);
72 struct private_amp_data
*pad
= fn
->private_data
;
73 struct btr_node
*btrn
= fn
->btrn
;
74 int ret
, factor
= 64 + pad
->amp
;
75 size_t i
, in_bytes
, len
;
77 bool inplace
= btr_inplace_ok(btrn
);
79 if (pad
->amp
== 0) { /* no amplification */
80 t
->error
= -E_AMP_ZERO_AMP
;
81 btr_splice_out_node(btrn
);
85 ret
= btr_node_status(btrn
, fn
->min_iqs
, BTR_NT_INTERNAL
);
90 btr_merge(btrn
, fn
->min_iqs
);
91 in_bytes
= btr_next_buffer(btrn
, (char **)&in
);
93 if (len
== 0) { /* eof and in_bytes == 1 */
101 out
= para_malloc(len
* 2);
103 for (i
= 0; i
< len
; i
++) {
104 int x
= (in
[i
] * factor
) >> 6;
107 if (out
[i
] != x
) /* overflow, clip */
108 out
[i
] = (x
>= 0)? 32767 : -32768;
112 btr_pushdown_one(btrn
);
114 btr_consume(btrn
, len
* 2);
115 btr_add_output((char *)out
, len
* 2, btrn
);
122 btr_remove_node(btrn
);
125 static void amp_free_config(void *conf
)
127 amp_cmdline_parser_free(conf
);
131 * The init function of the amplify filter.
133 * \param f Pointer to the struct to initialize.
135 void amp_filter_init(struct filter
*f
)
137 struct amp_filter_args_info dummy
;
139 amp_cmdline_parser_init(&dummy
);
141 f
->close
= amp_close
;
142 f
->pre_select
= generic_filter_pre_select
;
143 f
->post_select
= amp_post_select
;
144 f
->parse_config
= amp_parse_config
;
145 f
->free_config
= amp_free_config
;
146 f
->help
= (struct ggo_help
) {
147 .short_help
= amp_filter_args_info_help
,
148 .detailed_help
= amp_filter_args_info_detailed_help