- //SquareWave.c
- //gcc MKAiff.c SquareWave.c -o SquareWave
- #include "MKAiff.h"
- #define SAMPLE_RATE 44100
- #define NUM_CHANNELS 1
- #define BITS_PER_SAMPLE 16
- #define NUM_SECONDS 3
- const int numSamples = NUM_SECONDS * NUM_CHANNELS * SAMPLE_RATE;
- int main()
- {
- MKAiff* aiff = aiffWithDurationInSeconds(NUM_CHANNELS, SAMPLE_RATE, BITS_PER_SAMPLE, NUM_SECONDS);
- if(aiff == NULL) return 0;
- float audioBuffer[numSamples];
- double frequency = 440;
- int halfWavelength = SAMPLE_RATE / (2*frequency);
- float nextSample = -1;
- int i;
- for(i=0; i<numSamples; i+=NUM_CHANNELS)
- {
- if(!((i/NUM_CHANNELS) % halfWavelength))
- nextSample *= -1;
- audioBuffer[i] = nextSample;
- }
- aiffAppendFloatingPointSamples(aiff, audioBuffer, numSamples, aiffFloatSampleType);
- aiffSaveWithFilename(aiff, "SquareWave.aif");
- aiff = aiffDestroy(aiff);
- return 1;
- }
Output:
Builds On
AIFF TemplateExplanation of the Concepts
A square wave jumps between its highest value and its lowest value with no intermediate values. Here these values are -1 and +1, but in some analog implementations (like on the Arp 2500) the values are 0 and +1 or -1 and 0. Here is a plot of a square wave's value as a function of time:
The frequency content of a square wave is rich in odd numbered partials, but deprived of even numbered partials. This is evident in the Fourier Spectrograph:
For this reason, many musicians describe the square-wave as sounding "hollow".
Explanation of the Code
The value of the wave must flip from -1 to 1 every half-period. The number of frames in the half-period is calculated on line 21. line 26 checks to see if the current frame is the beginning of a half-period. The term (i/NUM_CHANNELS) is the current frame, and the current frame modulo the half-period will be zero at the beginning of every half-period, and non-zero at all other times. The logical 'not' operator, represented by an exclamation point in the C language, turns the value 0 into 'true' and all other values into 'false'. Line 27, which flips the value of the wave between -1 and +1, therefore, only gets evaluated every half-period.