• Main Page
  • Classes
  • Files
  • File List

jackringbuffer.hpp

00001 //C++ Classes that wrap JACK
00002 //Copyright 2007 Alex Norman
00003 //
00004 //This file is part of JACKC++.
00005 //
00006 //JACKC++ is free software: you can redistribute it and/or modify
00007 //it under the terms of the GNU General Public License as published by
00008 //the Free Software Foundation, either version 3 of the License, or
00009 //(at your option) any later version.
00010 //
00011 //JACKC++ is distributed in the hope that it will be useful,
00012 //but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //GNU General Public License for more details.
00015 //
00016 //You should have received a copy of the GNU General Public License
00017 //along with JACKC++.  If not, see <http://www.gnu.org/licenses/>.
00018 
00019 #ifndef JACK_RING_BUFFER_CLASS_H
00020 #define JACK_RING_BUFFER_CLASS_H
00021 
00022 #ifndef NULL
00023 #define NULL 0
00024 #endif
00025 
00026 extern "C" {
00027 #include <jack/ringbuffer.h>
00028 }
00029 #include <string.h>
00030 
00031 namespace JackCpp {
00032 
00033 template<typename Type>
00034 
00051         class RingBuffer {
00052                 private:
00053                         jack_ringbuffer_t *mRingBufferPtr;
00054                         size_t mLength;
00055                 public:
00061                         RingBuffer(size_t size, bool mlock = false){
00062                                 mLength = size;
00063                                 mRingBufferPtr = jack_ringbuffer_create(mLength * sizeof(Type));
00064 
00065                                 //should we lock the memory for the ring buffer?
00066                                 if(mlock)
00067                                         jack_ringbuffer_mlock(mRingBufferPtr);
00068                         }
00070                         ~RingBuffer(){
00071                                 if(mRingBufferPtr != NULL)
00072                                         jack_ringbuffer_free(mRingBufferPtr);
00073                         }
00074 
00076                         size_t length(){
00077                                 return mLength;
00078                         }
00079 
00081                         size_t getReadSpace(){ 
00082                                 return jack_ringbuffer_read_space(mRingBufferPtr) / sizeof(Type);
00083                         }
00084 
00086                         size_t getWriteSpace(){
00087                                 return jack_ringbuffer_write_space(mRingBufferPtr) / sizeof(Type);
00088                         }
00089                         
00097                         void read(Type &dest){
00098                                 if(getReadSpace() <= 0){
00099                                         //throw error!!!!
00100                                         return;
00101                                 }
00102                                 jack_ringbuffer_read(mRingBufferPtr, (char *)&dest, sizeof(Type));
00103                         }
00104 
00113                         void read(Type *dest, unsigned cnt){
00114                                 jack_ringbuffer_data_t readVec[2];
00115                                 unsigned int read_size = sizeof(Type) * cnt;
00116                                 if(getReadSpace() <= 0){
00117                                         //throw error!!!!
00118                                         return;
00119                                 }
00120 
00121                                 //get the readvector
00122                                 jack_ringbuffer_get_read_vector(mRingBufferPtr, readVec);
00123 
00124                                 //if the first vector has enough data then just read from there
00125                                 if(readVec[0].len >= read_size){
00126                                         memcpy(dest, readVec[0].buf, read_size);
00127                                 } else {
00128                                         //if the first vector is zero length then read from the second
00129                                         if(readVec[0].len == 0){
00130                                                 memcpy(dest, readVec[1].buf, read_size);
00131                                         } else {
00132                                                 //this gets tricky
00133                                                 char * byterep = (char *)dest;
00134                                                 //first read the data out of the first vector
00135                                                 memcpy(byterep, readVec[0].buf, readVec[0].len);
00136                                                 //then read the rest out of the second
00137                                                 memcpy(byterep + readVec[0].len, readVec[1].buf, read_size - readVec[0].len);
00138                                         }
00139                                 }
00140                                 //advance the read pointer
00141                                 jack_ringbuffer_read_advance(mRingBufferPtr, read_size);
00142                         }
00143                         
00149                         void write(Type src){
00150                                 if(getWriteSpace() <= 0){
00151                                         //throw error!!!!
00152                                         return;
00153                                 }
00154                                 jack_ringbuffer_write(mRingBufferPtr, (char *)&src, sizeof(Type));
00155                         }
00156 
00163                         void write(Type *src, unsigned int cnt){
00164                                 jack_ringbuffer_data_t writeVec[2];
00165                                 unsigned int write_size = sizeof(Type) * cnt;
00166                                 if(cnt > getWriteSpace()){
00167                                         //throw error!!!!
00168                                         return;
00169                                 }
00170 
00171                                 //get the write vector
00172                                 jack_ringbuffer_get_write_vector(mRingBufferPtr, writeVec);
00173                                 //if there is enough room in the first vector then just write there
00174                                 if(writeVec[0].len >= write_size){
00175                                         memcpy(writeVec[0].buf,src,write_size);
00176                                 } else {
00177                                         //if there is no room in the first vector then write into the second
00178                                         if(writeVec[0].len == 0){
00179                                                 memcpy(writeVec[1].buf,src,write_size);
00180                                         } else {
00181                                                 //this is more tricky, we have to split the data up
00182                                                 char * byterep = (char *)src;
00183                                                 //copy the first chunck
00184                                                 memcpy(writeVec[0].buf, byterep, writeVec[0].len);
00185                                                 //copy the second chunck
00186                                                 memcpy(writeVec[1].buf, byterep + writeVec[0].len, write_size - writeVec[0].len);
00187                                         }
00188                                 }
00189                                 jack_ringbuffer_write_advance(mRingBufferPtr, write_size);
00190                         }
00191 
00198                         void reset(){
00199                                 jack_ringbuffer_reset(mRingBufferPtr);
00200                         }
00201         };
00202 
00203 }
00204 
00205 #endif

Generated on Wed Apr 20 2011 13:46:10 for JackCpp by  doxygen 1.7.1