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

  1. //AcceleratedVibrato.c
  2. //gcc MKAiff.c AcceleratedVibrato.c -o AcceleratedVibrato
  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 envelopeDuration=2, startingValue=1, endingValue=7;
  19. double vibratoFrequency=startingValue, vibratoAngle=0, vibratoDepth=frequency / 100;
  20. envelopeDuration *= SAMPLE_RATE;
  21. double envelopeIncrement = ((endingValue - startingValue)/envelopeDuration);
  22. int i;
  23. for(i=0; i<numSamples; i+=NUM_CHANNELS)
  24. {
  25. audioBuffer[i] = sin(angle);
  26. angle += (frequency + sin(vibratoAngle) * vibratoDepth) * TWO_PI_OVER_SAMPLE_RATE;
  27. vibratoAngle += vibratoFrequency * TWO_PI_OVER_SAMPLE_RATE;
  28. if(i/NUM_CHANNELS < envelopeDuration) vibratoFrequency += envelopeIncrement;
  29. }
  30. aiffAppendFloatingPointSamples(aiff, audioBuffer, numSamples, aiffFloatSampleType);
  31. aiffSaveWithFilename(aiff, "AcceleratedVibrato.aif");
  32. aiffDestroy(aiff);
  33. return 0;
  34. }

Output:

Explanation of the Concepts

Not only can the frequency of an audio wave be modulated, byt the frequency of a sub-audio wave can be modulated as well. In the previous chapter we modulated the frequency of an audio-rate sine wave by a sub-audio-rate sine wave. Here we will modulate the frequency of that subaudio-rate sine wave by a linear envelope. This will cause the rate of the vibrato to change linearly over time. It is important to notice that this particular envelope is not as long as the sound that it is modulating. When the envelope ends, it holds its current value rather than returning to 0, or something else.

Explanation of the Code

This is identical to the previous example, except that the standard variables for a linear envelope have been declared on lines 26 and 27. On line 33, the vibrato sine-wave's value is added to the audio sine-wave's frequency, and on line 37 the envelope's value is added in turn to the vibrato sine-wave.