annotate examples/basic_analog_input/render.cpp @ 372:db2fe4e1b88e prerelease

Doxygen content added to each example render.cpp. References to AnalogReadFrame etc. removed from doxygen content.
author Robert Jack <robert.h.jack@gmail.com>
date Thu, 09 Jun 2016 18:16:05 +0100
parents 1feb9c23ac57
children 9dc5a0ccad25
rev   line source
robert@372 1 /*
robert@372 2 ____ _____ _ _
robert@372 3 | __ )| ____| | / \
robert@372 4 | _ \| _| | | / _ \
robert@372 5 | |_) | |___| |___ / ___ \
robert@372 6 |____/|_____|_____/_/ \_\.io
robert@372 7
robert@372 8 */
robert@372 9
andrewm@57 10 /*
andrewm@57 11 * render.cpp
andrewm@57 12 *
andrewm@57 13 * Created on: Oct 24, 2014
andrewm@57 14 * Author: parallels
andrewm@57 15 */
andrewm@57 16
robert@372 17 /**
robert@372 18 \example 3_analog_input
robert@372 19
robert@372 20 Connecting potentiometers
robert@372 21 -------------------------
robert@372 22
robert@372 23 This sketch produces a sine tone, the frequency and amplitude of which are
robert@372 24 affected by data received on the analog pins. Before looping through each audio
robert@372 25 frame, we declare a value for the frequency and amplitude of our sine tone
robert@372 26 (line 55); we adjust these values by taking in data from analog sensors
robert@372 27 (for example potentiometers) with `analogRead()`.
robert@372 28
robert@372 29 - connect a 10K pot to 3.3V and GND on its 1st and 3rd pins.
robert@372 30 - connect the 2nd middle pin of the pot to analogIn 0.
robert@372 31 - connect another 10K pot in the same way but with the middle pin connected to analogIn 1.
robert@372 32
robert@372 33 The important thing to notice is that audio is sampled twice as often as analog
robert@372 34 data. The audio sampling rate is 44.1kHz (44100 frames per second) and the
robert@372 35 analog sampling rate is 22.05kHz (22050 frames per second). On line 62 you might
robert@372 36 notice that we are processing the analog data and updating frequency and
robert@372 37 amplitude only on every second audio sample, since the analog sampling rate is
robert@372 38 half that of the audio.
robert@372 39
robert@372 40 Note that the pin numbers are stored in the variables `gAnalogInputFrequency` and
robert@372 41 `gAnalogInputAmplitude`. These are declared in the main.cpp file; if you look in
robert@372 42 that file you will see that they have the values of 0 and 1. Bear in mind that
robert@372 43 these are analog input pins which is a specific header!
robert@372 44 */
andrewm@57 45
giuliomoro@301 46 #include <Bela.h>
andrewm@57 47 #include <Utilities.h>
andrewm@57 48 #include <rtdk.h>
andrewm@57 49 #include <cmath>
andrewm@57 50
andrewm@57 51 float gPhase;
andrewm@57 52 float gInverseSampleRate;
andrewm@57 53 int gAudioFramesPerAnalogFrame;
andrewm@57 54
andrewm@57 55 // These settings are carried over from main.cpp
andrewm@57 56 // Setting global variables is an alternative approach
andrewm@57 57 // to passing a structure to userData in setup()
andrewm@57 58
andrewm@57 59 extern int gSensorInputFrequency;
andrewm@57 60 extern int gSensorInputAmplitude;
andrewm@57 61
andrewm@57 62 // setup() is called once before the audio rendering starts.
andrewm@57 63 // Use it to perform any initialisation and allocation which is dependent
andrewm@57 64 // on the period size or sample rate.
andrewm@57 65 //
andrewm@57 66 // userData holds an opaque pointer to a data structure that was passed
andrewm@57 67 // in from the call to initAudio().
andrewm@57 68 //
andrewm@57 69 // Return true on success; returning false halts the program.
andrewm@57 70
giuliomoro@301 71 bool setup(BelaContext *context, void *userData)
andrewm@57 72 {
andrewm@57 73 if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) {
andrewm@57 74 rt_printf("Error: this example needs analog enabled, with 4 or 8 channels\n");
andrewm@57 75 return false;
andrewm@57 76 }
andrewm@57 77
andrewm@57 78 gAudioFramesPerAnalogFrame = context->audioFrames / context->analogFrames;
andrewm@57 79 gInverseSampleRate = 1.0 / context->audioSampleRate;
andrewm@57 80 gPhase = 0.0;
andrewm@57 81
andrewm@57 82 return true;
andrewm@57 83 }
andrewm@57 84
andrewm@57 85 // render() is called regularly at the highest priority by the audio engine.
andrewm@57 86 // Input and output are given from the audio hardware and the other
andrewm@57 87 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
andrewm@57 88 // will be 0.
andrewm@57 89
giuliomoro@301 90 void render(BelaContext *context, void *userData)
andrewm@57 91 {
andrewm@57 92 float frequency = 440.0;
andrewm@57 93 float amplitude = 0.8;
andrewm@57 94
andrewm@57 95 // There are twice as many audio frames as matrix frames since audio sample rate
andrewm@57 96 // is twice as high
andrewm@57 97
andrewm@57 98 for(unsigned int n = 0; n < context->audioFrames; n++) {
andrewm@57 99 if(!(n % gAudioFramesPerAnalogFrame)) {
andrewm@57 100 // Even audio samples: update frequency and amplitude from the matrix
andrewm@308 101 frequency = map(analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputFrequency), 0, 1, 100, 1000);
andrewm@308 102 amplitude = analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputAmplitude);
andrewm@57 103 }
andrewm@57 104
andrewm@57 105 float out = amplitude * sinf(gPhase);
andrewm@57 106
andrewm@57 107 for(unsigned int channel = 0; channel < context->audioChannels; channel++)
andrewm@57 108 context->audioOut[n * context->audioChannels + channel] = out;
andrewm@57 109
andrewm@57 110 gPhase += 2.0 * M_PI * frequency * gInverseSampleRate;
andrewm@57 111 if(gPhase > 2.0 * M_PI)
andrewm@57 112 gPhase -= 2.0 * M_PI;
andrewm@57 113 }
andrewm@57 114 }
andrewm@57 115
andrewm@57 116 // cleanup() is called once at the end, after the audio has stopped.
andrewm@57 117 // Release any resources that were allocated in setup().
andrewm@57 118
giuliomoro@301 119 void cleanup(BelaContext *context, void *userData)
andrewm@57 120 {
andrewm@57 121
andrewm@57 122 }