Fix HST channel emulator for keeping coherent phase between frames

master
Xavier Arteaga 5 years ago committed by Xavier Arteaga
parent 88f56721ee
commit a44a61d781

@ -73,11 +73,12 @@ public:
void run(cf_t* in[SRSLTE_MAX_CHANNELS], cf_t* out[SRSLTE_MAX_CHANNELS], uint32_t len, const srslte_timestamp_t& t); void run(cf_t* in[SRSLTE_MAX_CHANNELS], cf_t* out[SRSLTE_MAX_CHANNELS], uint32_t len, const srslte_timestamp_t& t);
private: private:
float hst_init_phase = 0.0f;
srslte_channel_fading_t* fading[SRSLTE_MAX_CHANNELS] = {}; srslte_channel_fading_t* fading[SRSLTE_MAX_CHANNELS] = {};
srslte_channel_delay_t* delay[SRSLTE_MAX_CHANNELS] = {}; srslte_channel_delay_t* delay[SRSLTE_MAX_CHANNELS] = {};
srslte_channel_awgn_t* awgn = nullptr; srslte_channel_awgn_t* awgn = nullptr;
srslte_channel_hst_t* hst = nullptr; // HST has no buffers / no multiple instance is required srslte_channel_hst_t* hst = nullptr;
srslte_channel_rlf_t* rlf = nullptr; // RLF has no buffers / no multiple instance is required srslte_channel_rlf_t* rlf = nullptr;
cf_t* buffer_in = nullptr; cf_t* buffer_in = nullptr;
cf_t* buffer_out = nullptr; cf_t* buffer_out = nullptr;
log_filter* log_h = nullptr; log_filter* log_h = nullptr;

@ -136,6 +136,16 @@ channel::~channel()
} }
} }
extern "C" {
static inline cf_t local_cexpf(float phase)
{
cf_t ret;
__real__ ret = cosf(phase);
__imag__ ret = sinf(phase);
return ret;
}
}
void channel::set_logger(log_filter* _log_h) void channel::set_logger(log_filter* _log_h)
{ {
log_h = _log_h; log_h = _log_h;
@ -155,6 +165,11 @@ void channel::run(cf_t* in[SRSLTE_MAX_CHANNELS],
// Copy input buffer // Copy input buffer
memcpy(buffer_in, in[i], sizeof(cf_t) * len); memcpy(buffer_in, in[i], sizeof(cf_t) * len);
if (hst) {
srslte_channel_hst_execute(hst, buffer_in, buffer_out, len, &t);
srslte_vec_sc_prod_ccc(buffer_out, local_cexpf(hst_init_phase), buffer_in, len);
}
if (awgn) { if (awgn) {
srslte_channel_awgn_run_c(awgn, buffer_in, buffer_out, len); srslte_channel_awgn_run_c(awgn, buffer_in, buffer_out, len);
memcpy(buffer_in, buffer_out, sizeof(cf_t) * len); memcpy(buffer_in, buffer_out, sizeof(cf_t) * len);
@ -170,11 +185,6 @@ void channel::run(cf_t* in[SRSLTE_MAX_CHANNELS],
memcpy(buffer_in, buffer_out, sizeof(cf_t) * len); memcpy(buffer_in, buffer_out, sizeof(cf_t) * len);
} }
if (hst) {
srslte_channel_hst_execute(hst, buffer_in, buffer_out, len, &t);
memcpy(buffer_in, buffer_out, sizeof(cf_t) * len);
}
if (rlf) { if (rlf) {
srslte_channel_rlf_execute(rlf, buffer_in, buffer_out, len, &t); srslte_channel_rlf_execute(rlf, buffer_in, buffer_out, len, &t);
memcpy(buffer_in, buffer_out, sizeof(cf_t) * len); memcpy(buffer_in, buffer_out, sizeof(cf_t) * len);
@ -185,6 +195,21 @@ void channel::run(cf_t* in[SRSLTE_MAX_CHANNELS],
} }
} }
if (hst) {
// Increment phase to keep it coherent between frames
hst_init_phase += (2 * M_PI * len * hst->fs_hz / hst->srate_hz);
// Positive Remainder
while (hst_init_phase > 2 * M_PI) {
hst_init_phase -= 2 * M_PI;
}
// Negative Remainder
while (hst_init_phase < -2 * M_PI) {
hst_init_phase += 2 * M_PI;
}
}
if (log_h) { if (log_h) {
// Logging // Logging
std::stringstream str; std::stringstream str;

Loading…
Cancel
Save