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

  1. //StereoPanning.c
  2. //gcc MKAiff.c StereoPanning.c -o StereoPanning
  3. #include "MKAiff.h"
  4. #include <math.h>
  5. #define SAMPLE_RATE 44100
  6. #define NUM_CHANNELS 2
  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 volumeFrequency = 1, volumeAngle = 0;
  19. float nextSample;
  20. int i;
  21. for(i=0; i<numSamples; i+=NUM_CHANNELS)
  22. {
  23. nextSample = sin(angle);
  24. audioBuffer[i] = nextSample * ((sin(volumeAngle) + 1) / 2);
  25. audioBuffer[i+1] = nextSample * ((sin(volumeAngle+PI) + 1) / 2);
  26. angle += frequency * TWO_PI_OVER_SAMPLE_RATE;
  27. volumeAngle += volumeFrequency * TWO_PI_OVER_SAMPLE_RATE;
  28. }
  29. aiffAppendFloatingPointSamples(aiff, audioBuffer, numSamples, aiffFloatSampleType);
  30. aiffSaveWithFilename(aiff, "StereoPanning.aif");
  31. aiffDestroy(aiff);
  32. return 0;
  33. }

Output:

Explanation of the Concepts

In the Basic Panning chapter, it was shown how to place a sound in the stereo field. We will now focus our attention on how to move a sound back and forth in the stereo field. This is accomplished by turning the volume up in the left channel while turning it down in the right channel, and vice-versum. Here, we will turn the volume up and down sinusoidally, and the volume of each channel will be out of phase by 180 degrees (see the chapter on sine waves for more on this), which will produce the desired effect. To state this in a way that puts it in context: we will start with an audio signal (here a 440 Hz sine wave), and we will modulate its amplitude by another (1 Hz) sine wave and send it to a channel. We will also modulate the original audio signal by a second, similar 1Hz sine wave, and send the result to the other channel.

Explanation of the Code

This example uses 2 sine waves. The variables for the audio-rate sine wave are declared on line 22 and are identical to those declared in the sine-wave chapter. On the next line (23) are the variables for another sine-wave, whose frequency is just 1 cycle per second. In the chapter on Simple Volume Control we learned that the volume of a signal can be controlled by simply multiplying every sample by some number between 0 and 1, so to modulate the amplitude, we just scale the volume-controling wave to be between 0 and 1, and multiply it by the audio wave. On line 29 the value of the audio wave is calculated. On line 30, the right channel is then calculated by multiplying the audio wave by the volume-controlling wave, which is scaled by adding one and dividing by 2. on line 31 the left channel is calculated in the same fashion, except that PI radians (180 degrees) are added to the angle of the volume-controlling wave before its value is calculated.