File det_private.h¶
File List > detector > det_private.h
Go to the documentation of this file
#ifndef DET_PRIVATE_H
#define DET_PRIVATE_H
#include <stdlib.h>
#include <string.h>
/* det_noise_mode_t must be visible before this header is included. */
#ifndef DET_NOISE_MODE_T_DEFINED
# error "Include detector_core.h or detector2d_core.h before det_private.h"
#endif
static size_t
next_pow2 (size_t n)
{
size_t c = 1;
while (c < n)
c <<= 1;
return c;
}
/* Create a dp_f32_t ring of at least cap_min complex samples.
* dp_f32_create requires the byte count to be page-aligned, which varies
* by OS (4 KiB on Linux/Windows, 16 KiB on macOS). We start at the
* smallest power-of-2 >= cap_min and double until create succeeds. */
static dp_f32_t *
_ring_create (size_t cap_min)
{
size_t cap = next_pow2 (cap_min > 1 ? cap_min : 1);
dp_f32_t *ring = NULL;
while (!ring)
{
ring = dp_f32_create (cap);
if (!ring)
{
cap <<= 1;
if (cap > ((size_t)1 << 28))
return NULL; /* refuse > 256 M samples */
}
}
return ring;
}
static int
_cmp_f32_asc (const void *a, const void *b)
{
float fa = *(const float *)a;
float fb = *(const float *)b;
return (fa > fb) - (fa < fb);
}
static float
_noise_estimate (const float *mag, size_t lo, size_t hi, float *scratch,
det_noise_mode_t mode)
{
if (lo > hi)
return 0.0f;
size_t count = hi - lo + 1;
switch (mode)
{
case DET_NOISE_MEAN:
{
float s = 0.0f;
for (size_t i = lo; i <= hi; i++)
s += mag[i];
return s / (float)count;
}
case DET_NOISE_MEDIAN:
memcpy (scratch, mag + lo, count * sizeof (float));
qsort (scratch, count, sizeof (float), _cmp_f32_asc);
return scratch[count / 2];
case DET_NOISE_MIN:
{
float m = mag[lo];
for (size_t i = lo + 1; i <= hi; i++)
if (mag[i] < m)
m = mag[i];
return m;
}
case DET_NOISE_MAX:
{
float m = mag[lo];
for (size_t i = lo + 1; i <= hi; i++)
if (mag[i] > m)
m = mag[i];
return m;
}
}
return 0.0f; /* unreachable */
}
#endif /* DET_PRIVATE_H */