1 #include "OISConfig.h" 2 #ifdef OIS_LIRC_SUPPORT 3 /* 4 The zlib/libpng License 5 6 Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com) 7 8 This software is provided 'as-is', without any express or implied warranty. In no event will 9 the authors be held liable for any damages arising from the use of this software. 10 11 Permission is granted to anyone to use this software for any purpose, including commercial 12 applications, and to alter it and redistribute it freely, subject to the following 13 restrictions: 14 15 1. The origin of this software must not be misrepresented; you must not claim that 16 you wrote the original software. If you use this software in a product, 17 an acknowledgment in the product documentation would be appreciated but is 18 not required. 19 20 2. Altered source versions must be plainly marked as such, and must not be 21 misrepresented as being the original software. 22 23 3. This notice may not be removed or altered from any source distribution. 24 25 # ------------------------# 26 # Original License follows: 27 # ------------------------# 28 29 * PortAudio Portable Real-Time Audio Library 30 * Latest version at: http://www.audiomulch.com/portaudio/ 31 * <platform> Implementation 32 * Copyright (c) 1999-2000 <author(s)> 33 * 34 * Permission is hereby granted, free of charge, to any person obtaining 35 * a copy of this software and associated documentation files 36 * (the "Software"), to deal in the Software without restriction, 37 * including without limitation the rights to use, copy, modify, merge, 38 * publish, distribute, sublicense, and/or sell copies of the Software, 39 * and to permit persons to whom the Software is furnished to do so, 40 * subject to the following conditions: 41 * 42 * The above copyright notice and this permission notice shall be 43 * included in all copies or substantial portions of the Software. 44 * 45 * Any person wishing to distribute modifications to the Software is 46 * requested to send the modifications to the original developer so that 47 * they can be incorporated into the canonical version. 48 * 49 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 50 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 51 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 52 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 53 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 54 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 55 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 56 */ 57 #ifndef OIS_LIRCRingBuffer_H 58 #define OIS_LIRCRingBuffer_H 59 60 #include "OISPrereqs.h" 61 62 namespace OIS 63 { 64 struct LIRCEvent 65 { 66 //! high bit (0x80000000) will be on if button pushed, else it was released 67 unsigned int button; 68 }; 69 70 /// <summary> 71 /// Ring Buffer (fifo) used to store 16bit pcm data 72 /// </summary> 73 class LIRCRingBuffer 74 { 75 private: 76 //! Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init 77 int bufferSize; 78 //! Used for wrapping indices with extra bit to distinguish full/empty. 79 int bigMask; 80 // Used for fitting indices to buffer. 81 int smallMask; 82 83 // Buffer holding the actual event buffers 84 LIRCEvent *buffer; 85 86 //! Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. 87 volatile int writeIndex; 88 89 //! Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. 90 volatile int readIndex; 91 92 public: LIRCRingBuffer(unsigned int numEntries)93 LIRCRingBuffer( unsigned int numEntries ) 94 { 95 numEntries = RoundUpToNextPowerOf2( numEntries ); 96 97 //2 bytes per short 98 bufferSize = (int)numEntries; 99 buffer = new LIRCEvent[numEntries]; 100 101 Flush(); 102 103 bigMask = (int)(numEntries*2)-1; 104 smallMask = (int)(numEntries)-1; 105 } 106 ~LIRCRingBuffer()107 ~LIRCRingBuffer() 108 { 109 delete buffer; 110 } 111 RoundUpToNextPowerOf2(unsigned int n)112 unsigned int RoundUpToNextPowerOf2( unsigned int n ) 113 { 114 int numBits = 0; 115 if( ((n-1) & n) == 0) 116 return n; //Already Power of two. 117 118 while( n > 0 ) 119 { 120 n= n>>1; 121 numBits++; 122 } 123 return (unsigned int)(1<<numBits); 124 } 125 126 GetReadAvailable()127 int GetReadAvailable( ) 128 { 129 return ( (writeIndex - readIndex) & bigMask ); 130 } 131 132 GetWriteAvailable()133 int GetWriteAvailable( ) 134 { 135 return ( bufferSize - GetReadAvailable()); 136 } 137 138 Write(LIRCEvent * data,int numEntries)139 int Write( LIRCEvent *data, int numEntries ) 140 { 141 int size1 = 0, size2 = 0, numWritten; 142 int data1Ptr = 0, data2Ptr = 0; 143 144 numWritten = GetWriteRegions( numEntries, data1Ptr, size1, data2Ptr, size2 ); 145 146 if( size2 > 0 ) 147 { 148 //copy to two parts 149 memcpy( &buffer[data1Ptr], data, sizeof(LIRCEvent) * size1 ); 150 //Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 ); 151 memcpy( &buffer[data2Ptr], &data[size1], sizeof(LIRCEvent) * size2 ); 152 //Array.Copy( data, offsetPtr + size1, buffer, data2Ptr, size2 ); 153 } 154 else 155 { //Copy all continous 156 memcpy( &buffer[data1Ptr], data, sizeof(LIRCEvent) * size1 ); 157 //Array.Copy( data, offsetPtr, buffer, data1Ptr, size1 ); 158 } 159 AdvanceWriteIndex( numWritten ); 160 return numWritten; 161 } 162 163 164 /// <summary> 165 /// Reads requested number of entries into sent array. 166 /// Returns number written 167 /// </summary> Read(LIRCEvent * data,int numEntries)168 int Read( LIRCEvent *data, int numEntries ) 169 { 170 int size1 = 0, size2 = 0, numRead, data1Ptr = 0, data2Ptr = 0; 171 172 numRead = GetReadRegions( numEntries, data1Ptr, size1, data2Ptr, size2 ); 173 174 if( size2 > 0 ) 175 { 176 memcpy( data, &buffer[data1Ptr], sizeof(LIRCEvent) * size1 ); 177 //Array.Copy( buffer, data1Ptr, data, 0, size1 ); 178 memcpy( &data[size1], &buffer[data2Ptr], sizeof(LIRCEvent) * size2 ); 179 //Array.Copy( buffer, data2Ptr, data, size1, size2 ); 180 } 181 else 182 memcpy( data, &buffer[data1Ptr], sizeof(LIRCEvent) * size1 ); 183 //Array.Copy( buffer, data1Ptr, data, 0, size1 ); 184 185 AdvanceReadIndex( numRead ); 186 return numRead; 187 } 188 189 private: 190 GetWriteRegions(int numEntries,int & dataPtr1,int & sizePtr1,int & dataPtr2,int & sizePtr2)191 int GetWriteRegions( int numEntries, int &dataPtr1, int &sizePtr1, 192 int &dataPtr2, int &sizePtr2 ) 193 { 194 int index; 195 int available = GetWriteAvailable(); 196 if( numEntries > available ) 197 numEntries = available; 198 199 //Check to see if write is not contiguous. 200 index = writeIndex & smallMask; 201 if( (index + numEntries) > bufferSize ) 202 { 203 //Write data in two blocks that wrap the buffer. 204 int firstHalf = bufferSize - index; 205 dataPtr1 = index;//&buffer[index]; 206 sizePtr1 = firstHalf; 207 dataPtr2 = 0;//&buffer[0]; 208 sizePtr2 = numEntries - firstHalf; 209 } 210 else 211 { 212 dataPtr1 = index;//&buffer[index]; 213 sizePtr1 = numEntries; 214 dataPtr2 = 0; 215 sizePtr2 = 0; 216 } 217 return numEntries; 218 } 219 220 GetReadRegions(int numEntries,int & dataPtr1,int & sizePtr1,int & dataPtr2,int & sizePtr2)221 int GetReadRegions( int numEntries, int &dataPtr1, int &sizePtr1, int &dataPtr2, int &sizePtr2 ) 222 { 223 int index; 224 int available = GetReadAvailable( ); 225 if( numEntries > available ) 226 numEntries = available; 227 228 // Check to see if read is not contiguous 229 index = readIndex & smallMask; 230 if( (index + numEntries) > bufferSize ) 231 { 232 // Write data in two blocks that wrap the buffer 233 int firstHalf = bufferSize - index; 234 dataPtr1 = index;//&buffer[index]; 235 sizePtr1 = firstHalf; 236 dataPtr2 = 0;//&buffer[0]; 237 sizePtr2 = numEntries - firstHalf; 238 } 239 else 240 { 241 dataPtr1 = index;//&buffer[index]; 242 sizePtr1 = numEntries; 243 dataPtr2 = 0; 244 sizePtr2 = 0; 245 } 246 return numEntries; 247 } 248 249 AdvanceWriteIndex(int numEntries)250 int AdvanceWriteIndex( int numEntries ) 251 { 252 return writeIndex = (writeIndex + numEntries) & bigMask; 253 } 254 255 AdvanceReadIndex(int numEntries)256 int AdvanceReadIndex( int numEntries ) 257 { 258 return readIndex = (readIndex + numEntries) & bigMask; 259 } 260 261 Flush()262 void Flush( ) 263 { 264 writeIndex = readIndex = 0; 265 } 266 }; 267 } 268 #endif //#define OIS_LIRCRingBuffer_H 269 #endif 270