| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 | /*  *  Squeezelite - lightweight headless squeezebox emulator * *  (c) Adrian Smith 2012-2015, triode1@btinternet.com *      Ralph Irving 2015-2017, ralph_irving@hotmail.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. *  * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program.  If not, see <http://www.gnu.org/licenses/>. * */// fifo bufffers #define _GNU_SOURCE#include "squeezelite.h"// _* called with muxtex lockedinline unsigned _buf_used(struct buffer *buf) {	return buf->writep >= buf->readp ? buf->writep - buf->readp : buf->size - (buf->readp - buf->writep);}unsigned _buf_space(struct buffer *buf) {	return buf->size - _buf_used(buf) - 1; // reduce by one as full same as empty otherwise}unsigned _buf_cont_read(struct buffer *buf) {	return buf->writep >= buf->readp ? buf->writep - buf->readp : buf->wrap - buf->readp;}unsigned _buf_cont_write(struct buffer *buf) {	return buf->writep >= buf->readp ? buf->wrap - buf->writep : buf->readp - buf->writep;}void _buf_inc_readp(struct buffer *buf, unsigned by) {	buf->readp += by;	if (buf->readp >= buf->wrap) {		buf->readp -= buf->size;	}}void _buf_inc_writep(struct buffer *buf, unsigned by) {	buf->writep += by;	if (buf->writep >= buf->wrap) {		buf->writep -= buf->size;	}}void buf_flush(struct buffer *buf) {	mutex_lock(buf->mutex);	buf->readp  = buf->buf;	buf->writep = buf->buf;	mutex_unlock(buf->mutex);}void _buf_flush(struct buffer *buf) {	buf->readp  = buf->buf;	buf->writep = buf->buf;}// adjust buffer to multiple of mod bytes so reading in multiple always wraps on frame boundaryvoid buf_adjust(struct buffer *buf, size_t mod) {	size_t size;	mutex_lock(buf->mutex);	size = ((unsigned)(buf->base_size / mod)) * mod;	buf->readp  = buf->buf;	buf->writep = buf->buf;	buf->wrap   = buf->buf + size;	buf->size   = size;	mutex_unlock(buf->mutex);}// called with mutex locked to resize, does not retain contents, reverts to original size if failsvoid _buf_resize(struct buffer *buf, size_t size) {	if (size == buf->size) return;	free(buf->buf);	buf->buf = malloc(size);	if (!buf->buf) {		size    = buf->size;		buf->buf= malloc(size);		if (!buf->buf) {			size = 0;		}	}	buf->readp  = buf->buf;	buf->writep = buf->buf;	buf->wrap   = buf->buf + size;	buf->size   = size;	buf->base_size = size;}void buf_init(struct buffer *buf, size_t size) {	buf->buf    = malloc(size);	buf->readp  = buf->buf;	buf->writep = buf->buf;	buf->wrap   = buf->buf + size;	buf->size   = size;	buf->base_size = size;	mutex_create_p(buf->mutex);}void buf_destroy(struct buffer *buf) {	if (buf->buf) {		free(buf->buf);		buf->buf = NULL;		buf->size = 0;		buf->base_size = 0;		mutex_destroy(buf->mutex);	}}
 |