3.4 C implementation
Assuming you have successfully implemented a passthrough in the previous guide, we can simply copy and paste this project from within the SW4STM32 software. After pasting it, a pop-up will ask to give a name to the copied project. We recommend choosing a name with the current date and "alien_voice" in it. Remember to delete the binary (ELF) file of the original project inside the copied project.
Setting up timer for benchmarking
Open the CubeMX software to update the initialization code by opening the IOC file of the copied project.
For this exercise, we will only need to add the configuration of a timer (to benchmark our implementation) as the rest of the system is already up and running. In order to activate a timer, you need to set a "Clock Source". This is done from the "Pinout" tab on the left-hand column as shown below:

Figure: Set the "Clock Source" to "Internal Clock" in order to enable "TIM2".
Next, we need to configure the timer from the "Configuration" tab by pressing "TIM2" under "Control" (see below).

A pop-up similar to below should appear.

You can leave the rest of the parameters as is for "TIM2". Finally, you can update the initialization code by pressing the gear button in the toolbar. As before, do not open the project when prompted to do; select "Close".
You can now open the SW4STM32 software. In order to use the timer we configured, we will need to define a variable to keep track of the time and a macro to reset the timer. Between the USER CODE BEGIN PV and USER CODE END PV comments, add the following lines in the main.c file.
To use this macro, just call it in your code, then the variable current_time_us will be updated and the timer will be reset.
We want to assess if the processing time is longer or shorter than what our chosen buffer length and sampling frequency allows us. To do this, we will define some additional variables and constants (also between the USER CODE BEGIN PV and USER CODE END PV comments).
In between the USER CODE BEGIN 2 and USER CODE END 2 comments, we propose adding the following lines to read the timer and print the result of the benchmarking tool to the console.
You will notice that we used a printf function in order to output text on the debug console. To enable this function you need to make the following changes to your project:
In the Project Properties ("right-click" project > Properties), navigate to "C/C++ Build > Settings" on the left-hand side (see the figure below). Under "MCU GCC Linker -> Miscellaneous", update the "Linker flags" field with:

Add the following function prototype above the
mainfunction (e.g. between theUSER CODE BEGIN PFPandUSER CODE END PFPcomments):Add the following function call in the body of the
mainfunction (before anyprintf):In Debug Configurations (dropdown from the bug icon) add the following option under the "Startup" tab:
After this setup, the printf output will be shown in the debug console of Eclipse (precisely in the open ocd console). Be careful, the modification made in the Debug Configuration will not stay if you copy and paste your project to make a new version!
Alien voice effect
We will now add our robot voice effect! As mentioned previously, we will also implement a simple high pass filter and add a gain to make the output more audible. Below is the final process function we propose you to use. Insert it between the USER CODE BEGIN 4 and USER CODE END 4 comments.
Copy the sinusoid lookup table below and place it between the USER CODE BEGIN PV and USER CODE END PV comments.
Extra features
If you have some extra time, we propose to make a few improvements to the system!
We will now program one of the on-board buttons - the blue button called "B1" - to toggle the alien voice effect. Copy the following code between the USER CODE BEGIN PV and USER CODE END PV comments.
In the above code snippet, you will find the state variable we propose for the FX (effects) state and the callback that is needed to react to the button. To activate the callback, you need to go into CubeMX and enable "EXTI line 4 to 15" from the Configuration tab under "System > NVIC". Then modify your process function using a condition as proposed in the code snippet below.
Finally, you can try changing the modulation frequency and creating your lookup tables by running this Python script for modified values of f_sine.
Congrats on implementing your (perhaps) first voice effect! In the next chapter, we will implement a more sophisticated high-pass filter than the one used here. To this end, we will come across fundamental theory and practical skills in digital filter design.
Last updated
Was this helpful?