How do you implement a circular buffer in C?

后端 未结 8 2076
滥情空心
滥情空心 2020-11-28 00:53

I have a need for a fixed-size (selectable at run-time when creating it, not compile-time) circular buffer which can hold objects of any type and it needs to be very

8条回答
  •  难免孤独
    2020-11-28 01:17

    // Note power of two buffer size
    #define kNumPointsInMyBuffer 1024 
    
    typedef struct _ringBuffer {
        UInt32 currentIndex;
        UInt32 sizeOfBuffer;
        double data[kNumPointsInMyBuffer];
    } ringBuffer;
    
    // Initialize the ring buffer
    ringBuffer *myRingBuffer = (ringBuffer *)calloc(1, sizeof(ringBuffer));
    myRingBuffer->sizeOfBuffer = kNumPointsInMyBuffer;
    myRingBuffer->currentIndex = 0;
    
    // A little function to write into the buffer
    // N.B. First argument of writeIntoBuffer() just happens to have the
    // same as the one calloc'ed above. It will only point to the same
    // space in memory if the calloc'ed pointer is passed to
    // writeIntoBuffer() as an arg when the function is called. Consider
    // using another name for clarity
    void writeIntoBuffer(ringBuffer *myRingBuffer, double *myData, int numsamples) {
        // -1 for our binary modulo in a moment
        int buffLen = myRingBuffer->sizeOfBuffer - 1;
        int lastWrittenSample = myRingBuffer->currentIndex;
    
        int idx;
        for (int i=0; i < numsamples; ++i) {
            // modulo will automagically wrap around our index
            idx = (i + lastWrittenSample) & buffLen; 
            myRingBuffer->data[idx] = myData[i];
        }
    
        // Update the current index of our ring buffer.
        myRingBuffer->currentIndex += numsamples;
        myRingBuffer->currentIndex &= myRingBuffer->sizeOfBuffer - 1;
    }
    

    As long as your ring buffer's length is a power of two, the incredibly fast binary "&" operation will wrap around your index for you. For my application, I'm displaying a segment of audio to the user from a ring buffer of audio acquired from a microphone.

    I always make sure that the maximum amount of audio that can be displayed on screen is much less than the size of the ring buffer. Otherwise you might be reading and writing from the same chunk. This would likely give you weird display artifacts.

提交回复
热议问题