Add simple echo effect
This commit is contained in:
parent
87681a036a
commit
97518a0a4a
3 changed files with 98 additions and 0 deletions
12
libs/audio/include/psemek/audio/echo.hpp
Normal file
12
libs/audio/include/psemek/audio/echo.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <psemek/audio/effect.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace psemek::audio
|
||||||
|
{
|
||||||
|
|
||||||
|
std::shared_ptr<effect> echo(float delay, float volume);
|
||||||
|
|
||||||
|
}
|
||||||
18
libs/audio/include/psemek/audio/utils.hpp
Normal file
18
libs/audio/include/psemek/audio/utils.hpp
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <limits>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace psemek::audio
|
||||||
|
{
|
||||||
|
|
||||||
|
inline std::int16_t clamp(float v)
|
||||||
|
{
|
||||||
|
static auto const min = std::numeric_limits<std::int16_t>::min();
|
||||||
|
static auto const max = std::numeric_limits<std::int16_t>::max();
|
||||||
|
|
||||||
|
return static_cast<std::int16_t>(std::min<int>(max, std::max<int>(min, std::round(v))));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
68
libs/audio/source/echo.cpp
Normal file
68
libs/audio/source/echo.cpp
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
#include <psemek/audio/echo.hpp>
|
||||||
|
#include <psemek/audio/engine.hpp>
|
||||||
|
#include <psemek/audio/utils.hpp>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace psemek::audio
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct echo_impl
|
||||||
|
: audio::effect
|
||||||
|
{
|
||||||
|
echo_impl(float delay, float volume)
|
||||||
|
: volume_(volume)
|
||||||
|
{
|
||||||
|
int sample_count = std::round(delay * audio::engine::frequency * audio::engine::channels);
|
||||||
|
samples_.reserve(sample_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view name() const override
|
||||||
|
{
|
||||||
|
return "echo";
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(std::int16_t * data, std::size_t size) override
|
||||||
|
{
|
||||||
|
if (samples_.size() < samples_.capacity())
|
||||||
|
{
|
||||||
|
auto count = std::min(samples_.capacity() - samples_.size(), size);
|
||||||
|
std::copy(data, data + count, std::back_inserter(samples_));
|
||||||
|
pos_ += count;
|
||||||
|
data += count;
|
||||||
|
size -= count;
|
||||||
|
|
||||||
|
if (pos_ == samples_.capacity())
|
||||||
|
pos_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; size > 0; ++data, --size)
|
||||||
|
{
|
||||||
|
float s = clamp((*data) + samples_[pos_] * volume_);
|
||||||
|
samples_[pos_] = *data;
|
||||||
|
*data = s;
|
||||||
|
|
||||||
|
++pos_;
|
||||||
|
if (pos_ == samples_.capacity())
|
||||||
|
pos_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::int16_t> samples_;
|
||||||
|
std::size_t pos_ = 0;
|
||||||
|
float volume_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<effect> echo(float delay, float volume)
|
||||||
|
{
|
||||||
|
return std::make_shared<echo_impl>(delay, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue