forked from n1gp/rtl_hpsdr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrtl_hpsdr.h
182 lines (162 loc) · 5.37 KB
/
rtl_hpsdr.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#ifndef _RTL_HPSDR_H
#define _RTL_HPSDR_H
/* This file rtl_hpsdr.h is part of rtl_hpsdr.
*
* rtl_hpsdr - an RTL to HPSDR software translation server
* Copyright (C) 2014 Richard Koch
*
* rtl_hpsdr 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.
*
* rtl_hpsdr 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 rtl_hpsdr. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/timeb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <pthread.h>
#include <stdbool.h>
#include <semaphore.h>
#include <time.h>
#include <signal.h>
#include <unistd.h>
#include <math.h>
#include <limits.h>
#include <string.h>
#include <libgen.h>
#include <errno.h>
#include <rtl-sdr.h>
#ifdef INCLUDE_NEON
#include <arm_neon.h>
#elif defined INCLUDE_SSE2
#include <xmmintrin.h>
#endif
#define PRG_VERSION "1.3" // see ChangeLog for history
#define HERMES_FW_VER 25 //2.5
#define PORT 1024
#define MAX_BUFFER_LEN (2048 * 8)
#define HPSDR_FRAME_LEN 1032
#define IQ_FRAME_DATA_LEN 63
#define DOWNSAMPLE_192 8 // downsample value used to get 192khz
#define RTL_SAMPLE_RATE (192000 * DOWNSAMPLE_192)
#define RTL_READ_COUNT (2048 * DOWNSAMPLE_192 * 8)
#define MAX_RCVRS 8 // cuSDR64 limits this to 7
#define MAXSTR 64
#define COEFF3072_H_16_LENGTH 16
#define COEFF1536_H_16_LENGTH 16
#define COEFF1536_H_32_LENGTH 32
#define COEFF1536_H_64_LENGTH 64
extern float coeff3072_768_H_16[COEFF3072_H_16_LENGTH];
extern float coeff1536_384_H_16[COEFF1536_H_16_LENGTH];
extern float coeff1536_192_H_16[COEFF1536_H_16_LENGTH];
extern float coeff1536_96_H_16[COEFF1536_H_16_LENGTH];
extern float coeff1536_48_H_16[COEFF1536_H_16_LENGTH];
extern float coeff1536_384_H_32[COEFF1536_H_32_LENGTH];
extern float coeff1536_192_H_32[COEFF1536_H_32_LENGTH];
extern float coeff1536_96_H_32[COEFF1536_H_32_LENGTH];
extern float coeff1536_48_H_32[COEFF1536_H_32_LENGTH];
extern float coeff1536_384_H_64[COEFF1536_H_64_LENGTH];
extern float coeff1536_192_H_64[COEFF1536_H_64_LENGTH];
extern float coeff1536_96_H_64[COEFF1536_H_64_LENGTH];
extern float coeff1536_48_H_64[COEFF1536_H_64_LENGTH];
#define BIQUAD_COEFF_IN_STAGE 5
#define IIR_LPF_STAGES 3
#define IIR_LPF_Taps_STATE_SIZE (IIR_LPF_STAGES * 2)
typedef struct
{
uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */
float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
} arm_biquad_cascade_df2T_instance_f32;
struct main_cb {
int total_num_rcvrs;
int active_num_rcvrs;
u_int rcvrs_mask;
int nsamps_packet;
int frame_offset1;
int frame_offset2;
int output_rate;
int length_fir;
char sound_dev[32];
char net_dev[32];
// the last array member is used to remember last settings
int agc_mode[MAX_RCVRS + 1];
int direct_mode[MAX_RCVRS + 1];
int gain[MAX_RCVRS + 1];
int freq_offset[MAX_RCVRS + 1];
int rcvr_order[MAX_RCVRS + 1];
int signal_multiplier[MAX_RCVRS + 1];
struct timeb freq_ltime[MAX_RCVRS];
struct timeb freq_ttime[MAX_RCVRS];
// filter coefficient table pointers
float* align1536_48_H;
float* align1536_96_H;
float* align1536_192_H;
float* align1536_384_H;
float* align3072_768_H;
float* coeff_48;
float* coeff_96;
float* coeff_192;
float* coeff_384;
float* coeff_768;
struct rcvr_cb {
float dest[4] __attribute__((aligned(16)));
int rcvr_num;
int freq;
u_int rcvr_mask;
rtlsdr_dev_t* rtldev;
struct main_cb* mcb;
pthread_t hpsdrsim_sendiq_thr;
pthread_t rtl_read_thr;
int iqSample_offset;
int iqSamples_remaining;
float iqSamples[(RTL_READ_COUNT + (IQ_FRAME_DATA_LEN * 2))];
u_char rtl_buf[RTL_READ_COUNT];
float* iq_buf;
float* iq_buf_final;
float iq_buf_I[RTL_READ_COUNT];
float iq_buf_Q[RTL_READ_COUNT];
float32_t IIR_LPF_I_State[IIR_LPF_Taps_STATE_SIZE];
float32_t IIR_LPF_Q_State[IIR_LPF_Taps_STATE_SIZE];
arm_biquad_cascade_df2T_instance_f32 IIR_LPF_I;
arm_biquad_cascade_df2T_instance_f32 IIR_LPF_Q;
bool LPF_inited;
bool LPF_downsampled;
} rcb[MAX_RCVRS];
};
void downsample(struct rcvr_cb* rcb);
void downsample_init();
void format_payload(void);
int init_rtl(int rcvr_num, int dev_index);
void load_packet(struct rcvr_cb* rcb);
void rtl_sighandler(int signum);
int get_addr(int sock, char* ifname);
void hpsdrsim_reveal(void);
static pthread_t hpsdrsim_thread_id;
void* hpsdrsim_thread(void* arg);
static pthread_t watchdog_thread_id;
void* hpsdrsim_watchdog_thread(void* arg);
void* hpsdrsim_sendiq_thr_func(void* arg);
void* rtl_read_thr_func(void* arg);
void hpsdrsim_stop_threads();
void open_local_sound(char* adevice);
void close_local_sound();
void write_local_sound(unsigned char* samples);
void reopen_local_sound();
#endif // _RTL_HPSDR_H