S0002E – DSP Systems In Practice
nadlun-5@student.ltu.se
rikqva-5@student.ltu.se
Abstract
This report is for a project in the course DSP - Systems in Practice (S0002E). The project is about the design and implementation of a signal generator on the STUD-1 DSP Development Board .
There are many elements to take into consideration when implementing mathematical waveform algorithms on a DSP. This report discusses the problems and solutions for the implementation, ranging from division, frequency scaling to waveform algorithms.
The STUD-1 DSP Development Board has a user interface which contains one LCD, 4 LEDs and two rotary encoders. These were utilized to implement the waveform and scaling selections.
1 Introduction 2
2 Scaling 3
2.1 Amplitude Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.2 Frequency Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
3 Ideal Signals 5
3.1 Square Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
3.2 Sawtooth Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
3.3 Triangle Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
3.4 Sinusoid Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
4 Quantized Signals 11
4.1 Square Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
4.2 Sawtooth Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
4.3 Triangle Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
4.4 Sinusoid Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
5 User Interface 18
6 Analysis & Results 19
6.1 Amplitude Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
6.2 Frequency Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
6.3 Square Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
6.4 Sawtooth Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
6.5 Triangle Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
6.6 Sinusoid Wave . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
7 Conclusion 21
A Matlab Code 22
A.1 Sinusoid waveform implementation . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
1
The development board used for this project, the STUD-1 , is developed by Rubico. It has the
ADSP-2191 Digital Signal Processing (DSP) chip, which uses 16 bits fixed point arithmetics. The
DSP uses the 1.15 binary representation for numbers.
The assembler used is the as219x , and linker ld21 which are a part of the open21xx tool suite from SharpShin . The bootable program file ( *.bin
) is loaded to the EEPROM on the STUD-1 DSP
Development Board using PonyProg2000 . To run the program on the development board all that is needed is to press the reset switch.
The idea of the project is to create a signal generator that can handle some preprogrammed signals and noises, a preliminary list can be found below. The signals should also be user selectable using the interface on the STUD-1 DSP Development Board . Some of the signal parameter should also be selectable using the interface.
The following functions should be implemented, with tunable parameters:
• All Pass Buffer
• Square
• Triangle
• Sawtooth
• Inverted Sawtooth
• Sinusoid
The all pass buffer should simply forward the input signal, and scale the amplitude if selected.
The other waveforms should be implemented directly on the DSP and ignoring all other inputs at that time.
The goal of the project is of course to make the ideas into reality. Learn some techniques on how to implement and approximate sinusoids on the DSP chip in assembler.
2
One important aspect of a signal generator is to be able to change some paremeters since it’s not practical to use if you have to reprogram it every time you need to change something. In this section the method for scaling the amplitude and frequency will be analyzed in detail. There will be both some theory behind it and the practical implementation.
The maximum amplitude is always set to one internally as default to decrease the amount of computational error. But sometimes it can be necessary to scale the output as well in case there is some sensitive equipment on the output.
There are several ways to scale the amplitude. On this DSP the number system is a fixed point
1.15 HEX and the internal signals will therefore be between -1 and almost 1. The scaling of output will therefore be simple to implement. This is because it’s just to multiply the output by a number between 0 and 1, depending on the desired scale factor.
Two classic ways to scale the output is to scale it linearly or logarithmically. The hearing is logarithmic and since most of this course is directed towards audio the output will be scaled logarithmically.
To make this implementation on the DSP a lookup table is calculated using matlab and converted to 1.15 HEX format. The scaling coefficient is placed in steps between 1 and 0 in 100 steps.
3
Frequency is one of those parameters that the user often want to specify. The logarithmic hearing is also reflected in the frequency aspect. This course is mostly directed towards audio instead of general signal theory. Therefore the frequency will be logarithmically scaled, similar to the amplitude model.
To continue on the sound aspect there are several different logarithmic tables directed towards music. In this project it was decided to use the tempered scale piano table, since it is standard in western music.
This list is imported to Matlab and converted to half period times in samples, as seen in figure 1.
Due to the quantization and the availability of steps in the higher frequency range the table had to be modified. At first there were a few duplicates when the half period time went close to zero
(high frequency).
There are two major ways to solve this problem, the best alternative if you only consider output signal is to increase the DAC clock frequency. This was sadly not a possibility in this case since the hardware is already made. The other option is to make the best of the situation and remove these duplicates. This means that some frequencies will be unavailable from this table.
To implement the sinusoid function the quarter period time was required which caused another problem. The DSP can only support fixed point numbers so if an odd half period is divided by two, one bit will be lost in the process. This does not sound like much but when there are only around 4 samples on a half period it can make a significant difference. To go around this problem the number of available output frequencies has to be limited further so only even half periods are allowed in the table.
Piano Frequencies
5000
4000
3000
2000
1000
0
0 10 60 70 20 30 40
Frequency number (n)
50
Piano Freq Scaled & Quantized Half Period Times
800
600
400
200
0
0 10 20 30 40
Frequency number (n)
50 60 70
Figure 1: Modified frequency table for the tempered scale implementation
4
The signals should be implemented on the DSP, but since it is inefficient to write code directly in assembler and search for errors the algorithms will be designed in two steps. The first step will be to implement the functions in Matlab with instructions available for the assembler so the conversion to assembler will be simplified.
This section will deal with the ideal algorithm implementation in Matlab, for the real implementation see section 4. It will be divided into subsections, one for each waveform.
The first function implemented was the square wave, because it is the simplest one on the list specified above. Because all thats required to make it work is to switch sign of the output at a fixed rate.
All of the waveforms including this one will be scaled in frequency. One simple way to implement that is to go by the half period time and make the change when a counter reaches that point.
For the square wave the only thing required is to implement the counter, then switch the sign and reset the counter every time a half period has passed. This can also be expressed in a mathematical form seen in equation 1, y = ( − 1) n
·
T
1 / 2 (1) where n is the number of half period times T
1 / 2 that has passed.
The result of this ideal function can be seen in figure 2. The selected frequency setting is just one example, but the amplitude is set to the maximum value available from the DSP.
Matlab Generated Square Wave
0
−0.2
−0.4
−0.6
−0.8
0.4
0.2
0.8
0.6
0 0.5
1 1.5
2 2.5
Samples (n)
3 3.5
4 x 10
4.5
4
Figure 2: Ideal Matlab implementation of the square waveform
5
The second wave on the list to be implemented was the sawtooth waveform. The sawtooth waveform has a linear slope and a transient jump back down to the start. The linear slope can be achieved by making a fixed increment every sample and simply ignore the overflow. When the overflow occurs the output will get the opposite sign, so the reset part takes care of itself.
To be able to scale the frequency of the waveform there are two major options available. First is to simply change the increment size for the sawtooth wave instead of changing the half period length as was done for the square wave. The other option is to keep the same half period length used for the square wave and calculate the increment value from that.
To keep the scaling simple it was decided to use the half period length as scaling factor for all functions. The slope is a straight line described by equation 2, where m is a simple offset found in equation 3.
The slope coefficient is the same as the increment step for the next sample and is defined as k in equation 3. The ∆ y and ∆ x term is defined as the difference in amplitude and frequency respectively between the next peak and the current sample.
y = kx + m (2) where m = − 1 and k =
∆ y
∆ x
(3) and
0 ≤ x ≤ T
1 / 2
(4)
The result of this ideal equation can be seen in figure 3. The selected frequency is just one example, the amplitude is set to the maximum possible output from the DSP.
Matlab Generated Sawtooth Wave
1
0.8
0.6
0.4
0.2
0
−0.2
−0.4
−0.6
−0.8
−1
0 0.5
1 1.5
2 2.5
Samples (n)
3 3.5
4 4.5
x 10
4
Figure 3: Ideal Matlab implementation of the sawtooth waveform
6
The triangle waveform is very similar to the sawtooth waveform, but instead of letting the output overflow each half period it should start going back down. The only real change thats required is to add another sign variable s to the output equation, seen in equation 5.
The m variable is just an offset so the wave will go between -1 and 1, and can be found in equation 6.
The slope coefficient k is the same as in the sawtooth case and can be found in equation 6.
The sign variable s should change sign every half period, the resulting equation can be found in equation 7.
y = s ( kx + m ) (5) where m = − 1 and k =
∆ y
∆ x
(6) and s = ( − 1) n
·
T
1 / 2 and 0 ≤ x ≤ T
1 / 2 where n is the number of half period times T
1 / 2 that has passed so far.
(7)
The result of this ideal equation can be seen in figure 4. The selected frequency is just one example, the amplitude is set to the maximum possible output from the DSP.
Matlab Generated Triangle Wave
0.4
0.2
0
−0.2
−0.4
−0.6
−0.8
−1
1
0.8
0.6
0 1 2 3 4
Samples (n)
5 6 7 8 x 10 4
Figure 4: Ideal Matlab implementation of the triangle waveform
7
There are several ways to implement a sinusoid function on limited hardware. For example by using a lookup table, polynomial approximations and filter resonators.
Lookup Table: A predefined table which is stepped through. The values are used as output.
Polynomial Approx: This will make an estimation of the sinusoid function using predefined mathematical expression.
Filter Resonator: Created from an IIR filter, with the poles located ideally on the unit circle, which can cause instability to the system.
A lookup table is easily created in Matlab and can simply be implemented on the DSP. Due to the architecture of the DSP, high resolution lookup tables are possible.
The polynomial approximations discussed here are the Pade and Taylor polynomials. This method does not require much memory space compared to a lookup table, but requires more mathematical operations instead.
A DSP with fixed point number system will suffer from quantization effects, therefore an IIR filter resonator with quantized coefficients can become very unstable. The output can diverge to infinity if the poles are outside of the unit circle. If the resonator have its poles located inside the unit circle instead, the output will decay over time. This method needs some checking algorithms to keep the output at a stable amplitude over time.
The focus in this report will be on the Pade and Taylor polynomials and their implementation.
To minimize the calculations only second order polynomial was implemented, as seen in figure 5 this is enough to get an acceptable precision. The graph looks fairly good between − π/ 2 and π/ 2, since the function is periodic this is enough to make a complete waveform, as described below.
1
Matlab Comparison between Ideal cosine and Pade/Taylor approximations
Real cos
Pade cos
Taylor cos
0.5
0
−0.5
−1
−1.5
−2
−3 −2 −1 0
ω
1 2 3
Figure 5: Comparison between the Pade and Taylor cosine approximations
8
To create a sinusoid function, either a cosine or sinus function can be considered, since the only difference is the phase. The approximation algorithms can differ quite a bit in complexity in some cases. For example both the Pade and Taylor approximations for the cosine function are a bit simpler to implement, compared to the corresponding sinusoid approximation. This can be seen in equation 8 and equation 9 respectively.
Second order Pade approximations:
y = cos( x ) ≈
12 − 5 x 2
12 + x 2
y = sin( x ) ≈ x (60 − 7 x 2 )
60 + 3 x 2
(8)
Second order Taylor approximations:
y = cos( x ) ≈ 1 − x 2
2!
+ x 4
4!
y = sin( x ) ≈ x − x 3
3!
+ x 5
5!
(9) where
− π ≤ x ≤ π (10)
When dealing with limited hardware with limited computational functions, a too complex approximation should be avoided. As division on the ADSP-2191 gives one bit precision for each operation, division should be avoided as much as possible. Division is also difficult to implement correctly on the DSP. Division by a number 2 n is on the other hand easily accomplished by shifting n steps to the right.
Due to these reasons, the Pade approximations are ruled out, which leaves the Taylor approximations. Because of the uneven divisors in the Taylor sinusoid approximation, the cosine approximation is more suited to be implemented on the DSP. Especially when the answer from the x 2 operation can be used to calculate x 4 , by utilizing x 4 = ( x 2 ) 2 .
Due to the periodic nature of the sinusoid, only a half period is required to recreate a complete function, if a sign change is made every half period. If this is utilized the Pade and Taylor approximation limits are changed from [ − π, π ] to [ − π/ 2 , π/ 2]. Then the precision would be greatly improved as seen in figure 5.
To utilize the system described above a phase offset is required, this can cause some problems with the implementation on the DSP. The negative half period is a mirrored copy of the positive half period, so it should be possible to take only the positive side and flip it. If interested, some of the more important aspects of this implementation in Matlab can be found in appendix A.1.
9
The result of the Taylor cosine approximation can be seen in figure 6. The selected frequency is just one example, the amplitude is set to the maximum possible output from the DSP.
The truly ideal sinusoid waveform is shown in blue color, and the Taylor implementation in green.
The Taylor approximation overlaps the ideal sinusoid almost at every sample. As expected, the approximation is not as good around 0. The red x ’s indicates when either a sign or a slope change is performed.
Matlab Generated Sinusoid Wave
0.6
0
−0.2
0.4
0.2
1
0.8
−0.4
−0.6
−0.8
−1
0 0.5
1
Samples (n)
1.5
Real cos
Taylor cos
Quarter period
indicator
2 x 10 5
Figure 6: Ideal Matlab implementation of the sinusoid waveform
10
This section will deal with the quantized signals and the corresponding problems.
The first waveform that was implemented on the DSP was the square wave. This because it is the simplest of all fundamental waveforms to produce digitally.
It was implemented straight forward according to the matlab implementation, see section 3.1. A sample counter was defined, to be able to determine if a half period is elapsed, and the half period time in samples is retrieved from a predefined lookup table, see section 2.2.
The output for a 500 Hz square wave signal can be seen in figure 7. Because of the low pass filter effect of the DAC , the transients will have some ringing artifact. This can be observed more in figure 8.
Figure 7: DSP square wave output for a 500 Hz signal
Another artifact from the DAC , is shown in figure 9. As the output is AC coupled, it will have the effect of a high pass filter, so that low frequency content will converge to 0. This is because the
DSP is made for audio, and bias currents can damage speakers or headphones.
A general purpose signal generator should be able to turn on/off this AC coupling. In some cases it could be desired to have low frequency signals, or a DC offset. This is not possible to implement with our hardware, due to the DAC .
11
Figure 8: DSP square wave output for about 1 kHz, showing LPF effect of the DAC
Figure 9: DSP square wave output for a 20 Hz signal, showing HPF effect of the DAC
12
The sawtooth waveform was first implemented using a constant increment and ignoring the frequency scaling, for testing purposes. Once it was confirmed that the increment factor works as intended it was time to implement the dynamic increment variable, see section 3.2.
Due to the previous tests with a fixed increment factor and period counter using the square wave, the only problem left is the calculation of the slope. The mathematics can be found in section 3.2, equation 2 and the only problem with this algorithm implementation is to make the division.
To calculate the number of samples left until the next half period switch (∆ x ), the current counter is subtracted from the half period length. The half period length should always be larger then the current sample so both of these numbers can be treated as unsigned.
To calculate the difference between the current sample and the maximum value of 1 (∆ y ), its just to subtract the two numbers. But since the current value could be negative the result could overflow, so this has to be taken care of. The simple solution used here is to first divide the current output and the maximum value (1) by two (arithmetic downshift one step), and the subtract. The downside of this operation is that the lowest bit will be lost, it can be saved but it will take a lot of effort.
To get the next increment value k it’s just to divide ∆ y by ∆ x , and up-shift the result by one bit afterwards to compensate for the previous downshift of ∆ y . As division on the ADSP-2191 gives one bit precision for each operation, 16 division computations needs to be performed to get a 16 bit result.
The inverted sawtooth waveform was also implemented, the only addition to the code was to make an if-statement at the end, changing the sign of the output. This caused no problems, since it was made in the same way as the amplitude scaling.
Figure 10: DSP sawtooth wave output for 500 Hz
13
The triangle waveform implementation is quite similar to the sawtooth waveform implementation described in section 4.2. The difference is mainly the boundary condition, instead of changing sign of the output, only the sign of the slope variable should be changed.
As seen in figure 11, this works as expected. Altough at high frequencies, the sample count is low for each period and the effect of this can be seen in figure 12.
At low frequencies, the triangle wave suffers from the same high pass effect as for the square waveform, seen in figure 9. This phenomenon is described more in section 4.1.
Figure 11: DSP triangle wave output for 500 Hz
14
Figure 12: DSP triangle output for about 5.5 kHz, showing the few samples available
15
The sinusoidal waveform is the main focus of this project, and was implemented according to the theory in section 3.4. One of the potential problems with the algorithm was the division and since that’s been tried before it should not cause much problems this time. However, the division was already sorted out during the implementation of the sawtooth waveform, see section 4.2.
The implementation of the Taylor polynomial was straight forward because it was pre-scaled in
Matlab to fit into the 1.15 Hex format. The division with the factorial coefficients are also prescaled in Matlab so only a multiplication is required, this will save a lot of cycles.
The major problem with this function was to implement the quarter period that was required for the sign changes. Since it is only possible to use integers for the sample counter it had to be a fix value. If for example the half period length is set to 5, the quarter period will be rounded to 2. This can cause a lot of problems with all odd half period lengths, especially at the higher frequencies.
One way to ”fix” this problem is to increase the speed of the DAC and ignore the effect. This is not a possibility in our case, so the second option was to try and implement an odd offset at some periods to compensate. This should be possible in theory, but due to time limitations there was not enough time to make it work.
The third alternative is to make modifications to the half period times. The only parts affected are the odd values in the list, so the simple way is to remove or round all odd half period lengths so they become even. This is far from an elegant solution but it works with minimal changes to the other parts of the algorithms.
Figure 13: DSP sinusoid wave output for 500 Hz
16
Because the second order Taylor approximation isn’t perfect, there is an error when crossing the
0. This error can be seen in detail in figure 14. The error is mostly noticed in the lower frequency range, as the skip is just over one sample. When increasing frequency, there are less samples altogether, and the filter effect on the DAC reduces the effect.
Figure 14: DSP sinusoid approximation error, due to the order of the polynomial
There are ways to minimize this error, for example by increasing the order of the approximation. To get a really smooth approximation the polynomial order must be increased significantly. Because this requires more computations, there is another solution available that could be worth taking into consideration.
The solution would be to take the average of the second order Pade and Taylor approximations.
This would yield a good match between low order of the polynomials and still get a highly improved result. The idea of this can be seen in figure 5 page 8. The Taylor approximation lies a bit above the true cosine and the Pade approximation a bit below (between [ − π, π ]), and the true cosine is just in the middle. So by making a simple average of the two signals the error can be reduced significantly without increasing the order of the polynomials.
This is also one of those cool and time consuming ideas that wasn’t implemented in this project.
The solution was simply to ignore the effect, since it has no major effect in the resulting sound.
17
The STUD-1 DSP Development Board , seen in figure 15, has two rotary encoders, four LEDs
(three of which are dedicated to the user) and one LCD.
The left rotary encoder is stepped and the right rotary encoder is continuous. The left rotary encoder has also got a push button. Both of these are digital, so any changes will send a pulse to the DSP. The DSP polls the encoders for changes, which means that it will check for changes once every cycle in the main loop.
The LCD has 2 rows, and each row holds 16 characters. Macros for updating the display are provided by Rubico . The macros take pre-defined text strings and sends them to the display.
Figure 15: The STUD-1 DSP Development Board, used in this project
The left rotary encoder is used to select waveform by turning back and forth. Pressing the left rotary encoder will change which setting to modify. Modification of a selected setting is done by turning the right rotary encoder.
The available settings are:
Void: Selecting this setting will not change anything.
Frequency: Sets the frequency of the waveform.
Amplitude: Sets the output amplitude of the waveform.
Each user input performed on the rotary encoders also updates the LCD, displaying which waveform is active and which setting that is selected.
The LEDs are not used in this project.
18
There are many factors that need consideration when designing a digital signal generator on a DSP, such as fixed point arithmetics, clock frequency, hardware limitations etc. This section discusses these problems and solutions how to avoid them.
This section will deal with the problems from both the Matlab implementation and the DSP conversion.
The amplitude scaling was not implemented in Matlab because previous labs had contained similar code. To avoid losing bits when doing the calculations, the downscaling should only be for the output and not for the variables used to calculate the waveform.
To get a linear scale for the hearing the scale factor should be set as logarithmic, this was implemented using a lookup table.
The frequency scaling was implemented as half period times in a lookup table, because of the logarithmic behavior of the human hearing. All functions utilizes the half period times, and in addition the quarter period times for sinusoid.
The main concern was the downshift from half period time to quarter period time, as this operation will make the scale factor loose one bit. This is not a good thing, because this will make a corrupted output sinusoid waveform due to sign switching one sample early.
The solution was to round all half period times to even numbers, and remove all duplicate entries in the lookup table.
The square wave implementation in matlab was straight forwards and no major problems occurred.
For the DSP implementation, no problems occurred. The main problem is due to the hardware limitation of the DAC . Because of the low pass filter effect of the DAC , the output will have an underdampened step response. The DAC also has an high pass filter effect, which causes the DC of a waveform to converge to 0.
To implement a sawtooth waveform in matlab was straight forward. To make things easier for the DSP implementation later the code was adapted to DSP syntax. This went well for all parts except for the division to calculate the slope variable.
Due to the work done in matlab, the DSP implementation went smoothly, except division which was forseen.
19
The triangle waveform has a similar algorithm with the sawtooth waveform, The only difference is the boundary condition. So to make this implementation it was just to change some settings in one of the if statements.
The same problem was found with the hardware that the waveform is uneven at higher frequencies, but that’s hardware specific and can’t be solved for this project.
The waveform was the major focus of this project, there were several ideas for the implementation.
For example using a lookup table, IIR resonator and a polynomial approximation, for details see section 3.4. The Taylor polynomial approximation was used for this project, all details can be found in section 3.4.
The algorithm implementation was first made in matlab using similar operations as for the DSP.
This made the DSP implementation a lot easier since it was just to rewrite the syntax. However, there was one problem during the implementation which required some thinking.
To get the quarter period length its just to divide the half period length by two (downshift one step), this is simple in matlab and on the DSP. But the problem that occurred is the rounding of integers after division. When the half period length is low (high frequency) this rounding effect can have a significant effect.
For example if the half period length is equal to 5 the quarter period length would become
5 / 2 = 2 .
5 ≈ 2. This will effect the frequency scaling and also distort the signal.
The solution to this problem was to round all half period times to even numbers, and remove all duplicates. This will reduce the number of available frequencies, and also the frequency precision.
However, this rounding effect is negligible in the lower frequency range, because the human hearing is logarithmic.
20
The amplitude and frequency scaling are implemented using logarithmic lookup tables, to correspond with the human hearing. Because of rounding and quantization artifacts, the frequency precision is good at the lower frequency range. However it can’t handle high frequencies due to hardware limitations.
Before implementing the waveforms on the DSP, they were implemented in Matlab. This allowed the algorithms to be tested before implementation, which simplified the translation to DSP assembler. Some differences, such as division, could not be directly translated and took some time to implement.
The signal generator is suited for audio, because of the choice of using logarithmic frequency and amplitude scaling. The waveforms selected can be found in for example synthesizers, analog musical instruments and signal generators.
When generating waveforms digitally, the DAC clock frequency sets the maximums frequency limitation for the output. This is a problem that could not be solved without hardware modifications.
Polling or interrupt problems with the rotary encoders can cause the adjustments of the settings to become unsteady. This problem was not solved, because limited time and knowledge on exactly what caused these malfunctions.
21
31
32
33
34
35
26
27
28
29
30
21
22
23
24
25
16
17
18
19
20
8
9
6
7
3
4
1
2
5
10
11
12
13
14
15
41
42
43
44
45
36
37
38
39
40
46
47
48
49
50
Listing 1: Saturation code and comments
% Initialize variables used in the loop offset = 1; s i g n = 1; m = 1; k = 1; f o r n =1: length ( x )
% If the counter has reached its maximum i f p e r i o d _ c o u n t e r >= q u a r t _ p e r i o d
% Just for the red marks on the final plot k = k +1; yhp (1 , k ) = x ( n ) ; yhp (2 , k ) = 0;
% Change offset and start going backwards offset = -1;
% Change the sign of the output s i g n = s i g n * -1; end
% Calculate the new period counter p e r i o d _ c o u n t e r = p e r i o d _ c o u n t e r + offset ;
% If the period counter has reached the minimum i f p e r i o d _ c o u n t e r == 0
% Just for the red marks on the final plot k = k +1; yhp (1 , k ) = x ( n ) ; yhp (2 , k ) = y ( n -1) ; yhp (2 ,1) = 1; end
% Change offset and start going forwards offset = 1; p e r i o d _ c o u n t e r = 1;
% Calculate the current scaled x value xn ( n ) = p e r i o d _ c o u n t e r / half_perio d ;
% Scaled to match 1.15 HEX format and to be easily implemented y ( n ) = 1*0.2026 - xn ( n ) .^2 + xn ( n ) .^4*0.82 25 ;
% To compensate for the downscaling made above y ( n ) = y ( n ) * 4 * 0 . 6 1 6 9 * 2 ; end
% To give the output the correct sign y ( n ) = y ( n ) * s i g n ;
% Just for plotting the ideal cosine value ycos = cos ( x *2* p i ) ;
22