/** * @ingroup lte_cfi_coding * Main DSP function * Encodes the control format indicator (CFI) * * @return On success, returns a non-negative number indicating the output * samples that should be transmitted through all output interface. To specify a different length * for certain interface, use the function set_output_samples(int idx, int len) * On error returns -1. * */ int work(void **inp, void **out) { int i; int rcv_samples, snd_samples; input_t *input; output_t *output; input = inp[0]; output = out[0]; rcv_samples = get_input_samples(0); snd_samples = NOF_BITS; if ((input[0] > 0) && (input[0] < 5)) { memcpy(output, &table[input[0]-1], NOF_BITS); } else { moderror_msg("Wrong cfi %d. Specify 1, 2, 3, or 4 (4 reserved)." "\n", input[0]); return -1; } /* printf("\n\n"); for (i=0; i<snd_samples; i++) { printf("%d",output[i]); } printf("\n\n %d %d %d", table, &table[input[0]-1], &table[input[0]-1][0]); */ return snd_samples; }
/** * @ingroup lte_resource_mapper * * Main DSP function * * This function allocates the data symbols of one slot (0.5 ms) in the corresponding place * of the LTE frame grid. During initialization phase CRS, PSS and SSS signals has been * incorporated and will no be modified during run phase. * PBCH (Physical Broadcast Channel), PCFICH (Physical Control Format Indicator Channel) & * PDCCH (Physical Downlink Control Channel) will be incorporated. * */ int work(void **inp, void **out) { if (subframe_idx_id) { param_get_int(subframe_idx_id, &subframe_idx); } #ifdef CHECK_RCV_SAMPLES int n; n=check_received_samples_mapper(); if (n < 1) { return n; } #endif #ifdef _COMPILE_ALOE moddebug("subframe_idx=%d tstamp=%d rcv=%d\n",subframe_idx,oesr_tstamp(ctx),get_input_samples(0)); #endif if (allocate_all_channels(inp,out[0])) { moderror("Error allocating channels\n"); return 0; } subframe_idx++; if (subframe_idx==NOF_SUBFRAMES_X_FRAME) { subframe_idx=0; } return 0; }
/**@ingroup gen_mux * */ int work(void **inp, void **out) { int i; int out_len; int nof_active_inputs; nof_active_inputs = 0; for (i=0;i<nof_inputs;i++) { input_lengths[i] = get_input_samples(i); nof_active_inputs++; } if (exclusive && nof_active_inputs>1) { moderror_msg("Exclusive mux but %d inputs have data\n",nof_active_inputs); return -1; } if(check_all && (nof_active_inputs<nof_inputs)) { moderror_msg("Only %d/%d inputs have data\n",nof_active_inputs,nof_inputs); return -1; } if (!out[0]) { moderror("Output not ready\n"); return -1; } out_len = sum_i(input_lengths,nof_inputs); if (out_len) { mux(inp,out[0],input_lengths,input_padding_pre,nof_inputs,input_sample_sz); } return out_len; }
/**@ingroup gen_demux * */ int work(void **inp, void **out) { int i; int rcv_len, out_len; rcv_len=get_input_samples(0); moddebug("%d samples recevied.\n",rcv_len); if (!rcv_len) return 0; modinfo_msg("received %d bytes\n",rcv_len); if ((rcv_len - sum_special_output_lengths) % (nof_outputs-nof_special_outputs)) { /* moderror_msg("Received length %d is not multiple of the number of output interfaces %d\n", rcv_len,nof_outputs); */ return 0; } out_len = (rcv_len - sum_special_output_lengths) / (nof_outputs-nof_special_outputs); for (i=0;i<nof_outputs;i++) { if (special_output_length[i]) { output_lengths[i] = special_output_length[i]; } else { output_lengths[i] = out_len; } set_output_samples(i,output_lengths[i]); if (!out[i]) { moderror_msg("output itf %d not ready\n",out[i]); return -1; } } demux(inp[0],out,output_lengths,output_padding_pre, output_padding_post,nof_outputs,input_sample_sz); return 0; }
/** * @ingroup file_sink * * Writes the received samples to the dac output buffer * */ int work(void **inp, void **out) { int rcv_samples; input_t *buffer = inp[0]; rcv_samples = get_input_samples(0); #ifdef _COMPILE_ALOE if (rcv_samples != last_rcv_samples) { last_rcv_samples = rcv_samples; modinfo_msg("Receiving %d samples at tslot %d\n", rcv_samples,oesr_tstamp(ctx)); } #endif if (!rcv_samples) { return 0; } switch(data_type) { case 0: rtdal_datafile_write_real(fd,(float*) buffer,rcv_samples); break; case 1: rtdal_datafile_write_complex(fd, (_Complex float*) buffer,rcv_samples); break; case 2: rtdal_datafile_write_complex_short(fd, (_Complex short*) buffer,rcv_samples); break; case -1: rtdal_datafile_write_bin(fd,buffer,rcv_samples); } return 0; }
/** * @ingroup udp_sink * * Writes the received samples to the dac output buffer * */ int work(void **inp, void **out) { int rcv_samples; int n; char tmp[16]; int nof_pkts,pkt_len,i; input_t *input = inp[0]; rcv_samples = get_input_samples(0); if (!rcv_samples) { return 0; } nof_pkts=1; param_get_int(blen_id,&nof_pkts); if (rcv_samples % nof_pkts) { modinfo_msg("Warning received packet len %d not multiple of %d packets\n", rcv_samples,nof_pkts); } pkt_len = rcv_samples/nof_pkts; modinfo_msg("Sending %d packets of %d bytes\n",nof_pkts,pkt_len); for (i=0;i<nof_pkts;i++) { n = sendto(fd,&input[i*pkt_len],pkt_len,0,(struct sockaddr *) &servaddr, sizeof (servaddr)); if (n == -1) { perror("sendto"); return -1; } } return 0; }
/** * @ingroup dac_sink * * Writes the received samples to the dac output buffer * */ int work(void **inp, void **out) { int rcv_samples; int n; rcv_samples = get_input_samples(0); if (!rcv_samples) { return 0; } if (check_blen && check_blen != rcv_samples) { moderror_msg("Expected %d samples but got %d\n", check_blen, rcv_samples); return -1; } if (process_params()) { return -1; } vec_mult_c_r((complex_t*) inp[0],out_buffer,amplitude,rcv_samples); if (enable_dac) { n = rtdal_dac_send(dac,out_buffer,rcv_samples,blocking); } else { n = rcv_samples; } modinfo_msg("send %d samples amplitude %g\n",n,amplitude); if (n != rcv_samples) { moderror_msg("Sent %d/%d samples\n",n,rcv_samples); return -1; } return 0; }
/** * @ingroup gen_hard_demod * * Main DSP function * * Calls the appropriate function for demodulating all recevied symbols. * * \param inp Input interface buffers. The value inp[i] points to the buffer received * from the i-th interface. The function get_input_samples(i) returns the number of received * samples (the sample size is by default sizeof(input_t)) * * \param out Output interface buffers. The value out[i] points to the buffer where the samples * to be sent through the i-th interfaces must be stored. * * @return On success, returns a non-negative number indicating the output * samples that should be transmitted through all output interface. To specify a different length * for certain interface, use the function set_output_samples(int idx, int len) * On error returns -1. * * */ int work(void **inp, void **out) { int rcv_samples, snd_samples; int modulation; int bits_per_symbol; input_t *input; output_t *output; float *inreal; if (!get_input_samples(0)) { return 0; } /* Dynamically obtain modulation type */ if (param_get_int(modulation_id, &modulation) != 1) { moderror("Error getting 'modulation' parameter. Assuming BPSK.\n"); modulation = BPSK; } /* Verify parameters */ if ((modulation != BPSK) && (modulation != QPSK) && (modulation != QAM16) && (modulation != QAM64)) { moderror_msg("Invalid modulation %d. Specify 1 for BPSK, 2 for QPSK," "4 for 16QAM, or 6 for 64QAM\n", modulation); return -1; } input = inp[0]; output = out[0]; rcv_samples = get_input_samples(0); /* number of input samples */ bits_per_symbol = get_bits_per_symbol(modulation); if (in_real) { inreal = inp[0]; hard_demod_real(inreal, output, rcv_samples, modulation); } else { hard_demod(input, output, rcv_samples, modulation); } snd_samples = rcv_samples*bits_per_symbol; return snd_samples; }
int work(void **inp, void **out) { int i, out_len; input_t *input; output_t *output; param_get_int(modulation_id,&modulation); for (i=0;i<NOF_INPUT_ITF;i++) { input = inp[i]; output = out[i]; if (get_input_samples(i)) { out_len = modulate(input,output,get_input_samples(i)); if (out_len == -1) { return -1; } set_output_samples(i,out_len); } } return 0; }
int work(void **inp, void **out) { int i, j, nof_fft; int dft_size; input_t *input; output_t *output; dft_plan_t *plan; if (param_get_int(dft_size_id,&dft_size) != 1) { moderror("Getting parameter dft_size\n"); return -1; } plan = find_plan(dft_size); if (!plan) { if ((plan = generate_new_plan(dft_size)) == NULL) { moderror("Generating plan.\n"); return -1; } } for (i=0;i<NOF_INPUT_ITF;i++) { input = inp[i]; output = out[i]; if (get_input_samples(i) % dft_size) { moderror_msg("Number of input samples (%d) must be multiple of dft_size (%d), in " "interface %d\n",get_input_samples(i),dft_size,i); return -1; } nof_fft = get_input_samples(i)/dft_size; for (j=0;j<nof_fft;j++) { dft_run_c2c(plan, &input[j*dft_size], &output[j*dft_size]); } set_output_samples(i,dft_size*nof_fft); } return 0; }
/** * @ingroup lte_ratematching * * Main DSP function * */ int work(void **inp, void **out) { int i, in_pkt_len, out_pkt_len, j; int rcv_samples; char *input, *output; param_get_int(pre_padding_id, &pre_padding); param_get_int(post_padding_id, &post_padding); param_get_int(nof_packets_id, &nof_packets); for (i=0;i<NOF_INPUT_ITF;i++) { input = inp[i]; output = out[i]; rcv_samples = get_input_samples(i); moddebug("%d samples received on input interface %d.\n",rcv_samples,i); if (rcv_samples == 0) { moddebug("%d samples to process. Returning.\n", rcv_samples); continue; } if ((rcv_samples) % nof_packets) { moderror_msg("Received samples (%d) should multiple of " "nof_packets (%d)\n", rcv_samples, nof_packets); return -1; } in_pkt_len = rcv_samples / nof_packets; if (direction) { out_pkt_len = in_pkt_len - pre_padding - post_padding; } else { out_pkt_len = in_pkt_len + pre_padding + post_padding; } if (in_pkt_len) { if (direction) { for (j=0;j<nof_packets;j++) { memcpy(outaddr(0),inaddr(pre_padding),input_sample_sz*out_pkt_len); } } else { for (j=0;j<nof_packets;j++) { memset(outaddr(0),0,input_sample_sz*pre_padding); memcpy(outaddr(pre_padding),inaddr(0),input_sample_sz*in_pkt_len); memset(outaddr(pre_padding+in_pkt_len),0,input_sample_sz*post_padding); } } moddebug("%d samples sent to output interface %d.\n",out_pkt_len*nof_packets, i); set_output_samples(i,out_pkt_len*nof_packets); } } return 0; }
/** * @ingroup Lte Rate Matching of convolutionally encoded information * Applied for PDCCH * * Main DSP function * * * \param inp Input interface buffers. The value inp[i] points to the buffer received * from the i-th interface. The function get_input_samples(i) returns the number of received * samples (the sample size is by default sizeof(input_t)) * * \param out Output interface buffers. The value out[i] points to the buffer where the samples * to be sent through the i-th interfaces must be stored. * * \param E Number of output bits of rate matching in transmitter mode * \param S Number of output bits of rate matching in receiver mode * * @return On success, returns a non-negative number indicating the output * samples that should be transmitted through all output interface. To specify a different length * for certain interface, use the function set_output_samples(int idx, int len) * On error returns -1. */ int work(void **inp, void **out) { int S, E; int rcv_samples, snd_samples; char *input_b; char *output_b; float *input_f; float *output_f; rcv_samples = get_input_samples(0); if (!rcv_samples || !out[0] || rcv_samples > 3*6114) { return 0; } input_f = inp[0]; input_b = inp[0]; output_f = out[0]; output_b = out[0]; if (!direction) { /* @Transmitter */ if (param_get_int(E_id, &E) != 1) { moderror("Error getting parameter 'E', indiciating the " "number of rate matching output samples in Tx mode.\n"); return -1; } if (E > OUTPUT_MAX_SAMPLES) { moderror("Too may output samples (E).\n"); return -1; } rate_matching(input_b, output_b, rcv_samples, E); snd_samples = E; } else { /* @Receiver */ if (param_get_int(S_id, &S) != 1) { moderror("Error getting parameter 'S', indiciating the " "number of rate matching output samples in Rx mode\n"); return -1; } if (S > OUTPUT_MAX_SAMPLES) { moderror("Too may output samples (S).\n"); return -1; } if (S%3 > 0) { moderror("Number of output samples S not integer divisible by 3.\n"); return -1; } snd_samples = rate_unmatching(input_f, output_f, rcv_samples, S); } return snd_samples; }
/**@ingroup gen_mux * */ int work(void **inp, void **out) { int i; int out_len; for (i=0;i<nof_inputs;i++) { input_lengths[i] = get_input_samples(i); } out_len = sum_i(input_lengths,nof_inputs); if (out_len) { mux(inp,out[0],input_lengths,input_padding_pre,nof_inputs,input_sample_sz); } return out_len; }
int work(void **inp, void **out) { int i, out_len, j; input_t *input; output_t *output; int rcv_samples; for (i=0;i<NOF_INPUT_ITF;i++) { input = inp[i]; output = out[i]; moddebug("rcv_len=%d\n",get_input_samples(i)); rcv_samples = get_input_samples(i); if (rcv_samples) { conv_encode(input,rcv_samples,constraint_length,rate,g,tail_bit, output,&out_len); for (j=0;j<padding;j++) { output[out_len+j] = 0; } set_output_samples(i,out_len+padding); } } return 0; }
int work(void **inp, void **out) { int len; if (!direction) { if (!out[0]) { return 0; } len = send_dci(out[0]); if (len == -1) { return -1; } return len; } else { len = get_input_samples(0); recv_dci(inp[0],out[0],len); } return 0; }
/**@ingroup gen_crc * Adds a CRC to every received packet from each interface */ int work(void **inp, void **out) { int i; unsigned int n; input_t *input; if (poly_id) param_get_int(poly_id,&poly); if (long_crc_id) param_get_int(long_crc_id, &long_crc); for (i=0;i<NOF_INPUT_ITF;i++) { if (get_input_samples(i)) { moddebug("rcv_len=%d\n",get_input_samples(i)); memcpy(out[i],inp[i],sizeof(input_t)*get_input_samples(i)); input = out[i]; n = icrc(0, input, get_input_samples(i), long_crc, poly, mode == MODE_ADD); if (mode==MODE_CHECK) { if (n) { total_errors++; } total_pkts++; set_output_samples(i,get_input_samples(i)-long_crc); if (!print_nof_pkts) { tscnt++; if (tscnt==interval_ts) { tscnt=0; #ifdef PRINT_BLER printf("Total blocks: %d\tTotal errors: %d\tBLER=%g\n", total_pkts,total_errors,(float)total_errors/total_pkts); #endif } } else { print_nof_pkts_cnt++; if (print_nof_pkts_cnt == print_nof_pkts) { print_nof_pkts_cnt=0; printf("Total blocks: %d\tTotal errors: %d\tBLER=%g\n", total_pkts,total_errors,(float)total_errors/total_pkts); total_pkts=0; total_errors=0; } } } else { set_output_samples(i,get_input_samples(i)+long_crc); } } } return 0; }
int work(void **inp, void **out) { int i,n; #if NOF_INPUTS>1 for (i=0;i<NOF_INPUT_ITF;i++) { binsource.input[i] = inp[i]; binsource.in_len[i] = get_input_samples(i) } #elif NOF_INPUTS == 1 binsource.input = inp[0]; binsource.in_len = get_input_samples(0); #endif #if NOF_OUTPUTS>1 for (i=0;i<NOF_OUTPUT_ITF;i++) { binsource.output[i] = out[i]; binsource.out_len = &out_len[i]; } #elif NOF_OUTPUTS == 1 binsourceoutput = out[0]; binsource.out_len = &out_len[0]; #endif /* Get input parameters */ if (param_get_int(nbits_id, &binsource.ctrl_in.nbits) != 1) { moderror("Error getting parameter nbits\n"); return -1; } /* call work */ n = binsource_work(&binsource); /* Set output nof_samples */ for (i=0;i<NOF_OUTPUT_ITF;i++) { set_output_samples(i,out_len[i]); binsource.out_len = &out_len[i]; } /* Set output parameters */ return n; }
/** * @ingroup lte_resource_mapper * * Main DSP function * * This function allocates the data symbols of one slot (0.5 ms) in the corresponding place * of the LTE frame grid. During initialization phase CRS, PSS and SSS signals has been * incorporated and will no be modified during run phase. * PBCH (Physical Broadcast Channel), PCFICH (Physical Control Format Indicator Channel) & * PDCCH (Physical Downlink Control Channel) will be incorporated. * */ int work(void **inp, void **out) { int n; subframe_idx=-1; if (subframe_idx_id) { param_get_int(subframe_idx_id, &subframe_idx); } #ifdef _COMPILE_ALOE moddebug("subframe_idx=%d tstamp=%d rcv_len=%d cfi=%d\n",subframe_idx,oesr_tstamp(ctx), get_input_samples(0),grid.cfi); #endif if (subframe_idx==-1) { return 0; } n=check_received_samples_demapper(); if (n < 1) { return n; } if (channels_init_grid(channel_ids, nof_channels)) { moderror("Initiating resource grid\n"); return 0; } if (deallocate_all_channels(channel_ids, nof_channels, inp[0],out)) { return -1; } if (extract_refsig(inp[0],out)) { return -1; } if (copy_signal(inp[0],out)) { return -1; } return 0; }
/** * @ingroup gen_hard_demod * * Main DSP function * * Calls the appropriate function for demodulating all recevied symbols. * * \param inp Input interface buffers. The value inp[i] points to the buffer received * from the i-th interface. The function get_input_samples(i) returns the number of received * samples (the sample size is by default sizeof(input_t)) * * \param out Output interface buffers. The value out[i] points to the buffer where the samples * to be sent through the i-th interfaces must be stored. * * @return On success, returns a non-negative number indicating the output * samples that should be transmitted through all output interface. To specify a different length * for certain interface, use the function set_output_samples(int idx, int len) * On error returns -1. * * */ int work(void **inp, void **out) { int i; int rcv_samples, snd_samples; int modulation; float sigma2; int bits_per_symbol; input_t *input; output_t *output; /* Dynamically obtain modulation type */ if (param_get_int(modulation_id, &modulation) != 1) { moderror("Error getting 'modulation' parameter. Assuming QPSK.\n"); modulation = QPSK; } /* Verify parameters */ if (modulation > 3 || modulation < 0) { moderror_msg("Invalid modulation %d. Specify 0 for BPSK, 1 for QPSK," "2 for 16QAM, or 3 for 64QAM\n", modulation); return -1; } else { modinfo_msg("Modulation type is %d (0:BPSK; 1:QPSK; 2:16QAM;" "3:64QAM)\n",modulation); } input = inp[0]; output = out[0]; rcv_samples = get_input_samples(0); /* number of input samples */ bits_per_symbol = get_bits_per_symbol(modulation); hard_demod(input, output, rcv_samples, modulation); snd_samples = rcv_samples*bits_per_symbol; /* printf("\n\n"); for (i=0; i<snd_samples; i++) { printf("%d",output[i]); } */ return snd_samples; }
/** * @TODO: * - re-compute c from N_id_2 */ int work(void **inp, void **out) { int rcv_samples=get_input_samples(0); int m0,m1; int subframe_idx,N_id_1; input_t *input=inp[0]; if (!rcv_samples) { return 0; } dft_run_c2c(&plan, &input[sss_pos_in_frame], input_fft); if (!get_m0m1(&input_fft[sss_pos_in_symbol],&m0,&m1,correlation_threshold)) { return 0; } subframe_idx=decide_subframe(m0,m1); N_id_1=decide_N_id_1(m0,m1); modinfo_msg("m0=%d, m1=%d subframe=%d\n", m0,m1,subframe_idx,N_id_1); #ifdef _COMPILE_ALOE if (sf_pm_idx >= 0 && !(subframe_idx && first)) { first=0; if (param_remote_set(out, 0, sf_pm_idx, &subframe_idx, sizeof(int))) { moderror("Setting parameter\n"); return -1; } } #endif return 0; }
/** * @ingroup template * * Main DSP function * * Document here your module, which parameters it requires and how it behaves as a function of them. * * \param inp Input interface buffers. The value inp[i] points to the buffer received * from the i-th interface. The function get_input_samples(i) returns the number of received * samples (the sample size is by default sizeof(input_t)) * * \param out Output interface buffers. The value out[i] points to the buffer where the samples * to be sent through the i-th interfaces must be stored. * * @return On success, returns a non-negative number indicating the output * samples that should be transmitted through all output interface. To specify a different length * for certain interface, use the function set_output_samples(int idx, int len) * On error returns -1. * * */ int work(void **inp, void **out) { int rcv_samples, snd_samples; int j; input_t *input; output_t *output; float gain; if (param_get_float(gain_id, &gain) != 1) { moderror("Error getting parameter gain\n"); return -1; } /* inp[n] and out[m] are pointer to the n-th and m-th input and output interfaces */ /* let us assume we only have one input and output interface */ input = inp[0]; output = out[0]; rcv_samples = get_input_samples(0); /* this function returns the samples received from an input */ for (j = 0; j < rcv_samples; j++) { /* do here your DSP work */ output[j] = gain*input[j]; } snd_samples = rcv_samples; return snd_samples; }
int work(void **inp, void **out) { int rcv_samples; int n; input_t *input; output_t *output; float gain_re,gain_im,variance,scale; _Complex float gain_c; if (!get_input_samples(0)) { return 0; } if (param_get_float(gain_re_id, &gain_re) != 1) { moderror("Error getting parameter gain_re\n"); return -1; } if (param_get_float(gain_im_id, &gain_im) != 1) { moderror("Error getting parameter gain_im\n"); return -1; } if (param_get_float(scale_id, &scale) != 1) { moderror("Error getting parameter scale\n"); return -1; } if (!auto_mode) { if (param_get_float(variance_id, &variance) != 1) { moderror("Error getting parameter variance\n"); return -1; } } else if (auto_mode == 1) { variance = get_variance(snr_current,scale); cnt_realizations++; if (cnt_realizations >= num_realizations) { snr_current += snr_step; cnt_realizations=0; } if (snr_current >= snr_max) { auto_mode=2; variance=0; } } __real__ gain_c = gain_re; __imag__ gain_c = gain_im; for (n=0;n<NOF_INPUT_ITF;n++) { input = inp[n]; output = out[n]; rcv_samples = get_input_samples(0); if (variance != 0) { gen_noise_c(noise_vec,variance,rcv_samples); vec_sum_c(output,input,noise_vec,rcv_samples); } else { memcpy(output,input,rcv_samples*sizeof(input_t)); } if (gain_re != 1.0 && gain_im != 0.0) { vec_mult_c(output,output,gain_c,rcv_samples); } } return rcv_samples; }
/** * Testsuite: * Generates random symbols and calls the module .... * @param ... * @param ... * @param ... */ int main(int argc, char **argv) { struct timespec tdata[3]; gnuplot_ctrl *plot; char tmp[64]; int ret, i, j; float *tmp_f; _Complex float *tmp_c; double *plot_buff_r; double *plot_buff_c; allocate_memory(); parameters = NULL; parse_paramters(argc, argv); if (generate_input_signal(input_data, input_lengths)) { printf("Error generating input signal\n"); exit(1); } for (i=0;i<nof_input_itf;i++) { if (!input_lengths[i]) { printf("Warning, input interface %d has zero length\n",i); } } if (initialize()) { printf("Error initializing\n"); exit(1); /* the reason for exiting should be printed out beforehand */ } #ifndef _ALOE_OLD_SKELETON for (i=0;i<nof_input_itf;i++) { input_ptr[i] = &input_data[i*input_max_samples*input_sample_sz]; } for (i=0;i<nof_output_itf;i++) { output_ptr[i] = &output_data[i*output_max_samples*output_sample_sz]; } clock_gettime(CLOCK_MONOTONIC,&tdata[1]); ret = work(input_ptr, output_ptr); clock_gettime(CLOCK_MONOTONIC,&tdata[2]); #else clock_gettime(CLOCK_MONOTONIC,&tdata[1]); ret = work(input_data, output_data); clock_gettime(CLOCK_MONOTONIC,&tdata[2]); #endif stop(); if (ret == -1) { printf("Error running\n"); exit(-1); } get_time_interval(tdata); for (i=0;i<nof_output_itf;i++) { if (!output_lengths[i]) { output_lengths[i] = ret; } if (!output_lengths[i]) { printf("Warning output interface %d has zero length\n",i); } } printf("\nExecution time: %d ns.\n", (int) tdata[0].tv_nsec); printf("FINISHED\n"); if (use_gnuplot) { for (i=0;i<nof_input_itf;i++) { plot_buff_r = malloc(sizeof(double)*input_lengths[i]); plot_buff_c = malloc(sizeof(double)*input_lengths[i]); if (input_sample_sz == sizeof(float)) { tmp_f = (float*) &input_data[i*input_max_samples]; for (j=0;j<input_lengths[i];j++) { plot_buff_r[j] = (double) tmp_f[j]; } plot = gnuplot_init() ; gnuplot_setstyle(plot,"lines"); snprintf(tmp,64,"input_%d",i); gnuplot_plot_x(plot, plot_buff_r, get_input_samples(i), tmp); free(plot_buff_r); } else if (input_sample_sz == sizeof(_Complex float)) { tmp_c = (_Complex float*) &input_data[i*input_max_samples]; for (j=0;j<input_lengths[i];j++) { plot_buff_r[j] = (double) __real__ tmp_c[j]; plot_buff_c[j] = (double) __imag__ tmp_c[j]; } plot = gnuplot_init() ; gnuplot_setstyle(plot,"lines"); snprintf(tmp,64,"input_real_%d",i); gnuplot_plot_x(plot, plot_buff_r, get_input_samples(i), tmp); plot = gnuplot_init() ; gnuplot_setstyle(plot,"lines"); snprintf(tmp,64,"input_imag_%d",i); gnuplot_plot_x(plot, plot_buff_c, get_input_samples(i), tmp); free(plot_buff_r); free(plot_buff_c); } } for (i=0;i<nof_output_itf;i++) { plot_buff_r = malloc(sizeof(double)*output_lengths[i]); plot_buff_c = malloc(sizeof(double)*output_lengths[i]); if (output_sample_sz == sizeof(float)) { tmp_f = (float*) &output_data[i*output_max_samples]; for (j=0;j<output_lengths[i];j++) { plot_buff_r[j] = (double) __real__ tmp_f[j]; } plot = gnuplot_init() ; gnuplot_setstyle(plot,"lines"); snprintf(tmp,64,"output_%d",i); gnuplot_plot_x(plot, plot_buff_r, output_lengths[i], tmp); free(plot_buff_r); } else if (output_sample_sz == sizeof(_Complex float)) { tmp_c = (_Complex float*) &output_data[i*output_max_samples]; for (j=0;j<output_lengths[i];j++) { plot_buff_r[j] = (double) __real__ tmp_c[j]; plot_buff_c[j] = (double) __imag__ tmp_c[j]; } plot = gnuplot_init() ; gnuplot_setstyle(plot,"lines"); snprintf(tmp,64,"output_real_%d",i); gnuplot_plot_x(plot, plot_buff_r, output_lengths[i], tmp); plot = gnuplot_init() ; gnuplot_setstyle(plot,"lines"); snprintf(tmp,64,"output_imag_%d",i); gnuplot_plot_x(plot, plot_buff_c, output_lengths[i], tmp); free(plot_buff_r); free(plot_buff_c); } } printf("Type ctrl+c to exit\n");fflush(stdout); free_memory(); pause(); /* make sure we exit here */ exit(1); } free_memory(); return 0; }
int work(void **inp, void **out) { int i, j, k; int rcv_samples, nof_ffts; int df, fs; int e; int dft_size; input_t *input; output_t *output; dft_plan_t *plan; if (param_get_int(dft_size_id,&dft_size) != 1) { dft_size = get_input_samples(0); moddebug("Parameter dft_size not defined. Assuming %d" " (number of input samples on interface 0).\n", dft_size); /*moderror("Getting parameter dft_size\n"); return -1;*/ } if (dft_size == 0) { modinfo("dft_size = 0. Returning.\n"); return 0; } else { moddebug("dft_size = %d.\n", dft_size); } /* if (param_get_int(param_id("dft_size"),&dft_size) != 1) { moddebug("Parameter dft_size not defined. Assuming %d" " (number of input samples on interface 0).\n", dft_size); } */ plan = find_plan(dft_size); if (!plan) { if ((plan = generate_new_plan(dft_size)) == NULL) { moderror("Generating plan.\n"); return -1; } } if (param_get_int(df_id, &df) != 1) { df = 0; } if (df != 0) { if (param_get_int(fs_id, &fs) != 1) { moderror("Parameter fs not defined.\n"); return -1; } if (fs <= 0) { moderror("Sampling rate fs must be larger than 0.\n"); return -1; } if ((df != previous_df) || (fs != previous_fs) || (dft_size != previous_dft_size)) { e = process_shift_params(df, fs, dft_size); if (e < 0) { return -1; } previous_df = df; previous_fs = fs; previous_dft_size = dft_size; } } for (i=0;i<NOF_INPUT_ITF;i++) { input = inp[i]; output = out[i]; rcv_samples = get_input_samples(i); moddebug("%d samples received on interface %d.\n",rcv_samples, i); if (rcv_samples == 0) { moddebug("%d samples to process. Returning.\n", rcv_samples); continue; } moddebug("Processing %d samples...\n",rcv_samples); if (rcv_samples % dft_size) { moderror_msg("Number of input samples (%d) not integer multiple" " of dft_size (%d) on interface %d\n",rcv_samples,dft_size,i); return -1; } if (get_input_samples(0)>0) { modinfo_msg("received %d samples\n",get_input_samples(0)); } nof_ffts = rcv_samples/dft_size; for (j=0;j<nof_ffts;j++) { if ((df != 0) && (direction == FORWARD)) { /* Rx: shift before FFT */ for (k=0;k<dft_size;k++) { input[j*dft_size+k] *= shift[k*shift_increment]; } } dft_run_c2c(plan, &input[j*dft_size], &output[j*dft_size]); if ((df !=0) && (direction == BACKWARD)) { /* Tx: shift after IFFT */ for (k=0;k<dft_size;k++) { output[j*dft_size+k] *= shift[k*shift_increment]; } } } set_output_samples(i,dft_size*nof_ffts); moddebug("%d samples sent to output interface %d.\n",dft_size*nof_ffts,i); } return 0; }
/**@ingroup gen_remcyclic * * For each interface, the number of received samples must be multiple of the OFDM symbol size, * otherwise the module produces and error and stops the waveform. * * It removes a cyclic prefix to each OFDM symbol received from each interface. */ int work(void **inp, void **out) { int i, j; int dft_size, cyclic_prefix_sz, first_cyclic_prefix_sz; int k, nof_ofdm_symbols_per_slot, rcv_samples; int cpy; int cnt; input_t *input; output_t *output; if (param_get_int(cyclic_prefix_sz_id, &cyclic_prefix_sz) != 1) { moderror("getting parameter cyclic_prefix_sz\n"); return -1; } if (first_cyclic_prefix_sz_id) { if (param_get_int(first_cyclic_prefix_sz_id, &first_cyclic_prefix_sz) != 1) { moderror("getting parameter first_cyclic_prefix_sz\n"); return -1; } } else { first_cyclic_prefix_sz = cyclic_prefix_sz; } if (param_get_int(dft_size_id, &dft_size) != 1) { /*moderror("getting parameter dft_size\n"); return -1;*/ dft_size = get_input_samples(0)-cyclic_prefix_sz; moddebug("Parameter dft_size not defined. Assuming %d" " (number of input samples on interface 0 - cyclic_prefix_sz)." "\n", dft_size); } if (dft_size <= 0) { modinfo("dft_size <= 0. Returning.\n"); return 0; } else { moddebug("dft_size = %d.\n", dft_size); } if (first_cyclic_prefix_sz > dft_size || cyclic_prefix_sz > dft_size) { moderror_msg("Error with parameters dft_size=%d, cyclic_prefix_sz=%d, " "first_cyclic_prefix_sz=%d\n",dft_size,cyclic_prefix_sz,first_cyclic_prefix_sz); return -1; } if (first_cyclic_prefix_sz == cyclic_prefix_sz) { nof_ofdm_symbols_per_slot = 6; } else { nof_ofdm_symbols_per_slot = 7; } for (i=0;i<NOF_INPUT_ITF;i++) { cnt=0; input = inp[i]; output = out[i]; rcv_samples = get_input_samples(i); moddebug("rcv_len=%d samples \n",rcv_samples); if (rcv_samples > 0) { j = 0; k = 0; while (cnt < rcv_samples) { if (j == k*nof_ofdm_symbols_per_slot) { cpy = first_cyclic_prefix_sz; k++; } else { cpy = cyclic_prefix_sz; } memcpy(output,&input[cpy],sizeof(input_t)*dft_size); input += dft_size+cpy; output += dft_size; cnt += dft_size+cpy; j++; } if (rcv_samples != cnt) { moderror_msg("Number of input samples (%d) should be " "equal to %d on interface %d\n",rcv_samples,cnt,i); return -1; } set_output_samples(i, j*dft_size); } } return 0; }
/**@ingroup plp_sink * Prints or displays the signal according to the selected mode. */ int work(void **inp, void **out) { int n,i,j; int mode; float *r_input; _Complex float *c_input; dft_plan_t *plan; strdef(xlabel); if (mode_id != NULL) { if (param_get_int(mode_id,&mode) != 1) { mode = 0; } } else { mode = 0; } memset(signal_lengths,0,sizeof(int)*2*NOF_INPUT_ITF); for (n=0;n<NOF_INPUT_ITF;n++) { if (is_complex && mode != MODE_PSD) { signal_lengths[2*n] = get_input_samples(n)/2; signal_lengths[2*n+1] = signal_lengths[2*n]; } else { signal_lengths[n] = get_input_samples(n); } if (get_input_samples(n) != last_rcv_samples) { last_rcv_samples = get_input_samples(n); #ifdef _COMPILE_ALOE modinfo_msg("Receiving %d samples at tslot %d\n",last_rcv_samples, oesr_tstamp(ctx)); #endif } } #ifdef _COMPILE_ALOE if (print_not_received) { for (n=0;n<NOF_INPUT_ITF;n++) { if (MOD_DEBUG) { ainfo_msg("ts=%d, rcv_len=%d\n",oesr_tstamp(ctx),get_input_samples(n)); } if (!get_input_samples(n)) { printf("ts=%d. Data not received from interface %d\n",oesr_tstamp(ctx),n); } } } #endif #ifdef _COMPILE_ALOE if (oesr_tstamp(ctx)-last_tstamp < interval_ts) { return 0; } last_tstamp = interval_ts; #endif switch(mode) { case MODE_SILENT: break; case MODE_PRINT: for (n=0;n<NOF_INPUT_ITF;n++) { if (inp[n]) { print_signal(inp[n],get_input_samples(n)); } } break; case MODE_SCOPE: #ifdef _COMPILE_ALOE snprintf(xlabel,STR_LEN,"# sample (ts=%d)",oesr_tstamp(ctx)); #else snprintf(xlabel,STR_LEN,"# sample"); #endif if (is_complex) { set_legend(c_legends,2*NOF_INPUT_ITF); } else { set_legend(r_legends,NOF_INPUT_ITF); } set_labels(xlabel,"amp"); for (n=0;n<NOF_INPUT_ITF;n++) { if (inp[n]) { if (is_complex) { c_input = inp[n]; for (i=0;i<signal_lengths[2*n];i++) { pl_signals[2*n*INPUT_MAX_SAMPLES+i] = (double) __real__ c_input[i]; pl_signals[(2*n+1)*INPUT_MAX_SAMPLES+i] = (double) __imag__ c_input[i]; } } else { r_input = inp[n]; for (i=0;i<signal_lengths[n];i++) { pl_signals[n*INPUT_MAX_SAMPLES+i] = (double) r_input[i]; } } } } plp_draw(pl_signals,signal_lengths,0); break; case MODE_PSD: #ifdef _COMPILE_ALOE snprintf(xlabel,STR_LEN,"freq. idx (ts=%d)",oesr_tstamp(ctx)); #else snprintf(xlabel,STR_LEN,"freq. idx"); #endif set_labels(xlabel,"PSD (dB/Hz)"); set_legend(fft_legends,NOF_INPUT_ITF); for (i=0;i<NOF_INPUT_ITF;i++) { if (signal_lengths[i]) { if (fft_size) { signal_lengths[i] = signal_lengths[i]>fft_size?fft_size:signal_lengths[i]; } plan = find_plan(signal_lengths[i]); c_input = inp[i]; r_input = inp[i]; if (!plan) { if ((plan = generate_new_plan(signal_lengths[i])) == NULL) { moderror("Generating plan.\n"); return -1; } } if (is_complex) { dft_run_c2r(plan, c_input, &f_pl_signals[i*INPUT_MAX_SAMPLES]); } else { dft_run_r2r(plan, r_input, &f_pl_signals[i*INPUT_MAX_SAMPLES]); } /*if (!is_complex) { signal_lengths[i] = signal_lengths[i]/2; }*/ for (j=0;j<signal_lengths[i];j++) { pl_signals[i*INPUT_MAX_SAMPLES+j] = (double) f_pl_signals[i*INPUT_MAX_SAMPLES+j]; } } } for (i=NOF_INPUT_ITF;i<2*NOF_INPUT_ITF;i++) { signal_lengths[i] = 0; } plp_draw(pl_signals,signal_lengths,0); break; default: moderror_msg("Unknown mode %d\n",mode); return -1; } return 0; }
/** * @ingroup dac_sink * * Writes the received samples to the dac output buffer * */ int work(void **inp, void **out) { int rcv_samples; float *input_rf; _Complex float *input_f; _Complex short *input_s; int i,j; float freq; float gain; float x=0; float *buffer_rf = buffer; _Complex float *buffer_f = buffer; _Complex short *buffer_s = buffer; if (param_get_float(freq_id,&freq) != 1) { moderror("Getting parameter freq_samp\n"); return -1; } if (gain_id) { if (param_get_float(gain_id,&gain) != 1) { moderror("Getting parameter gain\n"); return -1; } } else { gain = 1.0; } #ifdef _COMPILE_ALOE if (freq != last_freq) { modinfo_msg("Set sampling frequency to %.2f MHz at tslot %d\n", freq/1000000,oesr_tstamp(ctx)); last_freq = freq; } #endif rtdal_uhd_set_freq(freq); for (i=0;i<NOF_INPUT_ITF;i++) { input_s = inp[i]; input_f = inp[i]; input_rf = inp[i]; rcv_samples = get_input_samples(i); #ifdef _COMPILE_ALOE if (rcv_samples != last_rcv_samples) { last_rcv_samples = rcv_samples; modinfo_msg("Receiving %d samples at tslot %d\n",rcv_samples,oesr_tstamp(ctx)); } #endif rtdal_uhd_set_block_len(rcv_samples); x=0; for (j=0;j<rcv_samples;j++) { switch(data_type) { case 0: buffer_rf[j] = gain*input_rf[j]; break; case 1: buffer_f[j] = gain*input_f[j]; break; case 2: buffer_s[j] = gain*input_s[j]; break; } } } return 0; }
/**@ingroup gen_cyclic * * For each interface, the number of received samples must be multiple of the OFDM symbol size, * otherwise the module produces and error and stops the waveform. * * It adds a cyclic prefix to each OFDM symbol received from each interface. */ int work(void **inp, void **out) { int i, j; int nof_ofdm_symb; int dft_size, cyclic_prefix_sz, first_cyclic_prefix_sz; int k, nof_ofdm_symbols_per_slot,rcv_samples; int cnt; int cpy; div_t symbols; input_t *input; output_t *output; if (param_get_int(dft_size_id, &dft_size) != 1) { /*moderror("getting parameter dft_size\n"); return -1;*/ dft_size = get_input_samples(0); moddebug("Parameter dft_size not defined. Assuming %d" " (number of input samples on interface 0).\n", dft_size); } if (dft_size == 0) { modinfo("dft_size = 0. Returning.\n"); return 0; } else { moddebug("dft_size = %d.\n", dft_size); } if (param_get_int(cyclic_prefix_sz_id, &cyclic_prefix_sz) != 1) { moderror("getting parameter cyclic_prefix_sz\n"); return -1; } if (first_cyclic_prefix_sz_id) { if (param_get_int(first_cyclic_prefix_sz_id, &first_cyclic_prefix_sz) != 1) { moderror("getting parameter first_cyclic_prefix_sz\n"); return -1; } } else { first_cyclic_prefix_sz = cyclic_prefix_sz; } if (first_cyclic_prefix_sz > dft_size || cyclic_prefix_sz > dft_size) { moderror_msg("Error with parameters dft_size=%d, cyclic_prefix_sz=%d, " "first_cyclic_prefix_sz=%d\n",dft_size,cyclic_prefix_sz,first_cyclic_prefix_sz); return -1; } if (first_cyclic_prefix_sz == cyclic_prefix_sz) { nof_ofdm_symbols_per_slot = 6; } else { nof_ofdm_symbols_per_slot = 7; } for (i=0;i<NOF_INPUT_ITF;i++) { input = inp[i]; output = out[i]; rcv_samples = get_input_samples(i); moddebug("rcv_len=%d samples \n",rcv_samples); symbols = div(rcv_samples,dft_size); if (symbols.rem) { moderror_msg("Number of input samples (%d) must be " "integer multiple of dft_size (%d) on interface " "%d\n",rcv_samples,dft_size,i); return -1; } nof_ofdm_symb = symbols.quot; if (nof_ofdm_symb) { k = 0; cnt = 0; for (j=0;j<nof_ofdm_symb;j++) { if (j == k*nof_ofdm_symbols_per_slot) { cpy = first_cyclic_prefix_sz; k++; } else { cpy = cyclic_prefix_sz; } memcpy(output, &input[dft_size-cpy], sizeof(input_t)*cpy); memcpy(&output[cpy], input, sizeof(input_t)*dft_size); input += dft_size; output += dft_size+cpy; cnt += dft_size+cpy; } set_output_samples(i, cnt); } } return 0; }
/** * @ingroup lte_ratematching * * Main DSP function * */ int work(void **inp, void **out) { int in_len,nof_active_itf,out_len,out_len_block,rvidx; int i,j; int fft_size, mcs,cp_is_long,nrb; char *input_b; char *output_b; float *input_f; float *output_f; if (!get_input_samples(0)) { return 0; } if (out_len_id) { if (param_get_int(out_len_id, &out_len) != 1) { moderror("Error getting parameter out_len\n"); return -1; } } else { if (tslot_idx_id) { if (param_get_int(tslot_idx_id, &tslot_idx) != 1) { moderror("Error getting parameter tslot_idx\n"); return -1; } } if (param_get_int(fft_size_id, &fft_size) != 1) { moderror("Error getting parameter fft_size\n"); return -1; } if (param_get_int(mcs_id, &mcs) != 1) { moderror("Error getting parameter mcs\n"); return -1; } if (param_get_int(nrb_id, &nrb) != 1) { moderror("Error getting parameter nrb\n"); return -1; } if (param_get_int(cp_long_id, &cp_is_long) != 1) { moderror("Error getting parameter cp_is_long\n"); return -1; } if (!direction) { out_len = lte_get_psdch_bits_x_slot(lteslots_x_timeslot*tslot_idx, fft_size, cp_is_long, lteslots_x_timeslot)* lte_get_modulation_format(mcs); } else { out_len = lte_get_cbits(mcs,nrb); } if (out_len == -1) { moderror("Error computing bits per slot\n"); return -1; } } if (rvidx_id) { if (param_get_int(rvidx_id, &rvidx) != 1) { moderror("Error getting parameter rvidx\n"); return -1; } } else { rvidx = 0; } nof_active_itf = 0; for (i=0;i<NOF_INPUT_ITF;i++) { if (get_input_samples(i)) nof_active_itf++; } if (!nof_active_itf) { return 0; } out_len_block = out_len/nof_active_itf; output_f = out[0]; output_b = out[0]; for (i=0;i<NOF_INPUT_ITF;i++) { input_f = inp[i]; input_b = inp[i]; in_len = get_input_samples(i); if (in_len && inp[i]) { if(!direction) { if (char_RM_block(input_b,&output_b[i*out_len_block],in_len, out_len_block,rvidx)) { return -1; } } else { if (float_UNRM_block(input_f,&output_f[i*out_len_block],in_len, out_len_block,rvidx)) { return -1; } } } } tslot_idx++; if (tslot_idx == LTE_NOF_SLOTS_X_FRAME/lteslots_x_timeslot) { tslot_idx = 0; } return out_len_block*nof_active_itf; }