diff --git a/libs/audio/include/psemek/audio/stereo.hpp b/libs/audio/include/psemek/audio/stereo.hpp new file mode 100644 index 00000000..5dba80d4 --- /dev/null +++ b/libs/audio/include/psemek/audio/stereo.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include + +#include + +namespace psemek::audio +{ + + stream_ptr stereo(stream_ptr left, stream_ptr right); + +} diff --git a/libs/audio/source/stereo.cpp b/libs/audio/source/stereo.cpp new file mode 100644 index 00000000..6ea32820 --- /dev/null +++ b/libs/audio/source/stereo.cpp @@ -0,0 +1,51 @@ +#include + +#include + +namespace psemek::audio +{ + + namespace + { + + struct stereo_impl + : stream + { + stereo_impl(stream_ptr left, stream_ptr right) + : left_(std::move(left)) + , right_(std::move(right)) + {} + + std::size_t read(float * data, std::size_t sample_count) override + { + if (buffer_.size() < sample_count) + buffer_.resize(sample_count); + + auto right_result = right_->read(data, sample_count); + auto left_result = left_->read(buffer_.data(), sample_count); + + auto result = std::min(right_result, left_result); + + { + auto begin = buffer_.data(); + auto end = buffer_.data() + result; + auto dst = data; + for (; begin < end; begin += 2, dst += 2) + *dst = *begin; + } + return result; + } + + private: + stream_ptr left_, right_; + std::vector buffer_; + }; + + } + + stream_ptr stereo(stream_ptr left, stream_ptr right) + { + return std::make_shared(std::move(left), std::move(right)); + } + +}