A Hopf, Skip and a Jump
detectorbank.h
1 #ifndef _DETECTORBANK_H_
2 #define _DETECTORBANK_H_
3 
5 
7 #include <complex>
8 #include <utility>
9 #include <memory>
10 #include <vector>
11 #include <string>
12 #include <map>
13 #include <thread>
14 #include <mutex>
15 #include <condition_variable>
16 #include <cereal/access.hpp>
17 
18 #include "detectortypes.h"
19 #include "thread_pool.h"
20 
21 class AbstractDetector;
22 class ProfileManager;
23 
25 class DetectorBank {
26 
27 public:
29  static constexpr int solverMask { 0xff };
31  static constexpr int freqNormalizationMask { 0xff << 8 };
33  static constexpr int ampNormalizationMask { 0xff << 16 };
37  enum Features {
38 
39  // Choose numerical method
43  // Frequency normalisation
44  freq_unnormalized = 1 << 8,
45  search_normalized = 2 << 8,
47  // Amplitude normalisation
48  amp_unnormalized = 1 << 16,
49  amp_normalized = 2 << 16,
51  // Vanilla
54 
55  };
63  DetectorBank(const std::string& profile,
64  const inputSample_t* inputBuffer,
65  const std::size_t inputBufferSize);
66 
92  DetectorBank(const parameter_t sr,
93  const inputSample_t* inputBuffer,
94  const std::size_t inputBufferSize,
95  std::size_t numThreads,
96  const parameter_t* freqs = EDO12_pf,
97  parameter_t* bw = nullptr,
98  const std::size_t numDetectors = EDO12_pf_size,
99  Features features = Features::defaults,
100  parameter_t damping = 0.0001,
101  const parameter_t gain = 25.0);
102 
103  virtual ~DetectorBank();
104 
105  // Maybe want to reuse the object on a different input buffer
111  void setInputBuffer(const inputSample_t* inputBuffer,
112  const std::size_t inputBufferSize);
113  // Get some frames of z-values from the discriminators
114  // Repeated calls progressively traverse the audio input buffer.
115  // Returns the number of frames actually processed
116  // (0 at end of input)
124  int getZ(discriminator_t* frames,
125  std::size_t chans, std::size_t numFrames,
126  const std::size_t startChan = 0);
141  result_t absZ(result_t* absFrames,
142  std::size_t absChans,
143  const std::size_t absNumFrames,
144  discriminator_t* frames,
145  std::size_t maxThreads = 0
146  ) const;
152  bool seek(long int offset);
153 
154  // ACCESS FUNCTIONS
155 
159  std::size_t tell(void) const { return currentSample; };
163  parameter_t getSR(void) const { return sr; };
167  std::size_t getChans(void) const { return detectors.size(); };
171  std::size_t getBuflen(void) const { return inBufSize; };
179  parameter_t getW(std::size_t ch) const;
180 
187  parameter_t getFreqIn(std::size_t ch) const;
188 
190  std::string toXML(void) const;
195  void fromXML(std::string xml);
200  void saveProfile(std::string name);
201 
202 
203 protected:
209  void amplify(const inputSample_t*& signal,
210  std::size_t signalSize,
211  const parameter_t gain);
212 
213  void worker(int id);
214 
218  typedef struct {
219  std::size_t firstChannel;
220  std::size_t numChannels;
221  discriminator_t* frames;
222  std::size_t framesPerChannel;
223  std::size_t numFrames;
224  } GetZ_params;
225 
232  void getZDelegate(void* args);
233 
237  typedef struct {
238  std::size_t start, end;
239  result_t& mx;
240  } AbsZ_params;
241 
246  static const std::map<int, std::string> featuresToStringMap;
255  void stringToFeatures(const std::string& desc);
260  const std::string featuresToString(void) const;
261 
262  friend class cereal::access;
265  template<class Archive> void save(Archive& archive) const;
268  template<class Archive> void load(Archive& archive);
269 
271  std::vector<std::unique_ptr<AbstractDetector>> detectors;
272  std::size_t inBufSize;
273  const inputSample_t* inBuf;
275  std::unique_ptr<ThreadPool> threadPool;
276  std::size_t currentSample;
277  parameter_t d;
278  parameter_t sr;
280  parameter_t* bw;
281  parameter_t gain;
287  std::unique_ptr<inputSample_t[]> gainBuf;
288 
290  static const parameter_t EDO12_pf[];
292  static const int EDO12_pf_size;
293 
297 
307  const parameter_t f_in;
308  const parameter_t f_actual;
309  const inputSample_t* signal;
311  const parameter_t bandwidth;
312  };
313 
317  std::vector<detector_components> dbComponents;
318 
331  void setDBComponents(const parameter_t* frequencies,
332  const parameter_t* bandwidths,
333  const std::size_t numDetectors);
334 
335  parameter_t modF;
337 private:
354  void makeDetectors(const std::size_t numDetectors,
355  const parameter_t mu,
356  const parameter_t d,
357  const parameter_t sr,
358  const Features features,
359  //const parameter_t b,
360  const parameter_t gain);
361 
366  std::map<int, std::unique_ptr<inputSample_t[]>> input_pool;
367 
369  bool auto_bw;
370 };
371 
372 #endif
parameter_t sr
Operating sample rate.
Definition: detectorbank.h:278
Iteratively adjust response.
Definition: detectorbank.h:45
parameter_t d
Detector damping factor.
Definition: detectorbank.h:277
static const parameter_t EDO12_pf[]
Standard tuning set for a 12EDO piano keyboard.
Definition: detectorbank.h:290
void amplify(const inputSample_t *&signal, std::size_t signalSize, const parameter_t gain)
Apply a gain to the inputBuffer.
std::size_t inBufSize
Size of the current audio input buffer.
Definition: detectorbank.h:272
std::size_t getChans(void) const
Return the number of detectors currently maintained by this DetectorBank.
Definition: detectorbank.h:167
const parameter_t f_in
The caller&#39;s requested frequency.
Definition: detectorbank.h:307
void stringToFeatures(const std::string &desc)
Set this DetectorBank&#39;s features from a human-readable string using featuresToStringMap.
void getZDelegate(void *args)
Perform one thread&#39;s worth of work on the given channels.
parameter_t getFreqIn(std::size_t ch) const
Find the input frequency of a given channel&#39;s detector.
Use multiple detectors to find note onsets at given frequencies (with multithreading).
Definition: detectorbank.h:25
Fourth order Runge-Kutta.
Definition: detectorbank.h:41
std::size_t firstChannel
First channel to process.
Definition: detectorbank.h:219
parameter_t getSR(void) const
Get the sample rate associated with this DetectorBank.
Definition: detectorbank.h:163
result_t absZ(result_t *absFrames, std::size_t absChans, const std::size_t absNumFrames, discriminator_t *frames, std::size_t maxThreads=0) const
Take z-frames and fill a given array of the same dimensions (absFrames) with their absolute values...
static const int EDO12_pf_size
Size of standard 12EDO piano keyboard.
Definition: detectorbank.h:292
Struct to pass absZ thread parameters to a worker thread.
Definition: detectorbank.h:237
const parameter_t f_actual
The frequency of the detector used.
Definition: detectorbank.h:308
std::unique_ptr< ThreadPool > threadPool
Thread manager for concurrent sections.
Definition: detectorbank.h:275
Metaparameters for a detector.
Definition: detectorbank.h:306
Base class for detectors using different numerical methods.
Definition: detectors.h:21
void saveProfile(std::string name)
Save the current profile so that a DetectorBank can be constructed conveniently in future...
static const std::map< int, std::string > featuresToStringMap
Printable string representations of the flags in the Features enum Use the provided routines through ...
Definition: detectorbank.h:246
static ProfileManager profileManager
The profile manager responsible for loading and saving detectorbank properties.
Definition: detectorbank.h:296
std::string toXML(void) const
Return description of the detectorbank serialised in XML form.
void load(Archive &archive)
Write the relevant properties of the detector bank to an archive.
discriminator_t * frames
Output array.
Definition: detectorbank.h:221
const parameter_t bandwidth
Detector bandwdith.
Definition: detectorbank.h:311
std::size_t getBuflen(void) const
Find out the total number of samples currently available.
Definition: detectorbank.h:171
void makeDetectors(const std::size_t numDetectors, const parameter_t mu, const parameter_t d, const parameter_t sr, const Features features, const parameter_t gain)
Utility routine to make the appropriate detectors and tune them according to the required feature set...
Scale real and imaginary parts of the response.
Definition: detectorbank.h:49
Features features
Detector method & normalistion.
Definition: detectorbank.h:279
DetectorBank(const std::string &profile, const inputSample_t *inputBuffer, const std::size_t inputBufferSize)
Construct a DetectorBank from archived parameters.
std::size_t numChannels
Number of channels to process.
Definition: detectorbank.h:220
Without amplitude normalisation.
Definition: detectorbank.h:48
std::map< int, std::unique_ptr< inputSample_t[]> > input_pool
Mapping of ratio of requested frequency to the maximum used detector frequency for this solver and no...
Definition: detectorbank.h:366
int getZ(discriminator_t *frames, std::size_t chans, std::size_t numFrames, const std::size_t startChan=0)
Get the next numFrames of detector bank output.
parameter_t modF
Frequency above which the signal should be modulated.
Definition: detectorbank.h:335
bool auto_bw
Has DetectorBank created its own array of zeros for bandwidth?
Definition: detectorbank.h:369
void setDBComponents(const parameter_t *frequencies, const parameter_t *bandwidths, const std::size_t numDetectors)
Create the detector_components required for each detector in the detector bank.
parameter_t * bw
Array of bandwidths.
Definition: detectorbank.h:280
std::unique_ptr< inputSample_t[]> gainBuf
If a gain is applied to the input signal, this pointer refers to the locally allocated buffer contain...
Definition: detectorbank.h:287
const inputSample_t * inBuf
The current input buffer.
Definition: detectorbank.h:273
const inputSample_t * signal
Pointer to a frequency-shifted version of the input data.
Definition: detectorbank.h:309
std::size_t numFrames
Number of frames left to process.
Definition: detectorbank.h:223
std::size_t framesPerChannel
Number of frames per channel.
Definition: detectorbank.h:222
profilemanager.h
const std::string featuresToString(void) const
Produce a human-readable string describing this DetectorBank&#39;s features using featuresToStringMap.
static constexpr int ampNormalizationMask
Bit mask for specifying the amplitude normalisation method.
Definition: detectorbank.h:33
parameter_t gain
Audio input gain to be applided.
Definition: detectorbank.h:281
static constexpr int solverMask
Bit mask for specifying the solver method.
Definition: detectorbank.h:29
static constexpr int freqNormalizationMask
Bit mask for specifying the frequency normalisation method.
Definition: detectorbank.h:31
std::vector< std::unique_ptr< AbstractDetector > > detectors
Detectors to be run by this detector bank.
Definition: detectorbank.h:271
parameter_t getW(std::size_t ch) const
Find the frequency of a given channel&#39;s detector.
void setInputBuffer(const inputSample_t *inputBuffer, const std::size_t inputBufferSize)
Change the input, without recreating the detector bank.
bool seek(long int offset)
Set input sample at which to start the detection.
std::size_t currentSample
How far along the input for next read.
Definition: detectorbank.h:276
Struct to pass getZ thread parameters to a worker thread.
Definition: detectorbank.h:218
Without frequency normalisation.
Definition: detectorbank.h:44
std::size_t tell(void) const
Get the index of current input sample.
Definition: detectorbank.h:159
void save(Archive &archive) const
Write the relevant properties of the detector bank to an archive.
Features
Specify numerical and normalisation methods for this detector bank.
Definition: detectorbank.h:37
std::vector< detector_components > dbComponents
Vector of detector_components describing each AbstractDetector in the vector detectors.
Definition: detectorbank.h:317
void fromXML(std::string xml)
Set the state of the detectorbank according to a previously serialised XML description.
Default is Runge-Kutta, unnormalised frequency, normalised amplitude.
Definition: detectorbank.h:53