/* * cbl_open_silence — то же, что cbl_open, но при недоливе тишину шлёт САМА * libc: буфер под неё аллоцируется здесь. Именно этот модуль тянет malloc, * поэтому приложения на cbl_open() за него не платят. * * БУФЕР НЕ ОСВОБОЖДАЕТСЯ. cbl_close() его не трогает намеренно: free() * в cbl_close вернул бы malloc в резидент всем подряд — ровно то, от чего * уходили. Потеря невелика (128 или 256 байт), а при повторном открытии * буфер переиспользуется; окончательно память возвращает выход из * программы. */ #include #include #include #include "_cbl.h" /* Сколько байт под буфером сейчас лежит. Помнить обязательно: у 8-бит * формата блок 128, у 16-бит — 256, и открытие 16-бит ПОСЛЕ 8-бит писало бы * memset'ом мимо выделенного куска. */ static uint16_t silence_cap; int cbl_open_silence(uint8_t freq_code, uint8_t fmt, uint8_t pump_mode, cbl_fill_fn fill) { uint16_t block = (fmt & CBL_FMT_MONO16) ? 256u : 128u; uint8_t quiet = (fmt & CBL_FMT_MONO16) ? 0x00 : 0x80; if (silence_cap < block) { uint8_t *p = malloc(block); if (!p) { errno = ENOMEM; return -1; } _cbl_silence = p; /* прежний кусок не освобождаем — см. шапку */ silence_cap = block; } memset(_cbl_silence, quiet, block); return _cbl_open_raw(freq_code, fmt, pump_mode, CBL_UNDERRUN_SILENCE, fill); }