DSPark 1.6.1
Header-only audio DSP framework in pure C++20 — zero dependencies
Loading...
Searching...
No Matches
MidSide.h
Go to the documentation of this file.
1// DSPark - Professional Audio DSP Framework
2// Copyright (c) 2026 Cristian Moresi - MIT License
3
4#pragma once
5
28#include "../Core/AudioBuffer.h"
29
30#include <cassert>
31
32// DSPARK_RESTRICT is normally provided by SimdOps.h (via AudioBuffer.h).
33// Guard against redefinition so this header stays self-contained if included alone.
34#ifndef DSPARK_RESTRICT
35 #if defined(__clang__) || defined(__GNUC__)
36 #define DSPARK_RESTRICT __restrict__
37 #elif defined(_MSC_VER)
38 #define DSPARK_RESTRICT __restrict
39 #else
40 #define DSPARK_RESTRICT
41 #endif
42#endif
43
44namespace dspark {
45
55template <typename T>
56struct MidSide
57{
68 static constexpr void encodeSample(T& left_mid, T& right_side) noexcept
69 {
70 const T l = left_mid;
71 const T r = right_side;
72 left_mid = (l + r) * T(0.5);
73 right_side = (l - r) * T(0.5);
74 }
75
84 static constexpr void decodeSample(T& mid_left, T& side_right) noexcept
85 {
86 const T m = mid_left;
87 const T s = side_right;
88 mid_left = m + s;
89 side_right = m - s;
90 }
91
106 static void encode(AudioBufferView<T> buffer) noexcept
107 {
108 assert(buffer.getNumChannels() >= 2);
109
110 const int n = buffer.getNumSamples();
111 if (buffer.getNumChannels() < 2 || n <= 0) return; // Release-safe
112
113 T* DSPARK_RESTRICT left = buffer.getChannel(0);
114 T* DSPARK_RESTRICT right = buffer.getChannel(1);
115
116 for (int i = 0; i < n; ++i)
117 {
118 const T l = left[i];
119 const T r = right[i];
120 left[i] = (l + r) * T(0.5); // Mid
121 right[i] = (l - r) * T(0.5); // Side
122 }
123 }
124
136 static void decode(AudioBufferView<T> buffer) noexcept
137 {
138 assert(buffer.getNumChannels() >= 2);
139
140 const int n = buffer.getNumSamples();
141 if (buffer.getNumChannels() < 2 || n <= 0) return; // Release-safe
142
143 T* DSPARK_RESTRICT mid = buffer.getChannel(0);
144 T* DSPARK_RESTRICT side = buffer.getChannel(1);
145
146 for (int i = 0; i < n; ++i)
147 {
148 const T m = mid[i];
149 const T s = side[i];
150 mid[i] = m + s; // Left
151 side[i] = m - s; // Right
152 }
153 }
154};
155
156} // namespace dspark
#define DSPARK_RESTRICT
Definition SimdOps.h:60
Non-owning view over audio channel data.
Definition AudioBuffer.h:50
Main namespace for the DSPark framework.
Static utility for Mid/Side stereo encoding and decoding.
Definition MidSide.h:57
static void encode(AudioBufferView< T > buffer) noexcept
Encodes an entire stereo buffer from Left/Right to Mid/Side.
Definition MidSide.h:106
static void decode(AudioBufferView< T > buffer) noexcept
Decodes an entire stereo buffer from Mid/Side back to Left/Right.
Definition MidSide.h:136
static constexpr void encodeSample(T &left_mid, T &right_side) noexcept
Encodes a single sample frame from Left/Right to Mid/Side in-place.
Definition MidSide.h:68
static constexpr void decodeSample(T &mid_left, T &side_right) noexcept
Decodes a single sample frame from Mid/Side to Left/Right in-place.
Definition MidSide.h:84