Square-wave and boolean-modulated output using sampling


Tones of a specified frequency can easily be produced on nearly all mcus (microcontrollers) using pwm (pulse-width modulation). The output is a square wave. This post explores the use of sampling to produce frequency waves. Although this is more processor-intensive method, it does allow for greater control of the output wave. This post introduces the concept of “boolean-modulation”, where the on-off states of an input square-wave signal is processed by boolean logic. It demonstrates how to produce an effect that is similar to a binaural beat. Additional harmonics are introduced into the output, giving them a “funkier” effect.

Algorithm for producing sampled square waves

Suppose the following:

  • fs is the desired sampling frequency of the wave. fs = 44100 (Hz) is a typical sample rate for many audio files
  • fw_t is the frequency of the square wave to output. fw_t = 440 (Hz) is the frequency of the note “A”. More specifically, it is usually referred to “A4”.

The following algorithm, written in D, determines whether the output should be 0 or 1:

import std.math;
import std.stdio;

const float fw = 440; // frequency of wave
const float fs = 44100; // sample frequency
const int nsamples = 60 * cast(int)fs; // reserve space for 60 secs of tone

void main()
        float[] samples = new float[nsamples]; // the output
        float dt = 1 / fs; // time increment is inverse of sampling freq
        float t = 0; // time
        const float fw_t = 1.0/fw; // period of output wave
        for(int i=0; i< nsamples; i++) {
                t = fmod(t, fw_t); // limit time to one wave period
                samples[i] = 0;
                if(t>=0.5*fw_t) samples[i] = 1.0; // in second-half of wave
                t += dt; // increment time

        ... any extra processing, e.g. writing to file

It is an algorithm that can be translated easily to a microcontroller with a timer. The output is a 50% duty cycle. It can be changed easily.

Boolean modulation

Binaural beats are generated when two sine waves of similar, but non-identical, sine waves are added together. This method is not especially suited to microcontrollers because the output is of variable amplitude rather than a simple on/off of a GPIO pin.

However, all is not lost. The inspiration behind binaural beats can be modified to use simple boolean logic. The strategy is to generate two square waves of slightly different frequency. Their on/off states are OR’d together to produce the output state.

Here is example code:

import waved;
import std.math;
import std.stdio;

const float fw = 500; // frequency of wave
const float fs = 44100; // sample frequence
const int nsamples = 60 * cast(int)fs; // 60s
void main()
        float[] samples = new float[nsamples];
        float dt = 1 / fs;
        float t0 = 0, t1 = 0; // time of each of the two waves
        const float fw_t0 = 1.0/fw;
        const float fw_t1 = 1.0/(fw + 1.0); // add a little binaural
        for(int i=0; i< nsamples; i++) {
                samples[i] = 0;

                bool hi0= false;
                t0 = fmod(t0, fw_t0);
                if(t0>=0.5*fw_t0) hi0 = true;
                t0 += dt;

                bool hi1 = false;
                t1 = fmod(t1, fw_t1);
                if(t1>=0.5*fw_t1) hi1 = true;
                t1 += dt;
                if(hi0 || hi1) samples[i] = 0.1;
        writeln("sample array filled");
        Sound snd= Sound(cast(int)fs, 1, samples);
        encodeWAV(snd, "out.wav");

The frequency in this case is 500Hz. There is a small offset frequency – 1 Hz works well – that modifies the on/off state.

A 60 sec sample output is available here (470k size).

The source code is available here.

Parting remarks

This is an efficient way of generating waves with interesting tonal qualities for use in note production.

Ref: db7.102

About mcturra2000

Computer programmer living in Scotland.
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s