Skip to main content
deleted 32 characters in body; edited tags; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

A C FIFO queue for audio data can this be improved?

Many thanks for suggestions.

A C FIFO queue for audio data can this be improved?

Many thanks for suggestions.

FIFO queue for audio data

Source Link

A C FIFO queue for audio data can this be improved?

I have created a data structure to handle some audio data I am generating (simple sine wave right now). It had some errors in it due to some misunderstanding of my ancient C knowledge that has been fixed by my cousin. I am wondering if there may yet still be more issues.

I have considered turning this into a C++ class, but because I don't have enough experience with C++ I would likely turn it into a huge memory leak waiting to happen. This is really being used with Objective C on the iPad - but nothing prevents this from being used elsewhere.

All of the functions are publicly accessible, and should be fairly obvious how they should be used. But essentially you alloc the structure, push and pop (which make it sound like a stack but it very much is not), and finally release the structure. You will notice it is in a C Object Oriented Design - I did that intentionally to make things easier to remember.

I did not use a circular buffer because I hadn't reached the ballmer peak yet when I was writing this and I couldn't quite get the right form. The queue basically works on the principle that you append on the end, and take data off the top - and the stuff left is moved up to the top.

I was looking to use some vector acceleration functions from this at some point. It presently is being used in threaded code behind locks with NSCondition.

To see how this is being used now, the structure is used in this .m file and is part of this project.

Many thanks for suggestions.

// from the header file - just converted to a typedef, untested...
typedef struct {
    float *buffer;
    float *end;
    size_t max_length;
} FIFO;

#include "FIFO.h"

FIFO *FIFO_alloc(size_t length) {
    FIFO *restrict ptr = NULL;
    
    ptr = (FIFO*)calloc(1, sizeof(FIFO));
    if (ptr == NULL) {
        return NULL;
    }
    
    ptr->buffer = (float*)calloc(length, sizeof(float));
    if (ptr->buffer == NULL) {
        free(ptr);
        return NULL;
    }
    
    ptr->end = ptr->buffer;
    ptr->max_length = length;
    
    return ptr;
}

void FIFO_release(FIFO *fifo) {
    if (fifo) {
        free(fifo->buffer);
        free(fifo);
    }
}

bool FIFO_push(FIFO *restrict fifo, const float *restrict data, size_t count) {
    if (!fifo || !data || count == 0) return false;
    
    // test for the length available
    if (fifo->max_length - (int)(fifo->end - fifo->buffer) < count) {
        return false;
    }
    
    memcpy(fifo->end, data, count*sizeof(float));
    fifo->end += count;
    
    return true;
}

bool FIFO_pop(FIFO *restrict fifo, float *restrict data, size_t count) {
    if (!fifo || !data) return false;
    if (count == 0 || FIFO_size(fifo) < count) return false;
    
    // move count items from the buffer
    memcpy(data, fifo->buffer, count*sizeof(float));
    // move empty space back to the beginning
    memmove(fifo->buffer, fifo->buffer + count, (fifo->end - fifo->buffer - count) * sizeof(float));
    
    // reposition end pointer
    fifo->end -= count;
    
    return true;
}

size_t FIFO_size(const FIFO *fifo) {
    if (fifo) {
        return (size_t)(fifo->end - fifo->buffer);
    }
    
    return 0;
}

size_t FIFO_maxsize(const FIFO *fifo) {
    if (fifo) {
        return fifo->max_length;
    }
    
    return 0;
}