<commit_before>#include "Simple.hpp"
#include <utils/PulseGate.hpp>
#include <dsp/digital.hpp>

#include <array>
#include <algorithm>
#include <iostream>

namespace
{
	static constexpr unsigned int const MaxDivider = 128u;

	class ClockDividerImp
	{
	public:
		explicit ClockDividerImp(unsigned int index, unsigned int limit = 1u) :
			m_lightPulse(0.2f),
			m_index(index),
			m_limit(limit)
		{
		}

		void setLimit(unsigned int limit){ m_limit = limit;	}

		void reset()
		{
			m_current = 0u;
			m_lightPulse.reset();
		}

		void process(bool const clockTrigger,
					 std::vector<rack::Param> const& params,
					 std::vector<rack::Output>& outputs)
		{
			auto const& param = params.at(m_index);
			auto& output = outputs.at(m_index);
			auto gate = false;

			m_limit = static_cast<unsigned int>(param.value);
			if (clockTrigger)
			{
				++m_current;
				if (m_current >= m_limit)
				{
					gate = true;
					m_current = 0u;
				}
			}
			output.value = gate ? 10.f : 0.f;
			m_lightState = m_lightPulse.process(gate) ? 1.0 : 0.f;
		}

		float* lightState()
		{
			return &m_lightState;
		}
	private:
		PulseGate m_lightPulse;
		unsigned int const m_index;
		unsigned int m_current = 0u;
		unsigned int m_limit = 1u;
		float m_lightState = 0.f;
	};
}

struct ClockDivider : rack::Module
{
	enum ParamsIds
	{
		CLOCK_DIVIDER_0,
		CLOCK_DIVIDER_1,
		CLOCK_DIVIDER_2,
		CLOCK_DIVIDER_3,
		CLOCK_DIVIDER_4,
		CLOCK_DIVIDER_5,
		CLOCK_DIVIDER_6,
		CLOCK_DIVIDER_7,
		NUM_PARAMS
	};

	enum InputIds
	{
		INPUT_CLOCK,
		INPUT_RESET,
		NUM_INPUTS
	};

	enum OutputIds
	{
		OUTPUT_CLOCK_0,
		OUTPUT_CLOCK_1,
		OUTPUT_CLOCK_2,
		OUTPUT_CLOCK_3,
		OUTPUT_CLOCK_4,
		OUTPUT_CLOCK_5,
		OUTPUT_CLOCK_6,
		OUTPUT_CLOCK_7,
		OUTPUT_RESET,
		OUTPUT_CLOCK,
		NUM_OUTPUTS
	};

	static constexpr unsigned int const ClockDividerCount = 8u;

	ClockDivider() :
		Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS)
	{
		auto initClockDivider = 1u;

		for (auto i = 0u; i < ClockDividerCount; ++i)
		{
			m_clockDividers.emplace_back(i, std::min(128u, initClockDivider));
			initClockDivider *= 2u;
		};
	}

	void reset()
	{
		std::for_each(m_clockDividers.begin(), m_clockDividers.end(),
					  [](ClockDividerImp& imp) { imp.reset(); });
	}

	void step() override
	{
		auto const& inputClock = inputs.at(INPUT_CLOCK);
		auto const& inputReset = inputs.at(INPUT_RESET);
		bool const clockTick = inputClock.active && m_clockTrigger.process(inputClock.value);

		if (inputReset.active && m_resetTrigger.process(inputReset.value))
		{
			reset();
		}
		for (auto& divider : m_clockDividers)
		{
			divider.process(clockTick, params, outputs);
		}

		outputs.at(OUTPUT_CLOCK).value = inputClock.value;
		outputs.at(OUTPUT_RESET).value = inputReset.value;
	}

	float* lightState(std::size_t const i)
	{
		return m_clockDividers[i].lightState();
	}

	void initialize() override
	{
		reset();
	}

	void randomize() override
	{
		reset();
	}
private:
	std::vector<ClockDividerImp> m_clockDividers;
	rack::SchmittTrigger m_resetTrigger;
	rack::SchmittTrigger m_clockTrigger;
};

struct ClockDividerKnob : rack::Davies1900hSmallBlackSnapKnob
{
	void connectLabel(rack::Label* label)
	{
		linkedLabel = label;
		if (linkedLabel)
		{
			linkedLabel->text = formatCurrentValue();
		}
	}

	void onChange() override
	{
		rack::Davies1900hSmallBlackSnapKnob::onChange();
		if (linkedLabel)
		{
			linkedLabel->text = formatCurrentValue();
		}
	}
private:
	std::string formatCurrentValue()const<commit_msg>Fixed API incompatibility after latest Rack changes.<commit_after>#include "Simple.hpp"
#include <utils/PulseGate.hpp>
#include <dsp/digital.hpp>

#include <array>
#include <algorithm>
#include <iostream>

namespace
{
	static constexpr unsigned int const MaxDivider = 128u;

