103 lines
1.9 KiB
C++
103 lines
1.9 KiB
C++
#include <psemek/audio/wave/white_noise.hpp>
|
|
#include <psemek/audio/constants.hpp>
|
|
#include <psemek/audio/detail/white_noise.hpp>
|
|
#include <psemek/random/generator.hpp>
|
|
#include <psemek/random/uniform.hpp>
|
|
|
|
#include <vector>
|
|
#include <atomic>
|
|
|
|
namespace psemek::audio
|
|
{
|
|
|
|
namespace
|
|
{
|
|
|
|
struct white_noise_impl
|
|
: stream
|
|
{
|
|
std::optional<std::size_t> length() const override
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::size_t read(util::span<float> samples) override
|
|
{
|
|
for (std::size_t i = 0; i < samples.size(); i += 2)
|
|
{
|
|
float value = d_(rng_);
|
|
samples[i + 0] = value;
|
|
samples[i + 1] = value;
|
|
}
|
|
|
|
played_.fetch_add(samples.size());
|
|
|
|
return samples.size();
|
|
}
|
|
|
|
std::size_t played() const override
|
|
{
|
|
return played_.load();
|
|
}
|
|
|
|
private:
|
|
random::generator rng_{0x4b0a763ef6573bf2ull, 0};
|
|
random::uniform_distribution<float> d_{-1.f, 1.f};
|
|
std::atomic<std::size_t> played_;
|
|
};
|
|
|
|
struct fixed_white_noise_impl
|
|
: stream
|
|
{
|
|
fixed_white_noise_impl(float frequency)
|
|
: buffer_(detail::white_noise(std::round(audio::frequency / frequency)))
|
|
{}
|
|
|
|
std::optional<std::size_t> length() const override
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::size_t read(util::span<float> samples) override
|
|
{
|
|
std::size_t const size = buffer_.size();
|
|
|
|
for (std::size_t i = 0; i < samples.size(); i += 2)
|
|
{
|
|
samples[i + 0] = buffer_[buffer_pos_];
|
|
samples[i + 1] = buffer_[buffer_pos_];
|
|
|
|
buffer_pos_ += 1;
|
|
buffer_pos_ %= size;
|
|
}
|
|
|
|
played_.fetch_add(samples.size());
|
|
|
|
return samples.size();
|
|
}
|
|
|
|
std::size_t played() const override
|
|
{
|
|
return played_.load();
|
|
}
|
|
|
|
private:
|
|
std::vector<float> buffer_;
|
|
std::size_t buffer_pos_{0};
|
|
|
|
std::atomic<std::size_t> played_;
|
|
};
|
|
|
|
}
|
|
|
|
stream_ptr white_noise()
|
|
{
|
|
return std::make_shared<white_noise_impl>();
|
|
}
|
|
|
|
stream_ptr white_noise(float frequency)
|
|
{
|
|
return std::make_shared<fixed_white_noise_impl>(frequency);
|
|
}
|
|
|
|
}
|