An Audio Synthesis Textbook For Musicians, Digital Artists and Programmers by Mike Krzyzaniak

  1. //SquareSiren.c
  2. //gcc MKAiff.c SquareSiren.c -o SquareSiren
  3. #include "MKAiff.h"
  4. #include <math.h>
  5. #define SAMPLE_RATE 44100
  6. #define NUM_CHANNELS 1
  7. #define BITS_PER_SAMPLE 16
  8. #define NUM_SECONDS 3
  9. const int numSamples = NUM_SECONDS * NUM_CHANNELS * SAMPLE_RATE;
  10. #define PI 3.141592653589793
  11. const double TWO_PI_OVER_SAMPLE_RATE = 2*PI/SAMPLE_RATE;
  12. int main()
  13. {
  14. MKAiff* aiff = aiffWithDurationInSeconds(NUM_CHANNELS, SAMPLE_RATE, BITS_PER_SAMPLE, NUM_SECONDS);
  15. if(aiff == NULL) return 0;
  16. float audioBuffer[numSamples];
  17. double frequency = 440, angle = 0;
  18. double sirenFrequency = 7, sirenAmplitude = frequency / 4;
  19. int sirenHalfWavelength = SAMPLE_RATE / (2*sirenFrequency);
  20. float nextSirenSample = sirenAmplitude;
  21. int i;
  22. for(i=0; i<numSamples; i+=NUM_CHANNELS)
  23. {
  24. if(!((i/NUM_CHANNELS) % sirenHalfWavelength))
  25. nextSirenSample *= -1;
  26. angle += (frequency + nextSirenSample) * TWO_PI_OVER_SAMPLE_RATE;
  27. audioBuffer[i] = sin(angle);
  28. }
  29. aiffAppendFloatingPointSamples(aiff, audioBuffer, numSamples, aiffFloatSampleType);
  30. aiffSaveWithFilename(aiff, "SquareSiren.aif");
  31. aiffDestroy(aiff);
  32. return 0;
  33. }

Output:

Explanation of the Concepts

This example modulates the frequency of a sine wave by a square wave. Another way to say that is that a the value of square wave will be added to the frequency of a sine wave. The sine wave is a regular, run-of-the-mill audio-rate sine wave. The square wave, on the other hand, has a frequency of only 7 cycles per second, which would be to low to hear if we tried to send it directly to the speaker. Luckily, we are not sending it to the speaker, we are just replacing the frequency variable of the sine wave with it. To clarify, the plot of the sine wave's frequency of a function of time will look like this:

Frequency-Time

The yellow line represents the nominal frequency of the sine wave, and the white line is the actual frequency of the sine wave after modulation.

For comparison, here is a plot of the resultant sine wave, in terms of the values of the actual samples in the audio buffer, plotted as a function of time.

Sample-Time

These plots indicate that the sine wave is heard alternately at a lower and higher frequency than its nominal frequency. The interval between low and high frequency is represented by the amplitude of the square wave. This is evident in the first graph above, but can be rather confusing conceptually, and it is important to remember, so I will state it again: The amplitude of the square wave controls the frequency deviation of the sine wave.

This typically means that we will want to define the amplitude of the square wave in terms of the frequency of the sine wave. If, for instance, the amplitude of the square wave were defined independently as just, say 50 units, that would create an interval of about 1.5 octaves about a 100 Hz sine wave (100 Hz plus or minus 50 is 50 and 150, which is an octave and a fifth). The same square wave would produce an interval of only a major second about a 1000 Hz sine wave (1000 Hz plus or minus 50 is 950 and 1050, which is 173 cents). For this reason, it is usually better to declare the amplitude of the square wave as a percentage of the frequency of the sine wave.

Explanation of the Code

Line 22 declares the standard variables for the sine wave, and lines 24-26 declare the standard variables for the square wave. Additionally, the square wave's amplitude has also been declared on line 24. This was not necessary in the initial chapter on square-waves, because it was assumed that the wave would simply oscillate between 1 and -1. On line 26 the initial sample of the square wave is set to its amplitude, because it will oscillate between its positive and negative amplitude. Lines 31 and 32 are the typical way of calculating the square wave's value. Lines 34 and 35 are the typical way f calculating the sine-wave's value, except that the value of the square wave is added to the frequency of the sine wave on line 34.