-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain_receiver.c
More file actions
188 lines (156 loc) · 6.83 KB
/
main_receiver.c
File metadata and controls
188 lines (156 loc) · 6.83 KB
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
183
184
185
186
187
188
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
// 引入所有模块
#include "common.h"
#include "css_common.h"
#include "source_codec.h"
#include "tbcc_channel.h"
#include "css_modulator.h"
#include "css_demodulator.h"
#include "interleaver.h"
// === 新增头文件 ===
#include "css_doppler.h"
// ==========================================
// 工具函数:保存数据到文件
// ==========================================
void save_debug_data(const char *filename, const float *data, size_t len) {
FILE *fp = fopen(filename, "w");
if (!fp) {
printf("[Error] Could not open file %s for writing\n", filename);
return;
}
for (size_t i = 0; i < len; i++) {
fprintf(fp, "%f\n", data[i]);
}
fclose(fp);
printf("[File] Saved %zu samples to '%s'\n", len, filename);
}
void print_preview_int(const char *label, const int *data, int len) {
printf(" > %-30s: ", label);
for (int i = 0; i < len; i++) printf("%d", data[i]);
printf("...\n");
}
void print_preview_float(const char *label, const float *data, int len) {
printf(" > %-30s: ", label);
for (int i = 0; i < len; i++) printf("%+.1f ", data[i]);
printf("...\n");
}
// ==========================================
// 信道模拟:高斯白噪声
// ==========================================
void add_awgn(float *signal, size_t len, float snr_db) {
float sig_energy = 0;
for(size_t i=0; i<len; i++) sig_energy += signal[i]*signal[i];
float sig_power = sig_energy / len;
float noise_power = sig_power / pow(10.0, snr_db/10.0);
float noise_std = sqrt(noise_power);
printf("\n[Channel] Adding AWGN (SNR: %.1f dB)...\n", snr_db);
for (size_t i = 0; i < len; i++) {
float u1 = (float)rand() / RAND_MAX;
float u2 = (float)rand() / RAND_MAX;
if(u1 < 1e-6) u1 = 1e-6;
float z = sqrt(-2.0 * log(u1)) * cos(2.0 * PI * u2);
signal[i] += noise_std * z;
}
}
// ==========================================
// 主函数
// ==========================================
int main() {
srand(time(NULL));
printf("============================================\n");
printf(" CSS Full Chain Receiver Simulation \n");
printf("============================================\n");
// 1. 初始化
tbcc_init();
ModConfig mod_cfg = {
.fs = 192000.0, .bw_total_low = 9000.0, .bw_total_high = 15000.0,
.subband_bw = 300.0, .subband_guard = 80.0, .num_subbands = 16,
.t_hfm_sync = 0.050, .t_lfm_pilot = 0.050, .t_guard_long = 0.020,
.t_sym_active = 0.020, .t_sym_guard = 0.020
};
WaveformBank *bank = mod_init_waveform_bank(&mod_cfg);
// 2. 发送端处理
printf("\n[Tx] Generating Transmission Signal...\n");
AppData tx_data = { .longitude = 120.013, .latitude = 30.4560, .depth = 50.0, .timestamp_us = 1234564578 };
int frame_bits[FRAME_LEN_BITS];
build_tx_frame(&tx_data, frame_bits);
int encoded_bits[TBCC_ENC_LEN];
tbcc_encode(frame_bits, encoded_bits);
int interleaved_bits[TBCC_ENC_LEN];
block_interleave(encoded_bits, interleaved_bits);
uint8_t packed_payload[32];
memset(packed_payload, 0, 32);
for(int i=0; i<TBCC_ENC_LEN; i++) {
if(interleaved_bits[i]) packed_payload[i/8] |= (1 << (7-(i%8)));
}
float *tx_signal = NULL;
size_t tx_len = 0;
mod_assemble_full_frame(packed_payload, bank, &mod_cfg, &tx_signal, &tx_len);
save_debug_data("data_tx_clean.txt", tx_signal, tx_len);
// ------------------------------------------------
// 3. 信道传输 (模拟多普勒 + 噪声)
// ------------------------------------------------
// === 设置模拟参数 ===
float sim_velocity = 1.0f; // 相对速度 15 m/s
float c = 1500.0f;
// 使用双向/回波模型公式,或者单纯为了加大难度测试算法
float alpha_true = (c + sim_velocity) / (c - sim_velocity);
printf("\n[Channel] Simulating Doppler (v=%.2f m/s, alpha=%.6f)...\n", sim_velocity, alpha_true);
// 计算接收长度 (物理压缩/拉伸)
size_t rx_len_raw = (size_t)floor(tx_len / alpha_true);
float *rx_signal_raw = (float*)malloc(rx_len_raw * sizeof(float));
// (A) 多普勒效应: 重采样 (Tx -> Rx)
// 注意:resample_linear 中 rate=alpha 表示 input 被抽取 (压缩)
resample_linear(tx_signal, tx_len, alpha_true, rx_signal_raw, rx_len_raw);
// (B) 加噪声
add_awgn(rx_signal_raw, rx_len_raw, 20.0f); // 稍微提高一点 SNR 方便调试多普勒
save_debug_data("data_rx_doppler_noisy.txt", rx_signal_raw, rx_len_raw);
// ------------------------------------------------
// 4. 接收端处理
// ------------------------------------------------
printf("\n[Rx] Starting Receiver Processing...\n");
// === (A) 多普勒估计与补偿 ===
printf(" > Performing Doppler Estimation & Compensation...\n");
DopplerResult dop_res = css_doppler_process(rx_signal_raw, rx_len_raw, &mod_cfg, bank);
if (dop_res.comp_signal == NULL) {
printf("[Error] Doppler compensation failed!\n");
return -1;
}
save_debug_data("data_rx_compensated.txt", dop_res.comp_signal, dop_res.comp_len);
// === (B) CSS 解调 (使用补偿后的信号) ===
float rx_soft_interleaved[TBCC_ENC_LEN];
// 注意:将补偿后的信号传入解调器
demod_process_full_frame(dop_res.comp_signal, dop_res.comp_len, &mod_cfg, bank, rx_soft_interleaved);
// === (C) 后续链路 (解交织 -> 译码) ===
float rx_soft_ordered[TBCC_ENC_LEN];
block_deinterleave_soft(rx_soft_interleaved, rx_soft_ordered);
int rx_decoded_bits[FRAME_LEN_BITS];
tbcc_decode(rx_soft_ordered, rx_decoded_bits);
// ------------------------------------------------
// 5. 结果分析
// ------------------------------------------------
printf("\n[Analysis] Performance Metrics:\n");
int error_count = 0;
for (int i = 0; i < FRAME_LEN_BITS; i++) {
if (frame_bits[i] != rx_decoded_bits[i]) error_count++;
}
printf(" > BER: %.4f%% (%d errors)\n", (float)error_count/FRAME_LEN_BITS*100.0f, error_count);
AppData rx_data;
if (parse_rx_frame(rx_decoded_bits, &rx_data)) {
printf("[Result] CRC PASS. Data Recovered.\n");
printf(" > Depth: %.1fm (Tx: %.1fm)\n", rx_data.depth, tx_data.depth);
} else {
printf("[Result] CRC FAILED.\n");
}
// 清理
free(tx_signal);
free(rx_signal_raw);
free(dop_res.comp_signal); // 记得释放补偿后的信号
mod_free_waveform_bank(bank, mod_cfg.num_subbands);
printf("\n=== Simulation Finished ===\n");
return 0;
}