filter-chain: add hilbert function

Can be used to perform a 90 degree phase shift.
This commit is contained in:
Wim Taymans 2021-08-25 21:20:42 +02:00
parent 09a0fdcc0f
commit a701a500af

View file

@ -24,6 +24,7 @@
#include "config.h" #include "config.h"
#include <math.h>
#ifdef HAVE_SNDFILE #ifdef HAVE_SNDFILE
#include <sndfile.h> #include <sndfile.h>
#endif #endif
@ -491,6 +492,8 @@ static float *read_samples(const char *filename, float gain, int delay, int offs
length -= SPA_MIN(offset, length); length -= SPA_MIN(offset, length);
n = delay + length; n = delay + length;
if (n == 0)
return NULL;
samples = calloc(n * info.channels, sizeof(float)); samples = calloc(n * info.channels, sizeof(float));
if (samples == NULL) if (samples == NULL)
@ -518,6 +521,36 @@ static float *read_samples(const char *filename, float gain, int delay, int offs
#endif #endif
} }
static float *create_hilbert(const char *filename, float gain, int delay, int offset,
int length, int *n_samples)
{
float *samples, v;
int i, n, h;
if (length <= 0)
length = 1024;
length -= SPA_MIN(offset, length);
n = delay + length;
if (n == 0)
return NULL;
samples = calloc(n, sizeof(float));
if (samples == NULL)
return NULL;
gain *= 2 / M_PI;
h = length / 2;
for (i = 1; i < h; i += 2) {
v = (gain / i) * (0.43f + 0.57f * cosf(i * M_PI / h));
samples[delay + h + i] = -v;
samples[delay + h - i] = v;
}
*n_samples = n;
return samples;
}
static void * convolver_instantiate(const struct fc_descriptor * Descriptor, static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
unsigned long SampleRate, int index, const char *config) unsigned long SampleRate, int index, const char *config)
{ {
@ -577,13 +610,19 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
} }
if (!filename[0]) if (!filename[0])
return NULL; return NULL;
if (delay < 0) if (delay < 0)
delay = 0; delay = 0;
if (offset < 0) if (offset < 0)
offset = 0; offset = 0;
samples = read_samples(filename, gain, delay, offset, if (spa_streq(filename, "/hilbert")) {
length, channel, &n_samples); samples = create_hilbert(filename, gain, delay, offset,
length, &n_samples);
} else {
samples = read_samples(filename, gain, delay, offset,
length, channel, &n_samples);
}
if (samples == NULL) if (samples == NULL)
return NULL; return NULL;