robert@533: /* robert@533: ____ _____ _ _ robert@533: | __ )| ____| | / \ robert@533: | _ \| _| | | / _ \ robert@533: | |_) | |___| |___ / ___ \ robert@533: |____/|_____|_____/_/ \_\ robert@533: robert@533: The platform for ultra-low latency audio and sensor processing robert@533: robert@533: http://bela.io robert@533: robert@533: A project of the Augmented Instruments Laboratory within the robert@533: Centre for Digital Music at Queen Mary University of London. robert@533: http://www.eecs.qmul.ac.uk/~andrewm robert@533: robert@533: (c) 2016 Augmented Instruments Laboratory: Andrew McPherson, robert@533: Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack, robert@533: Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved. robert@533: robert@533: The Bela software is distributed under the GNU Lesser General Public License robert@533: (LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt robert@533: */ robert@533: robert@533: #include robert@533: #include robert@533: robert@533: float gFrequency = 4.0; robert@533: float gPhase; robert@533: float gInverseSampleRate; robert@533: robert@533: bool setup(BelaContext *context, void *userData) robert@533: { robert@533: robert@533: gInverseSampleRate = 1.0 / context->audioSampleRate; robert@533: gPhase = 0.0; robert@533: robert@533: return true; robert@533: } robert@533: robert@533: void render(BelaContext *context, void *userData) robert@533: { robert@533: // Nested for loops for audio channels robert@533: for(unsigned int n = 0; n < context->audioFrames; n++) { robert@533: robert@533: // Generate a sinewave with frequency set by gFrequency robert@533: // and amplitude from -0.5 to 0.5 robert@533: float lfo = sinf(gPhase) * 0.5; robert@533: // Keep track and wrap the phase of the sinewave robert@533: gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate; robert@533: if(gPhase > 2.0 * M_PI) robert@533: gPhase -= 2.0 * M_PI; robert@533: robert@533: for(unsigned int channel = 0; channel < context->audioChannels; channel++) { robert@533: // Read the audio input and half the amplitude robert@533: float input = audioRead(context, n, channel) * 0.5; robert@533: // Write to audio output the audio input multiplied by the sinewave robert@533: audioWrite(context, n, channel, (input*lfo)); robert@533: robert@533: } robert@533: } robert@533: robert@533: // Nested for loops for analog channels robert@533: for(unsigned int n = 0; n < context->analogFrames; n++) { robert@533: for(unsigned int ch = 0; ch < context->analogChannels; ch++) { robert@533: // Read analog channel 0 and map the range from 0-1 to 0.25-20 robert@533: // use this to set the value of gFrequency robert@533: gFrequency = map(analogRead(context, n, 0), 0.0, 1.0, 0.25, 20.0); robert@533: robert@533: } robert@533: } robert@533: robert@533: } robert@533: robert@533: void cleanup(BelaContext *context, void *userData) robert@533: { robert@533: robert@533: } robert@533: robert@533: robert@533: /** robert@533: \example tremolo/render.cpp robert@533: robert@533: A simple tremolo effect robert@533: ----------------------- robert@533: robert@533: This sketch demonstrates how to make a simple tremolo effect with one potiometer to robert@533: control the rate of the effect. A tremolo effect is a simple type of amplitude modulation robert@533: where the amplitude of one signal is continuous modulated by the amplitude of another. robert@533: This is achieved by multiplying to signals together. robert@533: robert@533: In this example we want to create a tremolo effect like that you would find in a guitar robert@533: effects box so our first signal will be our audio input into which we could plug a guitar robert@533: or external sound source. This will be our 'carrier' signal. robert@533: robert@533: The second signal that we will use, the 'modulator', will be a low freqeuncy oscillator (LFO), robert@533: in this case a sinetone which we will generate in the same way as the 01-Basic/sinetone example. robert@533: The frequency of this sinetone is determined by a global variable, `gFrequency`. Again, the robert@533: sinetone is produced by incrementing the phase of a sine function on every audio frame. robert@533: robert@533: In `render()` you'll see two nested for loop structures, one for audio and the other for the robert@533: analogs. You should be pretty familiar with this structure by now. In the first of these for loops robert@533: we deal with all the audio -- in the second with reading the analog input channels. We read the robert@533: value of analog input 0 and map it to an appropriate range for controlling the frequency robert@533: of the sine tone. robert@533: robert@533: The lfo is then mulitplied together with the audio input and sent to the audio output. robert@533: */