Add audio compressor knee
This commit is contained in:
parent
dba6148554
commit
a80487abbc
3 changed files with 19 additions and 9 deletions
|
|
@ -68,7 +68,7 @@ struct audio_app
|
||||||
{
|
{
|
||||||
mixer_ = audio::make_mixer();
|
mixer_ = audio::make_mixer();
|
||||||
volume_control_ = audio::volume_stereo(mixer_, 0.5f, 0.5f, 0.1f);
|
volume_control_ = audio::volume_stereo(mixer_, 0.5f, 0.5f, 0.1f);
|
||||||
engine_.output()->stream(audio::compressor(volume_control_, audio::from_db(-2.f), 0.95f, 0.002f, 1.f));
|
engine_.output()->stream(audio::compressor(volume_control_, audio::from_db(-2.f), 0.95f, 0.002f, 1.f, audio::from_db(1.f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_key_down(SDL_Keycode key) override
|
void on_key_down(SDL_Keycode key) override
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,9 @@
|
||||||
namespace psemek::audio
|
namespace psemek::audio
|
||||||
{
|
{
|
||||||
|
|
||||||
stream_ptr compressor(stream_ptr stream, float volume_threshold = from_db(-1.f), float strength = 0.9f, float envelope_attack = 0.01f, float envelope_release = 1.f);
|
stream_ptr compressor(stream_ptr stream, float volume_threshold = from_db(-2.f), float strength = 0.9f, float envelope_attack = 0.01f, float envelope_release = 1.f,
|
||||||
|
float knee = from_db(1.f));
|
||||||
|
|
||||||
stream_ptr limiter(stream_ptr stream, float volume_threshold = from_db(0.f), float envelope_attack = 0.01f, float envelope_release = 1.f);
|
stream_ptr limiter(stream_ptr stream, float volume_threshold = from_db(0.f), float envelope_attack = 0.01f, float envelope_release = 1.f, float knee = 0.f);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#include <psemek/audio/effect/compressor.hpp>
|
#include <psemek/audio/effect/compressor.hpp>
|
||||||
#include <psemek/audio/smooth.hpp>
|
#include <psemek/audio/smooth.hpp>
|
||||||
#include <psemek/geom/math.hpp>
|
#include <psemek/geom/math.hpp>
|
||||||
|
#include <psemek/geom/interval.hpp>
|
||||||
|
#include <psemek/geom/contains.hpp>
|
||||||
|
|
||||||
namespace psemek::audio
|
namespace psemek::audio
|
||||||
{
|
{
|
||||||
|
|
@ -11,12 +13,13 @@ namespace psemek::audio
|
||||||
struct compressor_impl
|
struct compressor_impl
|
||||||
: stream
|
: stream
|
||||||
{
|
{
|
||||||
compressor_impl(stream_ptr stream, float volume_threshold, float strength, float envelope_attack, float envelope_release)
|
compressor_impl(stream_ptr stream, float volume_threshold, float strength, float envelope_attack, float envelope_release, float knee)
|
||||||
: stream_(std::move(stream))
|
: stream_(std::move(stream))
|
||||||
, volume_threshold_log_(std::log(volume_threshold))
|
, volume_threshold_log_(std::log(volume_threshold))
|
||||||
, strength_(strength)
|
, strength_(strength)
|
||||||
, envelope_attack_multiplier_(smoothness_to_multiplier(envelope_attack))
|
, envelope_attack_multiplier_(smoothness_to_multiplier(envelope_attack))
|
||||||
, envelope_release_multiplier_(smoothness_to_multiplier(envelope_release))
|
, envelope_release_multiplier_(smoothness_to_multiplier(envelope_release))
|
||||||
|
, knee_range_(geom::expand(geom::interval<float>::singleton(volume_threshold_log_), std::log(knee) * 0.5f))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::optional<std::size_t> length() const override
|
std::optional<std::size_t> length() const override
|
||||||
|
|
@ -38,7 +41,12 @@ namespace psemek::audio
|
||||||
|
|
||||||
float strength = strength_;
|
float strength = strength_;
|
||||||
|
|
||||||
float log_gain = strength * std::min(0.f, volume_threshold_log_ - std::log(envelope_));
|
float envelope_log = std::log(envelope_);
|
||||||
|
|
||||||
|
if (geom::contains(knee_range_, envelope_log))
|
||||||
|
strength *= geom::unlerp(knee_range_, envelope_log);
|
||||||
|
|
||||||
|
float log_gain = strength * std::min(0.f, volume_threshold_log_ - envelope_log);
|
||||||
|
|
||||||
float gain = std::exp(log_gain);
|
float gain = std::exp(log_gain);
|
||||||
|
|
||||||
|
|
@ -60,19 +68,20 @@ namespace psemek::audio
|
||||||
float strength_;
|
float strength_;
|
||||||
float envelope_attack_multiplier_;
|
float envelope_attack_multiplier_;
|
||||||
float envelope_release_multiplier_;
|
float envelope_release_multiplier_;
|
||||||
|
geom::interval<float> knee_range_;
|
||||||
float envelope_ = 0.f;
|
float envelope_ = 0.f;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_ptr compressor(stream_ptr stream, float volume_threshold, float strength, float envelope_attack, float envelope_release)
|
stream_ptr compressor(stream_ptr stream, float volume_threshold, float strength, float envelope_attack, float envelope_release, float knee)
|
||||||
{
|
{
|
||||||
return std::make_shared<compressor_impl>(std::move(stream), volume_threshold, strength, envelope_attack, envelope_release);
|
return std::make_shared<compressor_impl>(std::move(stream), volume_threshold, strength, envelope_attack, envelope_release, knee);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_ptr limiter(stream_ptr stream, float volume_threshold, float envelope_attack, float envelope_release)
|
stream_ptr limiter(stream_ptr stream, float volume_threshold, float envelope_attack, float envelope_release, float knee)
|
||||||
{
|
{
|
||||||
return compressor(std::move(stream), volume_threshold, 1.f, envelope_attack, envelope_release);
|
return compressor(std::move(stream), volume_threshold, 1.f, envelope_attack, envelope_release, knee);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue