Change tu_fifo_get_linear_write/read_info() to return a struct

Compilers always complain that variables set by function via pointer
might be uninitialized so to avoid that return values are now delivered
via struct.
This commit is contained in:
Reinhard Panhuber 2021-04-23 11:48:54 +02:00
parent a98d0217a0
commit 7072f0155e
3 changed files with 51 additions and 47 deletions

View File

@ -647,26 +647,26 @@ static bool audiod_decode_type_I_pcm(uint8_t rhport, audiod_function_t* audio, u
uint8_t cnt_ff; uint8_t cnt_ff;
// Decode // Decode
void * dst, * dst_wrap;
uint8_t * src; uint8_t * src;
uint8_t * dst_end; uint8_t * dst_end;
uint16_t len, len_wrap = 0;
tu_fifo_linear_wr_info info;
for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++)
{ {
src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx]; src = &audio->lin_buf_out[cnt_ff*audio->n_channels_per_ff_rx * audio->n_bytes_per_sampe_rx];
len = tu_fifo_get_linear_write_info(&audio->rx_supp_ff[cnt_ff], 0, nBytesPerFFToRead, &dst, &len_wrap, &dst_wrap); info = tu_fifo_get_linear_write_info(&audio->rx_supp_ff[cnt_ff], 0, nBytesPerFFToRead);
dst_end = dst + len; dst_end = info.ptr_lin + info.len_lin;
src = audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, dst, dst_end, src, n_ff_used); src = audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, info.ptr_lin, dst_end, src, n_ff_used);
// Handle wrapped part of FIFO // Handle wrapped part of FIFO
if (len_wrap != 0) if (info.len_wrap != 0)
{ {
dst_end = dst_wrap + len_wrap; dst_end = info.ptr_wrap + info.len_wrap;
audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, dst_wrap, dst_end, src, n_ff_used); audiod_interleaved_copy_bytes_fast_decode(nBytesToCopy, info.ptr_wrap, dst_end, src, n_ff_used);
} }
tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], len + len_wrap); tu_fifo_advance_write_pointer(&audio->rx_supp_ff[cnt_ff], info.len_lin + info.len_wrap);
} }
// Number of bytes should be a multiple of CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX but checking makes no sense - no way to correct it // Number of bytes should be a multiple of CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX * CFG_TUD_AUDIO_N_CHANNELS_RX but checking makes no sense - no way to correct it
@ -973,28 +973,28 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi
nBytesPerFFToSend = (nBytesPerFFToSend / nBytesToCopy) * nBytesToCopy; nBytesPerFFToSend = (nBytesPerFFToSend / nBytesToCopy) * nBytesToCopy;
// Encode // Encode
void * src, * src_wrap;
uint8_t * dst; uint8_t * dst;
uint8_t * src_end; uint8_t * src_end;
uint16_t len, len_wrap = 0; // Give len_wrap a value such that compiler does not complain - although it gets initialized in any case...
tu_fifo_linear_wr_info info;
for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++) for (cnt_ff = 0; cnt_ff < n_ff_used; cnt_ff++)
{ {
dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sampe_tx]; dst = &audio->lin_buf_in[cnt_ff*audio->n_channels_per_ff_tx*audio->n_bytes_per_sampe_tx];
len = tu_fifo_get_linear_read_info(&audio->tx_supp_ff[cnt_ff], 0, nBytesPerFFToSend, &src, &len_wrap, &src_wrap); info = tu_fifo_get_linear_read_info(&audio->tx_supp_ff[cnt_ff], 0, nBytesPerFFToSend);
src_end = src + len; src_end = info.ptr_lin + info.len_lin;
dst = audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, src, src_end, dst, n_ff_used); dst = audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, info.ptr_lin, src_end, dst, n_ff_used);
// Handle wrapped part of FIFO // Handle wrapped part of FIFO
if (len_wrap != 0) if (info.len_wrap != 0)
{ {
src_end = src_wrap + len_wrap; src_end = info.ptr_wrap + info.len_wrap;
audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, src_wrap, src_end, dst, n_ff_used); audiod_interleaved_copy_bytes_fast_encode(nBytesToCopy, info.ptr_wrap, src_end, dst, n_ff_used);
} }
tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], len + len_wrap); tu_fifo_advance_read_pointer(&audio->tx_supp_ff[cnt_ff], info.len_lin + info.len_wrap);
} }
return nBytesPerFFToSend * n_ff_used; return nBytesPerFFToSend * n_ff_used;

View File

