Revalogics
Well-known member
Hi guys, I have an issue with "AudioEffectDelay". Using it together with I2S input and output makes the code freeze. However, using USB input and output makes all parts of the code operable.
Hardwares used are Teensy 3.6, a 20 x 4 (HD44780-compliant) LCD module, a rotary encoder with button, and a UDA1345TS audio CODEC board (uses I2S).
My Teensyduino is version 1.35 and Audio Library is version 1.30.
Hardware Notes:
I2S is configured with different pins, see "Alternate (Pinout Friendly)" column. Pin 3 is physically connected to pin 25 (therefore pin 25 is configured as INPUT for it to not interfere with pin 3) for accessibility of the ribbon wire used in my audio CODEC board.
Rotary encoder is connected to pins 1 and 2, its button to pin 0, its common and other button pin to GND.
LCD module is 20 x 4, connected to pins 23 to 17, pins configured as LCD RS, R/W, EN, D4, D5, D6, D7, respectively. D4 to D7 has a 1kΩ series resistor to interface with LCD 5V output (during reads) and Teensy 3.6 3.3V logic levels.
This is the code I'm talking about. If you uncomment lines 13, 24, 26, 27, 31, 94 - 101, and line 261, (lines concerning delay1), the code does not work (no sound output, LCD is not initialized, evident by black bars on LCD rows 1 and 3). Using the code below "as is" works.
Hardwares used are Teensy 3.6, a 20 x 4 (HD44780-compliant) LCD module, a rotary encoder with button, and a UDA1345TS audio CODEC board (uses I2S).
My Teensyduino is version 1.35 and Audio Library is version 1.30.
Hardware Notes:
I2S is configured with different pins, see "Alternate (Pinout Friendly)" column. Pin 3 is physically connected to pin 25 (therefore pin 25 is configured as INPUT for it to not interfere with pin 3) for accessibility of the ribbon wire used in my audio CODEC board.
Rotary encoder is connected to pins 1 and 2, its button to pin 0, its common and other button pin to GND.
LCD module is 20 x 4, connected to pins 23 to 17, pins configured as LCD RS, R/W, EN, D4, D5, D6, D7, respectively. D4 to D7 has a 1kΩ series resistor to interface with LCD 5V output (during reads) and Teensy 3.6 3.3V logic levels.
Code:
I2S Bus Single Shield Dual Shield (Teensy 3.6) Alternate (Pinout Friendly) Possibilities
TX1 22(I2S0_TXD0:PTC1:ALT6) 22(I2S0_TXD0:PTC1:ALT6) 3(I2S0_TXD0:PTA12:ALT6) 3(PTA12:ALT6) 22(PTC1:ALT6) 56(PTE10:ALT4)
TX2 15(I2S0_TXD1:PTC0:ALT6) 26(I2S0_TXD1:PTA14:ALT7) 15(PTC0:ALT6) 26(PTA14:ALT7)
RX1 13(I2S0_RXD0:PTC5:ALT4) 13(I2S0_RXD0:PTC5:ALT4) 27(I2S0_RXD0:PTA15:ALT6) 13(PTC5:ALT4) 27(PTA15:ALT6)
RX2 38(I2S0_RXD1:PTC11:ALT4) 28(I2S0_RXD1:PTA16:ALT7) 28(PTA16:ALT7) 38(PTC11:ALT4)
LRCLK 23(I2S0_TX_FS:PTC2:ALT6) 23(I2S0_TX_FS:PTC2:ALT6) 30(I2S0_TX_FS:PTB19:ALT4) 4(PTA13:ALT6) 23(PTC2:ALT6) 30(PTB19:ALT4) 57(PTE11:ALT4)
BCLK 9(I2S0_TX_BCLK:PTC3:ALT6) 9(I2S0_TX_BCLK:PTC3:ALT6) 29(I2S0_TX_BCLK:PTB18:ALT4) 9(PTC3:ALT6) 25(PTA5:ALT6) 29(PTB18:ALT4)
MCLK 11(I2S0_MCLK:PTC6:ALT6) 11(I2S0_MCLK:PTC6:ALT6) 35(I2S0_MCLK:PTC8:ALT4) 11(PTC6:ALT6) 35(PTC8:ALT4) 39(PTA17:ALT6)
I2S0_TXD0 PTE10:ALT4[56] PTA12:ALT6[3] PTC1:ALT6[22]
I2S0_TXD1 PTE9:ALT2 PTA14:ALT7[26] PTC0:ALT6[15]
I2S0_RXD0 PTE7:ALT4 PTA15:ALT6[27] PTC5:ALT4[13]
I2S0_RXD1 PTE8:ALT2 PTA16:ALT7[28] PTC11:ALT4[38]
I2S0_TX_FS PTE11:ALT4[57] PTA13:ALT6[4] PTB19:ALT4[30] PTC2:ALT6[23]
I2S0_RX_FS PTE8:ALT4 PTA16:ALT6[28] PTC7:ALT4[12] PTC10:ALT4[37]
I2S0_TX_BCLK PTE12:ALT4 PTA5:ALT6[25] PTB18:ALT4[29] PTC3:ALT6[9]
I2S0_RX_BCLK PTE9:ALT4 PTA14:ALT6[26] PTC6:ALT4[11] PTC9:ALT4[36]
I2S0_MCLK PTE6:ALT4 PTA17:ALT6[39] PTC6:ALT6[11] PTC8:ALT4[35]
This is the code I'm talking about. If you uncomment lines 13, 24, 26, 27, 31, 94 - 101, and line 261, (lines concerning delay1), the code does not work (no sound output, LCD is not initialized, evident by black bars on LCD rows 1 and 3). Using the code below "as is" works.
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioInputI2S i2s1; //xy=123,184
AudioInputUSB usb1; //xy=123,216
AudioMixer4 mixer3; //xy=243,337
AudioAnalyzePeak peak1; //xy=287,131
AudioMixer4 mixer1; //xy=287,184
//AudioEffectDelay delay1; //xy=367,337
AudioEffectReverb reverb1; //xy=410,184
AudioMixer4 mixer2; //xy=558,204
AudioAnalyzePeak peak2; //xy=696,166
AudioOutputI2S i2s2; //xy=696,210
AudioOutputUSB usb2; //xy=696,242
AudioOutputAnalog dac1; //xy=340,245
AudioConnection patchCord1(i2s1, 0, mixer1, 0);
AudioConnection patchCord2(i2s1, 0, peak1, 0);
AudioConnection patchCord3(i2s1, 0, mixer2, 1);
AudioConnection patchCord4(i2s1, 0, mixer3, 0);
//AudioConnection patchCord5(mixer3, 0, delay1, 0);
AudioConnection patchCord6(mixer1, reverb1);
//AudioConnection patchCord7(delay1, 0, mixer2, 2);
//AudioConnection patchCord8(delay1, 0, mixer3, 1);
AudioConnection patchCord9(reverb1, 0, mixer2, 0);
AudioConnection patchCord10(mixer2, 0, i2s2, 0);
AudioConnection patchCord11(mixer2, peak2);
// GUItool: end automatically generated code
#include <LiquidCrystalFast.h>
#include <Bounce.h>
const float scale00dBV = 1.000000000;
const float scale03dBV = 0.707945784;
const float scale06dBV = 0.501187234;
const float scale09dBV = 0.354813389;
const float scale12dBV = 0.251188643;
const float scale15dBV = 0.177827941;
const float scale18dBV = 0.125892541;
const float scale21dBV = 0.089125094;
const float scale24dBV = 0.063095734;
const float scale27dBV = 0.044668359;
const float scale30dBV = 0.031622777;
const float scale33dBV = 0.022387211;
const float scale36dBV = 0.015848932;
const float scale39dBV = 0.011220185;
const float scale42dBV = 0.007943282;
const float scale45dBV = 0.005623413;
const float scale48dBV = 0.003981072;
const float scale51dBV = 0.002818383;
const float scale54dBV = 0.001995262;
const float scale57dBV = 0.001412538;
const float scale60dBV = 0.001000000;
float peak1raw, peak2raw, peak1val, peak2val;
int DELAY_TIME = 1; // 1-330
int DELAY_FEEDBACK = 0; // 0-100
int DELAY_MIX = 0; // 0-100
int REVERB_TIME = 8; // 1-16
int REVERB_MIX = 100; // 0-100
int BYPASS_MIX = 0; // 0-100
int peak1mtr, peak2mtr, displayMode, knobVal, knobPos;
long knobReadCurr;
boolean buttonState, knobDir, knobRotate;
elapsedMillis LCDtimer;
elapsedMillis LCDtimer2;
elapsedMillis buttonTimer;
LiquidCrystalFast MC2004(23, 22, 21, 20, 19, 18, 17);
const int buttonPin = 0;
const int encoderPin1 = 1;
const int encoderPin2 = 2;
Bounce button = Bounce(buttonPin, 10);
void setup () {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(encoderPin1, INPUT_PULLUP);
pinMode(encoderPin2, INPUT_PULLUP);
pinMode(25, INPUT);
AudioMemory(260);
Serial.begin(115200);
AudioNoInterrupts();
byte char1[8] = {0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00}; // █ up
byte char2[8] = {0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x00}; // █ down
byte char3[8] = {0x1F, 0x1F, 0x1F, 0x00, 0x1F, 0x1F, 0x1F, 0x00}; // █ up & down
byte char4[8] = {0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; // dot
mixer1.gain(0, REVERB_MIX * 0.00125); // reverb input gain
mixer2.gain(0, 2.64); // reverb output gain
mixer2.gain(1, BYPASS_MIX * 0.0033); // input-to-output gain
mixer2.gain(2, DELAY_MIX * 0.0033); // delay output gain
mixer3.gain(0, (200 - DELAY_FEEDBACK) * 0.0050); // delay input gain
mixer3.gain(1, DELAY_FEEDBACK * 0.00499); // delay feedback gain
reverb1.reverbTime(REVERB_TIME);
//delay1.delay(0, DELAY_TIME);
//delay1.disable(1);
//delay1.disable(2);
//delay1.disable(3);
//delay1.disable(4);
//delay1.disable(5);
//delay1.disable(6);
//delay1.disable(7);
MC2004.createChar(0, char1);
MC2004.createChar(1, char2);
MC2004.createChar(2, char3);
MC2004.createChar(3, char4);
MC2004.begin(20, 4);
MC2004.clear();
buttonTimer = 3001;
LCDtimer = 51;
LCDtimer2 = 251;
peak1val = 1.00;
peak2val = 1.00;
AudioInterrupts();
}
void loop() {
button.update();
if(button.fallingEdge()) {
buttonState = 1;
switch(displayMode) {
case 0:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Reverb Time = ");
MC2004.print(REVERB_TIME);
MC2004.print("s ");
break;
case 1:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Reverb Mix = ");
MC2004.print(REVERB_MIX);
MC2004.print("% ");
break;
case 2:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Bypass Mix = ");
MC2004.print(BYPASS_MIX);
MC2004.print("% ");
break;
case 3:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Delay Time = ");
MC2004.print(DELAY_TIME);
MC2004.print("ms ");
break;
case 4:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Delay Mix = ");
MC2004.print(DELAY_MIX);
MC2004.print("% ");
break;
case 5:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("DelayFeedback = ");
MC2004.print(DELAY_FEEDBACK);
MC2004.print("% ");
break;
}
displayMode++;
if(displayMode == 6) displayMode = 0;
buttonTimer = 0;
}
if(digitalRead(encoderPin1) && digitalRead(encoderPin2)) {
knobPos = 0;
}
if(!digitalRead(encoderPin1) && digitalRead(encoderPin2)) {
if(knobPos == 2) {
knobRotate = 1;
}
knobPos = 1;
}
if(!digitalRead(encoderPin1) && !digitalRead(encoderPin2)) {
if(knobPos == 3) {
knobDir = 0;
}
if(knobPos == 1) {
knobDir = 1;
}
knobPos = 2;
}
if(digitalRead(encoderPin1) && !digitalRead(encoderPin2)) {
if(knobPos == 2) {
knobRotate = 1;
}
knobPos = 3;
}
if(buttonState && knobRotate) {
knobRotate = 0;
if(knobDir == 0) knobVal = -1;
if(knobDir == 1) knobVal = 1;
switch(displayMode) {
case 0:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("DelayFeedback = ");
DELAY_FEEDBACK = DELAY_FEEDBACK + knobVal;
if(DELAY_FEEDBACK < 0) DELAY_FEEDBACK = 0;
if(DELAY_FEEDBACK > 100) DELAY_FEEDBACK = 100;
MC2004.print(DELAY_FEEDBACK);
mixer3.gain(0, (200 - DELAY_FEEDBACK) * 0.0050);
mixer3.gain(1, DELAY_FEEDBACK * 0.00499);
MC2004.print("%");
break;
case 1:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Reverb Time = ");
REVERB_TIME = REVERB_TIME + knobVal;
if(REVERB_TIME < 1) REVERB_TIME = 1;
if(REVERB_TIME > 16) REVERB_TIME = 16;
MC2004.print(REVERB_TIME);
reverb1.reverbTime(REVERB_TIME);
MC2004.print("s");
break;
case 2:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Reverb Mix = ");
REVERB_MIX = REVERB_MIX + knobVal;
if(REVERB_MIX < 0) REVERB_MIX = 0;
if(REVERB_MIX > 100) REVERB_MIX = 100;
MC2004.print(REVERB_MIX);
mixer1.gain(0, REVERB_MIX * 0.00125);
MC2004.print("%");
break;
case 3:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Bypass Mix = ");
BYPASS_MIX = BYPASS_MIX + knobVal;
if(BYPASS_MIX < 0) BYPASS_MIX = 0;
if(BYPASS_MIX > 100) BYPASS_MIX = 100;
MC2004.print(BYPASS_MIX);
mixer2.gain(1, BYPASS_MIX * 0.0033);
MC2004.print("%");
break;
case 4:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Delay Time = ");
DELAY_TIME = DELAY_TIME + knobVal;
if(DELAY_TIME < 1) DELAY_TIME = 1;
if(DELAY_TIME > 330) DELAY_TIME = 330;
MC2004.print(DELAY_TIME);
//delay1.delay(0, DELAY_TIME);
MC2004.print("ms");
break;
case 5:
MC2004.setCursor(0, 1);
MC2004.print(" ");
MC2004.setCursor(0, 1);
MC2004.print("Delay Mix = ");
DELAY_MIX = DELAY_MIX + knobVal;
if(DELAY_MIX < 0) DELAY_MIX = 0;
if(DELAY_MIX > 100) DELAY_MIX = 100;
MC2004.print(DELAY_MIX);
mixer2.gain(2, DELAY_MIX * 0.0033);
MC2004.print("%");
break;
}
buttonTimer = 0;
}
if(peak1.available()) peak1raw = peak1.read();
if(peak2.available()) peak2raw = peak2.read();
if(peak1raw > peak1val) peak1val = peak1raw;
if(peak2raw > peak2val) peak2val = peak2raw;
if(peak1val >= scale00dBV) peak1mtr = 20;
if(peak1val < scale00dBV && peak1val >= scale03dBV) peak1mtr = 19;
if(peak1val < scale03dBV && peak1val >= scale06dBV) peak1mtr = 18;
if(peak1val < scale06dBV && peak1val >= scale09dBV) peak1mtr = 17;
if(peak1val < scale09dBV && peak1val >= scale12dBV) peak1mtr = 16;
if(peak1val < scale12dBV && peak1val >= scale15dBV) peak1mtr = 15;
if(peak1val < scale15dBV && peak1val >= scale18dBV) peak1mtr = 14;
if(peak1val < scale18dBV && peak1val >= scale21dBV) peak1mtr = 13;
if(peak1val < scale21dBV && peak1val >= scale24dBV) peak1mtr = 12;
if(peak1val < scale24dBV && peak1val >= scale27dBV) peak1mtr = 11;
if(peak1val < scale27dBV && peak1val >= scale30dBV) peak1mtr = 10;
if(peak1val < scale30dBV && peak1val >= scale36dBV) peak1mtr = 9;
if(peak1val < scale36dBV && peak1val >= scale39dBV) peak1mtr = 8;
if(peak1val < scale39dBV && peak1val >= scale42dBV) peak1mtr = 7;
if(peak1val < scale42dBV && peak1val >= scale45dBV) peak1mtr = 6;
if(peak1val < scale45dBV && peak1val >= scale48dBV) peak1mtr = 5;
if(peak1val < scale45dBV && peak1val >= scale48dBV) peak1mtr = 5;
if(peak1val < scale48dBV && peak1val >= scale51dBV) peak1mtr = 4;
if(peak1val < scale51dBV && peak1val >= scale54dBV) peak1mtr = 3;
if(peak1val < scale54dBV && peak1val >= scale57dBV) peak1mtr = 2;
if(peak1val < scale57dBV && peak1val >= scale60dBV) peak1mtr = 1;
if(peak1val < scale60dBV) peak1mtr = 0;
if(peak2val >= scale00dBV) peak2mtr = 20;
if(peak2val < scale00dBV && peak2val >= scale03dBV) peak2mtr = 19;
if(peak2val < scale03dBV && peak2val >= scale06dBV) peak2mtr = 18;
if(peak2val < scale06dBV && peak2val >= scale09dBV) peak2mtr = 17;
if(peak2val < scale09dBV && peak2val >= scale12dBV) peak2mtr = 16;
if(peak2val < scale12dBV && peak2val >= scale15dBV) peak2mtr = 15;
if(peak2val < scale15dBV && peak2val >= scale18dBV) peak2mtr = 14;
if(peak2val < scale18dBV && peak2val >= scale21dBV) peak2mtr = 13;
if(peak2val < scale21dBV && peak2val >= scale24dBV) peak2mtr = 12;
if(peak2val < scale24dBV && peak2val >= scale27dBV) peak2mtr = 11;
if(peak2val < scale27dBV && peak2val >= scale30dBV) peak2mtr = 10;
if(peak2val < scale30dBV && peak2val >= scale36dBV) peak2mtr = 9;
if(peak2val < scale36dBV && peak2val >= scale39dBV) peak2mtr = 8;
if(peak2val < scale39dBV && peak2val >= scale42dBV) peak2mtr = 7;
if(peak2val < scale42dBV && peak2val >= scale45dBV) peak2mtr = 6;
if(peak2val < scale45dBV && peak2val >= scale48dBV) peak2mtr = 5;
if(peak2val < scale45dBV && peak2val >= scale48dBV) peak2mtr = 5;
if(peak2val < scale48dBV && peak2val >= scale51dBV) peak2mtr = 4;
if(peak2val < scale51dBV && peak2val >= scale54dBV) peak2mtr = 3;
if(peak2val < scale54dBV && peak2val >= scale57dBV) peak2mtr = 2;
if(peak2val < scale57dBV && peak2val >= scale60dBV) peak2mtr = 1;
if(peak2val < scale60dBV) peak2mtr = 0;
if(LCDtimer >= 50) {
LCDtimer = 0;
if(buttonTimer > 3000 && LCDtimer2 > 250) {
buttonTimer = 3001;
LCDtimer2 = 0;
MC2004.setCursor(0, 1);
MC2004.print("CPU: ");
if(AudioProcessorUsage() < 10.00) {
MC2004.write(0x03);
MC2004.write(0x03);
}
if(AudioProcessorUsage() < 100.00 && AudioProcessorUsage() >= 10.00) {
MC2004.write(0x03);
}
MC2004.print(AudioProcessorUsage());
MC2004.print(" MEM: ");
if(AudioMemoryUsage() < 10.00) {
MC2004.write(0x03);
MC2004.write(0x03);
}
if(AudioMemoryUsage() < 100.00 && AudioMemoryUsage() >= 10.00) {
MC2004.write(0x03);
}
MC2004.print(AudioMemoryUsage());
displayMode = 0;
buttonState = 0;
}
MC2004.setCursor(0, 2);
MC2004.print("RVB ");
if(REVERB_TIME <= 9) MC2004.write(0x03);
MC2004.print(REVERB_TIME);
MC2004.print("s");
MC2004.setCursor(10, 2);
MC2004.print("M");
if(REVERB_MIX <= 9) {
MC2004.write(0x03);
MC2004.write(0x03);
}
if(REVERB_MIX <= 99 && REVERB_MIX > 9) MC2004.write(0x03);
MC2004.print(REVERB_MIX);
MC2004.setCursor(16, 2);
MC2004.print("B");
if(BYPASS_MIX <= 9) {
MC2004.write(0x03);
MC2004.write(0x03);
}
if(BYPASS_MIX <= 99 && BYPASS_MIX > 9) MC2004.write(0x03);
MC2004.print(BYPASS_MIX);
MC2004.setCursor(0, 3);
MC2004.print("DLY ");
if(DELAY_TIME <= 9) {
MC2004.write(0x03);
MC2004.write(0x03);
}
if(DELAY_TIME <= 99 && DELAY_TIME > 9) MC2004.write(0x03);
MC2004.print(DELAY_TIME);
MC2004.print("ms");
MC2004.setCursor(10, 3);
MC2004.print("M");
if(DELAY_MIX <= 9) {
MC2004.write(0x03);
MC2004.write(0x03);
}
if(DELAY_MIX <= 99 && DELAY_MIX > 9) MC2004.write(0x03);
MC2004.print(DELAY_MIX);
MC2004.setCursor(16, 3);
MC2004.print("F");
if(DELAY_FEEDBACK <= 9) {
MC2004.write(0x03);
MC2004.write(0x03);
}
if(DELAY_FEEDBACK <= 99 && DELAY_FEEDBACK > 9) MC2004.write(0x03);
MC2004.print(DELAY_FEEDBACK);
MC2004.setCursor(0, 0);
if(peak1mtr == peak2mtr) {
for(int a = 0; a < peak1mtr; a++) {
MC2004.write(0x02);
}
for(int a = 0; a < 20 - peak1mtr; a++) {
MC2004.write(0x20);
}
}
if(peak1mtr > peak2mtr) {
int difference = peak1mtr - peak2mtr;
for(int a = 0; a < peak2mtr; a++) {
MC2004.write(0x02);
}
for(int a = 0; a < difference; a++) {
MC2004.write(0x00);
}
for(int a = 0; a < 20 - peak1mtr; a++) {
MC2004.write(0x20);
}
}
if(peak1mtr < peak2mtr) {
int difference = peak2mtr - peak1mtr;
for(int a = 0; a < peak1mtr; a++) {
MC2004.write(0x02);
}
for(int a = 0; a < difference; a++) {
MC2004.write(0x01);
}
for(int a = 0; a < 20 - peak2mtr; a++) {
MC2004.write(0x20);
}
}
peak1val = peak1val * scale03dBV;
peak2val = peak2val * scale03dBV;
}
}
Last edited: