#include <psemek/audio/effect/volume_base.hpp>
#include <psemek/audio/constants.hpp>
#include <psemek/audio/detail/smooth.hpp>

#include <psemek/log/log.hpp>

#include <cmath>

namespace psemek::audio
{

	volume_base::volume_base(float gain_left, float gain_right, float smoothness)
		: gain_{gain_left, gain_right}
		, smoothness_multiplier_{smoothness_to_multiplier(smoothness)}
		, real_gain_{gain_left, gain_right}
	{}

	float volume_base::smoothness() const
	{
		return multiplier_to_smoothness(smoothness_multiplier_.load());
	}

	float volume_base::smoothness(float value)
	{
		auto old = smoothness_multiplier_.exchange(smoothness_to_multiplier(value));
		return multiplier_to_smoothness(old);
	}

	void volume_base::apply(util::span<float> samples)
	{
		float gain[2] = {gain_[0].load(), gain_[1].load()};
		float smoothness_multiplier = smoothness_multiplier_.load();

		for (auto p = samples.begin(); p < samples.end();)
		{
			*p++ *= real_gain_[0];
			*p++ *= real_gain_[1];

			smooth_update(real_gain_[0], gain[0], smoothness_multiplier);
			smooth_update(real_gain_[1], gain[1], smoothness_multiplier);
		}
	}

}
