• 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 "byte_buffer.h"
11 #include "cras_audio_area.h"
12 #include "cras_config.h"
13 #include "cras_iodev.h"
14 #include "cras_iodev_list.h"
15 #include "cras_types.h"
16 #include "cras_util.h"
17 #include "sfh.h"
18 #include "utlist.h"
19 
20 #define LOOPBACK_BUFFER_SIZE 8192
21 
22 static const char *loopdev_names[LOOPBACK_NUM_TYPES] = {
23 	"Post Mix Pre DSP Loopback",
24 	"Post DSP Loopback",
25 };
26 
27 static size_t loopback_supported_rates[] = {
28 	48000, 0
29 };
30 
31 static size_t loopback_supported_channel_counts[] = {
32 	2, 0
33 };
34 
35 static snd_pcm_format_t loopback_supported_formats[] = {
36 	SND_PCM_FORMAT_S16_LE,
37 	0
38 };
39 
40 /* loopack iodev.  Keep state of a loopback device.
41  *    sample_buffer - Pointer to sample buffer.
42  */
43 struct loopback_iodev {
44 	struct cras_iodev base;
45 	enum CRAS_LOOPBACK_TYPE loopback_type;
46 	struct timespec last_filled;
47 	struct byte_buffer *sample_buffer;
48 };
49 
sample_hook(const uint8_t * frames,unsigned int nframes,const struct cras_audio_format * fmt,void * cb_data)50 static int sample_hook(const uint8_t *frames, unsigned int nframes,
51 		       const struct cras_audio_format *fmt,
52 		       void *cb_data)
53 {
54 	struct loopback_iodev *loopdev = (struct loopback_iodev *)cb_data;
55 	struct byte_buffer *sbuf = loopdev->sample_buffer;
56 	unsigned int frame_bytes = cras_get_format_bytes(fmt);
57 	unsigned int frames_to_copy, bytes_to_copy;
58 	struct cras_iodev *edev = cras_iodev_list_get_first_enabled_iodev(
59 			CRAS_STREAM_OUTPUT);
60 
61 	/* If there's no active streams, the logic in frames_queued will fill
62 	 * zeros for loopback capture, do not accept zeros for draining device.
63 	 */
64 	if (!edev || !edev->streams)
65 		return 0;
66 
67 	frames_to_copy = MIN(buf_writable_bytes(sbuf) / frame_bytes, nframes);
68 	if (!frames_to_copy)
69 		return 0;
70 
71 	bytes_to_copy = frames_to_copy * frame_bytes;
72 	memcpy(buf_write_pointer(sbuf), frames, bytes_to_copy);
73 	buf_increment_write(sbuf, bytes_to_copy);
74 	clock_gettime(CLOCK_MONOTONIC_RAW, &loopdev->last_filled);
75 
76 	return frames_to_copy;
77 }
78 
register_loopback_hook(enum CRAS_LOOPBACK_TYPE loopback_type,struct cras_iodev * iodev,loopback_hook_t hook,void * cb_data)79 static void register_loopback_hook(enum CRAS_LOOPBACK_TYPE loopback_type,
80 				   struct cras_iodev *iodev,
81 				   loopback_hook_t hook, void *cb_data)
82 {
83 	if (!iodev) {
84 		syslog(LOG_ERR, "Failed to register loopback hook.");
85 		return;
86 	}
87 
88 	if (loopback_type == LOOPBACK_POST_MIX_PRE_DSP)
89 		cras_iodev_register_pre_dsp_hook(iodev, hook, cb_data);
90 	else if (loopback_type == LOOPBACK_POST_DSP)
91 		cras_iodev_register_post_dsp_hook(iodev, hook, cb_data);
92 }
93 
device_enabled_hook(struct cras_iodev * iodev,int enabled,void * cb_data)94 static void device_enabled_hook(struct cras_iodev *iodev, int enabled,
95 				void *cb_data)
96 {
97 	struct loopback_iodev *loopdev = (struct loopback_iodev *)cb_data;
98 	struct cras_iodev *edev;
99 
100 	if (iodev->direction != CRAS_STREAM_OUTPUT)
101 		return;
102 
103 	if (!enabled) {
104 		/* Unregister loopback hook from disabled iodev. */
105 		register_loopback_hook(loopdev->loopback_type, iodev, NULL,
106 				       NULL);
107 	} else {
108 		/* Register loopback hook onto first enabled iodev. */
109 		edev = cras_iodev_list_get_first_enabled_iodev(
110 				CRAS_STREAM_OUTPUT);
111 		register_loopback_hook(loopdev->loopback_type, edev,
112 				       sample_hook, cb_data);
113 	}
114 }
115 
116 /*
117  * iodev callbacks.
118  */
119 
frames_queued(const struct cras_iodev * iodev,struct timespec * hw_tstamp)120 static int frames_queued(const struct cras_iodev *iodev,
121 			 struct timespec *hw_tstamp)
122 {
123 	struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
124 	struct byte_buffer *sbuf = loopdev->sample_buffer;
125 	unsigned int frame_bytes = cras_get_format_bytes(iodev->format);
126 	struct cras_iodev *edev = cras_iodev_list_get_first_enabled_iodev(
127 			CRAS_STREAM_OUTPUT);
128 
129 	if (!edev || !edev->streams) {
130 		unsigned int frames_since_last, frames_to_fill, bytes_to_fill;
131 
132 		frames_since_last = cras_frames_since_time(
133 				&loopdev->last_filled,
134 				iodev->format->frame_rate);
135 		frames_to_fill = MIN(buf_writable_bytes(sbuf) / frame_bytes,
136 				     frames_since_last);
137 		if (frames_to_fill > 0) {
138 			bytes_to_fill = frames_to_fill * frame_bytes;
139 			memset(buf_write_pointer(sbuf), 0, bytes_to_fill);
140 			buf_increment_write(sbuf, bytes_to_fill);
141 			clock_gettime(CLOCK_MONOTONIC_RAW,
142 				      &loopdev->last_filled);
143 		}
144 	}
145 	*hw_tstamp = loopdev->last_filled;
146 	return buf_queued_bytes(sbuf) / frame_bytes;
147 }
148 
delay_frames(const struct cras_iodev * iodev)149 static int delay_frames(const struct cras_iodev *iodev)
150 {
151 	struct timespec tstamp;
152 
153 	return frames_queued(iodev, &tstamp);
154 }
155 
close_record_dev(struct cras_iodev * iodev)156 static int close_record_dev(struct cras_iodev *iodev)
157 {
158 	struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
159 	struct byte_buffer *sbuf = loopdev->sample_buffer;
160 	struct cras_iodev *edev;
161 
162 	cras_iodev_free_format(iodev);
163 	cras_iodev_free_audio_area(iodev);
164 	buf_reset(sbuf);
165 
166 	edev = cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT);
167 	register_loopback_hook(loopdev->loopback_type, edev, NULL, NULL);
168 	cras_iodev_list_set_device_enabled_callback(NULL, NULL);
169 
170 	return 0;
171 }
172 
open_record_dev(struct cras_iodev * iodev)173 static int open_record_dev(struct cras_iodev *iodev)
174 {
175 	struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
176 	struct cras_iodev *edev;
177 
178 	cras_iodev_init_audio_area(iodev, iodev->format->num_channels);
179 	clock_gettime(CLOCK_MONOTONIC_RAW, &loopdev->last_filled);
180 
181 	edev = cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT);
182 	register_loopback_hook(loopdev->loopback_type, edev, sample_hook,
183 			       (void *)iodev);
184 	cras_iodev_list_set_device_enabled_callback(device_enabled_hook,
185 						    (void *)iodev);
186 
187 	return 0;
188 }
189 
get_record_buffer(struct cras_iodev * iodev,struct cras_audio_area ** area,unsigned * frames)190 static int get_record_buffer(struct cras_iodev *iodev,
191 		      struct cras_audio_area **area,
192 		      unsigned *frames)
193 {
194 	struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
195 	struct byte_buffer *sbuf = loopdev->sample_buffer;
196 	unsigned int frame_bytes = cras_get_format_bytes(iodev->format);
197 	unsigned int avail_frames = buf_readable_bytes(sbuf) / frame_bytes;
198 
199 	*frames = MIN(avail_frames, *frames);
200 	iodev->area->frames = *frames;
201 	cras_audio_area_config_buf_pointers(iodev->area, iodev->format,
202 					    buf_read_pointer(sbuf));
203 	*area = iodev->area;
204 
205 	return 0;
206 }
207 
put_record_buffer(struct cras_iodev * iodev,unsigned nframes)208 static int put_record_buffer(struct cras_iodev *iodev, unsigned nframes)
209 {
210 	struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
211 	struct byte_buffer *sbuf = loopdev->sample_buffer;
212 	unsigned int frame_bytes = cras_get_format_bytes(iodev->format);
213 
214 	buf_increment_read(sbuf, nframes * frame_bytes);
215 
216 	return 0;
217 }
218 
flush_record_buffer(struct cras_iodev * iodev)219 static int flush_record_buffer(struct cras_iodev *iodev)
220 {
221 	struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
222 	struct byte_buffer *sbuf = loopdev->sample_buffer;
223 	unsigned int queued_bytes = buf_queued_bytes(sbuf);
224 	buf_increment_read(sbuf, queued_bytes);
225 	return 0;
226 }
227 
update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)228 static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
229 			       unsigned dev_enabled)
230 {
231 }
232 
create_loopback_iodev(enum CRAS_LOOPBACK_TYPE type)233 static struct cras_iodev *create_loopback_iodev(enum CRAS_LOOPBACK_TYPE type)
234 {
235 	struct loopback_iodev *loopback_iodev;
236 	struct cras_iodev *iodev;
237 
238 	loopback_iodev = calloc(1, sizeof(*loopback_iodev));
239 	if (loopback_iodev == NULL)
240 		return NULL;
241 
242 	loopback_iodev->sample_buffer = byte_buffer_create(1024*16*4);
243 	if (loopback_iodev->sample_buffer == NULL) {
244 		free(loopback_iodev);
245 		return NULL;
246 	}
247 
248 	loopback_iodev->loopback_type = type;
249 
250 	iodev = &loopback_iodev->base;
251 	iodev->direction = CRAS_STREAM_INPUT;
252 	snprintf(iodev->info.name, ARRAY_SIZE(iodev->info.name), "%s",
253 		 loopdev_names[type]);
254 	iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = '\0';
255 	iodev->info.stable_id = SuperFastHash(iodev->info.name,
256 					      strlen(iodev->info.name),
257 					      strlen(iodev->info.name));
258 	iodev->info.stable_id_new = iodev->info.stable_id;
259 
260 	iodev->supported_rates = loopback_supported_rates;
261 	iodev->supported_channel_counts = loopback_supported_channel_counts;
262 	iodev->supported_formats = loopback_supported_formats;
263 	iodev->buffer_size = LOOPBACK_BUFFER_SIZE;
264 
265 	iodev->frames_queued = frames_queued;
266 	iodev->delay_frames = delay_frames;
267 	iodev->update_active_node = update_active_node;
268 	iodev->open_dev = open_record_dev;
269 	iodev->close_dev = close_record_dev;
270 	iodev->get_buffer = get_record_buffer;
271 	iodev->put_buffer = put_record_buffer;
272 	iodev->flush_buffer = flush_record_buffer;
273 
274 	return iodev;
275 }
276 
277 /*
278  * Exported Interface.
279  */
280 
loopback_iodev_create(enum CRAS_LOOPBACK_TYPE type)281 struct cras_iodev *loopback_iodev_create(enum CRAS_LOOPBACK_TYPE type)
282 {
283 	struct cras_iodev *iodev;
284 	struct cras_ionode *node;
285 	enum CRAS_NODE_TYPE node_type;
286 
287 	switch (type) {
288 	case LOOPBACK_POST_MIX_PRE_DSP:
289 		node_type = CRAS_NODE_TYPE_POST_MIX_PRE_DSP;
290 		break;
291 	case LOOPBACK_POST_DSP:
292 		node_type = CRAS_NODE_TYPE_POST_DSP;
293 		break;
294 	default:
295 		return NULL;
296 	}
297 
298 	iodev = create_loopback_iodev(type);
299 	if (iodev == NULL)
300 		return NULL;
301 
302 	/* Create a dummy ionode */
303 	node = (struct cras_ionode *)calloc(1, sizeof(*node));
304 	node->dev = iodev;
305 	node->type = node_type;
306 	node->plugged = 1;
307 	node->volume = 100;
308 	node->stable_id = iodev->info.stable_id;
309 	node->stable_id_new = iodev->info.stable_id_new;
310 	node->software_volume_needed = 0;
311 	node->max_software_gain = 0;
312 	strcpy(node->name, loopdev_names[type]);
313 	cras_iodev_add_node(iodev, node);
314 	cras_iodev_set_active_node(iodev, node);
315 
316 	cras_iodev_list_add_input(iodev);
317 
318 	return iodev;
319 }
320 
loopback_iodev_destroy(struct cras_iodev * iodev)321 void loopback_iodev_destroy(struct cras_iodev *iodev)
322 {
323 	struct loopback_iodev *loopdev = (struct loopback_iodev *)iodev;
324 	struct byte_buffer *sbuf = loopdev->sample_buffer;
325 
326 	cras_iodev_list_rm_input(iodev);
327 
328 	byte_buffer_destroy(sbuf);
329 	free(loopdev);
330 }
331