arduino-audio-tools
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
MedianFilter.h
1#pragma once
2#include "Filter.h"
3#include "AudioTools/CoreAudio/AudioBasic/Collections/Vector.h"
4
5namespace audio_tools {
6
14template <typename T>
15class MedianFilter : public Filter<T> {
16 public:
17 MedianFilter(int size = 7) {
18 medianBuffer.resize(size);
19 medianFilter.numNodes = size;
20 medianFilter.medianBuffer = medianBuffer.data();
21 init(&medianFilter);
22 };
23
24 virtual T process(T in) override { return insert(&medianFilter, in); }
25
26 protected:
27 struct MedianNode_t {
28 T value = 0; // sample value
29 struct MedianNode_t *nextAge = nullptr; // pointer to next oldest value
30 struct MedianNode_t *nextValue = nullptr; // pointer to next smallest value
31 struct MedianNode_t *prevValue =
32 nullptr; // pointer to previous smallest value
33 };
34
36 unsigned int numNodes = 0; // median node buffer length
37 MedianNode_t *medianBuffer = nullptr; // median node buffer
38 MedianNode_t *ageHead = nullptr; // pointer to oldest value
39 MedianNode_t *valueHead = nullptr; // pointer to smallest value
40 MedianNode_t *medianHead = nullptr; // pointer to median value
41 };
42
43 MedianFilter_t medianFilter;
44 Vector<MedianNode_t> medianBuffer{0};
45
46 int init(MedianFilter_t *medianFilter) {
47 if (medianFilter && medianFilter->medianBuffer &&
48 (medianFilter->numNodes % 2) && (medianFilter->numNodes > 1)) {
49 // initialize buffer nodes
50 for (unsigned int i = 0; i < medianFilter->numNodes; i++) {
51 medianFilter->medianBuffer[i].value = 0;
52 medianFilter->medianBuffer[i].nextAge =
53 &medianFilter->medianBuffer[(i + 1) % medianFilter->numNodes];
54 medianFilter->medianBuffer[i].nextValue =
55 &medianFilter->medianBuffer[(i + 1) % medianFilter->numNodes];
56 medianFilter->medianBuffer[(i + 1) % medianFilter->numNodes].prevValue =
57 &medianFilter->medianBuffer[i];
58 }
59 // initialize heads
60 medianFilter->ageHead = medianFilter->medianBuffer;
61 medianFilter->valueHead = medianFilter->medianBuffer;
62 medianFilter->medianHead =
63 &medianFilter->medianBuffer[medianFilter->numNodes / 2];
64
65 return 0;
66 }
67
68 return -1;
69 }
70
71 int insert(MedianFilter_t *medianFilter, T sample) {
72 unsigned int i;
73 MedianNode_t *newNode=nullptr, *it=nullptr;
74
75 if (medianFilter->ageHead == medianFilter->valueHead) {
76 // if oldest node is also the smallest node, increment value head
77 medianFilter->valueHead = medianFilter->valueHead->nextValue;
78 }
79
80 if ((medianFilter->ageHead == medianFilter->medianHead) ||
81 (medianFilter->ageHead->value > medianFilter->medianHead->value)) {
82 // prepare for median correction
83 medianFilter->medianHead = medianFilter->medianHead->prevValue;
84 }
85
86 // replace age head with new sample
87 newNode = medianFilter->ageHead;
88 newNode->value = sample;
89
90 // remove age head from list
91 medianFilter->ageHead->nextValue->prevValue =
92 medianFilter->ageHead->prevValue;
93 medianFilter->ageHead->prevValue->nextValue =
94 medianFilter->ageHead->nextValue;
95 // increment age head
96 medianFilter->ageHead = medianFilter->ageHead->nextAge;
97
98 // find new node position
99 it = medianFilter->valueHead; // set iterator as value head
100 for (i = 0; i < medianFilter->numNodes - 1; i++) {
101 if (sample < it->value) {
102 if (i == 0) { // replace value head if new node is the smallest
103 medianFilter->valueHead = newNode;
104 }
105 break;
106 }
107 it = it->nextValue;
108 }
109
110 // insert new node in list
111 it->prevValue->nextValue = newNode;
112 newNode->prevValue = it->prevValue;
113 it->prevValue = newNode;
114 newNode->nextValue = it;
115
116 // adjust median node
117 if (i >= (medianFilter->numNodes / 2)) {
118 medianFilter->medianHead = medianFilter->medianHead->nextValue;
119 }
120
121 return medianFilter->medianHead->value;
122 }
123};
124
125} // namespace audio_tools
Abstract filter interface definition;.
Definition Filter.h:28
An embedded friendly, fast one-dimensional median filter algorithm implementation in C and C++ Useful...
Definition MedianFilter.h:15
Vector implementation which provides the most important methods as defined by std::vector....
Definition Vector.h:21
Generic Implementation of sound input and output for desktop environments using portaudio.
Definition AudioCodecsBase.h:10
Definition MedianFilter.h:35
Definition MedianFilter.h:27