Skip to content

Commit 9829481

Browse files
committed
fir, fir_p: Allow filter fs to be ignored.
1 parent 8b17eae commit 9829481

File tree

5 files changed

+37
-22
lines changed

5 files changed

+37
-22
lines changed

README.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,8 @@ Example:
284284
of coefficients for one filter channel. Missing values are filled with
285285
zeros.
286286

287-
The `input_options` are useful when loading raw (headerless) input files
288-
and are as follows:
287+
The `input_options` are useful mostly when loading raw (headerless) input
288+
files and are as follows:
289289

290290
Flag | Description
291291
----------------- | -----------------------------
@@ -295,6 +295,9 @@ Example:
295295
`-r frequency[k]` | Sample rate.
296296
`-c channels` | Number of channels.
297297

298+
By default, the sample rate of the filter must match that of the effect.
299+
Mismatches may be ignored by setting the sample rate to "any".
300+
298301
* `fir_p [input_options] [max_part_len] [file:][~/]filter_path|coefs:list[/list...]`
299302
Zero-latency non-uniform partitioned 64-bit direct/FFT convolution. Usually
300303
a bit slower than the `zita_convolver` effect except for very long filters

dsp.1

+6-2
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ filters up to 16 taps. For longer filters, the latency is equal to the
294294
of coefficients for one filter channel. Missing values are filled with
295295
zeros.
296296
.sp 0.5
297-
The \fIinput_options\fR are useful when loading raw (headerless) input files
298-
and are as follows:
297+
The \fIinput_options\fR are useful mostly when loading raw (headerless) input
298+
files and are as follows:
299299
.RS
300300
.TP
301301
\fB\-t\fR \fItype\fR
@@ -314,6 +314,10 @@ Sample rate.
314314
Number of channels.
315315
.RE
316316
.TP
317+
\
318+
By default, the sample rate of the filter must match that of the effect.
319+
Mismatches may be ignored by setting the sample rate to ``any''.
320+
.TP
317321
\fBfir_p\fR [\fIinput_options\fR] [\fImax_part_len\fR] [file:][~/]\fIfilter_path\fR|coefs:\fIlist\fR[/\fIlist\fR...]
318322
Zero-latency non-uniform partitioned 64-bit direct/FFT convolution. Usually
319323
a bit slower than the \fBzita_convolver\fR effect except for very long filters

fir.c

+24-16
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ struct effect * fir_effect_init_with_filter(const struct effect_info *ei, const
387387
return e;
388388
}
389389

