• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
float_buffer_create(unsigned int max_size,unsigned int num_channels)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. */
float_buffer_destroy(struct float_buffer ** b)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. */
float_buffer_write_pointer(struct float_buffer * b)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. */
float_buffer_writable(struct float_buffer * b)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. */
float_buffer_written(struct float_buffer * b,unsigned int nwritten)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. */
float_buffer_read_pointer(struct float_buffer * b,unsigned int offset,unsigned int * readable)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. */
float_buffer_level(struct float_buffer * b)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. */
float_buffer_reset(struct float_buffer * b)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. */
float_buffer_read(struct float_buffer * b,unsigned int nread)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