miniDSP
A small C library for audio DSP
Loading...
Searching...
No Matches
minidsp_gcc.c File Reference

GCC-PHAT delay estimation: cross-correlation, delay search, and multi-signal delay estimation. More...

#include "minidsp.h"
#include "minidsp_internal.h"
Include dependency graph for minidsp_gcc.c:

Go to the source code of this file.

Functions

static void _xcorr_free (void)
 Free all dynamically allocated FFT buffers.
 
static void _xcorr_malloc (void)
 Allocate all buffers needed for cross-correlation of length _N.
 
static void _xcorr_teardown (void)
 Destroy existing FFTW plans and free all buffers.
 
static void _xcorr_setup (void)
 Allocate buffers and create FFTW plans for signals of length _N.
 
static void _gcc_setup (unsigned N)
 Ensure the cached FFT setup matches the requested signal length.
 
void md_gcc_teardown (void)
 Tear down the GCC-PHAT FFT cache and reset its cached length.
 
static void _fftshift (const double *in, double *out, unsigned N)
 Shift an FFT output so that the zero-lag is in the middle.
 
static void _max_index (const double *a, unsigned N, double *max, unsigned *maxi)
 Find the index and value of the maximum element in an array.
 
void MD_get_multiple_delays (const double **sigs, unsigned M, unsigned N, unsigned margin, int weightfunc, int *outdelays)
 Estimate delays between a reference signal and several other signals.
 
int MD_get_delay (const double *siga, const double *sigb, unsigned N, double *ent, unsigned margin, int weightfunc)
 Estimate the delay (in samples) between two signals.
 
void MD_gcc (const double *siga, const double *sigb, unsigned N, double *lagvals, int weightfunc)
 Compute the Generalized Cross-Correlation between two signals.
 

Variables

static unsigned _N = 0
 
static double * siga_loc = nullptr
 
static double * sigb_loc = nullptr
 
static double * lags_loc = nullptr
 
static fftw_complex * ffta = nullptr
 
static fftw_complex * fftb = nullptr
 
static fftw_complex * xspec = nullptr
 
static double * xcorr = nullptr
 
static fftw_plan pa = nullptr
 
static fftw_plan pb = nullptr
 
static fftw_plan px = nullptr
 

Detailed Description

GCC-PHAT delay estimation: cross-correlation, delay search, and multi-signal delay estimation.

Author
Chuck Wooters woote.nosp@m.rs@h.nosp@m.ey.co.nosp@m.m

How GCC-PHAT works (the big picture):

Imagine you clap your hands in a room with two microphones. Microphone A hears the clap slightly before microphone B because it is closer to you. GCC-PHAT measures that tiny time difference by looking at how the two signals line up in the frequency domain.

Mathematically:

  1. Take the FFT of both signals: FFT(A), FFT(B)
  2. Compute the cross-spectrum: X = FFT(B) * conj(FFT(A))
  3. Normalise by magnitude: X_phat = X / |X| (This "phase transform" sharpens the correlation peak.)
  4. Inverse-FFT back to time: xcorr = IFFT(X_phat)
  5. The index of the peak in xcorr tells you the delay.

Definition in file minidsp_gcc.c.

Function Documentation

◆ _fftshift()

static void _fftshift ( const double *  in,
double *  out,
unsigned  N 
)
static

Shift an FFT output so that the zero-lag is in the middle.

After an inverse FFT, the zero-lag (time=0) value is at index 0, with positive lags at the start and negative lags at the end. This function rearranges the array so that the zero-lag ends up at index ceil(N/2), which is more intuitive for reading off delays.

Before: [0, +1, +2, ..., +N/2, -N/2+1, ..., -2, -1] After: [-N/2+1, ..., -1, 0, +1, ..., +N/2]

Definition at line 167 of file minidsp_gcc.c.

◆ _gcc_setup()

static void _gcc_setup ( unsigned  N)
static

Ensure the cached FFT setup matches the requested signal length.

If the length changed, rebuild everything. Otherwise do nothing.

Definition at line 129 of file minidsp_gcc.c.

◆ _max_index()

static void _max_index ( const double *  a,
unsigned  N,
double *  max,
unsigned *  maxi 
)
static

Find the index and value of the maximum element in an array.

Parameters
aInput array.
NLength of the array (must be >= 1).
maxOutput: the maximum value found.
maxiOutput: the index of that maximum value.

Definition at line 187 of file minidsp_gcc.c.

◆ _xcorr_free()

static void _xcorr_free ( void  )
static

Free all dynamically allocated FFT buffers.

Definition at line 53 of file minidsp_gcc.c.

◆ _xcorr_malloc()

static void _xcorr_malloc ( void  )
static

Allocate all buffers needed for cross-correlation of length _N.