390-
sample_t * fir_read_filter(const struct effect_info *ei, const char *dir, const struct codec_params *p, int *channels, ssize_t *frames)
390+
sample_t * fir_read_filter(const struct effect_info *ei, const struct stream_info *istream, const char *dir, const struct codec_params *p, int *channels, ssize_t *frames)
391391
{
392392
static const char coefs_str_prefix[] = "coefs:";
393393
static const char file_str_prefix[] = "file:";
@@ -445,6 +445,7 @@ sample_t * fir_read_filter(const struct effect_info *ei, const char *dir, const
445445
struct codec_params c_params = *p;
446446
c_params.path = fp;
447447
c_params.mode = CODEC_MODE_READ;
448+
if (p->fs == 0) c_params.fs = istream->fs;
448449
struct codec *c = init_codec(&c_params);
449450
if (c == NULL) {
450451
LOG_FMT(LL_ERROR, "%s: error: failed to open filter file: %s", ei->name, fp);
@@ -456,10 +457,13 @@ sample_t * fir_read_filter(const struct effect_info *ei, const char *dir, const
456457
free(fp);
457458
*channels = c->channels;
458459
*frames = c->frames;
459-
if (c->fs != p->fs) {
460-
LOG_FMT(LL_ERROR, "%s: error: sample rate mismatch: fs=%d filter_fs=%d", ei->name, p->fs, c->fs);
461-
destroy_codec(c);
462-
return NULL;
460+
if (c->fs != istream->fs) {
461+
if (p->fs > 0) {
462+
LOG_FMT(LL_ERROR, "%s: error: sample rate mismatch: fs=%d filter_fs=%d", ei->name, istream->fs, c->fs);
463+
destroy_codec(c);
464+
return NULL;
465+
}
466+
else LOG_FMT(LL_VERBOSE, "%s: info: ignoring sample rate mismatch: fs=%d filter_fs=%d", ei->name, istream->fs, c->fs);
463467
}
464468
data = calloc(c->frames * c->channels, sizeof(sample_t));
465469
if (c->read(c, data, c->frames) != c->frames) {
@@ -492,16 +496,20 @@ int fir_parse_opts(const struct effect_info *ei, const struct stream_info *istre
492496
case 'L': p->endian = CODEC_ENDIAN_LITTLE; break;
493497
case 'N': p->endian = CODEC_ENDIAN_LITTLE; break;
494498
case 'r':
495-
p->fs = lround(parse_freq(g->arg, &endptr));
496-
if (check_endptr(ei->name, g->arg, endptr, "sample rate"))
497-
return 1;
498-
if (p->fs <= 0) {
499-
LOG_FMT(LL_ERROR, "%s: error: sample rate must be > 0", ei->name);
500-
return 1;
501-
}
502-
if (p->fs != istream->fs) {
503-
LOG_FMT(LL_ERROR, "%s: error: sample rate mismatch: stream_fs=%d requested_fs=%d", ei->name, istream->fs, p->fs);
504-
return 1;
499+
if (strcmp(g->arg, "any") == 0)
500+
p->fs = 0;
501+
else {
502+
p->fs = lround(parse_freq(g->arg, &endptr));
503+
if (check_endptr(ei->name, g->arg, endptr, "sample rate"))
504+
return 1;
505+
if (p->fs <= 0) {
506+
LOG_FMT(LL_ERROR, "%s: error: sample rate must be > 0", ei->name);
507+
return 1;
508+
}
509+
if (p->fs != istream->fs) {
510+
LOG_FMT(LL_ERROR, "%s: error: sample rate mismatch: stream_fs=%d requested_fs=%d", ei->name, istream->fs, p->fs);
511+
return 1;
512+
}
505513
}
506514
break;
507515
case 'c':
@@ -543,7 +551,7 @@ struct effect * fir_effect_init(const struct effect_info *ei, const struct strea
543551
return NULL;
544552
}
545553
c_params.path = argv[g.ind];
546-
filter_data = fir_read_filter(ei, dir, &c_params, &filter_channels, &filter_frames);
554+
filter_data = fir_read_filter(ei, istream, dir, &c_params, &filter_channels, &filter_frames);
547555
if (filter_data == NULL)
548556
return NULL;
549557
e = fir_effect_init_with_filter(ei, istream, channel_selector, filter_data, filter_channels, filter_frames, 0);

fir.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#define FIR_INPUT_CODEC_OPTS "t:e:BLNr:c:"
2828

2929
struct effect * fir_effect_init_with_filter(const struct effect_info *, const struct stream_info *, const char *, sample_t *, int, ssize_t, int);
30-
sample_t * fir_read_filter(const struct effect_info *, const char *, const struct codec_params *, int *, ssize_t *);
30+
sample_t * fir_read_filter(const struct effect_info *, const struct stream_info *, const char *, const struct codec_params *, int *, ssize_t *);
3131
int fir_parse_opts(const struct effect_info *, const struct stream_info *, struct codec_params *, struct dsp_getopt_state *, int, const char *const *, const char *,
3232
int (*extra_opt_fn)(const struct effect_info *, const struct stream_info *, const struct codec_params *, int, const char *));
3333
struct effect * fir_effect_init(const struct effect_info *, const struct stream_info *, const char *, const char *, int, const char *const *);

fir_p.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ struct effect * fir_p_effect_init(const struct effect_info *ei, const struct str
539539
++g.ind;
540540
}
541541
c_params.path = argv[g.ind];
542-
filter_data = fir_read_filter(ei, dir, &c_params, &filter_channels, &filter_frames);
542+
filter_data = fir_read_filter(ei, istream, dir, &c_params, &filter_channels, &filter_frames);
543543
if (filter_data == NULL)
544544
return NULL;
545545
e = fir_p_effect_init_with_filter(ei, istream, channel_selector, filter_data, filter_channels, filter_frames, max_part_len);

0 commit comments

Comments
 (0)