-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanalog output osc.cpp
More file actions
149 lines (121 loc) · 4.83 KB
/
analog output osc.cpp
File metadata and controls
149 lines (121 loc) · 4.83 KB
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
____ _____ _ _
| __ )| ____| | / \
| _ \| _| | | / _ \
| |_) | |___| |___ / ___ \
|____/|_____|_____/_/ \_\
The platform for ultra-low latency audio and sensor processing
http://bela.io
A project of the Augmented Instruments Laboratory within the
Centre for Digital Music at Queen Mary University of London.
http://www.eecs.qmul.ac.uk/~andrewm
(c) 2016 Augmented Instruments Laboratory: Andrew McPherson,
Astrid Bin, Liam Donovan, Christian Heinrichs, Robert Jack,
Giulio Moro, Laurel Pardue, Victor Zappi. All rights reserved.
The Bela software is distributed under the GNU Lesser General Public License
(LGPL 3.0), available here: https://www.gnu.org/licenses/lgpl-3.0.txt
*/
#include <Bela.h>
#include <cmath>
#include <OSCServer.h>
#include <OSCClient.h>
OSCServer oscServer;
OSCClient oscClient;
// Set range for analog outputs designed for driving LEDs
const float kMinimumAmplitude = (1.5 / 5.0);
const float kAmplitudeRange = 1.0 - kMinimumAmplitude;
float gFrequency = 1.0;
float gPhase;
float gInverseSampleRate;
//make an outputfreq and input array for all the analog ins and outs on the board. inputs are not yet implemented.
float outputfreq [8];
float outputPhases [8];
//this is the stuff for the osc server:
int localPort = 7562;
int remotePort = 7563;
const char* remoteIp = "192.168.7.1";
// parse messages received by OSC Server
// msg is Message class of oscpkt: http://gruntthepeon.free.fr/oscpkt/
int parseMessage(oscpkt::Message msg){
rt_printf("received message to: %s\n", msg.addressPattern().c_str());
int intArg;
float floatArg;
// this makes the bela expect a 32bit integer first for the channel # and a floating point argument for the frequency value second:
if (msg.match("/osc-test").popInt32(intArg).popFloat(floatArg).isOkNoMoreArgs()){
rt_printf("received int %i and float %f\n", intArg, floatArg);
}
else if (msg.match("/freq").popInt32(intArg).popFloat(floatArg).isOkNoMoreArgs()){
rt_printf("here\n");
//else if (msg.match("/freq").popFloat(floatArg).isOkNoMoreArgs()){
//rt_printf("here\n");
// we added an else if condition to make sure the received freq value is within certain range
if (floatArg <= 12000 && floatArg >= 0.00001)
{
rt_printf("received float %f\n", floatArg);
//gFrequency=floatArg;
// this makes the float write to the corresponding entry index in the array:
outputfreq[intArg]=floatArg;
}
}
return intArg;
}
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;
}
// Check that we have the same number of inputs and outputs.
if(context->audioInChannels != context->audioOutChannels ||
context->analogInChannels != context-> analogOutChannels){
printf("Error: for this project, you need the same number of input and output channels.\n");
return false;
}
gInverseSampleRate = 1.0 / context->analogSampleRate;
gPhase = 0.0;
for(int i = 0; i < 8; i++) {
outputPhases[i] = 0;
}
oscServer.setup(localPort);
oscClient.setup(remotePort, remoteIp);
// the following code sends an OSC message to address /osc-setup
// then waits 1 second for a reply on /osc-setup-reply
bool handshakeReceived = false;
oscClient.sendMessageNow(oscClient.newMessage.to("/osc-setup").end());
oscServer.receiveMessageNow(1000);
while (oscServer.messageWaiting()){
if (oscServer.popMessage().match("/osc-setup-reply")){
handshakeReceived = true;
}
}
if (handshakeReceived){
rt_printf("handshake received!\n");
} else {
rt_printf("timeout!\n");
}
return true;
}
void render(BelaContext *context, void *userData)
{
for(unsigned int n = 0; n < context->analogFrames; n++) {
for(unsigned int channel = 0; channel < context->analogOutChannels; channel++) {
float out = kMinimumAmplitude + kAmplitudeRange * 0.5f * (1.0f + sinf(outputPhases[channel]));
analogWrite(context, n, channel, out);
// Update and wrap phase of sine tone
//this is the original code using gFrequency from the analog out example
//gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate;
outputPhases[channel] += 2.0 * M_PI * outputfreq[channel] * gInverseSampleRate;
if(outputPhases[channel] > 2.0 * M_PI)
outputPhases[channel] -= 2.0 * M_PI;
}
// is this where updating the outputfreq array goes?
}
while (oscServer.messageWaiting()){
int count = parseMessage(oscServer.popMessage());
oscClient.queueMessage(oscClient.newMessage.to("/osc-acknowledge").add(count).add(4.2f).add(std::string("OSC message received")).end());
}
}
void cleanup(BelaContext *context, void *userData)
{
}