6 #ifndef _RNBO_DATAREF_H_
7 #define _RNBO_DATAREF_H_
18 #define RNBO_DEFAULT_SAMPLERATE 44100
61 bool operator==(
const DataType& rhs)
const
63 if (type != rhs.type)
return false;
70 return (audioBufferInfo.channels == rhs.audioBufferInfo.channels
71 && audioBufferInfo.samplerate == rhs.audioBufferInfo.samplerate);
77 bool operator!=(
const DataType& rhs)
const
79 return !operator==(rhs);
82 bool matches(
const DataType& rhs)
const
84 if (type ==
Untyped)
return false;
85 return type == rhs.type;
104 DataRef(DataRef&& other)
108 _sizeInBytes = other._sizeInBytes;
111 _touched = other._touched;
113 _internal = other._internal;
114 _index = other._index;
115 _requestedSizeInBytes = other._requestedSizeInBytes;
116 _allocatedSizeInBytes = other._allocatedSizeInBytes;
117 _deAlloc = other._deAlloc;
120 other._data =
nullptr;
121 other._sizeInBytes = 0;
122 other._deAlloc =
false;
123 other._name =
nullptr;
124 other._file =
nullptr;
125 other._requestedSizeInBytes = 0;
127 other._tag =
nullptr;
130 void operator=(
const DataRef& ref ) =
delete;
138 DataRef& operator=(DataRef&& other)
140 if (
this != &other) {
143 _sizeInBytes = other._sizeInBytes;
146 _touched = other._touched;
147 _deAlloc = other._deAlloc;
149 _internal = other._internal;
150 _index = other._index;
151 _requestedSizeInBytes = other._requestedSizeInBytes;
152 _allocatedSizeInBytes = other._allocatedSizeInBytes;
155 other._data =
nullptr;
156 other._sizeInBytes = 0;
157 other._deAlloc =
false;
158 other._name =
nullptr;
159 other._file =
nullptr;
160 other._requestedSizeInBytes = 0;
161 other._allocatedSizeInBytes = 0;
163 other._tag =
nullptr;
169 void operator=(DataRef& other)
171 if (
this != &other) {
174 _sizeInBytes = other._sizeInBytes;
177 _touched = other._touched;
178 _deAlloc = other._deAlloc;
180 _internal = other._internal;
181 _index = other._index;
182 _requestedSizeInBytes = other._requestedSizeInBytes;
183 _allocatedSizeInBytes = other._allocatedSizeInBytes;
186 other._data =
nullptr;
187 other._sizeInBytes = 0;
188 other._deAlloc =
false;
189 other._name =
nullptr;
190 other._file =
nullptr;
191 other._requestedSizeInBytes = 0;
192 other._allocatedSizeInBytes = 0;
194 other._tag =
nullptr;
198 DataRef* operator->() {
206 inline DataType getType()
const {
210 void setType(DataType type) {
214 inline const char *getName()
const {
218 void setName(
const char *name) {
219 if (name && Platform::strlen(name)) _name = name;
220 else _name =
nullptr;
223 inline const char *getFile()
const {
227 void setFile(
const char *file) {
228 if (file && Platform::strlen(file)) _file = file;
229 else _file =
nullptr;
232 inline char *getData() {
236 const char *getData()
const {
240 void setData(
char *data,
size_t sizeInBytes,
bool deAlloc =
false) {
244 _sizeInBytes = _allocatedSizeInBytes = sizeInBytes;
250 inline size_t getSizeInBytes()
const {
254 void requestSizeInBytes(
size_t size,
bool force) {
255 if (size > _requestedSizeInBytes || force) _requestedSizeInBytes = size;
258 bool hasRequestedSize()
const {
259 return _requestedSizeInBytes > 0;
262 void resetRequestedSizeInByte() {
263 _requestedSizeInBytes = 0;
266 inline bool getTouched()
const {
270 void setTouched(
bool value) {
274 void allocateIfNeeded() {
275 if (_requestedSizeInBytes) {
276 if (_requestedSizeInBytes > _allocatedSizeInBytes || !_deAlloc) {
277 auto oldData = _data;
278 _data =
static_cast<char *
>(Platform::calloc(_requestedSizeInBytes, 1));
279 if (_deAlloc && oldData) {
281 Platform::memcpy(_data, oldData, _sizeInBytes);
282 Platform::free(oldData);
290 _sizeInBytes = _allocatedSizeInBytes = _requestedSizeInBytes;
294 if (_requestedSizeInBytes > _sizeInBytes) {
295 Platform::memset(_data + _sizeInBytes, 0, _requestedSizeInBytes - _sizeInBytes);
298 _sizeInBytes = _requestedSizeInBytes;
303 void freeIfNeeded() {
304 if (_deAlloc && _data !=
nullptr) {
305 Platform::free(_data);
311 inline bool wantsFill()
const {
315 void setWantsFill(
bool value) {
319 inline const char *getTag()
const {
323 void setTag(
const char *tag) {
324 if (tag && Platform::strlen(tag)) _tag = tag;
328 void setInternal(
bool value) {
332 inline bool isInternal()
const {
337 Platform::memset(_data, 0, _sizeInBytes);
340 void setIndex(DataRefIndex index) {
349 const char* _name =
nullptr;
350 const char* _file =
nullptr;
351 const char* _tag =
nullptr;
353 size_t _sizeInBytes = 0;
354 size_t _requestedSizeInBytes = 0;
355 size_t _allocatedSizeInBytes = 0;
356 char *_data =
nullptr;
357 bool _touched =
false;
358 bool _deAlloc =
false;
359 bool _wantsFill =
false;
360 bool _internal =
false;
369 static inline DataRef& initDataRef(DataRef& ref,
const char *name,
bool internal,
const char* file,
const char* tag) {
371 ref.setInternal(
internal);
383 template<
typename... Ts> MultiDataRef(Ts & ... args)
384 : _count(sizeof ... (args))
386 _refs =
static_cast<DataRef**
>(Platform::malloc(_count *
sizeof(DataRef *)));
387 DataRef* refs[
sizeof...(args)] = {
static_cast<DataRef*
>(&args)...};
388 for (
size_t i = 0; i < _count; i++) {
393 MultiDataRef() =
default;
395 MultiDataRef(MultiDataRef&& other)
397 _count = other._count;
398 _current = other._current;
401 other._refs =
nullptr;
403 _index = other._index;
407 void operator=(
const MultiDataRef& ref ) =
delete;
409 MultiDataRef& operator=(MultiDataRef&& other)
411 if (
this != &other) {
412 _count = other._count;
413 _current = other._current;
416 other._refs =
nullptr;
418 _index = other._index;
424 void operator=(MultiDataRef& other)
426 if (
this != &other) {
427 _count = other._count;
428 _current = other._current;
431 other._refs =
nullptr;
433 _index = other._index;
440 Platform::free(_refs);
444 MultiDataRef* operator->() {
448 void setCurrent(DataRefIndex current) {
449 if (current >= 0 && current <
static_cast<DataRefIndex>(_count)) {
454 DataRef& getCurrent()
const {
455 return *_refs[_current];
462 void setIndex(DataRefIndex index) {
473 DataRef** _refs =
nullptr;
477 template<
typename ... Ts> MultiDataRef initMultiRef(Ts & ... args)
479 MultiDataRef ref(args...);
486 template<
typename T,
typename DR>
class DataView {
488 DataView(DR& dataRef)
495 virtual ~DataView() {}
497 inline T& operator[](
size_t i) {
498 T *values =
reinterpret_cast<T*
>(_dataRef->getData());
502 inline T operator[](
size_t i)
const {
503 T *values =
reinterpret_cast<T*
>(_dataRef->getData());
507 inline bool typeislockfree()
const {
508 #if defined(_MSC_VER)
510 #elif defined(__clang__) || defined(__GNUC__)
512 return __atomic_is_lock_free(
sizeof(T), &dummy);
514 #ifndef RNBO_NOSTDLIB
515 return std::atomic<T>{}.is_lock_free();
521 inline T atomicload(
const Index index,
int order = 5)
const {
522 if (index < getSize()) {
523 T *loc =
reinterpret_cast<T*
>(_dataRef->getData()) + index;
524 #if defined(__clang__) || defined(__GNUC__)
529 __atomic_load(loc, &ret, order);
531 #elif defined(_MSC_VER)
534 return InterlockedOr64(loc, 0);
536 return InterlockedOr(loc, 0);
538 return InterlockedOr16(loc, 0);
540 return InterlockedOr8(loc, 0);
552 inline void atomicstore(
const Index index, T value,
int order = 5) {
553 if (index < DataView<T, DR>::getSize()) {
554 T *loc =
reinterpret_cast<T*
>(_dataRef->getData()) + index;
555 #if defined(__clang__) || defined(__GNUC__)
558 __atomic_store(loc, &value, order);
559 #elif defined(_MSC_VER)
562 InterlockedExchange64(loc, value);
565 InterlockedExchange(loc, value);
568 InterlockedExchange16(loc, value);
571 InterlockedExchange8(loc, value);
583 DataView* operator->() {
587 const DataView* operator->()
const {
591 inline size_t getSize()
const {
595 virtual void updateCachedSize() {
596 _size = _dataRef->getSizeInBytes() /
sizeof(T);
599 inline DataType getType()
const {
600 return _dataRef->getType();
603 void setType(DataType type) {
604 _dataRef->setType(type);
608 inline size_t getSizeInBytes()
const {
609 return _dataRef->getSizeInBytes();
612 void setTouched(
bool value) {
613 _dataRef->setTouched(value);
617 return _dataRef->getTouched();
620 virtual DataView<T, DR>* allocateIfNeeded() {
621 _dataRef->allocateIfNeeded();
626 void setWantsFill(
bool value) {
627 _dataRef->setWantsFill(value);
631 _dataRef->setData(
nullptr, 0);
639 return _dataRef->getIndex();
644 virtual void reInit() {
650 void requestSize(
size_t size) {
651 size_t sizeInBytes = size *
sizeof(T);
652 _dataRef->requestSizeInBytes(sizeInBytes,
false);
656 virtual DataView<T, DR>* setSize(
size_t size) {
657 size_t sizeInBytes = size *
sizeof(T);
658 _dataRef->requestSizeInBytes(sizeInBytes,
true);
659 _dataRef->allocateIfNeeded();
664 void reInit(DR& dataRef) {
677 template<
typename T,
typename U>
class DataViewRef {
682 virtual ~DataViewRef()
687 DataViewRef(
const DataViewRef<T, U>& other)
689 other._view->_usage++;
701 void operator=(U* view )
708 void operator=(
const DataViewRef<T, U>& other)
710 if (&other !=
this) {
711 other._view->_usage++;
717 inline T& operator[](
size_t i) {
721 inline T operator[](
size_t i)
const {
732 if (!_view->_usage)
delete _view;
744 template<
typename T,
typename DR>
class OneDimensionalArray :
public DataView<T, DR>
747 OneDimensionalArray(DR& dataRef)
748 : DataView<T, DR>(dataRef)
752 DataView<T, DR>::setType(info);
755 void requestSize(
size_t size) {
756 DataView<T, DR>::requestSize(size);
759 inline size_t getChannels()
const {
763 inline number getSampleRate()
const {
767 virtual OneDimensionalArray<T, DR>* allocateIfNeeded()
override {
768 DataView<T, DR>::allocateIfNeeded();
772 inline T getSample(
const size_t ,
const size_t index)
const {
773 return DataView<T, DR>::operator[](index);
776 inline T getSampleSafe(
const long channel,
const long index)
const {
777 if (channel == 0 && index < DataView<T, DR>::getSize()) {
778 return DataView<T, DR>::operator[](index);
784 inline void setSample(
const size_t ,
const size_t index,
const T value) {
785 DataView<T, DR>::operator[](index) = value;
788 inline void setSampleSafe(
const long channel,
const long index,
const T value) {
789 if (channel == 0 && index < DataView<T, DR>::getSize()) {
790 DataView<T, DR>::operator[](index) = value;
794 OneDimensionalArray<T, DR>* setSize(
size_t size)
override {
795 DataView<T, DR>::setSize(size);
803 template<
typename T,
typename DR>
class InterleavedAudioBuffer :
public DataView<T, DR>
807 : DataView<T, DR>(dataRef)
812 info.audioBufferInfo.channels = 0;
813 info.audioBufferInfo.samplerate = RNBO_DEFAULT_SAMPLERATE;
814 DataView<T, DR>::setType(info);
820 virtual ~InterleavedAudioBuffer()
override {}
822 InterleavedAudioBuffer* operator->() {
826 inline T getSample(
const size_t channel,
const size_t index)
const {
827 if (!_audioData)
return 0;
828 return _audioData[_channels * index + channel];
831 inline T getSampleSafe(
const long channel,
const long index)
const {
832 if (!_audioData)
return 0;
833 const auto ind = _channels * index + channel;
834 if (ind < 0 ||
static_cast<size_t>(ind) >= DataView<T, DR>::getSize() * _channels) {
835 return static_cast<T
>(0);
837 return _audioData[ind];
841 inline void setSample(
const size_t channel,
const size_t index,
const T value) {
843 _audioData[_channels * index + channel] = value;
846 inline void setSampleSafe(
const long channel,
const long index,
const T value) {
847 if (channel < 0 ||
static_cast<size_t>(channel) >= _channels || index < 0 ||
static_cast<size_t>(index) >= DataView<T, DR>::getSize()) {
850 _audioData[_channels * index + channel] = value;
853 inline size_t getChannels()
const {
857 inline number getSampleRate()
const {
858 DataType info = DataView<T, DR>::getType();
859 return info.audioBufferInfo.samplerate;
862 void setSampleRate(number sampleRate) {
863 DataType info = DataView<T, DR>::getType();
864 info.audioBufferInfo.samplerate = sampleRate;
865 DataView<T, DR>::setType(info);
868 bool isInterleaved() {
873 void requestSize(
size_t size,
size_t channels) {
874 DataView<T, DR>::requestSize(size * channels);
875 _requestedChannels = channels;
878 InterleavedAudioBuffer<T, DR>* setSize(
size_t size)
override {
879 DataView<T, DR>::setSize(size * _channels);
883 void updateCachedSize()
override {
884 DataType info = DataView<T, DR>::getType();
885 _channels = info.audioBufferInfo.channels;
886 _audioData =
reinterpret_cast<T*
>(DataView<T, DR>::_dataRef->getData());
887 DataView<T, DR>::_size = _channels ? (DataView<T, DR>::getSizeInBytes() /
sizeof(T)) / _channels : 0;
890 virtual InterleavedAudioBuffer<T, DR>* setChannels(
size_t channels) {
891 if (channels != _channels) {
892 size_t currentSize = DataView<T, DR>::getSize();
894 DataType info = DataView<T, DR>::getType();
895 info.audioBufferInfo.channels = channels;
896 DataView<T, DR>::setType(info);
899 _channels = channels;
900 _audioData =
reinterpret_cast<T*
>(DataView<T, DR>::_dataRef->getData());
903 DataView<T, DR>::clear();
905 DataView<T, DR>::setSize(currentSize * _channels);
911 InterleavedAudioBuffer<T, DR>* allocateIfNeeded()
override {
912 if (_requestedChannels > 0) {
913 if (_channels != 0 && _requestedChannels != _channels) {
914 DataView<T, DR>::setZero();
917 DataType info = DataView<T, DR>::getType();
918 info.audioBufferInfo.channels = _requestedChannels;
919 DataView<T, DR>::setType(info);
921 DataView<T, DR>::allocateIfNeeded();
932 size_t _requestedChannels = 0;
933 size_t _channels = 0;
934 T* _audioData =
nullptr;
943 class Float32Buffer :
public InterleavedAudioBuffer<float, DataRef>
946 Float32Buffer(DataRef& dataRef)
947 : InterleavedAudioBuffer<float, DataRef>(dataRef, DataType::Float32AudioBuffer)
950 virtual Float32Buffer* allocateIfNeeded()
override {
951 InterleavedAudioBuffer<float, DataRef>::allocateIfNeeded();
955 virtual Float32Buffer* setChannels(
size_t channels)
override {
956 InterleavedAudioBuffer<float, DataRef>::setChannels(channels);
960 virtual Float32Buffer* setSize(
size_t size)
override {
961 InterleavedAudioBuffer<float, DataRef>::setSize(size);
966 using Float32BufferRef = DataViewRef<float, Float32Buffer >;
971 class Float64Buffer :
public InterleavedAudioBuffer<double, DataRef>
974 Float64Buffer(DataRef& dataRef)
975 : InterleavedAudioBuffer<double, DataRef>(dataRef, DataType::Float64AudioBuffer)
978 virtual Float64Buffer* allocateIfNeeded()
override {
979 InterleavedAudioBuffer<double, DataRef>::allocateIfNeeded();
983 virtual Float64Buffer* setChannels(
size_t channels)
override {
984 InterleavedAudioBuffer<double, DataRef>::setChannels(channels);
988 virtual Float64Buffer* setSize(
size_t size)
override {
989 InterleavedAudioBuffer<double, DataRef>::setSize(size);
994 using Float64BufferRef = DataViewRef<double, Float64Buffer>;
1000 class SampleBuffer :
public InterleavedAudioBuffer<SampleValue, DataRef>
1003 SampleBuffer(DataRef& dataRef)
1004 : InterleavedAudioBuffer<
SampleValue, DataRef>(dataRef, DataType::SampleAudioBuffer)
1007 virtual SampleBuffer* allocateIfNeeded()
override {
1008 InterleavedAudioBuffer<SampleValue, DataRef>::allocateIfNeeded();
1012 virtual SampleBuffer* setChannels(
size_t channels)
override {
1013 InterleavedAudioBuffer<SampleValue, DataRef>::setChannels(channels);
1017 virtual SampleBuffer* setSize(
size_t size)
override {
1018 InterleavedAudioBuffer<SampleValue, DataRef>::setSize(size);
1023 using SampleBufferRef = DataViewRef<SampleValue, SampleBuffer>;
1036 template <
typename T>
class MultiBuffer :
public InterleavedAudioBuffer<T, DataRef>
1040 : InterleavedAudioBuffer<T, DataRef>(multiRef.getCurrent(), type)
1041 , _multiRef(multiRef)
1044 void setCurrent(DataRefIndex current) {
1045 _multiRef.setCurrent(current);
1049 return _multiRef.getIndex();
1052 void reInit()
override {
1053 InterleavedAudioBuffer<T, DataRef>::reInit(_multiRef.getCurrent());
1057 return _multiRef.getCurrentIndex();
1061 MultiDataRef& _multiRef;
1067 class Float32MultiBuffer :
public MultiBuffer<float>
1070 Float32MultiBuffer(MultiDataRef& dataRef)
1071 : MultiBuffer<float>(dataRef, DataType::Float32AudioBuffer)
1075 using Float32MultiBufferRef = DataViewRef<float, Float32MultiBuffer >;
1080 class Float64MultiBuffer :
public MultiBuffer<double>
1083 Float64MultiBuffer(MultiDataRef& dataRef)
1084 : MultiBuffer<double>(dataRef, DataType::Float64AudioBuffer)
1088 using Float64MultiBufferRef = DataViewRef<double, Float64MultiBuffer>;
1091 using Int8Buffer = OneDimensionalArray<int8_t, DataRef>;
1092 using Int8BufferRef = DataViewRef<int8_t, Int8Buffer>;
1094 using UInt8Buffer = OneDimensionalArray<uint8_t, DataRef>;
1095 using UInt8BufferRef = DataViewRef<uint8_t, UInt8Buffer>;
1097 using Int32Buffer = OneDimensionalArray<int32_t, DataRef>;
1098 using Int32BufferRef = DataViewRef<int32_t, Int32Buffer>;
1100 using UInt32Buffer = OneDimensionalArray<uint32_t, DataRef>;
1101 using UInt32BufferRef = DataViewRef<uint32_t, UInt32Buffer>;
1103 using Int64Buffer = OneDimensionalArray<int64_t, DataRef>;
1104 using Int64BufferRef = DataViewRef<int64_t, Int64Buffer>;
1106 using UInt64Buffer = OneDimensionalArray<uint64_t, DataRef>;
1107 using UInt64BufferRef = DataViewRef<uint64_t, UInt64Buffer>;
1109 using IntBuffer = OneDimensionalArray<Int, DataRef>;
1110 using IntBufferRef = DataViewRef<Int, IntBuffer>;
1112 using UIntBuffer = OneDimensionalArray<UInt, DataRef>;
1113 using UIntBufferRef = DataViewRef<UInt, UIntBuffer>;
1134 audioBufferInfo.channels = channels;
1135 audioBufferInfo.samplerate = samplerate;
1148 audioBufferInfo.channels = channels;
1149 audioBufferInfo.samplerate = samplerate;
1158 template<
class T,
typename U>
void updateMultiRef(T patcher, U& ref,
DataRefIndex current)
1160 ref->setCurrent(current);
1161 patcher->getEngine()->sendDataRefUpdated(ref->getIndex());
1163 template<
typename T>
void updateMultiRef(T, Float32BufferRef&, DataRefIndex) {}
1164 template<
typename T>
void updateMultiRef(T, Float64BufferRef&, DataRefIndex) {}
1165 template<
typename T>
void updateMultiRef(T, SampleBufferRef&, DataRefIndex) {}
1167 template<
class T,
typename U>
void updateDataRef(T patcher, U& ref)
1169 patcher->getEngine()->sendDataRefUpdated(ref->getIndex());
1173 static DataRef& serializeDataRef(DataRef& ref) {
1174 ref.resetRequestedSizeInByte();
1178 template<
typename T,
typename U> T& reInitDataView(T& bufferRef, U&) {
1179 bufferRef->reInit();
1187 type = ref.getType();
1196 sizeInBytes = ref.getSizeInBytes();
1197 data = (uint8_t *)Platform::malloc(sizeInBytes);
1198 Platform::memcpy(data, ref.getData(), sizeInBytes);
1211 sizeInBytes = other.sizeInBytes;
1214 other.data =
nullptr;
1215 other.sizeInBytes = 0;
1222 sizeInBytes = other.sizeInBytes;
1223 data = (uint8_t*)Platform::malloc(sizeInBytes);
1224 Platform::memcpy(data, other.data, sizeInBytes);
1230 size_t sizeInBytes = 0;
1231 uint8_t* data =
nullptr;
1239 template<
class T>
void deserializeBuffer(T patcher, DataRef& dst,
const SerializedBuffer& src) {
1240 char* data = (
char *)Platform::malloc(src.sizeInBytes);
1241 Platform::memcpy(data, src.data, src.sizeInBytes);
1242 dst.setData(data, src.sizeInBytes,
true);
1243 dst.setType(src.type);
1244 patcher->getEngine()->sendDataRefUpdated(dst->getIndex());
1249 #endif // #ifndef _RNBO_DATAREF_H_