summaryrefslogtreecommitdiff
path: root/src/lib/delay_line.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-07-15 00:14:28 +0100
committerCarl Hetherington <cth@carlh.net>2012-07-15 00:14:28 +0100
commitbb767c7e338414beee132af3e96829c1448e214b (patch)
treebec2858dcc7225a9bcc2acd8170c25508f6df6cb /src/lib/delay_line.cc
parent66c9be6bdb1361e5681e094a0c8170d268aa9518 (diff)
Move things round a bit.
Diffstat (limited to 'src/lib/delay_line.cc')
-rw-r--r--src/lib/delay_line.cc110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/lib/delay_line.cc b/src/lib/delay_line.cc
new file mode 100644
index 000000000..c510fb4e3
--- /dev/null
+++ b/src/lib/delay_line.cc
@@ -0,0 +1,110 @@
+/*
+ Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <stdint.h>
+#include <cstring>
+#include <algorithm>
+#include <iostream>
+#include "delay_line.h"
+
+using namespace std;
+
+/** Construct a DelayLine delaying by some number of bytes.
+ * @param d Number of bytes to delay by; +ve moves data later.
+ */
+DelayLine::DelayLine (int d)
+ : _delay (d)
+ , _buffer (0)
+ , _negative_delay_remaining (0)
+{
+ if (d > 0) {
+ /* We need a buffer to keep some data in */
+ _buffer = new uint8_t[d];
+ memset (_buffer, 0, d);
+ } else if (d < 0) {
+ /* We can do -ve delays just by chopping off
+ the start, so no buffer needed.
+ */
+ _negative_delay_remaining = -d;
+ }
+}
+
+DelayLine::~DelayLine ()
+{
+ delete[] _buffer;
+}
+
+int
+DelayLine::feed (uint8_t* data, int size)
+{
+ int available = size;
+
+ if (_delay > 0) {
+
+ /* Copy the input data */
+ uint8_t input[size];
+ memcpy (input, data, size);
+
+ int to_do = size;
+
+ /* Write some of our buffer to the output */
+ int const from_buffer = min (to_do, _delay);
+ memcpy (data, _buffer, from_buffer);
+ to_do -= from_buffer;
+
+ /* Write some of the input to the output */
+ int const from_input = min (to_do, size);
+ memcpy (data + from_buffer, input, from_input);
+
+ int const left_in_buffer = _delay - from_buffer;
+
+ /* Shuffle our buffer down */
+ memmove (_buffer, _buffer + from_buffer, left_in_buffer);
+
+ /* Copy remaining input data to our buffer */
+ memcpy (_buffer + left_in_buffer, input + from_input, size - from_input);
+
+ } else if (_delay < 0) {
+
+ /* Chop the initial data off until _negative_delay_remaining
+ is zero, then just pass data.
+ */
+
+ int const to_do = min (size, _negative_delay_remaining);
+ available = size - to_do;
+ memmove (data, data + to_do, available);
+ _negative_delay_remaining -= to_do;
+
+ }
+
+ return available;
+}
+
+/** With -ve delays, the DelayLine will have data to give after
+ * all input data has been passed to ::feed().
+ * Call this method after passing all input data.
+ *
+ * @param buffer Pointer to buffer of _delay bytes in length,
+ * which will be filled with remaining data.
+ */
+void
+DelayLine::get_remaining (uint8_t* buffer)
+{
+ memset (buffer, 0, -_delay);
+}