-
Notifications
You must be signed in to change notification settings - Fork 139
/
render.cpp
99 lines (80 loc) · 3.2 KB
/
render.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
____ _____ _ _
| __ )| ____| | / \
| _ \| _| | | / _ \
| |_) | |___| |___ / ___ \
|____/|_____|_____/_/ \_\
http://bela.io
*/
/**
\example Analog/analog-input/render.cpp
Connecting potentiometers
-------------------------
This sketch produces a sine tone, the frequency and amplitude of which are
modulated by data received on the analog input pins. Before looping through each audio
frame, we declare a value for the `frequency` and `amplitude` of our sine tone;
we adjust these values by taking in data from analog sensors (for example potentiometers)
with `analogRead()`.
- connect a 10K pot to 3.3V and GND on its 1st and 3rd pins.
- connect the 2nd middle pin of the pot to analogIn 0.
- connect another 10K pot in the same way but with the middle pin connected to analogIn 1.
The important thing to notice is that audio is sampled twice as often as analog
data. The audio sampling rate is 44.1kHz (44100 frames per second) and the
analog sampling rate is 22.05kHz (22050 frames per second). Notice that we are
processing the analog data and updating frequency and amplitude only on every
second audio sample, since the analog sampling rate is half that of the audio.
````
if(!(n % gAudioFramesPerAnalogFrame)) {
// Even audio samples: update frequency and amplitude from the analog inputs
frequency = map(analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputFrequency), 0, 1, 100, 1000);
amplitude = analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputAmplitude);
}
````
*/
#include <Bela.h>
#include <cmath>
float gPhase;
float gInverseSampleRate;
int gAudioFramesPerAnalogFrame = 0;
// Set the analog channels to read from
int gSensorInputFrequency = 0;
int gSensorInputAmplitude = 1;
bool setup(BelaContext *context, void *userData)
{
// Check if analog channels are enabled
if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) {
rt_printf("Error: this example needs analog enabled, with 4 or 8 channels\n");
return false;
}
// Useful calculations
gAudioFramesPerAnalogFrame = context->audioFrames / context->analogFrames;
gInverseSampleRate = 1.0 / context->audioSampleRate;
gPhase = 0.0;
return true;
}
void render(BelaContext *context, void *userData)
{
static float frequency;
static float amplitude;
for(unsigned int n = 0; n < context->audioFrames; n++) {
if(gAudioFramesPerAnalogFrame && !(n % gAudioFramesPerAnalogFrame)) {
// read analog inputs and update frequency and amplitude
// Depending on the sampling rate of the analog inputs, this will
// happen every audio frame (if it is 44100)
// or every two audio frames (if it is 22050)
frequency = map(analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputFrequency), 0, 1, 100, 1000);
amplitude = analogRead(context, n/gAudioFramesPerAnalogFrame, gSensorInputAmplitude);
}
float out = amplitude * sinf(gPhase);
for(unsigned int channel = 0; channel < context->audioOutChannels; channel++) {
audioWrite(context, n, channel, out);
}
// Update and wrap phase of sine tone
gPhase += 2.0f * (float)M_PI * frequency * gInverseSampleRate;
if(gPhase > M_PI)
gPhase -= 2.0f * (float)M_PI;
}
}
void cleanup(BelaContext *context, void *userData)
{
}