void TempoTrackV2::calculateBeatPeriod(const vector<double> &df, vector<double> &beat_period, vector<double> &tempi) { // to follow matlab.. split into 512 sample frames with a 128 hop size // calculate the acf, // then the rcf.. and then stick the rcfs as columns of a matrix // then call viterbi decoding with weight vector and transition matrix // and get best path unsigned int wv_len = 128; double rayparam = 43.; // make rayleigh weighting curve d_vec_t wv(wv_len); for (unsigned int i=0; i<wv.size(); i++) { wv[i] = (static_cast<double> (i) / pow(rayparam,2.)) * exp((-1.*pow(-static_cast<double> (i),2.)) / (2.*pow(rayparam,2.))); } // beat tracking frame size (roughly 6 seconds) and hop (1.5 seconds) unsigned int winlen = 512; unsigned int step = 128; // matrix to store output of comb filter bank, increment column of matrix at each frame d_mat_t rcfmat; int col_counter = -1; // main loop for beat period calculation for (unsigned int i=0; i+winlen<df.size(); i+=step) { // get dfframe d_vec_t dfframe(winlen); for (unsigned int k=0; k<winlen; k++) { dfframe[k] = df[i+k]; } // get rcf vector for current frame d_vec_t rcf(wv_len); get_rcf(dfframe,wv,rcf); rcfmat.push_back( d_vec_t() ); // adds a new column col_counter++; for (unsigned int j=0; j<rcf.size(); j++) { rcfmat[col_counter].push_back( rcf[j] ); } } // now call viterbi decoding function viterbi_decode(rcfmat,wv,beat_period,tempi); }
void CSt4285::demodulate_and_equalize( FComplex *in ) { int i, symbol_offset, data_offset, dt; unsigned char data[DATA_AND_PROBE_SYMBOLS_PER_FRAME*4]; float a,b; rx_scramble_count = 0; symbol_offset = 0; data_offset = 0; soft_index = 0; TaskFastIntr("s4285_de0"); switch(rx_mode&0x00F0) { case RX_75_BPS: case RX_150_BPS: case RX_300_BPS: case RX_600_BPS: for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); TaskFastIntr("s4285_de0_d0"); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); TaskFastIntr("s4285_de0_p0"); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); TaskFastIntr("s4285_de0_d1"); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); TaskFastIntr("s4285_de0_p1"); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); TaskFastIntr("s4285_de0_d2"); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); TaskFastIntr("s4285_de0_p2"); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); TaskFastIntr("s4285_de0_d3"); rx_scramble_count++; symbol_offset +=2; } break; case RX_1200_BPS: for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); rx_scramble_count++; symbol_offset +=2; } break; case RX_2400_BPS: for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { equalize_data( &in[symbol_offset] ); rx_scramble_count++; symbol_offset +=2; } break; case RX_1200U_BPS: for( i = 0; i < DATA_LENGTH ; i++ ) { data[data_offset++] = equalize_data( &in[symbol_offset] ).data; rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { data[data_offset++] = equalize_data( &in[symbol_offset] ).data; rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { data[data_offset++] = equalize_data( &in[symbol_offset] ).data; rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { data[data_offset++] = equalize_data( &in[symbol_offset] ).data; rx_scramble_count++; symbol_offset +=2; } break; case RX_2400U_BPS: for( i = 0; i < DATA_LENGTH ; i++ ) { dt = equalize_data( &in[symbol_offset] ).data; data[data_offset++] = dt&2?1:0; data[data_offset++] = dt&1?1:0; rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { dt = equalize_data( &in[symbol_offset] ).data; data[data_offset++] = dt&2?1:0; data[data_offset++] = dt&1?1:0; rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { dt = equalize_data( &in[symbol_offset] ).data; data[data_offset++] = dt&2?1:0; data[data_offset++] = dt&1?1:0; rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { dt = equalize_data( &in[symbol_offset] ).data; data[data_offset++] = dt&2?1:0; data[data_offset++] = dt&1?1:0; rx_scramble_count++; symbol_offset +=2; } break; case RX_3600U_BPS: for( i = 0; i < DATA_LENGTH ; i++ ) { dt = equalize_data( &in[symbol_offset] ).data; data[data_offset++] = dt&4?1:0; data[data_offset++] = dt&2?1:0; data[data_offset++] = dt&1?1:0; rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { dt = equalize_data( &in[symbol_offset] ).data; data[data_offset++] = dt&4?1:0; data[data_offset++] = dt&2?1:0; data[data_offset++] = dt&1?1:0; rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { dt = equalize_data( &in[symbol_offset] ).data; data[data_offset++] = dt&4?1:0; data[data_offset++] = dt&2?1:0; data[data_offset++] = dt&1?1:0; rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < PROBE_LENGTH ; i++ ) { equalize_train( &in[symbol_offset], scrambler_train_table[rx_scramble_count] ); rx_scramble_count++; symbol_offset +=2; } for( i = 0; i < DATA_LENGTH ; i++ ) { dt = equalize_data( &in[symbol_offset] ).data; data[data_offset++] = dt&4?1:0; data[data_offset++] = dt&2?1:0; data[data_offset++] = dt&1?1:0; rx_scramble_count++; symbol_offset +=2; } break; default: break; } /* De-interleave if required */ TaskFastIntr("s4285_de1"); int do_viterbi = 0; if (do_viterbi) { if( (rx_mode&0x00F0) <= RX_2400_BPS ) { for( i = 0 ; i < soft_index; i++ ) sd[i] = deinterleave( sd[i] ); } /* Error correct and pack for output */ TaskFastIntr("s4285_de2"); switch( rx_mode&0x00F0) { case RX_75_BPS: /* 75 Baud */ for( i = 0; i<DATA_LENGTH/4; i++ ) { a = (sd[i*16]+sd[(i*16)+2]+sd[(i*16)+4]+sd[(i*16)+6]+sd[(i*16)+8]+sd[(i*16)+10]+sd[(i*16)+12]+sd[(i*16)+14])/8; b = (sd[(i*16)+1]+sd[(i*16)+3]+sd[(i*16)+5]+sd[(i*16)+7]+sd[(i*16)+9]+sd[(i*16)+11]+sd[(i*16)+13]+sd[(i*16)+15])/8; data[data_offset++] = viterbi_decode( a, b ); } break; case RX_150_BPS: /* 150 Baud */ for( i = 0; i<DATA_LENGTH/2; i++ ) { a = (sd[i*8]+sd[(i*8)+2]+sd[(i*8)+4]+sd[(i*8)+6])/4; b = (sd[(i*8)+1]+sd[(i*8)+3]+sd[(i*8)+5]+sd[(i*8)+7])/4; data[data_offset++] = viterbi_decode( a, b ); } break; case RX_300_BPS: /* 300 Baud */ for( i = 0; i<DATA_LENGTH; i++ ) { a = (sd[i*4]+sd[(i*4)+2])/2; b = (sd[(i*4)+1]+sd[(i*4)+3])/2; data[data_offset++] = viterbi_decode( a, b ); } break; case RX_600_BPS: /* 600 Baud */ for( i = 0; i<DATA_LENGTH*2; i++ ) { data[data_offset++] = viterbi_decode( sd[i*2],sd[(i*2)+1]); TaskFastIntr("s4285_de2_vd"); } break; case RX_1200_BPS: /* 1200 Baud */ for( i = 0; i<DATA_LENGTH*4; i++ ) { data[data_offset++] = viterbi_decode( sd[i*2],sd[(i*2)+1]); } break; case RX_2400_BPS: /* 2400 */ for( i = 0; i<DATA_LENGTH*8; i++ ) { data[data_offset++] = viterbi_decode( sd[(i*2)],sd[(i*2)+1]); } break; case RX_1200U_BPS: break; case RX_2400U_BPS: break; case RX_3600U_BPS: break; default: break; } } TaskFastIntr("s4285_de3"); // Output data for( i = 0; i < data_offset; i++ ) { output_data[output_offset] = data[i]; output_offset++; if (output_offset == OUTPUT_DATA_LENGTH) { //printf("s4285 WARNING: output_data overflow\n"); output_offset = 0; } } TaskFastIntr("s4285_de4"); }
int main(int argc, char **argv) { viterbi_t dec; convcoder_t cod; modem_table_t modem; demod_soft_t demod; int frame_cnt; float *llr; char *data_tx, *data_rx, *symbols; cf_t *iq; int i; parse_args(argc,argv); if (!seed) { seed = time(NULL); } srand(seed); int coded_length = 3 * (frame_length + ((tail_biting)?0:6)); printf("Convolutional Code 1/3 K=7 Test\n"); printf(" Frame length: %d\n", frame_length); printf(" Codeword length: %d\n", coded_length); printf(" Tail bitting: %s\n", tail_biting?"yes":"no"); printf(" EbNo: %.2f\n", ebno_db); data_tx = malloc(frame_length * sizeof(char)); if (!data_tx) { perror("malloc"); exit(-1); } data_rx = malloc(frame_length * sizeof(char)); if (!data_rx) { perror("malloc"); exit(-1); } symbols = malloc(coded_length * sizeof(char)); if (!symbols) { perror("malloc"); exit(-1); } llr = malloc(coded_length * sizeof(float)); if (!llr) { perror("malloc"); exit(-1); } iq = malloc(coded_length * sizeof(cf_t)); if (!iq) { perror("malloc"); exit(-1); } cod.K = 7; cod.R = 3; cod.tail_biting = tail_biting; cod.framelength = frame_length; cod.poly[0] = 0x6D; cod.poly[1] = 0x4F; cod.poly[2] = 0x57; float var = sqrt(pow(10,-ebno_db/10)); modem_table_init(&modem); modem_table_std(&modem, LTE_QPSK, true); demod_soft_init(&demod); demod_soft_table_set(&demod, &modem); demod_soft_alg_set(&demod, APPROX); demod_soft_sigma_set(&demod, var); viterbi_init(&dec, viterbi_37, cod.poly, frame_length, tail_biting); /* read all file or nof_frames */ frame_cnt = 0; unsigned int errors=0; while (frame_cnt < nof_slots) { /* generate data_tx */ for (i=0;i<frame_length;i++) { data_tx[i] = message[i]; } convcoder_encode(&cod, data_tx, symbols); bit_fprint(stdout, symbols, 120); mod_modulate(&modem, symbols, iq, coded_length); if (ebno_db < 100.0) { ch_awgn(iq, iq, var, coded_length/2); } demod_soft_demodulate(&demod, iq, llr, coded_length/2); viterbi_decode(&dec, llr, data_rx); errors += bit_diff(data_tx, data_rx, frame_length); frame_cnt++; } printf("BER:\t%g\t%u errors\n", (float) errors/(frame_cnt*frame_length), errors); viterbi_free(&dec); free(data_tx); free(symbols); free(iq); free(llr); free(data_rx); printf("Done\n"); exit(0); }
/* segment using HMM and then histogram clustering */ void cluster_segment(int* q, double** features, int frames_read, int feature_length, int nHMM_states, int histogram_length, int nclusters, int neighbour_limit) { int i, j; /*****************************/ if (0) { /* try just using the predominant bin number as a 'decoded state' */ nHMM_states = feature_length + 1; /* allow a 'zero' state */ double chroma_thresh = 0.05; double maxval; int maxbin; for (i = 0; i < frames_read; i++) { maxval = 0; for (j = 0; j < feature_length; j++) { if (features[i][j] > maxval) { maxval = features[i][j]; maxbin = j; } } if (maxval > chroma_thresh) q[i] = maxbin; else q[i] = feature_length; } } if (1) { /*****************************/ /* scale all the features to 'balance covariances' during HMM training */ double scale = 10; for (i = 0; i < frames_read; i++) for (j = 0; j < feature_length; j++) features[i][j] *= scale; /* train an HMM on the features */ /* create a model */ model_t* model = hmm_init(features, frames_read, feature_length, nHMM_states); /* train the model */ hmm_train(features, frames_read, model); /* printf("\n\nafter training:\n"); hmm_print(model); */ /* decode the hidden state sequence */ viterbi_decode(features, frames_read, model, q); hmm_close(model); /*****************************/ } /*****************************/ /* fprintf(stderr, "HMM state sequence:\n"); for (i = 0; i < frames_read; i++) fprintf(stderr, "%d ", q[i]); fprintf(stderr, "\n\n"); */ /* create histograms of states */ double* h = (double*) malloc(frames_read*nHMM_states*sizeof(double)); /* vector in row major order */ create_histograms(q, frames_read, nHMM_states, histogram_length, h); /* cluster the histograms */ int nbsched = 20; /* length of inverse temperature schedule */ double* bsched = (double*) malloc(nbsched*sizeof(double)); /* inverse temperature schedule */ double b0 = 100; double alpha = 0.7; bsched[0] = b0; for (i = 1; i < nbsched; i++) bsched[i] = alpha * bsched[i-1]; cluster_melt(h, nHMM_states, frames_read, bsched, nbsched, nclusters, neighbour_limit, q); /* now q holds a sequence of cluster assignments */ free(h); free(bsched); }
void Decoder::decode(Instance * inst) { init_lattice(inst); viterbi_decode(inst); get_result(inst); free_lattice(); }