Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp@0:f0a3e5729b8f, 2019-10-16 (annotated)
- Committer:
- gemmaro
- Date:
- Wed Oct 16 04:09:09 2019 +0000
- Revision:
- 0:f0a3e5729b8f
- Child:
- 1:1bec1c13107e
First commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gemmaro | 0:f0a3e5729b8f | 1 | #include "mbed.h" |
gemmaro | 0:f0a3e5729b8f | 2 | |
gemmaro | 0:f0a3e5729b8f | 3 | DigitalOut myled1(LED1); |
gemmaro | 0:f0a3e5729b8f | 4 | DigitalOut myled2(LED2); |
gemmaro | 0:f0a3e5729b8f | 5 | DigitalOut myled3(LED3); |
gemmaro | 0:f0a3e5729b8f | 6 | AnalogIn MicIn(p15); |
gemmaro | 0:f0a3e5729b8f | 7 | AnalogOut HeadPhoneOut(p18); |
gemmaro | 0:f0a3e5729b8f | 8 | |
gemmaro | 0:f0a3e5729b8f | 9 | #define DATA_SIZE 15000 |
gemmaro | 0:f0a3e5729b8f | 10 | #define PI 3.1415926535897932384626433832795 |
gemmaro | 0:f0a3e5729b8f | 11 | signed short data[DATA_SIZE]; |
gemmaro | 0:f0a3e5729b8f | 12 | |
gemmaro | 0:f0a3e5729b8f | 13 | /** |
gemmaro | 0:f0a3e5729b8f | 14 | * fs: Frequency Sampling |
gemmaro | 0:f0a3e5729b8f | 15 | * offset: AD-C, DA-C |
gemmaro | 0:f0a3e5729b8f | 16 | */ |
gemmaro | 0:f0a3e5729b8f | 17 | Timer t; |
gemmaro | 0:f0a3e5729b8f | 18 | int fs = 8000; |
gemmaro | 0:f0a3e5729b8f | 19 | int dt_us = 125; |
gemmaro | 0:f0a3e5729b8f | 20 | int offset; |
gemmaro | 0:f0a3e5729b8f | 21 | |
gemmaro | 0:f0a3e5729b8f | 22 | int filter_size; |
gemmaro | 0:f0a3e5729b8f | 23 | double b[50]; |
gemmaro | 0:f0a3e5729b8f | 24 | double w[50]; |
gemmaro | 0:f0a3e5729b8f | 25 | |
gemmaro | 0:f0a3e5729b8f | 26 | void wait100us(void) { |
gemmaro | 0:f0a3e5729b8f | 27 | while (t.read_us() < dt_us) {}; |
gemmaro | 0:f0a3e5729b8f | 28 | t.reset(); |
gemmaro | 0:f0a3e5729b8f | 29 | } |
gemmaro | 0:f0a3e5729b8f | 30 | |
gemmaro | 0:f0a3e5729b8f | 31 | void rec(void) { |
gemmaro | 0:f0a3e5729b8f | 32 | unsigned short InDat; |
gemmaro | 0:f0a3e5729b8f | 33 | int i; |
gemmaro | 0:f0a3e5729b8f | 34 | |
gemmaro | 0:f0a3e5729b8f | 35 | /// recording |
gemmaro | 0:f0a3e5729b8f | 36 | myled1 = 1; |
gemmaro | 0:f0a3e5729b8f | 37 | for (i = 0; i < DATA_SIZE; ++i) { |
gemmaro | 0:f0a3e5729b8f | 38 | InDat = MicIn.read_u16() >> 4; |
gemmaro | 0:f0a3e5729b8f | 39 | data[i] = InDat; |
gemmaro | 0:f0a3e5729b8f | 40 | wait100us(); |
gemmaro | 0:f0a3e5729b8f | 41 | } |
gemmaro | 0:f0a3e5729b8f | 42 | myled1 = 0; |
gemmaro | 0:f0a3e5729b8f | 43 | } |
gemmaro | 0:f0a3e5729b8f | 44 | |
gemmaro | 0:f0a3e5729b8f | 45 | void get_offset(void) { |
gemmaro | 0:f0a3e5729b8f | 46 | unsigned short InDat; |
gemmaro | 0:f0a3e5729b8f | 47 | double a = 0; |
gemmaro | 0:f0a3e5729b8f | 48 | int i; |
gemmaro | 0:f0a3e5729b8f | 49 | for (i = 0; i < 1000; ++i) { |
gemmaro | 0:f0a3e5729b8f | 50 | InDat = MicIn.read_u16() >> 4; |
gemmaro | 0:f0a3e5729b8f | 51 | a += (double)InDat; |
gemmaro | 0:f0a3e5729b8f | 52 | wait100us(); |
gemmaro | 0:f0a3e5729b8f | 53 | } |
gemmaro | 0:f0a3e5729b8f | 54 | offset = (unsigned int)(a / 1000); |
gemmaro | 0:f0a3e5729b8f | 55 | printf("%d\n\r", offset); |
gemmaro | 0:f0a3e5729b8f | 56 | } |
gemmaro | 0:f0a3e5729b8f | 57 | |
gemmaro | 0:f0a3e5729b8f | 58 | void hanning_window(int window_size) { |
gemmaro | 0:f0a3e5729b8f | 59 | int i; |
gemmaro | 0:f0a3e5729b8f | 60 | for (i = 0; i < window_size; ++i) { |
gemmaro | 0:f0a3e5729b8f | 61 | w[i] = 0.5 - 0.5 * cos(2 * PI * ((i + 1) - 0.5) / window_size); |
gemmaro | 0:f0a3e5729b8f | 62 | } |
gemmaro | 0:f0a3e5729b8f | 63 | } |
gemmaro | 0:f0a3e5729b8f | 64 | |
gemmaro | 0:f0a3e5729b8f | 65 | int lps(int k, int offsets, int fc) { |
gemmaro | 0:f0a3e5729b8f | 66 | if (k == offsets) { |
gemmaro | 0:f0a3e5729b8f | 67 | return 2 * fc; |
gemmaro | 0:f0a3e5729b8f | 68 | } |
gemmaro | 0:f0a3e5729b8f | 69 | return 2 * fc * sin(2 * PI * fc * (k - offsets)) / (2 * PI * fc * (k - offsets)); |
gemmaro | 0:f0a3e5729b8f | 70 | } |
gemmaro | 0:f0a3e5729b8f | 71 | |
gemmaro | 0:f0a3e5729b8f | 72 | int high_pass_filter(int k, int offsets, int fc) { |
gemmaro | 0:f0a3e5729b8f | 73 | if (k == offsets) { |
gemmaro | 0:f0a3e5729b8f | 74 | return 1 - 2 * fc; |
gemmaro | 0:f0a3e5729b8f | 75 | } |
gemmaro | 0:f0a3e5729b8f | 76 | return -2 * fc * sin(2 * PI * fc * k) / (2 * PI * fc * k); |
gemmaro | 0:f0a3e5729b8f | 77 | } |
gemmaro | 0:f0a3e5729b8f | 78 | |
gemmaro | 0:f0a3e5729b8f | 79 | int band_pass_filter(int k, int offsets, int fc1, int fc2) { |
gemmaro | 0:f0a3e5729b8f | 80 | if (k == offsets) { |
gemmaro | 0:f0a3e5729b8f | 81 | return 2 * (fc2 - fc1); |
gemmaro | 0:f0a3e5729b8f | 82 | } |
gemmaro | 0:f0a3e5729b8f | 83 | return 2 * fc2 * sin(2 * PI * fc2 * k) / (2 * PI * fc2 * k) - 2 * fc1 * sin(2 * PI * fc1 * k) / (2 * PI * fc1 * k); |
gemmaro | 0:f0a3e5729b8f | 84 | } |
gemmaro | 0:f0a3e5729b8f | 85 | |
gemmaro | 0:f0a3e5729b8f | 86 | int band_eliminate_filter(int k, int offsets, int fc1, int fc2) { |
gemmaro | 0:f0a3e5729b8f | 87 | if (k == offsets) { |
gemmaro | 0:f0a3e5729b8f | 88 | return 1 - 2 * (fc2 - fc1); |
gemmaro | 0:f0a3e5729b8f | 89 | } |
gemmaro | 0:f0a3e5729b8f | 90 | return 2 * fc1 * sin(2 * PI * fc1 * k) / (2 * PI * fc1 * k) - 2 * fc2 * sin(2 * PI * fc2 * k) / (2 * PI * fc2 * k); |
gemmaro | 0:f0a3e5729b8f | 91 | } |
gemmaro | 0:f0a3e5729b8f | 92 | |
gemmaro | 0:f0a3e5729b8f | 93 | void fir_lpf(int fs, int fe, int delta) { |
gemmaro | 0:f0a3e5729b8f | 94 | int offsets; |
gemmaro | 0:f0a3e5729b8f | 95 | int k; |
gemmaro | 0:f0a3e5729b8f | 96 | float fc, delta_s; |
gemmaro | 0:f0a3e5729b8f | 97 | |
gemmaro | 0:f0a3e5729b8f | 98 | fc = (((float)fe +(float)delta / 2) / fs); |
gemmaro | 0:f0a3e5729b8f | 99 | delta_s = ((float)delta / fs); |
gemmaro | 0:f0a3e5729b8f | 100 | filter_size = (int)(3.1 / delta_s); |
gemmaro | 0:f0a3e5729b8f | 101 | if (filter_size % 2 == 0) filter_size += 1; |
gemmaro | 0:f0a3e5729b8f | 102 | hanning_window(filter_size); |
gemmaro | 0:f0a3e5729b8f | 103 | |
gemmaro | 0:f0a3e5729b8f | 104 | offsets = (filter_size - 1) / 2; |
gemmaro | 0:f0a3e5729b8f | 105 | for (k = 0; k < filter_size; ++k) { |
gemmaro | 0:f0a3e5729b8f | 106 | b[k] = lps(k, offsets, fc); |
gemmaro | 0:f0a3e5729b8f | 107 | } |
gemmaro | 0:f0a3e5729b8f | 108 | |
gemmaro | 0:f0a3e5729b8f | 109 | for (k = 0; k < filter_size; ++k) { |
gemmaro | 0:f0a3e5729b8f | 110 | b[k] *= w[k]; |
gemmaro | 0:f0a3e5729b8f | 111 | } |
gemmaro | 0:f0a3e5729b8f | 112 | } |
gemmaro | 0:f0a3e5729b8f | 113 | |
gemmaro | 0:f0a3e5729b8f | 114 | int main() { |
gemmaro | 0:f0a3e5729b8f | 115 | unsigned short InDat, OutDat; |
gemmaro | 0:f0a3e5729b8f | 116 | int fe = 100; |
gemmaro | 0:f0a3e5729b8f | 117 | int delta = 1000; |
gemmaro | 0:f0a3e5729b8f | 118 | int fs = 8000; |
gemmaro | 0:f0a3e5729b8f | 119 | int n, k; |
gemmaro | 0:f0a3e5729b8f | 120 | double y; |
gemmaro | 0:f0a3e5729b8f | 121 | |
gemmaro | 0:f0a3e5729b8f | 122 | /// Timer interrupt |
gemmaro | 0:f0a3e5729b8f | 123 | t.start(); |
gemmaro | 0:f0a3e5729b8f | 124 | t.reset(); |
gemmaro | 0:f0a3e5729b8f | 125 | get_offset(); |
gemmaro | 0:f0a3e5729b8f | 126 | |
gemmaro | 0:f0a3e5729b8f | 127 | /// Filter parameter |
gemmaro | 0:f0a3e5729b8f | 128 | myled1 = 1; |
gemmaro | 0:f0a3e5729b8f | 129 | fir_lpf(fs, fe, delta); |
gemmaro | 0:f0a3e5729b8f | 130 | myled1 = 0; |
gemmaro | 0:f0a3e5729b8f | 131 | |
gemmaro | 0:f0a3e5729b8f | 132 | while(1) { |
gemmaro | 0:f0a3e5729b8f | 133 | myled2 = 1; |
gemmaro | 0:f0a3e5729b8f | 134 | rec(); |
gemmaro | 0:f0a3e5729b8f | 135 | wait(2); |
gemmaro | 0:f0a3e5729b8f | 136 | myled2 = 0; |
gemmaro | 0:f0a3e5729b8f | 137 | |
gemmaro | 0:f0a3e5729b8f | 138 | /// filter |
gemmaro | 0:f0a3e5729b8f | 139 | myled3 = 1; |
gemmaro | 0:f0a3e5729b8f | 140 | for (n = filter_size; n < DATA_SIZE; ++n) { |
gemmaro | 0:f0a3e5729b8f | 141 | y = 0; |
gemmaro | 0:f0a3e5729b8f | 142 | for (k = 0; k < filter_size; ++k) { |
gemmaro | 0:f0a3e5729b8f | 143 | y += (int)(b[k] * (data[n - k] - offset)); |
gemmaro | 0:f0a3e5729b8f | 144 | } |
gemmaro | 0:f0a3e5729b8f | 145 | InDat = y + offset; |
gemmaro | 0:f0a3e5729b8f | 146 | OutDat = InDat >> 2; |
gemmaro | 0:f0a3e5729b8f | 147 | HeadPhoneOut.write_u16(OutDat << 6); |
gemmaro | 0:f0a3e5729b8f | 148 | wait100us(); |
gemmaro | 0:f0a3e5729b8f | 149 | } |
gemmaro | 0:f0a3e5729b8f | 150 | myled3 = 0; |
gemmaro | 0:f0a3e5729b8f | 151 | } |
gemmaro | 0:f0a3e5729b8f | 152 | } |