Transceiver52M: Use independent noise vectors for each channel

Each ARFCN channel may be independently configureted and possibly on
separate hardware, so don't share a single vector for noise estimate
calculations. Allow a non-pointer based iterator so we can get away
with using the default copy constructor.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 3e2f838..4078c8f 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -43,6 +43,7 @@
 #define NOISE_CNT			20
 
 TransceiverState::TransceiverState()
+  : mNoiseLev(0.0), mNoises(NOISE_CNT)
 {
   for (int i = 0; i < 8; i++) {
     chanType[i] = Transceiver::NONE;
@@ -80,8 +81,8 @@
 			 GSM::Time wTransmitLatency,
 			 RadioInterface *wRadioInterface)
   : mBasePort(wBasePort), mAddr(TRXAddress),
-    mTransmitLatency(wTransmitLatency), mClockSocket(NULL), mRadioInterface(wRadioInterface),
-    mNoiseLev(0.0), mNoises(NOISE_CNT), mSPSTx(wSPS), mSPSRx(1), mChans(wChans),
+    mTransmitLatency(wTransmitLatency), mClockSocket(NULL),
+    mRadioInterface(wRadioInterface), mSPSTx(wSPS), mSPSRx(1), mChans(wChans),
     mOn(false), mTxFreq(0.0), mRxFreq(0.0), mPower(-10), mMaxExpectedDelay(0)
 {
   GSM::Time startTime(random() % gHyperframe,0);
@@ -351,13 +352,12 @@
  * state information and channel estimate if necessary. Equalization
  * is currently disabled.
  */
-bool Transceiver::detectTSC(TransceiverState *state,
-			    signalVector &burst,
+bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
                             complex &amp, float &toa, GSM::Time &time)
 {
   int tn = time.TN();
   float chanOffset, threshold = 5.0;
-  bool needDFE = false, estimateChan = false;
+  bool noise, needDFE = false, estimateChan = false;
   double elapsed = time - state->chanEstimateTime[tn];
   signalVector *chanResp;
 
@@ -378,7 +378,8 @@
     return false;
   }
 
-  state->SNRestimate[tn] = amp.norm2() / (mNoiseLev * mNoiseLev + 1.0);
+  noise = state->mNoiseLev;
+  state->SNRestimate[tn] = amp.norm2() / (noise * noise + 1.0);
 
   /* Set equalizer if unabled */
   if (needDFE && estimateChan) {
@@ -430,6 +431,7 @@
   int max_i = -1;
   signalVector *burst;
   SoftVector *bits = NULL;
+  TransceiverState *state = &mStates[chan];
 
   /* Blocking FIFO read */
   radioVector *radio_burst = mReceiveFIFO[chan]->read();
@@ -464,16 +466,16 @@
   /* Average noise on diversity paths and update global levels */
   burst = radio_burst->getVector(max_i);
   avg = sqrt(avg / radio_burst->chans());
-  mNoiseLev = mNoises.avg();
+  state->mNoiseLev = state->mNoises.avg();
 
   /* Detect normal or RACH bursts */
   if (type == TSC)
-    success = detectTSC(&mStates[chan], *burst, amp, toa, time);
+    success = detectTSC(state, *burst, amp, toa, time);
   else
-    success = detectRACH(&mStates[chan], *burst, amp, toa);
+    success = detectRACH(state, *burst, amp, toa);
 
   if (!success) {
-    mNoises.insert(avg);
+    state->mNoises.insert(avg);
     delete radio_burst;
     return NULL;
   }
@@ -482,8 +484,8 @@
   if (equalize && (type != TSC))
     equalize = false;
 
-  if (avg - mNoiseLev > 0.0)
-    bits = demodulate(&mStates[chan], *burst, amp, toa, time.TN(), equalize);
+  if (avg - state->mNoiseLev > 0.0)
+    bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
 
   wTime = time;
   RSSI = (int) floor(20.0 * log10(rxFullScale / avg));
@@ -594,8 +596,9 @@
   }
   else if (strcmp(command,"NOISELEV")==0) {
     if (mOn) {
+      float lev = mStates[chan].mNoiseLev;
       sprintf(response,"RSP NOISELEV 0 %d",
-              (int) round(20.0*log10(rxFullScale/mNoiseLev)));
+              (int) round(20.0 * log10(rxFullScale / lev)));
     }
     else {
       sprintf(response,"RSP NOISELEV 1  0");
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index 30b2fd3..51b6e24 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -76,6 +76,10 @@
   float SNRestimate[8];
   float chanRespOffset[8];
   complex chanRespAmplitude[8];
+
+  /* Received noise energy levels */
+  float mNoiseLev;
+  noiseVector mNoises;
 };
 
 /** The Transceiver class, responsible for physical layer of basestation */
@@ -114,9 +118,6 @@
     IDLE	       ///< timeslot is an idle (or dummy) burst
   } CorrType;
 
-  float mNoiseLev;      ///< Average noise level
-  noiseVector mNoises;  ///< Vector holding running noise measurements
-
   /** modulate and add a burst to the transmit queue */
   void addRadioVector(size_t chan, BitVector &bits,
                       int RSSI, GSM::Time &wTime);
diff --git a/Transceiver52M/radioVector.cpp b/Transceiver52M/radioVector.cpp
index ead4481..d6fb742 100644
--- a/Transceiver52M/radioVector.cpp
+++ b/Transceiver52M/radioVector.cpp
@@ -74,10 +74,9 @@
 	return true;
 }
 
-noiseVector::noiseVector(size_t n)
+noiseVector::noiseVector(size_t size)
+	: std::vector<float>(size), itr(0)
 {
-	this->resize(n);
-	it = this->begin();
 }
 
 float noiseVector::avg()
@@ -95,10 +94,10 @@
 	if (!size())
 		return false;
 
-	if (it == this->end())
-		it = this->begin();
+	if (itr >= this->size())
+		itr = 0;
 
-	*it++ = val;
+	(*this)[itr++] = val;
 
 	return true;
 }
diff --git a/Transceiver52M/radioVector.h b/Transceiver52M/radioVector.h
index 9acce94..0e83503 100644
--- a/Transceiver52M/radioVector.h
+++ b/Transceiver52M/radioVector.h
@@ -48,12 +48,12 @@
 
 class noiseVector : std::vector<float> {
 public:
-	noiseVector(size_t len = 0);
+	noiseVector(size_t size = 0);
 	bool insert(float val);
 	float avg();
 
 private:
-	std::vector<float>::iterator it;
+	size_t itr;
 };
 
 class VectorFIFO : public InterthreadQueue<radioVector> { };