mirror of https://github.com/PentHertz/srsLTE.git
Using short correlation for peak tracking
This commit is contained in:
parent
ecbd3dda2c
commit
5a032c4316
|
@ -48,7 +48,7 @@ float gain_offset = B210_DEFAULT_GAIN_CORREC;
|
|||
|
||||
cell_detect_cfg_t cell_detect_config = {
|
||||
100, // nof_frames_total
|
||||
3.0 // early-stops cell detection if mean PSR is above this value
|
||||
6.0 // early-stops cell detection if mean PSR is above this value
|
||||
};
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -149,16 +149,11 @@ int main(int argc, char **argv) {
|
|||
uint8_t bch_payload[BCH_PAYLOAD_LEN], bch_payload_unpacked[BCH_PAYLOAD_LEN];
|
||||
uint32_t sfn_offset;
|
||||
float rssi_utra=0,rssi=0, rsrp=0, rsrq=0, snr=0;
|
||||
cf_t *nullce[MAX_PORTS];
|
||||
uint32_t si_window_length;
|
||||
scheduling_info_t sinfo[MAX_SINFO];
|
||||
scheduling_info_t *sinfo_sib4 = NULL;
|
||||
uint32_t neighbour_cell_ids[MAX_NEIGHBOUR_CELLS];
|
||||
|
||||
|
||||
for (int i=0;i<MAX_PORTS;i++) {
|
||||
nullce[i] = NULL;
|
||||
}
|
||||
cf_t *ce[MAX_PORTS];
|
||||
|
||||
parse_args(&prog_args, argc, argv);
|
||||
|
||||
|
@ -174,6 +169,10 @@ int main(int argc, char **argv) {
|
|||
cuhd_set_rx_freq(uhd, (double) prog_args.uhd_freq);
|
||||
cuhd_rx_wait_lo_locked(uhd);
|
||||
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (detect_and_decode_cell(&cell_detect_config, uhd, prog_args.force_N_id_2, &cell)) {
|
||||
fprintf(stderr, "Cell not found\n");
|
||||
|
@ -215,12 +214,17 @@ int main(int argc, char **argv) {
|
|||
int sf_re = SF_LEN_RE(cell.nof_prb, cell.cp);
|
||||
|
||||
cf_t *sf_symbols = vec_malloc(sf_re * sizeof(cf_t));
|
||||
|
||||
for (int i=0;i<MAX_PORTS;i++) {
|
||||
ce[i] = vec_malloc(sizeof(cf_t) * sf_re);
|
||||
}
|
||||
|
||||
cuhd_start_rx_stream(uhd);
|
||||
|
||||
bool sib4_window_start = false;
|
||||
uint32_t sib4_window_cnt = 0;
|
||||
|
||||
|
||||
/* Main loop */
|
||||
while (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1) {
|
||||
|
||||
|
@ -307,9 +311,7 @@ int main(int argc, char **argv) {
|
|||
/* We are looking for SI Blocks, search only in appropiate places */
|
||||
if (sib4_window_start && !(ue_sync_get_sfidx(&ue_sync) == 5 && (sfn%2)==0))
|
||||
{
|
||||
/* printf("[%d/%d]: Trying SIB4 in SF: %d, SFN: %d\n", sib4_window_cnt, si_window_length,
|
||||
ue_sync_get_sfidx(&ue_sync), sfn);
|
||||
*/ n = ue_dl_decode_sib(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync),
|
||||
n = ue_dl_decode_sib(&ue_dl, sf_buffer, data, ue_sync_get_sfidx(&ue_sync),
|
||||
((int) ceilf((float)3*sib4_window_cnt/2))%4);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "Error decoding UE DL\n");fflush(stdout);
|
||||
|
@ -340,7 +342,7 @@ int main(int argc, char **argv) {
|
|||
/* Run FFT for all subframe data */
|
||||
lte_fft_run_sf(&fft, sf_buffer, sf_symbols);
|
||||
|
||||
chest_dl_estimate(&chest, sf_symbols, nullce, ue_sync_get_sfidx(&ue_sync));
|
||||
chest_dl_estimate(&chest, sf_symbols, ce, ue_sync_get_sfidx(&ue_sync));
|
||||
|
||||
rssi = VEC_CMA(vec_avg_power_cf(sf_buffer,SF_LEN(lte_symbol_sz(cell.nof_prb))),rssi,nframes);
|
||||
rssi_utra = VEC_CMA(chest_dl_get_rssi(&chest),rssi_utra,nframes);
|
||||
|
@ -357,7 +359,10 @@ int main(int argc, char **argv) {
|
|||
10*log10(rssi*1000)-gain_offset,
|
||||
10*log10(rssi_utra*1000)-gain_offset,
|
||||
10*log10(rsrp*1000)-gain_offset,
|
||||
10*log10(rsrq), 10*log10(snr));
|
||||
10*log10(rsrq), 10*log10(snr));
|
||||
if (verbose != VERBOSE_NONE) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
void init_plots();
|
||||
void do_plots(ue_dl_t *q, uint32_t sf_idx);
|
||||
void do_plots(ue_dl_t *q, uint32_t sf_idx, ue_sync_t *qs);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -175,12 +175,6 @@ int main(int argc, char **argv) {
|
|||
uint32_t sfn_offset;
|
||||
parse_args(&prog_args, argc, argv);
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
if (!prog_args.disable_plots) {
|
||||
init_plots();
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("Opening UHD device...\n");
|
||||
if (cuhd_open(prog_args.uhd_args, &uhd)) {
|
||||
fprintf(stderr, "Error opening uhd\n");
|
||||
|
@ -225,11 +219,19 @@ int main(int argc, char **argv) {
|
|||
// Register Ctrl+C handler
|
||||
signal(SIGINT, sig_int_handler);
|
||||
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
if (!prog_args.disable_plots) {
|
||||
init_plots();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
cuhd_start_rx_stream(uhd);
|
||||
|
||||
// Variables for measurements
|
||||
uint32_t nframes=0;
|
||||
float rsrp=0, rsrq=0, snr=0;
|
||||
float rsrp=1.0, rsrq=1.0, snr=1.0;
|
||||
|
||||
/* Main loop */
|
||||
while (!go_exit && (sf_cnt < prog_args.nof_subframes || prog_args.nof_subframes == -1)) {
|
||||
|
@ -276,6 +278,10 @@ int main(int argc, char **argv) {
|
|||
rsrp = VEC_CMA(chest_dl_get_rsrp(&ue_dl.chest),rsrp,nframes);
|
||||
snr = VEC_CMA(chest_dl_get_snr(&ue_dl.chest),snr,nframes);
|
||||
nframes++;
|
||||
|
||||
if (isnan(rsrq)) {
|
||||
rsrq = 0;
|
||||
}
|
||||
|
||||
// Plot and Printf
|
||||
if (ue_sync_get_sfidx(&ue_sync) == 0) {
|
||||
|
@ -298,7 +304,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
if (!prog_args.disable_plots && ue_sync_get_sfidx(&ue_sync) == 5) {
|
||||
do_plots(&ue_dl, 5);
|
||||
do_plots(&ue_dl, 5, &ue_sync);
|
||||
}
|
||||
#endif
|
||||
} else if (ret == 0) {
|
||||
|
@ -332,12 +338,13 @@ int main(int argc, char **argv) {
|
|||
|
||||
|
||||
#include "liblte/graphics/plot.h"
|
||||
plot_real_t poutfft;
|
||||
plot_real_t poutfft, p_sync;
|
||||
plot_real_t pce;
|
||||
plot_scatter_t pscatrecv, pscatequal, pscatequal_pdcch;
|
||||
plot_scatter_t pscatequal, pscatequal_pdcch;
|
||||
|
||||
float tmp_plot[SLOT_LEN_RE(MAX_PRB, CPNORM)];
|
||||
float tmp_plot2[SLOT_LEN_RE(MAX_PRB, CPNORM)];
|
||||
float tmp_plot3[SLOT_LEN_RE(MAX_PRB, CPNORM)];
|
||||
|
||||
void init_plots() {
|
||||
plot_init();
|
||||
|
@ -351,10 +358,9 @@ void init_plots() {
|
|||
plot_real_setLabels(&pce, "Index", "dB");
|
||||
plot_real_setYAxisScale(&pce, -60, 0);
|
||||
|
||||
plot_scatter_init(&pscatrecv);
|
||||
plot_scatter_setTitle(&pscatrecv, "Received Symbols");
|
||||
plot_scatter_setXAxisScale(&pscatrecv, -4, 4);
|
||||
plot_scatter_setYAxisScale(&pscatrecv, -4, 4);
|
||||
plot_real_init(&p_sync);
|
||||
plot_real_setTitle(&p_sync, "PSS Cross-Corr abs value");
|
||||
plot_real_setYAxisScale(&p_sync, 0, 1);
|
||||
|
||||
plot_scatter_init(&pscatequal);
|
||||
plot_scatter_setTitle(&pscatequal, "PDSCH - Equalized Symbols");
|
||||
|
@ -368,7 +374,7 @@ void init_plots() {
|
|||
|
||||
}
|
||||
|
||||
void do_plots(ue_dl_t *q, uint32_t sf_idx) {
|
||||
void do_plots(ue_dl_t *q, uint32_t sf_idx, ue_sync_t *qs) {
|
||||
int i;
|
||||
uint32_t nof_re = SLOT_LEN_RE(q->cell.nof_prb, q->cell.cp);
|
||||
uint32_t nof_symbols = q->harq_process[0].prb_alloc.re_sf[sf_idx];
|
||||
|
@ -386,7 +392,10 @@ void do_plots(ue_dl_t *q, uint32_t sf_idx) {
|
|||
}
|
||||
plot_real_setNewData(&poutfft, tmp_plot, nof_re);
|
||||
plot_real_setNewData(&pce, tmp_plot2, REFSIGNAL_NUM_SF(q->cell.nof_prb,0));
|
||||
plot_scatter_setNewData(&pscatrecv, q->pdsch.pdsch_symbols[0], nof_symbols);
|
||||
int max = vec_max_fi(qs->strack.pss.conv_output_avg, qs->strack.pss.frame_size+qs->strack.pss.fft_size-1);
|
||||
vec_sc_prod_fff(qs->strack.pss.conv_output_avg, 1/qs->strack.pss.conv_output_avg[max], tmp_plot2, qs->strack.pss.frame_size+qs->strack.pss.fft_size-1);
|
||||
plot_real_setNewData(&p_sync, tmp_plot2, qs->strack.pss.frame_size);
|
||||
|
||||
plot_scatter_setNewData(&pscatequal, q->pdsch.pdsch_d, nof_symbols);
|
||||
plot_scatter_setNewData(&pscatequal_pdcch, q->pdcch.pdcch_d, 36*q->pdcch.nof_cce);
|
||||
}
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
typedef _Complex float cf_t; /* this is only a shortcut */
|
||||
|
||||
#define CONVOLUTION_FFT
|
||||
#define DEFAULT_CORRELATION_TH 10000
|
||||
#define DEFAULT_NOSYNC_TIMEOUT 5
|
||||
|
||||
#define PSS_LEN 62
|
||||
#define PSS_RE 6*12
|
||||
|
|
|
@ -37,6 +37,7 @@ typedef _Complex float cf_t;
|
|||
|
||||
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
// Cumulative moving average
|
||||
#define VEC_CMA(data, average, n) ((average) + ((data) - (average)) / ((n)+1))
|
||||
|
|
|
@ -373,6 +373,7 @@ float chest_dl_get_rssi(chest_dl_t *q) {
|
|||
*/
|
||||
float chest_dl_get_rsrq(chest_dl_t *q) {
|
||||
return q->cell.nof_prb*q->rsrp[0] / q->rssi[0];
|
||||
|
||||
}
|
||||
|
||||
float chest_dl_get_rsrp(chest_dl_t *q) {
|
||||
|
|
|
@ -290,20 +290,27 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value)
|
|||
memcpy(q->tmp_input, input, q->frame_size * sizeof(cf_t));
|
||||
|
||||
/* Correlate input with PSS sequence */
|
||||
#ifdef CONVOLUTION_FFT
|
||||
conv_output_len = conv_fft_cc_run(&q->conv_fft, q->tmp_input,
|
||||
q->pss_signal_freq[q->N_id_2], q->conv_output);
|
||||
#else
|
||||
conv_output_len = conv_cc(input, q->pss_signal_freq[q->N_id_2], q->conv_output, q->frame_size, q->fft_size);
|
||||
#endif
|
||||
if (q->frame_size >= q->fft_size) {
|
||||
#ifdef CONVOLUTION_FFT
|
||||
conv_output_len = conv_fft_cc_run(&q->conv_fft, q->tmp_input,
|
||||
q->pss_signal_freq[q->N_id_2], q->conv_output);
|
||||
#else
|
||||
conv_output_len = conv_cc(input, q->pss_signal_freq[q->N_id_2], q->conv_output, q->frame_size, q->fft_size);
|
||||
#endif
|
||||
} else {
|
||||
for (int i=0;i<q->frame_size;i++) {
|
||||
q->conv_output[i] = vec_dot_prod_ccc(q->pss_signal_freq[q->N_id_2], &input[i], q->fft_size);
|
||||
}
|
||||
conv_output_len = q->frame_size;
|
||||
}
|
||||
|
||||
|
||||
#ifdef PSS_ABS_SQUARE
|
||||
vec_abs_square_cf(q->conv_output, q->conv_output_abs, conv_output_len-1);
|
||||
#else
|
||||
vec_abs_cf(q->conv_output, q->conv_output_abs, conv_output_len-1);
|
||||
#endif
|
||||
|
||||
#ifdef PSS_ABS_SQUARE
|
||||
vec_abs_square_cf(q->conv_output, q->conv_output_abs, conv_output_len-1);
|
||||
#else
|
||||
vec_abs_cf(q->conv_output, q->conv_output_abs, conv_output_len-1);
|
||||
#endif
|
||||
|
||||
vec_sc_prod_fff(q->conv_output_abs, q->ema_alpha, q->conv_output_abs, conv_output_len-1);
|
||||
vec_sc_prod_fff(q->conv_output_avg, 1-q->ema_alpha, q->conv_output_avg, conv_output_len-1);
|
||||
|
||||
|
@ -321,16 +328,35 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value)
|
|||
pl_ub ++;
|
||||
}
|
||||
// Find end of peak lobe to the left
|
||||
int pl_lb = corr_peak_pos-1;
|
||||
while(q->conv_output_avg[pl_lb-1] <= q->conv_output_avg[pl_lb] && pl_lb > 1) {
|
||||
pl_lb --;
|
||||
int pl_lb;
|
||||
if (corr_peak_pos > 0) {
|
||||
pl_lb = corr_peak_pos-1;
|
||||
while(q->conv_output_avg[pl_lb-1] <= q->conv_output_avg[pl_lb] && pl_lb > 1) {
|
||||
pl_lb --;
|
||||
}
|
||||
} else {
|
||||
pl_lb = 0;
|
||||
}
|
||||
|
||||
int sl_distance_right = conv_output_len-1-pl_ub;
|
||||
if (sl_distance_right < 0) {
|
||||
sl_distance_right = 0;
|
||||
}
|
||||
int sl_distance_left = pl_lb;
|
||||
|
||||
int sl_right = pl_ub+vec_max_fi(&q->conv_output_avg[pl_ub], conv_output_len-1 - pl_ub);
|
||||
int sl_left = vec_max_fi(q->conv_output_avg, pl_lb);
|
||||
int sl_right = pl_ub+vec_max_fi(&q->conv_output_avg[pl_ub], sl_distance_right);
|
||||
int sl_left = vec_max_fi(q->conv_output_avg, sl_distance_left);
|
||||
float side_lobe_value = MAX(q->conv_output_avg[sl_right], q->conv_output_avg[sl_left]);
|
||||
if (corr_peak_value) {
|
||||
*corr_peak_value = q->conv_output_avg[corr_peak_pos]/side_lobe_value;
|
||||
|
||||
if (*corr_peak_value < 2.0) {
|
||||
INFO("pl_ub=%d, pl_lb=%d, sl_right: %d (%.2f), sl_left: %d (%.2f), PSR: %.2f/%.2f=%.2f\n", pl_ub, pl_lb,
|
||||
sl_right, 1000000*q->conv_output_avg[sl_right],
|
||||
sl_left, 1000000*q->conv_output_avg[sl_left],
|
||||
1000000*q->conv_output_avg[corr_peak_pos], 1000000*side_lobe_value,*corr_peak_value
|
||||
);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (corr_peak_value) {
|
||||
|
|
|
@ -52,7 +52,6 @@ int sync_init(sync_t *q, uint32_t frame_size, uint32_t fft_size) {
|
|||
int ret = LIBLTE_ERROR_INVALID_INPUTS;
|
||||
|
||||
if (q != NULL &&
|
||||
frame_size >= fft_size &&
|
||||
frame_size <= 307200 &&
|
||||
fft_size_isvalid(fft_size))
|
||||
{
|
||||
|
|
|
@ -53,14 +53,16 @@ float uhd_gain=40.0, uhd_freq=-1.0;
|
|||
int nof_frames = -1;
|
||||
uint32_t fft_size=64;
|
||||
float threshold = 0.4;
|
||||
int N_id_2_sync = -1;
|
||||
int N_id_2_sync = -1;
|
||||
lte_cp_t cp=CPNORM;
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [adgtvnp] -f rx_frequency_hz -i cell_id\n", prog);
|
||||
printf("Usage: %s [aedgtvnp] -f rx_frequency_hz -i cell_id\n", prog);
|
||||
printf("\t-a UHD args [Default %s]\n", uhd_args);
|
||||
printf("\t-g UHD Gain [Default %.2f dB]\n", uhd_gain);
|
||||
printf("\t-n nof_frames [Default %d]\n", nof_frames);
|
||||
printf("\t-l N_id_2 to sync [Default use cell_id]\n");
|
||||
printf("\t-e Extended CP [Default Normal]\n", fft_size);
|
||||
printf("\t-s symbol_sz [Default %d]\n", fft_size);
|
||||
printf("\t-t threshold [Default %.2f]\n", threshold);
|
||||
#ifndef DISABLE_GRAPHICS
|
||||
|
@ -73,7 +75,7 @@ void usage(char *prog) {
|
|||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "adgtvsfil")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "adgetvsfil")) != -1) {
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
uhd_args = argv[optind];
|
||||
|
@ -87,6 +89,9 @@ void parse_args(int argc, char **argv) {
|
|||
case 't':
|
||||
threshold = atof(argv[optind]);
|
||||
break;
|
||||
case 'e':
|
||||
cp = CPEXT;
|
||||
break;
|
||||
case 'i':
|
||||
cell_id = atoi(argv[optind]);
|
||||
break;
|
||||
|
@ -154,6 +159,7 @@ int main(int argc, char **argv) {
|
|||
fprintf(stderr, "Error initiating PSS\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (pss_synch_set_N_id_2(&pss, N_id_2_sync)) {
|
||||
fprintf(stderr, "Error setting N_id_2=%d\n",N_id_2_sync);
|
||||
exit(-1);
|
||||
|
@ -233,7 +239,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// Find SSS
|
||||
int sss_idx = peak_idx-2*fft_size-CP(fft_size, CPNORM_LEN);
|
||||
int sss_idx = peak_idx-2*fft_size-(CP_ISNORM(cp)?CP(fft_size, CPNORM_LEN):CP(fft_size, CPEXT_LEN));
|
||||
if (sss_idx >= 0 && sss_idx < flen-fft_size) {
|
||||
sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value);
|
||||
if (sss_synch_N_id_1(&sss, m0, m1) != N_id_1) {
|
||||
|
|
|
@ -75,6 +75,7 @@ int ue_celldetect_init_max(ue_celldetect_t * q, uint32_t max_frames_total) {
|
|||
sync_set_threshold(&q->sfind, 1.0);
|
||||
sync_sss_en(&q->sfind, true);
|
||||
sync_set_sss_algorithm(&q->sfind, SSS_PARTIAL_3);
|
||||
sync_set_em_alpha(&q->sfind, 0.01);
|
||||
|
||||
q->max_frames_total = max_frames_total;
|
||||
q->nof_frames_total = CS_DEFAULT_NOFFRAMES_TOTAL;
|
||||
|
|
|
@ -49,6 +49,7 @@ cf_t dummy[MAX_TIME_OFFSET];
|
|||
#define FIND_THRESHOLD 4.0
|
||||
#define TRACK_THRESHOLD 2.0
|
||||
#define TRACK_MAX_LOST 10
|
||||
#define TRACK_FRAME_SIZE 32
|
||||
|
||||
|
||||
int ue_sync_init(ue_sync_t *q,
|
||||
|
@ -76,7 +77,7 @@ int ue_sync_init(ue_sync_t *q,
|
|||
fprintf(stderr, "Error initiating sync find\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
if(sync_init(&q->strack, CURRENT_FFTSIZE, CURRENT_FFTSIZE)) {
|
||||
if(sync_init(&q->strack, TRACK_FRAME_SIZE, CURRENT_FFTSIZE)) {
|
||||
fprintf(stderr, "Error initiating sync track\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
@ -190,7 +191,7 @@ int track_peak_ok(ue_sync_t *q, uint32_t track_idx) {
|
|||
q->sf_idx = sync_get_sf_idx(&q->strack);
|
||||
}
|
||||
} else {
|
||||
q->time_offset = ((int) track_idx - (int) CURRENT_FFTSIZE);
|
||||
q->time_offset = ((int) track_idx - (int) q->strack.frame_size/2);
|
||||
|
||||
/* If the PSS peak is beyond the frame (we sample too slowly),
|
||||
discard the offseted samples to align next frame */
|
||||
|
@ -305,7 +306,7 @@ int ue_sync_get_buffer(ue_sync_t *q, cf_t **sf_symbols) {
|
|||
track_idx = 0;
|
||||
|
||||
/* track pss around the middle of the subframe, where the PSS is */
|
||||
ret = sync_find(&q->strack, q->input_buffer, CURRENT_SFLEN/2-CURRENT_FFTSIZE, &track_idx);
|
||||
ret = sync_find(&q->strack, q->input_buffer, CURRENT_SFLEN/2-CURRENT_FFTSIZE-q->strack.frame_size/2, &track_idx);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error tracking correlation peak\n");
|
||||
return LIBLTE_ERROR;
|
||||
|
|
|
@ -91,15 +91,17 @@ uint32_t conv_fft_cc_run(conv_fft_cc_t *q, cf_t *input, cf_t *filter, cf_t *outp
|
|||
}
|
||||
|
||||
uint32_t conv_cc(cf_t *input, cf_t *filter, cf_t *output, uint32_t input_len, uint32_t filter_len) {
|
||||
uint32_t i,j;
|
||||
uint32_t output_len;
|
||||
output_len=input_len+filter_len-1;
|
||||
for (i=0;i<input_len;i++) {
|
||||
for (j=0;j<filter_len;j++) {
|
||||
output[i+j]+=input[i]*filter[j];
|
||||
}
|
||||
uint32_t i;
|
||||
uint32_t M = filter_len;
|
||||
uint32_t N = input_len;
|
||||
|
||||
for (i=0;i<M;i++) {
|
||||
output[i]=vec_dot_prod_ccc(&input[i],&filter[i],i);
|
||||
}
|
||||
return output_len;
|
||||
for (;i<M+N-1;i++) {
|
||||
output[i] = vec_dot_prod_ccc(&input[i-M], filter, M);
|
||||
}
|
||||
return M+N-1;
|
||||
}
|
||||
|
||||
/* Centered convolution. Returns the same number of input elements. Equivalent to conv(x,h,'same') in matlab.
|
||||
|
|
Loading…
Reference in New Issue