mirror of https://github.com/merbanan/rtl_433.git
140 lines
6.5 KiB
C
140 lines
6.5 KiB
C
/** @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;
|
|
|
|
/** 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(uint16_t const *x_buf, int16_t *y_buf, uint32_t len, filter_state_t *state);
|
|
|
|
/** FM demodulator.
|
|
|
|
Function is stateful.
|
|
@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
|
|
@param[in,out] state State to store between chunk processing
|
|
*/
|
|
void baseband_demod_FM(uint8_t const *x_buf, int16_t *y_buf, unsigned long num_samples, uint32_t samp_rate, float low_pass, demodfm_state_t *state);
|
|
|
|
/// For evaluation.
|
|
void baseband_demod_FM_cs16(int16_t const *x_buf, int16_t *y_buf, unsigned long num_samples, uint32_t samp_rate, float low_pass, demodfm_state_t *state);
|
|
|
|
/** Initialize tables and constants.
|
|
Should be called once at startup.
|
|
*/
|
|
void baseband_init(void);
|
|
|
|
#endif /* INCLUDE_BASEBAND_H_ */
|