docs: update file inventory and module header contracts
Refresh both AGENTS guides and clarify module purpose, usage, ownership, threading, return values and wire formats in headers. Remove the unused timeout_heap freed_count field and unimplemented getter.
This commit is contained in:
1 parent
c19eff67f6
commit
a97e8bcc1f
118 files changed
+628
-406
No files matched your search
@@ -1,3 +1,9 @@
|
||||
/* audio_compressor — адаптивное усиление int16 PCM (моно/стерео) с общей огибающей каналов.
|
||||
* create → configure → обработка → destroy; объект использует один владелец, блокировок нет.
|
||||
* Запись: push принимает произвольные порции, flush завершает хвост и lookahead; output принадлежит объекту.
|
||||
* Поток: process_frame обрабатывает ровно sample_rate*block_duration_ms/1000*channels отсчётов,
|
||||
* требует нулевого lookahead и пустого входного накопителя; in/out могут совпадать.
|
||||
* count/output_size — interleaved отсчёты, не байты и не кадры на канал. Выключение даёт исходный PCM. */
|
||||
#ifndef AUDIO_COMPRESSOR_H
|
||||
#define AUDIO_COMPRESSOR_H
|
||||
|
||||
@@ -19,7 +25,7 @@ typedef struct {
|
||||
float max_gain_db;
|
||||
float rise_rate_per_sec;
|
||||
float release_rate_per_sec; /* скорость плавного снижения gain (0 = авто: rise*5) */
|
||||
float target_level;
|
||||
float target_level; /* Линейная амплитуда огибающей, не дБ; 0 задаёт default 0.25. */
|
||||
} audio_compressor_config_t;
|
||||
|
||||
struct audio_compressor* audio_compressor_create(void);
|
||||
@@ -35,9 +41,11 @@ void audio_compressor_reset(struct audio_compressor* ac);
|
||||
void audio_compressor_set_enabled(struct audio_compressor* ac, int enabled);
|
||||
int audio_compressor_is_enabled(const struct audio_compressor* ac);
|
||||
|
||||
/* push копирует вход; push/flush возвращают 0 / -1. Ошибка накопления требует reset перед повтором. */
|
||||
int audio_compressor_push(struct audio_compressor* ac, const int16_t* samples, size_t count);
|
||||
int audio_compressor_flush(struct audio_compressor* ac);
|
||||
|
||||
/* Указатель действителен до изменения/освобождения выходного буфера; вызывающий его не освобождает. */
|
||||
const int16_t* audio_compressor_output(const struct audio_compressor* ac);
|
||||
size_t audio_compressor_output_size(const struct audio_compressor* ac);
|
||||
|
||||
|
||||
+7
-6
@@ -80,7 +80,7 @@ typedef int debug_category_t;
|
||||
/* Debug configuration structure */
|
||||
typedef struct {
|
||||
debug_level_t level; // Global debug level (default: ERROR)
|
||||
debug_level_t category_levels[DEBUG_CATEGORY_COUNT]; // Per-category levels (0 = disabled)
|
||||
debug_level_t category_levels[DEBUG_CATEGORY_COUNT]; // Уровень категории: NONE наследует общий, DISABLED выключает
|
||||
int timestamp_enabled; // Include timestamps in output
|
||||
int function_name_enabled; // Include function names
|
||||
int file_line_enabled; // Include file:line info
|
||||
@@ -99,18 +99,19 @@ extern debug_config_t g_debug_config;
|
||||
void debug_config_init(void);
|
||||
|
||||
/* Set debug level */
|
||||
// итоговый level = max (global level - здесь задается, category level)
|
||||
// Общий уровень применяется к категориям с уровнем NONE.
|
||||
void debug_set_level(debug_level_t level);
|
||||
|
||||
/* Set debug level for specific category (0 = disabled, otherwise uses that level) */
|
||||
/* Уровень категории заменяет общий; NONE наследует его, DISABLED подавляет вывод. */
|
||||
void debug_set_category_level(debug_category_t category, debug_level_t level);
|
||||
|
||||
/* Enable/disable specific categories */
|
||||
/* enable фиксирует текущий общий уровень; disable возвращает к наследованию (NONE).
|
||||
* Для полного выключения использовать debug_set_category_level(cat, DEBUG_LEVEL_DISABLED). */
|
||||
void debug_enable_category(debug_category_t category);
|
||||
void debug_disable_category(debug_category_t category);
|
||||
void debug_set_categories(debug_category_t categories);
|
||||
|
||||
/* Set masks directly */
|
||||
/* Установка уровня одной категории (аргумент categories — индекс, не битовая маска). */
|
||||
void debug_set_masks(debug_category_t categories, debug_level_t level);
|
||||
|
||||
/* Configure output options */
|
||||
@@ -126,7 +127,7 @@ int debug_reopen_log(void);
|
||||
void debug_enable_console(int enable);
|
||||
|
||||
|
||||
// IP address to string (static buffer, single-threaded)
|
||||
// IP/sockaddr в строку: результат возвращается по значению, освобождать не требуется.
|
||||
typedef struct {
|
||||
char str[54]; // INET6_ADDRSTRLEN(45) + 6chars (:port) + \0
|
||||
} ip_str_t;
|
||||
|
||||
+4
-1
@@ -2,7 +2,10 @@
|
||||
* @file json_flat.h
|
||||
* @brief Парсер плоского JSON без вложенности: {"key":"value",...}
|
||||
*
|
||||
* Только строковые значения. Callback получает полные строки без обрезания.
|
||||
* Только строковые значения и обычные escapes; \uXXXX не поддерживается.
|
||||
* Callback получает полные key/value, действительные только до его возврата.
|
||||
* parse возвращает 0 при успехе/остановке callback, -1 при ошибке; остановка не проверяет остаток ввода.
|
||||
* get ищет первый ключ и копирует значение с NUL, при малом буфере обрезает; 0 найден, -1 ошибка/нет ключа.
|
||||
*/
|
||||
|
||||
#ifndef JSON_FLAT_H
|
||||
|
||||
+4
-2
@@ -1,6 +1,10 @@
|
||||
#ifndef LL_QUEUE_H
|
||||
#define LL_QUEUE_H
|
||||
|
||||
/* Очередь одного uasync-потока; наличие pthread-заголовков не делает её межпоточной.
|
||||
* put может синхронно вызвать consumer/waiter. Держать владельцев живыми до завершения callbacks,
|
||||
* waiter handle обнулять целиком и отменять до освобождения; entry и dgram освобождаются отдельно. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -306,7 +310,6 @@ void queue_waiter_cancel(struct ll_queue* q, struct queue_waiter_handle* h);
|
||||
* @brief Добавляет элемент в конец очереди (FIFO).
|
||||
* @param q очередь
|
||||
* @param entry элемент
|
||||
* @param id идентификатор для поиска
|
||||
* @return 0 — успех, -1 — превышен лимит (элемент освобождён)
|
||||
*/
|
||||
int queue_data_put(struct ll_queue* q, struct ll_entry* entry);
|
||||
@@ -315,7 +318,6 @@ int queue_data_put(struct ll_queue* q, struct ll_entry* entry);
|
||||
* @brief Добавляет элемент в начало очереди (LIFO, высокий приоритет).
|
||||
* @param q очередь
|
||||
* @param entry элемент
|
||||
* @param id идентификатор
|
||||
* @return 0 — успех, -1 — превышен лимит (элемент освобождён)
|
||||
*/
|
||||
int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/**
|
||||
* Memory management layer
|
||||
* Provides wrappers for malloc/realloc/calloc/free with error handling
|
||||
* mem — выделение памяти с защитными полями, местом аллокации и учётом живых блоков.
|
||||
* Использовать u_malloc/u_calloc/u_realloc/u_strdup и парный u_free; обычный free к этим блокам неприменим.
|
||||
* Макросы передают LOCATION автоматически. OOM возвращает NULL; обнаруженное повреждение завершает процесс.
|
||||
* realloc при ошибке сохраняет старый блок, при size=0 освобождает его.
|
||||
* Отчёт u_report_unfreed_blocks вызывать после остановки потоков, меняющих список аллокаций.
|
||||
*/
|
||||
#ifndef MEM_H
|
||||
#define MEM_H
|
||||
|
||||
+7
-1
@@ -1,4 +1,9 @@
|
||||
// memory_pool.h
|
||||
/* memory_pool — повторное использование блоков фиксированного размера в одном потоке.
|
||||
* init создаёт пустой пул; alloc выделяет блок по требованию или берёт свободный и обнуляет payload.
|
||||
* free проверяет защитный хвост и возвращает не более MEMORY_POOL_MAX_FREE блоков в кеш.
|
||||
* object_size должен вмещать void*: свободный блок хранит next в начале payload.
|
||||
* Перед destroy вернуть все выданные блоки: destroy освобождает только кеш и сам пул.
|
||||
* name заимствован до destroy; блок возвращать только своему пулу, внутренней синхронизации нет. */
|
||||
#ifndef MEMORY_POOL_H
|
||||
#define MEMORY_POOL_H
|
||||
|
||||
@@ -40,6 +45,7 @@ size_t memory_pool_get_total_free_blocks(void);
|
||||
#define memory_pool_alloc(pool) memory_pool_alloc_impl(pool, PLOCATION)
|
||||
#define memory_pool_free(pool, obj) memory_pool_free_impl(pool, obj, PLOCATION)
|
||||
|
||||
/* Проверяет присутствие в кеше свободных блоков; не определяет состояние уже освобождённого через u_free блока. */
|
||||
int memory_pool_is_freed(struct memory_pool* pool, void* obj);
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/* opus_codec — владеющие обёртки encoder/decoder libopus для int16 interleaved PCM.
|
||||
* create принимает частоту и 1/2 канала; неположительная частота → 48000, неверные каналы → моно.
|
||||
* Encoder/decoder имеют состояние потока; каждому нужен один последовательный владелец.
|
||||
* frame_samples — отсчёты НА КАНАЛ: PCM вмещает frame_samples*channels элементов.
|
||||
* encode возвращает байты Opus, decode — отсчёты на канал; отрицательное значение означает ошибку.
|
||||
* out_cap — байты; decode с data=NULL/len=0 использует PLC libopus. Освобождение — соответствующим destroy. */
|
||||
#ifndef OPUS_CODEC_H
|
||||
#define OPUS_CODEC_H
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/**
|
||||
* Platform compatibility layer for POSIX functions on Windows
|
||||
* platform_compat — общие заголовки POSIX/Windows и адаптеры отсутствующих POSIX-функций.
|
||||
* Также предоставляет криптографический random_bytes, адреса интерфейсов, выбор default route
|
||||
* и классификацию публичных IPv4. Сокетные типы/ошибки и nonblocking API — в socket_compat.h.
|
||||
*/
|
||||
|
||||
#ifndef PLATFORM_COMPAT_H
|
||||
|
||||
+7
-4
@@ -22,17 +22,20 @@
|
||||
* • Все динамические данные (строки, массивы, списки) выделяются через u_malloc.
|
||||
* • При encode длина переменных полей кодируется всегда 2 байтами (uint16_t, big-endian).
|
||||
* • Для linked list в буфере сохраняется только количество узлов + сырые данные узлов
|
||||
* (next-указатели НЕ сериализуются, они восстанавливаются при decode).
|
||||
* (включая байты next/padding; decode заменяет next восстановленными ссылками).
|
||||
* • serialize_decode принимает буфер БЕЗ заголовка.
|
||||
* • serialize_free освобождает ВСЮ структуру и все вложенные динамические объекты.
|
||||
* • Поля в schema.fields должны идти в порядке возрастания offset.
|
||||
* • max_size (если > 0) — жёсткий лимит размера выходного буфера.
|
||||
* • Поля кодируются в порядке schema.fields; фиксированные данные копируются без смены endian.
|
||||
* • max_size (если > 0) — лимит encode; header при header_len > 0 обязателен.
|
||||
* • Переменные counts ограничены 65535; elem_size=1 добавляет NUL и для byte-массивов.
|
||||
* • Linked nodes копируются целиком, без рекурсивного кодирования вложенных указателей.
|
||||
* • Этот формат зависит от ABI сырых полей; сериализация не нормализует размер/выравнивание структур.
|
||||
*
|
||||
* @example
|
||||
* // 1. Описание структуры
|
||||
* typedef struct Node {
|
||||
* uint32_t value;
|
||||
* struct Node* next; // next по offset = 4
|
||||
* struct Node* next; // положение задаётся offsetof(Node, next)
|
||||
* } Node;
|
||||
*
|
||||
* typedef struct {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Запускает официальную стриминговую модель silero_vad.onnx (v5, ~2.3 МБ),
|
||||
* которая по окну аудио возвращает вероятность наличия речи [0..1].
|
||||
* Рекуррентное состояние (GRU) хранится внутри объекта и переносится между
|
||||
* Рекуррентное состояние модели хранится внутри объекта и переносится между
|
||||
* вызовами. Обёртка также хранит 64 последних отсчёта аудио и добавляет их
|
||||
* перед новым окном: ONNX получает 576 отсчётов, публичный API принимает 512.
|
||||
*
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* Socket compatibility layer for cross-platform support (POSIX / Windows)
|
||||
* MSYS2 UCRT64 compatible
|
||||
* Единые socket_t, коды ошибок и wrappers сокетов POSIX/Windows (включая MSYS2 UCRT64).
|
||||
* platform_init/cleanup обслуживают Winsock; UDP/nonblocking/options/sendto/recvfrom — операции ОС.
|
||||
* Созданные сокеты закрывает владелец через socket_close_wrapper; event loop находится в u_async.h.
|
||||
*/
|
||||
|
||||
#ifndef SOCKET_COMPAT_H
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
* перед кодированием. Работает на interleaved int16 PCM, 1/2 канала, частота 48000 (можно
|
||||
* 8000/16000/32000/48000), кадр 20 мс (960 сэмплов @48 кГц).
|
||||
*
|
||||
* Объект не имеет внутренних блокировок: feed/process/reset/get_stats выполняет один владелец
|
||||
* либо вызывающий сериализует их общей блокировкой. Аппаратные callbacks сами AEC не вызывают.
|
||||
*
|
||||
* Модель использования (duplex-контур звонка):
|
||||
* - рендер (far-end, то что пошло в динамик) → speex_aec_feed_playback();
|
||||
* - захват (near-end, микрофон) → speex_aec_process_capture().
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
/* sliding_window_min.h */
|
||||
/* swm_min — минимум последних window_size целых значений (окно по числу добавлений, не по времени).
|
||||
* create → add/get_min → destroy; память окна выделяется при create, внутренняя синхронизация отсутствует. */
|
||||
#ifndef SLIDING_WINDOW_MIN_H
|
||||
#define SLIDING_WINDOW_MIN_H
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ TimeoutHeap *timeout_heap_create(size_t initial_capacity) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "Creating TH3...");
|
||||
h->size = 0;
|
||||
h->capacity = initial_capacity;
|
||||
h->freed_count = 0;
|
||||
h->user_data = NULL;
|
||||
h->free_callback = NULL;
|
||||
return h;
|
||||
|
||||
+11
-11
@@ -1,4 +1,9 @@
|
||||
// timeout_heap.h
|
||||
/* timeout_heap — min-heap таймеров для uasync; сам не измеряет время и не вызывает таймеры.
|
||||
* Владелец задаёт абсолютные expiration в одной шкале и извлекает готовые записи через peek/pop.
|
||||
* cancel помечает запись; её data передаётся free_callback при последующей очистке или destroy.
|
||||
* Без free_callback data не освобождается. Успешный pop передаёт data вызывающему.
|
||||
* index_ptr, если задан, должен жить до удаления записи; heap обновляет индекс при перестановках.
|
||||
* Все операции одного heap выполняются в одном потоке, внутренней синхронизации нет. */
|
||||
|
||||
#ifndef TIMEOUT_HEAP_H
|
||||
#define TIMEOUT_HEAP_H
|
||||
@@ -11,7 +16,7 @@ extern "C" {
|
||||
#include <stdint.h> // For uint64_t
|
||||
#include <stddef.h> // For size_t
|
||||
|
||||
typedef uint64_t TimeoutTime; // e.g., milliseconds since epoch or from now
|
||||
typedef uint64_t TimeoutTime; // Абсолютное время в шкале владельца (uasync использует timebase: 0.1 мс).
|
||||
|
||||
typedef struct {
|
||||
TimeoutTime expiration; // Sort key (smaller = earlier)
|
||||
@@ -26,7 +31,6 @@ struct TimeoutHeap {
|
||||
TimeoutEntry *heap; // Dynamic array
|
||||
size_t size; // Current number of elements
|
||||
size_t capacity; // Allocated size
|
||||
size_t freed_count; // Number of freed timer nodes
|
||||
void* user_data; // User data for free callback
|
||||
void (*free_callback)(void* user_data, void* data); // Callback to free data
|
||||
};
|
||||
@@ -48,7 +52,7 @@ void timeout_heap_destroy(TimeoutHeap *h);
|
||||
* Set a callback function to free data when deleted nodes are removed.
|
||||
* @param h The heap.
|
||||
* @param user_data User data passed to callback.
|
||||
* @param callback Callback function (if NULL, data is freed with free()).
|
||||
* @param callback Освобождает data отменённых записей и всех записей при destroy; NULL оставляет data владельцу.
|
||||
*/
|
||||
void timeout_heap_set_free_callback(TimeoutHeap *h, void* user_data, void (*callback)(void* user_data, void* data));
|
||||
|
||||
@@ -57,6 +61,7 @@ void timeout_heap_set_free_callback(TimeoutHeap *h, void* user_data, void (*call
|
||||
* @param h The heap.
|
||||
* @param expiration The expiration time.
|
||||
* @param data User data associated with the timeout.
|
||||
* @param index_ptr Optional pointer to a live size_t updated with the entry's zero-based heap index.
|
||||
* @return 0 on success, -1 on allocation failure.
|
||||
*/
|
||||
int timeout_heap_push(TimeoutHeap *h, TimeoutTime expiration, void *data, size_t *index_ptr);
|
||||
@@ -88,15 +93,10 @@ int timeout_heap_pop(TimeoutHeap *h, TimeoutEntry *out);
|
||||
*/
|
||||
int timeout_heap_cancel(TimeoutHeap *h, TimeoutTime expiration, void *data);
|
||||
|
||||
/* Отмена по сохранённому индексу; data защищает от отмены чужой записи. 0 / -1, освобождение отложено. */
|
||||
int timeout_heap_cancel_at(TimeoutHeap *h, size_t index, void *data);
|
||||
|
||||
/**
|
||||
* Get the number of freed timer nodes.
|
||||
* @param h The heap.
|
||||
* @return Count of freed timer nodes.
|
||||
*/
|
||||
size_t timeout_heap_get_freed_count(TimeoutHeap *h);
|
||||
|
||||
/* Число записей, включая ещё не извлечённые отменённые; NULL → 0. */
|
||||
size_t timeout_heap_get_size(TimeoutHeap *h);
|
||||
|
||||
|
||||
|
||||
+5
-3
@@ -1,6 +1,8 @@
|
||||
// uasync.h
|
||||
|
||||
// модуль асинхронных операций. добавляем сокеты и таймауты и mainloop их обслуживает.
|
||||
/* Цикл событий одного потока: сокеты (epoll/poll/select), таймеры и FIFO call_soon.
|
||||
* create → регистрация callbacks → poll/mainloop → destroy вне callbacks после остановки владельцев.
|
||||
* Таймауты задаются в timebase 0.1мс; arg принадлежит вызывающему, освобождает его callback/владелец.
|
||||
* API сокетов/таймеров используется в потоке loop. Из другого потока — post/post_reserved и wakeup;
|
||||
* публикация не продлевает время жизни ua/arg, их освобождение нужно согласовать с остановкой producers. */
|
||||
|
||||
#ifndef UASYNC_H
|
||||
#define UASYNC_H
|
||||
|
||||
Reference in new issue
Block a user