#pragma once #include #include #include #include #include #include #include #include #include namespace Ottobit { class Senior { #define BITS 16 #define RATE 64 public: halp_meta(name, "Senior") halp_meta(category, "Audio") halp_meta(c_name, "senior") halp_meta(uuid, "fe8425d7-64d3-4b8b-a652-1d80026edc8b") // Define inputs and outputs ports. // See the docs at https://github.com/celtera/avendish struct ins { halp::dynamic_audio_bus<"Input", double> audio; halp::knob_f32<"SAMPLE RATE", halp::range{.min = .1, .max = 1., .init = 1.}> s_rate; using log_map = halp::log_mapper>; struct : halp::knob_f32<"BITS", halp::range{.min = 3, .max = BITS, .init = BITS}> { using mapper = log_map; } bits; struct : halp::knob_f32<"FREQ", halp::range{.min = .4, .max = 200., .init = 5.}> { using mapper = log_map; } freq; halp::knob_f32<"DEPTH", halp::range{.min = 0., .max = 1., .init = 0.}> depth; halp::knob_f32<"AM/RING/FM", halp::range{.min = 0., .max = 2., .init = 0.}> am_fm; } inputs; struct { halp::dynamic_audio_bus<"Output", double> audio; } outputs; using setup = halp::setup; void prepare(setup info) { // Initialization, this method will be called with buffer size, etc. set_bit_factor(); lfo.set_sample_rate(info.rate); lfo.freq(5); skipped_frames.resize(info.input_channels); fms.resize(info.input_channels); for (auto& fm : fms) { fm.set_sample_rate(info.rate); fm.maxDelay(0.1); } phases.resize(info.output_channels); float phase_frac{1.f / info.output_channels}; for (int i{0}; i < info.output_channels; i++) { phases[i] = i * phase_frac; } } // Do our processing for N samples using tick = halp::tick; // Defined in the .cpp void operator()(tick t); // UI is defined in another file to keep things clear. struct ui; private: int bit_factor, step_size{0}; double previous_bits{BITS}, previous_rate{1}, previous_depth{0}, previous_am_fm{0}, am_amp{0}, fm_amp{0}; std::vector phases; std::vector skipped_frames; std::vector> fms; gam::LFO lfo{5.}; void set_bit_factor(); double crush(const double& f); }; } // namespace Ottobit