hack: Add manual cosine power ramp mask
diff --git a/Transceiver52M/sigProcLib.cpp b/Transceiver52M/sigProcLib.cpp
index 9d8410b..fd59e00 100644
--- a/Transceiver52M/sigProcLib.cpp
+++ b/Transceiver52M/sigProcLib.cpp
@@ -44,14 +44,14 @@
 #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 @@
 /** 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 @@
   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 @@
 {
   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 @@
   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 @@
   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 @@
   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 @@
   }
 
   /* 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 @@
   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,