1 /** 2 * Copyright 2017 Cut Through Recordings 3 * License: MIT License 4 * Author(s): Ethan Reker 5 */ 6 module ddsp.util.buffer; 7 8 import core.stdc.stdlib; 9 10 /// Just a simple generic circular buffer. Should fulfill the needs of most 11 /// simple delaying tasks. 12 class Buffer(T) 13 { 14 public: 15 nothrow: 16 @nogc: 17 18 this(const size_t size) 19 { 20 _maxSize = size; 21 mallocBuffer(_maxSize); 22 _currentSize = _maxSize; 23 _writeIndex = _currentSize - 1; 24 _readIndex = 0; 25 } 26 27 /// Gets the element from the buffer at the current read index, and 28 /// increments the read index. 29 T read() 30 { 31 T element = _buffer[_readIndex]; 32 incrementIndex(_readIndex); 33 return element; 34 } 35 36 /// Assign the buffer element at the current write index to element and 37 /// increment the write index. 38 void write(const T element) 39 { 40 _buffer[_writeIndex] = element; 41 incrementIndex(_writeIndex); 42 } 43 44 /// Resize the buffer. If the new size is larger than the max size, the buffer 45 /// will be reallocated so that size is the new maximum size. It is very 46 /// inefficient to delete and allocate large amounts of memory like this so 47 /// it is recommended to give the buffer an initial max size that will never 48 /// be exceeded. 49 void setSize(const size_t size) 50 { 51 if(size > _maxSize) 52 { 53 _maxSize = size; 54 mallocBuffer(_maxSize); 55 _currentSize = _maxSize; 56 } 57 else 58 { 59 _currentSize = _maxSize; 60 } 61 _writeIndex = _currentSize - 1; 62 _readIndex = 0; 63 } 64 65 private: 66 /// The size that the buffer is originally set to. 67 size_t _maxSize; 68 69 /// The size that the buffer is currently set to. 70 size_t _currentSize; 71 72 /// Array that holds the elements 73 T* _buffer; 74 75 /// Points to the current sample to be read from 76 size_t _readIndex; 77 78 /// Points to the current sample to be written to 79 size_t _writeIndex; 80 81 /// Takes an index and increments it by 1, if it exceeds the size of the buffer 82 /// it will be wrapped around to 0. 83 void incrementIndex(ref size_t index) 84 { 85 if(++index >= _maxSize) 86 index = 0; 87 } 88 89 void mallocBuffer(const size_t bufferSize) 90 { 91 if(_buffer) 92 free(_buffer); 93 94 _buffer = cast(T*) malloc(bufferSize * T.sizeof); 95 foreach(element; 0..bufferSize) 96 _buffer[element] = cast(T) 0; 97 } 98 }