Twitch SDK (Internal)
decreasebitdepthoperator.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 
13 
14 namespace ttv
15 {
31  template <typename InputSource, typename OutputSampleType, typename ContextType>
33  {
34  public:
35  DecreaseBitDepthOperator(ContextType& context)
36  : mInputSource(context)
37  {
38  }
39 
40  using InputSampleType = typename InputSource::SampleType;
41  static_assert(std::is_integral<InputSampleType>::value, "Input sample type must be integral.");
42  static_assert(std::is_integral<OutputSampleType>::value, "Output sample type must be integral.");
43  static_assert(std::is_signed<InputSampleType>::value == std::is_signed<OutputSampleType>::value, "Input sample type and output sample type must have same signedness.");
44  static_assert(sizeof(InputSampleType) > sizeof(OutputSampleType), "Output sample type must be smaller than the input sample type.");
45 
46  using SampleType = OutputSampleType;
47  static constexpr size_t SampleRate = InputSource::SampleRate;
48 
49 
50  InputSource& GetInputSource()
51  {
52  return mInputSource;
53  }
54 
55 
57  {
58  return mInputSource.GetSampleRange();
59  }
60 
61 
62  SampleType operator[](size_t index) const
63  {
64  assert(index >= GetSampleRange().startIndex);
65  assert(index < GetSampleRange().startIndex + GetSampleRange().sampleCount);
66 
67  // We don't directly use bit shifting math here, because bit shift right is actually
68  // implementation-defined for negative values. We can use division and modulus here
69  // instead and since the divisor is based on the sizeof() and known at compile-time,
70  // the compiler will know that the divisor is a power of two and will do whatever
71  // fancy bit shift math is appropriate for the architecture we're compiling for.
72  constexpr InputSampleType divisor = static_cast<InputSampleType>(1 << ((sizeof(InputSampleType) - sizeof(OutputSampleType)) * 8));
73 
74  InputSampleType inputSample = mInputSource[index];
75 
76  InputSampleType quotient = inputSample / divisor;
77  InputSampleType remainder = inputSample % divisor;
78 
79  // This should return us -1, 0 or 1 depending on the result of the dither.
80  InputSampleType ditheredNoise = ContextType::Options::Ditherer::DitherFractionalValue(remainder, divisor);
81 
82  return static_cast<OutputSampleType>(quotient + ditheredNoise);
83  }
84 
85  private:
86  InputSource mInputSource;
87  };
88 }
typename InputSource::SampleType InputSampleType
Definition: decreasebitdepthoperator.h:40
SampleType operator[](size_t index) const
Definition: decreasebitdepthoperator.h:62
JSON (JavaScript Object Notation).
Definition: adsapi.h:16
SampleRange GetSampleRange() const
Definition: decreasebitdepthoperator.h:56
static constexpr size_t SampleRate
Definition: decreasebitdepthoperator.h:47
OutputSampleType SampleType
Definition: decreasebitdepthoperator.h:46
#define assert(expr)
Definition: assertion.h:47
Definition: dsputilities.h:60
InputSource mInputSource
Definition: decreasebitdepthoperator.h:86
InputSource & GetInputSource()
Definition: decreasebitdepthoperator.h:50
Definition: decreasebitdepthoperator.h:32
DecreaseBitDepthOperator(ContextType &context)
Definition: decreasebitdepthoperator.h:35