Skip to content

Commit e214292

Browse files
committed
audio_board: change control protocol to OSC
1 parent 3290bfe commit e214292

3 files changed

Lines changed: 85 additions & 99 deletions

File tree

hardware/firmware/audio_board/.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@
2222
[submodule "vendor/Adafruit-GFX-Library"]
2323
path = vendor/Adafruit-GFX-Library
2424
url = https://github.com/adafruit/Adafruit-GFX-Library
25+
[submodule "vendor/OSC"]
26+
path = vendor/OSC
27+
url = https://github.com/CNMAT/OSC

hardware/firmware/audio_board/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ set_property(SOURCE ${VENDOR_ROOT}/Audio/memcpy_audio.S PROPERTY LANGUAGE C)
9090
import_arduino_library(${VENDOR_ROOT} Adafruit-GFX-Library)
9191
import_arduino_library(${VENDOR_ROOT} Adafruit_BusIO)
9292
import_arduino_library(${VENDOR_ROOT} Adafruit_SSD1306)
93+
import_arduino_library(${VENDOR_ROOT} OSC)
9394

9495
# Build this project
9596
add_executable(${PROJECT_NAME}.elf main.cpp teensy4_usb_descriptor.c ${TEENSY_SOURCES} ${TEENSY_LIB_SOURCES})

hardware/firmware/audio_board/main.cpp

Lines changed: 81 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#include <Adafruit_GFX.h>
99
#include <Adafruit_SSD1306.h>
10+
#include <OSCMessage.h>
11+
#include <SLIPEncodedSerial.h>
1012

1113
#define SCREEN_WIDTH 128 // OLED display width, in pixels
1214
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
@@ -15,6 +17,8 @@
1517
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
1618
#endif
1719

20+
SLIPEncodedUSBSerial slip(Serial);
21+
1822
// GUItool: begin automatically generated code
1923
AudioInputI2SQuad i2s_quad1; //xy=336,677
2024
AudioSynthNoisePink pink1; //xy=338,824
@@ -209,6 +213,12 @@ set_crosspoint(int channel, int bus, float gain)
209213
matrix[bus][channel / 4]->gain(channel % 4, gain);
210214
}
211215

216+
float
217+
get_crosspoint(int channel, int bus)
218+
{
219+
return matrix[bus][channel / 4]->getGain(channel % 4);
220+
}
221+
212222
void
213223
set_mix(int bus, float in1, float in2, float in3, float in4, float in5, float in6)
214224
{
@@ -241,13 +251,69 @@ reset_state()
241251
set_mix(6, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
242252
}
243253

254+
void
255+
onOscChannel(OSCMessage &msg, int patternOffset)
256+
{
257+
char buf[12];
258+
int channel = -1;
259+
int addr;
260+
int offset;
261+
262+
// /ch/<num>
263+
for (int i = 0; i < 6; i++) {
264+
sprintf(buf, "/%d", i);
265+
offset = msg.match(buf, patternOffset);
266+
if (offset) {
267+
channel = i;
268+
addr = offset + patternOffset;
269+
break;
270+
}
271+
}
272+
if (channel < 0) return;
273+
274+
// /ch/<num>/mix
275+
offset = msg.match("/mix", addr);
276+
addr += offset;
277+
if (offset < 1) return;
278+
279+
// /ch/<num>/mix/<bus>/level
280+
int bus = -1;
281+
for (int i = 0; i < 6; i++) {
282+
sprintf(buf, "/%d/level", i);
283+
int offset = msg.match(buf, addr);
284+
if (offset) {
285+
bus = i;
286+
break;
287+
}
288+
}
289+
if (bus < 0) return;
290+
291+
if (msg.isFloat(0)) {
292+
set_crosspoint(channel, bus, msg.getFloat(0));
293+
} else {
294+
char address[22];
295+
snprintf(address, 22, "/ch/%d/mix/%d/level", channel, bus);
296+
OSCMessage response(address);
297+
response.add(get_crosspoint(channel, bus));
298+
slip.beginPacket();
299+
response.send(slip);
300+
slip.endPacket();
301+
}
302+
}
303+
304+
void
305+
onPacketReceived(OSCMessage msg)
306+
{
307+
msg.route("/ch", onOscChannel);
308+
}
309+
244310
void
245311
setup()
246312
{
247313

248314
#ifdef DISPLAY
249315
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
250-
Serial.println(F("SSD1306 allocation failed"));
316+
//Serial.println(F("SSD1306 allocation failed"));
251317
}
252318
display.display();
253319
delay(200);
@@ -261,12 +327,16 @@ setup()
261327
sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
262328
sgtl5000_1.volume(0.5);
263329
sgtl5000_1.lineInLevel(0, 0);
330+
sgtl5000_1.adcHighPassFilterDisable();
264331

265332
sgtl5000_2.setWire(1);
266333
sgtl5000_2.enable();
267334
sgtl5000_2.inputSelect(AUDIO_INPUT_LINEIN);
268335
sgtl5000_2.volume(0.5);
269336
sgtl5000_2.lineInLevel(0, 0);
337+
sgtl5000_2.adcHighPassFilterDisable();
338+
339+
slip.begin(115200);
270340
}
271341

