KrisKasprzak
Well-known member
All,
I'm making good progress with my mic monitor for my DLSR--this device will fit between my lapel mic and my Canon 7D, so i can have dynamic level control. So far i've got working
1. LCD with touch
2. Audio shield
3. FFT
4. slider like gain contol
5. options screen
6. low and high pass filters (but no clue how to set the parameters)
I'm getting some noise though (hiss and a very faint sound like a sci-fi phaser gun). i'm not sure if it's a bad implementation of the audio objects of if I need to add some filtering which I'm trying but not really working, also i'm powering my unit from my PC USB.
Regarding filters, how do you set them
1. if I want to remove everything below say 60 HZ, i use a high pass with frequency at 60 correct?
2. if I want to remove everything above say 10000 hz I use a low pass with the frequency at 10000 correct?
3. how do you disable the filters in code, currently i'm just setting the filters so the won't filter anything--probably not the right way?
I'm not sure what stage and Q really do, right now i'm just swapping values until my noise gets removed--which it's not
thing.setLowpass(stage, frequency, Q);
Anyone wanna look at my code and see if there are any glaring issues that will cause noise? I can strip my code down to the bar min if needed.
I'm making good progress with my mic monitor for my DLSR--this device will fit between my lapel mic and my Canon 7D, so i can have dynamic level control. So far i've got working
1. LCD with touch
2. Audio shield
3. FFT
4. slider like gain contol
5. options screen
6. low and high pass filters (but no clue how to set the parameters)
I'm getting some noise though (hiss and a very faint sound like a sci-fi phaser gun). i'm not sure if it's a bad implementation of the audio objects of if I need to add some filtering which I'm trying but not really working, also i'm powering my unit from my PC USB.
Regarding filters, how do you set them
1. if I want to remove everything below say 60 HZ, i use a high pass with frequency at 60 correct?
2. if I want to remove everything above say 10000 hz I use a low pass with the frequency at 10000 correct?
3. how do you disable the filters in code, currently i'm just setting the filters so the won't filter anything--probably not the right way?
I'm not sure what stage and Q really do, right now i'm just swapping values until my noise gets removed--which it's not
thing.setLowpass(stage, frequency, Q);
Anyone wanna look at my code and see if there are any glaring issues that will cause noise? I can strip my code down to the bar min if needed.
Code:
/*
This program is a microphone montitor for a DSLR, it will sit between a mic and DSLR input so the user can control the mic levels and see the
levels.
Author Kasprak
Date 4/8/2018
revisions
rev description author
1.0 initial creation Kasprzak
connection map
Teensy 3.2 Display
0 Touch pin
1 Touch pin
2 Touch pin
3 Touch pin
4 Touch pin
5 LED pin (PWM to control brightness)
6
7 MOSI
8
9
10
11
12 MISO
13
14 SCK
A1
A2
A3
A4
A5
A6 Chip Select
A7 DC
A8
A9
*/
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <ILI9341_t3.h>
#include <Colors.h> // kasprzaks list of defines for colors, nothing fancy
#include "UTouch.h" // touchscreen lib
#include <font_ArialBold.h> // custom fonts that ships with ILI9341_t3.h
#include <font_Arial.h> // custom fonts that ships with ILI9341_t3.h
#include <EEPROM.h>
#define FILTER_Q .707
#define MIXGAIN 20
#define MIC_BAR_GAIN 70 // multiplier for the specific mic
#define LED_PIN 5
#define DC_PIN 21
#define CS_PIN 20
#define PIN_RST 255 // 255 = unused, connect to 3.3V
#define MO_PIN 7
#define Display_SCLK 14
#define MI_PIN 12
#define WIDTH 13
#define OFFSET 35
#define HIGHPASS 80
#define LOWPASS 4000
// variables for the locations of the keypad buttons
#define BUTTON_X 100
#define BUTTON_Y 80
#define BUTTON_W 60
#define BUTTON_H 30
#define BUTTON_SPACING_X 10
#define BUTTON_SPACING_Y 10
#define BUTTON_TEXTSIZE 2
ILI9341_t3 Display = ILI9341_t3(CS_PIN, DC_PIN, 240, 320, PIN_RST, MO_PIN, Display_SCLK, MI_PIN);
AudioInputI2S i2s1; //xy=100,155
AudioMixer4 mixer1; //xy=316,91
AudioMixer4 mixer2; //xy=316,245
AudioFilterBiquad biquad1; //xy=499,91
AudioFilterBiquad biquad2; //xy=507,246
AudioOutputI2S i2s2; //xy=684,181
AudioAnalyzeFFT1024 fft1024_1; //xy=770,420
AudioConnection patchCord1(i2s1, 0, mixer1, 0);
AudioConnection patchCord2(i2s1, 1, mixer2, 0);
AudioConnection patchCord3(mixer1, biquad1);
AudioConnection patchCord4(mixer2, biquad2);
AudioConnection patchCord5(biquad1, 0, i2s2, 0);
AudioConnection patchCord6(biquad2, 0, i2s2, 1);
AudioConnection patchCord7(biquad2, fft1024_1);
AudioControlSGTL5000 sgtl5000_1; //xy=746,53
// GUItool: end automatically generated code
int left, top , wide , high;
int TempNum;
int HighPassF = 0;
int LowPassF = 0;
int MicGain = 5;
byte ShowHistory = 0;
byte Background = 0;
byte Brightness = 255;
byte HighPass = 0;
byte LowPass = 0;
uint16_t BackColor = C_BLACK;
uint16_t ForeColor = C_WHITE;
unsigned long Showit;
char SetupBtnText[8] = "Setup";
char ChangeBtnText[8] = "Set";
char DoneBtnText[8] = "Done";
char FilterText[2][5] = {"Off", "On" };
char HistoryText[2][5] = {"No", "Yes" };
char KeyPadBtnText[12][5] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "Done", "0", "Clr" };
uint16_t KeyPadBtnColor[12] = {C_BLUE, C_BLUE, C_BLUE,
C_BLUE, C_BLUE, C_BLUE,
C_BLUE, C_BLUE, C_BLUE,
C_DKGREEN, C_BLUE, C_DKRED
};
byte Qty, j, i, row, col, b;
int x, y, MixGain, oMixGain;
// An array to hold the 16 frequency bands
float level[16];
float Max[16];
UTouch Touch( 0, 1, 2, 3, 4);
Adafruit_GFX_Button KeyPadBtn[12];
Adafruit_GFX_Button SetupBtn;
Adafruit_GFX_Button HistoryBtn;
Adafruit_GFX_Button MicGainBtn;
Adafruit_GFX_Button BackColorBtn;
Adafruit_GFX_Button HighPassFBtn;
Adafruit_GFX_Button LowPassFBtn;
Adafruit_GFX_Button DoneBtn;
Adafruit_GFX_Button HighPassBtn;
Adafruit_GFX_Button LowPassBtn;
void setup() {
pinMode(0, INPUT);
pinMode(1, INPUT);
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
Display.begin();
Display.fillScreen(C_BLACK);
Display.setRotation(3);
GetParameters();
if (Background == 0) {
BackColor = C_BLACK;
ForeColor = C_WHITE;
}
else {
BackColor = C_WHITE;
ForeColor = C_BLACK;
}
analogWrite(LED_PIN, Brightness);
Display.fillScreen(BackColor);
AudioMemory(12);
sgtl5000_1.enable();
sgtl5000_1.volume(.7);
sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
sgtl5000_1.lineInLevel(MicGain);
sgtl5000_1.adcHighPassFilterDisable();
fft1024_1.windowFunction(AudioWindowHanning1024);
if (HighPass == 1) {
biquad1.setHighpass(0, HighPassF, FILTER_Q);
biquad2.setHighpass(0, HighPassF, FILTER_Q);
}
else if (HighPass == 0) {
biquad1.setHighpass(0, 20, FILTER_Q);
biquad2.setHighpass(0, 20, FILTER_Q);
}
if (LowPass == 1) {
biquad1.setLowpass(0, LowPassF, FILTER_Q);
biquad2.setLowpass(0, LowPassF, FILTER_Q);
}
else if (LowPass == 0) {
biquad1.setLowpass(0, 20000, FILTER_Q);
biquad2.setLowpass(0, 20000, FILTER_Q);
}
Touch.InitTouch();
Touch.setPrecision(PREC_EXTREME);
SetupBtn.initButton(&Display, 270, 18, 80, 29, C_DKRED, C_RED, C_WHITE, SetupBtnText, 2);
HistoryBtn.initButton(&Display, 225, 70, 50, 25, C_DKGREY, C_GREY, C_BLACK, ChangeBtnText, 2);
MicGainBtn.initButton(&Display, 225, 100, 50, 25, C_DKGREY, C_GREY, C_BLACK, ChangeBtnText, 2);
HighPassBtn.initButton(&Display, 225, 130, 50, 25, C_DKGREY, C_GREY, C_BLACK, ChangeBtnText, 2);
LowPassBtn.initButton(&Display, 225, 160, 50, 25, C_DKGREY, C_GREY, C_BLACK, ChangeBtnText, 2);
HighPassFBtn.initButton(&Display, 280, 130, 50, 25, C_DKGREY, C_GREY, C_BLACK, ChangeBtnText, 2);
LowPassFBtn.initButton(&Display, 280, 160, 50, 25, C_DKGREY, C_GREY, C_BLACK, ChangeBtnText, 2);
BackColorBtn.initButton(&Display, 225, 190, 50, 25, C_DKGREY, C_GREY, C_BLACK, ChangeBtnText, 2);
DoneBtn.initButton(&Display, 270, 18, 80, 29, C_DKRED, C_RED, C_WHITE, DoneBtnText, 2);
// create KeyPadBtn
for (row = 0; row < 4; row++) {
for (col = 0; col < 3; col++) {
KeyPadBtn[col + row * 3].initButton(&Display, BUTTON_X + col * (BUTTON_W + BUTTON_SPACING_X),
BUTTON_Y + row * (BUTTON_H + BUTTON_SPACING_Y),
BUTTON_W, BUTTON_H, C_WHITE, KeyPadBtnColor[col + row * 3], C_WHITE,
KeyPadBtnText[col + row * 3], BUTTON_TEXTSIZE);
}
}
delay(100);
y = 150;
MixGain = y;
oMixGain = y;
mixer1.gain(0, (220 - MixGain) / MIXGAIN);
mixer2.gain(0, (220 - MixGain) / MIXGAIN);
DrawMainScreen();
DrawGain();
}
void loop() {
if (fft1024_1.available()) {
ProcessTouch();
level[0] = fft1024_1.read(0) * 1.21 * MIC_BAR_GAIN;
level[1] = fft1024_1.read(1) * 1.18 * MIC_BAR_GAIN;
level[2] = fft1024_1.read(2, 3) * 1.15 * MIC_BAR_GAIN;
level[3] = fft1024_1.read(4, 6) * 1.12 * MIC_BAR_GAIN;
level[4] = fft1024_1.read(7, 10) * 1.09 * MIC_BAR_GAIN;
level[5] = fft1024_1.read(11, 15) * 1.06 * MIC_BAR_GAIN;
level[6] = fft1024_1.read(16, 22) * 1.03 * MIC_BAR_GAIN;
level[7] = fft1024_1.read(23, 32) * 1.00 * MIC_BAR_GAIN;
level[8] = fft1024_1.read(33, 46) * 0.96 * MIC_BAR_GAIN;
level[9] = fft1024_1.read(47, 66) * 0.93 * MIC_BAR_GAIN;
level[10] = fft1024_1.read(67, 93) * 0.90 * MIC_BAR_GAIN;
level[11] = fft1024_1.read(94, 131) * 0.87 * MIC_BAR_GAIN;
level[12] = fft1024_1.read(132, 184) * 0.84 * MIC_BAR_GAIN;
level[13] = fft1024_1.read(185, 257) * 0.81 * MIC_BAR_GAIN;
level[14] = fft1024_1.read(258, 359) * 0.78 * MIC_BAR_GAIN;
level[15] = fft1024_1.read(360, 511) * 0.75 * MIC_BAR_GAIN;
for (i = 0; i < 16; i++) { // cycle through the 16 channels
int line1 = level[i] * 180;
if (line1 > 180) {
line1 = 180;
}
// get number of bars
Qty = line1 / 10;
for (j = Qty; j < 18; j++) {
Display.fillRect( (i * WIDTH) + OFFSET, 220 - (j * 10), WIDTH - 1, 9, BackColor);
}
if (ShowHistory) {
if (Qty > Max[i]) {
Max[i] = Qty - 1;
}
if ((millis() - Showit ) > 2000) {
Showit = millis();
for (byte k = 0; k < 16; k++) {
Display.fillRect((i * WIDTH) + OFFSET, 220 - (Max[k] * 10), WIDTH - 1, 9, BackColor);
Max[k] = 0;
}
}
else {
if (Max[i] < 12) {
Display.fillRect( (i * WIDTH) + OFFSET, 220 - (Max[i] * 10), WIDTH - 1, 9, C_GREEN);
}
else if (Max[i] < 16) {
Display.fillRect( (i * WIDTH) + OFFSET, 220 - (Max[i] * 10), WIDTH - 1, 9, C_YELLOW);
}
else {
Display.fillRect( (i * WIDTH) + OFFSET, 220 - (Max[i] * 10), WIDTH - 1, 9, C_RED);
}
}
}
for ( j = 0; j < Qty; j++) {
if (j < 12) {
Display.fillRect( (i * WIDTH) + OFFSET, 220 - (j * 10), WIDTH - 1, 9, C_GREEN);
}
else if (j < 16) {
Display.fillRect( (i * WIDTH) + OFFSET, 220 - (j * 10), WIDTH - 1, 9, C_YELLOW);
}
else {
Display.fillRect( (i * WIDTH) + OFFSET, 220 - (j * 10), WIDTH - 1, 9, C_RED);
}
}
Display.setFont(Arial_12_Bold);
Display.setTextColor(ForeColor, BackColor);
Display.setCursor(2, 220);
Display.print(F("-o")) ;
Display.setCursor(16, 220);
Display.print(F("o")) ;
Display.setCursor(2, 100);
Display.print(F("-12")) ;;
Display.setCursor(2, 45);
Display.print(F("+3")) ;;
Display.drawFastHLine( 27, 229, 215, C_GREY);
Display.drawFastHLine( 27, 109, 215, C_GREY);
Display.drawFastHLine( 27, 49, 215, C_GREY);
}
}
}
void DrawMainScreen() {
Display.setFont(Arial_18_Bold);
Display.setTextColor(C_DKGREY, BackColor);
Display.setCursor(5, 7);
Display.print("DSLR Mic Monitor");
Display.setTextColor(C_BLUE, BackColor);
Display.setCursor(3, 5);
Display.print("DSLR Mic Monitor");
Display.setFont(Arial_14);
SetupBtn.drawButton();
}
void DrawGain() {
// clear old button
Display.fillRoundRect (266, oMixGain, 45, 20, 3, BackColor);
Display.fillRoundRect( 258, 40, 60, 190, 6, C_GREY);
Display.drawRoundRect( 258, 40, 60, 190, 6, C_DKGREY);
Display.fillRect( 275, 60, 3, 140, C_BLACK);
Display.fillRect( 298, 60, 3, 140, C_BLACK);
Display.fillRoundRect (266, MixGain, 45, 18, 3, C_DKGREY);
Display.drawRoundRect (266, MixGain, 45, 18, 3, C_GREY);
Display.setFont(Arial_12_Bold);
Display.setTextColor(C_BLACK, BackColor);
Display.setCursor(270, 45);
Display.print(F("Gain")) ;
Display.setCursor(275, 205);
Display.print(F("L")) ;
Display.setCursor(295, 205);
Display.print(F("R")) ;
mixer1.gain(0, (220 - MixGain) / MIXGAIN);
mixer2.gain(0, (220 - MixGain) / MIXGAIN);
}
void ProcessTouch() {
if (Touch.dataAvailable()) {
Touch.read();
x = Touch.getX();
y = Touch.getY();
delay(50); // debounce the touch
if (PressIt(SetupBtn, x, y) == true) {
SetupScreen();
return;
}
else if ((x > 250) & (y > 53) & (y < 190)) {
//oMixGain = MixGain;
MixGain = y;
if (oMixGain != MixGain) {
oMixGain = MixGain;
DrawGain();
}
}
else if (( x > 10) & (x < 200)) {
Brightness = map(y, 0, 240, 255, 10);
analogWrite(LED_PIN, Brightness);
}
}
}
void SetupScreen() {
bool KeepIn = true;
DrawSetupScreen();
while (KeepIn) {
if (Touch.dataAvailable()) {
Touch.read();
x = Touch.getX();
y = Touch.getY();
if (PressIt(HistoryBtn, x, y) == true) {
if (ShowHistory == 1) {
ShowHistory = 0;
}
else if (ShowHistory == 0) {
ShowHistory = 1;
}
DrawSetupScreen();
}
if (PressIt(MicGainBtn, x, y) == true) {
KeyPad(MicGain, 5, 15);
sgtl5000_1.lineInLevel(MicGain);
}
if (PressIt(BackColorBtn, x, y) == true) {
if (Background == 0) {
Background = 1;
BackColor = C_WHITE;
ForeColor = C_BLACK;
DrawSetupScreen();
}
else {
Background = 0;
BackColor = C_BLACK;
ForeColor = C_WHITE;
DrawSetupScreen();
}
// save back color
}
if (PressIt(HighPassBtn, x, y) == true) {
if (HighPass == 0) {
HighPass = 1;
biquad1.setHighpass(0, HighPassF, FILTER_Q);
biquad2.setHighpass(0, HighPassF, FILTER_Q);
}
else if (HighPass == 1) {
HighPass = 0;
biquad1.setHighpass(0, 20, FILTER_Q);
biquad2.setHighpass(0, 20, FILTER_Q);
}
DrawSetupScreen();
}
if (PressIt(LowPassBtn, x, y) == true) {
if (LowPass == 0) {
LowPass = 1;
biquad1.setLowpass(0, LowPassF, FILTER_Q);
biquad2.setLowpass(0, LowPassF, FILTER_Q);
}
else if (LowPass == 1) {
LowPass = 0;
biquad1.setLowpass(0, 20000, FILTER_Q);
biquad2.setLowpass(0, 20000, FILTER_Q);
}
DrawSetupScreen();
}
if (PressIt(HighPassFBtn, x, y) == true) {
KeyPad(HighPassF, 20, 400);
DrawSetupScreen();
}
if (PressIt(LowPassFBtn, x, y) == true) {
KeyPad(LowPassF, 400, 20000);
DrawSetupScreen();
}
if (PressIt(DoneBtn, x, y) == true) {
KeepIn = false;
}
}
}
// save data and exit
EEPROM.put(10, ShowHistory);
EEPROM.put(20, Background);
EEPROM.put(30, MicGain);
EEPROM.put(40, HighPass);
EEPROM.put(50, LowPass);
EEPROM.put(60, HighPassF);
EEPROM.put(70, LowPassF);
Display.fillScreen(BackColor);
DrawMainScreen();
DrawGain();
}
void DrawSetupScreen() {
Display.fillScreen(BackColor);
Display.setFont(Arial_18_Bold);
Display.setTextColor(C_DKGREY, BackColor);
Display.setCursor(5, 7);
Display.print("Setup");
Display.setTextColor(C_BLUE, BackColor);
Display.setCursor(3, 5);
Display.print("Setup");
Display.setFont(Arial_12_Bold);
Display.setTextColor(ForeColor, BackColor);
HistoryBtn.drawButton();
MicGainBtn.drawButton();
HighPassBtn.drawButton();
LowPassBtn.drawButton();
HighPassFBtn.drawButton();
LowPassFBtn.drawButton();
BackColorBtn.drawButton();
DoneBtn.drawButton();
Display.setTextColor(ForeColor, BackColor);
Display.setFont(Arial_12);
Display.setCursor(10 , 65);
Display.print("Show bar history: " + String(HistoryText[ShowHistory]));
Display.setCursor(10 , 95);
Display.print("Microphone gain: " + String(MicGain));
Display.setCursor(10 , 125);
Display.print("High Pass: " + String(FilterText[HighPass]) + ", " + String(HighPassF) + " hz");
Display.setCursor(10 , 155);
Display.print("Low Pass: " + String(FilterText[LowPass]) + ", " + String(LowPassF) + " hz");
Display.setCursor(10 , 185);
Display.print("Background color");
}
/*
Function to draw a keypad input screen
Potential edits: possibly button colors
*/
void KeyPad(int & TheNumber, int MinVal, int MaxVal) {
Display.setFont(Arial_14);
left = BUTTON_X - (BUTTON_W);
top = BUTTON_Y - (2 * BUTTON_H);
wide = (3 * BUTTON_W ) + (8 * BUTTON_SPACING_X);
high = 5 * (BUTTON_H + BUTTON_SPACING_Y);
TempNum = TheNumber;
bool KeepIn = true;
Display.fillRect(left, top, wide , high, C_DKGREY);
Display.drawRect(left, top, wide , high, C_LTGREY);
Display.fillRect(left + 10, top + 10, wide - 20 , 30, C_GREY);
Display.drawRect(left + 10, top + 10, wide - 20 , 30, C_WHITE);
Display.setCursor(left + 110 , top + 18);
Display.setTextColor(C_BLACK, 80);
Display.print("(" + String(MinVal) + " - " + String(MaxVal) + ")");
Display.setCursor(left + 20 , top + 18);
Display.setTextColor(C_BLACK, C_GREY);
Display.print(TheNumber);
for (row = 0; row < 4; row++) {
for (col = 0; col < 3; col++) {
KeyPadBtn[col + row * 3].drawButton();
}
}
while (KeepIn) {
// get the touch point
if (Touch.dataAvailable()) {
Touch.read();
x = Touch.getX();
y = Touch.getY();
// go thru all the KeyPadBtn, checking if they were pressed
for (b = 0; b < 12; b++) {
if (PressIt(KeyPadBtn[b], x, y) == true) {
if ((b < 9) | (b == 10)) {
TempNum *= 10;
if (TempNum == 0) {
Display.fillRect(left + 10, top + 10, 80 , 30, C_GREY);
}
if (b != 10) {
TempNum += (b + 1);
}
if (TempNum > MaxVal) {
Display.fillRect(left + 10, top + 10, 80 , 30, C_GREY);
TempNum = TempNum / 10;
// TempNum -= (b + 1);
}
}
// clr button! delete char
if (b == 11) {
Display.fillRect(left + 10, top + 10, 80 , 30, C_GREY);
Display.drawRect(left + 10, top + 10, 80 , 30, C_WHITE);
TempNum = 0;
}
if (b == 9) {
if (TempNum >= MinVal) {
KeepIn = false;
}
}
Display.setCursor(left + 20 , top + 18);
Display.setTextColor(C_BLACK, C_GREY);
Display.print(TempNum);
}
}
}
}
TheNumber = TempNum;
DrawSetupScreen();
}
void GetParameters() {
byte i, test;
EEPROM.get(0, test);
if (test == 255) {
// new programmer reset the whole thing
for (i = 0; i < 255; i++) {
EEPROM.put(i, 0);
}
// set some defaulTouch
// and populate the eeprom
ShowHistory = 0;
EEPROM.get(10, ShowHistory);
Background = 0;
EEPROM.put(20, Background);
MicGain = 5;
EEPROM.put(30, MicGain);
HighPass = 0;
EEPROM.put(40, HighPass);
LowPass = 0;
EEPROM.put(50, LowPass);
HighPassF = 4000;
EEPROM.put(40, HighPassF);
LowPassF = 40;
EEPROM.put(50, LowPassF);
}
EEPROM.get(10, ShowHistory);
EEPROM.get(20, Background);
EEPROM.get(30, MicGain);
EEPROM.get(40, HighPass);
EEPROM.get(50, LowPass);
EEPROM.get(60, HighPassF);
EEPROM.get(70, LowPassF);
}
/*
function to proccess a button press
Potential edits: modify delay to change debounce behavior
*/
bool PressIt(Adafruit_GFX_Button TheButton, int x, int y) {
if (TheButton.contains(x, y)) {
TheButton.press(true); // tell the button it is pressed
} else {
TheButton.press(false); // tell the button it is NOT pressed
}
if (TheButton.justReleased()) {
TheButton.drawButton(); // draw normal
}
if (TheButton.justPressed()) {
TheButton.drawButton(true); // draw invert!
delay(200); // UI debouncing
TheButton.drawButton(false); // draw invert!
return true;
}
return false;
}