aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M/radioInterfaceResamp.cpp
diff options
context:
space:
mode:
authorTom Tsou <tom.tsou@ettus.com>2015-08-21 19:32:58 -0700
committerTom Tsou <tom.tsou@ettus.com>2016-07-01 03:03:11 -0700
commit28670fb5dad8e48ff74051a5bbe0c8309b04c817 (patch)
treef93d11d8a26701cdecceebdf40b9fac006c8af03 /Transceiver52M/radioInterfaceResamp.cpp
parent05c6feb71dd2f66b74c9e1671d91570485479836 (diff)
iface: Add inner ring-buffer implementation
Two buffers, inner and outer, are used in the transceiver implementation. The outer buffer interfaces with the device receive interface to guarantee timestamp aligned and contiguously allocated sample buffers. The inner buffer absorbs vector size differences between GSM bursts (156 or 157 samples) and the resampler interface (typically fixed multiples of 65). Reimplement the inner buffer with a ring buffer that allows fixed size segments on the outer (resampler) portion and variable lengths (GSM side) on the inner side. Compared to the previous stack-like version, this implementation removes unnecessary copying of buffer contents. Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
Diffstat (limited to 'Transceiver52M/radioInterfaceResamp.cpp')
-rw-r--r--Transceiver52M/radioInterfaceResamp.cpp81
1 files changed, 33 insertions, 48 deletions
diff --git a/Transceiver52M/radioInterfaceResamp.cpp b/Transceiver52M/radioInterfaceResamp.cpp
index f898d65..26dd40b 100644
--- a/Transceiver52M/radioInterfaceResamp.cpp
+++ b/Transceiver52M/radioInterfaceResamp.cpp
@@ -1,8 +1,10 @@
/*
* Radio device interface with sample rate conversion
- * Written by Thomas Tsou <tom@tsou.cc>
*
- * Copyright 2011, 2012, 2013 Free Software Foundation, Inc.
+ * Copyright (C) 2011-2014 Free Software Foundation, Inc.
+ * Copyright (C) 2015 Ettus Research LLC
+ *
+ * Author: Tom Tsou <tom@tsou.cc>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -58,8 +60,8 @@ static size_t resamp_outchunk = 0;
RadioInterfaceResamp::RadioInterfaceResamp(RadioDevice *wRadio,
size_t sps, size_t chans)
: RadioInterface(wRadio, sps, chans),
- innerSendBuffer(NULL), outerSendBuffer(NULL),
- innerRecvBuffer(NULL), outerRecvBuffer(NULL)
+ outerSendBuffer(NULL),
+ outerRecvBuffer(NULL)
{
}
@@ -70,17 +72,13 @@ RadioInterfaceResamp::~RadioInterfaceResamp()
void RadioInterfaceResamp::close()
{
- delete innerSendBuffer;
delete outerSendBuffer;
- delete innerRecvBuffer;
delete outerRecvBuffer;
delete upsampler;
delete dnsampler;
- innerSendBuffer = NULL;
outerSendBuffer = NULL;
- innerRecvBuffer = NULL;
outerRecvBuffer = NULL;
upsampler = NULL;
@@ -157,21 +155,18 @@ bool RadioInterfaceResamp::init(int type)
* and requires headroom equivalent to the filter length. Low
* rate buffers are allocated in the main radio interface code.
*/
- innerSendBuffer =
- new signalVector(NUMCHUNKS * resamp_inchunk, upsampler->len());
+ sendBuffer[0] = new RadioBuffer(NUMCHUNKS, resamp_inchunk,
+ upsampler->len(), true);
+ recvBuffer[0] = new RadioBuffer(NUMCHUNKS * 20, resamp_inchunk, 0, false);
+
outerSendBuffer =
new signalVector(NUMCHUNKS * resamp_outchunk);
outerRecvBuffer =
new signalVector(resamp_outchunk, dnsampler->len());
- innerRecvBuffer =
- new signalVector(NUMCHUNKS * resamp_inchunk / mSPSTx);
convertSendBuffer[0] = new short[outerSendBuffer->size() * 2];
convertRecvBuffer[0] = new short[outerRecvBuffer->size() * 2];
- sendBuffer[0] = innerSendBuffer;
- recvBuffer[0] = innerRecvBuffer;
-
return true;
}
@@ -181,7 +176,7 @@ void RadioInterfaceResamp::pullBuffer()
bool local_underrun;
int rc, num_recv;
- if (recvCursor > innerRecvBuffer->size() - resamp_inchunk)
+ if (recvBuffer[0]->getFreeSegments() <= 0)
return;
/* Outer buffer access size is fixed */
@@ -204,57 +199,47 @@ void RadioInterfaceResamp::pullBuffer()
/* Write to the end of the inner receive buffer */
rc = dnsampler->rotate((float *) outerRecvBuffer->begin(),
resamp_outchunk,
- (float *) (innerRecvBuffer->begin() + recvCursor),
+ recvBuffer[0]->getWriteSegment(),
resamp_inchunk);
if (rc < 0) {
LOG(ALERT) << "Sample rate upsampling error";
}
- recvCursor += resamp_inchunk;
+ /* Set history for the next chunk */
+ outerRecvBuffer->updateHistory();
}
/* Send a timestamped chunk to the device */
-void RadioInterfaceResamp::pushBuffer()
+bool RadioInterfaceResamp::pushBuffer()
{
- int rc, chunks, num_sent;
- int inner_len, outer_len;
-
- if (sendCursor < resamp_inchunk)
- return;
-
- if (sendCursor > innerSendBuffer->size())
- LOG(ALERT) << "Send buffer overflow";
+ int rc;
+ size_t numSent;
- chunks = sendCursor / resamp_inchunk;
-
- inner_len = chunks * resamp_inchunk;
- outer_len = chunks * resamp_outchunk;
+ if (sendBuffer[0]->getAvailSegments() <= 0)
+ return false;
/* Always send from the beginning of the buffer */
- rc = upsampler->rotate((float *) innerSendBuffer->begin(), inner_len,
- (float *) outerSendBuffer->begin(), outer_len);
+ rc = upsampler->rotate(sendBuffer[0]->getReadSegment(),
+ resamp_inchunk,
+ (float *) outerSendBuffer->begin(),
+ resamp_outchunk);
if (rc < 0) {
LOG(ALERT) << "Sample rate downsampling error";
}
convert_float_short(convertSendBuffer[0],
(float *) outerSendBuffer->begin(),
- powerScaling[0], 2 * outer_len);
-
- num_sent = mRadio->writeSamples(convertSendBuffer,
- outer_len,
- &underrun,
- writeTimestamp);
- if (num_sent != outer_len) {
- LOG(ALERT) << "Transmit error " << num_sent;
+ powerScaling[0], 2 * resamp_outchunk);
+
+ numSent = mRadio->writeSamples(convertSendBuffer,
+ resamp_outchunk,
+ &underrun,
+ writeTimestamp);
+ if (numSent != resamp_outchunk) {
+ LOG(ALERT) << "Transmit error " << numSent;
}
- /* Shift remaining samples to beginning of buffer */
- memmove(innerSendBuffer->begin(),
- innerSendBuffer->begin() + inner_len,
- (sendCursor - inner_len) * 2 * sizeof(float));
+ writeTimestamp += resamp_outchunk;
- writeTimestamp += outer_len;
- sendCursor -= inner_len;
- assert(sendCursor >= 0);
+ return true;
}