+ int ret;
+ struct resample_context *ctx = fn->private_data;
+ struct btr_node *btrn = fn->btrn;
+ struct lls_parse_result *lpr = fn->lpr;
+
+ ctx->channels = U32_OPTVAL(CHANNELS, lpr);
+ if (!OPT_GIVEN(CHANNELS, lpr)) {
+ ret = get_btr_val("channels", btrn);
+ if (ret >= 0)
+ ctx->channels = ret;
+ }
+ ctx->source_sample_rate = U32_OPTVAL(SAMPLE_RATE, lpr);
+ if (!OPT_GIVEN(SAMPLE_RATE, lpr)) {
+ ret = get_btr_val("sample_rate", btrn);
+ if (ret >= 0)
+ ctx->source_sample_rate = ret;
+ }
+ /* reject all sample formats except 16 bit signed, little endian */
+ ret = get_btr_val("sample_format", btrn);
+ if (ret >= 0 && ret != SF_S16_LE) {
+ const char * const sample_formats[] = {SAMPLE_FORMATS};
+ PARA_ERROR_LOG("unsupported sample format: %s\n",
+ sample_formats[ret]);
+ return -ERRNO_TO_PARA_ERROR(EINVAL);
+ }
+ ctx->ratio = U32_OPTVAL(DEST_SAMPLE_RATE, lpr)
+ / (float)ctx->source_sample_rate;
+ return 1;
+}
+
+static int resample_init(struct filter_node *fn)
+{
+ 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(trafo[converter],
+ U32_OPTVAL(CHANNELS, fn->lpr), &ret);
+ if (!ctx->src_state) {
+ PARA_ERROR_LOG("%s\n", src_strerror(ret));
+ return -E_LIBSAMPLERATE;
+ }
+ fn->min_iqs = 2 * ctx->channels;
+ return 1;