1 /* Copyright 2018 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #ifndef FLOAT_BUFFER_H_ 7 #define FLOAT_BUFFER_H_ 8 9 #include "byte_buffer.h" 10 11 /* 12 * Circular buffer storing deinterleaved floating point data. 13 * Members: 14 * fp - Pointer to be filled wtih read/write position of the buffer. 15 * num_channels - Number of channels. 16 */ 17 struct float_buffer { 18 struct byte_buffer *buf; 19 float **fp; 20 unsigned int num_channels; 21 }; 22 23 /* 24 * Creates an float_buffer. 25 * Args: 26 * max_size - The max number of frames this buffer may store. 27 * num_channels - Number of channels of the deinterleaved data. 28 */ 29 static inline struct float_buffer *float_buffer_create( 30 unsigned int max_size, 31 unsigned int num_channels) 32 { 33 struct float_buffer *b; 34 35 b = (struct float_buffer *)calloc(1, sizeof(*b)); 36 37 b->num_channels = num_channels; 38 b->fp = (float **)malloc(num_channels * sizeof(float *)); 39 b->buf = (struct byte_buffer *) 40 calloc(1, sizeof(struct byte_buffer) + 41 max_size * num_channels * sizeof(float)); 42 b->buf->max_size = max_size; 43 b->buf->used_size = max_size; 44 return b; 45 } 46 47 /* Destroys the float buffer. */ 48 static inline void float_buffer_destroy(struct float_buffer **b) 49 { 50 if (*b == NULL) 51 return; 52 53 byte_buffer_destroy(&(*b)->buf); 54 free((*b)->fp); 55 free(*b); 56 *b = NULL; 57 } 58 59 /* Gets the write pointer of given float_buffer. */ 60 static inline float *const *float_buffer_write_pointer(struct float_buffer *b) 61 { 62 unsigned int i; 63 float *data = (float *)b->buf->bytes; 64 65 for (i = 0; i < b->num_channels; i++, data += b->buf->max_size) 66 b->fp[i] = data + b->buf->write_idx; 67 return b->fp; 68 } 69 70 /* Gets the number of frames can write to the float_buffer. */ 71 static inline unsigned int float_buffer_writable(struct float_buffer *b) 72 { 73 return buf_writable(b->buf); 74 } 75 76 /* Marks |nwritten| of frames as written to float_buffer. */ 77 static inline void float_buffer_written(struct float_buffer *b, 78 unsigned int nwritten) 79 { 80 buf_increment_write(b->buf, nwritten); 81 } 82 83 /* Gets the read pointer of given float_buffer. */ 84 static inline float *const *float_buffer_read_pointer(struct float_buffer *b, 85 unsigned int offset, 86 unsigned int *readable) 87 { 88 unsigned int i; 89 float *data = (float *)b->buf->bytes; 90 unsigned int nread = buf_readable(b->buf); 91 92 if (offset >= buf_queued(b->buf)) { 93 *readable = 0; 94 offset = 0; 95 } else if (offset >= nread) { 96 /* wraps */ 97 offset = offset + b->buf->read_idx - b->buf->max_size; 98 *readable = MIN(*readable, b->buf->write_idx - offset); 99 } else { 100 *readable = MIN(*readable, nread - offset); 101 offset += b->buf->read_idx; 102 } 103 104 for (i = 0; i < b->num_channels; i++, data += b->buf->max_size) 105 b->fp[i] = data + offset; 106 return b->fp; 107 } 108 109 /* Gets the buffer level in frames queued in float_buffer. */ 110 static inline unsigned int float_buffer_level(struct float_buffer *b) 111 { 112 return buf_queued(b->buf); 113 } 114 115 /* Resets float_buffer to initial state. */ 116 static inline void float_buffer_reset(struct float_buffer *b) 117 { 118 buf_reset(b->buf); 119 } 120 121 /* Marks |nread| frames as read in float_buffer. */ 122 static inline void float_buffer_read(struct float_buffer *b, 123 unsigned int nread) 124 { 125 buf_increment_read(b->buf, nread); 126 } 127 128 #endif /* FLOAT_BUFFER_H_ */ 129