#include #include "Ottobit.hpp" namespace Meris { void Ottobit::operator()(tick t) { // Only compute bit_factor when the control changes if (inputs.bits != previous_bits) { set_bit_factor(); previous_bits = inputs.bits; } // Only compute skipped_frames when the control changes if (inputs.rate != previous_rate) { step_size = (1. - inputs.rate) * RATE; previous_rate = inputs.rate; } // Process the input buffer for(int i{0}; i < inputs.audio.channels; i++) { auto* in = inputs.audio[i]; auto* out = outputs.audio[i]; // Init current_frame for each channel double current_frame{crush_frame(in[0])}; for(int j{0}; j < t.frames; j++) { if (skipped_frames[i] <= step_size) skipped_frames[i]++; else { skipped_frames[i] = 0; current_frame = crush_frame(in[j]); } out[j] = current_frame; } } } void Ottobit::set_bit_factor() { bit_factor = pow(2, inputs.bits) - 1; } double Ottobit::crush_frame(const double& f) { if (inputs.bits == BITS) return f; else { // Rounding using static_cast // return static_cast(static_cast(f * bit_factor)) / bit_factor; // Close, but prefer Lance Putnama's Gama's use of roundMagic return gam::scl::round(f * bit_factor) / bit_factor; } } }