aboutsummaryrefslogtreecommitdiffstats
path: root/templates/2_convolve_overlap_save.cpp
blob: 57c020a1e63851d017eea4eb7e2b443d765b6166 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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.
 */

Sample *process_data(Samples samples)
{
    static Sample buffer[samples.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 Sample prev[filter_size];

    for (int n = 0; n < samples.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[samples.size() - filter_size + i];

    return buffer;
}