| /* .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, | |||||