1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include <pthread.h>
7 #include <sys/param.h>
8 #include <syslog.h>
9
10 #include "cras_audio_area.h"
11 #include "cras_config.h"
12 #include "cras_iodev.h"
13 #include "cras_iodev_list.h"
14 #include "cras_rstream.h"
15 #include "cras_types.h"
16 #include "utlist.h"
17
18 #define EMPTY_BUFFER_SIZE (16 * 1024)
19 #define EMPTY_FRAME_SIZE 4
20 #define EMPTY_FRAMES (EMPTY_BUFFER_SIZE / EMPTY_FRAME_SIZE)
21
22 static size_t empty_supported_rates[] = { 44100, 48000, 0 };
23
24 static size_t empty_supported_channel_counts[] = { 1, 2, 0 };
25
26 static snd_pcm_format_t empty_supported_formats[] = {
27 SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S24_LE, SND_PCM_FORMAT_S32_LE,
28 SND_PCM_FORMAT_S24_3LE, 0
29 };
30
31 struct empty_iodev {
32 struct cras_iodev base;
33 uint8_t *audio_buffer;
34 uint64_t read_frames, written_frames;
35 struct timespec dev_start_time;
36 };
37
38 /*
39 * Current level of the audio buffer. This is made up based on what has been
40 * read/written and how long it has been since the start. Simulates audio
41 * hardware running at the given sample rate.
42 */
current_level(const struct cras_iodev * iodev)43 static unsigned int current_level(const struct cras_iodev *iodev)
44 {
45 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev;
46 uint64_t frames_since_start, nframes;
47
48 if (iodev->active_node->type == CRAS_NODE_TYPE_HOTWORD)
49 return 0;
50
51 frames_since_start = cras_frames_since_time(
52 &empty_iodev->dev_start_time, iodev->format->frame_rate);
53
54 if (iodev->direction == CRAS_STREAM_INPUT) {
55 nframes = frames_since_start - empty_iodev->read_frames;
56 return MIN(nframes, EMPTY_FRAMES);
57 }
58
59 /* output */
60 if (empty_iodev->written_frames <= frames_since_start)
61 return 0;
62 return empty_iodev->written_frames - frames_since_start;
63 }
64
65 /*
66 * iodev callbacks.
67 */
68
frames_queued(const struct cras_iodev * iodev,struct timespec * tstamp)69 static int frames_queued(const struct cras_iodev *iodev,
70 struct timespec *tstamp)
71 {
72 clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
73 return current_level(iodev);
74 }
75
delay_frames(const struct cras_iodev * iodev)76 static int delay_frames(const struct cras_iodev *iodev)
77 {
78 return 0;
79 }
80
close_dev(struct cras_iodev * iodev)81 static int close_dev(struct cras_iodev *iodev)
82 {
83 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev;
84
85 free(empty_iodev->audio_buffer);
86 empty_iodev->audio_buffer = NULL;
87 cras_iodev_free_audio_area(iodev);
88 return 0;
89 }
90
configure_dev(struct cras_iodev * iodev)91 static int configure_dev(struct cras_iodev *iodev)
92 {
93 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev;
94
95 if (iodev->format == NULL)
96 return -EINVAL;
97
98 cras_iodev_init_audio_area(iodev, iodev->format->num_channels);
99 empty_iodev->audio_buffer = calloc(1, EMPTY_BUFFER_SIZE);
100 empty_iodev->read_frames = 0;
101 empty_iodev->written_frames = 0;
102
103 clock_gettime(CLOCK_MONOTONIC_RAW, &empty_iodev->dev_start_time);
104
105 return 0;
106 }
107
get_buffer(struct cras_iodev * iodev,struct cras_audio_area ** area,unsigned * frames)108 static int get_buffer(struct cras_iodev *iodev, struct cras_audio_area **area,
109 unsigned *frames)
110 {
111 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev;
112 unsigned int avail, current;
113
114 if (iodev->direction == CRAS_STREAM_OUTPUT) {
115 avail = EMPTY_FRAMES - current_level(iodev);
116 *frames = MIN(*frames, avail);
117 } else {
118 current = current_level(iodev);
119 *frames = MIN(*frames, current);
120 }
121
122 iodev->area->frames = *frames;
123 cras_audio_area_config_buf_pointers(iodev->area, iodev->format,
124 empty_iodev->audio_buffer);
125 *area = iodev->area;
126 return 0;
127 }
128
129 /*
130 * Returns -EPIPE if there are not enough frames or spaces in device buffer.
131 * It matches other alsa-based devices.
132 */
put_buffer(struct cras_iodev * iodev,unsigned frames)133 static int put_buffer(struct cras_iodev *iodev, unsigned frames)
134 {
135 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev;
136
137 if (iodev->direction == CRAS_STREAM_INPUT) {
138 if (current_level(iodev) < frames)
139 return -EPIPE;
140 empty_iodev->read_frames += frames;
141 } else {
142 if (EMPTY_FRAMES - current_level(iodev) < frames)
143 return -EPIPE;
144 empty_iodev->written_frames += frames;
145 }
146 return 0;
147 }
148
flush_buffer(struct cras_iodev * iodev)149 static int flush_buffer(struct cras_iodev *iodev)
150 {
151 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev;
152
153 if (iodev->direction == CRAS_STREAM_INPUT)
154 empty_iodev->read_frames = 0;
155 else
156 empty_iodev->written_frames = 0;
157
158 clock_gettime(CLOCK_MONOTONIC_RAW, &empty_iodev->dev_start_time);
159 return 0;
160 }
161
update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)162 static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
163 unsigned dev_enabled)
164 {
165 }
166
167 /*
168 * Exported Interface.
169 */
170
empty_iodev_create(enum CRAS_STREAM_DIRECTION direction,enum CRAS_NODE_TYPE node_type)171 struct cras_iodev *empty_iodev_create(enum CRAS_STREAM_DIRECTION direction,
172 enum CRAS_NODE_TYPE node_type)
173 {
174 struct empty_iodev *empty_iodev;
175 struct cras_iodev *iodev;
176 struct cras_ionode *node;
177
178 if (direction != CRAS_STREAM_INPUT && direction != CRAS_STREAM_OUTPUT)
179 return NULL;
180
181 empty_iodev = calloc(1, sizeof(*empty_iodev));
182 if (empty_iodev == NULL)
183 return NULL;
184 iodev = &empty_iodev->base;
185 iodev->direction = direction;
186
187 iodev->supported_rates = empty_supported_rates;
188 iodev->supported_channel_counts = empty_supported_channel_counts;
189 iodev->supported_formats = empty_supported_formats;
190 iodev->buffer_size = EMPTY_FRAMES;
191
192 iodev->configure_dev = configure_dev;
193 iodev->close_dev = close_dev;
194 iodev->frames_queued = frames_queued;
195 iodev->delay_frames = delay_frames;
196 iodev->get_buffer = get_buffer;
197 iodev->put_buffer = put_buffer;
198 iodev->flush_buffer = flush_buffer;
199 iodev->update_active_node = update_active_node;
200 iodev->no_stream = cras_iodev_default_no_stream_playback;
201
202 /* Create a dummy ionode */
203 node = (struct cras_ionode *)calloc(1, sizeof(*node));
204 node->dev = iodev;
205 node->type = node_type;
206 node->volume = 100;
207 strcpy(node->name, "(default)");
208 cras_iodev_add_node(iodev, node);
209 cras_iodev_set_active_node(iodev, node);
210
211 /* Finally add it to the appropriate iodev list. */
212 if (direction == CRAS_STREAM_INPUT) {
213 if (node->type == CRAS_NODE_TYPE_HOTWORD) {
214 snprintf(iodev->info.name, ARRAY_SIZE(iodev->info.name),
215 "Silent hotword device.");
216 iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] =
217 '\0';
218 iodev->info.idx = SILENT_HOTWORD_DEVICE;
219 } else {
220 snprintf(iodev->info.name, ARRAY_SIZE(iodev->info.name),
221 "Silent record device.");
222 iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] =
223 '\0';
224 iodev->info.idx = SILENT_RECORD_DEVICE;
225 }
226 } else {
227 snprintf(iodev->info.name, ARRAY_SIZE(iodev->info.name),
228 "Silent playback device.");
229 iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = '\0';
230 iodev->info.idx = SILENT_PLAYBACK_DEVICE;
231 }
232
233 return iodev;
234 }
235
empty_iodev_destroy(struct cras_iodev * iodev)236 void empty_iodev_destroy(struct cras_iodev *iodev)
237 {
238 struct empty_iodev *empty_iodev = (struct empty_iodev *)iodev;
239
240 if (iodev->direction == CRAS_STREAM_INPUT)
241 cras_iodev_list_rm_input(iodev);
242 else
243 cras_iodev_list_rm_output(iodev);
244 free(iodev->active_node);
245 cras_iodev_free_resources(iodev);
246 free(empty_iodev);
247 }
248