From f816f702a5bd621a79cefeda9442801418a58fce Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 12 Aug 2021 09:59:56 +0200 Subject: [PATCH] filter-chain: make sndfile optional Replace the code paths that require sndfile with a fallback when the dependency was not found. --- meson.build | 5 +- .../module-filter-chain/builtin_plugin.c | 109 +++++++++++------- 2 files changed, 72 insertions(+), 42 deletions(-) diff --git a/meson.build b/meson.build index 9697e7331..f99d89a6a 100644 --- a/meson.build +++ b/meson.build @@ -325,7 +325,10 @@ sdl_dep = dependency('sdl2', required : get_option('sdl2')) summary({'SDL 2': sdl_dep.found()}, bool_yn: true, section: 'Misc dependencies') ncurses_dep = dependency('ncursesw', required : false) sndfile_dep = dependency('sndfile', version : '>= 1.0.20', required : get_option('sndfile')) -summary({'sndfile': sndfile_dep.found()}, bool_yn: true, section: 'pw-cat/pw-play/pw-dump tool') +summary({'sndfile': sndfile_dep.found()}, bool_yn: true, section: 'pw-cat/pw-play/pw-dump/filter-chain') +if sndfile_dep.found() + cdata.set('HAVE_SNDFILE', 1) +endif pulseaudio_dep = dependency('libpulse', required : get_option('libpulse')) summary({'libpulse': pulseaudio_dep.found()}, bool_yn: true, section: 'Streaming between daemons') avahi_dep = dependency('avahi-client', required : get_option('avahi')) diff --git a/src/modules/module-filter-chain/builtin_plugin.c b/src/modules/module-filter-chain/builtin_plugin.c index e26d2be09..dd0455e9a 100644 --- a/src/modules/module-filter-chain/builtin_plugin.c +++ b/src/modules/module-filter-chain/builtin_plugin.c @@ -22,9 +22,14 @@ * DEALINGS IN THE SOFTWARE. */ +#include "config.h" + +#ifdef HAVE_SNDFILE #include +#endif #include +#include #include "plugin.h" @@ -386,14 +391,63 @@ struct convolver_impl { struct convolver *conv; }; +static float *read_samples(const char *filename, float gain, int delay, int offset, + int length, int channel, int *n_samples) +{ + float *samples; +#ifdef HAVE_SNDFILE + SF_INFO info; + SNDFILE *f; + int i, n; + + spa_zero(info); + f = sf_open(filename, SFM_READ, &info) ; + if (f == NULL) { + fprintf(stderr, "can't open %s", filename); + return NULL; + } + + if (length <= 0) + length = info.frames; + else + length = SPA_MIN(length, info.frames); + + length -= SPA_MIN(offset, length); + + n = delay + length; + + samples = calloc(n * info.channels, sizeof(float)); + if (samples == NULL) + return NULL; + + if (offset > 0) + sf_seek(f, offset, SEEK_SET); + sf_readf_float(f, samples + (delay * info.channels), length); + sf_close(f); + + channel = channel % info.channels; + + for (i = 0; i < n; i++) + samples[i] = samples[info.channels * i + channel] * gain; + + *n_samples = n; + return samples; +#else + pw_log_error("compiled without sndfile support, can't load samples: " + "using dirac impulse"); + samples = calloc(1, sizeof(float)); + samples[0] = gain; + *n_samples = 1; + return samples; +#endif +} + static void * convolver_instantiate(const struct fc_descriptor * Descriptor, unsigned long SampleRate, int index, const char *config) { struct convolver_impl *impl; - SF_INFO info; - SNDFILE *f; float *samples; - int i, offset = 0, length = 0, channel = index, n_frames; + int offset = 0, length = 0, channel = index, n_samples; struct spa_json it[2]; const char *val; char key[256]; @@ -443,13 +497,18 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor, } if (!filename[0]) return NULL; + if (delay < 0) + delay = 0; + if (offset < 0) + offset = 0; - spa_zero(info); - f = sf_open(filename, SFM_READ, &info) ; - if (f == NULL) { - fprintf(stderr, "can't open %s", filename); + samples = read_samples(filename, gain, delay, offset, + length, channel, &n_samples); + if (samples == NULL) return NULL; - } + + if (blocksize <= 0) + blocksize = SPA_CLAMP(n_samples, 64, 256); impl = calloc(1, sizeof(*impl)); if (impl == NULL) @@ -457,40 +516,8 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor, impl->rate = SampleRate; - if (delay < 0) - delay = 0; - - if (length <= 0) - length = info.frames; - else - length = SPA_MIN(length, info.frames); - - if (offset < 0) - offset = 0; - length -= SPA_MIN(offset, length); - - n_frames = delay + length; - - if (blocksize == 0) - blocksize = SPA_CLAMP(n_frames, 64, 256); - - samples = calloc(sizeof(float), n_frames * info.channels); - if (samples == NULL) - return NULL; - - if (offset > 0) - sf_seek(f, offset, SEEK_SET); - sf_readf_float(f, samples + (delay * info.channels), length); - - channel = channel % info.channels; - - for (i = 0; i < n_frames; i++) - samples[i] = samples[info.channels * i + channel] * gain; - - impl->conv = convolver_new(blocksize, samples, n_frames); - + impl->conv = convolver_new(blocksize, samples, n_samples); free(samples); - sf_close(f); return impl; }