2 Writing algorithms
Clyne edited this page 2 years ago

Algorithms for stmdspgui are written in C++. If you are more familiar with the programming language C, don't worry; nearly all written C is also valid C++.

Here are some resources on C++:

"Your first algorithm"

Below is the first algorithm we will look at. This is in fact what is shown whenever a new algorithm is created in stmdspgui.

Sample* process_data(Sample* samples)
{
    return samples;
}

This process_data function has one parameter named samples, which "points" to a chunk of input signal samples that were read from the ADC. The function is also expected to return a pointer to samples; this pointer will be used by the DAC to produce the output signal.

In the function body, the above algorithm is simply returning the sample pointer that it received. We refer to this as a "passthrough" algorithm, since the input signal is passed through to the output without any modifications.

All this algorithm is really good for is giving you a sense of an algorithm function's general structure. You will be guided through writing a real algorithm next; however, you can visit Running algorithms if you wish to learn about that first.

Your second algorithm

For our next algorithm, let's write code to amplify the input signal by a factor of two. To start, we will write a for loop to iterate over each input sample:

    for (int i = 0; i < SIZE; i++) {
        // In here, amplify `samples[i]` by a factor of two.
    }

SIZE is a constant that equals the number of samples in the input sample chunk (which is also how many samples must be in the output sample chunk).

For the amplification, you may be tempted to just write samples[i] = samples[i] * 2. Feel free to try that out, but an extra operation will be needed.

The add-on board scales signals so that the processor can handle a range of -3.3V to +3.3V. This means the processor's ADC reads a zero for -3.3V, 4,095 for +3.3V, and 2,048 for 0V. Since a zero ADC reading does not equal 0V, we need to add an offset to our amplification; otherwise, the amplified output will have an offset.

Multiplying a 0V reading of 2,048 by two gives us 4,095, which would output as 3.3V. So, there's an offset of 2,048 that needs to be taken care of:

    for (int i = 0; i < SIZE; i++) {
        samples[i] = samples[i] * 2 - 2048;
    }

Finally, we add this code into process_data and the algorithm is done.

Sample* process_data(Sample* samples)
{
    for (int i = 0; i < SIZE; i++) {
        samples[i] = samples[i] * 2 - 2048;
    }
    
    return samples;
}

Things to watch out for

TODO finish

  • sample bit size
  • sample variable bit size
  • overflow