• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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