DSPark 1.8.0
Header-only C++20 DSP for real-time and offline audio
Loading...
Searching...
No Matches
MidSide.h
1// DSPark - Professional Audio DSP Framework
2// Copyright (c) 2026 Cristian Moresi - MIT License
3
4#pragma once
5
30#include "../Core/AudioBuffer.h"
31
32#include <cassert>
33
34// DSPARK_RESTRICT is normally provided by SimdOps.h (via AudioBuffer.h).
35// Guard against redefinition so this header stays self-contained if included alone.
36#ifndef DSPARK_RESTRICT
37 #if defined(__clang__) || defined(__GNUC__)
38 #define DSPARK_RESTRICT __restrict__
39 #elif defined(_MSC_VER)
40 #define DSPARK_RESTRICT __restrict
41 #else
42 #define DSPARK_RESTRICT
43 #endif
44#endif
45
46namespace dspark {
47
57template <typename T>
58struct MidSide
59{
70 static constexpr void encodeSample(T& left_mid, T& right_side) noexcept
71 {
72 const T l = left_mid;
73 const T r = right_side;
74 left_mid = (l + r) * T(0.5);
75 right_side = (l - r) * T(0.5);
76 }
77
86 static constexpr void decodeSample(T& mid_left, T& side_right) noexcept
87 {
88 const T m = mid_left;
89 const T s = side_right;
90 mid_left = m + s;
91 side_right = m - s;
92 }
93
108 static void encode(AudioBufferView<T> buffer) noexcept
109 {
110 assert(buffer.getNumChannels() >= 2);
111
112 const int n = buffer.getNumSamples();
113 if (buffer.getNumChannels() < 2 || n <= 0) return; // Release-safe
114
115 T* DSPARK_RESTRICT left = buffer.getChannel(0);
116 T* DSPARK_RESTRICT right = buffer.getChannel(1);
117
118 for (int i = 0; i < n; ++i)
119 {
120 const T l = left[i];
121 const T r = right[i];
122 left[i] = (l + r) * T(0.5); // Mid
123 right[i] = (l - r) * T(0.5); // Side
124 }
125 }
126
138 static void decode(AudioBufferView<T> buffer) noexcept
139 {
140 assert(buffer.getNumChannels() >= 2);
141
142 const int n = buffer.getNumSamples();
143 if (buffer.getNumChannels() < 2 || n <= 0) return; // Release-safe
144
145 T* DSPARK_RESTRICT mid = buffer.getChannel(0);
146 T* DSPARK_RESTRICT side = buffer.getChannel(1);
147
148 for (int i = 0; i < n; ++i)
149 {
150 const T m = mid[i];
151 const T s = side[i];
152 mid[i] = m + s; // Left
153 side[i] = m - s; // Right
154 }
155 }
156};
157
158} // namespace dspark
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:59
static void encode(AudioBufferView< T > buffer) noexcept
Encodes an entire stereo buffer from Left/Right to Mid/Side.
Definition MidSide.h:108
static void decode(AudioBufferView< T > buffer) noexcept
Decodes an entire stereo buffer from Mid/Side back to Left/Right.
Definition MidSide.h:138
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:70
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:86