12-polyphonic "chiptune" MIDI synthesizer for LPC1768 (Standalone version)

Dependencies:   ClockControl PowerControl mbed

Committer:
kayekss
Date:
Tue Dec 23 21:50:53 2014 +0000
Revision:
6:cda45a5e723e
Parent:
0:727737138ac5
Supports "Panic on offline" feature when using MIDI-port input

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kayekss 0:727737138ac5 1 #ifndef RINGBUFFER_H_
kayekss 0:727737138ac5 2 #define RINGBUFFER_H_
kayekss 0:727737138ac5 3
kayekss 0:727737138ac5 4 #include <stdint.h>
kayekss 0:727737138ac5 5
kayekss 0:727737138ac5 6 template <class T>
kayekss 0:727737138ac5 7 class RingBuffer {
kayekss 0:727737138ac5 8 private:
kayekss 0:727737138ac5 9 uint32_t readPos;
kayekss 0:727737138ac5 10 uint32_t writePos;
kayekss 0:727737138ac5 11 uint32_t itemCount;
kayekss 0:727737138ac5 12 uint32_t length;
kayekss 0:727737138ac5 13 T* buffer;
kayekss 0:727737138ac5 14
kayekss 0:727737138ac5 15 public:
kayekss 0:727737138ac5 16 RingBuffer(uint32_t);
kayekss 0:727737138ac5 17 ~RingBuffer();
kayekss 0:727737138ac5 18 bool isWritable();
kayekss 0:727737138ac5 19 bool isReadable();
kayekss 0:727737138ac5 20 bool write(T&);
kayekss 0:727737138ac5 21 T* read();
kayekss 0:727737138ac5 22 T* peek();
kayekss 0:727737138ac5 23 void flush();
kayekss 0:727737138ac5 24 int find(T);
kayekss 0:727737138ac5 25
kayekss 0:727737138ac5 26 uint32_t getItemCount();
kayekss 0:727737138ac5 27 };
kayekss 0:727737138ac5 28
kayekss 0:727737138ac5 29 template <class T>
kayekss 0:727737138ac5 30 RingBuffer<T>::RingBuffer(uint32_t len) {
kayekss 0:727737138ac5 31 length = len;
kayekss 0:727737138ac5 32 buffer = new T[length];
kayekss 0:727737138ac5 33 readPos = 0;
kayekss 0:727737138ac5 34 writePos = 0;
kayekss 0:727737138ac5 35 itemCount = 0;
kayekss 0:727737138ac5 36 }
kayekss 0:727737138ac5 37
kayekss 0:727737138ac5 38 template <class T>
kayekss 0:727737138ac5 39 RingBuffer<T>::~RingBuffer() {
kayekss 0:727737138ac5 40 delete[] buffer;
kayekss 0:727737138ac5 41 }
kayekss 0:727737138ac5 42
kayekss 0:727737138ac5 43 template <class T>
kayekss 0:727737138ac5 44 bool RingBuffer<T>::isWritable() {
kayekss 0:727737138ac5 45 return itemCount < length;
kayekss 0:727737138ac5 46 }
kayekss 0:727737138ac5 47
kayekss 0:727737138ac5 48 template <class T>
kayekss 0:727737138ac5 49 bool RingBuffer<T>::isReadable() {
kayekss 0:727737138ac5 50 return itemCount > 0;
kayekss 0:727737138ac5 51 }
kayekss 0:727737138ac5 52
kayekss 0:727737138ac5 53 template <class T>
kayekss 0:727737138ac5 54 bool RingBuffer<T>::write(T& n) {
kayekss 0:727737138ac5 55 if (!isWritable()) {
kayekss 0:727737138ac5 56 return false;
kayekss 0:727737138ac5 57 }
kayekss 0:727737138ac5 58 buffer[writePos++] = n;
kayekss 0:727737138ac5 59 if (writePos == length) {
kayekss 0:727737138ac5 60 writePos = 0;
kayekss 0:727737138ac5 61 }
kayekss 0:727737138ac5 62 itemCount++;
kayekss 0:727737138ac5 63 return true;
kayekss 0:727737138ac5 64 }
kayekss 0:727737138ac5 65
kayekss 0:727737138ac5 66 template <class T>
kayekss 0:727737138ac5 67 T* RingBuffer<T>::read() {
kayekss 0:727737138ac5 68 uint32_t readPosTemp = readPos;
kayekss 0:727737138ac5 69
kayekss 0:727737138ac5 70 if (!isReadable()) {
kayekss 0:727737138ac5 71 return NULL;
kayekss 0:727737138ac5 72 }
kayekss 0:727737138ac5 73 readPos++;
kayekss 0:727737138ac5 74 if (readPos == length) {
kayekss 0:727737138ac5 75 readPos = 0;
kayekss 0:727737138ac5 76 }
kayekss 0:727737138ac5 77 itemCount--;
kayekss 0:727737138ac5 78 return &buffer[readPosTemp];
kayekss 0:727737138ac5 79 }
kayekss 0:727737138ac5 80
kayekss 0:727737138ac5 81 template <class T>
kayekss 0:727737138ac5 82 T* RingBuffer<T>::peek() {
kayekss 0:727737138ac5 83 if (!isReadable()) {
kayekss 0:727737138ac5 84 return NULL;
kayekss 0:727737138ac5 85 }
kayekss 0:727737138ac5 86 return &buffer[readPos];
kayekss 0:727737138ac5 87 }
kayekss 0:727737138ac5 88
kayekss 0:727737138ac5 89 template <class T>
kayekss 0:727737138ac5 90 void RingBuffer<T>::flush() {
kayekss 0:727737138ac5 91 itemCount = 0;
kayekss 0:727737138ac5 92 readPos = writePos;
kayekss 0:727737138ac5 93 }
kayekss 0:727737138ac5 94
kayekss 0:727737138ac5 95 template <class T>
kayekss 0:727737138ac5 96 int RingBuffer<T>::find(T key) {
kayekss 0:727737138ac5 97 uint32_t p = readPos;
kayekss 0:727737138ac5 98
kayekss 0:727737138ac5 99 for (uint32_t i = 0; i < itemCount; i++) {
kayekss 0:727737138ac5 100 if (buffer[p] == key) {
kayekss 0:727737138ac5 101 return i;
kayekss 0:727737138ac5 102 }
kayekss 0:727737138ac5 103 p++;
kayekss 0:727737138ac5 104 if (p == length) p = 0;
kayekss 0:727737138ac5 105 }
kayekss 0:727737138ac5 106 return -1;
kayekss 0:727737138ac5 107 }
kayekss 0:727737138ac5 108
kayekss 0:727737138ac5 109 template <class T>
kayekss 0:727737138ac5 110 uint32_t RingBuffer<T>::getItemCount() {
kayekss 0:727737138ac5 111 return this->itemCount;
kayekss 0:727737138ac5 112 }
kayekss 0:727737138ac5 113
kayekss 0:727737138ac5 114 #endif