annotate projects/basic_analog_input/render.cpp @ 292:3d26df8a8a6c

Updated Heavy files to match latest Heavy API
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 24 May 2016 01:10:04 +0100
parents ac8eb07afcf5
children 5433c83ce04e
rev   line source
robert@269 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
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@269 17 /**
robert@269 18 \example 3_analog_input
robert@269 19
robert@269 20 Connecting potentiometers
robert@269 21 -------------------------
robert@269 22
robert@269 23 This sketch produces a sine tone, the frequency and amplitude of which are
robert@269 24 affected by data received on the analog pins. Before looping through each audio
robert@269 25 frame, we declare a value for the frequency and amplitude of our sine tone
robert@269 26 (line 55); we adjust these values by taking in data from analog sensors
robert@269 27 (for example, a potentiometer).
robert@269 28
robert@269 29 The important thing to notice is that audio is sampled twice as often as analog
robert@269 30 data. The audio sampling rate is 44.1kHz (44100 frames per second) and the
robert@269 31 analog sampling rate is 22.05kHz (22050 frames per second). On line 62 you might
robert@269 32 notice that we are processing the analog data and updating frequency and
robert@269 33 amplitude only on every second audio sample, since the analog sampling rate is
robert@269 34 half that of the audio.
robert@269 35
robert@269 36 Note that the pin numbers are stored in the variables `gAnalogInputFrequency` and
robert@269 37 `gAnalogInputAmplitude`. These are declared in the main.cpp file; if you look in
robert@269 38 that file you will see that they have the values of 0 and 1. Bear in mind that
robert@269 39 these are analog input pins which is a specific header!
robert@269 40 */
andrewm@57 41
andrewm@57 42 #include <BeagleRT.h>
andrewm@57 43 #include <Utilities.h>
andrewm@57 44 #include <rtdk.h>
andrewm@57 45 #include <cmath>
andrewm@57 46
andrewm@57 47 float gPhase;
andrewm@57 48 float gInverseSampleRate;
andrewm@57 49 int gAudioFramesPerAnalogFrame;
andrewm@57 50
andrewm@57 51 // These settings are carried over from main.cpp
andrewm@57 52 // Setting global variables is an alternative approach
andrewm@57 53 // to passing a structure to userData in setup()
andrewm@57 54
andrewm@57 55 extern int gSensorInputFrequency;
andrewm@57 56 extern int gSensorInputAmplitude;
andrewm@57 57
andrewm@57 58 // setup() is called once before the audio rendering starts.
andrewm@57 59 // Use it to perform any initialisation and allocation which is dependent
andrewm@57 60 // on the period size or sample rate.
andrewm@57 61 //
andrewm@57 62 // userData holds an opaque pointer to a data structure that was passed
andrewm@57 63 // in from the call to initAudio().
andrewm@57 64 //
andrewm@57 65 // Return true on success; returning false halts the program.
andrewm@57 66
robert@269 67
andrewm@57 68 bool setup(BeagleRTContext *context, void *userData)
andrewm@57 69 {
andrewm@57 70 if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) {
andrewm@57 71 rt_printf("Error: this example needs analog enabled, with 4 or 8 channels\n");
andrewm@57 72 return false;
andrewm@57 73 }
andrewm@57 74
andrewm@57 75 gAudioFramesPerAnalogFrame = context->audioFrames / context->analogFrames;
andrewm@57 76 gInverseSampleRate = 1.0 / context->audioSampleRate;
andrewm@57 77 gPhase = 0.0;
andrewm@57 78
andrewm@57 79 return true;
andrewm@57 80 }
andrewm@57 81
andrewm@57 82 // render() is called regularly at the highest priority by the audio engine.
andrewm@57 83 // Input and output are given from the audio hardware and the other
andrewm@57 84 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
andrewm@57 85 // will be 0.
andrewm@57 86
andrewm@57 87 void render(BeagleRTContext *context, void *userData)
andrewm@57 88 {
andrewm@57 89 float frequency = 440.0;
andrewm@57 90 float amplitude = 0.8;
andrewm@57 91
andrewm@57 92 // There are twice as many audio frames as matrix frames since audio sample rate
andrewm@57 93 // is twice as high
andrewm@57 94
andrewm@57 95 for(unsigned int n = 0; n < context->audioFrames; n++) {
andrewm@57 96 if(!(n % gAudioFramesPerAnalogFrame)) {
andrewm@57 97 // Even audio samples: update frequency and amplitude from the matrix
andrewm@57 98 frequency = map(analogReadFrame(context, n/gAudioFramesPerAnalogFrame, gSensorInputFrequency), 0, 1, 100, 1000);
andrewm@57 99 amplitude = analogReadFrame(context, n/gAudioFramesPerAnalogFrame, gSensorInputAmplitude);
andrewm@57 100 }
andrewm@57 101
andrewm@57 102 float out = amplitude * sinf(gPhase);
andrewm@57 103
andrewm@57 104 for(unsigned int channel = 0; channel < context->audioChannels; channel++)
andrewm@57 105 context->audioOut[n * context->audioChannels + channel] = out;
andrewm@57 106
andrewm@57 107 gPhase += 2.0 * M_PI * frequency * gInverseSampleRate;
andrewm@57 108 if(gPhase > 2.0 * M_PI)
andrewm@57 109 gPhase -= 2.0 * M_PI;
andrewm@57 110 }
andrewm@57 111 }
andrewm@57 112
andrewm@57 113 // cleanup() is called once at the end, after the audio has stopped.
andrewm@57 114 // Release any resources that were allocated in setup().
andrewm@57 115
andrewm@57 116 void cleanup(BeagleRTContext *context, void *userData)
andrewm@57 117 {
andrewm@57 118
andrewm@57 119 }