Skip to content

Commit

Permalink
Merge PR #112: New converters: u16o12 and s16 #109
Browse files Browse the repository at this point in the history
nb: regenerated starch files *not* committed yet, in the name of
minimizing merge conflicts for the moment.
  • Loading branch information
mutability committed Feb 11, 2021
2 parents 33bb2d9 + 1b5b46f commit 75650f2
Show file tree
Hide file tree
Showing 13 changed files with 890 additions and 181 deletions.
52 changes: 52 additions & 0 deletions convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,54 @@ static void convert_sc16q11(void *iq_data,
}
}

static void convert_s16(void *iq_data,
uint16_t *mag_data,
unsigned nsamples,
struct converter_state *state,
double *out_mean_level,
double *out_mean_power)
{
MODES_NOTUSED(state);

const int16_t *in = (const int16_t *) iq_data;

if (STARCH_IS_ALIGNED(in) && STARCH_IS_ALIGNED(mag_data))
starch_magnitude_s16_aligned(in, mag_data, nsamples);
else
starch_magnitude_s16(in, mag_data, nsamples);

if (out_mean_level && out_mean_power) {
if (STARCH_IS_ALIGNED(mag_data))
starch_mean_power_u16_aligned(mag_data, nsamples, out_mean_level, out_mean_power);
else
starch_mean_power_u16(mag_data, nsamples, out_mean_level, out_mean_power);
}
}

static void convert_u16o12(void *iq_data,
uint16_t *mag_data,
unsigned nsamples,
struct converter_state *state,
double *out_mean_level,
double *out_mean_power)
{
MODES_NOTUSED(state);

const uint16_t *in = (const uint16_t *) iq_data;

if (STARCH_IS_ALIGNED(in) && STARCH_IS_ALIGNED(mag_data))
starch_magnitude_u16o12_aligned(in, mag_data, nsamples);
else
starch_magnitude_u16o12(in, mag_data, nsamples);

if (out_mean_level && out_mean_power) {
if (STARCH_IS_ALIGNED(mag_data))
starch_mean_power_u16_aligned(mag_data, nsamples, out_mean_level, out_mean_power);
else
starch_mean_power_u16(mag_data, nsamples, out_mean_level, out_mean_power);
}
}

iq_convert_fn init_converter(input_format_t format,
double sample_rate,
int filter_dc,
Expand All @@ -111,6 +159,10 @@ iq_convert_fn init_converter(input_format_t format,
return convert_sc16;
case INPUT_SC16Q11:
return convert_sc16q11;
case INPUT_S16:
return convert_s16;
case INPUT_U16O12:
return convert_u16o12;
default:
fprintf(stderr, "no suitable converter for format=%d\n", format);
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#define DUMP1090_CONVERT_H

struct converter_state;
typedef enum { INPUT_UC8=0, INPUT_SC16, INPUT_SC16Q11 } input_format_t;
typedef enum { INPUT_UC8=0, INPUT_SC16, INPUT_SC16Q11, INPUT_S16, INPUT_U16O12 } input_format_t;

typedef void (*iq_convert_fn)(void *iq_data,
uint16_t *mag_data,
Expand Down
42 changes: 42 additions & 0 deletions dsp/benchmark/magnitude_s16_benchmark.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>


void STARCH_BENCHMARK(magnitude_s16) (void)
{
int16_t *in = NULL;
uint16_t *out_mag = NULL;
const unsigned len = 65535;

if (!(in = STARCH_BENCHMARK_ALLOC(len, int16_t)) || !(out_mag = STARCH_BENCHMARK_ALLOC(len, uint16_t))) {
goto done;
}

unsigned i = 0;

for (; i < len; ++i) {
in[i] = i - 32767;
out_mag[i] = abs(in[i]);
}

STARCH_BENCHMARK_RUN( magnitude_s16, in, out_mag, len );

done:
STARCH_BENCHMARK_FREE(in);
STARCH_BENCHMARK_FREE(out_mag);
}

bool STARCH_BENCHMARK_VERIFY(magnitude_s16) (const int16_t *in, uint16_t *out, unsigned len)
{
bool okay = true;

for (unsigned i = 0; i < len; ++i) {
okay = (out[i] == abs(in[i]));
if (!okay) {
fprintf(stderr, "verification failed: in[%u]=%d out[%u]=%u\n", i, in[i], i, out[i]);
}
}

return okay;
}
48 changes: 48 additions & 0 deletions dsp/benchmark/magnitude_u16o12_benchmark.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

void STARCH_BENCHMARK(magnitude_u16o12) (void)
{
uint16_t *in = NULL;
uint16_t *out_mag = NULL;
const unsigned len = 4096;
unsigned i;

if (!(in = STARCH_BENCHMARK_ALLOC(len, uint16_t)) || !(out_mag = STARCH_BENCHMARK_ALLOC(len, uint16_t))) {
goto done;
}

for (i = 1; i < len; i++) {
in[i] = i;
}

STARCH_BENCHMARK_RUN( magnitude_u16o12, in, out_mag, len );

done:
STARCH_BENCHMARK_FREE(in);
STARCH_BENCHMARK_FREE(out_mag);
}

bool STARCH_BENCHMARK_VERIFY(magnitude_u16o12) (const uint16_t *in, uint16_t *out, unsigned len)
{
bool okay = true;

for (unsigned i = 1; i < len; ++i) {
uint16_t j;
if (in[i] < 2048) {
j = 2048 - (out[i] * 2047.0 / 65535.0f - 0.5f);
} else {
j = 2048 + (out[i] * 2047.0 / 65535.0f + 0.5f);
}
okay = (j == in[j]);
if (!okay) {
fprintf(stderr, "verification failed: in[%u]=%d out[%u]=%u\n", i, in[i], i, out[i]);
}
}

return okay;
}

#undef CONVERT_AND_SCALE
#undef MAGIC_SCALER
23 changes: 23 additions & 0 deletions dsp/helpers/tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,26 @@ const uint16_t * get_sc16q11_mag_12bit_table()
return table;
}

#define CONVERT_AND_SCALE(__in) ceil(abs(le16toh(__in) - 2048) * (32767.0 / 2047.0))

const uint16_t * get_u16o12_mag_table()
{
static uint16_t *table = NULL;

if (table) {
return table;
}

table = malloc(sizeof(uint16_t) * 4096 * 4096);
if (!table) {
fprintf(stderr, "can't allocate u16to12 conversion lookup table\n");
abort();
}

table[0] = 65535;
for (int i = 1; i < 4096 ; i++) {
table[i] = CONVERT_AND_SCALE(i);
}

return table;
}
1 change: 1 addition & 0 deletions dsp/helpers/tables.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
const uint16_t * get_uc8_mag_table();
const uint16_t * get_sc16q11_mag_11bit_table();
const uint16_t * get_sc16q11_mag_12bit_table();
const uint16_t * get_u16o12_mag_table();

#endif
17 changes: 17 additions & 0 deletions dsp/impl/magnitude_s16.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <math.h>
#include <endian.h>

/* Convert (little-endian) signed 16-bit values to unsigned 16-bit magnitudes */

void STARCH_IMPL(magnitude_s16, exact_u32) (const int16_t *in, uint16_t *out, unsigned len)
{
const int16_t * restrict in_align = STARCH_ALIGNED(in);
uint16_t * restrict out_align = STARCH_ALIGNED(out);

while (len--) {
out_align[0] = abs((int16_t) le16toh(in_align[0]));

out_align += 1;
in_align += 1;
}
}
Loading

0 comments on commit 75650f2

Please sign in to comment.