1 /* Copyright (c) 2013 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 "audio_thread_log.h"
11 #include "byte_buffer.h"
12 #include "cras_audio_area.h"
13 #include "cras_config.h"
14 #include "cras_iodev.h"
15 #include "cras_iodev_list.h"
16 #include "cras_types.h"
17 #include "cras_util.h"
18 #include "sfh.h"
19 #include "utlist.h"
20
21 #define LOOPBACK_BUFFER_SIZE 8192
22
23 static const char *loopdev_names[LOOPBACK_NUM_TYPES] = {
24 "Post Mix Pre DSP Loopback",
25 "Post DSP Loopback",
26 };
27
28 static size_t loopback_supported_rates[] = { 48000, 0 };
29
30 static size_t loopback_supported_channel_counts[] = { 2, 0 };
31
32 static snd_pcm_format_t loopback_supported_formats[] = {
33 SND_PCM_FORMAT_S16_LE,
34 0,
35 };
36
37 /* loopack iodev. Keep state of a loopback device.
38 * loopback_type - Pre-dsp or post-dsp.
39 * read_frames - Frames of audio data read since last dev start.
40 * started - True to indicate the target device is running, otherwise false.
41 * dev_start_time - The timestamp of the last call to configure_dev.
42 * sample_buffer - Pointer to sample buffer.
43 * sender_idx - Index of the output device to read loopback audio.
44 */
45 struct loopback_iodev {
46 struct cras_iodev base;
47 enum CRAS_LOOPBACK_TYPE loopback_type;
48 uint64_t read_frames;
49 bool started;
50 struct timespec dev_start_time;
51 struct byte_buffer *sample_buffer;
52 unsigned int sender_idx;
53 };
54
sample_hook_start(bool start,void * cb_data)55 static int sample_hook_start(bool start, void *cb_data)
56 {
57 struct loopback_iodev *loopdev = (struct loopback_iodev *)cb_data;
58 loopdev->started = start;
59 return 0;
60 }
61
62 /*
63 * Called in the put buffer function of the sender that hooked to.
64 *
65 * Returns:
66 * Number of frames copied to the sample buffer in the hook.
67 */
sample_hook(const uint8_t * frames,unsigned int nframes,const struct cras_audio_format * fmt,void * cb_data)68 static int sample_hook(const uint8_t *frames, unsigned int nframes,
69 const struct cras_audio_format *fmt, void *cb_data)
70 {
71 struct loopback_iodev *loopdev = (struct loopback_iodev *)cb_data;
72 struct byte_buffer *sbuf = loopdev->sample_buffer;
73 unsigned int frame_bytes = cras_get_format_bytes(fmt);
74 unsigned int frames_to_copy, bytes_to_copy, frames_copied = 0;
75 int i;
76
77 for (i = 0; i < 2; i++) {
78 frames_to_copy = MIN(buf_writable(sbuf) / frame_bytes, nframes);
79 if (!frames_to_copy)
80 break;
81
82 bytes_to_copy = frames_to_copy * frame_bytes;
83 memcpy(buf_write_pointer(sbuf), frames, bytes_to_copy);
84 buf_increment_write(sbuf, bytes_to_copy);
85 frames += bytes_to_copy;
86 nframes -= frames_to_copy;
87 frames_copied += frames_to_copy;
88 }
89
90 ATLOG(atlog, AUDIO_THREAD_LOOPBACK_SAMPLE_HOOK, nframes + frames_copied,
91 frames_copied, 0);
92
93 return frames_copied;
94 }
95
update_first_output_to_loopback(struct loopback_iodev * loopdev)96 static void update_first_output_to_loopback(struct loopback_iodev *loopdev)
97 {
98 struct cras_iodev *edev;
99
100 /* Register loopback hook onto first enabled iodev. */
101 edev = cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT);
102 if (edev) {
103 loopdev->sender_idx = edev->info.idx;
104 cras_iodev_list_register_loopback(
105 loopdev->loopback_type, loopdev->sender_idx,
106 sample_hook, sample_hook_start, loopdev->base.info.idx);
107 }
108 }
109
device_enabled_hook(struct cras_iodev * iodev,void * cb_data)110 static void device_enabled_hook(struct cras_iodev *iodev, void *cb_data)
111 {
112 struct loopback_iodev *loopdev = (struct loopback_iodev *)cb_data;
113
114 if (iodev->direction != CRAS_STREAM_OUTPUT)
115 return;
116
117 update_first_output_to_loopback(loopdev);
118 }
119
device_disabled_hook(struct cras_iodev * iodev,void * cb_data)120 static void device_disabled_hook(struct cras_iodev *iodev, void *cb_data)
121 {
122 struct loopback_iodev *loopdev = (struct loopback_iodev *)cb_data;
123
124 if (loopdev->sender_idx != iodev->info.idx)
125 return;
126
127 /* Unregister loopback hook from disabled iodev. */
128 cras_iodev_list_unregister_loopback(loopdev->loopback_type,
129 loopdev->sender_idx,
130 loopdev->base.info.idx);
131 update_first_output_to_loopback(loopdev);
132 }
133
134 /*
135 * iodev callbacks.
136 */
137
frames_queued(const struct cras_iodev * iodev,struct timespec * hw_tstamp)138 static int frames_queued(const struct cras_iodev *iodev,
139 struct timespec *hw_tstamp)
140 {
141 struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
142 struct byte_buffer *sbuf = loopdev->sample_buffer;
143 unsigned int frame_bytes = cras_get_format_bytes(iodev->format);
144
145 if (!loopdev->started) {
146 unsigned int frames_since_start, frames_to_fill, bytes_to_fill;
147
148 frames_since_start = cras_frames_since_time(
149 &loopdev->dev_start_time, iodev->format->frame_rate);
150 frames_to_fill =
151 frames_since_start > loopdev->read_frames ?
152 frames_since_start - loopdev->read_frames :
153 0;
154 frames_to_fill =
155 MIN(buf_writable(sbuf) / frame_bytes, frames_to_fill);
156 if (frames_to_fill > 0) {
157 bytes_to_fill = frames_to_fill * frame_bytes;
158 memset(buf_write_pointer(sbuf), 0, bytes_to_fill);
159 buf_increment_write(sbuf, bytes_to_fill);
160 }
161 }
162 clock_gettime(CLOCK_MONOTONIC_RAW, hw_tstamp);
163 return buf_queued(sbuf) / frame_bytes;
164 }
165
delay_frames(const struct cras_iodev * iodev)166 static int delay_frames(const struct cras_iodev *iodev)
167 {
168 struct timespec tstamp;
169
170 return frames_queued(iodev, &tstamp);
171 }
172
close_record_dev(struct cras_iodev * iodev)173 static int close_record_dev(struct cras_iodev *iodev)
174 {
175 struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
176 struct byte_buffer *sbuf = loopdev->sample_buffer;
177
178 cras_iodev_free_format(iodev);
179 cras_iodev_free_audio_area(iodev);
180 buf_reset(sbuf);
181
182 cras_iodev_list_unregister_loopback(loopdev->loopback_type,
183 loopdev->sender_idx,
184 loopdev->base.info.idx);
185 loopdev->sender_idx = NO_DEVICE;
186 cras_iodev_list_set_device_enabled_callback(NULL, NULL, (void *)iodev);
187
188 return 0;
189 }
190
configure_record_dev(struct cras_iodev * iodev)191 static int configure_record_dev(struct cras_iodev *iodev)
192 {
193 struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
194 struct cras_iodev *edev;
195
196 cras_iodev_init_audio_area(iodev, iodev->format->num_channels);
197 clock_gettime(CLOCK_MONOTONIC_RAW, &loopdev->dev_start_time);
198 loopdev->read_frames = 0;
199 loopdev->started = 0;
200
201 edev = cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT);
202 if (edev) {
203 loopdev->sender_idx = edev->info.idx;
204 cras_iodev_list_register_loopback(
205 loopdev->loopback_type, loopdev->sender_idx,
206 sample_hook, sample_hook_start, iodev->info.idx);
207 }
208 cras_iodev_list_set_device_enabled_callback(
209 device_enabled_hook, device_disabled_hook, (void *)iodev);
210
211 return 0;
212 }
213
get_record_buffer(struct cras_iodev * iodev,struct cras_audio_area ** area,unsigned * frames)214 static int get_record_buffer(struct cras_iodev *iodev,
215 struct cras_audio_area **area, unsigned *frames)
216 {
217 struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
218 struct byte_buffer *sbuf = loopdev->sample_buffer;
219 unsigned int frame_bytes = cras_get_format_bytes(iodev->format);
220 unsigned int avail_frames = buf_readable(sbuf) / frame_bytes;
221
222 ATLOG(atlog, AUDIO_THREAD_LOOPBACK_GET, *frames, avail_frames, 0);
223
224 *frames = MIN(avail_frames, *frames);
225 iodev->area->frames = *frames;
226 cras_audio_area_config_buf_pointers(iodev->area, iodev->format,
227 buf_read_pointer(sbuf));
228 *area = iodev->area;
229
230 return 0;
231 }
232
put_record_buffer(struct cras_iodev * iodev,unsigned nframes)233 static int put_record_buffer(struct cras_iodev *iodev, unsigned nframes)
234 {
235 struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
236 struct byte_buffer *sbuf = loopdev->sample_buffer;
237 unsigned int frame_bytes = cras_get_format_bytes(iodev->format);
238
239 buf_increment_read(sbuf, (size_t)nframes * (size_t)frame_bytes);
240 loopdev->read_frames += nframes;
241 ATLOG(atlog, AUDIO_THREAD_LOOPBACK_PUT, nframes, 0, 0);
242 return 0;
243 }
244
flush_record_buffer(struct cras_iodev * iodev)245 static int flush_record_buffer(struct cras_iodev *iodev)
246 {
247 struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
248 struct byte_buffer *sbuf = loopdev->sample_buffer;
249 unsigned int queued_bytes = buf_queued(sbuf);
250 buf_increment_read(sbuf, queued_bytes);
251 loopdev->read_frames = 0;
252 return 0;
253 }
254
update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)255 static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
256 unsigned dev_enabled)
257 {
258 }
259
create_loopback_iodev(enum CRAS_LOOPBACK_TYPE type)260 static struct cras_iodev *create_loopback_iodev(enum CRAS_LOOPBACK_TYPE type)
261 {
262 struct loopback_iodev *loopback_iodev;
263 struct cras_iodev *iodev;
264
265 loopback_iodev = calloc(1, sizeof(*loopback_iodev));
266 if (loopback_iodev == NULL)
267 return NULL;
268
269 loopback_iodev->sample_buffer = byte_buffer_create(1024 * 16 * 4);
270 if (loopback_iodev->sample_buffer == NULL) {
271 free(loopback_iodev);
272 return NULL;
273 }
274
275 loopback_iodev->loopback_type = type;
276
277 iodev = &loopback_iodev->base;
278 iodev->direction = CRAS_STREAM_INPUT;
279 snprintf(iodev->info.name, ARRAY_SIZE(iodev->info.name), "%s",
280 loopdev_names[type]);
281 iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = '\0';
282 iodev->info.stable_id =
283 SuperFastHash(iodev->info.name, strlen(iodev->info.name),
284 strlen(iodev->info.name));
285
286 iodev->supported_rates = loopback_supported_rates;
287 iodev->supported_channel_counts = loopback_supported_channel_counts;
288 iodev->supported_formats = loopback_supported_formats;
289 iodev->buffer_size = LOOPBACK_BUFFER_SIZE;
290
291 iodev->frames_queued = frames_queued;
292 iodev->delay_frames = delay_frames;
293 iodev->update_active_node = update_active_node;
294 iodev->configure_dev = configure_record_dev;
295 iodev->close_dev = close_record_dev;
296 iodev->get_buffer = get_record_buffer;
297 iodev->put_buffer = put_record_buffer;
298 iodev->flush_buffer = flush_record_buffer;
299
300 /*
301 * Record max supported channels into cras_iodev_info.
302 * The value is the max of loopback_supported_channel_counts.
303 */
304 iodev->info.max_supported_channels = 2;
305
306 return iodev;
307 }
308
309 /*
310 * Exported Interface.
311 */
312
loopback_iodev_create(enum CRAS_LOOPBACK_TYPE type)313 struct cras_iodev *loopback_iodev_create(enum CRAS_LOOPBACK_TYPE type)
314 {
315 struct cras_iodev *iodev;
316 struct cras_ionode *node;
317 enum CRAS_NODE_TYPE node_type;
318
319 switch (type) {
320 case LOOPBACK_POST_MIX_PRE_DSP:
321 node_type = CRAS_NODE_TYPE_POST_MIX_PRE_DSP;
322 break;
323 case LOOPBACK_POST_DSP:
324 node_type = CRAS_NODE_TYPE_POST_DSP;
325 break;
326 default:
327 return NULL;
328 }
329
330 iodev = create_loopback_iodev(type);
331 if (iodev == NULL)
332 return NULL;
333
334 /* Create an empty ionode */
335 node = (struct cras_ionode *)calloc(1, sizeof(*node));
336 node->dev = iodev;
337 node->type = node_type;
338 node->plugged = 1;
339 node->volume = 100;
340 node->ui_gain_scaler = 1.0f;
341 node->stable_id = iodev->info.stable_id;
342 node->software_volume_needed = 0;
343 strcpy(node->name, loopdev_names[type]);
344 cras_iodev_add_node(iodev, node);
345 cras_iodev_set_active_node(iodev, node);
346
347 cras_iodev_list_add_input(iodev);
348
349 return iodev;
350 }
351
loopback_iodev_destroy(struct cras_iodev * iodev)352 void loopback_iodev_destroy(struct cras_iodev *iodev)
353 {
354 struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
355 struct byte_buffer *sbuf = loopdev->sample_buffer;
356
357 cras_iodev_list_rm_input(iodev);
358 free(iodev->nodes);
359
360 byte_buffer_destroy(&sbuf);
361 free(loopdev);
362 }
363