コード例 #1
0
ファイル: agc.c プロジェクト: CodaCarlson/srsLTE
void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) {
  float gain_db = 10*log10(q->gain); 
  float gain_uhd_db = 1.0;
  //float gain_uhd = 1.0;  
  float y = 0; 
  // Apply current gain to input signal 
  if (!q->uhd_handler) {
    srslte_vec_sc_prod_cfc(signal, q->gain, signal, len);
  } else {
    if (q->gain < 1) {
      q->gain = 1.0; 
    }
    if (isinf(gain_db) || isnan(gain_db)) {
      q->gain = 10.0; 
    } else {
      gain_uhd_db = q->set_gain_callback(q->uhd_handler, gain_db);        
      q->gain = pow(10, gain_uhd_db/10);
    }
  }
  float *t; 
  switch(q->mode) {
    case SRSLTE_AGC_MODE_ENERGY:
      y = sqrtf(crealf(srslte_vec_dot_prod_conj_ccc(signal, signal, len))/len);
      break;
    case SRSLTE_AGC_MODE_PEAK_AMPLITUDE:
      t = (float*) signal; 
      y = t[srslte_vec_max_fi(t, 2*len)];// take only positive max to avoid abs() (should be similar) 
      break;
    default: 
      fprintf(stderr, "Unsupported AGC mode\n");
      return; 
  }
  
  if (q->nof_frames > 0) {
    q->y_tmp[q->frame_cnt++] = y; 
    if (q->frame_cnt == q->nof_frames) {
      q->frame_cnt = 0; 
      switch(q->mode) {
        case SRSLTE_AGC_MODE_ENERGY:
          y = srslte_vec_acc_ff(q->y_tmp, q->nof_frames)/q->nof_frames;
          break;
        case SRSLTE_AGC_MODE_PEAK_AMPLITUDE:
          y = q->y_tmp[srslte_vec_max_fi(q->y_tmp, q->nof_frames)];
          break;
        default: 
          fprintf(stderr, "Unsupported AGC mode\n");
          return; 
      }
    }
  }
  
  double gg = 1.0; 
  if (q->isfirst) {
    q->y_out = y; 
    q->isfirst = false; 
  } else {
    if (q->frame_cnt == 0) {
      q->y_out = (1-q->bandwidth) * q->y_out + q->bandwidth * y;
      if (!q->lock) {
        gg = expf(-0.5*q->bandwidth*logf(q->y_out/q->target));
        q->gain *= gg; 
      }          
      INFO("AGC gain: %.2f (%.2f) y_out=%.3f, y=%.3f target=%.1f gg=%.2f\n", gain_db, gain_uhd_db, q->y_out, y, q->target, gg);      
    }
  }
}
コード例 #2
0
int srslte_prach_detect_offset(srslte_prach_t *p,
                               uint32_t freq_offset,
                               cf_t *signal,
                               uint32_t sig_len,
                               uint32_t *indices,
                               float *t_offsets,
                               float    *peak_to_avg,
                               uint32_t *n_indices)
{
  int ret = SRSLTE_ERROR;
  if(p       != NULL &&
     signal  != NULL &&
     sig_len > 0     &&
     indices != NULL)
  {
    
    if(sig_len < p->N_ifft_prach){
      fprintf(stderr, "srslte_prach_detect: Signal length is %d and should be %d\n", sig_len, p->N_ifft_prach);
      return SRSLTE_ERROR_INVALID_INPUTS;
    }
    
    // FFT incoming signal
    srslte_dft_run(p->fft, signal, p->signal_fft);

    *n_indices = 0;

    // Extract bins of interest
    uint32_t N_rb_ul = srslte_nof_prb(p->N_ifft_ul);
    uint32_t k_0 = freq_offset*N_RB_SC - N_rb_ul*N_RB_SC/2 + p->N_ifft_ul/2;
    uint32_t K = DELTA_F/DELTA_F_RA;
    uint32_t begin = PHI + (K*k_0) + (K/2);

    memcpy(p->prach_bins, &p->signal_fft[begin], p->N_zc*sizeof(cf_t));
    
    for(int i=0;i<p->N_roots;i++){
      cf_t *root_spec = p->dft_seqs[p->root_seqs_idx[i]];
     
      srslte_vec_prod_conj_ccc(p->prach_bins, root_spec, p->corr_spec, p->N_zc);

      srslte_dft_run(p->zc_ifft, p->corr_spec, p->corr_spec);
      
      srslte_vec_abs_square_cf(p->corr_spec, p->corr, p->N_zc);

      float corr_ave = srslte_vec_acc_ff(p->corr, p->N_zc)/p->N_zc;
      
      uint32_t winsize = 0;
      if(p->N_cs != 0){
        winsize = p->N_cs;
      }else{
        winsize = p->N_zc;
      }
      uint32_t n_wins = p->N_zc/winsize;

      float max_peak = 0; 
      for(int j=0;j<n_wins;j++) {
        uint32_t start = (p->N_zc-(j*p->N_cs))%p->N_zc;
        uint32_t end = start+winsize;
        if (end>p->deadzone) {
          end-=p->deadzone;
        }
        start += p->deadzone;
        p->peak_values[j] = 0;
        for(int k=start;k<end;k++) {
          if(p->corr[k] > p->peak_values[j]) {
            p->peak_values[j]  = p->corr[k];
            p->peak_offsets[j] = k-start; 
            if (p->peak_values[j] > max_peak) {
              max_peak = p->peak_values[j];
            }
          }
        }
      }
      if (max_peak > p->detect_factor*corr_ave) {
        for (int j=0;j<n_wins;j++) {
          if(p->peak_values[j] > p->detect_factor*corr_ave)
          {
            printf("ncs=%d, nzc=%d, nwins=%d, Nroot=%d, i=%d, j=%d, start=%d, peak_value=%f, peak_offset=%d, tseq=%f\n", 
                   p->N_cs, p->N_zc, n_wins, p->N_roots, i, j, (p->N_zc-(j*p->N_cs))%p->N_zc, p->peak_values[j], 
                   p->peak_offsets[j], p->T_seq*1e6);
            memcpy(save_corr, p->corr, p->N_zc*sizeof(float));
            if (indices) {
              indices[*n_indices]     = (i*n_wins)+j;
            }
            if (peak_to_avg) {
              peak_to_avg[*n_indices] = p->peak_values[j]/corr_ave; 
            }
            if (t_offsets) {
              t_offsets[*n_indices] = (float) p->peak_offsets[j]*p->T_seq/p->N_zc; 
            }            
            (*n_indices)++;          
          }
        }
      }
    }

    ret = SRSLTE_SUCCESS;
  }
  return ret;
}