libsidplayfp  2.15.0
simpleMixer.h
1 /*
2  * This file is part of libsidplayfp, a SID player engine.
3  *
4  * Copyright 2011-2025 Leandro Nini <drfiemost@users.sourceforge.net>
5  * Copyright 2007-2010 Antti Lankila
6  * Copyright (C) 2000 Simon White
7  *
8  * This program 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  * This program 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 this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 #ifndef SIMPLEMIXER_H
25 #define SIMPLEMIXER_H
26 
27 #include <vector>
28 #include <version>
29 #include <cstdint>
30 
31 #ifdef __cpp_lib_math_constants
32 # include <numbers>
33 #endif
34 
35 namespace libsidplayfp
36 {
37 
42 {
43 private:
44  static constexpr int_least32_t SCALE_FACTOR = 1 << 16;
45 
46 #ifdef __cpp_lib_math_constants
47  static constexpr double SQRT_2 = std::numbers::sqrt2;
48  static constexpr double SQRT_3 = std::numbers::sqrt3;
49 #else
50  static constexpr double SQRT_2 = 1.41421356237;
51  static constexpr double SQRT_3 = 1.73205080757;
52 #endif
53 
54  static constexpr int_least32_t SCALE[3] = {
55  SCALE_FACTOR, // 1 chip, no scale
56  static_cast<int_least32_t>((1.0 / SQRT_2) * SCALE_FACTOR), // 2 chips, scale by sqrt(2)
57  static_cast<int_least32_t>((1.0 / SQRT_3) * SCALE_FACTOR) // 3 chips, scale by sqrt(3)
58  };
59 
60 private:
61  using mixer_func_t = int_least32_t (SimpleMixer::*)() const;
62 
63 private:
64  std::vector<short*> m_buffers;
65 
66  std::vector<int_least32_t> m_iSamples;
67 
68  std::vector<mixer_func_t> m_mix;
69 
70 private:
71  void updateParams();
72 
73  /*
74  * Channel matrix
75  *
76  * C1
77  * L 1.0
78  * R 1.0
79  *
80  * C1 C2
81  * L 1.0 0.5
82  * R 0.5 1.0
83  *
84  * C1 C2 C3
85  * L 1.0 1.0 0.5
86  * R 0.5 1.0 1.0
87  */
88 
89  // Mono mixing
90  template <int Chips>
91  int_least32_t mono() const
92  {
93  int_least32_t res = 0;
94  for (int i = 0; i < Chips; i++)
95  res += m_iSamples[i];
96  return res * SCALE[Chips-1] / SCALE_FACTOR;
97  }
98 
99  // Stereo mixing
100  int_least32_t stereo_OneChip() const { return m_iSamples[0]; }
101 
102  int_least32_t stereo_ch1_TwoChips() const
103  {
104  return (m_iSamples[0] + 0.5*m_iSamples[1]) * SCALE[1] / SCALE_FACTOR;
105  }
106  int_least32_t stereo_ch2_TwoChips() const
107  {
108  return (0.5*m_iSamples[0] + m_iSamples[1]) * SCALE[1] / SCALE_FACTOR;
109  }
110 
111  int_least32_t stereo_ch1_ThreeChips() const
112  {
113  return (m_iSamples[0] + m_iSamples[1] + 0.5*m_iSamples[2]) * SCALE[2] / SCALE_FACTOR;
114  }
115  int_least32_t stereo_ch2_ThreeChips() const
116  {
117  return (0.5*m_iSamples[0] + m_iSamples[1] + m_iSamples[2]) * SCALE[2] / SCALE_FACTOR;
118  }
119 
120 private:
121  SimpleMixer() = delete;
122  SimpleMixer(const SimpleMixer&) = delete;
123 
124 public:
128  SimpleMixer(bool stereo, short** buffers, int chips);
129 
133  unsigned int doMix(short *buffer, unsigned int samples);
134 };
135 
136 }
137 
138 #endif // MIXER_H
Definition: simpleMixer.h:42
unsigned int doMix(short *buffer, unsigned int samples)
Definition: simpleMixer.cpp:39