2 * Copyright (C) 2009 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 /** The size of the output data buffer. */
23 #define AMP_CHUNK_SIZE 40960
25 extern char *stat_item_values
[NUM_STAT_ITEMS
];
27 /** Data specific to the amplify filter. */
28 struct private_amp_data
{
29 /** Points to the configuration data for this instance of this filter. */
30 struct amp_filter_args_info
*conf
;
31 /** Amplification factor. */
35 static void amp_close(struct filter_node
*fn
)
37 free(fn
->private_data
);
41 static int amp_parse_config(int argc
, char **argv
, void **config
)
43 struct amp_filter_args_info
*amp_conf
= para_calloc(sizeof(*amp_conf
));
44 int ret
= -E_AMP_SYNTAX
;
46 if (amp_cmdline_parser(argc
, argv
, amp_conf
))
48 ret
= -ERRNO_TO_PARA_ERROR(EINVAL
);
49 if (amp_conf
->amp_arg
< 0)
58 static void amp_open(struct filter_node
*fn
)
60 struct private_amp_data
*pad
= para_calloc(sizeof(*pad
));
63 fn
->private_data
= pad
;
65 if (!pad
->conf
->amp_given
&& stat_item_values
[SI_AMPLIFICATION
])
66 sscanf(stat_item_values
[SI_AMPLIFICATION
], "%u", &pad
->amp
);
68 pad
->amp
= pad
->conf
->amp_arg
;
69 fn
->bufsize
= AMP_CHUNK_SIZE
;
70 fn
->buf
= para_malloc(fn
->bufsize
);
71 PARA_NOTICE_LOG("amplification: %u (scaling factor: %1.2f)\n",
72 pad
->amp
, pad
->amp
/ 64.0 + 1.0);
75 static void amp_post_select(__a_unused
struct sched
*s
, struct task
*t
)
77 struct filter_node
*fn
= container_of(t
, struct filter_node
, task
);
78 struct private_amp_data
*pad
= fn
->private_data
;
79 struct btr_node
*btrn
= fn
->btrn
;
80 int ret
, factor
= 64 + pad
->amp
;
81 size_t i
, in_bytes
, len
;
83 bool inplace
= btr_inplace_ok(btrn
);
85 if (pad
->amp
== 0) { /* no amplification */
86 t
->error
= -E_AMP_ZERO_AMP
;
87 btr_splice_out_node(btrn
);
91 ret
= btr_node_status(btrn
, fn
->min_iqs
, BTR_NT_INTERNAL
);
96 btr_merge(btrn
, fn
->min_iqs
);
97 in_bytes
= btr_next_buffer(btrn
, (char **)&in
);
99 if (len
== 0) { /* eof and in_bytes == 1 */
107 out
= para_malloc(len
* 2);
109 for (i
= 0; i
< len
; i
++) {
110 int x
= (in
[i
] * factor
) >> 6;
113 if (out
[i
] != x
) /* overflow, clip */
114 out
[i
] = (x
>= 0)? 32767 : -32768;
118 btr_pushdown_one(btrn
);
120 btr_consume(btrn
, len
* 2);
121 btr_add_output((char *)out
, len
* 2, btrn
);
128 btr_remove_node(btrn
);
131 static void amp_free_config(void *conf
)
133 amp_cmdline_parser_free(conf
);
137 * The init function of the amplify filter.
139 * \param f Pointer to the struct to initialize.
141 void amp_filter_init(struct filter
*f
)
143 struct amp_filter_args_info dummy
;
145 amp_cmdline_parser_init(&dummy
);
147 f
->close
= amp_close
;
148 f
->pre_select
= generic_filter_pre_select
;
149 f
->post_select
= amp_post_select
;
150 f
->parse_config
= amp_parse_config
;
151 f
->free_config
= amp_free_config
;
152 f
->help
= (struct ggo_help
) {
153 .short_help
= amp_filter_args_info_help
,
154 .detailed_help
= amp_filter_args_info_detailed_help