hack: Add manual cosine power ramp mask

This commit is contained in:
Tom Tsou 2015-06-29 19:27:35 -07:00 committed by Tom Tsou
parent 5adc5ad68a
commit e11ef4d969
1 changed files with 76 additions and 23 deletions

View File

@ -44,14 +44,14 @@ using namespace GSM;
#define CLIP_THRESH 30000.0f
/** Lookup tables for trigonometric approximation */
float cosTable[TABLESIZE+1]; // add 1 element for wrap around
float sinTable[TABLESIZE+1];
float sincTable[TABLESIZE+1];
double cosTable[TABLESIZE+1]; // add 1 element for wrap around
double sinTable[TABLESIZE+1];
double sincTable[TABLESIZE+1];
/** Constants */
static const float M_PI_F = (float)M_PI;
static const float M_2PI_F = (float)(2.0*M_PI);
static const float M_1_2PI_F = 1/M_2PI_F;
static const double M_PI_F = M_PI;
static const double M_2PI_F = (2.0 * M_PI);
static const double M_1_2PI_F = (1.0 / M_2PI_F);
/* Precomputed rotation vectors */
static signalVector *GMSKRotationN = NULL;
@ -269,8 +269,8 @@ complex expjLookup(float x)
/** Library setup functions */
void initTrigTables() {
for (int i = 0; i < TABLESIZE+1; i++) {
cosTable[i] = cos(2.0*M_PI*i/TABLESIZE);
sinTable[i] = sin(2.0*M_PI*i/TABLESIZE);
cosTable[i] = cos(2.0 * M_PI * (double) i / TABLESIZE);
sinTable[i] = sin(2.0 * M_PI * (double) i / TABLESIZE);
}
}
@ -280,11 +280,13 @@ void initGMSKRotationTables(int sps)
GMSKReverseRotationN = new signalVector(157 * sps);
signalVector::iterator rotPtr = GMSKRotationN->begin();
signalVector::iterator revPtr = GMSKReverseRotationN->begin();
float phase = 0.0;
double phase = 0.0;
while (rotPtr != GMSKRotationN->end()) {
*rotPtr++ = expjLookup(phase);
*revPtr++ = expjLookup(-phase);
phase += M_PI_F / 2.0F / (float) sps;
*rotPtr++ = complex(cos(phase), sin(phase));
*revPtr++ = complex(cos(-phase), sin(-phase));
phase += M_PI_F / 8.0;
}
GMSKRotation1 = new signalVector(157);
@ -701,8 +703,8 @@ static signalVector *modulateBurstLaurent(const BitVector &bits,
{
int burst_len;
float phase;
signalVector *c0_pulse, *c1_pulse, *c0_burst;
signalVector *c1_burst, *c0_shaped, *c1_shaped;
signalVector *c0_pulse, *c1_pulse, *c0_burst, *c2_burst;
signalVector *c1_burst, *c0_shaped, *c1_shaped, *c2_shaped;
signalVector::iterator c0_itr, c1_itr;
/*
@ -715,7 +717,17 @@ static signalVector *modulateBurstLaurent(const BitVector &bits,
c0_pulse = GSMPulse->c0;
c1_pulse = GSMPulse->c1;
burst_len = sps * (bits.size() + guard_len);
int i = 0, head = 4, tail = 4;
BitVector _bits = BitVector(148 + head + tail);
for (; i < head; i++)
_bits[i] = 1;
for (; i < 148 + head; i++)
_bits[i] = bits[i - head];
for (; i < 148 + head + tail; i++)
_bits[i] = 1;
burst_len = 625 + (head + tail) * sps;
c0_burst = new signalVector(burst_len, c0_pulse->size());
c0_burst->isReal(true);
@ -725,13 +737,16 @@ static signalVector *modulateBurstLaurent(const BitVector &bits,
c1_burst->isReal(true);
c1_itr = c1_burst->begin();
c2_burst = new signalVector(625, c0_pulse->size());
c2_burst->isReal(false);
/* Padded differential start bits */
*c0_itr = 2.0 * (0x01 & 0x01) - 1.0;
*c0_itr = 2.0 * (0x00 & 0x01) - 1.0;
c0_itr += sps;
/* Main burst bits */
for (unsigned i = 0; i < bits.size(); i++) {
*c0_itr = 2.0 * (bits[i] & 0x01) - 1.0;
for (unsigned i = 0; i < _bits.size(); i++) {
*c0_itr = 2.0 * (_bits[i] & 0x01) - 1.0;
c0_itr += sps;
}
@ -753,8 +768,8 @@ static signalVector *modulateBurstLaurent(const BitVector &bits,
c1_itr += sps;
/* Generate C1 phase coefficients */
for (unsigned i = 2; i < bits.size(); i++) {
phase = 2.0 * ((bits[i - 1] & 0x01) ^ (bits[i - 2] & 0x01)) - 1.0;
for (unsigned i = 2; i < _bits.size(); i++) {
phase = 2.0 * ((_bits[i - 1] & 0x01) ^ (_bits[i - 2] & 0x01)) - 1.0;
*c1_itr = *c0_itr * Complex<float>(0, phase);
c0_itr += sps;
@ -762,13 +777,14 @@ static signalVector *modulateBurstLaurent(const BitVector &bits,
}
/* End magic */
int i = bits.size();
phase = 2.0 * ((bits[i-1] & 0x01) ^ (bits[i-2] & 0x01)) - 1.0;
i = _bits.size();
phase = 2.0 * ((_bits[i-1] & 0x01) ^ (_bits[i-2] & 0x01)) - 1.0;
*c1_itr = *c0_itr * Complex<float>(0, phase);
/* Primary (C0) and secondary (C1) pulse shaping */
c0_shaped = convolve(c0_burst, c0_pulse, NULL, START_ONLY);
c1_shaped = convolve(c1_burst, c1_pulse, NULL, START_ONLY);
c2_shaped = new signalVector(625);
/* Sum shaped outputs into C0 */
c0_itr = c0_shaped->begin();
@ -776,11 +792,48 @@ static signalVector *modulateBurstLaurent(const BitVector &bits,
for (unsigned i = 0; i < c0_shaped->size(); i++ )
*c0_itr++ += *c1_itr++;
/*
* Generate shaping mask with squared-cosine pulse. Only 4 samples-per-symbol
* is supported here so use length of 8 samples or 2 symbols.
*/
int len = 8;
float mask[len];
for (i = 0; i < len; i++)
mask[i] = 0.5 * (1.0 - cos(M_PI * (float) i / len));
/*
* Ramp-up mask components:
* C0 filter group delay is 7.5 samples
* Subtract added head bits
* Subtract length of shaping mask
* Delay ramp by 1 sample
*/
i = 0;
int start = 8 + head * sps - len + 1;
for (;i < len; i++)
c2_shaped->begin()[i] = mask[i] * c0_shaped->begin()[start + i];
for (; i < 625; i++)
c2_shaped->begin()[i] = c0_shaped->begin()[start + i];
/*
* Ramp-down mask components:
* Length of ramp-up mask
* 148 useful bits
*/
int j;
int end = len + 148 * sps;
for (i = end, j = 0; i < end + len; i++, j++)
c2_shaped->begin()[i] *= mask[len - j - 1];
for (; i < 625; i++)
c2_shaped->begin()[i] = 0;
delete c0_burst;
delete c1_burst;
delete c0_shaped;
delete c1_shaped;
return c0_shaped;
return c2_shaped;
}
static signalVector *modulateBurstBasic(const BitVector &bits,