1 /* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2020 Intel Corporation. All rights reserved.
4 *
5 * Author: Karol Trzcinski <karolx.trzcinski@linux.intel.com>
6 */
7
8 /**
9 * \file include/sof/audio/audio_stream.h
10 * \brief Audio Stream API definition
11 * \author Karol Trzcinski <karolx.trzcinski@linux.intel.com>
12 */
13
14 #ifndef __SOF_AUDIO_AUDIO_STREAM_H__
15 #define __SOF_AUDIO_AUDIO_STREAM_H__
16
17 #include <sof/audio/format.h>
18 #include <sof/debug/panic.h>
19 #include <sof/math/numbers.h>
20 #include <sof/lib/alloc.h>
21 #include <sof/lib/cache.h>
22 #include <ipc/stream.h>
23
24 #include <stdbool.h>
25 #include <stdint.h>
26
27 /** \addtogroup audio_stream_api Audio Stream API
28 * @{
29 */
30
31 /**
32 * Audio stream is a circular buffer aware of audio format of the data
33 * in the buffer so provides API for reading and writing not only bytes,
34 * but also samples and frames.
35 *
36 * Audio stream does not perform any memory allocations. A client (a component
37 * buffer or dma) must allocate the memory for the underlying data buffer and
38 * provide it to the initialization routine.
39 *
40 * Once the client is done with reading/writing the data, it must commit the
41 * consumption/production and update the buffer state by calling
42 * audio_stream_consume()/audio_stream_produce() (just a single call following
43 * series of reads/writes).
44 */
45 struct audio_stream {
46 /* runtime data */
47 uint32_t size; /**< Runtime buffer size in bytes (period multiple) */
48 uint32_t avail; /**< Available bytes for reading */
49 uint32_t free; /**< Free bytes for writing */
50 void *w_ptr; /**< Buffer write pointer */
51 void *r_ptr; /**< Buffer read position */
52 void *addr; /**< Buffer base address */
53 void *end_addr; /**< Buffer end address */
54
55 /* runtime stream params */
56 enum sof_ipc_frame frame_fmt; /**< Sample data format */
57 uint32_t rate; /**< Number of data frames per second [Hz] */
58 uint16_t channels; /**< Number of samples in each frame */
59
60 bool overrun_permitted; /**< indicates whether overrun is permitted */
61 bool underrun_permitted; /**< indicates whether underrun is permitted */
62 };
63
64 /**
65 * Retrieves readable address of a sample at specified index (see versions of
66 * this macro specialized for various sample types).
67 * @param buffer Buffer.
68 * @param idx Index of sample.
69 * @param size Size of sample in bytes.
70 * @return Pointer to the sample.
71 *
72 * Once the consumer finishes reading samples from the buffer, it should
73 * "commit" the operation and update the buffer state by calling
74 * audio_stream_consume().
75 *
76 * @note Components should call comp_update_buffer_consume().
77 *
78 * @see audio_stream_get_frag().
79 * @see audio_stream_consume().
80 * @see comp_update_buffer_consume().
81 */
82 #define audio_stream_read_frag(buffer, idx, size) \
83 audio_stream_get_frag(buffer, (buffer)->r_ptr, idx, size)
84
85 /**
86 * Retrieves readable address of a signed 16-bit sample at specified index.
87 * @param buffer Buffer.
88 * @param idx Index of sample.
89 * @return Pointer to the sample.
90 *
91 * @see audio_stream_get_frag().
92 */
93 #define audio_stream_read_frag_s16(buffer, idx) \
94 audio_stream_get_frag(buffer, (buffer)->r_ptr, idx, sizeof(int16_t))
95
96 /**
97 * Retrieves readable address of a signed 32-bit sample at specified index.
98 * @param buffer Buffer.
99 * @param idx Index of sample.
100 * @return Pointer to the sample.
101 *
102 * @see audio_stream_get_frag().
103 */
104 #define audio_stream_read_frag_s32(buffer, idx) \
105 audio_stream_get_frag(buffer, (buffer)->r_ptr, idx, sizeof(int32_t))
106
107 /**
108 * Retrieves writeable address of a sample at specified index (see versions of
109 * this macro specialized for various sample types).
110 * @param buffer Buffer.
111 * @param idx Index of sample.
112 * @param size Size of sample in bytes.
113 * @return Pointer to the space for sample.
114 *
115 * Once the producer finishes writing samples to the buffer, it should
116 * "commit" the operation and update the buffer state by calling
117 * audio_stream_produce().
118 *
119 * @note Components should call comp_update_buffer_produce().
120 *
121 * @see audio_stream_get_frag().
122 * @see audio_stream_produce().
123 * @see comp_update_buffer_produce().
124 */
125 #define audio_stream_write_frag(buffer, idx, size) \
126 audio_stream_get_frag(buffer, (buffer)->w_ptr, idx, size)
127
128 /**
129 * Retrieves writeable address of a signed 16-bit sample at specified index.
130 * @param buffer Buffer.
131 * @param idx Index of sample.
132 * @return Pointer to the space for sample.
133 *
134 * @see audio_stream_get_frag().
135 */
136 #define audio_stream_write_frag_s16(buffer, idx) \
137 audio_stream_get_frag(buffer, (buffer)->w_ptr, idx, sizeof(int16_t))
138
139 /**
140 * Retrieves writeable address of a signed 32-bit sample at specified index.
141 * @param buffer Buffer.
142 * @param idx Index of sample.
143 * @return Pointer to the space for sample.
144 *
145 * @see audio_stream_get_frag().
146 */
147 #define audio_stream_write_frag_s32(buffer, idx) \
148 audio_stream_get_frag(buffer, (buffer)->w_ptr, idx, sizeof(int32_t))
149
150 /**
151 * Retrieves address of sample (space for sample) at specified index within
152 * the buffer. Index is interpreted as an offset relative to the specified
153 * pointer, rollover is ensured.
154 * @param buffer Circular buffer.
155 * @param ptr Pointer to start from, it may be either read or write pointer.
156 * @param idx Index of the sample.
157 * @param sample_size Size of the sample in bytes.
158 * @return Pointer to the sample.
159 */
160 #define audio_stream_get_frag(buffer, ptr, idx, sample_size) \
161 audio_stream_wrap(buffer, (char *)(ptr) + ((idx) * (sample_size)))
162
163 /**
164 * Applies parameters to the buffer.
165 * @param buffer Buffer.
166 * @param params Parameters (frame format, rate, number of channels).
167 * @return 0 if succeeded, error code otherwise.
168 */
audio_stream_set_params(struct audio_stream * buffer,struct sof_ipc_stream_params * params)169 static inline int audio_stream_set_params(struct audio_stream *buffer,
170 struct sof_ipc_stream_params *params)
171 {
172 if (!params)
173 return -EINVAL;
174
175 buffer->frame_fmt = params->frame_fmt;
176 buffer->rate = params->rate;
177 buffer->channels = params->channels;
178
179 return 0;
180 }
181
182 /**
183 * Calculates period size in bytes based on component stream's parameters.
184 * @param buf Component buffer.
185 * @return Period size in bytes.
186 */
audio_stream_frame_bytes(const struct audio_stream * buf)187 static inline uint32_t audio_stream_frame_bytes(const struct audio_stream *buf)
188 {
189 return get_frame_bytes(buf->frame_fmt, buf->channels);
190 }
191
192 /**
193 * Calculates sample size in bytes based on component stream's parameters.
194 * @param buf Component buffer.
195 * @return Size of sample in bytes.
196 */
audio_stream_sample_bytes(const struct audio_stream * buf)197 static inline uint32_t audio_stream_sample_bytes(const struct audio_stream *buf)
198 {
199 return get_sample_bytes(buf->frame_fmt);
200 }
201
202 /**
203 * Calculates period size in bytes based on component stream's parameters.
204 * @param buf Component buffer.
205 * @param frames Number of processing frames.
206 * @return Period size in bytes.
207 */
audio_stream_period_bytes(const struct audio_stream * buf,uint32_t frames)208 static inline uint32_t audio_stream_period_bytes(const struct audio_stream *buf,
209 uint32_t frames)
210 {
211 return frames * audio_stream_frame_bytes(buf);
212 }
213
214 /**
215 * Verifies the pointer and performs rollover when reached the end of
216 * the buffer.
217 * @param buffer Buffer accessed by the pointer.
218 * @param ptr Pointer
219 * @return Pointer, adjusted if necessary.
220 */
audio_stream_wrap(const struct audio_stream * buffer,void * ptr)221 static inline void *audio_stream_wrap(const struct audio_stream *buffer,
222 void *ptr)
223 {
224 if (ptr >= buffer->end_addr)
225 ptr = (char *)buffer->addr +
226 ((char *)ptr - (char *)buffer->end_addr);
227
228 return ptr;
229 }
230
231 /**
232 * Calculates available data in bytes, handling underrun_permitted behaviour
233 * @param stream Stream pointer
234 * @return amount of data available for processing in bytes
235 */
236 static inline uint32_t
audio_stream_get_avail_bytes(const struct audio_stream * stream)237 audio_stream_get_avail_bytes(const struct audio_stream *stream)
238 {
239 /*
240 * In case of underrun-permitted stream, report buffer full instead of
241 * empty. This way, any data present in such stream is processed at
242 * regular pace, but buffer will never be seen as completely empty by
243 * clients, and in turn will not cause underrun/XRUN.
244 */
245 if (stream->underrun_permitted)
246 return stream->avail != 0 ? stream->avail : stream->size;
247
248 return stream->avail;
249 }
250
251 /**
252 * Calculates available data in samples, handling underrun_permitted behaviour
253 * @param stream Stream pointer
254 * @return amount of data available for processing in samples
255 */
256 static inline uint32_t
audio_stream_get_avail_samples(const struct audio_stream * stream)257 audio_stream_get_avail_samples(const struct audio_stream *stream)
258 {
259 return audio_stream_get_avail_bytes(stream) /
260 audio_stream_sample_bytes(stream);
261 }
262
263 /**
264 * Calculates available data in frames, handling underrun_permitted behaviour
265 * @param stream Stream pointer
266 * @return amount of data available for processing in frames
267 */
268 static inline uint32_t
audio_stream_get_avail_frames(const struct audio_stream * stream)269 audio_stream_get_avail_frames(const struct audio_stream *stream)
270 {
271 return audio_stream_get_avail_bytes(stream) /
272 audio_stream_frame_bytes(stream);
273 }
274
275 /**
276 * Calculates free space in bytes, handling overrun_permitted behaviour
277 * @param stream Stream pointer
278 * @return amount of space free in bytes
279 */
280 static inline uint32_t
audio_stream_get_free_bytes(const struct audio_stream * stream)281 audio_stream_get_free_bytes(const struct audio_stream *stream)
282 {
283 /*
284 * In case of overrun-permitted stream, report buffer empty instead of
285 * full. This way, if there's any actual free space for data it is
286 * processed at regular pace, but buffer will never be seen as
287 * completely full by clients, and in turn will not cause overrun/XRUN.
288 */
289 if (stream->overrun_permitted)
290 return stream->free != 0 ? stream->free : stream->size;
291
292 return stream->free;
293 }
294
295 /**
296 * Calculates free space in samples, handling overrun_permitted behaviour
297 * @param stream Stream pointer
298 * @return amount of space free in samples
299 */
300 static inline uint32_t
audio_stream_get_free_samples(const struct audio_stream * stream)301 audio_stream_get_free_samples(const struct audio_stream *stream)
302 {
303 return audio_stream_get_free_bytes(stream) /
304 audio_stream_sample_bytes(stream);
305 }
306
307 /**
308 * Calculates free space in frames, handling overrun_permitted behaviour
309 * @param stream Stream pointer
310 * @return amount of space free in frames
311 */
312 static inline uint32_t
audio_stream_get_free_frames(const struct audio_stream * stream)313 audio_stream_get_free_frames(const struct audio_stream *stream)
314 {
315 return audio_stream_get_free_bytes(stream) /
316 audio_stream_frame_bytes(stream);
317 }
318
319 /**
320 * Verifies whether specified number of bytes can be copied from source buffer
321 * to sink buffer.
322 * @param source Source buffer.
323 * @param sink Sink buffer.
324 * @param bytes Number of bytes to copy.
325 * @return 0 if there is enough data in source and enough free space in sink.
326 * @return 1 if there is not enough free space in sink.
327 * @return -1 if there is not enough data in source.
328 */
audio_stream_can_copy_bytes(const struct audio_stream * source,const struct audio_stream * sink,uint32_t bytes)329 static inline int audio_stream_can_copy_bytes(const struct audio_stream *source,
330 const struct audio_stream *sink,
331 uint32_t bytes)
332 {
333 /* check for underrun */
334 if (audio_stream_get_avail_bytes(source) < bytes)
335 return -1;
336
337 /* check for overrun */
338 if (audio_stream_get_free_bytes(sink) < bytes)
339 return 1;
340
341 /* we are good to copy */
342 return 0;
343 }
344
345 /**
346 * Computes maximum number of bytes that can be copied from source buffer to
347 * sink buffer, verifying number of bytes available in source vs. free space
348 * available in sink.
349 * @param source Source buffer.
350 * @param sink Sink buffer.
351 * @return Number of bytes.
352 */
353 static inline uint32_t
audio_stream_get_copy_bytes(const struct audio_stream * source,const struct audio_stream * sink)354 audio_stream_get_copy_bytes(const struct audio_stream *source,
355 const struct audio_stream *sink)
356 {
357 uint32_t avail = audio_stream_get_avail_bytes(source);
358 uint32_t free = audio_stream_get_free_bytes(sink);
359
360 if (avail > free)
361 return free;
362 else
363 return avail;
364 }
365
366 /**
367 * Computes maximum number of frames that can be copied from source buffer
368 * to sink buffer, verifying number of available source frames vs. free
369 * space available in sink.
370 * @param source Source buffer.
371 * @param sink Sink buffer.
372 * @return Number of frames.
373 */
374 static inline uint32_t
audio_stream_avail_frames(const struct audio_stream * source,const struct audio_stream * sink)375 audio_stream_avail_frames(const struct audio_stream *source,
376 const struct audio_stream *sink)
377 {
378 uint32_t src_frames = audio_stream_get_avail_frames(source);
379 uint32_t sink_frames = audio_stream_get_free_frames(sink);
380
381 return MIN(src_frames, sink_frames);
382 }
383
384 /**
385 * Updates the buffer state after writing to the buffer.
386 * @param buffer Buffer to update.
387 * @param bytes Number of written bytes.
388 */
audio_stream_produce(struct audio_stream * buffer,uint32_t bytes)389 static inline void audio_stream_produce(struct audio_stream *buffer,
390 uint32_t bytes)
391 {
392 buffer->w_ptr = audio_stream_wrap(buffer,
393 (char *)buffer->w_ptr + bytes);
394
395 /* "overwrite" old data in circular wrap case */
396 if (bytes > audio_stream_get_free_bytes(buffer))
397 buffer->r_ptr = buffer->w_ptr;
398
399 /* calculate available bytes */
400 if (buffer->r_ptr < buffer->w_ptr)
401 buffer->avail = (char *)buffer->w_ptr - (char *)buffer->r_ptr;
402 else if (buffer->r_ptr == buffer->w_ptr)
403 buffer->avail = buffer->size; /* full */
404 else
405 buffer->avail = buffer->size -
406 ((char *)buffer->r_ptr - (char *)buffer->w_ptr);
407
408 /* calculate free bytes */
409 buffer->free = buffer->size - buffer->avail;
410 }
411
412 /**
413 * Updates the buffer state after reading from the buffer.
414 * @param buffer Buffer to update.
415 * @param bytes Number of read bytes.
416 */
audio_stream_consume(struct audio_stream * buffer,uint32_t bytes)417 static inline void audio_stream_consume(struct audio_stream *buffer,
418 uint32_t bytes)
419 {
420 buffer->r_ptr = audio_stream_wrap(buffer,
421 (char *)buffer->r_ptr + bytes);
422
423 /* calculate available bytes */
424 if (buffer->r_ptr < buffer->w_ptr)
425 buffer->avail = (char *)buffer->w_ptr - (char *)buffer->r_ptr;
426 else if (buffer->r_ptr == buffer->w_ptr)
427 buffer->avail = 0; /* empty */
428 else
429 buffer->avail = buffer->size -
430 ((char *)buffer->r_ptr - (char *)buffer->w_ptr);
431
432 /* calculate free bytes */
433 buffer->free = buffer->size - buffer->avail;
434 }
435
436 /**
437 * Resets the buffer.
438 * @param buffer Buffer to reset.
439 */
audio_stream_reset(struct audio_stream * buffer)440 static inline void audio_stream_reset(struct audio_stream *buffer)
441 {
442 /* reset read and write pointer to buffer bas */
443 buffer->w_ptr = buffer->addr;
444 buffer->r_ptr = buffer->addr;
445
446 /* free space is buffer size */
447 buffer->free = buffer->size;
448
449 /* there are no avail samples at reset */
450 buffer->avail = 0;
451 }
452
453 /**
454 * Initializes the buffer with specified memory block and size.
455 * @param buffer Buffer to initialize.
456 * @param buff_addr Address of the memory block to assign.
457 * @param size Size of the memory block in bytes.
458 */
audio_stream_init(struct audio_stream * buffer,void * buff_addr,uint32_t size)459 static inline void audio_stream_init(struct audio_stream *buffer,
460 void *buff_addr, uint32_t size)
461 {
462 buffer->size = size;
463 buffer->addr = buff_addr;
464 buffer->end_addr = (char *)buffer->addr + size;
465 audio_stream_reset(buffer);
466 }
467
468 /**
469 * Invalidates (in DSP d-cache) the buffer in range [r_ptr, r_ptr+bytes],
470 * with rollover if necessary.
471 * @param buffer Buffer.
472 * @param bytes Size of the fragment to invalidate.
473 */
audio_stream_invalidate(struct audio_stream * buffer,uint32_t bytes)474 static inline void audio_stream_invalidate(struct audio_stream *buffer,
475 uint32_t bytes)
476 {
477 uint32_t head_size = bytes;
478 uint32_t tail_size = 0;
479
480 /* check for potential wrap */
481 if ((char *)buffer->r_ptr + bytes > (char *)buffer->end_addr) {
482 head_size = (char *)buffer->end_addr - (char *)buffer->r_ptr;
483 tail_size = bytes - head_size;
484 }
485
486 dcache_invalidate_region(buffer->r_ptr, head_size);
487 if (tail_size)
488 dcache_invalidate_region(buffer->addr, tail_size);
489 }
490
491 /**
492 * Writes back (from DSP d-cache) the buffer in range [w_ptr, w_ptr+bytes],
493 * with rollover if necessary.
494 * @param buffer Buffer.
495 * @param bytes Size of the fragment to write back.
496 */
audio_stream_writeback(struct audio_stream * buffer,uint32_t bytes)497 static inline void audio_stream_writeback(struct audio_stream *buffer,
498 uint32_t bytes)
499 {
500 uint32_t head_size = bytes;
501 uint32_t tail_size = 0;
502
503 /* check for potential wrap */
504 if ((char *)buffer->w_ptr + bytes > (char *)buffer->end_addr) {
505 head_size = (char *)buffer->end_addr - (char *)buffer->w_ptr;
506 tail_size = bytes - head_size;
507 }
508
509 dcache_writeback_region(buffer->w_ptr, head_size);
510 if (tail_size)
511 dcache_writeback_region(buffer->addr, tail_size);
512 }
513
514 /**
515 * @brief Calculates numbers of bytes to buffer wrap and return
516 * minimum of calculated value and given bytes number.
517 * @param source Stream to get information from.
518 * @param ptr Read or write pointer from source
519 * @return Number of data samples to buffer wrap or given samples number.
520 */
521 static inline int
audio_stream_bytes_without_wrap(const struct audio_stream * source,const void * ptr)522 audio_stream_bytes_without_wrap(const struct audio_stream *source,
523 const void *ptr)
524 {
525 int to_end = (intptr_t)source->end_addr - (intptr_t)ptr;
526 return to_end;
527 }
528
529 /**
530 * @brief Calculates numbers of frames to buffer wrap and return
531 * minimum of calculated value.
532 * @param source Stream to get information from.
533 * @param ptr Read or write pointer from source
534 * @return Number of data frames to buffer wrap.
535 */
536 static inline uint32_t
audio_stream_frames_without_wrap(const struct audio_stream * source,const void * ptr)537 audio_stream_frames_without_wrap(const struct audio_stream *source,
538 const void *ptr)
539 {
540 uint32_t bytes = audio_stream_bytes_without_wrap(source, ptr);
541 uint32_t frame_bytes = audio_stream_frame_bytes(source);
542
543 return bytes / frame_bytes;
544 }
545
546 /**
547 * Copies data from source buffer to sink buffer.
548 * @param source Source buffer.
549 * @param ioffset Offset (in samples) in source buffer to start reading from.
550 * @param sink Sink buffer.
551 * @param ooffset Offset (in samples) in sink buffer to start writing to.
552 * @param samples Number of samples to copy.
553 * @return number of processed samples.
554 */
audio_stream_copy(const struct audio_stream * source,uint32_t ioffset,struct audio_stream * sink,uint32_t ooffset,uint32_t samples)555 static inline int audio_stream_copy(const struct audio_stream *source,
556 uint32_t ioffset,
557 struct audio_stream *sink,
558 uint32_t ooffset, uint32_t samples)
559 {
560 int ssize = audio_stream_sample_bytes(source); /* src fmt == sink fmt */
561 void *src = audio_stream_wrap(source,
562 (char *)source->r_ptr + ioffset * ssize);
563 void *snk = audio_stream_wrap(sink,
564 (char *)sink->w_ptr + ooffset * ssize);
565 uint32_t bytes = samples * ssize;
566 uint32_t bytes_src;
567 uint32_t bytes_snk;
568 uint32_t bytes_copied;
569 int ret;
570
571 while (bytes) {
572 bytes_src = audio_stream_bytes_without_wrap(source, src);
573 bytes_snk = audio_stream_bytes_without_wrap(sink, snk);
574 bytes_copied = MIN(bytes, MIN(bytes_src, bytes_snk));
575
576 ret = memcpy_s(snk, bytes_snk, src, bytes_copied);
577 assert(!ret);
578
579 bytes -= bytes_copied;
580 src = (char *)src + bytes_copied;
581 snk = (char *)snk + bytes_copied;
582
583 src = audio_stream_wrap(source, src);
584 snk = audio_stream_wrap(sink, snk);
585 }
586
587 return samples;
588 }
589
590 /**
591 * Writes zeros in range [w_ptr, w_ptr+bytes], with rollover if necessary.
592 * @param buffer Buffer.
593 * @param bytes Size of the fragment to write zero.
594 * @return 0 if there is enough free space in buffer.
595 * @return 1 if there is not enough free space in buffer.
596 */
audio_stream_set_zero(struct audio_stream * buffer,uint32_t bytes)597 static inline int audio_stream_set_zero(struct audio_stream *buffer,
598 uint32_t bytes)
599 {
600 uint32_t head_size = bytes;
601 uint32_t tail_size = 0;
602
603 /* check for overrun */
604 if (audio_stream_get_free_bytes(buffer) < bytes)
605 return 1;
606
607 /* check for potential wrap */
608 if ((char *)buffer->w_ptr + bytes > (char *)buffer->end_addr) {
609 head_size = (char *)buffer->end_addr - (char *)buffer->w_ptr;
610 tail_size = bytes - head_size;
611 }
612
613 memset(buffer->w_ptr, 0, head_size);
614 if (tail_size)
615 memset(buffer->addr, 0, tail_size);
616
617 return 0;
618 }
619
620 /** @}*/
621
622 #endif /* __SOF_AUDIO_AUDIO_STREAM_H__ */
623