BiquadCombo.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #pragma once
  2. #include <stdint.h> // for uint32_t
  3. #include <map> // for map
  4. #include <memory> // for unique_ptr, allocator
  5. #include <mutex> // for scoped_lock
  6. #include <stdexcept> // for invalid_argument
  7. #include <string> // for string, operator==, char_traits, basic_...
  8. #include <vector> // for vector
  9. #include "AudioTransform.h" // for AudioTransform
  10. #include "Biquad.h" // for Biquad
  11. #include "StreamInfo.h" // for StreamInfo
  12. #include "TransformConfig.h" // for TransformConfig
  13. namespace bell {
  14. class BiquadCombo : public bell::AudioTransform {
  15. private:
  16. std::vector<std::unique_ptr<bell::Biquad>> biquads;
  17. // Calculates Q values for Nth order Butterworth / Linkwitz-Riley filters
  18. std::vector<float> calculateBWQ(int order);
  19. std::vector<float> calculateLRQ(int order);
  20. public:
  21. BiquadCombo();
  22. ~BiquadCombo(){};
  23. int channel;
  24. std::map<std::string, float> paramCache = {{"order", 0.0f},
  25. {"frequency", 0.0f}};
  26. enum class FilterType { Highpass, Lowpass };
  27. void linkwitzRiley(float freq, int order, FilterType type);
  28. void butterworth(float freq, int order, FilterType type);
  29. std::unique_ptr<StreamInfo> process(
  30. std::unique_ptr<StreamInfo> data) override;
  31. void sampleRateChanged(uint32_t sampleRate) override;
  32. void reconfigure() override {
  33. std::scoped_lock lock(this->accessMutex);
  34. float freq = config->getFloat("frequency");
  35. int order = config->getInt("order");
  36. if (paramCache["frequency"] == freq && paramCache["order"] == order) {
  37. return;
  38. } else {
  39. paramCache["frequency"] = freq;
  40. paramCache["order"] = order;
  41. }
  42. this->channel = config->getChannels()[0];
  43. this->biquads = std::vector<std::unique_ptr<bell::Biquad>>();
  44. auto type = config->getString("combo_type");
  45. if (type == "lr_lowpass") {
  46. this->linkwitzRiley(freq, order, FilterType::Lowpass);
  47. } else if (type == "lr_highpass") {
  48. this->linkwitzRiley(freq, order, FilterType::Highpass);
  49. } else if (type == "bw_highpass") {
  50. this->butterworth(freq, order, FilterType::Highpass);
  51. } else if (type == "bw_lowpass") {
  52. this->butterworth(freq, order, FilterType::Highpass);
  53. } else {
  54. throw std::invalid_argument("Invalid combo filter type");
  55. }
  56. }
  57. };
  58. }; // namespace bell