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

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

Output:

Explanation of the Concepts

In the previous chapter we saw how to move a sound back and forth in a stereo field. Here, we will move a sound in an orbit around a quadrophonic field. The process is the same, except that the volume of each channel will be only 90 degrees (PI/2 radians) behind the next. The mathematical function cosine is the same as sine, except that it is advanced 90 degrees, so we can save a couple of additions by using it. Note that the above audio will not play properly unless you happen to have 4 speakers connected to your laptop!

Explanation of the Code

Line 9 sets the number of audio channels to 4. From there, this is identical to the previous chapter on stereo panning, except that here we have 2 extra intermediate channels whose volume will be 90 degrees (PI/2) out of phase with the other channels. This is accomplished using cosine. Notice that

cos(volumeAngle)

is identical to

sin(volumeAngle+PI/2)

and

cos(volumeAngle+PI)

is identical to

sin(volumeAngle+3*PI/2)

It is therefore better to use cosine, because it saves many multiplications and divisions.