filter-chain: add more convolver options

Add gain, delay, offset, length, channels options.
Make default blocksize depend on the ir length.
This commit is contained in:
Wim Taymans 2021-08-11 13:53:09 +02:00
parent dbe9f02471
commit 755eab0cd3
3 changed files with 140 additions and 20 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);