1 /** @addtogroup dsp_extra
2 * @{
3 */
4 /*
5 Copyright (C) 2016 D Levin (https://www.kfrlib.com)
6 This file is part of KFR
7
8 KFR is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
12
13 KFR is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with KFR.
20
21 If GPL is not suitable for your project, you must purchase a commercial license to use KFR.
22 Buying a commercial license is mandatory as soon as you develop commercial activities without
23 disclosing the source code of your own applications.
24 See https://www.kfrlib.com for details.
25 */
26 #pragma once
27
28 #include "../base.hpp"
29
30 namespace kfr
31 {
32 inline namespace CMT_ARCH_NAME
33 {
34
35 /**
36 * @brief Returns template expression that returns the sum of all the inputs
37 */
38 template <typename... E>
mixdown(E &&...e)39 internal::expression_function<fn::add, E...> mixdown(E&&... e)
40 {
41 return internal::expression_function<fn::add, E...>(fn::add(), std::forward<E>(e)...);
42 }
43
44 namespace internal
45 {
46 struct stereo_matrix
47 {
48 template <typename T, size_t N>
operator ()kfr::CMT_ARCH_NAME::internal::stereo_matrix49 KFR_MEM_INTRINSIC vec<vec<T, 2>, N> operator()(const vec<vec<T, 2>, N>& x) const
50 {
51 return process(x, csizeseq<N>);
52 }
53 template <typename T, size_t N, size_t... indices>
processkfr::CMT_ARCH_NAME::internal::stereo_matrix54 KFR_MEM_INTRINSIC vec<vec<T, 2>, N> process(const vec<vec<T, 2>, N>& x, csizes_t<indices...>) const
55 {
56 return vec<vec<T, 2>, N>(hadd(transpose(x[indices] * matrix))...);
57 }
58 const f64x2x2 matrix;
59 };
60 } // namespace internal
61
62 template <int = 0>
matrix_sum_diff()63 CMT_GNU_CONSTEXPR f64x2x2 matrix_sum_diff()
64 {
65 return { f64x2{ 1, 1 }, f64x2{ 1, -1 } };
66 }
67 template <int = 0>
matrix_halfsum_halfdiff()68 CMT_GNU_CONSTEXPR f64x2x2 matrix_halfsum_halfdiff()
69 {
70 return { f64x2{ 0.5, 0.5 }, f64x2{ 0.5, -0.5 } };
71 }
72
73 /**
74 * @brief Returns template expression that returns the vector of length 2 containing mix of the left and right
75 * channels
76 */
77 template <typename Left, typename Right,
78 typename Result =
79 internal::expression_function<internal::stereo_matrix, internal::expression_pack<Left, Right>>>
mixdown_stereo(Left && left,Right && right,const f64x2x2 & matrix)80 Result mixdown_stereo(Left&& left, Right&& right, const f64x2x2& matrix)
81 {
82 return Result(internal::stereo_matrix{ matrix },
83 pack(std::forward<Left>(left), std::forward<Right>(right)));
84 }
85 } // namespace CMT_ARCH_NAME
86 } // namespace kfr
87