|
| 1 | +// Example for DTMF detection using Goertzel algorithm |
| 2 | +// Uses AudioKit and I2S microphones as input |
| 3 | + |
| 4 | +#include "AudioTools.h" |
| 5 | +#include "AudioTools/AudioLibs/AudioBoardStream.h" |
| 6 | + |
| 7 | +AudioInfo info(44100, 2, 16); // 8kHz, mono, 16 bits |
| 8 | +AudioBoardStream kit(AudioKitEs8388V1); // Access I2S as stream |
| 9 | +//CsvOutput<int16_t> out(Serial, 1); |
| 10 | +GoertzelStream goertzel; //(out); |
| 11 | +StreamCopy copier(goertzel, kit); // copy kit to georzel |
| 12 | + |
| 13 | +// represent DTMF keys |
| 14 | +class DTMF { |
| 15 | + public: |
| 16 | + enum Dimension { Row, Col }; |
| 17 | + DTMF() = default; |
| 18 | + DTMF(Dimension d, int i) { |
| 19 | + if (d == Row) |
| 20 | + row = i; |
| 21 | + else |
| 22 | + col = i; |
| 23 | + } |
| 24 | + void clear() { |
| 25 | + row = -1; |
| 26 | + col = -1; |
| 27 | + } |
| 28 | + char getChar() { |
| 29 | + if (row == -1 || col == -1) return '?'; |
| 30 | + return keys[row][col]; |
| 31 | + } |
| 32 | + int row = -1; |
| 33 | + int col = -1; |
| 34 | + const char* keys[4] = {"123A", "456B", "789C", "*0#D"}; |
| 35 | +} actual_dtmf; |
| 36 | + |
| 37 | +// combine row and col information |
| 38 | +void GoetzelCallback(float frequency, float magnitude, void* ref) { |
| 39 | + DTMF* dtmf = (DTMF*)ref; |
| 40 | + LOGW("Time: %lu - Hz: %f Mag: %f", millis(), frequency, magnitude); |
| 41 | + // we get either row or col information |
| 42 | + if (dtmf->row != -1) { |
| 43 | + actual_dtmf.row = dtmf->row; |
| 44 | + } else { |
| 45 | + actual_dtmf.col = dtmf->col; |
| 46 | + |
| 47 | + // print detected key |
| 48 | + Serial.println(actual_dtmf.getChar()); |
| 49 | + actual_dtmf.clear(); |
| 50 | + } |
| 51 | +} |
| 52 | + |
| 53 | +void setup() { |
| 54 | + Serial.begin(115200); |
| 55 | + AudioToolsLogger.begin(Serial, AudioToolsLogLevel::Warning); |
| 56 | + |
| 57 | + // start audio input from microphones |
| 58 | + auto cfg = kit.defaultConfig(RX_MODE); |
| 59 | + cfg.copyFrom(info); |
| 60 | + cfg.sd_active = false; |
| 61 | + cfg.input_device = ADC_INPUT_LINE2; |
| 62 | + cfg.use_apll = false; |
| 63 | + kit.begin(cfg); |
| 64 | + |
| 65 | + // lower frequencies - with keys |
| 66 | + goertzel.addFrequency(697, new DTMF(DTMF::Row, 0)); |
| 67 | + goertzel.addFrequency(770, new DTMF(DTMF::Row, 1)); |
| 68 | + goertzel.addFrequency(852, new DTMF(DTMF::Row, 2)); |
| 69 | + goertzel.addFrequency(941, new DTMF(DTMF::Row, 3)); |
| 70 | + // higher frequencies with idx |
| 71 | + goertzel.addFrequency(1209, new DTMF(DTMF::Col, 0)); |
| 72 | + goertzel.addFrequency(1336, new DTMF(DTMF::Col, 1)); |
| 73 | + goertzel.addFrequency(1477, new DTMF(DTMF::Col, 2)); |
| 74 | + goertzel.addFrequency(1633, new DTMF(DTMF::Col, 3)); |
| 75 | + // define callback |
| 76 | + goertzel.setFrequencyDetectionCallback(GoetzelCallback); |
| 77 | + |
| 78 | + // start goertzel |
| 79 | + auto gcfg = goertzel.defaultConfig(); |
| 80 | + gcfg.copyFrom(info); |
| 81 | + gcfg.threshold = 5.0; |
| 82 | + gcfg.block_size = 1024; |
| 83 | + goertzel.begin(gcfg); |
| 84 | +} |
| 85 | + |
| 86 | +void loop() { copier.copy(); } |
0 commit comments