1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
/** @file
Various functions for baseband sample processing.
Copyright (C) 2012 by Benjamin Larsson <benjamin@southpole.se>
Copyright (C) 2015 Tommy Vestermark
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*/
#ifndef INCLUDE_BASEBAND_H_
#define INCLUDE_BASEBAND_H_
#include <stdint.h>
#include <math.h>
/** This will give a noisy envelope of OOK/ASK signals.
Subtract the bias (-128) and get an envelope estimation (absolute squared).
@param iq_buf input samples (I/Q samples in interleaved uint8)
@param[out] y_buf output buffer
@param len number of samples to process
@return the average level in dB
*/
float envelope_detect(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
// for evaluation
float envelope_detect_nolut(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
float magnitude_est_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
float magnitude_true_cu8(uint8_t const *iq_buf, uint16_t *y_buf, uint32_t len);
float magnitude_est_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len);
float magnitude_true_cs16(int16_t const *iq_buf, uint16_t *y_buf, uint32_t len);
#define AMP_TO_DB(x) (10.0f * ((x) > 0 ? log10f(x) : 0) - 42.1442f) // 10*log10f(16384.0f)
#define MAG_TO_DB(x) (20.0f * ((x) > 0 ? log10f(x) : 0) - 84.2884f) // 20*log10f(16384.0f)
#ifdef __exp10f
#define _exp10f(x) __exp10f(x)
#else
#define _exp10f(x) powf(10, x)
#endif
#define DB_TO_AMP(x) ((int)(_exp10f(((x) + 42.1442f) / 10.0f))) // 10*log10f(16384.0f)
#define DB_TO_MAG(x) ((int)(_exp10f(((x) + 84.2884f) / 20.0f))) // 20*log10f(16384.0f)
#define DB_TO_AMP_F(x) ((int)(0.5 + _exp10f((x) / 10.0f)))
#define DB_TO_MAG_F(x) ((int)(0.5 + _exp10f((x) / 20.0f)))
/*
tabulated magnitude and amplitude values:
10^(( 3 + 84.2884) / 20) = 23143 10^(( 3 + 42.1442) / 10) = 32690
10^(( 2 + 84.2884) / 20) = 20626 10^(( 2 + 42.1442) / 10) = 25967
10^(( 1 + 84.2884) / 20) = 18383 10^(( 1 + 42.1442) / 10) = 20626
10^(( 0 + 84.2884) / 20) = 16384 10^(( 0 + 42.1442) / 10) = 16384
10^((-1 + 84.2884) / 20) = 14602 10^((-1 + 42.1442) / 10) = 13014
10^((-2 + 84.2884) / 20) = 13014 10^((-2 + 42.1442) / 10) = 10338
10^((-3 + 84.2884) / 20) = 11599 10^((-3 + 42.1442) / 10) = 8211
10^((-4 + 84.2884) / 20) = 10338 10^((-4 + 42.1442) / 10) = 6523
10^((-5 + 84.2884) / 20) = 9213 10^((-5 + 42.1442) / 10) = 5181
10^((-6 + 84.2884) / 20) = 8211 10^((-6 + 42.1442) / 10) = 4115
10^((-7 + 84.2884) / 20) = 7318 10^((-7 + 42.1442) / 10) = 3269
10^((-8 + 84.2884) / 20) = 6523 10^((-8 + 42.1442) / 10) = 2597
10^((-9 + 84.2884) / 20) = 5813 10^((-9 + 42.1442) / 10) = 2063
10^((-10 + 84.2884) / 20) = 5181 10^((-10 + 42.1442) / 10) = 1638
10^((-11 + 84.2884) / 20) = 4618 10^((-11 + 42.1442) / 10) = 1301
10^((-12 + 84.2884) / 20) = 4115 10^((-12 + 42.1442) / 10) = 1034
10^((-13 + 84.2884) / 20) = 3668 10^((-13 + 42.1442) / 10) = 821
10^((-14 + 84.2884) / 20) = 3269 10^((-14 + 42.1442) / 10) = 652
10^((-15 + 84.2884) / 20) = 2914 10^((-15 + 42.1442) / 10) = 518
10^((-16 + 84.2884) / 20) = 2597 10^((-16 + 42.1442) / 10) = 412
10^((-17 + 84.2884) / 20) = 2314 10^((-17 + 42.1442) / 10) = 327
10^((-18 + 84.2884) / 20) = 2063 10^((-18 + 42.1442) / 10) = 260
10^((-19 + 84.2884) / 20) = 1838 10^((-19 + 42.1442) / 10) = 206
10^((-20 + 84.2884) / 20) = 1638 10^((-20 + 42.1442) / 10) = 164
10^((-21 + 84.2884) / 20) = 1460 10^((-21 + 42.1442) / 10) = 130
10^((-22 + 84.2884) / 20) = 1301 10^((-22 + 42.1442) / 10) = 103
10^((-23 + 84.2884) / 20) = 1160 10^((-23 + 42.1442) / 10) = 82
10^((-24 + 84.2884) / 20) = 1034 10^((-24 + 42.1442) / 10) = 65
10^((-25 + 84.2884) / 20) = 921 10^((-25 + 42.1442) / 10) = 52
10^((-26 + 84.2884) / 20) = 821 10^((-26 + 42.1442) / 10) = 41
10^((-27 + 84.2884) / 20) = 732 10^((-27 + 42.1442) / 10) = 33
10^((-28 + 84.2884) / 20) = 652 10^((-28 + 42.1442) / 10) = 26
10^((-29 + 84.2884) / 20) = 581 10^((-29 + 42.1442) / 10) = 21
10^((-30 + 84.2884) / 20) = 518 10^((-30 + 42.1442) / 10) = 16
10^((-31 + 84.2884) / 20) = 462 10^((-31 + 42.1442) / 10) = 13
10^((-32 + 84.2884) / 20) = 412 10^((-32 + 42.1442) / 10) = 10
*/
#define FILTER_ORDER 1
/// Filter state buffer.
typedef struct filter_state {
int16_t y[FILTER_ORDER];
int16_t x[FILTER_ORDER];
} filter_state_t;
/// FM_Demod state buffer.
typedef struct demodfm_state {
int32_t xr; ///< Last I/Q sample, real part
int32_t xi; ///< Last I/Q sample, imag part
int32_t xf; ///< Last Instantaneous frequency
int32_t yf; ///< Last Instantaneous frequency, low pass filtered
uint32_t rate; ///< Current sample rate
int32_t alp_16[2]; ///< Current low pass filter A coeffs, 16 bit
int32_t blp_16[2]; ///< Current low pass filter B coeffs, 16 bit
int64_t alp_32[2]; ///< Current low pass filter A coeffs, 32 bit
int64_t blp_32[2]; ///< Current low pass filter B coeffs, 32 bit
} demodfm_state_t;
/** Reset the lowpass filter to an initial state. */
void baseband_low_pass_filter_reset(filter_state_t *lowpass_filter);
/** Lowpass filter.
Function is stateful.
@param x_buf input samples to be filtered
@param[out] y_buf output from filter
@param len number of samples to process
@param[in,out] state State to store between chunk processing
*/
void baseband_low_pass_filter(filter_state_t *state, uint16_t const *x_buf, int16_t *y_buf, uint32_t len);
/** Reset the FM demodulator to an initial state. */
void baseband_demod_FM_reset(demodfm_state_t *demod_fm);
/** FM demodulator.
Function is stateful.
@param[in,out] state State to store between chunk processing
@param x_buf input samples (I/Q samples in interleaved uint8)
@param[out] y_buf output from FM demodulator
@param num_samples number of samples to process
@param samp_rate sample rate of samples to process
@param low_pass Low-pass filter frequency or ratio
*/
void baseband_demod_FM(demodfm_state_t *state, uint8_t const *x_buf, int16_t *y_buf, unsigned long num_samples, uint32_t samp_rate, float low_pass);
/// For evaluation.
void baseband_demod_FM_cs16(demodfm_state_t *state, int16_t const *x_buf, int16_t *y_buf, unsigned long num_samples, uint32_t samp_rate, float low_pass);
/** Initialize tables and constants.
Should be called once at startup.
*/
void baseband_init(void);
#endif /* INCLUDE_BASEBAND_H_ */
|