Voss Connection Detection  1
Detect a connector click using realtime code on Bela hardware
timedelay.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include <iostream>
3 #include "timedelay.h"
4 #include <libraries/Fft/Fft.h>
5 using std::cerr;
6 using std::endl;
7 
8 TimeDelay::TimeDelay(const float& fs):
9  fs(fs)
10 {
11 
12  static_assert(BLOCKSIZE > 2);
13  // Initialize copy arrays to zero
14  mic1_copy.resize(2*BLOCKSIZE, 0.0f);
15  mic2_copy.resize(2*BLOCKSIZE, 0.0f);
16  hann.resize(BLOCKSIZE);
17 
18  // Create a Hann Window
19  for(us i=0;i<BLOCKSIZE;i++) {
20  float phase = 2*M_PI*i/(BLOCKSIZE-1);
21  hann[i] = 0.5f*(1.0-cosf(phase));
22  }
23  fft1 = new Fft();
24  fft2 = new Fft();
25  ifft = new Fft();
26 
27  fft1->setup(2*BLOCKSIZE);
28  fft2->setup(2*BLOCKSIZE);
29  ifft->setup(2*BLOCKSIZE);
30 
31  re_conv.resize(BLOCKSIZE+1, 0.0f);
32  im_conv.resize(BLOCKSIZE+1, 0.0f);
33 
34 
35 }
36 
38  const Channel& mic2){
39 
40  // Multiply with Window and add to block
41  /* const us offset = BLOCKSIZE/2; */
42 
43  for(us i=0;i<BLOCKSIZE;i++) {
44  mic1_copy[i] = mic1.at(i)*hann.at(i);
45  mic2_copy[i] = mic2.at(i)*hann.at(i);
46  }
47  std::fill(mic1_copy.begin()+BLOCKSIZE,mic1_copy.end(), 0);
48  std::fill(mic2_copy.begin()+BLOCKSIZE,mic2_copy.end(), 0);
49 
50  fft1->fft(mic1_copy);
51  fft2->fft(mic2_copy);
52 
53  // Multiply one by the other in frequency domain, write back to first part of
54  // both arrays: mic1_copy is used as the real part of that signal, and mic2
55  // as the imaginary part of the signal.
56  for(us i=0;i<BLOCKSIZE+1;i++) {
57  /* for(us i=0;i<BLOCKSIZE;i++) { */
58  /* cerr << "i: " << i <<",Mic 1 copy [i]: " <<mic1_copy.at(i) << endl; */
59  /* cerr << "i: " << i <<",Mic 2 copy [i]: " <<mic2_copy.at(i) << endl; */
60 
61  // Note: in the frequency domain, a cross-correlation denotes the complex
62  // conjugate of f times g: f x g.
63  // Splitting up:
64  // re(f x g) = re(f) * re(g) - im(f) * im(g)
65  // im(f x g) = im(f) * re(g) + re(f) * im(g)
66 
67  // Real part multiplication, yes a plus there
68  re_conv.at(i) = fft1->fdr(i)*fft2->fdr(i) - fft1->fdi(i)*fft2->fdi(i);
69 
70  // Imaginary part multiplication
71  im_conv.at(i) = fft1->fdi(i)*fft2->fdr(i) + fft1->fdr(i)*fft2->fdi(i);
72 
73  /* cerr << "i: " << i << ". abs: "<< fft1.fda(i) << endl; */
74  /* cerr << "i: " << i << ". abs: "<< fft2.fda(i) << endl; */
75  }
76 
77  // Perform IFFT
78  ifft->ifft(re_conv, im_conv);
79  float max_val = 0.0f;
80  /* float max_val = -1e10f; */
81  int arg = 0;
82 
83  // Determine maxabs index
84  for(us i=0;i<2*BLOCKSIZE;i++) {
85  float curval = ifft->td(i);
86  /* cerr << "i: " << i << "curval: " << curval << endl; */
87  float abscurval = fabsf_neon(curval);
88 
89  if(abscurval > max_val) {
90  /* if(curval > max_val) { */
91  max_val = abscurval;
92  arg = i;
93  /* cerr << "i: " << i << "New max val: " << max_val << endl; */
94  }
95  /* cerr << i << endl; */
96  }
97 
98  /* cerr << "val: " << ifft.td(arg) << endl; */
99  // If in the high end, it is wrapped around to the negative part, due to
100  // the cyclic nature of the FFT and we have a negative value
101  // instead.
102  /* cerr << "arg without adjustment: " << arg << endl; */
103  if(arg > BLOCKSIZE/2) {
104  arg = -(BLOCKSIZE - arg);
105  }
106  /* cerr << "arg: " << arg << endl; */
107  return 1000*float(arg)/fs;
108 
109  }
110 
112  /* delete convolver; */
113  delete fft1;
114  delete fft2;
115  delete ifft;
116 
117  }
TimeDelay::~TimeDelay
~TimeDelay()
Definition: timedelay.cpp:111
Channel
std::array< float, BLOCKSIZE > Channel
A Channel contains data for the length of BLOCKSIZE.
Definition: config.h:183
timedelay.h
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
TimeDelay::determineDelay
float determineDelay(const Channel &mic1, const Channel &mic2)
Determine the delay between two microphone signals. A positive signal means that mic 1 comes [t] time...
Definition: timedelay.cpp:37
TimeDelay::TimeDelay
TimeDelay(const float &fs)
Initialize a time delay finder.
Definition: timedelay.cpp:8