forked from thesofproject/sof
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaudio_stream.c
More file actions
149 lines (117 loc) · 4.85 KB
/
audio_stream.c
File metadata and controls
149 lines (117 loc) · 4.85 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
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2023 Intel Corporation. All rights reserved.
//
#include <sof/audio/audio_stream.h>
#include <sof/audio/buffer.h>
static size_t audio_stream_get_free_size(struct sof_sink *sink)
{
struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api);
return audio_stream_get_free_bytes(audio_stream);
}
static int audio_stream_get_buffer(struct sof_sink *sink, size_t req_size,
void **data_ptr, void **buffer_start, size_t *buffer_size)
{
struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api);
if (req_size > audio_stream_get_free_size(sink))
return -ENODATA;
/* get circular buffer parameters */
*data_ptr = audio_stream->w_ptr;
*buffer_start = audio_stream->addr;
*buffer_size = audio_stream->size;
return 0;
}
static int audio_stream_commit_buffer(struct sof_sink *sink, size_t commit_size)
{
struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api);
struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream);
if (commit_size) {
buffer_stream_writeback(buffer, commit_size);
audio_stream_produce(audio_stream, commit_size);
}
return 0;
}
static size_t audio_stream_get_data_available(struct sof_source *source)
{
struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api);
return audio_stream_get_avail_bytes(audio_stream);
}
static int audio_stream_get_data(struct sof_source *source, size_t req_size,
void const **data_ptr, void const **buffer_start,
size_t *buffer_size)
{
struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api);
struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream);
if (req_size > audio_stream_get_data_available(source))
return -ENODATA;
buffer_stream_invalidate(buffer, req_size);
/* get circular buffer parameters */
*data_ptr = audio_stream->r_ptr;
*buffer_start = audio_stream->addr;
*buffer_size = audio_stream->size;
return 0;
}
static int audio_stream_release_data(struct sof_source *source, size_t free_size)
{
struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api);
if (free_size)
audio_stream_consume(audio_stream, free_size);
return 0;
}
static int audio_stream_set_ipc_params_source(struct sof_source *source,
struct sof_ipc_stream_params *params,
bool force_update)
{
struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api);
struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream);
return buffer_set_params(buffer, params, force_update);
}
static int audio_stream_set_ipc_params_sink(struct sof_sink *sink,
struct sof_ipc_stream_params *params,
bool force_update)
{
struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api);
struct comp_buffer *buffer = container_of(audio_stream, struct comp_buffer, stream);
return buffer_set_params(buffer, params, force_update);
}
static int audio_stream_source_set_alignment_constants(struct sof_source *source,
const uint32_t byte_align,
const uint32_t frame_align_req)
{
struct audio_stream *audio_stream = container_of(source, struct audio_stream, source_api);
audio_stream_init_alignment_constants(byte_align, frame_align_req, audio_stream);
return 0;
}
static int audio_stream_sink_set_alignment_constants(struct sof_sink *sink,
const uint32_t byte_align,
const uint32_t frame_align_req)
{
struct audio_stream *audio_stream = container_of(sink, struct audio_stream, sink_api);
audio_stream_init_alignment_constants(byte_align, frame_align_req, audio_stream);
return 0;
}
static const struct source_ops audio_stream_source_ops = {
.get_data_available = audio_stream_get_data_available,
.get_data = audio_stream_get_data,
.release_data = audio_stream_release_data,
.audio_set_ipc_params = audio_stream_set_ipc_params_source,
.set_alignment_constants = audio_stream_source_set_alignment_constants
};
static const struct sink_ops audio_stream_sink_ops = {
.get_free_size = audio_stream_get_free_size,
.get_buffer = audio_stream_get_buffer,
.commit_buffer = audio_stream_commit_buffer,
.audio_set_ipc_params = audio_stream_set_ipc_params_sink,
.set_alignment_constants = audio_stream_sink_set_alignment_constants
};
void audio_stream_init(struct audio_stream *audio_stream, void *buff_addr, uint32_t size)
{
audio_stream->size = size;
audio_stream->addr = buff_addr;
audio_stream->end_addr = (char *)audio_stream->addr + size;
source_init(audio_stream_get_source(audio_stream), &audio_stream_source_ops,
&audio_stream->runtime_stream_params);
sink_init(audio_stream_get_sink(audio_stream), &audio_stream_sink_ops,
&audio_stream->runtime_stream_params);
audio_stream_reset(audio_stream);
}