robert@464: /* robert@464: ____ _____ _ _ robert@464: | __ )| ____| | / \ robert@464: | _ \| _| | | / _ \ robert@464: | |_) | |___| |___ / ___ \ robert@464: |____/|_____|_____/_/ \_\ robert@464: robert@464: The platform for ultra-low latency audio and sensor processing robert@464: robert@464: http://bela.io robert@464: robert@464: A project of the Augmented Instruments Laboratory within the robert@464: Centre for Digital Music at Queen Mary University of London. robert@464: http://www.eecs.qmul.ac.uk/~andrewm robert@464: robert@464: (c) 2016 Augmented Instruments Laboratory: Andrew McPherson, robert@464: Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack, robert@464: Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved. robert@464: robert@464: The Bela software is distributed under the GNU Lesser General Public License robert@464: (LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt robert@464: */ robert@464: robert@464: robert@464: #include robert@464: #include robert@464: #include robert@464: robert@464: // Set range for analog outputs designed for driving LEDs robert@464: const float kMinimumAmplitude = (1.5 / 5.0); robert@464: const float kAmplitudeRange = 1.0 - kMinimumAmplitude; robert@464: robert@464: float gFrequency; robert@464: float gPhase; robert@464: float gInverseSampleRate; robert@464: robert@464: bool setup(BelaContext *context, void *userData) robert@464: { robert@464: // Retrieve a parameter passed in from the initAudio() call robert@464: gFrequency = *(float *)userData; robert@464: robert@464: if(context->analogFrames == 0) { robert@464: rt_printf("Error: this example needs the matrix enabled\n"); robert@464: return false; robert@464: } robert@464: robert@464: gInverseSampleRate = 1.0 / context->analogSampleRate; robert@464: gPhase = 0.0; robert@464: robert@464: return true; robert@464: } robert@464: robert@464: void render(BelaContext *context, void *userData) robert@464: { robert@464: for(unsigned int n = 0; n < context->analogFrames; n++) { robert@464: // Set LED to different phase for each matrix channel robert@464: float relativePhase = 0.0; robert@464: for(unsigned int channel = 0; channel < context->analogChannels; channel++) { robert@464: float out = kMinimumAmplitude + kAmplitudeRange * 0.5f * (1.0f + sinf(gPhase + relativePhase)); robert@464: robert@464: analogWrite(context, n, channel, out); robert@464: robert@464: // Advance by pi/4 (1/8 of a full rotation) for each channel robert@464: relativePhase += M_PI * 0.25; robert@464: } robert@464: robert@464: gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate; robert@464: if(gPhase > 2.0 * M_PI) robert@464: gPhase -= 2.0 * M_PI; robert@464: } robert@464: } robert@464: robert@464: void cleanup(BelaContext *context, void *userData) robert@464: { robert@464: robert@464: } robert@464: robert@464: /* ------------ Project Explantation ------------ */ robert@464: robert@464: /** robert@500: \example analog-output/render.cpp robert@464: robert@464: Fading LEDs robert@464: ----------- robert@464: robert@464: This sketch uses a sine wave to drive the brightness of a series of LEDs robert@464: connected to the eight analog out pins. Again you can see the nested `for` loop robert@464: structure but this time for the analog output channels rather than the audio. robert@464: robert@464: - connect an LED in series with a 470ohm resistor between each of the analogOut pins and ground. robert@464: robert@464: Within the first for loop in render we cycle through each frame in the analog robert@464: output matrix. At each frame we then cycle through the analog output channels robert@464: with another for loop and set the output voltage according to the phase of a robert@464: sine tone that acts as an LFO. The analog output pins can provide a voltage of robert@464: ~4.092V. robert@464: robert@464: The output on each pin is set with `analogWrite()` within the for loop that robert@464: cycles through the analog output channels. This needs to be provided with robert@464: arguments as follows `analogWrite(context, n, channel, out)`. Channel is robert@464: where the you give the address of the analog output pin (in this case we cycle robert@464: through each pin address in the for loop), out is the variable that holds the robert@464: desired output (in this case set by the sine wave). robert@464: robert@464: Notice that the phase of the brightness cycle for each led is different. This robert@464: is achieved by updating a variable that stores a relative phase value. This robert@464: variable is advanced by pi/4 (1/8 of a full rotation) for each channel giving robert@464: each of the eight LEDs a different phase. robert@464: */