Skip to content

Commit 137d087

Browse files
buf: extend audio_buf api and add default sink/src handlers
There are 3 APIs each buffer must implement (Sink/src/audio_buffer) for data producers/consumers/maintenance each of them need to have methods doing same operations - like settings stream parameters this commit provides simplification for buffer implementation - it is enough to implement those methods for audio_buffer API, default handlers for sink/src will propagate calls accordingly Specific handlers for sink and source may still be provided i.e. in case when sink or source API is not provided by a buffer but some other data producer (i.e. DAI) Also a default implementation of .audio_set_ipc_params is provided, that probably will fit needs of all buffers' implementation, except of currently used legacy comp_buffer Signed-off-by: Marcin Szkudlinski <marcin.szkudlinski@intel.com>
1 parent 61efedd commit 137d087

4 files changed

Lines changed: 166 additions & 18 deletions

File tree

src/audio/buffers/audio_buffer.c

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <stddef.h>
99
#include <errno.h>
1010
#include <rtos/alloc.h>
11+
#include <ipc/stream.h>
1112
#include <sof/audio/audio_buffer.h>
1213
#include <sof/audio/sink_api.h>
1314
#include <sof/audio/source_api.h>
@@ -95,3 +96,128 @@ void audio_buffer_free(struct sof_audio_buffer *buffer)
9596
buffer->ops->free(buffer);
9697
rfree(buffer);
9798
}
99+
100+
static
101+
int audio_buffer_source_set_ipc_params_default(struct sof_audio_buffer *buffer,
102+
struct sof_ipc_stream_params *params,
103+
bool force_update)
104+
{
105+
CORE_CHECK_STRUCT(buffer);
106+
107+
if (audio_buffer_hw_params_configured(buffer) && !force_update)
108+
return 0;
109+
110+
struct sof_audio_stream_params *audio_stream_params =
111+
audio_buffer_get_stream_params(buffer);
112+
113+
audio_stream_params->frame_fmt = params->frame_fmt;
114+
audio_stream_params->rate = params->rate;
115+
audio_stream_params->channels = params->channels;
116+
audio_stream_params->buffer_fmt = params->buffer_fmt;
117+
118+
audio_buffer_set_hw_params_configured(buffer);
119+
120+
if (buffer->ops->on_audio_format_set)
121+
return buffer->ops->on_audio_format_set(buffer);
122+
return 0;
123+
}
124+
125+
static
126+
int audio_buffer_sink_set_ipc_params(struct sof_sink *sink, struct sof_ipc_stream_params *params,
127+
bool force_update)
128+
{
129+
struct sof_audio_buffer *buffer = sof_audio_buffer_from_sink(sink);
130+
131+
if (buffer->ops->audio_set_ipc_params)
132+
return buffer->ops->audio_set_ipc_params(buffer, params, force_update);
133+
return audio_buffer_source_set_ipc_params_default(buffer, params, force_update);
134+
}
135+
136+
static
137+
int audio_buffer_sink_on_audio_format_set(struct sof_sink *sink)
138+
{
139+
struct sof_audio_buffer *buffer = sof_audio_buffer_from_sink(sink);
140+
141+
if (buffer->ops->on_audio_format_set)
142+
return buffer->ops->on_audio_format_set(buffer);
143+
return 0;
144+
}
145+
146+
static
147+
int audio_buffer_sink_set_alignment_constants(struct sof_sink *sink,
148+
const uint32_t byte_align,
149+
const uint32_t frame_align_req)
150+
{
151+
struct sof_audio_buffer *buffer = sof_audio_buffer_from_sink(sink);
152+
153+
if (buffer->ops->set_alignment_constants)
154+
return buffer->ops->set_alignment_constants(buffer, byte_align, frame_align_req);
155+
return 0;
156+
}
157+
158+
static
159+
int audio_buffer_source_set_ipc_params(struct sof_source *source,
160+
struct sof_ipc_stream_params *params, bool force_update)
161+
{
162+
struct sof_audio_buffer *buffer = sof_audio_buffer_from_source(source);
163+
164+
if (buffer->ops->audio_set_ipc_params)
165+
return buffer->ops->audio_set_ipc_params(buffer, params, force_update);
166+
return audio_buffer_source_set_ipc_params_default(buffer, params, force_update);
167+
}
168+
169+
static
170+
int audio_buffer_source_on_audio_format_set(struct sof_source *source)
171+
{
172+
struct sof_audio_buffer *buffer = sof_audio_buffer_from_source(source);
173+
174+
if (buffer->ops->on_audio_format_set)
175+
return buffer->ops->on_audio_format_set(buffer);
176+
return 0;
177+
}
178+
179+
static
180+
int audio_buffer_source_set_alignment_constants(struct sof_source *source,
181+
const uint32_t byte_align,
182+
const uint32_t frame_align_req)
183+
{
184+
struct sof_audio_buffer *buffer = sof_audio_buffer_from_source(source);
185+
186+
if (buffer->ops->set_alignment_constants)
187+
return buffer->ops->set_alignment_constants(buffer, byte_align, frame_align_req);
188+
return 0;
189+
}
190+
191+
void audio_buffer_init(struct sof_audio_buffer *buffer, uint32_t buffer_type, bool is_shared,
192+
struct source_ops *source_ops, struct sink_ops *sink_ops,
193+
const struct audio_buffer_ops *audio_buffer_ops,
194+
struct sof_audio_stream_params *audio_stream_params)
195+
{
196+
CORE_CHECK_STRUCT_INIT(&buffer, is_shared);
197+
buffer->buffer_type = buffer_type;
198+
buffer->ops = audio_buffer_ops;
199+
buffer->audio_stream_params = audio_stream_params;
200+
buffer->is_shared = is_shared;
201+
202+
/* set default implementations of sink/source methods, if there's no
203+
* specific implementation provided
204+
*/
205+
if (!sink_ops->audio_set_ipc_params)
206+
sink_ops->audio_set_ipc_params = audio_buffer_sink_set_ipc_params;
207+
if (!sink_ops->on_audio_format_set && buffer->ops->on_audio_format_set)
208+
sink_ops->on_audio_format_set = audio_buffer_sink_on_audio_format_set;
209+
if (!sink_ops->set_alignment_constants && buffer->ops->set_alignment_constants)
210+
sink_ops->set_alignment_constants = audio_buffer_sink_set_alignment_constants;
211+
212+
if (!source_ops->audio_set_ipc_params)
213+
source_ops->audio_set_ipc_params = audio_buffer_source_set_ipc_params;
214+
if (!source_ops->on_audio_format_set && buffer->ops->on_audio_format_set)
215+
source_ops->on_audio_format_set = audio_buffer_source_on_audio_format_set;
216+
if (!source_ops->set_alignment_constants && buffer->ops->set_alignment_constants)
217+
source_ops->set_alignment_constants = audio_buffer_source_set_alignment_constants;
218+
219+
source_init(audio_buffer_get_source(buffer), source_ops,
220+
audio_buffer_get_stream_params(buffer));
221+
sink_init(audio_buffer_get_sink(buffer), sink_ops,
222+
audio_buffer_get_stream_params(buffer));
223+
}

