Home | History | Annotate | Download | only in server
      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