Making sound again

This commit is contained in:
Neale Pickett 2020-10-25 11:36:58 -06:00
parent 41bbfdc1d7
commit 8aa7312ed5
8 changed files with 104 additions and 36 deletions

View File

@ -1,6 +1,9 @@
FQBN = adafruit:samd:adafruit_trellis_m4 FQBN = adafruit:samd:adafruit_trellis_m4
UF2_MOUNT = /mnt/chromeos/removable/TRELM4BOOT
default: build/uilleann.ino.uf2 default: build/uilleann.ino.uf2
install: build/uilleann.ino.uf2
./install.sh $< $(UF2_MOUNT)
# uf2conv.py is covered by an MIT license. # uf2conv.py is covered by an MIT license.
build/uf2conv.py: build/uf2conv.py:

View File

@ -1,4 +1,4 @@
// FM Algorithms used by the DX9 // Various FM Algorithms
// Excellent write-up: // Excellent write-up:
// https://gist.github.com/bryc/e997954473940ad97a825da4e7a496fa // https://gist.github.com/bryc/e997954473940ad97a825da4e7a496fa
@ -7,8 +7,37 @@
// Each operator has 4 input gains and one output gain: // Each operator has 4 input gains and one output gain:
// { 1→, 2→, 3→, 4→, →out} // { 1→, 2→, 3→, 4→, →out}
// 1→
#define ALG_SIMPLE \
{ \
{0, 0, 0, 0, 1}, \
{0}, \
{0}, \
{0}, \
}
// ⮎2→1→
#define ALG_OPL2_1(feedback) \
{ \
{0, 1, 0, 0, 1}, \
{0, feedback, 0, 0, 0}, \
{0}, \
{0}, \
}
// ⮎2→
// 1→
#define ALG_OPL2_2(feedback) \
{ \
{0, 0, 0, 0, 1} \
{0, feedback, 0, 0, 1} \
{0}, \
{0}, \
}
// ⮎4→3→2→1→ // ⮎4→3→2→1→
#define DX9_ALG_1(feedback) \ #define ALG_DX9_1(feedback) \
{ \ { \
{0, 1, 0, 0, 1}, \ {0, 1, 0, 0, 1}, \
{0, 0, 1, 0, 0}, \ {0, 0, 1, 0, 0}, \
@ -18,7 +47,7 @@
// ⮎4⬎ // ⮎4⬎
// 3→2→1→ // 3→2→1→
#define DX9_ALG_2(feedback) \ #define ALG_DX9_2(feedback) \
{ \ { \
{0, 1, 0, 0, 1}, \ {0, 1, 0, 0, 1}, \
{0, 0, 1, 1, 0}, \ {0, 0, 1, 1, 0}, \
@ -28,7 +57,7 @@
// ⮎4⬎ // ⮎4⬎
// 3→2→1→ // 3→2→1→
#define DX9_ALG_3(feedback) \ #define ALG_DX9_3(feedback) \
{ \ { \
{0, 1, 0, 1, 1}, \ {0, 1, 0, 1, 1}, \
{0, 0, 1, 0, 0}, \ {0, 0, 1, 0, 0}, \
@ -38,7 +67,7 @@
// ⮎4→3⬎ // ⮎4→3⬎
// 2→1→ // 2→1→
#define DX9_ALG_4(feedback) \ #define ALG_DX9_4(feedback) \
{ \ { \
{0, 1, 0, 1, 1}, \ {0, 1, 0, 1, 1}, \
{0, 0, 1, 0, 0}, \ {0, 0, 1, 0, 0}, \
@ -48,7 +77,7 @@
// ⮎4→3→ // ⮎4→3→
// 2→1→ // 2→1→
#define DX9_ALG_5(feedback) \ #define ALG_DX9_5(feedback) \
{ \ { \
{0, 1, 0, 0, 1}, \ {0, 1, 0, 0, 1}, \
{0, 0, 0, 0, 0}, \ {0, 0, 0, 0, 0}, \
@ -59,7 +88,7 @@
// 1→ // 1→
// ⮎4→2→ // ⮎4→2→
// 3→ // 3→
#define DX9_ALG_6(feedback) \ #define ALG_DX9_6(feedback) \
{ \ { \
{0, 0, 0, 0, 1}, \ {0, 0, 0, 0, 1}, \
{0, 0, 0, 1, 1}, \ {0, 0, 0, 1, 1}, \
@ -70,7 +99,7 @@
// 1→ // 1→
// 2→ // 2→
// ⮎4→3→ // ⮎4→3→
#define DX9_ALG_7(feedback) \ #define ALG_DX9_7(feedback) \
{ \ { \
{0, 0, 0, 0, 1}, \ {0, 0, 0, 0, 1}, \
{0, 0, 0, 0, 1}, \ {0, 0, 0, 0, 1}, \
@ -82,7 +111,7 @@
// 2→ // 2→
// 3→ // 3→
// ⮎4→ // ⮎4→
#define DX9_ALG_8(feedback) \ #define ALG_DX9_8(feedback) \
{ \ { \
{0, 0, 0, 0, 1}, \ {0, 0, 0, 0, 1}, \
{0, 0, 0, 0, 1}, \ {0, 0, 0, 0, 1}, \

15
install.sh Executable file
View File

@ -0,0 +1,15 @@
#! /bin/sh
src=$1
dst=$2
info=$dst/INFO_UF2.txt
echo -n "Waiting for $info to appear..."
while ! [ -f $info ]; do
echo -n "."
sleep 1
done
echo "👍"
cp $src $dst
echo "Installed!"

View File

@ -19,12 +19,9 @@ void setupJustPitches(uint8_t baseNote, float basePitch) {
JustPitches[baseNote + 7] = basePitch * 3 / 2; // A JustPitches[baseNote + 7] = basePitch * 3 / 2; // A
JustPitches[baseNote + 8] = basePitch * 8 / 5; // Bb JustPitches[baseNote + 8] = basePitch * 8 / 5; // Bb
JustPitches[baseNote + 9] = basePitch * 5 / 3; // B JustPitches[baseNote + 9] = basePitch * 5 / 3; // B
JustPitches[baseNote + 10] = basePitch * 9 / 5; // C JustPitches[baseNote + 10] = basePitch * 16 / 9; // C (fourth up from G)
JustPitches[baseNote + 11] = basePitch * 15 / 8; // C# JustPitches[baseNote + 11] = basePitch * 15 / 8; // C#
// Two fourths up from the base pitch, so G major scale sounds right
JustPitches[baseNote + 11] = basePitch * 8 / 3; // C#
// Octaves // Octaves
for (int note = baseNote; note < baseNote + 12; note++) { for (int note = baseNote; note < baseNote + 12; note++) {
for (int i = 1; i < 9; i++) { for (int i = 1; i < 9; i++) {

View File

@ -1,39 +1,45 @@
// "Factory" patches // "Factory" patches
#pragma once #pragma once
#include "dx9.h" #include "algorithms.h"
// Waveform, offset, multiplier, delay, attack, holdAmp, hold, decay, sustainAmp, release // Waveform, offset, multiplier, delay, attack, holdAmp, hold, decay, sustainAmp, release
FMPatch Bank[] = { FMPatch Bank[] = {
{ {
"Venus Oboe", "Square",
DX9_ALG_5(0), ALG_SIMPLE,
{ {
// Waveform off mult del att hldA hld dec susA rel // Waveform offs mult dely attk hldA hld decy susA rels
{WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 10.5, 0, 0.75, 5}, {WAVEFORM_SQUARE, 0, 1.00, 0, 10.5, 0.8, 10.5, 10, 0.50, 5},
{WAVEFORM_SINE, 0, 4.00, 0, 10.5, 1.0, 10.5, 0, 0.80, 5}, },
{WAVEFORM_SINE, 0, 8.00, 0, 10.5, 1.0, 10.5, 0, 0.50, 5}, },
{WAVEFORM_SINE, 0, 16.00, 0, 10.5, 1.0, 50.0, 0, 0.75, 5}, {
"Tubey",
ALG_OPL2_1(0),
{
// Waveform offs mult dely attk hldA hld decy susA rels
{WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 10.5, 10, 0.80, 5},
{WAVEFORM_SINE, 0, 8.00, 0, 10.5, 0.2, 10.5, 10, 0.10, 5},
}, },
}, },
{ {
"IWantPizza", "IWantPizza",
DX9_ALG_1(0), ALG_DX9_1(0),
{ {
{WAVEFORM_SINE, 0, 4.00, 0, 10.5, 1.0, 10.5, 0, 0.35, 20}, {WAVEFORM_SINE, 0, 4.00, 0, 10.5, 1.0, 10.5, 0, 0.35, 20},
{WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 10.5, 0, 0.30, 20}, {WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 10.5, 0, 0.30, 20},
{WAVEFORM_SINE, 0, 8.00, 0, 10.5, 1.0, 10.5, 0, 0.50, 20}, {WAVEFORM_SINE, 0, 8.00, 0, 10.5, 1.0, 10.5, 0, 0.50, 20},
{WAVEFORM_SINE, 0, 16.00, 0, 10.5, 1.0, 50, 0, 0.25, 20}, {WAVEFORM_SINE, 0, 16.00, 0, 10.5, 1.0, 50, 0, 0.25, 20},
}, },
}, },
{ {
"Ray Gun", "Ray Gun",
DX9_ALG_1(0), ALG_DX9_1(0),
{ {
{WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 10.5, 0, 0.35, 20}, {WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 10.5, 0, 0.35, 20},
{WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 10.5, 0, 0.30, 20}, {WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 10.5, 0, 0.30, 20},
{WAVEFORM_SINE, 0, 9.00, 0, 10.5, 1.0, 10.5, 0, 0.00, 20}, {WAVEFORM_SINE, 0, 9.00, 0, 10.5, 1.0, 10.5, 0, 0.00, 20},
{WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 50, 0, 0.25, 8}, {WAVEFORM_SINE, 0, 1.00, 0, 10.5, 1.0, 50, 0, 0.25, 8},
}, },
}, },
}; };

View File

@ -20,6 +20,7 @@ void FMVoiceLoadPatch(FMVoice *v, FMPatch *p) {
} }
v->outputMixer.gain(i, p->gains[i][NUM_OPERATORS]); v->outputMixer.gain(i, p->gains[i][NUM_OPERATORS]);
} }
v->patch = p;
} }
void FMVoiceSetPitch(FMVoice *v, float freq) { void FMVoiceSetPitch(FMVoice *v, float freq) {

View File

@ -93,11 +93,11 @@ typedef struct FMVoice {
#define FMOperatorWiring(name, i) \ #define FMOperatorWiring(name, i) \
{name.mixers[i], 0, name.oscillators[i], 0}, \ {name.mixers[i], 0, name.oscillators[i], 0}, \
{name.oscillators[i], 0, name.envelopes[i], 0}, \ {name.oscillators[i], 0, name.envelopes[i], 0}, \
{name.envelopes[i], 0, name.outputMixer, i}, \
{name.envelopes[i], 0, name.mixers[0], i}, \ {name.envelopes[i], 0, name.mixers[0], i}, \
{name.envelopes[i], 0, name.mixers[1], i}, \ {name.envelopes[i], 0, name.mixers[1], i}, \
{name.envelopes[i], 0, name.mixers[2], i}, \ {name.envelopes[i], 0, name.mixers[2], i}, \
{name.envelopes[i], 0, name.mixers[3], i} {name.envelopes[i], 0, name.mixers[3], i}, \
{name.envelopes[i], 0, name.outputMixer, i}
/** FMVoiceWiring outputs AudioConnection initializer to wire one FMVoice /** FMVoiceWiring outputs AudioConnection initializer to wire one FMVoice
*/ */

View File

@ -9,6 +9,7 @@
#include "notes.h" #include "notes.h"
#include "fingering.h" #include "fingering.h"
#define DEBUG
#define KNEE_OFFSET 0 #define KNEE_OFFSET 0
#define KEY_OFFSET 2 #define KEY_OFFSET 2
@ -23,7 +24,16 @@ AudioMixer4 mixL;
AudioMixer4 mixR; AudioMixer4 mixR;
AudioOutputAnalogStereo dacs1; AudioOutputAnalogStereo dacs1;
#ifdef DEBUG
AudioSynthNoiseWhite debug;
#endif
AudioConnection FMVoicePatchCords[] = { AudioConnection FMVoicePatchCords[] = {
#ifdef DEBUG
{debug, 0, mixL, 3},
{debug, 0, mixR, 3},
#endif
{Chanter.outputMixer, 0, biquad1, 0}, {Chanter.outputMixer, 0, biquad1, 0},
{biquad1, 0, mixL, 0}, {biquad1, 0, mixL, 0},
{biquad1, 0, mixR, 0}, {biquad1, 0, mixR, 0},
@ -61,7 +71,6 @@ Adafruit_NeoTrellisM4 trellis = Adafruit_NeoTrellisM4();
MicroOLED oled(9, 1); MicroOLED oled(9, 1);
QwiicButton bag; QwiicButton bag;
void setup() { void setup() {
setupJustPitches(NOTE_D4, PITCH_D4); setupJustPitches(NOTE_D4, PITCH_D4);
pinMode(LED_BUILTIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT);
@ -102,6 +111,12 @@ void setup() {
// Initialize processor and memory measurements // Initialize processor and memory measurements
AudioProcessorUsageMaxReset(); AudioProcessorUsageMaxReset();
AudioMemoryUsageMaxReset(); AudioMemoryUsageMaxReset();
#ifdef DEBUG
debug.amplitude(0.1);
mixL.gain(3, 0.1);
mixR.gain(3, 0.1);
#endif
} }
#define BUTTON_UP 0 #define BUTTON_UP 0
@ -152,8 +167,10 @@ void updateTunables(uint8_t buttons, int note) {
} }
} }
mixL.gain(0, gain); for (int i=0; i<3; i++) {
mixR.gain(0, gain); mixL.gain(i, gain);
mixR.gain(i, gain);
}
trellis.setPixelColor(BUTTON_VOLUME, trellis.ColorHSV(uint16_t(gain * 65535), 255, 80)); trellis.setPixelColor(BUTTON_VOLUME, trellis.ColorHSV(uint16_t(gain * 65535), 255, 80));
if (!note || (note == NOTE_CS5)) { if (!note || (note == NOTE_CS5)) {