-
Notifications
You must be signed in to change notification settings - Fork 9
/
fmmod.h
138 lines (130 loc) · 3.8 KB
/
fmmod.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
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
/*
* JMPXRDS, an FM MPX signal generator with RDS support on
* top of Jack Audio Connection Kit - Main processor
*
* 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 <jack/jack.h> /* For jack-related types */
#include "filters.h"
#include "resampler.h"
#include "oscilator.h" /* Also brings in stdint.h and config.h */
#include "rds_encoder.h"
#include "rtp_server.h"
/* We need something big enough to output the MPX
* signal. 96KHz should be enough for the audio part
* with SSB enabled but for proper stereo imaging and
* in order to support RDS output too (57Khz carrier)
* 192Khz is needed. */
#define FMMOD_OUTPUT_SAMPLERATE 192000
enum fmmod_errors {
FMMOD_ERR_INVALID_INPUT = -1,
FMMOD_ERR_RESAMPLER_ERR = -2,
FMMOD_ERR_JACKD_ERR = -3,
FMMOD_ERR_NOMEM = -4,
FMMOD_ERR_OSC_ERR = -5,
FMMOD_ERR_RDS_ERR = -6,
FMMOD_ERR_SHM_ERR = -7,
FMMOD_ERR_SOCK_ERR = -8,
FMMOD_ERR_RTP_ERR = -9,
FMMOD_ERR_ALREADY_RUNNING = -10,
FMMOD_ERR_LPF = -11,
FMMOD_ERR_HILBERT = -12,
FMMOD_ERR_AFLT = -13,
};
/* Stereo signal (L-R) encoding:
* DSB -> Double side band (default)
* SSB HARTLEY -> Single Side Band Hartley modulator
* SSB LPF -> LPF-Based Single Side Band modulator
* For more infos check out fmmod.c */
enum fmmod_stereo_modulation {
FMMOD_DSB = 0,
FMMOD_SSB_HARTLEY = 1,
FMMOD_SSB_LPF = 2,
FMMOD_MONO = 3
};
/* Control I/O channel */
struct fmmod_control {
float audio_gain;
float pilot_gain;
float rds_gain;
float stereo_carrier_gain;
float mpx_gain;
enum fmmod_stereo_modulation stereo_modulation;
int use_audio_lpf;
enum fmpreemph_mode preemph_tau;
float peak_mpx_out;
float peak_audio_in_l;
float peak_audio_in_r;
int sample_rate;
int max_samples;
};
/* Filters */
struct fmmod_flts {
struct fmpreemph_filter_data fmprf_l;
struct fmpreemph_filter_data fmprf_r;
struct lpf_filter_data lpf_l;
struct lpf_filter_data lpf_r;
struct lpf_filter_data ssb_lpf;
struct hilbert_transformer_data ht;
};
struct fmmod_instance {
/* State */
int active;
pthread_mutex_t proc_mutex;
pthread_cond_t proc_trigger;
jack_native_thread_t proc_tid;
/* Audio input buffer */
float *inbuf_l;
float *inbuf_r;
pthread_mutex_t inbuf_mutex;
uint32_t num_in_samples;
uint32_t num_out_samples;
uint32_t upsampled_num_samples;
/* Upsampled audio buffers */
float *uaudio_buf_0;
float *uaudio_buf_1;
pthread_mutex_t uaudio_buf_mutex;
/* MPX Output buffer */
float *umpxbuf;
float *outbuf;
pthread_mutex_t mpx_buf_mutex;
/* For socket output */
int out_sock_fd;
/* Filters */
struct fmmod_flts flts;
/* The Oscilator */
struct osc_state sin_osc;
/* The resampler */
struct resampler_data rsmpl;
/* The RDS Encoder */
struct rds_encoder rds_enc;
/* The RTP Server */
struct rtp_server rtpsrv;
/* Jack-related */
jack_port_t *inL;
jack_port_t *inR;
jack_port_t *outMPX;
jack_client_t *client;
jack_nframes_t added_latency;
/* SSB modulators */
struct osc_state cos_osc;
/* Control */
struct shm_mapping *ctl_map;
struct fmmod_control *ctl;
};
typedef int (*mpx_generator) (struct fmmod_instance *, const float*, const float*, int, float*);
int fmmod_initialize(struct fmmod_instance *fmmod);
void fmmod_destroy(struct fmmod_instance *fmmod, int shutdown);