6 #ifndef _RNBO_DATAREF_H_
7 #define _RNBO_DATAREF_H_
14 #define RNBO_DEFAULT_SAMPLERATE 44100
57 bool operator==(
const DataType& rhs)
const
59 if (type != rhs.type)
return false;
66 return (audioBufferInfo.channels == rhs.audioBufferInfo.channels
67 && audioBufferInfo.samplerate == rhs.audioBufferInfo.samplerate);
73 bool operator!=(
const DataType& rhs)
const
75 return !operator==(rhs);
78 bool matches(
const DataType& rhs)
const
80 if (type ==
Untyped)
return false;
81 return type == rhs.type;
100 DataRef(DataRef&& other)
104 _sizeInBytes = other._sizeInBytes;
107 _touched = other._touched;
109 _internal = other._internal;
110 _index = other._index;
111 _requestedSizeInBytes = other._requestedSizeInBytes;
112 _allocatedSizeInBytes = other._allocatedSizeInBytes;
113 _deAlloc = other._deAlloc;
116 other._data =
nullptr;
117 other._sizeInBytes = 0;
118 other._deAlloc =
false;
119 other._name =
nullptr;
120 other._file =
nullptr;
121 other._requestedSizeInBytes = 0;
123 other._tag =
nullptr;
126 void operator=(
const DataRef& ref ) =
delete;
134 DataRef& operator=(DataRef&& other)
136 if (
this != &other) {
139 _sizeInBytes = other._sizeInBytes;
142 _touched = other._touched;
143 _deAlloc = other._deAlloc;
145 _internal = other._internal;
146 _index = other._index;
147 _requestedSizeInBytes = other._requestedSizeInBytes;
148 _allocatedSizeInBytes = other._allocatedSizeInBytes;
151 other._data =
nullptr;
152 other._sizeInBytes = 0;
153 other._deAlloc =
false;
154 other._name =
nullptr;
155 other._file =
nullptr;
156 other._requestedSizeInBytes = 0;
157 other._allocatedSizeInBytes = 0;
159 other._tag =
nullptr;
165 void operator=(DataRef& other)
167 if (
this != &other) {
170 _sizeInBytes = other._sizeInBytes;
173 _touched = other._touched;
174 _deAlloc = other._deAlloc;
176 _internal = other._internal;
177 _index = other._index;
178 _requestedSizeInBytes = other._requestedSizeInBytes;
179 _allocatedSizeInBytes = other._allocatedSizeInBytes;
182 other._data =
nullptr;
183 other._sizeInBytes = 0;
184 other._deAlloc =
false;
185 other._name =
nullptr;
186 other._file =
nullptr;
187 other._requestedSizeInBytes = 0;
188 other._allocatedSizeInBytes = 0;
190 other._tag =
nullptr;
194 DataRef* operator->() {
202 inline DataType getType()
const {
206 void setType(DataType type) {
210 inline const char *getName()
const {
214 void setName(
const char *name) {
215 if (name && Platform::strlen(name)) _name = name;
216 else _name =
nullptr;
219 inline const char *getFile()
const {
223 void setFile(
const char *file) {
224 if (file && Platform::strlen(file)) _file = file;
225 else _file =
nullptr;
228 inline char *getData() {
232 const char *getData()
const {
236 void setData(
char *data,
size_t sizeInBytes,
bool deAlloc =
false) {
240 _sizeInBytes = _allocatedSizeInBytes = sizeInBytes;
246 inline size_t getSizeInBytes()
const {
250 void requestSizeInBytes(
size_t size,
bool force) {
251 if (size > _requestedSizeInBytes || force) _requestedSizeInBytes = size;
254 bool hasRequestedSize()
const {
255 return _requestedSizeInBytes > 0;
258 void resetRequestedSizeInByte() {
259 _requestedSizeInBytes = 0;
262 inline bool getTouched()
const {
266 void setTouched(
bool value) {
270 void allocateIfNeeded() {
271 if (_requestedSizeInBytes) {
272 if (_requestedSizeInBytes > _allocatedSizeInBytes || !_deAlloc) {
273 auto oldData = _data;
274 _data =
static_cast<char *
>(Platform::calloc(_requestedSizeInBytes, 1));
275 if (_deAlloc && oldData) {
277 Platform::memcpy(_data, oldData, _sizeInBytes);
278 Platform::free(oldData);
286 _sizeInBytes = _allocatedSizeInBytes = _requestedSizeInBytes;
290 if (_requestedSizeInBytes > _sizeInBytes) {
291 Platform::memset(_data + _sizeInBytes, 0, _requestedSizeInBytes - _sizeInBytes);
294 _sizeInBytes = _requestedSizeInBytes;
299 void freeIfNeeded() {
300 if (_deAlloc && _data !=
nullptr) {
301 Platform::free(_data);
307 inline bool wantsFill()
const {
311 void setWantsFill(
bool value) {
315 inline const char *getTag()
const {
319 void setTag(
const char *tag) {
320 if (tag && Platform::strlen(tag)) _tag = tag;
324 void setInternal(
bool value) {
328 inline bool isInternal()
const {
333 Platform::memset(_data, 0, _sizeInBytes);
336 void setIndex(DataRefIndex index) {
345 const char* _name =
nullptr;
346 const char* _file =
nullptr;
347 const char* _tag =
nullptr;
349 size_t _sizeInBytes = 0;
350 size_t _requestedSizeInBytes = 0;
351 size_t _allocatedSizeInBytes = 0;
352 char *_data =
nullptr;
353 bool _touched =
false;
354 bool _deAlloc =
false;
355 bool _wantsFill =
false;
356 bool _internal =
false;
365 static inline DataRef& initDataRef(DataRef& ref,
const char *name,
bool internal,
const char* file,
const char* tag) {
367 ref.setInternal(
internal);
379 template<
typename... Ts> MultiDataRef(Ts & ... args)
380 : _count(sizeof ... (args))
382 _refs =
static_cast<DataRef**
>(Platform::malloc(_count *
sizeof(DataRef *)));
383 DataRef* refs[
sizeof...(args)] = {
static_cast<DataRef*
>(&args)...};
384 for (
size_t i = 0; i < _count; i++) {
389 MultiDataRef() =
default;
391 MultiDataRef(MultiDataRef&& other)
393 _count = other._count;
394 _current = other._current;
397 other._refs =
nullptr;
399 _index = other._index;
403 void operator=(
const MultiDataRef& ref ) =
delete;
405 MultiDataRef& operator=(MultiDataRef&& other)
407 if (
this != &other) {
408 _count = other._count;
409 _current = other._current;
412 other._refs =
nullptr;
414 _index = other._index;
420 void operator=(MultiDataRef& other)
422 if (
this != &other) {
423 _count = other._count;
424 _current = other._current;
427 other._refs =
nullptr;
429 _index = other._index;
436 Platform::free(_refs);
440 MultiDataRef* operator->() {
444 void setCurrent(DataRefIndex current) {
445 if (current >= 0 && current <
static_cast<DataRefIndex>(_count)) {
450 DataRef& getCurrent()
const {
451 return *_refs[_current];
458 void setIndex(DataRefIndex index) {
469 DataRef** _refs =
nullptr;
473 template<
typename ... Ts> MultiDataRef initMultiRef(Ts & ... args)
475 MultiDataRef ref(args...);
482 template<
typename T,
typename DR>
class DataView {
484 DataView(DR& dataRef)
491 virtual ~DataView() {}
493 inline T& operator[](
size_t i) {
494 T *values =
reinterpret_cast<T*
>(_dataRef->getData());
498 inline T operator[](
size_t i)
const {
499 T *values =
reinterpret_cast<T*
>(_dataRef->getData());
503 DataView* operator->() {
507 const DataView* operator->()
const {
511 inline size_t getSize()
const {
515 virtual void updateCachedSize() {
516 _size = _dataRef->getSizeInBytes() /
sizeof(T);
519 inline DataType getType()
const {
520 return _dataRef->getType();
523 void setType(DataType type) {
524 _dataRef->setType(type);
528 inline size_t getSizeInBytes()
const {
529 return _dataRef->getSizeInBytes();
532 void setTouched(
bool value) {
533 _dataRef->setTouched(value);
537 return _dataRef->getTouched();
540 virtual DataView<T, DR>* allocateIfNeeded() {
541 _dataRef->allocateIfNeeded();
546 void setWantsFill(
bool value) {
547 _dataRef->setWantsFill(value);
551 _dataRef->setData(
nullptr, 0);
559 return _dataRef->getIndex();
564 virtual void reInit() {
570 void requestSize(
size_t size) {
571 size_t sizeInBytes = size *
sizeof(T);
572 _dataRef->requestSizeInBytes(sizeInBytes,
false);
576 virtual DataView<T, DR>* setSize(
size_t size) {
577 size_t sizeInBytes = size *
sizeof(T);
578 _dataRef->requestSizeInBytes(sizeInBytes,
true);
579 _dataRef->allocateIfNeeded();
584 void reInit(DR& dataRef) {
597 template<
typename T,
typename U>
class DataViewRef {
602 virtual ~DataViewRef()
607 DataViewRef(
const DataViewRef<T, U>& other)
609 other._view->_usage++;
621 void operator=(U* view )
628 void operator=(
const DataViewRef<T, U>& other)
630 if (&other !=
this) {
631 other._view->_usage++;
637 inline T& operator[](
size_t i) {
641 inline T operator[](
size_t i)
const {
652 if (!_view->_usage)
delete _view;
664 template<
typename T,
typename DR>
class OneDimensionalArray :
public DataView<T, DR>
667 OneDimensionalArray(DR& dataRef)
668 : DataView<T, DR>(dataRef)
672 DataView<T, DR>::setType(info);
675 void requestSize(
size_t size) {
676 DataView<T, DR>::requestSize(size);
683 template<
typename T,
typename DR>
class InterleavedAudioBuffer :
public DataView<T, DR>
687 : DataView<T, DR>(dataRef)
692 info.audioBufferInfo.channels = 0;
693 info.audioBufferInfo.samplerate = RNBO_DEFAULT_SAMPLERATE;
694 DataView<T, DR>::setType(info);
700 virtual ~InterleavedAudioBuffer()
override {}
702 InterleavedAudioBuffer* operator->() {
706 inline T getSample(
const size_t channel,
const size_t index)
const {
707 if (!_audioData)
return 0;
708 return _audioData[_channels * index + channel];
711 inline T getSampleSafe(
const long channel,
const long index)
const {
712 if (!_audioData)
return 0;
713 const auto ind = _channels * index + channel;
714 if (ind < 0 ||
static_cast<size_t>(ind) >= DataView<T, DR>::getSize() * _channels) {
715 return static_cast<T
>(0);
717 return _audioData[ind];
721 inline void setSample(
const size_t channel,
const size_t index,
const T value) {
723 _audioData[_channels * index + channel] = value;
726 inline void setSampleSafe(
const long channel,
const long index,
const T value) {
727 if (channel < 0 ||
static_cast<size_t>(channel) >= _channels || index < 0 ||
static_cast<size_t>(index) >= DataView<T, DR>::getSize()) {
730 _audioData[_channels * index + channel] = value;
733 inline size_t getChannels()
const {
737 inline number getSampleRate()
const {
738 DataType info = DataView<T, DR>::getType();
739 return info.audioBufferInfo.samplerate;
742 void setSampleRate(number sampleRate) {
743 DataType info = DataView<T, DR>::getType();
744 info.audioBufferInfo.samplerate = sampleRate;
745 DataView<T, DR>::setType(info);
748 bool isInterleaved() {
753 void requestSize(
size_t size,
size_t channels) {
754 DataView<T, DR>::requestSize(size * channels);
755 _requestedChannels = channels;
758 InterleavedAudioBuffer<T, DR>* setSize(
size_t size)
override {
759 DataView<T, DR>::setSize(size * _channels);
763 void updateCachedSize()
override {
764 DataType info = DataView<T, DR>::getType();
765 _channels = info.audioBufferInfo.channels;
766 _audioData =
reinterpret_cast<T*
>(DataView<T, DR>::_dataRef->getData());
767 DataView<T, DR>::_size = _channels ? (DataView<T, DR>::getSizeInBytes() /
sizeof(T)) / _channels : 0;
770 virtual InterleavedAudioBuffer<T, DR>* setChannels(
size_t channels) {
771 if (channels != _channels) {
772 size_t currentSize = DataView<T, DR>::getSize();
774 DataType info = DataView<T, DR>::getType();
775 info.audioBufferInfo.channels = channels;
776 DataView<T, DR>::setType(info);
779 _channels = channels;
780 _audioData =
reinterpret_cast<T*
>(DataView<T, DR>::_dataRef->getData());
783 DataView<T, DR>::clear();
785 DataView<T, DR>::setSize(currentSize * _channels);
791 InterleavedAudioBuffer<T, DR>* allocateIfNeeded()
override {
792 if (_requestedChannels > 0) {
793 if (_channels != 0 && _requestedChannels != _channels) {
794 DataView<T, DR>::setZero();
797 DataType info = DataView<T, DR>::getType();
798 info.audioBufferInfo.channels = _requestedChannels;
799 DataView<T, DR>::setType(info);
801 DataView<T, DR>::allocateIfNeeded();
812 size_t _requestedChannels = 0;
813 size_t _channels = 0;
814 T* _audioData =
nullptr;
823 class Float32Buffer :
public InterleavedAudioBuffer<float, DataRef>
826 Float32Buffer(DataRef& dataRef)
827 : InterleavedAudioBuffer<float, DataRef>(dataRef, DataType::Float32AudioBuffer)
830 virtual Float32Buffer* allocateIfNeeded() {
831 InterleavedAudioBuffer<float, DataRef>::allocateIfNeeded();
835 virtual Float32Buffer* setChannels(
size_t channels) {
836 InterleavedAudioBuffer<float, DataRef>::setChannels(channels);
840 virtual Float32Buffer* setSize(
size_t size) {
841 InterleavedAudioBuffer<float, DataRef>::setSize(size);
846 using Float32BufferRef = DataViewRef<float, Float32Buffer >;
851 class Float64Buffer :
public InterleavedAudioBuffer<double, DataRef>
854 Float64Buffer(DataRef& dataRef)
855 : InterleavedAudioBuffer<double, DataRef>(dataRef, DataType::Float64AudioBuffer)
858 virtual Float64Buffer* allocateIfNeeded() {
859 InterleavedAudioBuffer<double, DataRef>::allocateIfNeeded();
863 virtual Float64Buffer* setChannels(
size_t channels) {
864 InterleavedAudioBuffer<double, DataRef>::setChannels(channels);
868 virtual Float64Buffer* setSize(
size_t size) {
869 InterleavedAudioBuffer<double, DataRef>::setSize(size);
874 using Float64BufferRef = DataViewRef<double, Float64Buffer>;
880 class SampleBuffer :
public InterleavedAudioBuffer<SampleValue, DataRef>
883 SampleBuffer(DataRef& dataRef)
884 : InterleavedAudioBuffer<
SampleValue, DataRef>(dataRef, DataType::SampleAudioBuffer)
887 virtual SampleBuffer* allocateIfNeeded() {
888 InterleavedAudioBuffer<SampleValue, DataRef>::allocateIfNeeded();
892 virtual SampleBuffer* setChannels(
size_t channels) {
893 InterleavedAudioBuffer<SampleValue, DataRef>::setChannels(channels);
897 virtual SampleBuffer* setSize(
size_t size) {
898 InterleavedAudioBuffer<SampleValue, DataRef>::setSize(size);
903 using SampleBufferRef = DataViewRef<SampleValue, SampleBuffer>;
916 template <
typename T>
class MultiBuffer :
public InterleavedAudioBuffer<T, DataRef>
920 : InterleavedAudioBuffer<T, DataRef>(multiRef.getCurrent(), type)
921 , _multiRef(multiRef)
924 void setCurrent(DataRefIndex current) {
925 _multiRef.setCurrent(current);
929 return _multiRef.getIndex();
932 void reInit()
override {
933 InterleavedAudioBuffer<T, DataRef>::reInit(_multiRef.getCurrent());
937 return _multiRef.getCurrentIndex();
941 MultiDataRef& _multiRef;
947 class Float32MultiBuffer :
public MultiBuffer<float>
950 Float32MultiBuffer(MultiDataRef& dataRef)
951 : MultiBuffer<float>(dataRef, DataType::Float32AudioBuffer)
955 using Float32MultiBufferRef = DataViewRef<float, Float32MultiBuffer >;
960 class Float64MultiBuffer :
public MultiBuffer<double>
963 Float64MultiBuffer(MultiDataRef& dataRef)
964 : MultiBuffer<double>(dataRef, DataType::Float64AudioBuffer)
968 using Float64MultiBufferRef = DataViewRef<double, Float64MultiBuffer>;
973 class IntBuffer :
public OneDimensionalArray<uint32_t, DataRef>
976 IntBuffer(DataRef& dataRef)
977 : OneDimensionalArray<uint32_t, DataRef>(dataRef)
980 virtual IntBuffer* allocateIfNeeded() {
981 OneDimensionalArray<uint32_t, DataRef>::allocateIfNeeded();
986 using IntBufferRef = DataViewRef<uint32_t, IntBuffer>;
991 class UInt8Buffer :
public OneDimensionalArray<uint8_t, DataRef>
994 UInt8Buffer(DataRef& dataRef)
995 : OneDimensionalArray<uint8_t, DataRef>(dataRef)
998 virtual UInt8Buffer* allocateIfNeeded() {
999 OneDimensionalArray<uint8_t, DataRef>::allocateIfNeeded();
1004 using UInt8BufferRef = DataViewRef<uint8_t, UInt8Buffer>;
1024 audioBufferInfo.channels = channels;
1025 audioBufferInfo.samplerate = samplerate;
1038 audioBufferInfo.channels = channels;
1039 audioBufferInfo.samplerate = samplerate;
1048 template<
class T,
typename U>
void updateMultiRef(T patcher, U& ref,
DataRefIndex current)
1050 ref->setCurrent(current);
1051 patcher->getEngine()->sendDataRefUpdated(ref->getIndex());
1053 template<
typename T>
void updateMultiRef(T, Float32BufferRef&, DataRefIndex) {}
1054 template<
typename T>
void updateMultiRef(T, Float64BufferRef&, DataRefIndex) {}
1055 template<
typename T>
void updateMultiRef(T, SampleBufferRef&, DataRefIndex) {}
1057 template<
class T,
typename U>
void updateDataRef(T patcher, U& ref)
1059 patcher->getEngine()->sendDataRefUpdated(ref->getIndex());
1063 static DataRef& serializeDataRef(DataRef& ref) {
1064 ref.resetRequestedSizeInByte();
1068 template<
typename T,
typename U> T& reInitDataView(T& bufferRef, U&) {
1069 bufferRef->reInit();
1077 type = ref.getType();
1086 sizeInBytes = ref.getSizeInBytes();
1087 data = (uint8_t *)Platform::malloc(sizeInBytes);
1088 Platform::memcpy(data, ref.getData(), sizeInBytes);
1101 sizeInBytes = other.sizeInBytes;
1104 other.data =
nullptr;
1105 other.sizeInBytes = 0;
1112 sizeInBytes = other.sizeInBytes;
1113 data = (uint8_t*)Platform::malloc(sizeInBytes);
1114 Platform::memcpy(data, other.data, sizeInBytes);
1120 size_t sizeInBytes = 0;
1121 uint8_t* data =
nullptr;
1129 template<
class T>
void deserializeBuffer(T patcher, DataRef& dst,
const SerializedBuffer& src) {
1130 char* data = (
char *)Platform::malloc(src.sizeInBytes);
1131 Platform::memcpy(data, src.data, src.sizeInBytes);
1132 dst.setData(data, src.sizeInBytes,
true);
1133 dst.setType(src.type);
1134 patcher->getEngine()->sendDataRefUpdated(dst->getIndex());
1139 #endif // #ifndef _RNBO_DATAREF_H_