Exemplo n.º 1
0
cf_t srslte_vec_dot_prod_ccc(cf_t *x, cf_t *y, uint32_t len) {
#ifdef HAVE_VOLK_DOTPROD_FC_FUNCTION
  cf_t res;
  volk_32fc_x2_dot_prod_32fc(&res, x, y, len);
  return res; 
#else 
  uint32_t i;
  cf_t res = 0;
  for (i=0;i<len;i++) {
    res += x[i]*y[i];
  }
  return res;
#endif
}
Exemplo n.º 2
0
void * xlate_worker_thr(void *ptr) {
    worker * ctx = (worker*)ptr;

    int32_t mypos = ctx->last_written + 1;

    int fir_offset = 0;

    /* To avoid hassle with complicated FIR evaluation, we allocate *alldata bigger
     *  and copy the end of previous frame to the beginning of it, so we can compute
     *  the filter simply as sum(x_{n-j}*h_{j}) and don't care about overflows.
     *
     * The interesting fact is that if SDRPACKETSIZE is not divisible by decimation,
     *  the filtered frames will have different lengths.
     */
    float * alldata = calloc(sizeof(float), (SDRPACKETSIZE + MAXTAPS) * COMPLEX);
    float * firout = calloc(1, ctx->maxoutsize);
    lv_32fc_t phase_inc, phase;

    phase = lv_cmake(1.0, 0.0);

    while(1) {
        pthread_mutex_lock(&datamutex);
        if(sdr_cptr <= mypos || ctx->send_cptr <= mypos - BUFSIZE) { // there are no data to process or no free space
            pthread_cond_wait(&datacond, &datamutex);
            pthread_mutex_unlock(&datamutex);
            continue;
        }
        pthread_mutex_unlock(&datamutex);

        phase_inc = lv_cmake(cos(ctx->rotate * ctx->decim), sin(ctx->rotate * ctx->decim));

        memcpy(alldata, alldata+SDRPACKETSIZE*COMPLEX, MAXTAPS * COMPLEX * sizeof(float));
        memcpy(alldata + MAXTAPS, sdr_inbuf[mypos % BUFSIZE].data, SDRPACKETSIZE * COMPLEX * sizeof(float));

        int outsample = 0;
        int i;

        // evaluate the filter
        for(i = fir_offset; i<SDRPACKETSIZE; i+=ctx->decim) {
            lv_32fc_t* dst = (lv_32fc_t*) (firout + outsample*COMPLEX);
            volk_32fc_x2_dot_prod_32fc(dst,
                                       (lv_32fc_t*) (alldata+(i)*COMPLEX), // src
                                       (lv_32fc_t*)(ctx->taps), ctx->tapslen); // filter
            outsample++;
        }

        // rotator
        volk_32fc_s32fc_x2_rotator_32fc( (lv_32fc_t*) ctx->outbuf[mypos % BUFSIZE].data, // dst
                                         (lv_32fc_t*) firout, phase_inc, &phase, outsample);

        // save position so we know where to start evaluation the next frame
        fir_offset = i - SDRPACKETSIZE;

        ctx->outbuf[mypos % BUFSIZE].len = outsample * COMPLEX * sizeof(float);

        pthread_mutex_lock(&datamutex);
        if(ctx->newtaps != NULL) {
            free(ctx->taps);
            ctx->taps = get_complex_taps(ctx->newtaps, ctx->newtapslen, ctx->rotate);
            ctx->tapslen = ctx->newtapslen;
            ctx->maxval = calc_max_amplitude(ctx->newtaps, ctx->newtapslen);
            free(ctx->newtaps);
            ctx->newtaps = NULL;
        }
        if(!ctx->enabled) {
            pthread_mutex_unlock(&datamutex);
            break;
        }
        ctx->last_written = mypos;
        pthread_cond_broadcast(&datacond);
        pthread_mutex_unlock(&datamutex);

        mypos++;

    }

    // gracefully exit -- free and unlock everything...
    for(int i = 0; i<BUFSIZE; i++) {
        volk_free(ctx->outbuf[i].data);
    }
    free(ctx->taps);
    if(ctx->newtaps != NULL) {
        free(ctx->newtaps);
    }
    free(alldata);
    free(firout);

    return NULL;
}