Mmc-august-2012/Lab1

From CCRMA Wiki
Jump to: navigation, search

Lab 1 - Oscillators

In this lab, we will experiment with a variety of oscillators, both by themselves and in combination as FM operators.

Audio Bootup

Make sure you are up-to-date with your Xcode install, and that you are able to load code onto your iOS device. Create a new project ("single-view application"), and add MoAudio as described in the audioStuff download (found here: audioStuff.zip). To test everything out, write an audio callback that generates a sine wave at a fixed frequency, making sure that it runs in both the simulator and your device.

Basic Oscillators

Implement sine wave, triangle wave, sawtooth, and square wave oscillators using the phase-increment method shown in class. Structure each oscillator as a function that accepts a phase between [0,1] and returns the value at that phase, like this:

float exampleOsc(float p)
{
    return ???; // <-- fancy math goes here to figure out value for phase
}

Call this function from your callback, incrementing the phase after each frame. Software engineers may recognize this basic design pattern as modularity: the structuring of code into reusable blocks presenting a common interface. As we will see later, we can and will reuse these oscillators for more than simple waveform generation.

Add some basic UI to your app:

  • a widget to turn your oscillator on and off (you will probably find that, in computer music, an off-switch is the most useful UI of all)
  • a widget/widgets to select which type of oscillator is used
  • a widget/widgets to pick different notes and/or frequencies (you might find mtof.h in audioStuff useful for this -- mtof converts a MIDI note to a frequency)

Take a second to think about what kind of UI widget works best for the parameter being controlled.

FM

Introduce a modulator to your synthesis code. For basic FM, your code will look something like this:

float mod = mod_gain * exampleOsc(mod_phase); // calculate modulation
mod_phase += mod_freq/SRATE;
float sample = exampleOsc(osc_phase);
osc_phase += (osc_freq + mod)/SRATE;

Since each oscillator uses the same interface (take phase, return value), you can switch which waveform (sine, tri, saw, square) is used for the modulator and carrier -- modularity RULES. The specific combination of modulator and carrier waveform can have a dramatic effect on the resulting sound, so add some more UI to change the modulator oscillator.

Add UI to change the gain (multiplier) of the modulator. The larger the gain, the greater the "bandwidth" of the resulting sound. Experiment with what range this can accept -- values between 1-1000 are common in practice.

Add some UI to change the modulator frequency also. Note that, conventionally, FM only sounds tonal if the modulator frequency is an integer ratio of the carrier frequency, so your UI should account for this. But there are a lot of rich atonal timbres to be created in the realm of non-integral ratios between carrier and modulator, so feel free to experiment.

Bonus Round (Optional)

  • Use the accelerometer to vary FM parameters (modulator gain, modulator freq, carrier freq, carrier gain)
  • The FM implemented in this lab is 2-operator FM. A typical Yamaha DX7 patch used between 4 and 6 operators, in myriad configurations of modulation and re-modulation. Some of these configurations also used feedback-FM (i.e., a modulator that modulates itself). Experiment with multiple operator FM. What sort of UI would you use to control this?