-/*
- * Copyright (C) 2012 Andre Noll <maan@tuebingen.mpg.de>
- *
- * Licensed under the GPL v2. For licencing details see COPYING.
- */
+/* Copyright (C) 2012 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
/** \file resample_filter.c A sample rate converter based on libsamplerate. */
static void resample_open(struct filter_node *fn)
{
- struct resample_context *ctx = para_calloc(sizeof(*ctx));
+ struct resample_context *ctx = zalloc(sizeof(*ctx));
struct btr_node *btrn = fn->btrn;
struct wav_params wp;
btr_log_tree(btr_parent(btr_parent(btrn)), LL_INFO);
}
-static void resample_pre_select(struct sched *s, void *context)
+static void resample_pre_monitor(struct sched *s, void *context)
{
struct filter_node *fn = context;
struct resample_context *ctx = fn->private_data;
if (ret != 0)
return sched_min_delay(s);
- check_wav_pre_select(s, ctx->cwc);
+ check_wav_pre_monitor(s, ctx->cwc);
}
static int get_btr_val(const char *what, struct btr_node *btrn)
static int resample_init(struct filter_node *fn)
{
- int ret, converter = *(int *)fn->conf;
+ int ret;
+ const uint32_t trafo[] = {
+ [RCT_BEST] = SRC_SINC_BEST_QUALITY,
+ [RCT_MEDIUM] = SRC_SINC_MEDIUM_QUALITY,
+ [RCT_FASTEST] = SRC_SINC_FASTEST,
+ [RCT_ZERO_ORDER_HOLD] = SRC_ZERO_ORDER_HOLD,
+ [RCT_LINEAR] = SRC_LINEAR
+ };
struct resample_context *ctx = fn->private_data;
+ const struct lls_option *o_c = FILTER_CMD_OPT(RESAMPLE, CONVERTER);
+ uint32_t converter = U32_OPTVAL(CONVERTER, fn->lpr);
+ PARA_INFO_LOG("converter type: %s\n",
+ lls_enum_string_val(converter, o_c));
ret = resample_set_params(fn);
if (ret < 0)
return ret;
- ctx->src_state = src_new(converter, U32_OPTVAL(CHANNELS, fn->lpr), &ret);
+ ctx->src_state = src_new(trafo[converter],
+ U32_OPTVAL(CHANNELS, fn->lpr), &ret);
if (!ctx->src_state) {
PARA_ERROR_LOG("%s\n", src_strerror(ret));
return -E_LIBSAMPLERATE;
size_t *result_frames)
{
int ret, num_samples, out_samples;
+ float *in_float;
int16_t *out;
SRC_DATA data;
data.output_frames = num_frames * ctx->ratio + 1;
out_samples = data.output_frames * ctx->channels;
- data.data_in = para_malloc(num_samples * sizeof(float));
- src_short_to_float_array(in, data.data_in, num_samples);
- data.data_out = para_malloc(out_samples * sizeof(float));
+ in_float = arr_alloc(num_samples, sizeof(float));
+ src_short_to_float_array(in, in_float, num_samples);
+ data.data_in = in_float;
+ data.data_out = arr_alloc(out_samples, sizeof(float));
ret = src_process(ctx->src_state, &data);
- free(data.data_in);
+ free(in_float);
if (ret != 0) {
PARA_ERROR_LOG("%s\n", src_strerror(ret));
free(data.data_out);
return -E_LIBSAMPLERATE;
}
out_samples = data.output_frames_gen * ctx->channels;
- out = para_malloc(out_samples * sizeof(short));
+ out = arr_alloc(out_samples, sizeof(short));
src_float_to_short_array(data.data_out, out, out_samples);
free(data.data_out);
*result = out;
return data.input_frames_used;
}
-static int resample_post_select(__a_unused struct sched *s, void *context)
+static int resample_post_monitor(__a_unused struct sched *s, void *context)
{
int ret;
struct filter_node *fn = context;
size_t in_bytes, num_frames;
bool have_more;
- ret = check_wav_post_select(ctx->cwc);
+ ret = check_wav_post_monitor(ctx->cwc);
if (ret < 0)
goto out;
ret = btr_node_status(btrn, fn->min_iqs, BTR_NT_INTERNAL);
}
btr_merge(btrn, fn->min_iqs);
in_bytes = btr_next_buffer(btrn, (char **)&in);
- ret = -E_RESAMPLE_EOF;
+ ret = -E_EOF;
num_frames = in_bytes / 2 / ctx->channels;
if (num_frames == 0)
goto out;
if (ret < 0) {
btr_remove_node(&fn->btrn);
/* This releases the check_wav btr node */
- check_wav_post_select(ctx->cwc);
+ check_wav_post_monitor(ctx->cwc);
}
return ret;
}
static void *resample_setup(const struct lls_parse_result *lpr)
{
- int given, *converter;
- const char *converter_arg;
+ int given;
uint32_t u32;
/* sanity checks */
PARA_EMERG_LOG("fatal: destination sample rate can not be 0\n");
exit(EXIT_FAILURE);
}
- converter = para_malloc(sizeof(int));
- converter_arg = FILTER_CMD_OPT_STRING_VAL(RESAMPLE, CONVERTER, lpr);
- if (!strcmp(converter_arg, "best"))
- *converter = SRC_SINC_BEST_QUALITY;
- else if (!strcmp(converter_arg, "medium"))
- *converter = SRC_SINC_MEDIUM_QUALITY;
- else if (!strcmp(converter_arg, "fastest"))
- *converter = SRC_SINC_FASTEST;
- else if (!strcmp(converter_arg, "zero_order_hold"))
- *converter = SRC_ZERO_ORDER_HOLD;
- else if (!strcmp(converter_arg, "linear"))
- *converter = SRC_LINEAR;
- else {
- PARA_EMERG_LOG("invalid converter type: %s\n", converter_arg);
- exit(EXIT_FAILURE);
- }
- return converter;
+ return NULL;
}
static void resample_teardown(__a_unused const struct lls_parse_result *lpr,
const struct filter lsg_filter_cmd_com_resample_user_data = {
.setup = resample_setup,
.open = resample_open,
- .pre_select = resample_pre_select,
- .post_select = resample_post_select,
+ .pre_monitor = resample_pre_monitor,
+ .post_monitor = resample_post_monitor,
.close = resample_close,
.teardown = resample_teardown,
.execute = resample_execute