Fix incorrect assumptions about sizeof(long) on x86_64

pull/7/merge
pabr 2017-07-18 07:12:24 +02:00
rodzic bf9bf22646
commit 7fa0abce2e
5 zmienionych plików z 56 dodań i 52 usunięć

Wyświetl plik

@ -1,4 +1,5 @@
HEAD
* Fixed --hs mode on x86_64.
* Added --s8, --s16, --u16.
* Improved timing recovery at low SNR (small performance penalty).
* Added --hdlc mode (compatible with some satellite modems).

Wyświetl plik

@ -179,7 +179,7 @@ namespace leansdr {
// QPSK 1/2 only.
template<typename Thist, unsigned long long POLY1, unsigned long long POLY2>
template<typename Thist, uint64_t POLY1, uint64_t POLY2>
struct convol_poly2 {
typedef u8 uncoded_byte;
typedef u8 hardsymbol;

Wyświetl plik

@ -1,6 +1,8 @@
#ifndef LEANSDR_DVB_H
#define LEANSDR_DVB_H
#include <stdint.h>
#include "leansdr/viterbi.h"
#include "leansdr/convolutional.h"
#include "leansdr/sdr.h"
@ -99,17 +101,17 @@ namespace leansdr {
deconvol_sync(scheduler *sch,
pipebuf<softsymbol> &_in,
pipebuf<Tbyte> &_out,
unsigned long gX, unsigned long gY,
unsigned long pX, unsigned long pY)
uint32_t gX, uint32_t gY,
uint32_t pX, uint32_t pY)
: runnable(sch, "deconvol_sync"),
fastlock(false),
in(_in), out(_out,SIZE_RSPACKET),
skip(0) {
conv = new unsigned long[2];
conv = new uint32_t[2];
conv[0] = gX;
conv[1] = gY;
nG = 2;
punct = new unsigned long[2];
punct = new uint32_t[2];
punct[0] = pX;
punct[1] = pY;
punctperiod = 0;
@ -128,10 +130,10 @@ namespace leansdr {
locked = &syncs[0];
}
typedef unsigned long long signal_t;
typedef unsigned long long iq_t;
typedef uint64_t signal_t;
typedef uint64_t iq_t;
static int log2(unsigned long long x) {
static int log2(uint64_t x) {
int n = -1;
for ( ; x; ++n,x>>=1 ) ;
return n;
@ -209,7 +211,7 @@ namespace leansdr {
// Alternate polynomials for fastlock
for ( int b=0; b<punctperiod; ++b ) {
unsigned long long d=deconv[b], d2=d;
uint64_t d=deconv[b], d2=d;
// 1/2
if ( d == 0x00000000000003baLL ) d2 = 0x0000000000038ccaLL;
// 2/3
@ -242,18 +244,19 @@ namespace leansdr {
if ( sch->debug ) {
for ( int b=0; b<punctperiod; ++b )
fprintf(stderr, "deconv[%d]=0x%016llx %d taps / %d bits\n",
b, deconv[b], hamming_weight(deconv[b]), log2(deconv[b])+1);
b, (unsigned long long)deconv[b],
hamming_weight(deconv[b]), log2(deconv[b])+1);
}
// Sanity check
for ( int b=0; b<punctperiod; ++b ) {
for ( int i=0; i<maxsbits; ++i ) {
iq_t iq = convolve((iq_t)1<<(LATENCY+i));
unsigned long expect = (b==i) ? 1 : 0;
unsigned long d = parity(iq&deconv[b]);
int expect = (b==i) ? 1 : 0;
int d = parity(iq&deconv[b]);
if ( d != expect )
fail("Failed to inverse convolutional coding");
unsigned long d2 = parity(iq&deconv2[b]);
int d2 = parity(iq&deconv2[b]);
if ( d2 != expect )
fail("Failed to inverse convolutional coding (alt)");
}
@ -439,8 +442,8 @@ namespace leansdr {
pipewriter<Tbyte> out;
// DECONVOL
int nG;
unsigned long *conv; // [nG] Convolution polynomials; MSB is newest
unsigned long *punct; // [nG] Puncturing pattern
uint32_t *conv; // [nG] Convolution polynomials; MSB is newest
uint32_t *punct; // [nG] Puncturing pattern
int punctperiod, punctweight;
iq_t *deconv; // [punctperiod] Deconvolution polynomials
iq_t *deconv2; // [punctperiod] Alternate polynomials (for fastlock)
@ -456,7 +459,7 @@ namespace leansdr {
pipebuf<u8> &_out,
enum code_rate rate) {
// EN 300 421, section 4.4.3 Inner coding
unsigned long pX, pY;
uint32_t pX, pY;
switch ( rate ) {
case FEC12:
pX = 0x1; // 1
@ -510,7 +513,7 @@ namespace leansdr {
private:
pipereader<uncoded_byte> in;
pipewriter<hardsymbol> out;
convol_poly2<unsigned long, 0171, 0133> convol;
convol_poly2<uint32_t, 0171, 0133> convol;
}; // dvb_convol
@ -574,8 +577,7 @@ namespace leansdr {
static const int NSYNCS = 4;
struct sync_t {
deconvol_poly2<Tin, unsigned long,
unsigned long long, 0x3ba, 0x38f70> deconv;
deconvol_poly2<Tin, uint32_t, uint64_t, 0x3ba, 0x38f70> deconv;
u8 lut[4]; // TBD Swap and flip bits in the polynomials instead.
} syncs[NSYNCS];
@ -1079,10 +1081,10 @@ namespace leansdr {
struct viterbi_sync : runnable {
static const int TRACEBACK = 32; // Suitable for QPSK 1/2
typedef unsigned char TS, TCS, TUS;
typedef unsigned short TBM;
typedef unsigned long TPM;
typedef bitpath<unsigned long,TUS,1,TRACEBACK> dvb_path;
typedef uint8_t TS, TCS, TUS;
typedef uint16_t TBM;
typedef uint32_t TPM;
typedef bitpath<uint32_t,TUS,1,TRACEBACK> dvb_path;
typedef viterbi_dec<TS,64, TUS,2, TCS,4, TBM, TPM, dvb_path> dvb_dec;
typedef trellis<TS,64, TUS,2, 4> dvb_trellis;
@ -1107,7 +1109,7 @@ namespace leansdr {
resync_period(32) // 1/32 = 9% synchronization overhead
{
dvb_trellis *trell = new dvb_trellis();
unsigned long long dvb_polynomials[] = { DVBS_G1, DVBS_G2 };
uint64_t dvb_polynomials[] = { DVBS_G1, DVBS_G2 };
trell->init_convolutional(dvb_polynomials);
for ( int s=0; s<NSYNCS; ++s ) syncs[s] = new dvb_dec(trell);
}
@ -1189,10 +1191,10 @@ namespace leansdr {
struct viterbi_sync_bpsk : runnable {
static const int TRACEBACK = 32; // Suitable for BPSK 1/2
typedef unsigned char TS, TCS, TUS;
typedef unsigned short TBM;
typedef unsigned long TPM;
typedef bitpath<unsigned long,TUS,1,TRACEBACK> dvb_path;
typedef uint8_t TS, TCS, TUS;
typedef uint16_t TBM;
typedef uint32_t TPM;
typedef bitpath<uint32_t,TUS,1,TRACEBACK> dvb_path;
typedef viterbi_dec<TS,64, TUS,2, TCS,4, TBM, TPM, dvb_path> dvb_dec;
typedef trellis<TS,64, TUS,2, 4> dvb_trellis;
@ -1217,7 +1219,7 @@ namespace leansdr {
resync_period(32)
{
dvb_trellis *trell = new dvb_trellis();
unsigned long long dvb_polynomials[] = { DVBS_G1, DVBS_G2 };
uint64_t dvb_polynomials[] = { DVBS_G1, DVBS_G2 };
trell->init_convolutional(dvb_polynomials);
for ( int s=0; s<NSYNCS; ++s ) syncs[s] = new dvb_dec(trell);
}

Wyświetl plik

@ -2,6 +2,7 @@
#define LEANSDR_MATH_H
#include <math.h>
#include <stdint.h>
namespace leansdr {
@ -35,35 +36,35 @@ namespace leansdr {
}
// TBD Optimize with dedicated instructions
int hamming_weight(unsigned char x) {
int hamming_weight(uint8_t x) {
static const int lut[16] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4 };
return lut[x&15] + lut[x>>4];
}
int hamming_weight(unsigned short x) {
return hamming_weight((unsigned char)x)
+ hamming_weight((unsigned char)(x>>8));
int hamming_weight(uint16_t x) {
return hamming_weight((uint8_t)x)
+ hamming_weight((uint8_t)(x>>8));
}
int hamming_weight(unsigned long x) {
return hamming_weight((unsigned short)x)
+ hamming_weight((unsigned short)(x>>16));
int hamming_weight(uint32_t x) {
return hamming_weight((uint16_t)x)
+ hamming_weight((uint16_t)(x>>16));
}
int hamming_weight(unsigned long long x) {
return hamming_weight((unsigned long)x)
+ hamming_weight((unsigned long)(x>>32));
int hamming_weight(uint64_t x) {
return hamming_weight((uint32_t)x)
+ hamming_weight((uint32_t)(x>>32));
}
unsigned char parity(unsigned char x) {
unsigned char parity(uint8_t x) {
x ^= x>>4;
return (0x6996 >> (x&15)) & 1; // 16-entry look-up table
}
unsigned char parity(unsigned short x) {
return parity((unsigned char)(x^(x>>8)));
unsigned char parity(uint16_t x) {
return parity((uint8_t)(x^(x>>8)));
}
unsigned char parity(unsigned long x) {
return parity((unsigned short)(x^(x>>16)));
unsigned char parity(uint32_t x) {
return parity((uint16_t)(x^(x>>16)));
}
unsigned char parity(unsigned long long x) {
return parity((unsigned long)(x^(x>>32)));
unsigned char parity(uint64_t x) {
return parity((uint32_t)(x^(x>>32)));
}
@ -78,12 +79,12 @@ namespace leansdr {
lut[a].im = sinf(af);
}
}
inline const complex<float> &expi(unsigned short a) const {
inline const complex<float> &expi(uint16_t a) const {
return lut[a];
}
// a must fit in a signed long, otherwise behaviour is undefined
// a must fit in a int32_t, otherwise behaviour is undefined
inline const complex<float> &expi(float a) const {
return expi((unsigned short)(signed short)(signed long)a);
return expi((uint16_t)(int16_t)(int32_t)a);
}
};

Wyświetl plik

@ -34,7 +34,7 @@ namespace leansdr {
states[s].branches[cs].pred = NOSTATE;
}
void init_convolutional(unsigned long long G[]) {
void init_convolutional(uint64_t G[]) {
if ( NCS & (NCS-1) ) {
fprintf(stderr, "NCS must be a power of 2\n");
exit(1);
@ -46,8 +46,8 @@ namespace leansdr {
for ( TS s=0; s<NSTATES; ++s ) {
for ( TUS us=0; us<NUS; ++us ) {
// Run the convolutional encoder from state s with input us
unsigned long long shiftreg = s | (us*NSTATES);
unsigned long cs = 0;
uint64_t shiftreg = s | (us*NSTATES);
uint32_t cs = 0;
for ( int g=0; g<nG; ++g )
cs = (cs<<1) | parity(shiftreg&G[g]);
shiftreg /= NUS; // Shift bits for 1 uncoded symbol