Transceiver52M: Set resampling option automatically based on device

Remove the built time resampling selection and link both options.
Move the normal push/pullBuffer() calls back to the base class and
overload them in the inherited resampling class.

USRP2/N2xx devices are the only devices that require resampling so
return that resampling is necessary on the device open(), which is
the point at which the device type will be known.

The GSM transceiver only operates at a whole number multiple of
the GSM rate and doesn't care about the actual device rate and
if resampling is used. Therefore GSM specific portion of the
transceiver should only need to submit the samples-per-symbol
value to the device interface.

Then, the device should be able to determine the appropriate
sample rate (400 ksps or 270.833 ksps) and if resampling is
appropriate.

Signed-off-by: Thomas Tsou <tom@tsou.cc>
diff --git a/Transceiver52M/radioInterface.cpp b/Transceiver52M/radioInterface.cpp
index 8ad72b0..93d2ff3 100644
--- a/Transceiver52M/radioInterface.cpp
+++ b/Transceiver52M/radioInterface.cpp
@@ -27,6 +27,28 @@
 
 bool started = false;
 
+/* Device side buffers */
+static short rx_buf[OUTCHUNK * 2 * 2];
+static short tx_buf[INCHUNK * 2 * 2];
+
+/* Complex float to short conversion */
+static void floatToShort(short *out, float *in, int num)
+{
+  for (int i = 0; i < num; i++) {
+    out[2 * i + 0] = (short) in[2 * i + 0];
+    out[2 * i + 1] = (short) in[2 * i + 1];
+  }
+}
+
+/* Complex short to float conversion */
+static void shortToFloat(float *out, short *in, int num)
+{
+  for (int i = 0; i < num; i++) {
+    out[2 * i + 0] = (float) in[2 * i + 0];
+    out[2 * i + 1] = (float) in[2 * i + 1];
+  }
+}
+
 RadioInterface::RadioInterface(RadioDevice *wRadio,
 			       int wReceiveOffset,
 			       int wSPS,
@@ -236,3 +258,41 @@
   else
     return -1;
 }
+
+/* Receive a timestamped chunk from the device */ 
+void RadioInterface::pullBuffer()
+{
+  bool local_underrun;
+
+  /* Read samples. Fail if we don't get what we want. */
+  int num_rd = mRadio->readSamples(rx_buf, OUTCHUNK, &overrun,
+                                   readTimestamp, &local_underrun);
+
+  LOG(DEBUG) << "Rx read " << num_rd << " samples from device";
+  assert(num_rd == OUTCHUNK);
+
+  underrun |= local_underrun;
+  readTimestamp += (TIMESTAMP) num_rd;
+
+  shortToFloat(rcvBuffer + 2 * rcvCursor, rx_buf, num_rd);
+  rcvCursor += num_rd;
+}
+
+/* Send timestamped chunk to the device with arbitrary size */ 
+void RadioInterface::pushBuffer()
+{
+  if (sendCursor < INCHUNK)
+    return;
+
+  floatToShort(tx_buf, sendBuffer, sendCursor);
+
+  /* Write samples. Fail if we don't get what we want. */
+  int num_smpls = mRadio->writeSamples(tx_buf,
+                                       sendCursor,
+                                       &underrun,
+                                       writeTimestamp);
+  assert(num_smpls == sendCursor);
+
+  writeTimestamp += (TIMESTAMP) num_smpls;
+  sendCursor = 0;
+}