Definition at line 69 of file minidsp_gcc.c.

◆ _xcorr_setup()

static void _xcorr_setup ( void  )
static

Allocate buffers and create FFTW plans for signals of length _N.

FFTW plans describe how to compute an FFT of a given size. Creating a plan is slow (FFTW tries different strategies), but executing one is very fast. That is why we cache them.

We use real-to-complex (r2c) for forward transforms because our input signals are real-valued, and complex-to-real (c2r) for the inverse transform.

Definition at line 112 of file minidsp_gcc.c.

◆ _xcorr_teardown()

static void _xcorr_teardown ( void  )
static

Destroy existing FFTW plans and free all buffers.

IMPORTANT: This function does NOT reset _N. It is called from _xcorr_setup() where _N has already been set to the new value. Resetting _N here would corrupt the value just set by the caller.

Definition at line 91 of file minidsp_gcc.c.

◆ MD_gcc()

void MD_gcc ( const double *  siga,
const double *  sigb,
unsigned  N,
double *  lagvals,
int  weightfunc 
)

Compute the Generalized Cross-Correlation between two signals.

Compute the full generalized cross-correlation between two signals.

This is the core GCC-PHAT routine. It fills lagvals[] with the cross-correlation values, shifted so that the zero-lag value is at index ceil(N/2).

Parameters
sigaFirst signal.
sigbSecond signal.
NLength of both signals.
lagvalsOutput array of N doubles (pre-allocated by caller).
weightfuncSIMP or PHAT.

Definition at line 340 of file minidsp_gcc.c.

◆ md_gcc_teardown()

void md_gcc_teardown ( void  )

Tear down the GCC-PHAT FFT cache and reset its cached length.

Called only from MD_shutdown().

Definition at line 146 of file minidsp_gcc.c.

◆ MD_get_delay()

int MD_get_delay ( const double *  siga,
const double *  sigb,
unsigned  N,
double *  ent,
unsigned  margin,
int  weightfunc 
)

Estimate the delay (in samples) between two signals.

Estimate the delay between two signals.

The function computes the GCC between the two signals, then searches within a +/- margin window around zero-lag for the peak. The offset of that peak from zero is the estimated delay.

Parameters
sigaFirst signal (reference).
sigbSecond signal.
NLength of both signals.
entIf non-null, receives the normalised entropy of the lag values in the search window. High entropy (~1.0) means a flat, unreliable correlation; low entropy (~0.0) means a sharp, trustworthy peak.
marginHow far (in samples) to search around zero-lag.
weightfuncSIMP or PHAT.
Returns
Delay in samples.

Definition at line 290 of file minidsp_gcc.c.

◆ MD_get_multiple_delays()

void MD_get_multiple_delays ( const double **  sigs,
unsigned  M,
unsigned  N,
unsigned  margin,
int  weightfunc,
int *  outdelays 
)

Estimate delays between a reference signal and several other signals.

Estimate delays between a reference signal and M-1 other signals.

This is a convenience wrapper that calls MD_get_delay() for each non-reference signal. A Hanning window is applied to all signals before computing the cross-correlation.

Parameters
sigsArray of M pointers to signals. sigs[0] is the reference.
MNumber of signals (must be >= 2).
NLength of every signal.
marginSearch +/- margin samples around zero-lag.
weightfuncSIMP or PHAT.
outdelaysOutput: M-1 delay values (pre-allocated by caller).

Definition at line 225 of file minidsp_gcc.c.

Variable Documentation

◆ _N

unsigned _N = 0
static

Definition at line 35 of file minidsp_gcc.c.

◆ ffta

fftw_complex* ffta = nullptr
static

Definition at line 39 of file minidsp_gcc.c.

◆ fftb

fftw_complex* fftb = nullptr
static

Definition at line 40 of file minidsp_gcc.c.

◆ lags_loc

double* lags_loc = nullptr
static

Definition at line 38 of file minidsp_gcc.c.

◆ pa

fftw_plan pa = nullptr
static

Definition at line 44 of file minidsp_gcc.c.

◆ pb

fftw_plan pb = nullptr
static

Definition at line 45 of file minidsp_gcc.c.

◆ px

fftw_plan px = nullptr
static

Definition at line 46 of file minidsp_gcc.c.

◆ siga_loc

double* siga_loc = nullptr
static

Definition at line 36 of file minidsp_gcc.c.

◆ sigb_loc

double* sigb_loc = nullptr
static

Definition at line 37 of file minidsp_gcc.c.

◆ xcorr

double* xcorr = nullptr
static

Definition at line 42 of file minidsp_gcc.c.

◆ xspec

fftw_complex* xspec = nullptr
static

Definition at line 41 of file minidsp_gcc.c.