272342
float
@@ -282,109 +352,21 @@ float levels_peak[12];
282352

283353

284354
void
285-
print_channel_gain(const char *name, int channel)
286-
{
287-
float gains[6] = {};
288-
gains[0] = matrix[channel][0]->getGain(0);
289-
gains[1] = matrix[channel][0]->getGain(1);
290-
gains[2] = matrix[channel][0]->getGain(2);
291-
gains[3] = matrix[channel][0]->getGain(3);
292-
gains[4] = matrix[channel][1]->getGain(0);
293-
gains[5] = matrix[channel][1]->getGain(1);
294-
Serial.printf("%-6s", name);
295-
for (float gain: gains) {
296-
Serial.printf("%-3d ", (int) (gain * 100));
297-
}
298-
Serial.printf("\r\n");
299-
}
300-
301-
void
302-
do_cmd()
355+
loop()
303356
{
304-
char cmd = cmdbuffer[0];
305-
switch (cmd) {
306-
case 'l': {
307-
int channel = cmdbuffer[1] - '1';
308-
if (channel > 5 || channel < 0) {
309-
Serial.printf("usage: l<channel> in range 1-6\r\n");
310-
return;
311-
}
312-
float gains[] = {
313-
matrix[channel][0]->getGain(0),
314-
matrix[channel][0]->getGain(1),
315-
matrix[channel][0]->getGain(2),
316-
matrix[channel][0]->getGain(3),
317-
matrix[channel][1]->getGain(0),
318-
matrix[channel][1]->getGain(1),
319-
};
320-
for (float gain: gains) {
321-
Serial.printf("%d ", (int) (gain * 100));
357+
int size;
358+
OSCMessage msg;
359+
if (slip.available()) {
360+
while (!slip.endofPacket()) {
361+
if ((size = slip.available()) > 0) {
362+
while (size--)
363+
msg.fill(slip.read());
322364
}
323-
Serial.printf("\r\n");
324-
break;
325-
}
326-
case 's': {
327-
int input = cmdbuffer[1] - '1';
328-
int output = cmdbuffer[2] - '1';
329-
int gain = cmdbuffer.substring(3).toInt();
330-
set_crosspoint(input, output, (float) gain / 100.0f);
331-
Serial.printf("%d -> %d = %d\r\n", input, output, gain);
332-
break;
333-
}
334-
case 'e': {
335-
// Use e0 and e1 to disable or enable uart echo
336-
echo = cmdbuffer[1] == '1';
337-
break;
338-
}
339-
case 'h': {
340-
Serial.printf("Audio mixer commands:\r\n");
341-
Serial.printf("e<0|1> set the UART echo state\r\n");
342-
Serial.printf("s<in><out><gain> set the gain for one crosspoint\r\n");
343-
Serial.printf("l<out> print the levels sent to a specific output\r\n");
344-
Serial.printf("[lf] print the whole human-readable mixing matrix\r\n");
345-
}
346-
case 13:
347-
// Special case, print human readable status
348-
Serial.printf(" IN1 IN2 IN3 PC USB1 USB2\r\n");
349-
print_channel_gain("OUT1", 0);
350-
print_channel_gain("OUT2", 1);
351-
print_channel_gain("HP L", 2);
352-
print_channel_gain("HP R", 3);
353-
print_channel_gain("USB1", 4);
354-
print_channel_gain("USB2", 5);
355-
break;
356-
case 27:
357-
case 91:
358-
// Catch escape sequences
359-
break;
360-
default:
361-
Serial.printf("cmd: %d\r\n", cmd);
362-
}
363-
364-
}
365-
366-
void
367-
do_uart()
368-
{
369-
while (Serial.available()) {
370-
char inChar = (char) Serial.read();
371-
if (echo) {
372-
Serial.write(inChar);
373365
}
374-
cmdbuffer += inChar;
375-
if (inChar == 13) {
376-
do_cmd();
377-
cmdbuffer = "";
366+
if (!msg.hasError()) {
367+
onPacketReceived(msg);
378368
}
379369
}
380-
}
381-
382-
void
383-
loop()
384-
{
385-
if (Serial.available()) {
386-
do_uart();
387-
}
388370

389371
if (rms1.available()) {
390372
for (int i = 0; i < 12; i++) {

0 commit comments

Comments
 (0)