Очереди FIFO для передачи аудио данных


Я создал структуру данных для обработки аудио данных я генерации (простая синусоида прямо сейчас). У нее есть некоторые ошибки в нем в связи с некоторым непониманием мои древние знания, которые были исправлены, мой двоюродный брат. Мне интересно, если еще там может быть больше проблем.

Я рассмотрел это как класс C++, но поскольку у меня нет достаточного опыта с C++ я бы, вероятно, превратить его в огромную утечку памяти бывают. Это действительно используется с целью С на iPad - но ничто не мешает это использовать в другом месте.

Все функции являются общедоступными, и должно быть вполне очевидно, как они должны быть использованы. Но по сути вы к alloc структура, push и Pop (которые делают его звучать как стек, но это очень не), и, наконец, выпустить структуры. Вы заметите, что в объект C ориентированное проектирование - я сделал это намеренно, чтобы сделать вещи легче запомнить.

Я не использовать кольцевой буфер, потому что я не вышел на пик Баллмера, но когда я писал это, и я никак не мог попасть в нужную форму. Очереди в основном работает по принципу, который вы добавите в конце, и принимать данные от верхнего и левого перемещается вверх.

Я искал, чтобы использовать некоторые функции вектора ускорения от этого в какой-то момент. В настоящее время он используется в резьбовых кодом, замки с NSCondition.

Чтобы увидеть, как это используется сейчас, структуре используется в этом .м файл и является частью этого проекта.

// 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;
}


1525
3
задан 3 июля 2011 в 07:07 Источник Поделиться
Комментарии
2 ответа

Вот несколько советов в дополнение к тому, что Кит упоминает.

Я попытаюсь избежать памяти операции копирования и перемещения. Вы упоминаете кольцевой буфер, который является одним из способов сделать это, еще бы иметь ФИФО отдельных буферов и поп каждый буфер с фронта в полном комплекте. Избежать операции копирования и перемещения значительно ускорить код, который я предполагаю, является задачей при обработке аудио данных :)

Также, я бы падение состоит в том, что просто использовать структуру ФИФО вместо. Это делает его легче преобразовать в полный АТД (абстрактный тип данных) позже, и только вперед объявить структуру для пользователей, сохраняя при этом фактическая структура частная.

В качестве последнего замечания, вы абсолютно уверены, что ограничивать сайта-правильная, чтобы использовать здесь?

Редактировать:
Вот еще один наивный способ избавления от операция memove:

typedef struct {
float *buffer;
float *start;
float *end;
size_t max_length;
} FIFO;

bool FIFO_pop(FIFO *restrict fifo, float *restrict data, size_t count) {
if (!fifo || !data) return false;
if (count == 0 || FIFO_available(fifo) < count) return false;

// move count items from the buffer
memcpy(data, fifo->start, count*sizeof(float));
fifo->start += count;

return true;
}

Это будет работать только если вы знаете максимальный размер буфера, что вам нужно, но это должно дать вам представление.

2
ответ дан 4 июля 2011 в 09:07 Источник Поделиться

Выглядит неплохо....

есть несколько стиль вещей, которые я бы изменила

if (fifo->max_length - (int)(fifo->end - fifo->buffer) < count) {

Я бы кронштейн вещи здесь для ясности.

потенциально я бы также извлечь ФИФО->конец - ФИФО->буфер, в отдельную функцию, как вы его используете несколько раз

0
ответ дан 4 июля 2011 в 12:07 Источник Поделиться