diff --git a/src/daemon/filter-chain/sink-convolver.conf b/src/daemon/filter-chain/sink-convolver.conf index aa84b9801..c40358d6c 100644 --- a/src/daemon/filter-chain/sink-convolver.conf +++ b/src/daemon/filter-chain/sink-convolver.conf @@ -34,19 +34,108 @@ context.modules = [ nodes = [ { type = builtin - name = convolver label = convolver + name = convFL config = { - filename = "src/modules/module-filter-chain/street2-L.wav" - blocksize = 512 + filename = "hrir_kemar/hrir-kemar.wav" + channel = 0 } } + { + type = builtin + label = convolver + name = convFR + config = { + filename = "hrir_kemar/hrir-kemar.wav" + channel = 4 + } + } + { + type = builtin + label = convolver + name = convFC + config = { + filename = "hrir_kemar/hrir-kemar.wav" + channel = 2 + } + } + { + type = builtin + label = convolver + name = convLFE + config = { + filename = "hrir_kemar/hrir-kemar.wav" + channel = 3 + } + } + { + type = builtin + label = convolver + name = convSL + config = { + filename = "hrir_kemar/hrir-kemar.wav" + channel = 1 + } + } + { + type = builtin + label = convolver + name = convSR + config = { + filename = "hrir_kemar/hrir-kemar.wav" + channel = 5 + } + } + { + type = builtin + label = mixer + name = mix1L + } + { + type = builtin + label = mixer + name = mix1R + } + { + type = builtin + label = mixer + name = mixC + } + { + type = builtin + label = mixer + name = mix2L + } + { + type = builtin + label = mixer + name = mix2R + } ] + links = [ + { output = "convFL:Out" input = "mix1L:In 1" } + { output = "convSL:Out" input = "mix1L:In 2" } + + { output = "convFR:Out" input = "mix1R:In 1" } + { output = "convSR:Out" input = "mix1R:In 2" } + + { output = "convFC:Out" input = "mixC:In 1" } + { output = "convLFE:Out" input = "mixC:In 2" } + + { output = "mixC:Out" input = "mix2L:In 1" } + { output = "mix1L:Out" input = "mix2L:In 2" } + + { output = "mixC:Out" input = "mix2R:In 1" } + { output = "mix1R:Out" input = "mix2R:In 2" } + ] + inputs = [ "convFL:In" "convFR:In" "convFC:In" "convLFE:In" "convSL:In" "convSR:In" ] + outputs = [ "mix2L:Out" "mix2R:Out" ] + } capture.props = { media.class = Audio/Sink - audio.channels = 2 - audio.position = [ FL FR ] + audio.channels = 6 + audio.position = [ FL FR FC LFE SL SR] } playback.props = { node.passive = true diff --git a/src/modules/module-filter-chain/builtin_plugin.c b/src/modules/module-filter-chain/builtin_plugin.c index 35a03bc09..d563e7ab2 100644 --- a/src/modules/module-filter-chain/builtin_plugin.c +++ b/src/modules/module-filter-chain/builtin_plugin.c @@ -393,12 +393,14 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor, SF_INFO info; SNDFILE *f; float *samples; - int i, offset; + int i, offset = 0, length = 0, channel = index, n_frames; struct spa_json it[2]; const char *val; char key[256]; char filename[PATH_MAX] = ""; - int blocksize = 256; + int blocksize = 0; + int delay = 0; + float gain = 1.0f; if (config == NULL) return NULL; @@ -408,16 +410,32 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor, return NULL; while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) { - if (spa_streq(key, "filename")) { - if (spa_json_get_string(&it[1], filename, sizeof(filename)) <= 0) - return NULL; - } - else if (spa_streq(key, "blocksize")) { + if (spa_streq(key, "blocksize")) { if (spa_json_get_int(&it[1], &blocksize) <= 0) return NULL; } + else if (spa_streq(key, "gain")) { + if (spa_json_get_float(&it[1], &gain) <= 0) + return NULL; + } + else if (spa_streq(key, "delay")) { + if (spa_json_get_int(&it[1], &delay) <= 0) + return NULL; + } + else if (spa_streq(key, "filename")) { + if (spa_json_get_string(&it[1], filename, sizeof(filename)) <= 0) + return NULL; + } else if (spa_streq(key, "offset")) { - if (spa_json_get_int(&it[1], &index) <= 0) + if (spa_json_get_int(&it[1], &offset) <= 0) + return NULL; + } + else if (spa_streq(key, "length")) { + if (spa_json_get_int(&it[1], &length) <= 0) + return NULL; + } + else if (spa_streq(key, "channel")) { + if (spa_json_get_int(&it[1], &channel) <= 0) return NULL; } else if (spa_json_next(&it[1], &val) < 0) @@ -439,18 +457,31 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor, impl->rate = SampleRate; - samples = malloc(info.frames * sizeof(float) * info.channels); + if (length == 0) + length = info.frames; + else + length = SPA_MIN(length, info.frames); + + 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; - sf_readf_float(f, samples, info.frames); + sf_seek(f, offset, SEEK_SET); + sf_readf_float(f, samples + (delay * info.channels), length); - offset = index % info.channels; + channel = channel % info.channels; - for (i = 0; i < info.frames; i++) - samples[i] = samples[info.channels * i + offset]; + for (i = 0; i < n_frames; i++) + samples[i] = samples[info.channels * i + channel] * gain; - impl->conv = convolver_new(blocksize, samples, info.frames); + impl->conv = convolver_new(blocksize, samples, n_frames); free(samples); sf_close(f); diff --git a/src/modules/module-filter-chain/convolver.c b/src/modules/module-filter-chain/convolver.c index 00c4390d3..7a46cbbc1 100644 --- a/src/modules/module-filter-chain/convolver.c +++ b/src/modules/module-filter-chain/convolver.c @@ -180,7 +180,7 @@ int convolver_run(struct convolver *conv, const float *input, float *output, int kiss_fftri_f32(conv->ifft, conv->conv, conv->fft_buffer); for (i = 0; i < conv->segSize; i++) - conv->fft_buffer[i] /= conv->segSize * 2; + conv->fft_buffer[i] /= conv->segSize; Sum(output + processed, conv->fft_buffer + inputBufferPos, conv->overlap + inputBufferPos, processing);