Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
mid_side.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "detail/audio_range.hpp"
4
5#include <algorithm>
6#include <cmath>
7#include <cstddef>
8#include <type_traits>
9
10namespace pulp::signal {
11
16template <typename SampleType>
17inline void mid_side_encode(SampleType left, SampleType right, SampleType& mid,
18 SampleType& side) noexcept {
19 static_assert(std::is_floating_point_v<SampleType>);
20 constexpr SampleType kInvSqrt2 =
21 static_cast<SampleType>(0.707106781186547524400844362104849039L);
22 mid = (left + right) * kInvSqrt2;
23 side = (left - right) * kInvSqrt2;
24}
25
26template <typename SampleType>
27inline void mid_side_decode(SampleType mid, SampleType side, SampleType& left,
28 SampleType& right) noexcept {
29 static_assert(std::is_floating_point_v<SampleType>);
30 constexpr SampleType kInvSqrt2 =
31 static_cast<SampleType>(0.707106781186547524400844362104849039L);
32 left = (mid + side) * kInvSqrt2;
33 right = (mid - side) * kInvSqrt2;
34}
35
36template <typename SampleType>
37inline bool mid_side_encode_block(const SampleType* left, const SampleType* right, SampleType* mid,
38 SampleType* side, std::size_t frames) noexcept {
39 static_assert(std::is_floating_point_v<SampleType>);
40 if (left == nullptr || right == nullptr || mid == nullptr || side == nullptr ||
41 detail::audio_ranges_overlap(mid, side, frames))
42 return false;
43 if ((mid != left && detail::audio_ranges_overlap(mid, left, frames)) ||
44 (mid != right && detail::audio_ranges_overlap(mid, right, frames)) ||
45 (side != left && detail::audio_ranges_overlap(side, left, frames)) ||
46 (side != right && detail::audio_ranges_overlap(side, right, frames)))
47 return false;
48 for (std::size_t i = 0; i < frames; ++i) {
49 const auto l = left[i];
50 const auto r = right[i];
51 mid_side_encode(l, r, mid[i], side[i]);
52 }
53 return true;
54}
55
56template <typename SampleType>
57inline bool mid_side_decode_block(const SampleType* mid, const SampleType* side, SampleType* left,
58 SampleType* right, std::size_t frames) noexcept {
59 static_assert(std::is_floating_point_v<SampleType>);
60 if (mid == nullptr || side == nullptr || left == nullptr || right == nullptr ||
61 detail::audio_ranges_overlap(left, right, frames))
62 return false;
63 if ((left != mid && detail::audio_ranges_overlap(left, mid, frames)) ||
64 (left != side && detail::audio_ranges_overlap(left, side, frames)) ||
65 (right != mid && detail::audio_ranges_overlap(right, mid, frames)) ||
66 (right != side && detail::audio_ranges_overlap(right, side, frames)))
67 return false;
68 for (std::size_t i = 0; i < frames; ++i) {
69 const auto m = mid[i];
70 const auto s = side[i];
71 mid_side_decode(m, s, left[i], right[i]);
72 }
73 return true;
74}
75
79template <typename SampleType>
80inline SampleType stereo_width(SampleType left, SampleType right, SampleType width,
81 SampleType& out_left, SampleType& out_right) noexcept {
82 static_assert(std::is_floating_point_v<SampleType>);
83 if (!std::isfinite(width))
84 width = SampleType{1};
85 width = std::clamp(width, SampleType{0}, SampleType{2});
86 SampleType mid{}, side{};
87 mid_side_encode(left, right, mid, side);
88 mid_side_decode(mid, side * width, out_left, out_right);
89 return width;
90}
91
92} // namespace pulp::signal
Definition additive_bank.hpp:218
bool mid_side_encode_block(const SampleType *left, const SampleType *right, SampleType *mid, SampleType *side, std::size_t frames) noexcept
Definition mid_side.hpp:37
@ right
Definition multi_channel_meter.hpp:67
@ left
Definition multi_channel_meter.hpp:66
SampleType stereo_width(SampleType left, SampleType right, SampleType width, SampleType &out_left, SampleType &out_right) noexcept
Mono-safe width built on the orthonormal transform.
Definition mid_side.hpp:80
@ i
Definition formant_filter_bank.hpp:20
bool mid_side_decode_block(const SampleType *mid, const SampleType *side, SampleType *left, SampleType *right, std::size_t frames) noexcept
Definition mid_side.hpp:57
void mid_side_encode(SampleType left, SampleType right, SampleType &mid, SampleType &side) noexcept
Orthonormal stereo transform.
Definition mid_side.hpp:17
void mid_side_decode(SampleType mid, SampleType side, SampleType &left, SampleType &right) noexcept
Definition mid_side.hpp:27