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