void test_interleaving() { //This part tests interleaving uint8_t message[51]; uint8_t check_message[51]; unsigned int i; for(i = 0; i < 51; i++) message[i] = rand(); memcpy(check_message, message, 51); raw_data rd; rd.length = 51; rd.data = message; for(i = 0; i < 51; i++) printf("%x ", rd.data[i] & 0xff); printf("\n"); interleave(rd); for(i = 0; i < 51; i++) printf("%x ", rd.data[i] & 0xff); printf("\n"); deinterleave(rd); for(i = 0; i < 51; i++) printf("%x ", rd.data[i] & 0xff); printf("\n"); if(!memcmp(message, check_message, 51)) printf("success!\n"); else printf("Failure!\n"); }
bool CDMRTrellis::decode(const unsigned char* data, unsigned char* payload) { assert(data != NULL); assert(payload != NULL); signed char dibits[98U]; deinterleave(data, dibits); unsigned char points[49U]; dibitsToPoints(dibits, points); // Check the original code unsigned char tribits[49U]; unsigned int failPos = checkCode(points, tribits); if (failPos == 999U) { tribitsToBits(tribits, payload); return true; } unsigned char savePoints[49U]; for (unsigned int i = 0U; i < 49U; i++) savePoints[i] = points[i]; bool ret = fixCode(points, failPos, payload); if (ret) return true; if (failPos == 0U) return false; // Backtrack one place for a last go return fixCode(savePoints, failPos - 1U, payload); }
char* x123_decode(const char* in_str, const char* key, char* out_str) { Cdbg(DBE, "in_str=%s, key=%s", in_str, key); char* ibinstr; hexstr2binstr( in_str, &ibinstr ); //Cdbg(DBE, "ibinstr=%s", ibinstr); char* binstr; deinterleave( ibinstr, 8, &binstr ); //Cdbg(DBE, "deinterleave, binstr=%s", binstr); int shiftamount = getshiftamount( key, binstr ); //Cdbg(DBE, "shiftamount %d %s", shiftamount, key); char* unshiftbinstr; strleftshift( binstr, shiftamount, &unshiftbinstr ); //Cdbg(DBE, "unshiftbinstr %s", unshiftbinstr); binstr2str(unshiftbinstr, &out_str); Cdbg(DBE, "out_str %s", out_str); free(ibinstr); free(binstr); free(unshiftbinstr); return out_str; }
std::vector<unsigned int> crypto::VigenereCipher::keyLengthGuesses(const std::string& message) { std::vector<unsigned int> result (message.size()); std::iota(result.begin(), result.end(), 1); std::sort(result.begin(), result.end(), [&message](const unsigned int& x, const unsigned int& y) { auto xd = deinterleave(x, message); auto yd = deinterleave(y, message); crypto::prob_t xSLP = 0, ySLP = 0; for (const auto& i : xd) xSLP += crypto::sameLetterProbability(crypto::frequencyAnalysis(i)); xSLP /= x; for (const auto& i : yd) ySLP += crypto::sameLetterProbability(crypto::frequencyAnalysis(i)); ySLP /= y; return std::abs(xSLP - averageEnglishSLP) < std::abs(ySLP - averageEnglishSLP); }); return result; }
void print_frame() { int i; int nib = 0; int frid = -1; manchester1(frame_rawbits, frame_bits); deinterleave(frame_bits+CONF, 7, hamming_conf); deinterleave(frame_bits+DAT1, 13, hamming_dat1); deinterleave(frame_bits+DAT2, 13, hamming_dat2); hamming(hamming_conf, 7, block_conf); hamming(hamming_dat1, 13, block_dat1); hamming(hamming_dat2, 13, block_dat2); if (option_raw == 1) { for (i = 0; i < 7; i++) { nib = bits2val(block_conf+S*i, S); printf("%01X", nib & 0xFF); } printf(" "); for (i = 0; i < 13; i++) { nib = bits2val(block_dat1+S*i, S); printf("%01X", nib & 0xFF); } printf(" "); for (i = 0; i < 13; i++) { nib = bits2val(block_dat2+S*i, S); printf("%01X", nib & 0xFF); } printf("\n"); } else { conf_out(block_conf); frid = dat_out(block_dat1); if (frid == 8) print_gpx(); frid = dat_out(block_dat2); if (frid == 8) print_gpx(); } }
void decode_data(uint8_t raw[RAW_SIZE], uint8_t data[DATA_SIZE], int8_t error[2]) { uint8_t conv[CONV_SIZE]; uint8_t dec_data[RS_SIZE]; uint8_t rs[2][RS_BLOCK_SIZE]; deinterleave(raw, conv); viterbi(conv, dec_data); descramble_and_deinterleave(dec_data, rs); rs_decode(rs, data, error); }
void decode_data_debug( uint8_t raw[RAW_SIZE], // Data to be decoded, 5200 byte (soft bit format) uint8_t data[DATA_SIZE], // Decoded data, 256 byte int8_t error[2], // RS decoder modules corrected errors or -1 if unrecoverable error happened uint8_t conv[CONV_SIZE], // Deinterleaved data with SYNC removed (5132 byte, soft bit format) uint8_t dec_data[RS_SIZE], // Viterbi decoder output (320 byte): two RS codeblock interleaved and scrambled(!) uint8_t rs[2][RS_BLOCK_SIZE] // RS codeblocks without the leading padding 95 zeros ) { deinterleave(raw, conv); viterbi(conv, dec_data); descramble_and_deinterleave(dec_data, rs); rs_decode(rs, data, error); }
std::vector<crypto::VigenereCipher> crypto::VigenereCipher::bestGuesses(const std::string& message, const std::vector<char>& alphabet) { std::vector<crypto::VigenereCipher> result; std::vector<unsigned int> allShifts (alphabet.size()); std::iota(allShifts.begin(), allShifts.end(), 0); auto keyLengths = crypto::VigenereCipher::keyLengthGuesses(message); while (keyLengths.size() > 3) keyLengths.pop_back(); const unsigned int maxBadness = 2; std::vector<unsigned int> validIndices (maxBadness+1); std::iota(validIndices.begin(), validIndices.end(), 0); std::vector<std::string> deinterleaved; std::vector<std::vector<unsigned int>>* shiftGuesses; std::vector<std::vector<unsigned int>> choiceIndices; std::string* key; for (auto i : keyLengths) { deinterleaved = deinterleave(i, message); shiftGuesses = new std::vector<std::vector<unsigned int>>; for (auto j : deinterleaved) { std::sort(allShifts.begin(), allShifts.end(), [&alphabet,&j](const unsigned int& s1, const unsigned int& s2) { return crypto::frequencyDistance(crypto::frequencyAnalysis(crypto::AffineCipher(alphabet, 1, s1).decrypt(j)), crypto::averageEnglishFrequency) < crypto::frequencyDistance(crypto::frequencyAnalysis(crypto::AffineCipher(alphabet, 1, s2).decrypt(j)), crypto::averageEnglishFrequency); }); shiftGuesses->push_back(allShifts); } choiceIndices = allVectors(validIndices, i); std::sort(choiceIndices.begin(), choiceIndices.end(), [](const std::vector<unsigned int>& v1, const std::vector<unsigned int>& v2) { auto totalBad1 = v1.size() - std::count(v1.begin(), v1.end(), 0); auto totalBad2 = v2.size() - std::count(v2.begin(), v2.end(), 0); if (totalBad1 != totalBad2) return totalBad1 < totalBad2; auto totalBadness1 = std::accumulate(v1.begin(), v1.end(), 0); auto totalBadness2 = std::accumulate(v2.begin(), v2.end(), 0); if (totalBadness1 != totalBadness2) return totalBadness1 < totalBadness2; auto maxBadness1 = *std::max_element(v1.begin(), v1.end()); auto maxBadness2 = *std::max_element(v2.begin(), v2.end()); return maxBadness1 < maxBadness2; }); for (auto j : choiceIndices) { key = new std::string; for (unsigned int k = 0; k < i; ++k) key->push_back(alphabet[(*shiftGuesses)[k][j[k]]]); result.push_back(crypto::VigenereCipher(alphabet, *key)); delete key; } delete shiftGuesses; } return result; }
int paCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void * userData ){ AudioIO& io = *(AudioIO *)userData; const float * paI = (const float *)input; float * paO = (float *)output; bool bDeinterleave = true; if(bDeinterleave){ deinterleave(const_cast<float *>(&io.in(0,0)), paI, io.framesPerBuffer(), io.channelsInDevice() ); //deinterleave(&io.out(0,0), paO, io.framesPerBuffer(), io.channelsOutDevice()); } if(io.autoZeroOut()) io.zeroOut(); io(); // call callback // kill pesky nans so we don't hurt anyone's ears if(io.zeroNANs()){ for(int i=0; i<io.framesPerBuffer()*io.channelsOutDevice(); ++i){ float& s = (&io.out(0,0))[i]; if(isnan(s)) s = 0.f; } } if(io.clipOut()){ for(int i=0; i<io.framesPerBuffer()*io.channelsOutDevice(); ++i){ float& s = (&io.out(0,0))[i]; if (s<-1.f) s =-1.f; else if (s> 1.f) s = 1.f; } } if(bDeinterleave){ interleave(paO, &io.out(0,0), io.framesPerBuffer(), io.channelsOutDevice()); } return 0; }
// OK void test_interleave(){ int h = 5; int w = 8; int lm = h*w; int* map_out = (int*) malloc(sizeof(int)*lm); int** arr = new2d<int>(h,w); int* tmp = (int*) malloc(sizeof(int)*lm); for(int idx = 0 ; idx < 5 ; ++idx){ printf("original matrix:\n"); for(int i = 0 ; i < h ; ++i){ for(int j = 0 ; j < w ; ++j){ arr[i][j] = rand()%lm; printf("%d\t",arr[i][j]); } printf("\n"); } printf("\n\nrandom map:\n"); random_sequence(0,lm-1,map_out); for(int i = 0 ; i < lm ; ++i){ printf("%d ",map_out[i]); tmp[i] = arr[map_out[i]/w][map_out[i]%w]; } printf("\n\nmatrix after deinterleave:\n"); deinterleave(tmp,map_out,lm); for(int i = 0 ; i < h ; ++i){ for(int j = 0 ; j < w ; ++j){ printf("%d\t",tmp[i*w+j]); } printf("\n"); } printf("\n\n"); } free(map_out); delete2d<int>(arr); free(tmp); }
static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref) { AResampleContext *aresample = inlink->dst->priv; AVFilterLink * const outlink = inlink->dst->outputs[0]; int i, in_nb_samples = insamplesref->audio->nb_samples, cached_nb_samples = in_nb_samples + aresample->unconsumed_nb_samples, requested_out_nb_samples = aresample->ratio * cached_nb_samples, nb_channels = av_get_channel_layout_nb_channels(inlink->channel_layout); if (cached_nb_samples > aresample->max_cached_nb_samples) { for (i = 0; i < nb_channels; i++) { aresample->cached_data[i] = av_realloc(aresample->cached_data[i], cached_nb_samples * sizeof(int16_t)); aresample->resampled_data[i] = av_realloc(aresample->resampled_data[i], FFALIGN(sizeof(int16_t) * requested_out_nb_samples, 16)); if (aresample->cached_data[i] == NULL || aresample->resampled_data[i] == NULL) return; } aresample->max_cached_nb_samples = cached_nb_samples; if (aresample->outsamplesref) avfilter_unref_buffer(aresample->outsamplesref); aresample->outsamplesref = avfilter_get_audio_buffer(outlink, AV_PERM_WRITE, requested_out_nb_samples); outlink->out_buf = aresample->outsamplesref; } avfilter_copy_buffer_ref_props(aresample->outsamplesref, insamplesref); aresample->outsamplesref->audio->sample_rate = outlink->sample_rate; aresample->outsamplesref->pts = av_rescale(outlink->sample_rate, insamplesref->pts, inlink->sample_rate); /* av_resample() works with planar audio buffers */ if (!inlink->planar && nb_channels > 1) { int16_t *out[8]; for (i = 0; i < nb_channels; i++) out[i] = aresample->cached_data[i] + aresample->unconsumed_nb_samples; deinterleave(out, (int16_t *)insamplesref->data[0], nb_channels, in_nb_samples); } else { for (i = 0; i < nb_channels; i++) memcpy(aresample->cached_data[i] + aresample->unconsumed_nb_samples, insamplesref->data[i], in_nb_samples * sizeof(int16_t)); } for (i = 0; i < nb_channels; i++) { int consumed_nb_samples; const int is_last = i+1 == nb_channels; aresample->outsamplesref->audio->nb_samples = av_resample(aresample->resample, aresample->resampled_data[i], aresample->cached_data[i], &consumed_nb_samples, cached_nb_samples, requested_out_nb_samples, is_last); /* move unconsumed data back to the beginning of the cache */ aresample->unconsumed_nb_samples = cached_nb_samples - consumed_nb_samples; memmove(aresample->cached_data[i], aresample->cached_data[i] + consumed_nb_samples, aresample->unconsumed_nb_samples * sizeof(int16_t)); } /* copy resampled data to the output samplesref */ if (!inlink->planar && nb_channels > 1) { interleave((int16_t *)aresample->outsamplesref->data[0], aresample->resampled_data, nb_channels, aresample->outsamplesref->audio->nb_samples); } else { for (i = 0; i < nb_channels; i++) memcpy(aresample->outsamplesref->data[i], aresample->resampled_data[i], aresample->outsamplesref->audio->nb_samples * sizeof(int16_t)); } avfilter_filter_samples(outlink, avfilter_ref_buffer(aresample->outsamplesref, ~0)); avfilter_unref_buffer(insamplesref); }
int paCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void * userData ) { AudioIO& io = *(AudioIO *)userData; const float * paI = (const float *)input; float * paO = (float *)output; bool bDeinterleave = true; if(bDeinterleave) { deinterleave(const_cast<float *>(&io.in(0,0)), paI, io.framesPerBuffer(), io.channelsInDevice() ); //deinterleave(&io.out(0,0), paO, io.framesPerBuffer(), io.channelsOutDevice()); } if(io.autoZeroOut()) io.zeroOut(); io.processAudio(); // call callback // apply smoothly-ramped gain to all output channels if(io.usingGain()) { float dgain = (io.mGain-io.mGainPrev) / io.framesPerBuffer(); for(int j=0; j<io.channelsOutDevice(); ++j) { float * out = io.outBuffer(j); float gain = io.mGainPrev; for(int i=0; i<io.framesPerBuffer(); ++i) { out[i] *= gain; gain += dgain; } } io.mGainPrev = io.mGain; } // kill pesky nans so we don't hurt anyone's ears if(io.zeroNANs()) { for(int i=0; i<io.framesPerBuffer()*io.channelsOutDevice(); ++i) { float& s = (&io.out(0,0))[i]; //if(isnan(s)) s = 0.f; if(s != s) s = 0.f; // portable isnan; only nans do not equal themselves } } if(io.clipOut()) { for(int i=0; i<io.framesPerBuffer()*io.channelsOutDevice(); ++i) { float& s = (&io.out(0,0))[i]; if (s<-1.f) s =-1.f; else if (s> 1.f) s = 1.f; } } if(bDeinterleave) { interleave(paO, &io.out(0,0), io.framesPerBuffer(), io.channelsOutDevice()); } return 0; }
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"); }
/** Return the bounding box of the box with Morton codes @a cmin and @a cmax. * @pre cmin,cmax < end_code */ BoundingBox<point_type> cell(code_type cmin, code_type cmax) const { return BoundingBox<point_type>(pmin_ + cell_size_ * deinterleave(cmin), pmin_ + cell_size_ *(deinterleave(cmax)+1)); }
/** Return the center of the box with Morton codes @a cmin and @a cmax. * @pre cmin,cmax < end_code */ point_type center(code_type cmin, code_type cmax) const { return pmin_ + (cell_size_/2)*(deinterleave(cmax)+deinterleave(cmin)+1); }
//tests the methods used encoding and decoding, uses insert_errors2 to accomodate any bit rate float message_pass_rate(int num_tests, float BER) { int successes = 0; int errors = 0; int tries = 0; int wrong1 = 0, wrong2 = 0; //for(unsigned int i = 0; i < num_tests; i++) while(errors < 100) { raw_data rd; rd.length = 64; rd.data = (uint8_t*)alloc_named(rd.length, "message_pass_rate rd"); unsigned int i; for(i = 0; i < 64; i++) rd.data[i] = rand(); int t = 2; //PYTHON// //p = make_packet(rd); //encoded_packet ep = encode(&p); //currently convolutional- subject to change raw_data rs_encoded = rs_encode(rd, t); raw_data ep = convolute(rs_encoded); interleave(ep); //interleaves data in place insert_errors2(ep.data, ep.length, BER); deinterleave(ep); raw_data deconvoluted = deconvolute(ep, NULL); int isc = is_correctible(rs_encoded, deconvoluted, t, 0); raw_data decoded; rs_decode(deconvoluted, &decoded, t, NULL); //q = decode(ep, NULL); if(rd.length != decoded.length) { printf("lengths are not the same!\n"); printf("rd.length = %i, decoded.length = %i\n", rd.length, decoded.length); } if(!memcmp(decoded.data, rd.data, rd.length)) { if(!isc) wrong1++; //if(!isc) // is_correctible(rs_encoded, deconvoluted, t, 1); //assert(isc); successes++; } else { if(isc) wrong2++; //assert(!isc); errors++; } dealloc(ep.data); dealloc(rs_encoded.data); dealloc(deconvoluted.data); dealloc(decoded.data); dealloc(rd.data); if(tries >= num_tests) { printf("tries = %i, errors = %i\n", tries, errors); break; } tries++; } //return (float)successes / (float)num_tests; printf("wrong1 = %i\n", wrong1); printf("wrong2 = %i\n", wrong2); printf("tests = %i\n", successes + errors); return (float)successes / ((float)successes + (float)errors); }
Int huffspec_fxp( FrameInfo *pFrameInfo, BITS *pInputStream, Int nsect, SectInfo *pSectInfo, Int factors[], Int32 coef[], Int16 quantSpec[], Int16 tmp_spec[], const FrameInfo *pLongFrameInfo, PulseInfo *pPulseInfo, Int qFormat[]) { /*---------------------------------------------------------------------------- ; Define all local variables ----------------------------------------------------------------------------*/ const Hcb *pHcb; Int i; Int sfb; Int idx_count; Int sect_cb; /* section codebook */ Int dim; Int idx; Int stop_idx; /* index of 1st coef in next sfb */ Int sect_start; /* start index of sfb in one section*/ Int sect_end; /* index of 1st sfb in next section */ Int *pSfbStart; Int *pSfb; Int16 *pQuantSpec; /* probably could be short */ Int max = 0; /* rescaling parameters */ Int nsfb; Int tot_sfb; Int fac; Int32 *pCoef; /* ptr to coef[], inverse quantized coefs */ UInt16 scale; Int power_scale_div_4; Int sfbWidth; void (*pUnpack_idx)( Int16 quant_spec[], Int codeword_indx, const Hcb *pHuffCodebook, BITS *pInputStream, Int *max); Int(*pDec_huff_tab)(BITS *) = NULL; UInt32 temp; Int binaryDigits, QFormat; /*---------------------------------------------------------------------------- ; Function body here ----------------------------------------------------------------------------*/ sect_start = 0; stop_idx = 0; /* pSfb: ptr to array that holds stop index of each sfb */ pSfbStart = pFrameInfo->frame_sfb_top; // 2010.01.11 : // nsect can be 0 if (pSfbStart == NULL) { return (-1); /* error condition */ } pSfb = pSfbStart; /* decoding spectral values section by section */ for (i = nsect; i > 0; i--) { /* read the codebook and section length */ sect_cb = pSectInfo->sect_cb; /* codebook */ if ((sect_cb > 15) || (sect_cb < 0)) { return (-1); /* error condition */ } sect_end = pSectInfo->sect_end; /* # of sfbs */ if (sect_end < 0) { return (-1); /* error condition */ } pSectInfo++; /* sect_cb sect_cb - 1 * ZERO_HCB 1111b * 1 0000b * 2 0001b * 3 0010b * 4 0011b * 5 0100b * 6 0101b * 7 0110b * 8 0111b * 9 1000b * 10 1001b * 11 1010b * 12 1011b * NOISE_HCB 1100b * INTENSITY_HCB2 1101b * INTENSITY_HCB 1110b * if ( ((sect_cb - 1) & 0xC) == 0xC ) is identical to * if !((sect_cb == ZERO_HCB) || (sect_cb == NOISE_HCB) || * (sec_cb == INTENSITY_HCB) || (sect_cb==INTENSITY_HCB2) ) * use this compare scheme to speed up the execution */ if (((sect_cb - 1) & 0xC) != 0xC) { /* decode spec in one section */ if (sect_cb > BY4BOOKS) { dim = DIMENSION_2; /* set codebook dimension */ } else { dim = DIMENSION_4; } pHcb = &hcbbook_binary[sect_cb]; if (sect_cb == ESCBOOK) { pUnpack_idx = &unpack_idx_esc; } else if (pHcb->signed_cb == FALSE) { pUnpack_idx = &unpack_idx_sgn; } else { pUnpack_idx = &unpack_idx; } switch (sect_cb) { case 1: pDec_huff_tab = decode_huff_cw_tab1; break; case 2: pDec_huff_tab = decode_huff_cw_tab2; break; case 3: pDec_huff_tab = decode_huff_cw_tab3; break; case 4: pDec_huff_tab = decode_huff_cw_tab4; break; case 5: pDec_huff_tab = decode_huff_cw_tab5; break; case 6: pDec_huff_tab = decode_huff_cw_tab6; break; case 7: pDec_huff_tab = decode_huff_cw_tab7; break; case 8: pDec_huff_tab = decode_huff_cw_tab8; break; case 9: pDec_huff_tab = decode_huff_cw_tab9; break; case 10: pDec_huff_tab = decode_huff_cw_tab10; break; case 11: pDec_huff_tab = decode_huff_cw_tab11; break; default: return (-1); /* error condition */ } /* move ptr to first sfb of current section */ pQuantSpec = quantSpec + stop_idx; /* step through all sfbs in current section */ for (sfb = sect_start; sfb < sect_end; sfb++) { idx_count = *pSfb - stop_idx; stop_idx = *pSfb++; /* decode all coefs for one sfb */ while ((idx_count > 0) && (idx_count < 1024)) { idx = (*pDec_huff_tab)(pInputStream); (*pUnpack_idx)(pQuantSpec, idx, pHcb, pInputStream, &max); /* unpack idx -> coefs */ pQuantSpec += dim; idx_count -= dim; } /* while(idx_count) */ } /* for (sfb=sect_start) */ } else { /* current section uses ZERO_HCB, NOISE_HCB, etc */ /* move sfb pointer to the start sfb of next section */ pSfb = pSfbStart + sect_end; /* number of coefs in current section */ idx_count = *(pSfb - 1) - stop_idx; if ((idx_count > 1024) || (idx_count < 0)) { return (-1); /* error condition */ } /* * This memset is necessary in terms of (1) net savings in total * MIPS and (2) accurate Q-Formats for fft_rx2 * In case a scalefactor band uses ZERO_HCB, all coefficients of * that sfb should be zeros. Without this call to memset, the * coefficients for a ZERO_HCB sfb are the "leftovers" of the * previous frame, which may not have all zero values. This leads * to a drastical increase in the cycles consumed by esc_iquant_fxp * and fft_rx2, which is the most "expensive" function of the * library. * This memset also guarantees the Q_Format for sfbs with all zero * coefficients will be set properly. * Profiling data on ARM and TMS320C55x proves that there is a net * gain in total MIPS if a memset is called here. */ pv_memset(&quantSpec[stop_idx], 0, idx_count * sizeof(quantSpec[0])); /* * This memset is called because pQuantSpec points to tmp_spec * after deinterleaving */ pv_memset(&tmp_spec[stop_idx], 0, idx_count * sizeof(tmp_spec[0])); /* stop_idx is the index of the 1st coef of next section */ stop_idx = *(pSfb - 1); }/* if (sect_cb) */ sect_start = sect_end; } /* for (i=nsect) */ /* noisless coding reconstruction */ if (pFrameInfo->islong != FALSE) { if (pPulseInfo->pulse_data_present == 1) { pulse_nc(quantSpec, pPulseInfo, pLongFrameInfo, &max); /* add pulse data */ } pQuantSpec = quantSpec; } else { deinterleave(quantSpec, tmp_spec, pFrameInfo); pQuantSpec = tmp_spec; } /* inverse quantization, Q_format: Int32 */ /* rescaling */ /* what we can do here is assuming that we already know maxInput for each band, we have to go though each one of them for re-quant and scaling, and pick the right qFormat to apply to all spectral coeffs.*/ if ((max < 0) || (max > 8192)) /* (8192>>ORDER) == 1024 is the inverseQuantTable size */ { return (-1); /* error condition */ } else { /* Get (max/SPACING) ^ (1/3), in Q Format */ temp = inverseQuantTable[(max >> ORDER) + 1]; } /* Round up before shifting down to Q0 */ temp += ROUND_UP; /* shift down to Q0 and multiply by 2 (FACTOR) in one step */ temp >>= (QTABLE - 1); /* Now get max ^ (4/3) in Q0 */ temp *= max; binaryDigits = 31 - pv_normalize(temp); /* Prevent negative shifts caused by low maximums. */ if (binaryDigits < (SIGNED32BITS - QTABLE)) { binaryDigits = SIGNED32BITS - QTABLE; } QFormat = SIGNED32BITS - binaryDigits; /********************/ tot_sfb = 0; nsfb = pFrameInfo->sfb_per_win[0]; pCoef = coef; for (i = pFrameInfo->num_win; i > 0; i--) { stop_idx = 0; for (sfb = 0; sfb < nsfb; sfb++) { sfbWidth = pFrameInfo->win_sfb_top[0][sfb] - stop_idx; if ((sfbWidth < 0) || (sfbWidth > 1024)) { return (-1); /* error condition */ } stop_idx += sfbWidth; fac = factors[tot_sfb] - SF_OFFSET; scale = exptable[fac & 0x3]; power_scale_div_4 = fac >> 2; power_scale_div_4++; qFormat[tot_sfb] = QFormat; esc_iquant_scaling(pQuantSpec, pCoef, sfbWidth, QFormat, scale, max); pQuantSpec += sfbWidth; qFormat[tot_sfb] -= power_scale_div_4; pCoef += sfbWidth; tot_sfb++; } /* for (sfb) */ } /* for (i) */ /*---------------------------------------------------------------------------- ; Return status ----------------------------------------------------------------------------*/ return SUCCESS; } /* huffspec_fxp */
JNIEXPORT bool JNICALL Java_com_example_helloandroidcamera2_JNIUtils_blit( JNIEnv *env, jobject obj, jint srcWidth, jint srcHeight, jobject srcLumaByteBuffer, jint srcLumaRowStrideBytes, jobject srcChromaUByteBuffer, jobject srcChromaVByteBuffer, jint srcChromaElementStrideBytes, jint srcChromaRowStrideBytes, jobject dstSurface) { if (srcChromaElementStrideBytes != 1 && srcChromaElementStrideBytes != 2) { return false; } uint8_t *srcLumaPtr = reinterpret_cast<uint8_t *>( env->GetDirectBufferAddress(srcLumaByteBuffer)); uint8_t *srcChromaUPtr = reinterpret_cast<uint8_t *>( env->GetDirectBufferAddress(srcChromaUByteBuffer)); uint8_t *srcChromaVPtr = reinterpret_cast<uint8_t *>( env->GetDirectBufferAddress(srcChromaVByteBuffer)); if (srcLumaPtr == nullptr || srcChromaUPtr == nullptr || srcChromaVPtr == nullptr) { return false; } // Check that if src chroma channels are interleaved if element stride is 2. // Our Halide kernel "directly deinterleaves" UVUVUVUV --> UUUU, VVVV // to handle VUVUVUVU, just swap the destination pointers. uint8_t *srcChromaUVInterleavedPtr = nullptr; bool swapDstUV; if (srcChromaElementStrideBytes == 2) { if (srcChromaVPtr - srcChromaUPtr == 1) { srcChromaUVInterleavedPtr = srcChromaUPtr; // UVUVUV... swapDstUV = false; } else if (srcChromaUPtr - srcChromaVPtr == 1) { srcChromaUVInterleavedPtr = srcChromaVPtr; // VUVUVU... swapDstUV = true; } else { // stride is 2 but the pointers are not off by 1. return false; } } ANativeWindow *win = ANativeWindow_fromSurface(env, dstSurface); ANativeWindow_acquire(win); ANativeWindow_Buffer buf; if (int err = ANativeWindow_lock(win, &buf, NULL)) { LOGE("ANativeWindow_lock failed with error code %d\n", err); ANativeWindow_release(win); return false; } ANativeWindow_setBuffersGeometry(win, srcWidth, srcHeight, 0 /*format unchanged*/); if (buf.format != IMAGE_FORMAT_YV12) { LOGE("ANativeWindow buffer locked but its format was not YV12."); ANativeWindow_unlockAndPost(win); ANativeWindow_release(win); return false; } if (!checkBufferSizesMatch(srcWidth, srcHeight, &buf)) { LOGE("ANativeWindow buffer locked but its size was %d x %d, expected " "%d x %d", buf.width, buf.height, srcWidth, srcHeight); ANativeWindow_unlockAndPost(win); ANativeWindow_release(win); return false; } int32_t srcChromaWidth = srcWidth / 2; int32_t srcChromaHeight = srcHeight / 2; // This is guaranteed by the YV12 format, see android.graphics.ImageFormat. uint8_t *dstLumaPtr = reinterpret_cast<uint8_t *>(buf.bits); uint32_t dstLumaRowStrideBytes = buf.stride; uint32_t dstLumaSizeBytes = dstLumaRowStrideBytes * buf.height; uint32_t dstChromaRowStrideBytes = ALIGN(buf.stride / 2, 16); // Size of one chroma plane. uint32_t dstChromaSizeBytes = dstChromaRowStrideBytes * buf.height / 2; // Yes, V is actually first. uint8_t *dstChromaVPtr = dstLumaPtr + dstLumaSizeBytes; uint8_t *dstChromaUPtr = dstLumaPtr + dstLumaSizeBytes + dstChromaSizeBytes; // Copy over the luma channel. // If strides match, then it's a single copy. if (srcLumaRowStrideBytes == dstLumaRowStrideBytes) { memcpy(dstLumaPtr, srcLumaPtr, dstLumaSizeBytes); } else { // Else, copy row by row. for (int y = 0; y < srcHeight; y++) { uint8_t *srcLumaRow = srcLumaPtr + y * srcLumaRowStrideBytes; uint8_t *dstLumaRow = dstLumaPtr + y * dstLumaRowStrideBytes; memcpy(dstLumaRow, srcLumaRow, srcLumaRowStrideBytes); } } bool succeeded; // Handle the chroma channels. // If they are not interleaved, then use memcpy. // Otherwise, use Halide to deinterleave. if (srcChromaElementStrideBytes == 1) { // If strides match, then it's a single copy per channel. if (srcChromaRowStrideBytes == dstChromaRowStrideBytes) { memcpy(dstChromaUPtr, srcChromaUPtr, dstChromaSizeBytes); memcpy(dstChromaVPtr, srcChromaVPtr, dstChromaSizeBytes); } else { // Else, copy row by row. for (int y = 0; y < srcHeight; y++) { uint8_t *srcChromaURow = srcChromaUPtr + y * srcChromaRowStrideBytes; uint8_t *dstChromaURow = dstChromaUPtr + y * dstChromaRowStrideBytes; memcpy(dstChromaURow, srcChromaURow, srcChromaRowStrideBytes); } for (int y = 0; y < srcHeight; y++) { uint8_t *srcChromaVRow = srcChromaVPtr + y * srcChromaRowStrideBytes; uint8_t *dstChromaVRow = dstChromaVPtr + y * dstChromaRowStrideBytes; memcpy(dstChromaVRow, srcChromaVRow, srcChromaRowStrideBytes); } } succeeded = true; } else { // Make these static so that we can reuse device allocations across frames. // It doesn't matter now, but useful for GPU backends. static buffer_t srcBuf = { 0 }; static buffer_t dstBuf0 = { 0 }; static buffer_t dstBuf1 = { 0 }; srcBuf.host = srcChromaUVInterleavedPtr; srcBuf.host_dirty = true; srcBuf.extent[0] = 2 * srcChromaWidth; // src is interleaved. srcBuf.extent[1] = srcChromaHeight; srcBuf.extent[2] = 0; srcBuf.extent[3] = 0; srcBuf.stride[0] = 1; srcBuf.stride[1] = 2 * srcChromaWidth; srcBuf.min[0] = 0; srcBuf.min[1] = 0; srcBuf.elem_size = 1; dstBuf0.host = swapDstUV ? dstChromaVPtr : dstChromaUPtr; dstBuf0.extent[0] = srcChromaWidth; // src and dst width and height match. dstBuf0.extent[1] = srcChromaHeight; dstBuf0.extent[2] = 0; dstBuf0.extent[3] = 0; dstBuf0.stride[0] = 1; dstBuf0.stride[1] = dstChromaRowStrideBytes; // Halide stride in pixels but pixel size is 1 byte. dstBuf0.min[0] = 0; dstBuf0.min[1] = 0; dstBuf0.elem_size = 1; dstBuf1.host = swapDstUV ? dstChromaUPtr : dstChromaVPtr; dstBuf1.extent[0] = srcChromaWidth; // src and dst width and height match. dstBuf1.extent[1] = srcChromaHeight; dstBuf1.extent[2] = 0; dstBuf1.extent[3] = 0; dstBuf1.stride[0] = 1; dstBuf1.stride[1] = dstChromaRowStrideBytes; // Halide stride in pixels but pixel size is 1 byte. dstBuf1.min[0] = 0; dstBuf1.min[1] = 0; dstBuf1.elem_size = 1; // Use Halide to deinterleave the chroma channels. int err = deinterleave(&srcBuf, &dstBuf0, &dstBuf1); if (err != halide_error_code_success) { LOGE("deinterleave failed with error code: %d", err); } succeeded = (err != halide_error_code_success); } ANativeWindow_unlockAndPost(win); ANativeWindow_release(win); return succeeded; }
//*************************************************************************** int main(int argc, char *argv[]) { extern char *optarg; extern int optind; int i,j,k; unsigned char *symbols, *decdata; signed char message[]={-9,13,-35,123,57,-39,64,0,0,0,0}; char *callsign,*grid,*grid6, *call_loc_pow, *cdbm; char *ptr_to_infile,*ptr_to_infile_suffix; char uttime[5],date[7]; char xuttime[6],xdate[11]; int c,delta,nfft2=65536,verbose=0,quickmode=0,writenoise=0,usehashtable=1; int shift1, lagmin, lagmax, lagstep, worth_a_try, not_decoded, nadd, ndbm; int32_t n1, n2, n3; unsigned int nbits; unsigned int npoints, metric, maxcycles, cycles, maxnp; float df=375.0/256.0/2; float freq0[200],snr0[200],drift0[200],sync0[200]; int shift0[200]; float dt=1.0/375.0; double dialfreq_cmdline=0.0, dialfreq; float dialfreq_error=0.0; float fmin=-110, fmax=110; float f1, fstep, sync1, drift1, tblank=0, fblank=0; double *idat, *qdat; clock_t t0,t00; double tfano=0.0,treadwav=0.0,tcandidates=0.0,tsync0=0.0; double tsync1=0.0,tsync2=0.0,ttotal=0.0; // Parameters used for performance-tuning: maxcycles=10000; //Fano timeout limit double minsync1=0.10; //First sync limit double minsync2=0.12; //Second sync limit int iifac=3; //Step size in final DT peakup int symfac=45; //Soft-symbol normalizing factor int maxdrift=4; //Maximum (+/-) drift double minrms=52.0 * (symfac/64.0); //Final test for palusible decoding delta=60; //Fano threshold step t00=clock(); fftw_complex *fftin, *fftout; #include "./mettab.c" // Check for an optional FFTW wisdom file FILE *fp_fftw_wisdom_file; if ((fp_fftw_wisdom_file = fopen("fftw_wisdom_wsprd", "r"))) { fftw_import_wisdom_from_file(fp_fftw_wisdom_file); fclose(fp_fftw_wisdom_file); } idat=malloc(sizeof(double)*nfft2); qdat=malloc(sizeof(double)*nfft2); while ( (c = getopt(argc, argv, "b:e:f:Hnqt:wv")) !=-1 ) { switch (c) { case 'b': fblank = strtof(optarg,NULL); break; case 'e': dialfreq_error = strtof(optarg,NULL); // units of Hz // dialfreq_error = dial reading - actual, correct frequency break; case 'f': dialfreq_cmdline = strtod(optarg,NULL); // units of MHz break; case 'H': usehashtable = 0; break; case 'n': writenoise = 1; break; case 'q': quickmode = 1; break; case 't': tblank = strtof(optarg,NULL); break; case 'v': verbose = 1; break; case 'w': fmin=-150.0; fmax=150.0; break; case '?': usage(); return 1; } } if( optind+1 > argc) { usage(); return 1; } else { ptr_to_infile=argv[optind]; } FILE *fall_wspr, *fwsprd, *fhash, *ftimer, *fweb; FILE *fdiag; fall_wspr=fopen("ALL_WSPR.TXT","a"); fwsprd=fopen("wsprd.out","w"); fdiag=fopen("wsprd_diag","a"); fweb=fopen("wspr-now.txt","a"); if((ftimer=fopen("wsprd_timer","r"))) { //Accumulate timing data nr=fscanf(ftimer,"%lf %lf %lf %lf %lf %lf %lf", &treadwav,&tcandidates,&tsync0,&tsync1,&tsync2,&tfano,&ttotal); fclose(ftimer); } ftimer=fopen("wsprd_timer","w"); if( strstr(ptr_to_infile,".wav") ) { ptr_to_infile_suffix=strstr(ptr_to_infile,".wav"); t0 = clock(); npoints=readwavfile(ptr_to_infile, idat, qdat); treadwav += (double)(clock()-t0)/CLOCKS_PER_SEC; if( npoints == 1 ) { return 1; } dialfreq=dialfreq_cmdline - (dialfreq_error*1.0e-06); } else if ( strstr(ptr_to_infile,".c2") !=0 ) { ptr_to_infile_suffix=strstr(ptr_to_infile,".c2"); npoints=readc2file(ptr_to_infile, idat, qdat, &dialfreq); if( npoints == 1 ) { return 1; } dialfreq -= (dialfreq_error*1.0e-06); } else { printf("Error: Failed to open %s\n",ptr_to_infile); printf("WSPR file must have suffix .wav or .c2\n"); return 1; } // Parse date and time from given filename strncpy(date,ptr_to_infile_suffix-11,6); strncpy(uttime,ptr_to_infile_suffix-4,4); date[6]='\0'; uttime[4]='\0'; //added riyas sprintf(xdate, "20%.2s-%.2s-%.2s", date, date+2, date+4); xdate[10]='\0'; sprintf(xuttime, "%.2s:%.2s", uttime, uttime+2); xuttime[5]='\0'; // Do windowed ffts over 2 symbols, stepped by half symbols int nffts=4*floor(npoints/512)-1; fftin=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*512); fftout=(fftw_complex*) fftw_malloc(sizeof(fftw_complex)*512); PLAN3 = fftw_plan_dft_1d(512, fftin, fftout, FFTW_FORWARD, PATIENCE); float ps[512][nffts]; float w[512]; for(i=0; i<512; i++) { w[i]=sin(0.006135923*i); } memset(ps,0.0, sizeof(float)*512*nffts); for (i=0; i<nffts; i++) { for(j=0; j<512; j++ ) { k=i*128+j; fftin[j][0]=idat[k] * w[j]; fftin[j][1]=qdat[k] * w[j]; } fftw_execute(PLAN3); for (j=0; j<512; j++ ) { k=j+256; if( k>511 ) k=k-512; ps[j][i]=fftout[k][0]*fftout[k][0]+fftout[k][1]*fftout[k][1]; } } fftw_free(fftin); fftw_free(fftout); // Compute average spectrum float psavg[512]; memset(psavg,0.0, sizeof(float)*512); for (i=0; i<nffts; i++) { for (j=0; j<512; j++) { psavg[j]=psavg[j]+ps[j][i]; } } // Smooth with 7-point window and limit spectrum to +/-150 Hz int window[7]={1,1,1,1,1,1,1}; float smspec[411]; for (i=0; i<411; i++) { smspec[i]=0.0; for(j=-3; j<=3; j++) { k=256-205+i+j; smspec[i]=smspec[i]+window[j+3]*psavg[k]; } } // Sort spectrum values, then pick off noise level as a percentile float tmpsort[411]; for (j=0; j<411; j++) { tmpsort[j]=smspec[j]; } qsort(tmpsort, 411, sizeof(float), floatcomp); // Noise level of spectrum is estimated as 123/411= 30'th percentile float noise_level = tmpsort[122]; // Renormalize spectrum so that (large) peaks represent an estimate of snr float min_snr_neg33db = pow(10.0,(-33+26.5)/10.0); for (j=0; j<411; j++) { smspec[j]=smspec[j]/noise_level - 1.0; if( smspec[j] < min_snr_neg33db) smspec[j]=0.1; continue; } // Find all local maxima in smoothed spectrum. for (i=0; i<200; i++) { freq0[i]=0.0; snr0[i]=0.0; drift0[i]=0.0; shift0[i]=0; sync0[i]=0.0; } int npk=0; for(j=1; j<410; j++) { if((smspec[j]>smspec[j-1]) && (smspec[j]>smspec[j+1]) && (npk<200)) { freq0[npk]=(j-205)*df; snr0[npk]=10*log10(smspec[j])-26.5; npk++; } } // Compute corrected fmin, fmax, accounting for dial frequency error fmin += dialfreq_error; // dialfreq_error is in units of Hz fmax += dialfreq_error; // Don't waste time on signals outside of the range [fmin,fmax]. i=0; for( j=0; j<npk; j++) { if( freq0[j] >= fmin && freq0[j] <= fmax ) { freq0[i]=freq0[j]; snr0[i]=snr0[j]; i++; } } npk=i; t0=clock(); /* Make coarse estimates of shift (DT), freq, and drift * Look for time offsets up to +/- 8 symbols (about +/- 5.4 s) relative to nominal start time, which is 2 seconds into the file * Calculates shift relative to the beginning of the file * Negative shifts mean that signal started before start of file * The program prints DT = shift-2 s * Shifts that cause sync vector to fall off of either end of the data vector are accommodated by "partial decoding", such that missing symbols produce a soft-decision symbol value of 128 * The frequency drift model is linear, deviation of +/- drift/2 over the span of 162 symbols, with deviation equal to 0 at the center of the signal vector. */ int idrift,ifr,if0,ifd,k0; int kindex; float smax,ss,pow,p0,p1,p2,p3; for(j=0; j<npk; j++) { //For each candidate... smax=-1e30; if0=freq0[j]/df+256; for (ifr=if0-1; ifr<=if0+1; ifr++) { //Freq search for( k0=-10; k0<22; k0++) { //Time search for (idrift=-maxdrift; idrift<=maxdrift; idrift++) { //Drift search ss=0.0; pow=0.0; for (k=0; k<162; k++) { //Sum over symbols ifd=ifr+((float)k-81.0)/81.0*( (float)idrift )/(2.0*df); kindex=k0+2*k; if( kindex < nffts ) { p0=ps[ifd-3][kindex]; p1=ps[ifd-1][kindex]; p2=ps[ifd+1][kindex]; p3=ps[ifd+3][kindex]; p0=sqrt(p0); p1=sqrt(p1); p2=sqrt(p2); p3=sqrt(p3); ss=ss+(2*pr3[k]-1)*((p1+p3)-(p0+p2)); pow=pow+p0+p1+p2+p3; sync1=ss/pow; } } if( sync1 > smax ) { //Save coarse parameters smax=sync1; shift0[j]=128*(k0+1); drift0[j]=idrift; freq0[j]=(ifr-256)*df; sync0[j]=sync1; } } } } } tcandidates += (double)(clock()-t0)/CLOCKS_PER_SEC; nbits=81; symbols=malloc(sizeof(char)*nbits*2); memset(symbols,0,sizeof(char)*nbits*2); decdata=malloc((nbits+7)/8); grid=malloc(sizeof(char)*5); grid6=malloc(sizeof(char)*7); callsign=malloc(sizeof(char)*13); call_loc_pow=malloc(sizeof(char)*23); cdbm=malloc(sizeof(char)*3); float allfreqs[npk]; memset(allfreqs,0,sizeof(float)*npk); char allcalls[npk][13]; memset(allcalls,0,sizeof(char)*npk*13); memset(grid,0,sizeof(char)*5); memset(grid6,0,sizeof(char)*7); memset(callsign,0,sizeof(char)*13); memset(call_loc_pow,0,sizeof(char)*23); memset(cdbm,0,sizeof(char)*3); char hashtab[32768][13]; memset(hashtab,0,sizeof(char)*32768*13); uint32_t nhash( const void *, size_t, uint32_t); int nh; if( usehashtable ) { char line[80], hcall[12]; if( (fhash=fopen("hashtable.txt","r+")) ) { while (fgets(line, sizeof(line), fhash) != NULL) { sscanf(line,"%d %s",&nh,hcall); strcpy(*hashtab+nh*13,hcall); } } else { fhash=fopen("hashtable.txt","w+"); } fclose(fhash); } int uniques=0, noprint=0; /* Refine the estimates of freq, shift using sync as a metric. Sync is calculated such that it is a float taking values in the range [0.0,1.0]. Function sync_and_demodulate has three modes of operation mode is the last argument: 0 = no frequency or drift search. find best time lag. 1 = no time lag or drift search. find best frequency. 2 = no frequency or time lag search. Calculate soft-decision symbols using passed frequency and shift. NB: best possibility for OpenMP may be here: several worker threads could each work on one candidate at a time. */ for (j=0; j<npk; j++) { f1=freq0[j]; drift1=drift0[j]; shift1=shift0[j]; sync1=sync0[j]; // Fine search for best sync lag (mode 0) fstep=0.0; lagmin=shift1-144; lagmax=shift1+144; lagstep=8; if(quickmode) lagstep=16; t0 = clock(); sync_and_demodulate(idat, qdat, npoints, symbols, &f1, fstep, &shift1, lagmin, lagmax, lagstep, &drift1, symfac, &sync1, 0); tsync0 += (double)(clock()-t0)/CLOCKS_PER_SEC; // Fine search for frequency peak (mode 1) fstep=0.1; t0 = clock(); sync_and_demodulate(idat, qdat, npoints, symbols, &f1, fstep, &shift1, lagmin, lagmax, lagstep, &drift1, symfac, &sync1, 1); tsync1 += (double)(clock()-t0)/CLOCKS_PER_SEC; if( sync1 > minsync1 ) { worth_a_try = 1; } else { worth_a_try = 0; } int idt=0, ii=0, jiggered_shift; uint32_t ihash; double y,sq,rms; not_decoded=1; while ( worth_a_try && not_decoded && idt<=(128/iifac)) { ii=(idt+1)/2; if( idt%2 == 1 ) ii=-ii; ii=iifac*ii; jiggered_shift=shift1+ii; // Use mode 2 to get soft-decision symbols t0 = clock(); sync_and_demodulate(idat, qdat, npoints, symbols, &f1, fstep, &jiggered_shift, lagmin, lagmax, lagstep, &drift1, symfac, &sync1, 2); tsync2 += (double)(clock()-t0)/CLOCKS_PER_SEC; sq=0.0; for(i=0; i<162; i++) { y=(double)symbols[i] - 128.0; sq += y*y; } rms=sqrt(sq/162.0); if((sync1 > minsync2) && (rms > minrms)) { deinterleave(symbols); t0 = clock(); not_decoded = fano(&metric,&cycles,&maxnp,decdata,symbols,nbits, mettab,delta,maxcycles); tfano += (double)(clock()-t0)/CLOCKS_PER_SEC; /* ### Used for timing tests: if(not_decoded) fprintf(fdiag, "%6s %4s %4.1f %3.0f %4.1f %10.7f %-18s %2d %5u %4d %6.1f %2d\n", date,uttime,sync1*10,snr0[j], shift1*dt-2.0, dialfreq+(1500+f1)/1e6, "@ ", (int)drift1, cycles/81, ii, rms, maxnp); */ } idt++; if( quickmode ) break; } if( worth_a_try && !not_decoded ) { for(i=0; i<11; i++) { if( decdata[i]>127 ) { message[i]=decdata[i]-256; } else { message[i]=decdata[i]; } } unpack50(message,&n1,&n2); unpackcall(n1,callsign); unpackgrid(n2, grid); int ntype = (n2&127) - 64; /* Based on the value of ntype, decide whether this is a Type 1, 2, or 3 message. * Type 1: 6 digit call, grid, power - ntype is positive and is a member of the set {0,3,7,10,13,17,20...60} * Type 2: extended callsign, power - ntype is positive but not a member of the set of allowed powers * Type 3: hash, 6 digit grid, power - ntype is negative. */ if( (ntype >= 0) && (ntype <= 62) ) { int nu=ntype%10; if( nu == 0 || nu == 3 || nu == 7 ) { ndbm=ntype; memset(call_loc_pow,0,sizeof(char)*23); sprintf(cdbm,"%2d",ndbm); strncat(call_loc_pow,callsign,strlen(callsign)); strncat(call_loc_pow," ",1); strncat(call_loc_pow,grid,4); strncat(call_loc_pow," ",1); strncat(call_loc_pow,cdbm,2); strncat(call_loc_pow,"\0",1); ihash=nhash(callsign,strlen(callsign),(uint32_t)146); strcpy(*hashtab+ihash*13,callsign); noprint=0; } else { nadd=nu; if( nu > 3 ) nadd=nu-3; if( nu > 7 ) nadd=nu-7; n3=n2/128+32768*(nadd-1); unpackpfx(n3,callsign); ndbm=ntype-nadd; memset(call_loc_pow,0,sizeof(char)*23); sprintf(cdbm,"%2d",ndbm); strncat(call_loc_pow,callsign,strlen(callsign)); strncat(call_loc_pow," ",1); strncat(call_loc_pow,cdbm,2); strncat(call_loc_pow,"\0",1); ihash=nhash(callsign,strlen(callsign),(uint32_t)146); strcpy(*hashtab+ihash*13,callsign); noprint=0; } } else if ( ntype < 0 ) { ndbm=-(ntype+1); memset(grid6,0,sizeof(char)*7); strncat(grid6,callsign+5,1); strncat(grid6,callsign,5); ihash=(n2-ntype-64)/128; if( strncmp(hashtab[ihash],"\0",1) != 0 ) { sprintf(callsign,"<%s>",hashtab[ihash]); } else { sprintf(callsign,"%5s","<...>"); } memset(call_loc_pow,0,sizeof(char)*23); sprintf(cdbm,"%2d",ndbm); strncat(call_loc_pow,callsign,strlen(callsign)); strncat(call_loc_pow," ",1); strncat(call_loc_pow,grid6,strlen(grid6)); strncat(call_loc_pow," ",1); strncat(call_loc_pow,cdbm,2); strncat(call_loc_pow,"\0",1); noprint=0; // I don't know what to do with these... They show up as "A000AA" grids. if( ntype == -64 ) noprint=1; } // Remove dupes (same callsign and freq within 1 Hz) int dupe=0; for (i=0; i<npk; i++) { if(!strcmp(callsign,allcalls[i]) && (fabs(f1-allfreqs[i]) <1.0)) dupe=1; } if( (verbose || !dupe) && !noprint) { uniques++; strcpy(allcalls[uniques],callsign); allfreqs[uniques]=f1; // Add an extra space at the end of each line so that wspr-x doesn't // truncate the power (TNX to DL8FCL!) char mygrid[]="NK03"; char mycall[]="SIARS"; //printf("%4s=================%d\n",grid,distance(grid, mygrid)); printf("%4s %3.0f %4.1f %10.6f %2d %-s \n", uttime, snr0[j],(shift1*dt-2.0), dialfreq+(1500+f1)/1e6, (int)drift1, call_loc_pow); fprintf(fall_wspr, "%6s %4s %3.0f %3.0f %4.1f %10.7f %-22s %2d %5u %4d\n", date,uttime,sync1*10,snr0[j], shift1*dt-2.0, dialfreq+(1500+f1)/1e6, call_loc_pow, (int)drift1, cycles/81, ii); fprintf(fwsprd, "%6s %4s %3.0f %3.0f %4.1f %10.7f %-22s %2d %5u %4d\n", date,uttime,sync1*10,snr0[j], shift1*dt-2.0, dialfreq+(1500+f1)/1e6, call_loc_pow, (int)drift1, cycles/81, ii); fprintf(fweb," %10s %5s %s %10.7f %3.0f %2d %4s %2d %2d %5s %4s %d %d \n", xdate,xuttime,callsign,dialfreq+(1500+f1)/1e6,snr0[j],(int)drift1,grid,ndbm,ndbm,mycall,mygrid,distance(grid, mygrid),distance(grid, mygrid)); /* For timing tests fprintf(fdiag, "%6s %4s %4.1f %3.0f %4.1f %10.7f %-18s %2d %5u %4d %6.1f\n", date,uttime,sync1*10,snr0[j], shift1*dt-2.0, dialfreq+(1500+f1)/1e6, call_loc_pow, (int)drift1, cycles/81, ii, rms); */ } } } printf("<DecodeFinished>\n"); if ((fp_fftw_wisdom_file = fopen("fftw_wisdom_wsprd", "w"))) { fftw_export_wisdom_to_file(fp_fftw_wisdom_file); fclose(fp_fftw_wisdom_file); } ttotal += (double)(clock()-t00)/CLOCKS_PER_SEC; fprintf(ftimer,"%7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n\n", treadwav,tcandidates,tsync0,tsync1,tsync2,tfano,ttotal); fprintf(ftimer,"Code segment Seconds Frac\n"); fprintf(ftimer,"-----------------------------------\n"); fprintf(ftimer,"readwavfile %7.2f %7.2f\n",treadwav,treadwav/ttotal); fprintf(ftimer,"Coarse DT f0 f1 %7.2f %7.2f\n",tcandidates, tcandidates/ttotal); fprintf(ftimer,"sync_and_demod(0) %7.2f %7.2f\n",tsync0,tsync0/ttotal); fprintf(ftimer,"sync_and_demod(1) %7.2f %7.2f\n",tsync1,tsync1/ttotal); fprintf(ftimer,"sync_and_demod(2) %7.2f %7.2f\n",tsync2,tsync2/ttotal); fprintf(ftimer,"Fano decoder %7.2f %7.2f\n",tfano,tfano/ttotal); fprintf(ftimer,"-----------------------------------\n"); fprintf(ftimer,"Total %7.2f %7.2f\n",ttotal,1.0); fclose(fall_wspr); fclose(fwsprd); fclose(fdiag); fclose(ftimer); fftw_destroy_plan(PLAN1); fftw_destroy_plan(PLAN2); fftw_destroy_plan(PLAN3); if( usehashtable ) { fhash=fopen("hashtable.txt","w"); for (i=0; i<32768; i++) { if( strncmp(hashtab[i],"\0",1) != 0 ) { fprintf(fhash,"%5d %s\n",i,*hashtab+i*13); } } fclose(fhash); } if(fblank+tblank+writenoise == 999) return -1; //Silence compiler warning return 0; }
// write a Differential Data Stream void writeDDSfile(const char *filename,unsigned char *data,size_t bytes,unsigned int skip,unsigned int strip,int nofree) { int version=1; unsigned char *ptr1,*ptr2; int pre1,pre2, act1,act2, tmp1,tmp2; unsigned int cnt,cnt1,cnt2; int bits,bits1,bits2; if (bytes<1) ERRORMSG(); if (bytes>DDS_INTERLEAVE) version=2; if (skip<1 || skip>4) skip=1; if (strip<1 || strip>65536) strip=1; if ((DDS_file=fopen(filename,"wb"))==NULL) ERRORMSG(); fprintf(DDS_file,"%s",(version==1)?DDS_ID:DDS_ID2); deinterleave(data,bytes,skip,DDS_INTERLEAVE); initbuffer(); writebits(DDS_file,skip-1,2); writebits(DDS_file,strip++-1,16); ptr1=ptr2=data; pre1=pre2=0; cnt=cnt1=cnt2=0; bits=bits1=bits2=0; while (cnt++<bytes) { tmp1=*ptr1++; if (cnt<=strip) act1=tmp1-pre1; else act1=tmp1-pre1-*(ptr1-strip)+*(ptr1-strip-1); pre1=tmp1; while (act1<-128) act1+=256; while (act1>127) act1-=256; if (act1<=0) for (bits=0; (1<<bits)/2<-act1; bits++) ; else for (bits=0; (1<<bits)/2<=act1; bits++) ; bits=DDS_decode(DDS_code(bits)); if (cnt1==0) { cnt1++; bits1=bits; continue; } if (cnt1<(1<<DDS_RL)-1 && bits==bits1) { cnt1++; continue; } if (cnt1+cnt2<(1<<DDS_RL) && (cnt1+cnt2)*max(bits1,bits2)<cnt1*bits1+cnt2*bits2+DDS_RL+3) { cnt2+=cnt1; if (bits1>bits2) bits2=bits1; } else { writebits(DDS_file,cnt2,DDS_RL); writebits(DDS_file,DDS_code(bits2),3); while (cnt2-->0) { tmp2=*ptr2++; if (ptr2-strip<=data) act2=tmp2-pre2; else act2=tmp2-pre2-*(ptr2-strip)+*(ptr2-strip-1); pre2=tmp2; while (act2<-128) act2+=256; while (act2>127) act2-=256; writebits(DDS_file,act2+(1<<bits2)/2,bits2); } cnt2=cnt1; bits2=bits1; } cnt1=1; bits1=bits; } if (cnt1+cnt2<(1<<DDS_RL) && (cnt1+cnt2)*max(bits1,bits2)<cnt1*bits1+cnt2*bits2+DDS_RL+3) { cnt2+=cnt1; if (bits1>bits2) bits2=bits1; } else { writebits(DDS_file,cnt2,DDS_RL); writebits(DDS_file,DDS_code(bits2),3); while (cnt2-->0) { tmp2=*ptr2++; if (ptr2-strip<=data) act2=tmp2-pre2; else act2=tmp2-pre2-*(ptr2-strip)+*(ptr2-strip-1); pre2=tmp2; while (act2<-128) act2+=256; while (act2>127) act2-=256; writebits(DDS_file,act2+(1<<bits2)/2,bits2); } cnt2=cnt1; bits2=bits1; } if (cnt2!=0) { writebits(DDS_file,cnt2,DDS_RL); writebits(DDS_file,DDS_code(bits2),3); while (cnt2-->0) { tmp2=*ptr2++; if (ptr2-strip<=data) act2=tmp2-pre2; else act2=tmp2-pre2-*(ptr2-strip)+*(ptr2-strip-1); pre2=tmp2; while (act2<-128) act2+=256; while (act2>127) act2-=256; writebits(DDS_file,act2+(1<<bits2)/2,bits2); } } flushbits(DDS_file); fclose(DDS_file); if (nofree==0) free(data); else interleave(data,bytes,skip,DDS_INTERLEAVE); }
// interleave a byte stream static void interleave(unsigned char *data,size_t bytes,unsigned int skip,unsigned int block=0) {deinterleave(data,bytes,skip,block,TRUE);}
static int huffspec(faacDecHandle hDecoder, Info *info, int nsect, byte *sect, int *factors, Float *coef) { Hcb *hcb; Huffman *hcw; int i, j, k, table, step, stop, bottom, top; int *bands, *bandp; int *quant, *qp; int *tmp_spec; int *quantPtr; int *tmp_specPtr; quant = AllocMemory(LN2*sizeof(int)); tmp_spec = AllocMemory(LN2*sizeof(int)); quantPtr = quant; tmp_specPtr = tmp_spec; #ifndef _WIN32 SetMemory(quant, 0, LN2*sizeof(int)); #endif bands = info->bk_sfb_top; bottom = 0; k = 0; bandp = bands; for(i = nsect; i; i--) { table = sect[0]; top = sect[1]; sect += 2; if( (table == 0) || (table == NOISE_HCB) || (table == INTENSITY_HCB) || (table == INTENSITY_HCB2) ) { bandp = bands+top; k = bandp[-1]; bottom = top; continue; } if(table < BY4BOOKS+1) { step = 4; } else { step = 2; } hcb = &book[table]; hcw = hcb->hcw; qp = quant+k; for(j = bottom; j < top; j++) { stop = *bandp++; while(k < stop) { decode_huff_cw(hDecoder, hcw, qp, hcb); if (!hcb->signed_cb) get_sign_bits(hDecoder, qp, step); if(table == ESCBOOK){ qp[0] = getescape(hDecoder, qp[0]); qp[1] = getescape(hDecoder, qp[1]); } qp += step; k += step; } } bottom = top; } /* pulse coding reconstruction */ if ((info->islong) && (hDecoder->pulse_info.pulse_data_present)) pulse_nc(hDecoder, quant, &hDecoder->pulse_info); if (!info->islong) { deinterleave (quant,tmp_spec, (short)info->num_groups, info->group_len, info->sfb_per_sbk, info->sfb_width_128); for (i = LN2/16 - 1; i >= 0; --i) { *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; *quantPtr++ = *tmp_specPtr++; } } /* inverse quantization */ for (i=0; i<info->bins_per_bk; i++) { coef[i] = esc_iquant(hDecoder, quant[i]); } /* rescaling */ { int sbk, nsbk, sfb, nsfb, fac, top; Float *fp, scale; i = 0; fp = coef; nsbk = info->nsbk; for (sbk=0; sbk<nsbk; sbk++) { nsfb = info->sfb_per_sbk[sbk]; k=0; for (sfb=0; sfb<nsfb; sfb++) { top = info->sbk_sfb_top[sbk][sfb]; fac = factors[i++]-SF_OFFSET; if (fac >= 0 && fac < TEXP) { scale = hDecoder->exptable[fac]; } else { if (fac == -SF_OFFSET) { scale = 0; } else { scale = (float)pow(2.0, 0.25*fac); } } for ( ; k<top; k++) { *fp++ *= scale; } } } } if (quant) FreeMemory(quant); if (tmp_spec) FreeMemory(tmp_spec); return 1; }
int JackClient::Process(jack_nframes_t nframes, void *self) { int j = 0; bool isEncoded = ((JackClient*) self)->m_Encoded; for(std::map<int, JackPort*>::iterator i = m_InputPortMap.begin(); i != m_InputPortMap.end(); i++) { if(jack_port_connected(i->second->Port)) { sample_t *in = (sample_t *) jack_port_get_buffer(i->second->Port, nframes); // memcpy (i->second->Buf, in, sizeof (sample_t) * m_BufferSize); //m_BufferSize -> 2nd AudioCollector parameter //Buff attribué par SetInputBuf dans le construcAteur de AudioCollector if(isEncoded) { //Added this to write in the buffer only if //the encoder is in action if(!j) { //only streams the 1st Jack Input port if(ringbuffer_write_space(((JackClient*) self)->first) >= (sizeof(sample_t) * nframes)) { ringbuffer_write(((JackClient*) self)->first, (char *)in, (sizeof(sample_t) * nframes)); } /* else { std::cerr << "-----------Pas suffisament de place dans audio_fred !!!" << std::endl; }*/ j++; } } } } int channels = ((JackClient*) self)->m_ringbufferchannels; bool output_available = false; //m_ringbuffer created by ViewPort::add_audio //1024*512 rounded up to the next power of two. if(((JackClient*) self)->m_ringbuffer) { // static int firsttime = 1 + ceil(4096/nframes); // XXX pre-buffer TODO decrease this and compensate latency if(ringbuffer_read_space(((JackClient*) self)->m_ringbuffer) >= /*firsttime */ channels * nframes * sizeof(float)) { // firsttime=1; size_t rv = ringbuffer_read(((JackClient*) self)->m_ringbuffer, ((JackClient*) self)->m_inbuf, channels * nframes * sizeof(float)); if(isEncoded) { //Added this to write in the buffer only if //the encoder is in action if(ringbuffer_write_space(((JackClient*) self)->audio_mix_ring) >= rv) { // unsigned char *aPtr = (unsigned char *)((JackClient*) self)->m_inbuf; size_t rf = ringbuffer_write(((JackClient*) self)->audio_mix_ring, ((JackClient*) self)->m_inbuf, rv); if(rf != rv) std::cerr << "---" << rf << " : au lieu de :" << rv << " octets ecrits dans le ringbuffer !!" \ << std::endl; } else { std::cerr << "-----------Not enough room in audio_mix_ring !!!" << std::endl; } } //reads m_ringbuffer and puts it in m_inbuf //m_inbuf created in SetRingbufferPtr called by add_audio //4096 * channels * sizeof(float) if(rv >= channels * nframes * sizeof(float)) { output_available = true; } } #if 0 else if(firsttime == 1) fprintf(stderr, "AUDIO BUFFER UNDERRUN: %i samples < %i\n", ringbuffer_read_space(((JackClient*) self)->m_ringbuffer) / sizeof(float) / channels, nframes); #endif } j = 0; for(std::map<int, JackPort*>::iterator i = m_OutputPortMap.begin(); i != m_OutputPortMap.end(); i++) { if(output_available && j < channels) { sample_t *out = (sample_t *) jack_port_get_buffer(i->second->Port, nframes); memset(out, 0, sizeof(jack_default_audio_sample_t) * nframes); deinterleave(((JackClient*) self)->m_inbuf, out, channels , j, nframes); //writes nframes of channels m_inbuf to out //two times if stereo (shifted by the channel number) #if 0 // test-noise: int i; for(i = 0; i < nframes; i++) out[i] = (float) i / (float)nframes; #endif } else { // no output availaible, clear sample_t *out = (sample_t *) jack_port_get_buffer(i->second->Port, nframes); memset(out, 0, sizeof(sample_t) * nframes); } j++; } m_BufferSize = nframes; // if(RunCallback&&RunContext) // { // // do the work // RunCallback(RunContext, nframes); // } return 0; }