JPL Spatial
Sound spatialization and propagation library
Loading...
Searching...
No Matches
ChannelMixing.h
Go to the documentation of this file.
1//
2// ██╗██████╗ ██╗ ██╗██████╗ ███████╗
3// ██║██╔══██╗ ██║ ██║██╔══██╗██╔════╝ ** JPLSpatial **
4// ██║██████╔╝ ██║ ██║██████╔╝███████╗
5// ██ ██║██╔═══╝ ██║ ██║██╔══██╗╚════██║ https://github.com/Jaytheway/JPLSpatial
6// ╚█████╔╝██║ ███████╗██║██████╔╝███████║
7// ╚════╝ ╚═╝ ╚══════╝╚═╝╚═════╝ ╚══════╝
8//
9// Copyright Jaroslav Pevno, JPLSpatial is offered under the terms of the ISC license:
10//
11// Permission to use, copy, modify, and/or distribute this software for any purpose with or
12// without fee is hereby granted, provided that the above copyright notice and this permission
13// notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
14// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
16// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
18// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20#pragma once
21
22#include <JPLSpatial/Core.h>
25
26namespace JPL
27{
28 //======================================================================
31
41
42 inline void Add(float* dest, const float* source, uint32 destChannel, uint32 destNumChannels, uint32 numFrames)
43 {
46 for (uint32 di = 0, si = 0; di < totalSamples; di += destNumChannels, ++si)
47 dest[di] += source[si];
48 }
49
50 inline void ApplyGain(float* dest, uint32 numFrames, float gain)
51 {
52 const simd gainVe(gain);
54 while (numSimd--)
55 {
56 (simd(dest) *= gainVe).store(dest);
57 dest += simd::size();
58 }
59 for (uint32 t = 0; t < GetSIMDTail(numFrames); ++t)
60 {
61 dest[t] *= gain;
62 }
63 }
64
65 inline void ApplyGainRamp(float* dest, uint32 numFrames, float gainStart, float gainEnd)
66 {
67 const float delta = (gainEnd - gainStart) / static_cast<float>(numFrames);
68
69 static const simd ramp(1.0f, 2.0f, 3.0f, 4.0f);
70 static const simd four(4.0f);
71
74
75 while (numSimd--)
76 {
77 (simd(dest) *= ramp).store(dest);
78 dest += simd::size();
79 deltaVec += four;
80 }
81
82 float dt = deltaVec.get_lane<0>();
83 for (uint32 t = 0; t < GetSIMDTail(numFrames); ++t, dt += delta)
84 {
85 dest[t] *= dt;
86 }
87 }
88
91 {
92 // Offset to our channels of interest
95
96 // We can use either source or destination chanel count
98
99 // Will be 0, if gainEnd == gainStart
100 const float delta = (gainEnd - gainStart) / static_cast<float>(numFrames);
101
102 // Loop over with stride
104 {
105 dest[di] += source[si] * gainStart;
106 }
107 }
108
109 inline void AddAndApplyGainRamp(float* dest, const float* source, uint32 numChannels, uint32 numFrames, float gainStart, float gainEnd)
110 {
111 // Offset to our channels of interest
112
114
115 // Will be 0, if gainEnd == gainStart
116 const float delta = (gainEnd - gainStart) / static_cast<float>(numFrames);
117
118 // Loop over with stride
120 {
121 for (uint32 ch = si; ch < numChannels; ++ch)
122 {
123 dest[ch] += source[ch] * gainStart;
124 }
125 }
126 }
127
128 // Does not initialize `dest` to 0, does not apply normalization
129 inline void DownmixToMono(float* dest, const float* source, uint32 numChannels, uint32 numSamples)
130 {
131 for (uint32 si = 0, di = 0; si < numSamples; si += numChannels, ++di)
132 {
133 for (uint32 ch = 0; ch < numChannels; ++ch)
134 dest[di] += source[si + ch];
135 }
136 }
137} // namespace JPL
Definition AcousticMaterial.h:36
JPL_INLINE constexpr auto GetNumSIMDOps(std::unsigned_integral auto count) noexcept
Get number of SIMD operations that can fit into the count
Definition SIMDMath.h:51
void AddAndApplyGainRamp(float *dest, const float *source, uint32 destChannel, uint32 sourceChannel, uint32 destNumChannels, uint32 sourceNumChannels, uint32 numFrames, float gainStart, float gainEnd)
Definition ChannelMixing.h:89
void Add(float *dest, const float *source, uint32 destChannel, uint32 sourceChannel, uint32 destNumChannels, uint32 sourceNumChannels, uint32 numFrames)
Definition ChannelMixing.h:32
JPL_INLINE constexpr auto GetSIMDTail(std::unsigned_integral auto count) noexcept
Get the remaining tail from count that won't fill a simd vector.
Definition SIMDMath.h:45
void ApplyGain(float *dest, uint32 numFrames, float gain)
Definition ChannelMixing.h:50
std::uint32_t uint32
Definition Core.h:311
void ApplyGainRamp(float *dest, uint32 numFrames, float gainStart, float gainEnd)
Definition ChannelMixing.h:65
JPL_INLINE simd min(const simd &a, const simd &b) noexcept
Element-wise min.
Definition SIMD.h:1813
void DownmixToMono(float *dest, const float *source, uint32 numChannels, uint32 numSamples)
Definition ChannelMixing.h:129
Minimal 4-wide 32-bit float vector implementation for SIMD.
Definition SIMD.h:60
JPL_INLINE float get_lane() const noexcept
Get float component by index known at compile-time.
Definition SIMD.h:610
static constexpr std::size_t size() noexcept
Get number of element of the vector.
Definition SIMD.h:97