File farrow_core.h¶
File List > farrow > farrow_core.h
Go to the documentation of this file
#ifndef FARROW_CORE_H
#define FARROW_CORE_H
#include "clib_common.h"
#include "jm_perf.h"
#include "dp_state.h"
#include <complex.h>
#ifdef __cplusplus
extern "C" {
#endif
enum {
FARROW_LINEAR = 0,
FARROW_PARABOLIC = 1,
FARROW_CUBIC = 2,
};
/* All orders interpolate between tap d[1] and d[2]; d[3] is the newest sample,
* so the interpolation point lags the newest input by FARROW_GROUP_DELAY. */
#define FARROW_GROUP_DELAY 2u
typedef struct {
float complex d[4];
int order;
} farrow_state_t;
JM_FORCEINLINE void
farrow_init (farrow_state_t *s, int order)
{
s->d[0] = s->d[1] = s->d[2] = s->d[3] = 0.0f;
s->order = order;
}
JM_FORCEINLINE JM_HOT void
farrow_push (farrow_state_t *s, float complex x)
{
s->d[0] = s->d[1];
s->d[1] = s->d[2];
s->d[2] = s->d[3];
s->d[3] = x;
}
JM_FORCEINLINE JM_HOT float complex
farrow_eval (const farrow_state_t *s, float mu)
{
float complex d0 = s->d[0], d1 = s->d[1], d2 = s->d[2], d3 = s->d[3];
if (s->order == FARROW_LINEAR)
return d1 + mu * (d2 - d1);
if (s->order == FARROW_PARABOLIC)
{
/* symmetric piecewise-parabolic (Farrow, α = 0.5): linear plus a
* symmetric μ(μ-1) parabolic correction → no delay bias. */
float complex u = d0 - d1 - d2 + d3;
float complex c2 = 0.5f * u;
float complex c1 = (d2 - d1) - c2;
return (c2 * mu + c1) * mu + d1;
}
/* cubic */
float complex c3 = (1.0f / 6.0f) * (-d0 + 3.0f * d1 - 3.0f * d2 + d3);
float complex c2 = 0.5f * (d0 - 2.0f * d1 + d2);
float complex c1
= (1.0f / 6.0f) * (-2.0f * d0 - 3.0f * d1 + 6.0f * d2 - d3);
return ((c3 * mu + c2) * mu + c1) * mu + d1;
}
farrow_state_t *farrow_create(int order);
void farrow_destroy(farrow_state_t *state);
void farrow_reset(farrow_state_t *state);
size_t farrow_delay_max_out(farrow_state_t *state);
size_t farrow_delay(farrow_state_t *state, const float complex *x, size_t x_len, double mu, float complex *out, size_t max_out);
size_t farrow_get_group_delay(const farrow_state_t *state);
/* ── Serializable state (standard bytes interface; see dp_state.h) ──────────
* Whole-struct POD snapshot (pointer-free); the 4-tap delay line + order resume exactly into an
* identically-built instance. */
#define FARROW_STATE_MAGIC DP_FOURCC ('F', 'R', 'R', 'W')
#define FARROW_STATE_VERSION 1u
size_t farrow_state_bytes (const farrow_state_t *state);
void farrow_get_state (const farrow_state_t *state, void *blob);
int farrow_set_state (farrow_state_t *state, const void *blob);
#ifdef __cplusplus
}
#endif
#endif /* FARROW_CORE_H */