Normalized PSS correlation result. Use real part only. Extended sync_test to more bandwidth

This commit is contained in:
ismagom 2014-07-30 12:05:17 +02:00
parent 3dfb1824b4
commit 7658ced99d
19 changed files with 119 additions and 126 deletions

View File

@ -42,14 +42,18 @@ CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_dot_prod_32f HAVE_VOLK_DOTPROD_F_FUNCTION
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_s32f_atan2_32f HAVE_VOLK_ATAN_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_s32f_convert_16i HAVE_VOLK_CONVERT_FI_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_32f_x2 HAVE_VOLK_DEINTERLEAVE_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32f_x2_subtract_32f HAVE_VOLK_SUB_FLOAT_FUNCTION)
CHECK_FUNCTION_EXISTS_MATH(volk_32fc_deinterleave_real_32f HAVE_VOLK_DEINTERLEAVE_FUNCTION)
SET(VOLK_DEFINITIONS "HAVE_VOLK")
IF(${HAVE_VOLK_DOTPROD_CONJ_FC_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DOTPROD_CONJ_FC_FUNCTION")
ENDIF()
IF(${HAVE_VOLK_DEINTERLEAVE_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_DEINTERLEAVE_FUNCTION")
ENDIF()
IF(${HAVE_VOLK_SUB_FLOAT_FUNCTION})
SET(VOLK_DEFINITIONS "${VOLK_DEFINITIONS}; HAVE_VOLK_SUB_FLOAT_FUNCTION")
ENDIF()

View File

@ -81,8 +81,8 @@ ENDIF(${GRAPHICS_FIND} EQUAL -1)
IF(${CUHD_FIND} GREATER -1)
add_executable(scan_mib scan_mib.c)
target_link_libraries(scan_mib lte_phy cuhd )
add_executable(cell_search cell_search.c)
target_link_libraries(cell_search lte_phy cuhd )
MESSAGE(STATUS " UHD examples will be installed.")

View File

@ -109,7 +109,6 @@ int main(int argc, char **argv) {
int peak_pos[3];
float *cfo;
float peak_value[3];
float mean_value[3];
int frame_cnt;
cf_t *input;
uint32_t m0, m1;
@ -201,10 +200,10 @@ int main(int argc, char **argv) {
if (force_N_id_2 != -1) {
N_id_2 = force_N_id_2;
peak_pos[N_id_2] = pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2], &mean_value[N_id_2]);
peak_pos[N_id_2] = pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]);
} else {
for (N_id_2=0;N_id_2<3;N_id_2++) {
peak_pos[N_id_2] = pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2], &mean_value[N_id_2]);
peak_pos[N_id_2] = pss_synch_find_pss(&pss[N_id_2], input, &peak_value[N_id_2]);
}
float max_value=-99999;
N_id_2=-1;
@ -218,7 +217,7 @@ int main(int argc, char **argv) {
}
/* If peak detected */
if (peak_value[N_id_2]/mean_value[N_id_2] > corr_peak_threshold) {
if (peak_value[N_id_2] > corr_peak_threshold) {
sss_idx = peak_pos[N_id_2]-2*(symbol_sz+CP(symbol_sz,CPNORM_LEN));
if (sss_idx >= 0) {
@ -228,7 +227,7 @@ int main(int argc, char **argv) {
cfo[frame_cnt] = pss_synch_cfo_compute(&pss[N_id_2], &input[peak_pos[N_id_2]-128]);
printf("\t%d\t%d\t%d\t%d\t%.3f\t\t%3d\t%d\t%d\t%.3f\n",
frame_cnt,N_id_2, sss_synch_N_id_1(&sss[N_id_2], m0, m1),
sss_synch_subframe(m0, m1), peak_value[N_id_2]/mean_value[N_id_2],
sss_synch_subframe(m0, m1), peak_value[N_id_2],
peak_pos[N_id_2], m0, m1,
cfo[frame_cnt]);
}

View File

@ -72,7 +72,7 @@ typedef struct LIBLTE_API {
cf_t *pss_signal_freq[3]; // One sequence for each N_id_2
cf_t *tmp_input;
float *conv_abs;
float *conv_real;
cf_t *conv_output;
}pss_synch_t;
@ -102,8 +102,7 @@ LIBLTE_API int pss_synch_set_N_id_2(pss_synch_t *q,
LIBLTE_API int pss_synch_find_pss(pss_synch_t *q,
cf_t *input,
float *corr_peak_value,
float *corr_mean_value);
float *corr_peak_value);
LIBLTE_API float pss_synch_cfo_compute(pss_synch_t* q,
cf_t *pss_recv);

View File

@ -51,13 +51,10 @@
* functions sync_pss_det_absolute() and sync_pss_det_peakmean().
*/
enum sync_pss_det { ABSOLUTE, PEAK_MEAN};
typedef struct LIBLTE_API {
pss_synch_t pss_find;
pss_synch_t pss_track;
sss_synch_t sss;
enum sync_pss_det pss_mode;
float find_threshold;
float track_threshold;
float peak_value;
@ -103,12 +100,6 @@ LIBLTE_API void sync_set_threshold(sync_t *q,
float find_threshold,
float track_threshold);
/* Set peak comparison to absolute value */
LIBLTE_API void sync_pss_det_absolute(sync_t *q);
/* Set peak comparison to relative to the mean */
LIBLTE_API void sync_pss_det_peak_to_avg(sync_t *q);
/* Gets the slot id (0 or 10) */
LIBLTE_API uint32_t sync_get_slot_id(sync_t *q);

View File

@ -72,6 +72,7 @@ LIBLTE_API void vec_sc_prod_fff(float *x, float h, float *z, uint32_t len);
LIBLTE_API void vec_convert_fi(float *x, int16_t *z, float scale, uint32_t len);
LIBLTE_API void vec_deinterleave_cf(cf_t *x, float *real, float *imag, uint32_t len);
LIBLTE_API void vec_deinterleave_real_cf(cf_t *x, float *real, uint32_t len);
/* vector product (element-wise) */
LIBLTE_API void vec_prod_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len);

View File

@ -120,8 +120,6 @@ int ue_sync_init(ue_sync_t *q,
goto clean_exit;
}
sync_pss_det_absolute(&q->s);
if (cfo_init(&q->cfocorr, MAXIMUM_SFLEN)) {
fprintf(stderr, "Error initiating CFO\n");
goto clean_exit;

View File

@ -227,7 +227,7 @@ int main(int argc, char **argv) {
}
#endif
pos = pss_synch_find_pss(&pss, input_buffer, &peak, NULL);
pos = pss_synch_find_pss(&pss, input_buffer, &peak);
/*if (pos > 962 || pos < 958) {
unaligned++;
}

View File

@ -36,6 +36,7 @@
#include "liblte/phy/utils/dft.h"
#include "liblte/phy/utils/vector.h"
#include "liblte/phy/utils/convolution.h"
#include "liblte/phy/utils/debug.h"
int pss_synch_init_N_id_2(cf_t *pss_signal_freq, uint32_t N_id_2, uint32_t fft_size) {
@ -45,7 +46,7 @@ int pss_synch_init_N_id_2(cf_t *pss_signal_freq, uint32_t N_id_2, uint32_t fft_s
int ret = LIBLTE_ERROR_INVALID_INPUTS;
if (lte_N_id_2_isvalid(N_id_2) &&
fft_size < 2048)
fft_size <= 2048)
{
pss_generate(pss_signal_time, N_id_2);
@ -60,10 +61,10 @@ int pss_synch_init_N_id_2(cf_t *pss_signal_freq, uint32_t N_id_2, uint32_t fft_s
dft_plan_set_mirror(&plan, true);
dft_plan_set_dc(&plan, true);
dft_plan_set_norm(&plan, true);
dft_run_c(&plan, pss_signal_pad, pss_signal_freq);
vec_sc_prod_cfc(pss_signal_freq, (float) 1 / (fft_size), pss_signal_pad, fft_size);
vec_conj_cc(pss_signal_pad, pss_signal_freq, fft_size);
vec_conj_cc(pss_signal_freq, pss_signal_freq, fft_size);
dft_plan_free(&plan);
@ -97,8 +98,8 @@ int pss_synch_init_fft(pss_synch_t *q, uint32_t frame_size, uint32_t fft_size) {
buffer_size = fft_size + frame_size + 1;
q->conv_abs = vec_malloc(buffer_size * sizeof(float));
if (!q->conv_abs) {
q->conv_real = vec_malloc(buffer_size * sizeof(float));
if (!q->conv_real) {
fprintf(stderr, "Error allocating memory\n");
goto clean_and_exit;
}
@ -160,8 +161,8 @@ void pss_synch_free(pss_synch_t *q) {
if (q->conv_output) {
free(q->conv_output);
}
if (q->conv_abs) {
free(q->conv_abs);
if (q->conv_real) {
free(q->conv_real);
}
bzero(q, sizeof(pss_synch_t));
@ -231,8 +232,7 @@ int pss_synch_set_N_id_2(pss_synch_t *q, uint32_t N_id_2) {
*
* Input buffer must be subframe_size long.
*/
int pss_synch_find_pss(pss_synch_t *q, cf_t *input,
float *corr_peak_value, float *corr_mean_value)
int pss_synch_find_pss(pss_synch_t *q, cf_t *input, float *corr_peak_value)
{
int ret = LIBLTE_ERROR_INVALID_INPUTS;
@ -252,6 +252,7 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input,
memcpy(q->tmp_input, input, q->frame_size * sizeof(cf_t));
bzero(&q->tmp_input[q->frame_size], q->fft_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);
@ -259,16 +260,16 @@ int pss_synch_find_pss(pss_synch_t *q, cf_t *input,
conv_output_len = conv_cc(input, q->pss_signal_freq[q->N_id_2], q->conv_output, q->frame_size, q->fft_size);
#endif
vec_abs_cf(q->conv_output, q->conv_abs, conv_output_len);
corr_peak_pos = vec_max_fi(q->conv_abs, conv_output_len);
if (corr_peak_value) {
*corr_peak_value = q->conv_abs[corr_peak_pos];
}
if (corr_mean_value) {
*corr_mean_value = vec_acc_ff(q->conv_abs, conv_output_len)
/ conv_output_len;
}
/* Take the real part of the convolution result and normalize */
vec_deinterleave_real_cf(q->conv_output, q->conv_real, conv_output_len);
vec_sc_prod_fff(q->conv_real, 1.0/62.0, q->conv_real, conv_output_len);
/* Find maximum */
corr_peak_pos = vec_max_fi(q->conv_real, conv_output_len);
if (corr_peak_value) {
*corr_peak_value = q->conv_real[corr_peak_pos];
}
DEBUG("PSS correlation peak %.3f position %5d\n", q->conv_real[corr_peak_pos], corr_peak_pos);
ret = (int) corr_peak_pos;
}
return ret;

View File

@ -44,7 +44,7 @@ void generate_N_id_1_table(uint32_t table[30][30]);
int sss_synch_init(sss_synch_t *q, uint32_t fft_size) {
if (q != NULL &&
fft_size < 2048)
fft_size <= 2048)
{
uint32_t N_id_2;
struct sss_tables sss_tables;
@ -73,7 +73,7 @@ int sss_synch_init(sss_synch_t *q, uint32_t fft_size) {
int sss_synch_realloc(sss_synch_t *q, uint32_t fft_size) {
if (q != NULL &&
fft_size < 2048)
fft_size <= 2048)
{
dft_plan_free(&q->dftp_input);
if (dft_plan(&q->dftp_input, fft_size, FORWARD, COMPLEX)) {

View File

@ -51,7 +51,6 @@ int sync_init(sync_t *q, uint32_t find_frame_size, uint32_t track_frame_size, ui
fft_size_isvalid(fft_size))
{
bzero(q, sizeof(sync_t));
q->pss_mode = PEAK_MEAN;
q->detect_cp = true;
q->sss_en = true;
q->N_id_2 = 1000;
@ -126,13 +125,6 @@ void sync_free(sync_t *q) {
}
}
void sync_pss_det_absolute(sync_t *q) {
q->pss_mode = ABSOLUTE;
}
void sync_pss_det_peak_to_avg(sync_t *q) {
q->pss_mode = PEAK_MEAN;
}
void sync_set_threshold(sync_t *q, float find_threshold, float track_threshold) {
q->find_threshold = find_threshold;
q->track_threshold = track_threshold;
@ -277,27 +269,14 @@ int sync_track(sync_t *q, cf_t *input, uint32_t offset, uint32_t *peak_position)
input != NULL &&
fft_size_isvalid(q->fft_size))
{
float peak_value, mean_value, *mean_ptr;
uint32_t peak_pos;
pss_synch_set_N_id_2(&q->pss_track, q->N_id_2);
if (q->pss_mode == ABSOLUTE) {
mean_ptr = NULL;
} else {
mean_ptr = &mean_value;
}
peak_pos = pss_synch_find_pss(&q->pss_track, &input[offset], &peak_value, mean_ptr);
if (q->pss_mode == ABSOLUTE) {
q->peak_value = peak_value;
} else {
q->peak_value = peak_value / mean_value;
}
peak_pos = pss_synch_find_pss(&q->pss_track, &input[offset], &q->peak_value);
DEBUG("PSS possible tracking peak pos=%d peak=%.2f threshold=%.2f\n",
peak_pos, peak_value, q->track_threshold);
peak_pos, q->peak_value, q->track_threshold);
if (q->peak_value > q->track_threshold) {
if (offset + peak_pos > q->fft_size) {
@ -326,20 +305,13 @@ int sync_track(sync_t *q, cf_t *input, uint32_t offset, uint32_t *peak_position)
int sync_find(sync_t *q, cf_t *input, uint32_t *peak_position) {
uint32_t N_id_2, peak_pos[3];
float peak_value[3];
float mean_value[3];
float max=-999;
uint32_t i;
int ret;
float *mean_ptr;
for (N_id_2=0;N_id_2<3;N_id_2++) {
if (q->pss_mode == ABSOLUTE) {
mean_ptr = NULL;
} else {
mean_ptr = &mean_value[N_id_2];
}
pss_synch_set_N_id_2(&q->pss_find, N_id_2);
ret = pss_synch_find_pss(&q->pss_find, input, &peak_value[N_id_2], mean_ptr);
ret = pss_synch_find_pss(&q->pss_find, input, &peak_value[N_id_2]);
if (ret < 0) {
fprintf(stderr, "Error finding PSS for N_id_2=%d\n", N_id_2);
return LIBLTE_ERROR;
@ -354,19 +326,12 @@ int sync_find(sync_t *q, cf_t *input, uint32_t *peak_position) {
}
}
if (q->pss_mode == ABSOLUTE) {
q->peak_value = peak_value[N_id_2];
} else {
q->peak_value = peak_value[N_id_2] / mean_value[N_id_2];
}
if (peak_position) {
*peak_position = 0;
}
DEBUG("PSS possible peak N_id_2=%d, pos=%d peak=%.2f threshold=%.2f\n",
N_id_2, peak_pos[N_id_2], peak_value[N_id_2], q->find_threshold);
/* If peak detected */
if (q->peak_value > q->find_threshold) {
if (peak_pos[N_id_2] > q->fft_size &&
@ -376,8 +341,8 @@ int sync_find(sync_t *q, cf_t *input, uint32_t *peak_position) {
pss_synch_set_N_id_2(&q->pss_find, q->N_id_2);
q->cfo = pss_synch_cfo_compute(&q->pss_find, &input[peak_pos[N_id_2]-q->fft_size]);
DEBUG("PSS peak detected N_id_2=%d, pos=%d peak=%.2f par=%.2f th=%.2f cfo=%.4f\n", N_id_2,
peak_pos[N_id_2], peak_value[N_id_2], q->peak_value, q->find_threshold, q->cfo);
DEBUG("PSS peak detected N_id_2=%d, pos=%d peak=%.2f th=%.2f cfo=%.4f\n", N_id_2,
peak_pos[N_id_2], q->peak_value, q->find_threshold, q->cfo);
if (q->sss_en) {
if (sync_sss(q, input, peak_pos[q->N_id_2], q->detect_cp) < 0) {

View File

@ -32,6 +32,11 @@ ADD_TEST(sync_test_400 sync_test -o 400)
ADD_TEST(sync_test_100_e sync_test -o 100 -e)
ADD_TEST(sync_test_400_e sync_test -o 400 -e)
ADD_TEST(sync_test_100 sync_test -o 100 -p 50)
ADD_TEST(sync_test_400 sync_test -o 400 -p 50)
ADD_TEST(sync_test_100_e sync_test -o 100 -e -p 50)
ADD_TEST(sync_test_400_e sync_test -o 400 -e -p 50)
########################################################################
# CFO TEST
########################################################################

View File

@ -32,18 +32,21 @@
#include <unistd.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#include "liblte/phy/phy.h"
int cell_id = -1, offset = 0;
lte_cp_t cp = CPNORM;
uint32_t nof_prb=6;
#define FLEN 9600
#define FLEN SF_LEN(fft_size, cp)
void usage(char *prog) {
printf("Usage: %s [coev]\n", prog);
printf("Usage: %s [cpoev]\n", prog);
printf("\t-c cell_id [Default check for all]\n");
printf("\t-p nof_prb [Default %d]\n", nof_prb);
printf("\t-o offset [Default %d]\n", offset);
printf("\t-e extended CP [Default normal]\n");
printf("\t-v verbose\n");
@ -51,11 +54,14 @@ void usage(char *prog) {
void parse_args(int argc, char **argv) {
int opt;
while ((opt = getopt(argc, argv, "coev")) != -1) {
while ((opt = getopt(argc, argv, "cpoev")) != -1) {
switch (opt) {
case 'c':
cell_id = atoi(argv[optind]);
break;
case 'p':
nof_prb = atoi(argv[optind]);
break;
case 'o':
offset = atoi(argv[optind]);
break;
@ -82,32 +88,40 @@ int main(int argc, char **argv) {
uint32_t find_idx;
sync_t sync;
lte_fft_t ifft;
int fft_size;
parse_args(argc, argv);
fft_size = lte_symbol_sz(nof_prb);
if (fft_size < 0) {
fprintf(stderr, "Invalid nof_prb=%d\n", nof_prb);
exit(-1);
}
buffer = malloc(sizeof(cf_t) * FLEN);
if (!buffer) {
perror("malloc");
exit(-1);
}
fft_buffer = malloc(sizeof(cf_t) * 2 * FLEN);
fft_buffer = malloc(sizeof(cf_t) * FLEN);
if (!fft_buffer) {
perror("malloc");
exit(-1);
}
if (lte_ifft_init(&ifft, cp, 6)) {
if (lte_ifft_init(&ifft, cp, nof_prb)) {
fprintf(stderr, "Error creating iFFT object\n");
exit(-1);
}
if (sync_init(&sync, FLEN, 128, 128)) {
if (sync_init(&sync, FLEN, fft_size, fft_size)) {
fprintf(stderr, "Error initiating PSS/SSS\n");
return -1;
}
sync_set_threshold(&sync, 1, 1);
/* Set a very high threshold to make sure the correlation is ok */
sync_set_threshold(&sync, 0.99, 0.99);
if (cell_id == -1) {
cid = 0;
@ -125,19 +139,21 @@ int main(int argc, char **argv) {
for (ns=0;ns<2;ns++) {
memset(buffer, 0, sizeof(cf_t) * FLEN);
pss_put_slot(pss_signal, buffer, 6, cp);
sss_put_slot(ns?sss_signal5:sss_signal0, buffer, 6, cp);
pss_put_slot(pss_signal, buffer, nof_prb, cp);
sss_put_slot(ns?sss_signal5:sss_signal0, buffer, nof_prb, cp);
/* Transform to OFDM symbols */
memset(fft_buffer, 0, sizeof(cf_t) * 2 * FLEN);
memset(fft_buffer, 0, sizeof(cf_t) * FLEN);
lte_ifft_run_slot(&ifft, buffer, &fft_buffer[offset]);
vec_save_file("input", fft_buffer, sizeof(cf_t) * FLEN);
sync_find(&sync, fft_buffer, &find_idx);
find_ns = sync_get_slot_id(&sync);
printf("cell_id: %d find: %d, offset: %d, ns=%d find_ns=%d\n", cid, find_idx, offset,
ns, find_ns);
if (find_idx != offset + 960) {
printf("offset != find_offset: %d != %d\n", find_idx, offset + 960);
if (find_idx != offset + FLEN/2) {
printf("offset != find_offset: %d != %d\n", find_idx, offset + FLEN/2);
exit(-1);
}
if (ns*10 != find_ns) {

View File

@ -53,6 +53,9 @@ int conv_fft_cc_init(conv_fft_cc_t *q, uint32_t input_len, uint32_t filter_len)
if (dft_plan(&q->output_plan,q->output_len,BACKWARD,COMPLEX)) {
return LIBLTE_ERROR;
}
dft_plan_set_norm(&q->input_plan, true);
dft_plan_set_norm(&q->filter_plan, true);
dft_plan_set_norm(&q->output_plan, false);
return LIBLTE_SUCCESS;
}
@ -80,7 +83,7 @@ uint32_t conv_fft_cc_run(conv_fft_cc_t *q, cf_t *input, cf_t *filter, cf_t *outp
dft_run_c(&q->output_plan, q->output_fft, output);
return q->output_len;
return q->output_len-1;
}

View File

@ -32,6 +32,7 @@
#include <string.h>
#include "liblte/phy/utils/dft.h"
#include "liblte/phy/utils/vector.h"
#define dft_ceil(a,b) ((a-1)/b+1)
#define dft_floor(a,b) (a/b)
@ -144,11 +145,8 @@ void dft_run_c(dft_plan_t *plan, dft_c_t *in, dft_c_t *out) {
plan->forward, plan->mirror, plan->dc);
fftwf_execute(plan->p);
if (plan->norm) {
/**FIXME: Use VOLK */
norm = sqrtf(plan->size);
for (i=0;i<plan->size;i++) {
f_out[i] /= norm;
}
norm = 1.0/sqrtf(plan->size);
vec_sc_prod_cfc(f_out, norm, f_out, plan->size);
}
if (plan->db) {
for (i=0;i<plan->size;i++) {
@ -168,10 +166,8 @@ void dft_run_r(dft_plan_t *plan, dft_r_t *in, dft_r_t *out) {
memcpy(plan->in,in,sizeof(dft_r_t)*plan->size);
fftwf_execute(plan->p);
if (plan->norm) {
norm = plan->size;
for (i=0;i<len;i++) {
f_out[i] /= norm;
}
norm = 1.0/plan->size;
vec_sc_prod_fff(f_out, norm, f_out, plan->size);
}
if (plan->db) {
for (i=0;i<len;i++) {

View File

@ -155,6 +155,17 @@ void vec_deinterleave_cf(cf_t *x, float *real, float *imag, uint32_t len) {
#endif
}
void vec_deinterleave_real_cf(cf_t *x, float *real, uint32_t len) {
#ifdef HAVE_VOLK_DEINTERLEAVE_REAL_FUNCTION
volk_32fc_deinterleave_real_32f(real, x, len);
#else
int i;
for (i=0;i<len;i++) {
real[i] = __real__ x[i];
}
#endif
}
void *vec_malloc(uint32_t size) {
#ifndef HAVE_VOLK
return malloc(size);

6
matlab/sync/addnoise.m Normal file
View File

@ -0,0 +1,6 @@
function [ y ] = addnoise( x, snr_db )
v = 10^(-snr_db/10);
y=x+sqrt(v)*(randn(size(x))+1i*randn(size(x)))/sqrt(2);
y=y/sqrt(mean(y.*conj(y)));
end

View File

@ -1,18 +1,16 @@
function [ fs eps p_m w2] = find_pss( x, N_id_2, fft_size)
function [ w2] = find_pss2( x, N_id_2, fft_size)
c=lte_pss_zc(N_id_2);
cc=[zeros(fft_size/2-31,1); c; zeros(fft_size/2-31,1)];
cc=[0; cc(fft_size/2+1:fft_size); cc(2:fft_size/2)];
ccf=conj(ifft(cc));
ccd=[0; cc(fft_size/2+1:fft_size); cc(2:fft_size/2)];
ccf=sqrt(fft_size)*conj(ifft(ccd));
w2=conv(x,ccf);
%plot(10*log10(abs(w2)));%./mean(abs(w2))));
plot(abs(w2))
%axis([0 length(w2) 0 20])
[m i]=max(abs(w2));
p_m = m/mean(abs(w2));
fprintf('Frame starts at %d, m=%g, p=%g, p/m=%g dB\n',i, ...
mean(abs(w2)), m, 10*log10(m/mean(abs(w2))));
w2=real(conv(x,ccf))/62;
plot(w2)
[m i]=max(w2);
en=var(x,1);
p_m = m/en;
fprintf('Frame starts at %d, energy=%g, p=%g, p/en=%g dB\n',i, ...
en, m, m/en);
end