100 lines
2.7 KiB
C
100 lines
2.7 KiB
C
|
|
||
|
#if !defined(_circlebuffer_h)
|
||
|
#define _circlebuffer_h
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
#if defined(__cplusplus)
|
||
|
extern "C" {
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#if defined(_WIN32)
|
||
|
typedef __int64 int64_t;
|
||
|
#elif defined(__POWERPC) || defined(__APPLE)
|
||
|
#include <ppc/types.h>
|
||
|
#else
|
||
|
typedef long long int64_t;
|
||
|
#endif
|
||
|
|
||
|
#if !defined(_WIN32)
|
||
|
#pragma bool on
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
typedef unsigned char CircleRecord_t;
|
||
|
|
||
|
|
||
|
|
||
|
typedef void (*FuncLock_t)() ;
|
||
|
|
||
|
/* assume that assert, alerts, messages to go off before this ever is allowed to fill */
|
||
|
/*------------------------------------------------------------------------------------*/
|
||
|
typedef struct CircleBuf_tt
|
||
|
{
|
||
|
size_t head; /* points to start of usable data in buffer */
|
||
|
size_t count;
|
||
|
size_t bufSize;
|
||
|
int64_t bytesConsumed;
|
||
|
size_t recordSize;
|
||
|
size_t userData; /* might store actual recordsize */
|
||
|
int balance;
|
||
|
CircleRecord_t* buffer; /* 10 seconds of 16 bit stereo nice quality */
|
||
|
unsigned char* maxChunk;
|
||
|
size_t maxChunkLen;
|
||
|
int percent; /* level where buffer considered stable */
|
||
|
int wrapped; /* non-zero if data has wrapped at least once */
|
||
|
int muted;
|
||
|
|
||
|
FuncLock_t lock; /* in case there could be competition for any members */
|
||
|
FuncLock_t unlock; /* in case there could be competition for any members */
|
||
|
|
||
|
int starvedBytes; /* how many bytes we had to "conjure up" because we were empty (debug) */
|
||
|
int starvedRequests; /* how many request we honored when we have been in a starved state (debug) */
|
||
|
|
||
|
} CircleBuffer_t;
|
||
|
|
||
|
|
||
|
void testCircleBuffer(void);
|
||
|
void destroyCircleBuffer(CircleBuffer_t* cb);
|
||
|
int initCircleBuffer(CircleBuffer_t* cb, size_t size, int percent, size_t maxChunk, FuncLock_t lock, FuncLock_t unlock);
|
||
|
int addToCircleBuffer(CircleBuffer_t* cb, void* data, size_t count);
|
||
|
int readFromCircleBuffer(CircleBuffer_t* cb, void* dest, size_t count);
|
||
|
int accessCircleBuffer(CircleBuffer_t* cb, void* dest, size_t count);
|
||
|
void FreeWrapless(const CircleBuffer_t* cb, void* handle, size_t* sizeWrapless);
|
||
|
int resetCircleBuffer(CircleBuffer_t* cb);
|
||
|
int RewindBuffer(CircleBuffer_t* cb, int64_t len);
|
||
|
int ForwardBuffer(CircleBuffer_t* cb, int64_t len);
|
||
|
|
||
|
|
||
|
|
||
|
void CircleReport(const CircleBuffer_t* cb, const char* title);
|
||
|
|
||
|
|
||
|
|
||
|
int CirclePercent(CircleBuffer_t* cb);
|
||
|
|
||
|
int CircleAtLevel(CircleBuffer_t* cb);
|
||
|
|
||
|
int CircleOverLevel(CircleBuffer_t* cb);
|
||
|
|
||
|
|
||
|
|
||
|
typedef enum {
|
||
|
CB_NOERR = 0, /* OK */
|
||
|
CB_FULL = -1, /* Buffer overflow */
|
||
|
CB_MAX_LEVEL = -2, /* Buffer is over target full level (percent) */
|
||
|
CB_MIN_LEVEL = -3, /* Buffer is under target min level (percent) */
|
||
|
CB_EMPTY = -4 /* Buffer is empty */
|
||
|
} CB_Err_t;
|
||
|
#if defined(__cplusplus)
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|