first commit synth design tool guide code

This commit is contained in:
John Edgar Park 2018-12-14 13:56:39 -08:00
parent 3f5f52108c
commit 7c03d5d051
3 changed files with 388 additions and 0 deletions

View file

@ -0,0 +1,190 @@
/* Audio library demonstration - pocket synth with C major scale and 4 wave types */
//each row is a different waveform, envelope, and effect set in major scale
// row 0 sine, soft attack, long release ADSR
// row 1 square, hard attack, moderate release, flanger effect
// row 2 sawtooth, hard attack, soft release, chorus effect
// row 3 triangle, medium attack, long release ADSR, multi tap delay
#include <Audio.h>
#include <Adafruit_NeoTrellisM4.h>
Adafruit_NeoTrellisM4 trellis = Adafruit_NeoTrellisM4();
// Paste your Audio System Design Tool code below this line:
// GUItool: begin automatically generated code
AudioSynthWaveform wave0; //xy=453.84613037109375,254.61540985107422
AudioSynthWaveform wave1; //xy=453.84613037109375,294.6154098510742
AudioSynthWaveform wave2; //xy=453.84613037109375,354.6154098510742
AudioSynthWaveform wave3; //xy=453.84613037109375,404.6154098510742
AudioEffectEnvelope env0; //xy=602.8461303710938,254.61540985107422
AudioEffectEnvelope env1; //xy=602.8461303710938,294.6154098510742
AudioEffectEnvelope env2; //xy=602.8461303710938,354.6154098510742
AudioEffectEnvelope env3; //xy=602.8461303710938,404.6154098510742
AudioEffectChorus chorus1; //xy=734.6796264648438,333.14093017578125
AudioEffectFlange flange1; //xy=737.7564392089844,284.6794891357422
AudioEffectDelay delay1; //xy=880.7692260742188,582.3077392578125
AudioMixer4 mixer1; //xy=882.3076171875,284.6154327392578
AudioMixer4 mixerLeft; //xy=1041.9999389648438,293.84617614746094
AudioMixer4 mixerRight; //xy=1045.0768432617188,394.6153869628906
AudioOutputAnalogStereo audioOut; //xy=1212.8461303710938,354.6154098510742
AudioConnection patchCord1(wave0, env0);
AudioConnection patchCord2(wave1, env1);
AudioConnection patchCord3(wave2, env2);
AudioConnection patchCord4(wave3, env3);
AudioConnection patchCord5(env0, 0, mixer1, 0);
AudioConnection patchCord6(env1, flange1);
AudioConnection patchCord7(env2, chorus1);
AudioConnection patchCord8(env3, delay1);
AudioConnection patchCord9(env3, 0, mixer1, 3);
AudioConnection patchCord10(chorus1, 0, mixer1, 2);
AudioConnection patchCord11(flange1, 0, mixer1, 1);
AudioConnection patchCord12(delay1, 0, mixerLeft, 1);
AudioConnection patchCord13(delay1, 1, mixerLeft, 2);
AudioConnection patchCord14(delay1, 2, mixerRight, 1);
AudioConnection patchCord15(delay1, 3, mixerRight, 2);
AudioConnection patchCord16(mixer1, 0, mixerLeft, 0);
AudioConnection patchCord17(mixer1, 0, mixerRight, 0);
AudioConnection patchCord18(mixerLeft, 0, audioOut, 0);
AudioConnection patchCord19(mixerRight, 0, audioOut, 1);
// GUItool: end automatically generated code
AudioSynthWaveform *waves[4] = {
&wave0, &wave1, &wave2, &wave3,
};
short wave_type[4] = {
WAVEFORM_SINE,
WAVEFORM_SQUARE,
WAVEFORM_SAWTOOTH,
WAVEFORM_TRIANGLE,
};
float cmaj_low[8] = { 130.81, 146.83, 164.81, 174.61, 196.00, 220.00, 246.94, 261.63 };
float cmaj_high[8] = { 261.6, 293.7, 329.6, 349.2, 392.0, 440.0, 493.9, 523.3 };
AudioEffectEnvelope *envs[4] = {
&env0, &env1, &env2, &env3,
};
int n_chorus = 5;
#define CHORUS_DELAY_LENGTH (400*AUDIO_BLOCK_SAMPLES)
short chorusDelayline[CHORUS_DELAY_LENGTH];
#define FLANGER_DELAY_LENGTH (6*AUDIO_BLOCK_SAMPLES)
short flangerDelayline[FLANGER_DELAY_LENGTH];
void setup(){
Serial.begin(115200);
//while (!Serial);
trellis.begin();
trellis.setBrightness(255);
AudioMemory(120);
//Initialize the waveform nodes
wave0.begin(0.85, 50, WAVEFORM_SINE);
wave1.begin(0.4, 50, WAVEFORM_SQUARE);
wave2.begin(0.6, 50, WAVEFORM_SAWTOOTH);
wave3.begin(0.4, 50, WAVEFORM_TRIANGLE);
// reduce the gain on some channels, so half of the channels
// are "positioned" to the left, half to the right, but all
// are heard at least partially on both ears
mixerLeft.gain(0, 0.3);
mixerLeft.gain(1, 0.1);
mixerLeft.gain(2, 0.5);
mixerRight.gain(0, 0.3);
mixerRight.gain(1, 0.5);
mixerRight.gain(2, 0.1);
// set envelope parameters, for pleasing sound :-)
env0.attack(300);
env0.hold(2);
env0.decay(30);
env0.sustain(0.6);
env0.release(1200);
env1.attack(10);
env1.hold(2);
env1.decay(30);
env1.sustain(0.6);
env1.release(400);
env2.attack(10);
env2.hold(20);
env2.decay(30);
env2.sustain(0.6);
env2.release(1000);
env3.attack(10);
env3.hold(2);
env3.decay(30);
env3.sustain(0.6);
env3.release(600);
// set delay parameters
delay1.delay(0, 110);
delay1.delay(1, 660);
delay1.delay(2, 220);
delay1.delay(3, 1220);
// set effects parameters
chorus1.begin(chorusDelayline, CHORUS_DELAY_LENGTH, n_chorus);
flange1.begin(flangerDelayline, FLANGER_DELAY_LENGTH, FLANGER_DELAY_LENGTH/4, FLANGER_DELAY_LENGTH/4, .5);
Serial.println("setup done");
// Initialize processor and memory measurements
AudioProcessorUsageMaxReset();
AudioMemoryUsageMaxReset();
}
void noteOn(int num){
int voice = num/8;
float *scale;
if(voice == 0 || voice == 1) scale = cmaj_low;
else scale = cmaj_high;
AudioNoInterrupts();
waves[voice]->frequency(scale[num%8]);
envs[voice]->noteOn();
AudioInterrupts();
}
void noteOff(int num){
int voice = num/8;
envs[voice]->noteOff();
}
void loop() {
trellis.tick();
while(trellis.available())
{
keypadEvent e = trellis.read();
int keyindex = e.bit.KEY;
if(e.bit.EVENT == KEY_JUST_PRESSED){
trellis.setPixelColor(keyindex, Wheel(keyindex * 255 / 32)); // rainbow!
noteOn(keyindex);
}
else if(e.bit.EVENT == KEY_JUST_RELEASED){
noteOff(keyindex);
trellis.setPixelColor(keyindex, 0);
}
}
delay(10);
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return Adafruit_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return Adafruit_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return Adafruit_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

View file

@ -0,0 +1,52 @@
/*
Audio Library on Trellis M4
Demo of the audio sweep function.
The user specifies the amplitude,
start and end frequencies (which can sweep up or down)
and the length of time of the sweep.
*/
#include <Audio.h>
// Paste your Audio System Design Tool code below this line:
// GUItool: begin automatically generated code
AudioSynthToneSweep tonesweep1; //xy=531.0833129882812,166.08334350585938
AudioOutputAnalogStereo audioOutput; //xy=727.0833129882812,166.08334350585938
AudioConnection patchCord1(tonesweep1, 0, audioOutput, 0);
AudioConnection patchCord2(tonesweep1, 0, audioOutput, 1);
// GUItool: end automatically generated code
float t_ampx = 0.05; // Amplitude
int t_lox = 10; // Low frequency
int t_hix = 22000; // High frequency
float t_timex = 10; // Length of time of the sweep in seconds
void setup(void) {
Serial.begin(9600);
//while (!Serial) ;
delay(3000);
AudioMemory(6);
Serial.println("setup done");
if(!tonesweep1.play(t_ampx,t_lox,t_hix,t_timex)) {
Serial.println("AudioSynthToneSweep - begin failed");
while(1);
}
// wait for the sweep to end
while(tonesweep1.isPlaying());
// and now reverse the sweep
if(!tonesweep1.play(t_ampx,t_hix,t_lox,t_timex)) {
Serial.println("AudioSynthToneSweep - begin failed");
while(1);
}
// wait for the sweep to end
while(tonesweep1.isPlaying());
Serial.println("Done");
}
void loop(void){
}

View file

@ -0,0 +1,146 @@
// Trellis M4 Audio Workshop
// shows how to alter pitch with accelerometer
// Waveform Mod
#include <Audio.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL343.h>
#include "Adafruit_NeoTrellisM4.h"
#include <elapsedMillis.h>
Adafruit_ADXL343 accel = Adafruit_ADXL343(123, &Wire1);
// The NeoTrellisM4 object is a keypad and neopixel strip subclass
// that does things like auto-update the NeoPixels and stuff!
Adafruit_NeoTrellisM4 trellis = Adafruit_NeoTrellisM4();
// Paste your Audio System Design Tool code below this line:
// GUItool: begin automatically generated code
AudioSynthWaveform waveform1; //xy=592.7221984863281,187.38888549804688
AudioOutputAnalogStereo audioOutput; //xy=777.0833129882812,189.08334350585938
AudioConnection patchCord1(waveform1, 0, audioOutput, 0);
AudioConnection patchCord2(waveform1, 0, audioOutput, 1);
// GUItool: end automatically generated code
int xbend = 64;
int ybend = 64;
int last_xbend = 64;
int last_ybend = 64;
int count=1;
void setup() {
trellis.begin();
trellis.show(); // Initialize w all pixels off
trellis.setBrightness(255);
if(!accel.begin()) {
Serial.println("No accelerometer found");
while(1);
}
AudioMemory(10);
// Initialize processor and memory measurements
AudioProcessorUsageMaxReset();
AudioMemoryUsageMaxReset();
Serial.begin(115200);
waveform1.begin(WAVEFORM_SAWTOOTH);
delay(1000);
}
void loop() {
waveform1.frequency(110 + (ybend * 2));
waveform1.amplitude(0.05);
wait(5);
}
void wait(unsigned int milliseconds){
elapsedMillis msec=0;
while (msec <= milliseconds){
trellis.tick();
while(trellis.available()) {
keypadEvent e = trellis.read();
Serial.print((int)e.bit.KEY);
int keyindex = e.bit.KEY;
if(e.bit.EVENT == KEY_JUST_PRESSED){
Serial.println(" pressed");
trellis.setPixelColor(keyindex, Wheel(keyindex * 255 / 32)); // rainbow!
}
else if(e.bit.EVENT == KEY_JUST_RELEASED){
Serial.println(" released");
trellis.setPixelColor(keyindex, 0);
}
}
// Check for accelerometer
sensors_event_t event;
accel.getEvent(&event);
//check if it's been moved a decent amount
if (abs(event.acceleration.x) < 2.0) { // 2.0 m/s^2
// don't make any bend unless they've really started moving it
xbend = 64;
}
else {
if (event.acceleration.x > 0) {
xbend = ofMap(event.acceleration.x, 2.0, 10.0, 63, 0, true); // 2 ~ 10 m/s^2 is upward bend
}
else {
xbend = ofMap(event.acceleration.x, -2.0, -10.0, 64, 127, true); // -2 ~ -10 m/s^2 is downward bend
}
}
if (xbend != last_xbend) {
Serial.print("X mod: "); Serial.println(xbend);
last_xbend = xbend;
}
if (abs(event.acceleration.y) < 2.0) { // 2.0 m/s^2
ybend = 64;
}
else {
if (event.acceleration.y > 0) {
ybend = ofMap(event.acceleration.y, 2.0, 10.0, 63, 0, true); // 2 ~ 10 m/s^2 is upward bend
}
else {
ybend = ofMap(event.acceleration.y, -2.0, -10.0, 64, 127, true); // -2 ~ -10 m/s^2 is downward bend
}
}
if (ybend != last_ybend) {
Serial.print("Y mod: "); Serial.println(ybend);
last_ybend = ybend;
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return Adafruit_NeoPixel::Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return Adafruit_NeoPixel::Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return Adafruit_NeoPixel::Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
// floating point map
float ofMap(float value, float inputMin, float inputMax, float outputMin, float outputMax, bool clamp) {
float outVal = ((value - inputMin) / (inputMax - inputMin) * (outputMax - outputMin) + outputMin);
if (clamp) {
if (outputMax < outputMin) {
if (outVal < outputMax) outVal = outputMax;
else if (outVal > outputMin) outVal = outputMin;
} else {
if (outVal > outputMax) outVal = outputMax;
else if (outVal < outputMin) outVal = outputMin;
}
}
return outVal;
}