Transceiver52M: Add vectorized radio burst capability

This patch allows multiple signalVectors to be stored within
a single radioVector object. The motivation is to provide
a facility for diversity and/or MIMO burst handling. When
no channel value is specified, single channel bevhaviour
is maintained.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 4bd3143..caf2452 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -165,23 +165,23 @@
   return true;
 }
 
-void Transceiver::addRadioVector(size_t chan, BitVector &burst,
+void Transceiver::addRadioVector(size_t chan, BitVector &bits,
                                  int RSSI, GSM::Time &wTime)
 {
+  signalVector *burst;
+  radioVector *radio_burst;
+
   if (chan >= mTxPriorityQueues.size()) {
     LOG(ALERT) << "Invalid channel " << chan;
     return;
   }
 
-  // modulate and stick into queue 
-  signalVector* modBurst = modulateBurst(burst,
-					 8 + (wTime.TN() % 4 == 0),
-					 mSPSTx);
-  scaleVector(*modBurst,txFullScale * pow(10,-RSSI/10));
-  radioVector *newVec = new radioVector(*modBurst,wTime);
-  mTxPriorityQueues[chan].write(newVec);
+  burst = modulateBurst(bits, 8 + (wTime.TN() % 4 == 0), mSPSTx);
+  scaleVector(*burst, txFullScale * pow(10, -RSSI / 10));
 
-  delete modBurst;
+  radio_burst = new radioVector(wTime, burst);
+
+  mTxPriorityQueues[chan].write(radio_burst);
 }
 
 void Transceiver::pushRadioVector(GSM::Time &nowTime)
@@ -202,7 +202,9 @@
       modFN = burst->getTime().FN() % state->fillerModulus[TN];
 
       delete state->fillerTable[modFN][TN];
-      state->fillerTable[modFN][TN] = burst;
+      state->fillerTable[modFN][TN] = burst->getVector();
+      burst->setVector(NULL);
+      delete burst;
     }
 
     TN = nowTime.TN();
@@ -213,8 +215,10 @@
 
     if ((burst = mTxPriorityQueues[i].getCurrentBurst(nowTime))) {
       delete state->fillerTable[modFN][TN];
-      state->fillerTable[modFN][TN] = burst;
-      bursts[i] = burst;
+      state->fillerTable[modFN][TN] = burst->getVector();
+      bursts[i] = burst->getVector();
+      burst->setVector(NULL);
+      delete burst;
     }
   }
 
@@ -346,7 +350,7 @@
     return NULL;
   }
 
-  signalVector *vectorBurst = rxBurst;
+  signalVector *vectorBurst = rxBurst->getVector();
 
   energyDetect(*vectorBurst, 20 * mSPSRx, 0.0, &avg);
 
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index d1a6ec9..671603e 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -118,7 +118,7 @@
   noiseVector mNoises;  ///< Vector holding running noise measurements
 
   /** modulate and add a burst to the transmit queue */
-  void addRadioVector(size_t chan, BitVector &burst,
+  void addRadioVector(size_t chan, BitVector &bits,
                       int RSSI, GSM::Time &wTime);
 
   /** Push modulated burst into transmit FIFO corresponding to a particular timestamp */
diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp
index 5cf34de..43fa3a3 100644
--- a/Transceiver52M/radioInterface.cpp
+++ b/Transceiver52M/radioInterface.cpp
@@ -251,9 +251,11 @@
    */
   while (recvSz > burstSize) {
     for (size_t i = 0; i < mChans; i++) {
-      burst = new radioVector(burstSize, head, rcvClock);
+      burst = new radioVector(rcvClock, burstSize, head);
 
-      unRadioifyVector((float *) (recvBuffer[i]->begin() + readSz), *burst);
+      unRadioifyVector((float *) (recvBuffer[i]->begin() + readSz),
+                       *burst->getVector());
+
       if (mReceiveFIFO[i].size() < 32)
         mReceiveFIFO[i].write(burst);
       else
diff --git a/Transceiver52M/radioVector.cpp b/Transceiver52M/radioVector.cpp
index 8ab6695..ead4481 100644
--- a/Transceiver52M/radioVector.cpp
+++ b/Transceiver52M/radioVector.cpp
@@ -21,19 +21,24 @@
 
 #include "radioVector.h"
 
-radioVector::radioVector(const signalVector& wVector, GSM::Time& wTime)
-	: signalVector(wVector), mTime(wTime)
+radioVector::radioVector(GSM::Time &time, size_t size,
+			 size_t start, size_t chans)
+	: vectors(chans), mTime(time)
 {
+	for (size_t i = 0; i < vectors.size(); i++)
+		vectors[i] = new signalVector(size, start);
 }
 
-radioVector::radioVector(size_t size, GSM::Time& wTime)
-	: signalVector(size), mTime(wTime)
+radioVector::radioVector(GSM::Time& wTime, signalVector *vector)
+	: vectors(1), mTime(wTime)
 {
+	vectors[0] = vector;
 }
 
-radioVector::radioVector(size_t size, size_t start, GSM::Time& wTime)
-	: signalVector(size, start), mTime(wTime)
+radioVector::~radioVector()
 {
+	for (size_t i = 0; i < vectors.size(); i++)
+		delete vectors[i];
 }
 
 GSM::Time radioVector::getTime() const
@@ -51,6 +56,24 @@
 	return mTime > other.mTime;
 }
 
+signalVector *radioVector::getVector(size_t chan)
+{
+	if (chan >= vectors.size())
+		return NULL;
+
+	return vectors[chan];
+}
+
+bool radioVector::setVector(signalVector *vector, size_t chan)
+{
+	if (chan >= vectors.size())
+		return false;
+
+	vectors[chan] = vector;
+
+	return true;
+}
+
 noiseVector::noiseVector(size_t n)
 {
 	this->resize(n);
diff --git a/Transceiver52M/radioVector.h b/Transceiver52M/radioVector.h
index c5c255b..9acce94 100644
--- a/Transceiver52M/radioVector.h
+++ b/Transceiver52M/radioVector.h
@@ -26,16 +26,23 @@
 #include "GSMCommon.h"
 #include "Interthread.h"
 
-class radioVector : public signalVector {
+class radioVector {
 public:
-	radioVector(const signalVector& wVector, GSM::Time& wTime);
-	radioVector(size_t size, GSM::Time& wTime);
-	radioVector(size_t size, size_t start, GSM::Time& wTime);
+	radioVector(GSM::Time& wTime, size_t size = 0,
+		    size_t start = 0, size_t chans = 1);
+
+	radioVector(GSM::Time& wTime, signalVector *vector);
+	~radioVector();
+
 	GSM::Time getTime() const;
 	void setTime(const GSM::Time& wTime);
 	bool operator>(const radioVector& other) const;
 
+	signalVector *getVector(size_t chan = 0);
+	bool setVector(signalVector *vector, size_t chan = 0);
+	size_t chans() const { return vectors.size(); }
 private:
+	std::vector<signalVector *> vectors;
 	GSM::Time mTime;
 };