A Hopf, Skip and a Jump
detectors.h
1 #ifndef _ABSTRACTDETECTOR_H_
2 #define _ABSTRACTDETECTOR_H_
3 
4 #include <complex>
5 #include <utility>
6 #include <memory>
7 #include <string>
8 
9 #include <cereal/cereal.hpp>
10 #include <cereal/access.hpp>
11 #include <cereal/archives/xml.hpp>
12 #include <cereal/types/complex.hpp>
13 
14 #include "detectorbank.h"
15 #include "detectortypes.h"
16 
22 
23 public:
32  AbstractDetector(parameter_t f, parameter_t mu,
33  parameter_t d, parameter_t sr,
34  parameter_t detBw, parameter_t gain);
35 
36  virtual ~AbstractDetector();
38 
49  void processAudio(discriminator_t* target,
50  const inputSample_t* start, std::size_t count);
51 
70  bool searchNormalize(parameter_t searchStart,
71  parameter_t searchEnd,
72  const parameter_t toneDuration,
73  const parameter_t forcing_amplitude);
74 
84  bool amplitudeNormalize(const parameter_t forcing_amplitude);
85 
87  void scaleAmplitude();
88 
94  void generateTone(inputSample_t* tone,
95  const std::size_t duration,
96  const parameter_t frequency);
97 
98  // ACCESS FUNCTIONS
99 
104  parameter_t getW(void) const { return w; };
105 
110  virtual void reset() = 0;
111 
112 protected:
117  virtual void process(discriminator_t* target,
118  const inputSample_t* start, std::size_t count) = 0;
119 
120 
130  static const parameter_t getLyapunov(const parameter_t bw, const parameter_t amp);
131 
132  // DetectorBank is responsible for detector serialisation
138  template <class Archive> friend void DetectorBank::save(Archive&) const;
144  template <class Archive> friend void DetectorBank::load(Archive&);
145  friend class cereal::access;
150  template <class Archive> void save(Archive& archive) const
151  {
152  archive.setNextName("AbstractDetector");
153  archive.startNode();
154  archive(cereal::make_nvp("w_adjusted", w),
155  CEREAL_NVP(aScale),
156  CEREAL_NVP(iScale)
157  );
158  archive.finishNode();
159  }
164  template <class Archive> void load(Archive& archive)
165  {
166  //std::cout << "Starting to load an AbstractDetector\n";
167  archive.startNode();
168  archive(cereal::make_nvp("w_adjusted", w),
169  CEREAL_NVP(aScale),
170  CEREAL_NVP(iScale)
171  );
172 
173  archive.finishNode();
174  }
175 
176  parameter_t w;
177  parameter_t const mu;
178  parameter_t const d;
179  parameter_t const sr;
180  parameter_t const detBw;
181  parameter_t const gain;
182  discriminator_t aScale;
183  parameter_t iScale;
184  parameter_t b;
185  discriminator_t scale;
186  bool nrml { false };
190  static constexpr int maxNormIterations { 100 };
196  static constexpr double normConverged { 1.0028922878693671 };
197 
199  void makeScaleVectors();
200 
202  void getScaleValue(const parameter_t fr);
203 
204  std::vector<parameter_t> detScaleFreqs;
205  std::vector<discriminator_t> detScaleFactors;
206  static const std::array<std::vector<parameter_t>, 8> scaleFreqs;
207  static const std::array<std::vector<discriminator_t>, 8> scaleFactors;
208 };
209 
222 class CDDetector : public AbstractDetector {
223 public:
233  CDDetector(const parameter_t f, const parameter_t mu,
234  const parameter_t d, const parameter_t sr,
235  const parameter_t detBw, const parameter_t gain);
237  virtual ~CDDetector();
241  virtual void reset();
251  virtual void process(discriminator_t* target,
252  const inputSample_t* start,
253  const std::size_t count) override;
254 
255 private:
256  std::complex<parameter_t> zp;
257  std::complex<parameter_t> zpp;
258  inputSample_t xp;
259 };
260 
292 public:
302  RK4Detector(const parameter_t f, const parameter_t mu,
303  const parameter_t d, const parameter_t sr,
304  const parameter_t detBw, const parameter_t gain);
305  virtual ~RK4Detector();
309  virtual void reset();
319  virtual void process(discriminator_t* target,
320  const inputSample_t* start,
321  const std::size_t count) override;
322 private:
323  std::complex<parameter_t> zp;
324  std::complex<parameter_t> zpp;
325  inputSample_t xp;
326  inputSample_t xpp;
327 };
328 
329 #endif
parameter_t const detBw
Detector bandwidth.
Definition: detectors.h:180
virtual void process(discriminator_t *target, const inputSample_t *start, std::size_t count)=0
This method gets overridden in derived classes to produce an unnormalised version of the required out...
void load(Archive &archive)
Load the DetectorBank from a cereal archive.
Definition: detectors.h:164
static constexpr double normConverged
Ratio of discovered frequency to specification frequency to be considered "close enough" during seach...
Definition: detectors.h:196
parameter_t const sr
Sample rate.
Definition: detectors.h:179
AbstractDetector(parameter_t f, parameter_t mu, parameter_t d, parameter_t sr, parameter_t detBw, parameter_t gain)
parameter_t iScale
Scaling factor for imaginary part.
Definition: detectors.h:183
void getScaleValue(const parameter_t fr)
Get a scale value for a given frequency.
static constexpr int maxNormIterations
The maximum number of iterations to find best response during search_normalization.
Definition: detectors.h:190
parameter_t getW(void) const
Find the speficied characteristic frequency for this detector (post-modulation and -normalisation) ...
Definition: detectors.h:104
bool nrml
If search normalisation has been applied.
Definition: detectors.h:186
parameter_t const d
Detector damping factor.
Definition: detectors.h:178
parameter_t const mu
Distance from the bifurcation point.
Definition: detectors.h:177
virtual void reset()=0
Reset the internal values used to calculate z to 0.
Base class for detectors using different numerical methods.
Definition: detectors.h:21
Use the fourth order Runge-Kutta method to calculate the output.
Definition: detectors.h:291
void load(Archive &archive)
Write the relevant properties of the detector bank to an archive.
parameter_t w
Characteristic frequency.
Definition: detectors.h:176
std::complex< parameter_t > zp
previous z value
Definition: detectors.h:256
parameter_t b
Detector&#39;s first Lyapunov coefficent.
Definition: detectors.h:184
void scaleAmplitude()
Calculate amplitude scale factor.
std::complex< parameter_t > zpp
z value two samples ago
Definition: detectors.h:257
bool searchNormalize(parameter_t searchStart, parameter_t searchEnd, const parameter_t toneDuration, const parameter_t forcing_amplitude)
Normalise the detector frequency using an iterative scheme.
void save(Archive &archive) const
Save the DetectorBank as a cereal archive.
Definition: detectors.h:150
inputSample_t xpp
audio input sample two samples ago
Definition: detectors.h:326
inputSample_t xp
previous audio input sample
Definition: detectors.h:325
void makeScaleVectors()
Make freq and factor vectors for given method and normalisation.
std::complex< parameter_t > zpp
z value two samples ago
Definition: detectors.h:324
inputSample_t xp
previous audio input sample
Definition: detectors.h:258
discriminator_t aScale
Amplitude scaling factor.
Definition: detectors.h:182
Use the central-difference approximation to calculate the output.
Definition: detectors.h:222
discriminator_t scale
Detector&#39;s scale factor.
Definition: detectors.h:185
static const parameter_t getLyapunov(const parameter_t bw, const parameter_t amp)
Find the first Lyapunov coefficient required for a given bandwidth, with a given forcing amplitude...
void save(Archive &archive) const
Write the relevant properties of the detector bank to an archive.
void processAudio(discriminator_t *target, const inputSample_t *start, std::size_t count)
Process audio using the numerical method appropriate to the derived class.
bool amplitudeNormalize(const parameter_t forcing_amplitude)
Set the detector&#39;s a and iScale attributes by profiling an ideal detector response.
void generateTone(inputSample_t *tone, const std::size_t duration, const parameter_t frequency)
Generate a sine tone.
std::complex< parameter_t > zp
previous z value
Definition: detectors.h:323
parameter_t const gain
Detector gain.
Definition: detectors.h:181