Voss Connection Detection  1
Detect a connector click using realtime code on Bela hardware
conndetect_features.cpp
Go to the documentation of this file.
1 #include "conndetect_features.h"
2 #include <iostream>
3 #include <libraries/math_neon/math_neon.h>
4 
5 using namespace std;
6 const float number_pi = M_PI;
7 const float sq2 = sqrtf_neon(2.0f);
8 
17 #define max(a, b) (((a) > (b) ? a : b))
18 
24 static void createHannWindow(Channel &ch) {
25  for (us i = 0; i < BLOCKSIZE; i++) {
26  float tmp = sinf_neon(number_pi * i / (BLOCKSIZE - 1));
27  ch[i] = tmp * tmp;
28  }
29 }
30 
31 Features::Features(const float fs) {
32  createHannWindow(_window);
33  fft.setup(BLOCKSIZE);
34  // Compute frequency array, single sided spectrum
35  for (us i = 0; i < BLOCKSIZE / 2 + 1; i++) {
36 
37  // Dynamically allocated, as this is the input required for the Fft class.
38  _wbd.resize(BLOCKSIZE);
39  _freq[i] = ((float)i) * fs / ((float)BLOCKSIZE);
40  }
41 }
42 
43 void Features::setChannel(const Channel &channel) {
44  _rawdata = &channel;
45  static_assert(sizeof(Channel) / sizeof(float) == BLOCKSIZE, "Oops");
46  for (us i = 0; i < BLOCKSIZE; i++) {
47  _wbd[i] = channel[i] * _window[i];
48  _signal_squared[i] = _wbd[i] * _wbd[i];
49  }
50  _ms_computed = false;
51  _fft_computed = false;
52  _delta_computed = false;
53 }
54 
56  float peak = 0.0f;
57 
58  // Operate on signal squared, as then we do not have to compute the abs of
59  // the data anymore.
60  for (us i = 0; i < _wbd.size(); i++) {
61  peak = (_signal_squared[i] > peak) ? _signal_squared[i] : peak;
62  }
63  return 10 * log10f_neon(peak);
64 }
66  compute_ms();
67  // 10*log10(_ms) = 20*log10(sqrt(_ms))
68  return 10 * log10f_neon(_ms);
69 }
71  compute_ms();
72 
73  float kurtosis = 0;
74  for(us i = 0; i < BLOCKSIZE; i++) {
75  kurtosis += _signal_squared[i] * _signal_squared[i];
76  }
77  kurtosis /= (BLOCKSIZE * _ms);
78 
79  return kurtosis;
80 }
81 
85 void Features::compute_ms() {
86  if (_ms_computed)
87  return;
88  float ms = 0.0f;
89  for (us i = 0; i < BLOCKSIZE; i++) {
90  ms += _signal_squared[i];
91  }
92  ms /= BLOCKSIZE;
93  _ms = ms;
94  _ms_computed = true;
95 }
96 void Features::compute_fft() {
97 
105  if (_fft_computed)
106  return;
107  fft.fft(_wbd);
108 
109  _Ssq_tot = 0.0f;
110  _fc = 0.0f;
111 
112  float curpeak = 0.0f;
113  us idx_peak = 0;
114 
115  for (us i = 0; i < BLOCKSIZE / 2 + 1; i++) {
116  _Ssq[i] = fft.fdr(i) * fft.fdr(i) + fft.fdi(i) * fft.fdi(i);
117  _Ssq_tot += _Ssq[i];
118  _fc += _Ssq[i] * _freq[i];
119  if (curpeak < _Ssq[i]) {
120  idx_peak = i;
121  curpeak = _Ssq[i];
122  }
123  }
124  _fc /= _Ssq_tot;
125  _idx_peak = idx_peak;
126 
127  _fft_computed = true;
128 }
130  compute_fft();
131  return _freq[_idx_peak];
132 }
133 
134 void Features::compute_delta() {
135  if (_delta_computed)
136  return;
137  for (us i = 0; i < BLOCKSIZE - 1; i++) {
138  _absdelta[i] = fabsf_neon(_wbd[i + 1] - _wbd[i]);
139  }
140  _absdelta[BLOCKSIZE - 1] = 0;
141  _delta_computed = true;
142 }
143 float Features::wamp(float wampl) {
144  us wamp_ctr = 0;
145  compute_delta();
146 
147  for (us i = 0; i < BLOCKSIZE; i++) {
148  if (_absdelta[i] > wampl)
149  wamp_ctr++;
150  }
151  return (float)wamp_ctr;
152 }
153 float Features::zc(float zcl) {
154  us zc_ctr = 0;
155  compute_delta();
156 
157  for (us i = 0; i < BLOCKSIZE - 1; i++) {
158  if (_wbd[i] * _wbd[i + 1] < 0 && _absdelta[i] > zcl) {
159  zc_ctr++;
160  }
161  }
162  return (float)zc_ctr;
163 }
164 float Features::TM3() {
165  float tmp = 0.0f;
166 
167  for (us i = 0; i < BLOCKSIZE; i++) {
168  tmp += _signal_squared[i] * (*_rawdata)[i];
169  }
170  return tmp / BLOCKSIZE;
171 }
172 float Features::TM5() {
173  float tmp = 0.0f;
174  for (us i = 0; i < BLOCKSIZE; i++) {
175  tmp += _signal_squared[i] * _signal_squared[i] * (*_rawdata)[i];
176  }
177  return tmp / BLOCKSIZE;
178 }
180  compute_fft();
181 
182  float denom = 0.0f;
183  float num = _Ssq_tot * _fc * _fc;
184 
185  for (us i = 0; i < BLOCKSIZE / 2 + 1; i++) {
186  denom += _Ssq[i] * (_freq[i] - _fc) * (_freq[i] - _fc);
187  }
188 
189  return num / denom;
190 }
conndetect_features.h
Features::TM3
float TM3()
Temporal moment 3, defined as.
Definition: conndetect_features.cpp:164
Channel
std::array< float, BLOCKSIZE > Channel
A Channel contains data for the length of BLOCKSIZE.
Definition: config.h:183
Features::wamp
float wamp(float wampl)
Willson amplitude. Counts the number of difss in amplitude that have an absolute change in value larg...
Definition: conndetect_features.cpp:143
Features::inverse_variance
float inverse_variance()
Inverse of the variance in the center frequency, defined as:
Definition: conndetect_features.cpp:179
Features::rms_dB
float rms_dB()
Compute the rms level in dB (full scale, normalized to 1). The equation is:
Definition: conndetect_features.cpp:65
Features::Features
Features(const float fs)
Create features instance.
Definition: conndetect_features.cpp:31
Features::peak_freq
float peak_freq()
Compute the frequency at which the spectrum has the most power. It is defined as:
Definition: conndetect_features.cpp:129
number_pi
const float number_pi
Definition: conndetect_features.cpp:6
BLOCKSIZE
const us BLOCKSIZE
The size of a buffer in a block. Should be an integer number of samples, and preferrably a integer po...
Definition: config.h:105
us
unsigned int us
Used to much to not abbreviate.
Definition: config.h:38
Features::setChannel
void setChannel(const Channel &channel)
Set channel data to operate on. BORROWS the data on which it operates, be carefull not to delete the ...
Definition: conndetect_features.cpp:43
Features::kurtosis
float kurtosis()
Compute the kurtosis , scaled. It is defined as:
Definition: conndetect_features.cpp:70
Features::zc
float zc(float zc_l)
Compute zero-crossings with a difference larger than zcl.
Definition: conndetect_features.cpp:153
Features::peak_dB
float peak_dB()
Compute the peak level in dB (full scale, normalized to 1). The equation is:
Definition: conndetect_features.cpp:55
Features::TM5
float TM5()
Temporal moment 5, defined as.
Definition: conndetect_features.cpp:172
sq2
const float sq2
Definition: conndetect_features.cpp:7