commonlib
buffer.h
Go to the documentation of this file.
1 
11 #pragma once
12 
13 #include "memory.h"
14 #include <memory>
15 #include <mutex>
16 #include <cassert>
17 #include "lock_guard.h"
18 
19 BEGIN_NAMESPACE_MEMORY
20 
24 template <typename T>
26 {
27 public:
28  virtual ~ISourceBuffer() = default;
29 
34  virtual std::recursive_mutex& getLock() = 0;
35 
40  virtual size_t getSize() = 0;
41 
49  virtual size_t readSamples(T* samples, size_t samplesCount, bool incrementPosition = true) = 0;
50 
56  virtual void incrementReadPosition(size_t pos) = 0;
57 };
58 
62 template <typename T>
64 {
65 public:
66  virtual ~ITargetBuffer() = default;
67 
72  virtual std::recursive_mutex& getLock() = 0;
73 
78  virtual size_t getRemainingSize() = 0;
79 
87  virtual size_t writeSamples(const T* samples, size_t samplesCount, bool incrementPosition = true) = 0;
88 
94  virtual void incrementWritePosition(size_t pos) = 0;
95 };
96 
97 template <typename T>
98 static void operator<<(ITargetBuffer<T>& target, ISourceBuffer<T>& source)
99 {
100  transferBuffer(source, target);
101 }
102 
103 template <typename T>
104 static void operator>>(ISourceBuffer<T>& source, ITargetBuffer<T>& target)
105 {
106  transferBuffer(source, target);
107 }
108 
117 template <typename T, typename Locking = UseLock>
119  ITargetBuffer<T>& target,
120  bool incrementPosition = true,
121  size_t samplesCount = (std::numeric_limits<size_t>::max)())
122 {
125  samplesCount = std::min<size_t>(std::min<size_t>(samplesCount, source.getSize()), target.getRemainingSize());
126 
127  T* data = new T[samplesCount];
128  source.readSamples(data, samplesCount, incrementPosition);
129  target.writeSamples(data, samplesCount, incrementPosition);
130 
131  delete[] data;
132  return samplesCount;
133 }
134 
143 template <typename S, typename T>
145  ITargetBuffer<T>& target,
146  bool incrementPosition = true,
147  size_t samplesCount = (std::numeric_limits<size_t>::max)())
148 {
149  std::lock_guard<std::recursive_mutex> guardS(source.getLock());
150  std::lock_guard<std::recursive_mutex> guardT(target.getLock());
151 
152  assert(sizeof(S) % sizeof(T) == 0 || sizeof(T) % sizeof(S) == 0);
153 
154  size_t fS = (sizeof(S) > sizeof(T)) ? sizeof(S) / sizeof(T) : 1;
155  size_t fT = (sizeof(S) < sizeof(T)) ? sizeof(T) / sizeof(S) : 1;
156 
157  samplesCount = std::min<size_t>(std::min<size_t>(samplesCount, source.getSize() / fT), target.getRemainingSize() / fS);
158 
159  std::unique_ptr<T[]> data(new T[samplesCount * fS]);
160  source.readSamples((S*) data.get(), samplesCount * fT, incrementPosition);
161  target.writeSamples(data.get(), samplesCount * fS, incrementPosition);
162 
163  return samplesCount;
164 }
165 
166 END_NAMESPACE_MEMORY
virtual void incrementReadPosition(size_t pos)=0
Function increments read position for N samples.
virtual std::recursive_mutex & getLock()=0
Function return locking object.
Basic source buffer interface.
Definition: buffer.h:25
std::lock_guard with compile time option to ignore locking
size_t transferBuffer(ISourceBuffer< T > &source, ITargetBuffer< T > &target, bool incrementPosition=true, size_t samplesCount=(std::numeric_limits< size_t >::max)())
Transferring data from one buffer to another.
Definition: buffer.h:118
Definition: lock_guard.h:29
virtual size_t getRemainingSize()=0
Function returns remaining size in samples.
virtual size_t getSize()=0
Function returns current buffer size in samples.
virtual void incrementWritePosition(size_t pos)=0
Function increments write position for N samples.
virtual size_t writeSamples(const T *samples, size_t samplesCount, bool incrementPosition=true)=0
Function pushes the samples into buffer.
virtual std::recursive_mutex & getLock()=0
Function return locking object.
virtual size_t readSamples(T *samples, size_t samplesCount, bool incrementPosition=true)=0
Function reads the samples from buffer.
Basic target buffer interface.
Definition: buffer.h:63