annotate projects/basic_analog_output/render.cpp @ 316:18996c7dfac1

Updated libpd, now compatible with GLIBC_2.13
author Giulio Moro <giuliomoro@yahoo.it>
date Sat, 28 May 2016 01:23:10 +0100
parents ac8eb07afcf5
children 5433c83ce04e
rev   line source
andrewm@0 1 /*
robert@269 2 ____ _____ _ _
robert@269 3 | __ )| ____| | / \
robert@269 4 | _ \| _| | | / _ \
robert@269 5 | |_) | |___| |___ / ___ \
robert@269 6 |____/|_____|_____/_/ \_\.io
robert@269 7
robert@269 8 */
robert@269 9
robert@269 10 /*
andrewm@0 11 *
robert@269 12 * Andrew McPherson and Victor Zappi
robert@269 13 * Queen Mary, University of London
andrewm@0 14 */
andrewm@0 15
robert@269 16 /**
robert@269 17 \example 3_analog_output
robert@269 18
robert@269 19 Fading LEDs
robert@269 20 -----------
robert@269 21
robert@269 22 This sketch uses a sine wave to drive the brightness of a series of LEDs
robert@269 23 connected to the eight analog out pins. Again you can see the nested `for` loop
robert@269 24 structure but this time for the analog output channels rather than the audio.
robert@269 25
robert@269 26 Within the first `for` loop in render we cycle through each frame in the analog
robert@269 27 output matrix. At each frame we then cycle through the analog output channels
robert@269 28 with another `for` loop and set the output voltage according to the phase of a
robert@269 29 sine tone that acts as an LFO. The analog output pins can provide a voltage of
robert@269 30 ~4.092V.
robert@269 31
robert@269 32 The output on each pin is set with `analogWriteFrame` within the `for` loop that
robert@269 33 cycles through the analog output channels. This needs to be provided with
robert@269 34 arguments as follows `analogWriteFrame(context, n, channel, out)`. Channel is
robert@269 35 where the you give the address of the analog output pin (in this case we cycle
robert@269 36 through each pin address in the for loop), out is the variable that holds the
robert@269 37 desired output (in this case set by the sine wave).
robert@269 38
robert@269 39 Notice that the phase of the brightness cycle for each led is different. This
robert@269 40 is achieved by updating a variable that stores a relative phase value. This
robert@269 41 variable is advanced by pi/4 (1/8 of a full rotation) for each channel giving
robert@269 42 each of the eight LEDs a different phase.
robert@269 43
robert@269 44 */
robert@269 45
andrewm@0 46
andrewm@56 47 #include <BeagleRT.h>
andrewm@56 48 #include <Utilities.h>
andrewm@0 49 #include <rtdk.h>
andrewm@0 50 #include <cmath>
andrewm@0 51
andrewm@0 52 // Set range for analog outputs designed for driving LEDs
andrewm@52 53 const float kMinimumAmplitude = (1.5 / 5.0);
andrewm@52 54 const float kAmplitudeRange = 1.0 - kMinimumAmplitude;
andrewm@0 55
andrewm@0 56 float gFrequency;
andrewm@0 57 float gPhase;
andrewm@0 58 float gInverseSampleRate;
andrewm@0 59
andrewm@56 60 // setup() is called once before the audio rendering starts.
andrewm@0 61 // Use it to perform any initialisation and allocation which is dependent
andrewm@0 62 // on the period size or sample rate.
andrewm@0 63 //
andrewm@0 64 // userData holds an opaque pointer to a data structure that was passed
andrewm@0 65 // in from the call to initAudio().
andrewm@0 66 //
andrewm@0 67 // Return true on success; returning false halts the program.
andrewm@0 68
andrewm@56 69 bool setup(BeagleRTContext *context, void *userData)
andrewm@0 70 {
andrewm@0 71 // Retrieve a parameter passed in from the initAudio() call
andrewm@0 72 gFrequency = *(float *)userData;
andrewm@0 73
andrewm@52 74 if(context->analogFrames == 0) {
andrewm@12 75 rt_printf("Error: this example needs the matrix enabled\n");
andrewm@0 76 return false;
andrewm@0 77 }
andrewm@0 78
andrewm@52 79 gInverseSampleRate = 1.0 / context->analogSampleRate;
andrewm@0 80 gPhase = 0.0;
andrewm@0 81
andrewm@0 82 return true;
andrewm@0 83 }
andrewm@0 84
andrewm@0 85 // render() is called regularly at the highest priority by the audio engine.
andrewm@0 86 // Input and output are given from the audio hardware and the other
andrewm@0 87 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
andrewm@0 88 // will be 0.
andrewm@0 89
andrewm@52 90 void render(BeagleRTContext *context, void *userData)
andrewm@0 91 {
andrewm@56 92 for(unsigned int n = 0; n < context->analogFrames; n++) {
andrewm@0 93 // Set LED to different phase for each matrix channel
andrewm@0 94 float relativePhase = 0.0;
andrewm@56 95 for(unsigned int channel = 0; channel < context->analogChannels; channel++) {
andrewm@0 96 float out = kMinimumAmplitude + kAmplitudeRange * 0.5f * (1.0f + sinf(gPhase + relativePhase));
andrewm@0 97
andrewm@52 98 analogWriteFrame(context, n, channel, out);
andrewm@0 99
andrewm@0 100 // Advance by pi/4 (1/8 of a full rotation) for each channel
andrewm@0 101 relativePhase += M_PI * 0.25;
andrewm@0 102 }
andrewm@0 103
andrewm@0 104 gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate;
andrewm@0 105 if(gPhase > 2.0 * M_PI)
andrewm@0 106 gPhase -= 2.0 * M_PI;
andrewm@0 107 }
andrewm@0 108 }
andrewm@0 109
andrewm@56 110 // cleanup() is called once at the end, after the audio has stopped.
andrewm@56 111 // Release any resources that were allocated in setup().
andrewm@0 112
andrewm@56 113 void cleanup(BeagleRTContext *context, void *userData)
andrewm@0 114 {
andrewm@0 115
andrewm@0 116 }