-
Notifications
You must be signed in to change notification settings - Fork 9
/
filters.h
101 lines (90 loc) · 3.34 KB
/
filters.h
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
/*
* JMPXRDS, an FM MPX signal generator with RDS support on
* top of Jack Audio Connection Kit - Various filter implementations
*
* Copyright (C) 2015 Nick Kossifidis <[email protected]>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h> /* For typed integers */
#include <fftw3.h> /* For FFTW support */
#include <jack/jack.h> /* For jack-related types */
/* A generic FFT-based FIR low pass filter */
struct lpf_filter_data {
uint16_t period_size;
uint16_t num_bins;
uint16_t middle_bin;
uint16_t cutoff_bin;
uint32_t sample_rate;
float bin_bw;
fftwf_complex *filter_resp;
fftwf_complex *complex_buff;
float *real_in;
float *real_out;
uint16_t overlap_len;
fftwf_plan dft_plan;
fftwf_plan ift_plan;
};
/*
* Filtering on the frequency domain introduces errors
* when going back to time domain due to the fixed number
* of frequency bins used (time domain is continuous, freq
* domain is discrete). Such errors introduce noise on the
* filter's output (time aliasing). To reduce the noise we
* use a method known as overlap-discard where we re-use
* an ammount of frames from the previous input and discard
* the same amount of frames (the overlap) on the output.
* In other words we use a sliding window for doing FFT that
* spawns across multiple periods to make the filter's output
* more continuous in time domain. As a result of this we'll
* obviously introduce a systematic delay between input and
* output (output will be delayed by overlap samples).
*/
#define AFLT_LPF_OVERLAP_FACTOR 3
#define SSB_LPF_OVERLAP_FACTOR 3
void lpf_filter_destroy(const struct lpf_filter_data *);
int lpf_filter_init(struct lpf_filter_data *, uint32_t, uint32_t, uint16_t, uint8_t);
int lpf_filter_apply(const struct lpf_filter_data *, const float*, float*, uint16_t, float);
/* FM Preemphasis IIR filter */
struct fmpreemph_filter_data {
float last_in;
float last_out[2];
float ataps_50[2];
float btaps_50[2];
float ataps_75[2];
float btaps_75[2];
};
enum fmpreemph_mode {
LPF_PREEMPH_50US = 0, /* E.U. / WORLD */
LPF_PREEMPH_75US = 1, /* U.S. */
LPF_PREEMPH_NONE = 2,
LPF_PREEMPH_MAX = 3
};
int
fmpreemph_filter_init(struct fmpreemph_filter_data *, float);
float
fmpreemph_filter_apply(struct fmpreemph_filter_data *,
float, enum fmpreemph_mode);
#define AFLT_CUTOFF_FREQ 16750
/* Hilbert transformer for the Hartley modulator (SSB) */
struct hilbert_transformer_data {
uint16_t num_bins;
fftwf_complex *complex_buff;
float *real_buff;
fftwf_plan dft_plan;
fftwf_plan ift_plan;
};
int hilbert_transformer_init(struct hilbert_transformer_data *ht, uint16_t);
void hilbert_transformer_destroy(const struct hilbert_transformer_data *ht);
int hilbert_transformer_apply(const struct hilbert_transformer_data *ht, const float *, uint16_t);