Twitch SDK (Internal)
samplecache.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 #include <limits>
15 
16 namespace ttv
17 {
44  template <typename SampleType, size_t CacheSize>
46  {
47  public:
49  : mRangeStartIndex(std::numeric_limits<size_t>::max())
51  {
52  }
53 
55  {
56  return {mRangeStartIndex, CacheSize};
57  }
58 
59 
60  SampleType operator[](size_t index)
61  {
62  assert(index >= mRangeStartIndex);
63  assert(index < mRangeStartIndex + CacheSize);
64 
65  size_t difference = index - mRangeStartIndex;
66  return mDoubleRingBuffer[mRingBufferStartIndex + difference];
67  }
68 
69 
70  template <typename PopulatorType>
71  void Populate(size_t startIndex, PopulatorType&& populator)
72  {
73  SampleRange rangeToPopulate;
74  if (startIndex < mRangeStartIndex)
75  {
76  size_t difference = mRangeStartIndex - startIndex;
77  if (difference > CacheSize)
78  {
79  // Start from scratch and repopulate the entire cache
81  mRangeStartIndex = startIndex;
82  PopulateRange({startIndex, CacheSize}, std::forward<PopulatorType>(populator));
83  }
84  else
85  {
86  // Move the ring buffer index back and only populate the missing samples
87  mRingBufferStartIndex += CacheSize;
88  mRingBufferStartIndex -= difference;
89  mRingBufferStartIndex %= CacheSize;
90 
91  mRangeStartIndex = startIndex;
92  PopulateRange({startIndex, difference}, std::forward<PopulatorType>(populator));
93  }
94  }
95  else if (startIndex > mRangeStartIndex)
96  {
97  size_t difference = startIndex - mRangeStartIndex;
98  if (difference > CacheSize)
99  {
100  // Start from scratch and repopulate the entire cache
102  mRangeStartIndex = startIndex;
103  PopulateRange({startIndex, CacheSize}, std::forward<PopulatorType>(populator));
104  }
105  else
106  {
107  // Move the ring buffer index forward and only populate the missing samples.
108  mRingBufferStartIndex += difference;
109  mRingBufferStartIndex %= CacheSize;
110  mRangeStartIndex = startIndex;
111  PopulateRange({startIndex + CacheSize - difference, difference}, std::forward<PopulatorType>(populator));
112  }
113  }
114  }
115 
116  private:
117 
118  template <typename PopulatorType>
119  void PopulateRange(SampleRange range, PopulatorType&& populator)
120  {
121  for (size_t index = range.startIndex; index < range.startIndex + range.sampleCount; index++)
122  {
123  size_t difference = index - mRangeStartIndex;
124  size_t cacheIndex = (mRingBufferStartIndex + difference) % CacheSize;
125 
126  SampleType sample = static_cast<SampleType>(populator(index));
127  mDoubleRingBuffer[cacheIndex] = sample;
128  mDoubleRingBuffer[cacheIndex + CacheSize] = sample;
129  }
130  }
131 
132  std::array<SampleType, CacheSize * 2> mDoubleRingBuffer;
135  };
136 }
void PopulateRange(SampleRange range, PopulatorType &&populator)
Definition: samplecache.h:119
SampleType operator[](size_t index)
Definition: samplecache.h:60
Definition: cpp11transition.h:22
size_t sampleCount
Definition: dsputilities.h:80
JSON (JavaScript Object Notation).
Definition: adsapi.h:16
size_t mRangeStartIndex
Definition: samplecache.h:133
#define assert(expr)
Definition: assertion.h:47
Definition: dsputilities.h:60
size_t startIndex
Definition: dsputilities.h:75
Definition: samplecache.h:45
SampleCache()
Definition: samplecache.h:48
void Populate(size_t startIndex, PopulatorType &&populator)
Definition: samplecache.h:71
size_t mRingBufferStartIndex
Definition: samplecache.h:134
std::array< SampleType, CacheSize *2 > mDoubleRingBuffer
Definition: samplecache.h:132
SampleRange GetRange() const
Definition: samplecache.h:54