File: baseband.h

package info (click to toggle)
rtl-433 25.12-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,192 kB
  • sloc: ansic: 55,982; cpp: 3,263; python: 2,544; php: 55; javascript: 43; sh: 18; makefile: 16
file content (145 lines) | stat: -rw-r--r-- 6,843 bytes parent folder | download
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_ */