@ -905,7 +905,7 @@ void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n)
Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid
*/ */
/******************************************************************************/ /******************************************************************************/
uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n, void **ptr_lin, uint16_t *len_wrap, void **ptr_wrap) tu_fifo_linear_wr_info tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n)
{ {
// Operate on temporary values in case they change in between // Operate on temporary values in case they change in between
uint16_t w = f->wr_idx, r = f->rd_idx; uint16_t w = f->wr_idx, r = f->rd_idx;
@ -922,8 +922,10 @@ uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n,
cnt = f->depth; cnt = f->depth;
} }
tu_fifo_linear_wr_info info = {0,0,NULL,NULL};
// Skip beginning of buffer // Skip beginning of buffer
if (cnt == 0 || offset >= cnt) return 0; if (cnt == 0 || offset >= cnt) return info;
// Check if we can read something at and after offset - if too less is available we read what remains // Check if we can read something at and after offset - if too less is available we read what remains
cnt -= offset; cnt -= offset;
@ -934,26 +936,22 @@ uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n,
r = get_relative_pointer(f, r, offset); r = get_relative_pointer(f, r, offset);
// Copy pointer to buffer to start reading from // Copy pointer to buffer to start reading from
*ptr_lin = &f->buffer[r]; info.ptr_lin = &f->buffer[r];
*ptr_wrap = f->buffer; info.ptr_wrap = f->buffer;
// Check if there is a wrap around necessary // Check if there is a wrap around necessary
uint16_t len;
if (w > r) { if (w > r) {
// Non wrapping case // Non wrapping case
len = w - r; info.len_lin = tu_min16(n, w - r); // Limit to required length
len = tu_min16(n, len); // Limit to required length info.len_wrap = 0;
*len_wrap = 0;
} }
else else
{ {
len = f->depth - r; // Also the case if FIFO was full info.len_lin = tu_min16(n, f->depth - r); // Also the case if FIFO was full
len = tu_min16(n, len); info.len_wrap = n-info.len_lin; // n was already limited to what is available
*len_wrap = n-len; // n was already limited to what is available
} }
return len; return info;
} }
/******************************************************************************/ /******************************************************************************/
@ -979,11 +977,13 @@ uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n,
Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid Length of linear part IN ITEMS, if zero corresponding pointer ptr is invalid
*/ */
/******************************************************************************/ /******************************************************************************/
uint16_t tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n, void **ptr_lin, uint16_t *len_wrap, void **ptr_wrap) tu_fifo_linear_wr_info tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n)
{ {
uint16_t w = f->wr_idx, r = f->rd_idx; uint16_t w = f->wr_idx, r = f->rd_idx;
uint16_t free = _tu_fifo_remaining(f, w, r); uint16_t free = _tu_fifo_remaining(f, w, r);
tu_fifo_linear_wr_info info = {0,0,NULL,NULL};
if (!f->overwritable) if (!f->overwritable)
{ {
// Not overwritable limit up to full // Not overwritable limit up to full
@ -992,7 +992,7 @@ uint16_t tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n
else if (n >= f->depth) else if (n >= f->depth)
{ {
// If overwrite is allowed it must be less than or equal to 2 x buffer length, otherwise the overflow can not be resolved by the read functions // If overwrite is allowed it must be less than or equal to 2 x buffer length, otherwise the overflow can not be resolved by the read functions
TU_VERIFY(n <= 2*f->depth); if(n > 2*f->depth) return info;
n = f->depth; n = f->depth;
// We start writing at the read pointer's position since we fill the complete // We start writing at the read pointer's position since we fill the complete
@ -1002,31 +1002,27 @@ uint16_t tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n
} }
// Check if there is room to write to // Check if there is room to write to
if (free == 0 || offset >= free) return 0; if (free == 0 || offset >= free) return info;
// Get relative pointers // Get relative pointers
w = get_relative_pointer(f, w, offset); w = get_relative_pointer(f, w, offset);
r = get_relative_pointer(f, r, 0); r = get_relative_pointer(f, r, 0);
// Copy pointer to buffer to start writing to // Copy pointer to buffer to start writing to
*ptr_lin = &f->buffer[w]; info.ptr_lin = &f->buffer[w];
*ptr_wrap = f->buffer; // Always start of buffer info.ptr_wrap = f->buffer; // Always start of buffer
uint16_t len;
if (w < r) if (w < r)
{ {
// Non wrapping case // Non wrapping case
len = r-w; info.len_lin = tu_min16(n, r-w); // Limit to required length
len = tu_min16(n, len); // Limit to required length info.len_wrap = 0;
*len_wrap = 0;
} }
else else
{ {
len = f->depth - w; info.len_lin = tu_min16(n, f->depth - w); // Limit to required length
len = tu_min16(n, len); // Limit to required length info.len_wrap = n-info.len_lin; // Remaining length - n already was limited to free or FIFO depth
*len_wrap = n-len; // Remaining length - n already was limited to free or FIFO depth
} }
return len; return info;
} }

View File

@ -80,6 +80,14 @@ typedef struct
} tu_fifo_t; } tu_fifo_t;
typedef struct
{
uint16_t len_lin ; ///< linear length in item size
uint16_t len_wrap ; ///< wrapped length in item size
void * ptr_lin ; ///< linear part start pointer
void * ptr_wrap ; ///< wrapped part start pointer
} tu_fifo_linear_wr_info;
#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \ #define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \
{ \ { \
.buffer = _buffer, \ .buffer = _buffer, \
@ -136,8 +144,8 @@ void tu_fifo_advance_read_pointer (tu_fifo_t *f, uint16_t n);
// tu_fifo_advance_read_pointer()/tu_fifo_advance_write_pointer and conduct a second read/write operation // tu_fifo_advance_read_pointer()/tu_fifo_advance_write_pointer and conduct a second read/write operation
// TODO - update comments // TODO - update comments
uint16_t tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n, void **ptr_lin, uint16_t *len_wrap, void **ptr_wrap); tu_fifo_linear_wr_info tu_fifo_get_linear_read_info(tu_fifo_t *f, uint16_t offset, uint16_t n);
uint16_t tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n, void **ptr_lin, uint16_t *len_wrap, void **ptr_wrap); tu_fifo_linear_wr_info tu_fifo_get_linear_write_info(tu_fifo_t *f, uint16_t offset, uint16_t n);
static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer) static inline bool tu_fifo_peek(tu_fifo_t* f, void * p_buffer)
{ {