aboutsummaryrefslogtreecommitdiffstats
path: root/gui/templates
diff options
context:
space:
mode:
Diffstat (limited to 'gui/templates')
-rw-r--r--gui/templates/1_convolve_simple.cpp29
-rw-r--r--gui/templates/2_convolve_overlap_save.cpp47
-rw-r--r--gui/templates/3_fir.cpp47
3 files changed, 123 insertions, 0 deletions
diff --git a/gui/templates/1_convolve_simple.cpp b/gui/templates/1_convolve_simple.cpp
new file mode 100644
index 0000000..0f1973d
--- /dev/null
+++ b/gui/templates/1_convolve_simple.cpp
@@ -0,0 +1,29 @@
+/**
+ * 1_convolve_simple.cpp
+ * Written by Clyne Sullivan.
+ *
+ * Computes a convolution in the simplest way possible. While the code is brief, it lacks many
+ * possible optimizations. The convolution's result will not fill the output buffer either, as the
+ * transient response is not calculated.
+ */
+
+adcsample_t *process_data(adcsample_t *samples, unsigned int size)
+{
+ // Define our output buffer. SIZE is the largest size of the 'samples' buffer.
+ static adcsample_t buffer[SIZE];
+
+ // Define our filter
+ constexpr unsigned int filter_size = 3;
+ float filter[filter_size] = {
+ 0.3333, 0.3333, 0.3333
+ };
+
+ // Begin convolving:
+ for (int n = 0; n < size - (filter_size - 1); n++) {
+ buffer[n] = 0;
+ for (int k = 0; k < filter_size; k++)
+ buffer[n] += samples[n + k] * filter[k];
+ }
+
+ return buffer;
+}
diff --git a/gui/templates/2_convolve_overlap_save.cpp b/gui/templates/2_convolve_overlap_save.cpp
new file mode 100644
index 0000000..1387d7f
--- /dev/null
+++ b/gui/templates/2_convolve_overlap_save.cpp
@@ -0,0 +1,47 @@
+/**
+ * 2_convolve_overlap_save.cpp
+ * Written by Clyne Sullivan.
+ *
+ * This convolution examples takes an overlap-save approach, where samples from the previous run
+ * are saved so that the overall operation is not interrupted (i.e. the observed output will
+ * transition smoothly between processed "chunks").
+ *
+ * Note that there are still improvements that can be made to the code; for example, notice every
+ * spot where an integer/float conversion is necessary. Operations like these may slow down the
+ * computation.
+ */
+
+adcsample_t *process_data(adcsample_t *samples, unsigned int size)
+{
+ static adcsample_t buffer[SIZE];
+
+ constexpr unsigned int filter_size = 3;
+ float filter[filter_size] = {
+ 0.3333, 0.3333, 0.3333
+ };
+
+ // Keep a buffer of extra samples for overlap-save
+ static adcsample_t prev[filter_size];
+
+ for (int n = 0; n < size; n++) {
+ buffer[n] = 0;
+
+ for (int k = 0; k < filter_size; k++) {
+ int i = n - (filter_size - 1) + k;
+
+ // If i is >= 0, access current sample buffer.
+ // If i is < 0, provide the previous samples from the 'prev' buffer
+ if (i >= 0)
+ buffer[n] += samples[i] * filter[k];
+ else
+ buffer[n] += prev[filter_size - 1 + i] * filter[k];
+ }
+ }
+
+ // Save samples for the next convolution run
+ for (int i = 0; i < filter_size; i++)
+ prev[i] = samples[size - filter_size + i];
+
+ return buffer;
+}
+
diff --git a/gui/templates/3_fir.cpp b/gui/templates/3_fir.cpp
new file mode 100644
index 0000000..7af66a8
--- /dev/null
+++ b/gui/templates/3_fir.cpp
@@ -0,0 +1,47 @@
+/**
+ * 3_fir.cpp
+ * Written by Clyne Sullivan.
+ *
+ * The below code was written for applying FIR filters. While this is still essentially an overlap-
+ * save convolution, other optimizations have been made to allow for larger filters to be applied
+ * within the available execution time. Samples are also normalized so that they center around zero.
+ */
+
+adcsample_t *process_data(adcsample_t *samples, unsigned int size)
+{
+ static adcsample_t buffer[SIZE];
+
+ // Define the filter:
+ constexpr unsigned int filter_size = 3;
+ static float filter[filter_size] = {
+ // Put filter values here (note: precision will be truncated for 'float' size).
+ 0.3333, 0.3333, 0.3333
+ };
+
+ // Do an overlap-save convolution
+ static adcsample_t prev[filter_size];
+
+ for (int n = 0; n < size; n++) {
+ // Using a float variable for accumulation allows for better code optimization
+ float v = 0;
+
+ for (int k = 0; k < filter_size; k++) {
+ int i = n - (filter_size - 1) + k;
+
+ auto s = i >= 0 ? samples[i] : prev[filter_size - 1 + i];
+ // Sample values are 0 to 4095. Below, the original sample is normalized to a -1.0 to
+ // 1.0 range for calculation.
+ v += (s / 2048.f - 1) * filter[k];
+ }
+
+ // Return value to sample range of 0-4095.
+ buffer[n] = (v + 1) * 2048.f;
+ }
+
+ // Save samples for next convolution
+ for (int i = 0; i < filter_size; i++)
+ prev[i] = samples[size - filter_size + i];
+
+ return buffer;
+}
+