Unfortunately in the bare-metal world, development tools often come at a premium that is out of reach of hobbyist budgets. While I am grateful that microcontroller vendors frequently offer free development software, I often do not have a great experience working with these tools. I do however find them to be a great starting point when becoming acquainted with a particular microcontroller family.

After learning that Visual Studio Code (VS Code) offers extensions for debugging microcontroller projects, I decided to move my entire embedded development into VS Code and have not looked back since. This post will go through the steps that I took to be able to develop and debug firmware on VS Code. The files and code will be specific to the SiLabs EFM32PG12 microcontroller but the steps should apply to most microcontrollers.


Optimizing Audio Code

This post is about squeezing more performance from your microcontroller. If you followed the FIR filter and reverb posts, you will have noticed that we needed to enable compiler optimizations to keep the audio processing time low enough to ensure that all incoming buffers will get processed in a timely fashion – i.e. causing no glitches or other artifacts in the output audio.

While the compiler is particularly smart when it comes to optimization, there are some things that it can miss that you as the programmer can add. Before we get into optimization techniques however, we need to talk about measuring performance.


Over the last year, I have been busy with a project which unfortunately de-prioritized the frequency of blog posts on this website. While the project, called BitMasher, is currently ongoing, I felt that now is a good time to share some of the details and progress made on it so far.

BitMasher is a hand-held audio effects ‘game’ – a mashup of an audio effects box and retro-game elements:


Spatial Audio Edition

A while ago, I gave a talk on The Audio Programmer meetup on how I built a spatial audio plugin which you can watch below:

The plugin (called Orbiter) is open source and can be found in Github. A pdf of the slides from the talk is available here:

The video covers the development process in more detail but some of the concepts in the talk are covered briefly in this post.



Reverb (reverberation) is a super interesting topic.  While the basic physical principle is easy to understand, implementing reverb in digital form is the subject of much ongoing research and development.

In this post, we will be making use of the comb filters that we learned about in previous posts and apply them to create an early type of reverberator, the Schroeder Reverberator.

Time Domain Representation of an Impulse with Reverb Applied

Comb Filters

The previous post introduced the delay line which, by itself doesn’t create particularly interesting sounds. However, it is one of the fundamental building blocks for many (interesting) audio effects.

In this post, we will be using the delay line to create another family of basic building blocks also often used to create audio effects, the comb filter.

A Comb Filter Example

Time Domain FIR Filtering

In the previous posts, we went through the basic exercise of reading audio samples through the ADC and outputting them to the DAC without manipulating the samples. This time, we’re going to kick things up a notch and add a filter to our audio processing chain.

Audio Sample with no Filtering

Audio Sample with Low Pass Filtering


If you like math and haven’t yet seen 3blue1brown’s video on space-filling curves, I suggest you check it out.

At the start of the video, a problem is given: provided an image, map each pixel to an audible frequency. The collection of unique frequencies of each pixel would then be summed, resulting in some waveform.


Audio Buffers

In the previous post, we created a very basic example that read a sample of audio from some input and routed it directly to output. At a sample rate of 40 kHz, this sequence of events repeated every 25 usec.

This is fine, provided that any processing you do on the sample does not last longer than 25 usec. Apply any heavier processing however and you run the risk of having your audio sound something like this: