forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuffer.h
More file actions
151 lines (126 loc) · 4.93 KB
/
buffer.h
File metadata and controls
151 lines (126 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
* Copyright (c) 2017, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Intel Corporation nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
*/
#ifndef __INCLUDE_AUDIO_BUFFER_H__
#define __INCLUDE_AUDIO_BUFFER_H__
#include <stdint.h>
#include <stddef.h>
#include <sof/lock.h>
#include <sof/list.h>
#include <sof/stream.h>
#include <sof/dma.h>
#include <sof/audio/component.h>
#include <sof/trace.h>
#include <sof/schedule.h>
#include <uapi/ipc/topology.h>
/* pipeline tracing */
#define trace_buffer(__e) trace_event(TRACE_CLASS_BUFFER, __e)
#define trace_buffer_error(__e) trace_error(TRACE_CLASS_BUFFER, __e)
#define tracev_buffer(__e) tracev_event(TRACE_CLASS_BUFFER, __e)
/* audio component buffer - connects 2 audio components together in pipeline */
struct comp_buffer {
/* runtime data */
uint32_t connected; /* connected in path */
uint32_t size; /* runtime buffer size in bytes (period multiple) */
uint32_t alloc_size; /* allocated size in bytes */
uint32_t avail; /* available bytes for reading */
uint32_t free; /* free bytes for writing */
void *w_ptr; /* buffer write pointer */
void *r_ptr; /* buffer read position */
void *addr; /* buffer base address */
void *end_addr; /* buffer end address */
/* IPC configuration */
struct sof_ipc_buffer ipc_buffer;
/* connected components */
struct comp_dev *source; /* source component */
struct comp_dev *sink; /* sink component */
/* lists */
struct list_item source_list; /* list in comp buffers */
struct list_item sink_list; /* list in comp buffers */
spinlock_t lock;
};
/* pipeline buffer creation and destruction */
struct comp_buffer *buffer_new(struct sof_ipc_buffer *desc);
void buffer_free(struct comp_buffer *buffer);
/* called by a component after producing data into this buffer */
void comp_update_buffer_produce(struct comp_buffer *buffer, uint32_t bytes);
/* called by a component after consuming data from this buffer */
void comp_update_buffer_consume(struct comp_buffer *buffer, uint32_t bytes);
static inline void buffer_zero(struct comp_buffer *buffer)
{
tracev_buffer("BZr");
bzero(buffer->addr, buffer->size);
if (buffer->ipc_buffer.caps & SOF_MEM_CAPS_DMA)
dcache_writeback_region(buffer->addr, buffer->size);
}
/* get the max number of bytes that can be copied between sink and source */
static inline int comp_buffer_can_copy_bytes(struct comp_buffer *source,
struct comp_buffer *sink, uint32_t bytes)
{
/* check for underrun */
if (source->avail < bytes)
return -1;
/* check for overrun */
if (sink->free < bytes)
return 1;
/* we are good to copy */
return 0;
}
static inline uint32_t comp_buffer_get_copy_bytes(struct comp_buffer *source,
struct comp_buffer *sink)
{
if (source->avail > sink->free)
return sink->free;
else
return source->avail;
}
static inline void buffer_reset_pos(struct comp_buffer *buffer)
{
/* reset read and write pointer to buffer bas */
buffer->w_ptr = buffer->r_ptr = buffer->addr;
/* free space is buffer size */
buffer->free = buffer->size;
/* ther are no avail samples at reset */
buffer->avail = 0;
/* clear buffer contents */
buffer_zero(buffer);
}
/* set the runtime size of a buffer in bytes and improve the data cache */
/* performance by only using minimum space needed for runtime params */
static inline int buffer_set_size(struct comp_buffer *buffer, uint32_t size)
{
if (size > buffer->alloc_size)
return -ENOMEM;
if (size == 0)
return -EINVAL;
buffer->end_addr = buffer->addr + size;
buffer->size = size;
return 0;
}
#endif