	class ClockDividerImp
	{
	public:
		explicit ClockDividerImp(unsigned int index, unsigned int limit = 1u) :
			m_lightPulse(0.2f),
			m_index(index),
			m_limit(limit)
		{
		}

		void setLimit(unsigned int limit){ m_limit = limit;	}

		void reset()
		{
			m_current = 0u;
			m_lightPulse.reset();
		}

		void process(bool const clockTrigger,
					 std::vector<rack::Param> const& params,
					 std::vector<rack::Output>& outputs)
		{
			auto const& param = params.at(m_index);
			auto& output = outputs.at(m_index);
			auto gate = false;

			m_limit = static_cast<unsigned int>(param.value);
			if (clockTrigger)
			{
				++m_current;
				if (m_current >= m_limit)
				{
					gate = true;
					m_current = 0u;
				}
			}
			output.value = gate ? 10.f : 0.f;
			m_lightState = m_lightPulse.process(gate) ? 1.0 : 0.f;
		}

		float* lightState()
		{
			return &m_lightState;
		}
	private:
		PulseGate m_lightPulse;
		unsigned int const m_index;
		unsigned int m_current = 0u;
		unsigned int m_limit = 1u;
		float m_lightState = 0.f;
	};
}

struct ClockDivider : rack::Module
{
	enum ParamsIds
	{
		CLOCK_DIVIDER_0,
		CLOCK_DIVIDER_1,
		CLOCK_DIVIDER_2,
		CLOCK_DIVIDER_3,
		CLOCK_DIVIDER_4,
		CLOCK_DIVIDER_5,
		CLOCK_DIVIDER_6,
		CLOCK_DIVIDER_7,
		NUM_PARAMS
	};

	enum InputIds
	{
		INPUT_CLOCK,
		INPUT_RESET,
		NUM_INPUTS
	};

	enum OutputIds
	{
		OUTPUT_CLOCK_0,
		OUTPUT_CLOCK_1,
		OUTPUT_CLOCK_2,
		OUTPUT_CLOCK_3,
		OUTPUT_CLOCK_4,
		OUTPUT_CLOCK_5,
		OUTPUT_CLOCK_6,
		OUTPUT_CLOCK_7,
		OUTPUT_RESET,
		OUTPUT_CLOCK,
		NUM_OUTPUTS
	};

	static constexpr unsigned int const ClockDividerCount = 8u;

	ClockDivider() :
		Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS)
	{
		auto initClockDivider = 1u;

		for (auto i = 0u; i < ClockDividerCount; ++i)
		{
			m_clockDividers.emplace_back(i, std::min(128u, initClockDivider));
			initClockDivider *= 2u;
		};
	}

	void step() override
	{
		auto const& inputClock = inputs.at(INPUT_CLOCK);
		auto const& inputReset = inputs.at(INPUT_RESET);
		bool const clockTick = inputClock.active && m_clockTrigger.process(inputClock.value);

		if (inputReset.active && m_resetTrigger.process(inputReset.value))
		{
			reset();
		}
		for (auto& divider : m_clockDividers)
		{
			divider.process(clockTick, params, outputs);
		}

		outputs.at(OUTPUT_CLOCK).value = inputClock.value;
		outputs.at(OUTPUT_RESET).value = inputReset.value;
	}

	float* lightState(std::size_t const i)
	{
		return m_clockDividers[i].lightState();
	}

	void reset() override final
	{
		std::for_each(m_clockDividers.begin(), m_clockDividers.end(),
					  [](ClockDividerImp& imp) { imp.reset(); });
	}

	void randomize() override final
	{
		reset();
	}
private:
	std::vector<ClockDividerImp> m_clockDividers;
	rack::SchmittTrigger m_resetTrigger;
	rack::SchmittTrigger m_clockTrigger;
};

struct ClockDividerKnob : rack::Davies1900hSmallBlackSnapKnob
{
	void connectLabel(rack::Label* label)
	{
		linkedLabel = label;
		if (linkedLabel)
		{
			linkedLabel->text = formatCurrentValue();
		}
	}

	void onChange() override
	{
		rack::Davies1900hSmallBlackSnapKnob::onChange();
		if (linkedLabel)
		{
			linkedLabel->text = formatCurrentValue();
		}
	}
private:
	std::string formatCurrentValue()const
{'fraction_non_alphanumeric': 0.11712230215827338, 'fraction_numerical': 0.01381294964028777, 'mean_word_length': 4.026030368763558, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5133170', 'n_tokens_mistral': 3055, 'n_tokens_neox': 2598, 'n_words': 498}