gui improvements; code templates
parent
241a089c39
commit
f1ad979674
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue