/* .fir file parameters which generated these coefficients | |||||
100 1 3 16 32768 44100 | |||||
0 500 1200 1700 2300 | |||||
0.0000 1.0000 0.0000 | |||||
70.0000 1.0000 70.0000 | |||||
*/ | |||||
(short)0xFFAA, | |||||
(short)0xFFC5, | |||||
(short)0xFFB6, | |||||
(short)0xFFA7, | |||||
(short)0xFF9B, | |||||
(short)0xFF94, | |||||
(short)0xFF93, | |||||
(short)0xFF9A, | |||||
(short)0xFFAA, | |||||
(short)0xFFC4, | |||||
(short)0xFFE9, | |||||
(short)0x0017, | |||||
(short)0x004F, | |||||
(short)0x008E, | |||||
(short)0x00D1, | |||||
(short)0x0115, | |||||
(short)0x0155, | |||||
(short)0x018F, | |||||
(short)0x01BC, | |||||
(short)0x01D9, | |||||
(short)0x01E2, | |||||
(short)0x01D3, | |||||
(short)0x01AB, | |||||
(short)0x0168, | |||||
(short)0x010A, | |||||
(short)0x0095, | |||||
(short)0x000B, | |||||
(short)0xFF72, | |||||
(short)0xFED1, | |||||
(short)0xFE2E, | |||||
(short)0xFD92, | |||||
(short)0xFD06, | |||||
(short)0xFC92, | |||||
(short)0xFC3D, | |||||
(short)0xFC0D, | |||||
(short)0xFC08, | |||||
(short)0xFC30, | |||||
(short)0xFC85, | |||||
(short)0xFD06, | |||||
(short)0xFDAF, | |||||
(short)0xFE79, | |||||
(short)0xFF5C, | |||||
(short)0x004D, | |||||
(short)0x0143, | |||||
(short)0x0231, | |||||
(short)0x030D, | |||||
(short)0x03CB, | |||||
(short)0x0463, | |||||
(short)0x04CC, | |||||
(short)0x0502, | |||||
(short)0x0502, | |||||
(short)0x04CC, | |||||
(short)0x0463, | |||||
(short)0x03CB, | |||||
(short)0x030D, | |||||
(short)0x0231, | |||||
(short)0x0143, | |||||
(short)0x004D, | |||||
(short)0xFF5C, | |||||
(short)0xFE79, | |||||
(short)0xFDAF, | |||||
(short)0xFD06, | |||||
(short)0xFC85, | |||||
(short)0xFC30, | |||||
(short)0xFC08, | |||||
(short)0xFC0D, | |||||
(short)0xFC3D, | |||||
(short)0xFC92, | |||||
(short)0xFD06, | |||||
(short)0xFD92, | |||||
(short)0xFE2E, | |||||
(short)0xFED1, | |||||
(short)0xFF72, | |||||
(short)0x000B, | |||||
(short)0x0095, | |||||
(short)0x010A, | |||||
(short)0x0168, | |||||
(short)0x01AB, | |||||
(short)0x01D3, | |||||
(short)0x01E2, | |||||
(short)0x01D9, | |||||
(short)0x01BC, | |||||
(short)0x018F, | |||||
(short)0x0155, | |||||
(short)0x0115, | |||||
(short)0x00D1, | |||||
(short)0x008E, | |||||
(short)0x004F, | |||||
(short)0x0017, | |||||
(short)0xFFE9, | |||||
(short)0xFFC4, | |||||
(short)0xFFAA, | |||||
(short)0xFF9A, | |||||
(short)0xFF93, | |||||
(short)0xFF94, | |||||
(short)0xFF9B, | |||||
(short)0xFFA7, | |||||
(short)0xFFB6, | |||||
(short)0xFFC5, | |||||
(short)0xFFAA, | |||||
#include "filters.h" | |||||
short low_pass[NUM_COEFFS] = { | |||||
#include "lopass_4000_44100.h" | |||||
}; | |||||
short band_pass[NUM_COEFFS] = { | |||||
#include "bandp_1200_1700.h" | |||||
}; |
// Number of coefficients | |||||
#define NUM_COEFFS 100 | |||||
extern short low_pass[]; | |||||
extern short band_pass[]; | |||||
/* | |||||
The audio board uses the following pins. | |||||
6 - MEMCS | |||||
7 - MOSI | |||||
9 - BCLK | |||||
10 - SDCS | |||||
11 - MCLK | |||||
12 - MISO | |||||
13 - RX | |||||
14 - SCLK | |||||
15 - VOL | |||||
18 - SDA | |||||
19 - SCL | |||||
22 - TX | |||||
23 - LRCLK | |||||
*/ | |||||
//#include <arm_math.h> | |||||
#include <Audio.h> | |||||
#include <Wire.h> | |||||
#include <SD.h> | |||||
#include <SPI.h> | |||||
#include <Bounce.h> | |||||
#include "filters.h" | |||||
// If this pin is grounded the FIR filter is turned which | |||||
// makes just pass through the audio | |||||
// Don't use any of the pins listed above | |||||
#define PASSTHRU_PIN 1 | |||||
// If this pin goes low the next FIR filter in the list | |||||
// is switched in. | |||||
#define FILTER_PIN 0 | |||||
Bounce b_passthru = Bounce(PASSTHRU_PIN,15); | |||||
Bounce b_filter = Bounce(FILTER_PIN,15); | |||||
//const int myInput = AUDIO_INPUT_MIC; | |||||
const int myInput = AUDIO_INPUT_LINEIN; | |||||
AudioInputI2S audioInput; // audio shield: mic or line-in | |||||
AudioFilterFIR myFilter; | |||||
AudioOutputI2S audioOutput; // audio shield: headphones & line-out | |||||
// Create Audio connections between the components | |||||
// Both channels of the audio input go to the FIR filter | |||||
AudioConnection c1(audioInput, 0, myFilter, 0); | |||||
AudioConnection c2(audioInput, 1, myFilter, 1); | |||||
// both channels from the FIR filter go to the audio output | |||||
AudioConnection c3(myFilter, 0, audioOutput, 0); | |||||
AudioConnection c4(myFilter, 1, audioOutput, 1); | |||||
AudioControlSGTL5000 audioShield; | |||||
struct fir_filter { | |||||
short *coeffs; | |||||
short num_coeffs; | |||||
}; | |||||
// index of current filter. Start with the low pass. | |||||
int fir_idx = 0; | |||||
struct fir_filter fir_list[] = { | |||||
low_pass , 100, // low pass with cutoff at 1kHz and -60dB at 2kHz | |||||
band_pass, 100, // bandpass 1200Hz - 1700Hz | |||||
NULL, 0 | |||||
}; | |||||
void setup() { | |||||
Serial.begin(9600); | |||||
while (!Serial) ; | |||||
delay(3000); | |||||
pinMode(PASSTHRU_PIN,INPUT_PULLUP); | |||||
pinMode(FILTER_PIN,INPUT_PULLUP); | |||||
// It doesn't work properly with any less than 8 | |||||
AudioMemory(8); | |||||
audioShield.enable(); | |||||
audioShield.inputSelect(myInput); | |||||
audioShield.volume(50); | |||||
// Warn that the passthru pin is grounded | |||||
if(!digitalRead(PASSTHRU_PIN)) { | |||||
Serial.print("PASSTHRU_PIN ("); | |||||
Serial.print(PASSTHRU_PIN); | |||||
Serial.println(") is grounded"); | |||||
} | |||||
// Warn that the filter pin is grounded | |||||
if(!digitalRead(FILTER_PIN)) { | |||||
Serial.print("FILTER_PIN ("); | |||||
Serial.print(FILTER_PIN); | |||||
Serial.println(") is grounded"); | |||||
} | |||||
// Initialize the filter | |||||
myFilter.begin(fir_list[0].coeffs,fir_list[0].num_coeffs); | |||||
Serial.println("setup done"); | |||||
} | |||||
// index of current filter when passthrough is selected | |||||
int old_idx = -1; | |||||
// audio volume | |||||
int volume = 0; | |||||
void loop() | |||||
{ | |||||
// Volume control | |||||
int n = analogRead(15); | |||||
if (n != volume) { | |||||
volume = n; | |||||
audioShield.volume((float)n / 10.23); | |||||
} | |||||
// update the two buttons | |||||
b_passthru.update(); | |||||
b_filter.update(); | |||||
// If the passthru button is pushed, save the current | |||||
// filter index and then switch the filter to passthru | |||||
if(b_passthru.fallingEdge()) { | |||||
old_idx = fir_idx; | |||||
myFilter.begin(FIR_PASSTHRU,0); | |||||
} | |||||
// If passthru button is released, restore previous filter | |||||
if(b_passthru.risingEdge()) { | |||||
if(old_idx != -1)myFilter.begin(fir_list[fir_idx].coeffs,fir_list[fir_idx].num_coeffs); | |||||
old_idx = -1; | |||||
} | |||||
// switch to next filter in the list | |||||
if(b_filter.fallingEdge()) { | |||||
fir_idx++; | |||||
if(fir_list[fir_idx].num_coeffs == 0)fir_idx = 0; | |||||
myFilter.begin(fir_list[fir_idx].coeffs,fir_list[fir_idx].num_coeffs); | |||||
} | |||||
} | |||||
/* .fir file parameters which generated these coefficients | |||||
100 1 2 16 32768 44100 | |||||
0 1000 2000 | |||||
1.0000 0.0000 | |||||
1.0000 70.0000 | |||||
*/ | |||||
(short)0x0015, | |||||
(short)0x0011, | |||||
(short)0x0017, | |||||
(short)0x001E, | |||||
(short)0x0025, | |||||
(short)0x002C, | |||||
(short)0x0032, | |||||
(short)0x0037, | |||||
(short)0x003B, | |||||
(short)0x003C, | |||||
(short)0x003B, | |||||
(short)0x0036, | |||||
(short)0x002E, | |||||
(short)0x0021, | |||||
(short)0x000F, | |||||
(short)0xFFF9, | |||||
(short)0xFFDE, | |||||
(short)0xFFBF, | |||||
(short)0xFF9C, | |||||
(short)0xFF76, | |||||
(short)0xFF4F, | |||||
(short)0xFF27, | |||||
(short)0xFF02, | |||||
(short)0xFEDF, | |||||
(short)0xFEC2, | |||||
(short)0xFEAC, | |||||
(short)0xFEA0, | |||||
(short)0xFE9F, | |||||
(short)0xFEAC, | |||||
(short)0xFEC8, | |||||
(short)0xFEF4, | |||||
(short)0xFF31, | |||||
(short)0xFF7F, | |||||
(short)0xFFDF, | |||||
(short)0x0050, | |||||
(short)0x00D0, | |||||
(short)0x015E, | |||||
(short)0x01F8, | |||||
(short)0x029A, | |||||
(short)0x0341, | |||||
(short)0x03EA, | |||||
(short)0x0491, | |||||
(short)0x0532, | |||||
(short)0x05CA, | |||||
(short)0x0653, | |||||
(short)0x06CC, | |||||
(short)0x0731, | |||||
(short)0x077F, | |||||
(short)0x07B4, | |||||
(short)0x07CF, | |||||
(short)0x07CF, | |||||
(short)0x07B4, | |||||
(short)0x077F, | |||||
(short)0x0731, | |||||
(short)0x06CC, | |||||
(short)0x0653, | |||||
(short)0x05CA, | |||||
(short)0x0532, | |||||
(short)0x0491, | |||||
(short)0x03EA, | |||||
(short)0x0341, | |||||
(short)0x029A, | |||||
(short)0x01F8, | |||||
(short)0x015E, | |||||
(short)0x00D0, | |||||
(short)0x0050, | |||||
(short)0xFFDF, | |||||
(short)0xFF7F, | |||||
(short)0xFF31, | |||||
(short)0xFEF4, | |||||
(short)0xFEC8, | |||||
(short)0xFEAC, | |||||
(short)0xFE9F, | |||||
(short)0xFEA0, | |||||
(short)0xFEAC, | |||||
(short)0xFEC2, | |||||
(short)0xFEDF, | |||||
(short)0xFF02, | |||||
(short)0xFF27, | |||||
(short)0xFF4F, | |||||
(short)0xFF76, | |||||
(short)0xFF9C, | |||||
(short)0xFFBF, | |||||
(short)0xFFDE, | |||||
(short)0xFFF9, | |||||
(short)0x000F, | |||||
(short)0x0021, | |||||
(short)0x002E, | |||||
(short)0x0036, | |||||
(short)0x003B, | |||||
(short)0x003C, | |||||
(short)0x003B, | |||||
(short)0x0037, | |||||
(short)0x0032, | |||||
(short)0x002C, | |||||
(short)0x0025, | |||||
(short)0x001E, | |||||
(short)0x0017, | |||||
(short)0x0011, | |||||
(short)0x0015, | |||||