Twitch SDK (Internal)
dsputilities.h
Go to the documentation of this file.
1 /********************************************************************************************
2  * Twitch Broadcasting SDK
3  *
4  * This software is supplied under the terms of a license agreement with Twitch Interactive, Inc. and
5  * may not be copied or used except in accordance with the terms of that agreement
6  * Copyright (c) 2012-2017 Twitch Interactive, Inc.
7  *
8  *********************************************************************************************/
9 
10 #pragma once
11 
12 #include <array>
13 #include <cmath>
14 
15 namespace ttv
16 {
17  constexpr double kPi = 3.14159265358979323846;
18 
60  struct SampleRange
61  {
63  : startIndex(0)
64  , sampleCount(0)
65  {}
66 
68  : startIndex(startIndex)
69  , sampleCount(sampleCount)
70  {}
71 
75  size_t startIndex;
76 
80  size_t sampleCount;
81  };
82 
83 
88  {
89  size_t outputRangeStart = std::max(firstRange.startIndex, secondRange.startIndex);
90  size_t outputRangeEnd = std::min(firstRange.startIndex + firstRange.sampleCount, secondRange.startIndex + secondRange.sampleCount);
91 
92  if (outputRangeStart < outputRangeEnd)
93  {
94  return {outputRangeStart, outputRangeEnd - outputRangeStart};
95  }
96  else
97  {
98  return {};
99  }
100  }
101 
107  {
108  if ((extension.startIndex + extension.sampleCount >= range.startIndex) && (range.startIndex + range.sampleCount >= extension.startIndex))
109  {
110  size_t outputRangeStart = std::min(range.startIndex, extension.startIndex);
111  size_t outputRangeEnd = std::max(range.startIndex + range.sampleCount, extension.startIndex + extension.sampleCount);
112 
113  return {outputRangeStart, outputRangeEnd - outputRangeStart};
114  }
115 
116  return range;
117  }
118 
126  template <typename SampleTypeArg, size_t SampleRateArg, size_t ChannelCountArg = 1>
128  {
129  static_assert(ChannelCountArg != 0, "Channel count can't be zero.");
130  static_assert(SampleRateArg != 0, "Sample rate cannot be zero.");
131 
132  using SampleType = SampleTypeArg;
133  static constexpr size_t SampleRate = SampleRateArg;
134  static constexpr size_t ChannelCount = ChannelCountArg;
135  };
136 
142  template <typename IntegralType>
143  constexpr size_t BisectRange()
144  {
145  static_assert(std::is_integral<IntegralType>::value, "Must be an integral type.");
146  return 1 << ((sizeof(IntegralType) * 8) - 1);
147  }
148 
149 
156  template <typename SampleType>
157  std::enable_if_t<std::is_floating_point<SampleType>::value, SampleType> ClampAndCastSample(double input)
158  {
159  if (input > 1.0)
160  {
161  return static_cast<SampleType>(1.0);
162  }
163 
164  if (input < -1.0)
165  {
166  return static_cast<SampleType>(-1.0);
167  }
168 
169  return static_cast<SampleType>(input);
170  }
171 
178  template <typename SampleType>
179  std::enable_if_t<std::is_integral<SampleType>::value, SampleType> ClampAndCastSample(double input)
180  {
181  if (input > std::numeric_limits<SampleType>::max())
182  {
183  return std::numeric_limits<SampleType>::max();
184  }
185 
186  if (input < std::numeric_limits<SampleType>::min())
187  {
188  return std::numeric_limits<SampleType>::min();
189  }
190 
191  return static_cast<SampleType>(input);
192  }
193 
194 
201  template <typename Generator, size_t Length>
203  {
204  public:
206  {
207  for (size_t i = 0; i < Length; i++)
208  {
209  mValues[i] = Generator::Generate(i, Length);
210  }
211  }
212 
213  typename Generator::ReturnType operator[](size_t index) const
214  {
215  assert(index < mValues.size());
216 
217  return mValues[index];
218  }
219 
220  private:
221  std::array<typename Generator::ReturnType, Length> mValues;
222  };
223 
239  template <typename FirstGenerator, typename SecondGenerator>
241  {
242  static_assert(std::is_same<typename FirstGenerator::ReturnType, typename SecondGenerator::ReturnType>::value, "Factors of ProductGenerator must return the same type.");
243  using ReturnType = typename FirstGenerator::ReturnType;
244 
245  static ReturnType Generate(size_t index, size_t length)
246  {
247  return FirstGenerator::Generate(index, length) * SecondGenerator::Generate(index, length);
248  }
249  };
250 
251 
258  template <typename InputGenerator, size_t SamplingInterval>
260  {
261  using ReturnType = typename InputGenerator::ReturnType;
262 
263  static ReturnType Generate(size_t index, size_t length)
264  {
265  size_t cycleCount = length / SamplingInterval;
266  size_t intervalCount = index % cycleCount;
267  size_t shift = index / cycleCount;
268 
269  size_t cycledIndex = intervalCount * SamplingInterval + shift;
270 
271  return InputGenerator::Generate(cycledIndex, length);
272  }
273  };
274 
275 
279  template <typename SincFunctionParameters>
281  {
282  using ReturnType = double;
283 
284  static ReturnType Generate(size_t index, size_t length)
285  {
286  if (index * 2 == length + 1)
287  {
288  // We're exactly in the center.
289  return 1.0;
290  }
291 
292  double time = static_cast<double>(index) / static_cast<double>(length - 1);
293 
294  // Center along the domain
295  time -= 0.5;
296 
297  time *= static_cast<double>(SincFunctionParameters::Range);
298 
299  double x = 2.0 * kPi * time * SincFunctionParameters::Cutoff;
300 
301  return std::sin(x) / x;
302  }
303  };
304 
305 
309  template <typename Parameters>
311  {
312  using ReturnType = double;
313 
317  static double BesselFunction(double x)
318  {
319  constexpr double epsilon = 1E-21;
320  double halfXSquared = x * x / 4.0;
321 
322  double sigmaTerm = 1.0; // First sigma term is always 1
323  double sigma = sigmaTerm;
324 
325  for (double sigmaIndex = 1.0; sigmaTerm > sigma * epsilon; sigmaIndex++)
326  {
327  // We can calculate the next term by modifying the previous term.
328  sigmaTerm *= halfXSquared;
329  sigmaTerm /= (sigmaIndex * sigmaIndex);
330 
331  sigma += sigmaTerm;
332  }
333 
334  return sigma;
335  }
336 
337 
338  static ReturnType Generate(size_t index, size_t length)
339  {
340  double windowLengthMinusOne = static_cast<double>(Parameters::Length - 1);
341  double position = static_cast<double>(index) * static_cast<double>(windowLengthMinusOne) / static_cast<double>(length);
342 
343  double value = 2 * position - windowLengthMinusOne;
344  value /= windowLengthMinusOne;
345  value *= value;
346  value = 1.0 - value;
347  value = sqrt(value);
348  value *= Parameters::Beta;
349  value = BesselFunction(value);
350  value /= BesselFunction(Parameters::Beta);
351  return value;
352  }
353  };
354 }
SampleRange ExtendSampleRange(SampleRange range, SampleRange extension)
Definition: dsputilities.h:106
Definition: dsputilities.h:127
std::enable_if_t< std::is_floating_point< SampleType >::value, SampleType > ClampAndCastSample(double input)
Definition: dsputilities.h:157
Generator::ReturnType operator[](size_t index) const
Definition: dsputilities.h:213
Definition: dsputilities.h:202
double ReturnType
Definition: dsputilities.h:282
typename InputGenerator::ReturnType ReturnType
Definition: dsputilities.h:261
static ReturnType Generate(size_t index, size_t length)
Definition: dsputilities.h:338
constexpr double kPi
Definition: dsputilities.h:17
size_t sampleCount
Definition: dsputilities.h:80
SampleTypeArg SampleType
Definition: dsputilities.h:132
Definition: dsputilities.h:259
JSON (JavaScript Object Notation).
Definition: adsapi.h:16
#define assert(expr)
Definition: assertion.h:47
static ReturnType Generate(size_t index, size_t length)
Definition: dsputilities.h:263
Definition: dsputilities.h:310
Definition: dsputilities.h:60
Definition: dsputilities.h:240
SampleRange()
Definition: dsputilities.h:62
size_t startIndex
Definition: dsputilities.h:75
std::array< typename Generator::ReturnType, Length > mValues
Definition: dsputilities.h:221
Definition: dsputilities.h:280
typename FirstGenerator::ReturnType ReturnType
Definition: dsputilities.h:243
double ReturnType
Definition: dsputilities.h:312
SampleRange IntersectSampleRanges(SampleRange firstRange, SampleRange secondRange)
Definition: dsputilities.h:87
constexpr size_t BisectRange()
Definition: dsputilities.h:143
static ReturnType Generate(size_t index, size_t length)
Definition: dsputilities.h:245
SampleRange(size_t startIndex, size_t sampleCount)
Definition: dsputilities.h:67
LookupTable()
Definition: dsputilities.h:205
static ReturnType Generate(size_t index, size_t length)
Definition: dsputilities.h:284
static double BesselFunction(double x)
Definition: dsputilities.h:317