Implement true audio::white_noise

This commit is contained in:
Nikita Lisitsa 2023-10-03 14:32:17 +03:00
parent 831dd7b688
commit 9cbb9127b9
2 changed files with 52 additions and 6 deletions

View file

@ -5,6 +5,10 @@
namespace psemek::audio
{
// True noise
stream_ptr white_noise();
// Fixed-buffer noise to simulate a specific frequency
stream_ptr white_noise(float frequency);
}

View file

@ -1,6 +1,8 @@
#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>
@ -14,8 +16,41 @@ namespace psemek::audio
struct white_noise_impl
: stream
{
white_noise_impl(float frequency)
: buffer_(detail::white_noise(2 * 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
{
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
@ -29,13 +64,15 @@ namespace psemek::audio
for (std::size_t i = 0; i < samples.size(); i += 2)
{
samples[i + 0] = buffer_[buffer_pos_ + 0];
samples[i + 1] = buffer_[buffer_pos_ + 1];
samples[i + 0] = buffer_[buffer_pos_];
samples[i + 1] = buffer_[buffer_pos_];
buffer_pos_ += 2;
buffer_pos_ += 1;
buffer_pos_ %= size;
}
played_.fetch_add(samples.size());
return samples.size();
}
@ -53,9 +90,14 @@ namespace psemek::audio
}
stream_ptr white_noise()
{
return std::make_shared<white_noise_impl>();
}
stream_ptr white_noise(float frequency)
{
return std::make_shared<white_noise_impl>(frequency);
return std::make_shared<fixed_white_noise_impl>(frequency);
}
}