src/audio/buffers/comp_buffer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ static void comp_buffer_free(struct sof_audio_buffer *audio_buffer)
190190
rfree(buffer->stream.addr);
191191
}
192192

193-
static const struct source_ops comp_buffer_source_ops = {
193+
static struct source_ops comp_buffer_source_ops = {
194194
.get_data_available = comp_buffer_get_data_available,
195195
.get_data = comp_buffer_get_data,
196196
.release_data = comp_buffer_release_data,
@@ -199,7 +199,7 @@ static const struct source_ops comp_buffer_source_ops = {
199199
.set_alignment_constants = comp_buffer_source_set_alignment_constants
200200
};
201201

202-
static const struct sink_ops comp_buffer_sink_ops = {
202+
static struct sink_ops comp_buffer_sink_ops = {
203203
.get_free_size = comp_buffer_get_free_size,
204204
.get_buffer = comp_buffer_get_buffer,
205205
.commit_buffer = comp_buffer_commit_buffer,

src/audio/buffers/ring_buffer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,14 +284,14 @@ static int ring_buffer_set_ipc_params_sink(struct sof_sink *sink,
284284
return ring_buffer_set_ipc_params(ring_buffer, params, force_update);
285285
}
286286

287-
static const struct source_ops ring_buffer_source_ops = {
287+
static struct source_ops ring_buffer_source_ops = {
288288
.get_data_available = ring_buffer_get_data_available,
289289
.get_data = ring_buffer_get_data,
290290
.release_data = ring_buffer_release_data,
291291
.audio_set_ipc_params = ring_buffer_set_ipc_params_source,
292292
};
293293

294-
static const struct sink_ops ring_buffer_sink_ops = {
294+
static struct sink_ops ring_buffer_sink_ops = {
295295
.get_free_size = ring_buffer_get_free_size,
296296
.get_buffer = ring_buffer_get_buffer,
297297
.commit_buffer = ring_buffer_commit_buffer,

src/include/sof/audio/audio_buffer.h

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,32 @@ struct audio_buffer_ops {
3232
* OPTIONAL
3333
*/
3434
void (*clean)(struct sof_audio_buffer *buffer);
35+
36+
/**
37+
* OPTIONAL: Notification to the sink implementation about changes in audio format
38+
*
39+
* Once any of *audio_stream_params elements changes, the implementation of
40+
* sink may need to perform some extra operations.
41+
* This callback will be called immediately after any change
42+
*
43+
* @retval 0 if success, negative if new parameters are not supported
44+
*/
45+
int (*on_audio_format_set)(struct sof_audio_buffer *buffer);
46+
47+
/**
48+
* OPTIONAL
49+
* see sink_set_params comments
50+
*/
51+
int (*audio_set_ipc_params)(struct sof_audio_buffer *buffer,
52+
struct sof_ipc_stream_params *params, bool force_update);
53+
54+
/**
55+
* OPTIONAL
56+
* see comment for sink_set_alignment_constants
57+
*/
58+
int (*set_alignment_constants)(struct sof_audio_buffer *buffer,
59+
const uint32_t byte_align,
60+
const uint32_t frame_align_req);
3561
};
3662

3763
/* base class for all buffers, all buffers must inherit from it */
@@ -251,23 +277,19 @@ static inline struct sof_audio_buffer *sof_audio_buffer_from_source(struct sof_s
251277
* @param sink_ops pointer to virtual methods table for sink API
252278
* @param audio_buffer_ops pointer to required buffer virtual methods implementation
253279
* @param audio_stream_params pointer to audio stream (currently kept in buffer implementation)
280+
*
281+
* in sink_ops and source_ops API if there's no implemented of following methods:
282+
* on_audio_format_set
283+
* audio_set_ipc_params
284+
* set_alignment_constants
285+
*
286+
* default implementation will be used instead, redirecting those calls to proper
287+
* audio_buffer_ops operations
254288
*/
255-
static inline
256289
void audio_buffer_init(struct sof_audio_buffer *buffer, uint32_t buffer_type, bool is_shared,
257-
const struct source_ops *source_ops, const struct sink_ops *sink_ops,
290+
struct source_ops *source_ops, struct sink_ops *sink_ops,
258291
const struct audio_buffer_ops *audio_buffer_ops,
259-
struct sof_audio_stream_params *audio_stream_params)
260-
{
261-
CORE_CHECK_STRUCT_INIT(&buffer, is_shared);
262-
buffer->buffer_type = buffer_type;
263-
buffer->ops = audio_buffer_ops;
264-
buffer->audio_stream_params = audio_stream_params;
265-
buffer->is_shared = is_shared;
266-
source_init(audio_buffer_get_source(buffer), source_ops,
267-
audio_buffer_get_stream_params(buffer));
268-
sink_init(audio_buffer_get_sink(buffer), sink_ops,
269-
audio_buffer_get_stream_params(buffer));
270-
}
292+
struct sof_audio_stream_params *audio_stream_params);
271293

272294
/**
273295
* @brief free buffer and all allocated resources

0 commit comments

Comments
 (0)