• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <errno.h>
7 #include <fcntl.h>
8 #include <getopt.h>
9 #include <inttypes.h>
10 #include <limits.h>
11 #include <math.h>
12 #include <pthread.h>
13 #include <stdio.h>
14 #include <stdint.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <syslog.h>
18 #include <sys/mman.h>
19 #include <sys/param.h>
20 #include <sys/select.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 
25 #include "cras_client.h"
26 #include "cras_types.h"
27 #include "cras_util.h"
28 #include "cras_version.h"
29 
30 #define NOT_ASSIGNED (0)
31 #define PLAYBACK_BUFFERED_TIME_IN_US (5000)
32 
33 #define BUF_SIZE 32768
34 
35 static const size_t MAX_IODEVS = 10; /* Max devices to print out. */
36 static const size_t MAX_IONODES = 20; /* Max ionodes to print out. */
37 static const size_t MAX_ATTACHED_CLIENTS = 10; /* Max clients to print out. */
38 
39 static int pipefd[2];
40 static struct timespec last_latency;
41 static int show_latency;
42 static float last_rms_sqr_sum;
43 static int last_rms_size;
44 static float total_rms_sqr_sum;
45 static int total_rms_size;
46 static int show_rms;
47 static int show_total_rms;
48 static int keep_looping = 1;
49 static int exit_after_done_playing = 1;
50 static size_t duration_frames;
51 static int pause_client = 0;
52 static int pause_a_reply = 0;
53 static int pause_in_playback_reply = 1000;
54 
55 static char *channel_layout = NULL;
56 static int pin_device_id;
57 
58 static int play_short_sound = 0;
59 static int play_short_sound_periods = 0;
60 static int play_short_sound_periods_left = 0;
61 
62 static int effect_aec = 0;
63 static int effect_ns = 0;
64 static int effect_agc = 0;
65 static int effect_vad = 0;
66 static char *aecdump_file = NULL;
67 static char time_str[128];
68 
69 /* Sleep interval between cras_client_read_atlog calls. */
70 static const struct timespec follow_atlog_sleep_ts = {
71 	0, 50 * 1000 * 1000 /* 50 ms. */
72 };
73 
74 /* Conditional so the client thread can signal that main should exit. */
75 static pthread_mutex_t done_mutex = PTHREAD_MUTEX_INITIALIZER;
76 static pthread_cond_t done_cond = PTHREAD_COND_INITIALIZER;
77 
78 struct cras_audio_format *aud_format;
79 struct {
80 	char *name;
81 	snd_pcm_format_t format;
82 } supported_formats[] = {
83 	{ "S16_LE", SND_PCM_FORMAT_S16_LE },
84 	{ "S24_LE", SND_PCM_FORMAT_S24_LE },
85 	{ "S32_LE", SND_PCM_FORMAT_S32_LE },
86 	{ NULL, 0 },
87 };
88 
terminate_stream_loop()89 static int terminate_stream_loop()
90 {
91 	keep_looping = 0;
92 	return write(pipefd[1], "1", 1);
93 }
94 
get_block_size(uint64_t buffer_time_in_us,size_t rate)95 static size_t get_block_size(uint64_t buffer_time_in_us, size_t rate)
96 {
97 	return (size_t)(buffer_time_in_us * rate / 1000000);
98 }
99 
check_stream_terminate(size_t frames)100 static void check_stream_terminate(size_t frames)
101 {
102 	if (duration_frames) {
103 		if (duration_frames <= frames)
104 			terminate_stream_loop();
105 		else
106 			duration_frames -= frames;
107 	}
108 }
109 
fill_time_offset(time_t * sec_offset,int32_t * nsec_offset)110 static void fill_time_offset(time_t *sec_offset, int32_t *nsec_offset)
111 {
112 	struct timespec mono_time, real_time;
113 
114 	clock_gettime(CLOCK_MONOTONIC_RAW, &mono_time);
115 	clock_gettime(CLOCK_REALTIME, &real_time);
116 	*sec_offset = real_time.tv_sec - mono_time.tv_sec;
117 	*nsec_offset = real_time.tv_nsec - mono_time.tv_nsec;
118 }
119 
120 /* Compute square sum of samples (for calculation of RMS value). */
compute_sqr_sum_16(const int16_t * samples,int size)121 float compute_sqr_sum_16(const int16_t *samples, int size)
122 {
123 	unsigned i;
124 	float sqr_sum = 0;
125 
126 	for (i = 0; i < size; i++)
127 		sqr_sum += samples[i] * samples[i];
128 
129 	return sqr_sum;
130 }
131 
132 /* Update the RMS values with the given samples. */
update_rms(const uint8_t * samples,int size)133 int update_rms(const uint8_t *samples, int size)
134 {
135 	switch (aud_format->format) {
136 	case SND_PCM_FORMAT_S16_LE: {
137 		last_rms_sqr_sum =
138 			compute_sqr_sum_16((int16_t *)samples, size / 2);
139 		last_rms_size = size / 2;
140 		break;
141 	}
142 	default:
143 		return -EINVAL;
144 	}
145 
146 	total_rms_sqr_sum += last_rms_sqr_sum;
147 	total_rms_size += last_rms_size;
148 
149 	return 0;
150 }
151 
152 /* Parses a string with format <N>:<M> into a node id*/
parse_node_id(char * input,cras_node_id_t * id_out)153 static int parse_node_id(char *input, cras_node_id_t *id_out)
154 {
155 	const char *s;
156 	char *endptr;
157 	int dev_index;
158 	int node_index;
159 
160 	if (!id_out)
161 		return -EINVAL;
162 
163 	s = strtok(input, ":");
164 	if (!s)
165 		return -EINVAL;
166 	dev_index = strtol(s, &endptr, 10);
167 	if (*endptr)
168 		return -EINVAL;
169 
170 	s = strtok(NULL, ":");
171 	if (!s)
172 		return -EINVAL;
173 	node_index = strtol(s, &endptr, 10);
174 	if (*endptr)
175 		return -EINVAL;
176 
177 	*id_out = cras_make_node_id(dev_index, node_index);
178 	return 0;
179 }
180 
181 /* Parses a string with format <N>:<M>:<0-100> into a node id and a value */
parse_node_id_with_value(char * input,cras_node_id_t * id_out,int * value_out)182 static int parse_node_id_with_value(char *input, cras_node_id_t *id_out,
183 				    int *value_out)
184 {
185 	const char *s;
186 	char *endptr;
187 	int dev_index;
188 	int node_index;
189 	long int value;
190 
191 	if (!id_out || !value_out)
192 		return -EINVAL;
193 
194 	s = strtok(input, ":");
195 	if (!s)
196 		return -EINVAL;
197 	dev_index = strtol(s, &endptr, 10);
198 	if (*endptr)
199 		return -EINVAL;
200 
201 	s = strtok(NULL, ":");
202 	if (!s)
203 		return -EINVAL;
204 	node_index = strtol(s, &endptr, 10);
205 	if (*endptr)
206 		return -EINVAL;
207 
208 	s = strtok(NULL, ":");
209 	if (!s)
210 		return -EINVAL;
211 	value = strtol(s, &endptr, 10);
212 	if (*endptr)
213 		return -EINVAL;
214 	if (value > INT_MAX || value < INT_MIN)
215 		return -EOVERFLOW;
216 
217 	*id_out = cras_make_node_id(dev_index, node_index);
218 	*value_out = value;
219 	return 0;
220 }
221 
222 /* Run from callback thread. */
got_samples(struct cras_client * client,cras_stream_id_t stream_id,uint8_t * captured_samples,uint8_t * playback_samples,unsigned int frames,const struct timespec * captured_time,const struct timespec * playback_time,void * user_arg)223 static int got_samples(struct cras_client *client, cras_stream_id_t stream_id,
224 		       uint8_t *captured_samples, uint8_t *playback_samples,
225 		       unsigned int frames,
226 		       const struct timespec *captured_time,
227 		       const struct timespec *playback_time, void *user_arg)
228 {
229 	int *fd = (int *)user_arg;
230 	int ret;
231 	int write_size;
232 	int frame_bytes;
233 
234 	while (pause_client)
235 		usleep(10000);
236 
237 	cras_client_calc_capture_latency(captured_time, &last_latency);
238 
239 	frame_bytes = cras_client_format_bytes_per_frame(aud_format);
240 	write_size = frames * frame_bytes;
241 
242 	/* Update RMS values with all available frames. */
243 	if (keep_looping) {
244 		update_rms(captured_samples,
245 			   MIN(write_size, duration_frames * frame_bytes));
246 	}
247 
248 	check_stream_terminate(frames);
249 
250 	ret = write(*fd, captured_samples, write_size);
251 	if (ret != write_size)
252 		printf("Error writing file\n");
253 	return frames;
254 }
255 
256 /* Run from callback thread. */
put_samples(struct cras_client * client,cras_stream_id_t stream_id,uint8_t * captured_samples,uint8_t * playback_samples,unsigned int frames,const struct timespec * captured_time,const struct timespec * playback_time,void * user_arg)257 static int put_samples(struct cras_client *client, cras_stream_id_t stream_id,
258 		       uint8_t *captured_samples, uint8_t *playback_samples,
259 		       unsigned int frames,
260 		       const struct timespec *captured_time,
261 		       const struct timespec *playback_time, void *user_arg)
262 {
263 	uint32_t frame_bytes = cras_client_format_bytes_per_frame(aud_format);
264 	int fd = *(int *)user_arg;
265 	uint8_t buff[BUF_SIZE];
266 	int nread;
267 
268 	while (pause_client)
269 		usleep(10000);
270 
271 	if (pause_a_reply) {
272 		usleep(pause_in_playback_reply);
273 		pause_a_reply = 0;
274 	}
275 
276 	check_stream_terminate(frames);
277 
278 	cras_client_calc_playback_latency(playback_time, &last_latency);
279 
280 	if (play_short_sound) {
281 		if (play_short_sound_periods_left)
282 			/* Play a period from file. */
283 			play_short_sound_periods_left--;
284 		else {
285 			/* Fill zeros to play silence. */
286 			memset(playback_samples, 0,
287 			       MIN(frames * frame_bytes, BUF_SIZE));
288 			return frames;
289 		}
290 	}
291 
292 	nread = read(fd, buff, MIN(frames * frame_bytes, BUF_SIZE));
293 	if (nread <= 0) {
294 		if (exit_after_done_playing)
295 			terminate_stream_loop();
296 		return nread;
297 	}
298 
299 	memcpy(playback_samples, buff, nread);
300 	return nread / frame_bytes;
301 }
302 
303 /* Run from callback thread. */
304 static int
put_stdin_samples(struct cras_client * client,cras_stream_id_t stream_id,uint8_t * captured_samples,uint8_t * playback_samples,unsigned int frames,const struct timespec * captured_time,const struct timespec * playback_time,void * user_arg)305 put_stdin_samples(struct cras_client *client, cras_stream_id_t stream_id,
306 		  uint8_t *captured_samples, uint8_t *playback_samples,
307 		  unsigned int frames, const struct timespec *captured_time,
308 		  const struct timespec *playback_time, void *user_arg)
309 {
310 	int rc = 0;
311 	uint32_t frame_bytes = cras_client_format_bytes_per_frame(aud_format);
312 
313 	rc = read(0, playback_samples, frames * frame_bytes);
314 	if (rc <= 0) {
315 		terminate_stream_loop();
316 		return -1;
317 	}
318 
319 	return rc / frame_bytes;
320 }
321 
stream_error(struct cras_client * client,cras_stream_id_t stream_id,int err,void * arg)322 static int stream_error(struct cras_client *client, cras_stream_id_t stream_id,
323 			int err, void *arg)
324 {
325 	printf("Stream error %d\n", err);
326 	terminate_stream_loop();
327 	return 0;
328 }
329 
print_last_latency()330 static void print_last_latency()
331 {
332 	if (last_latency.tv_sec > 0 || last_latency.tv_nsec > 0)
333 		printf("%u.%09u\n", (unsigned)last_latency.tv_sec,
334 		       (unsigned)last_latency.tv_nsec);
335 	else {
336 		printf("-%lld.%09lld\n", (long long)-last_latency.tv_sec,
337 		       (long long)-last_latency.tv_nsec);
338 	}
339 }
340 
print_last_rms()341 static void print_last_rms()
342 {
343 	if (last_rms_size != 0)
344 		printf("%.9f\n", sqrt(last_rms_sqr_sum / last_rms_size));
345 }
346 
print_total_rms()347 static void print_total_rms()
348 {
349 	if (total_rms_size != 0)
350 		printf("%.9f\n", sqrt(total_rms_sqr_sum / total_rms_size));
351 }
352 
print_dev_info(const struct cras_iodev_info * devs,int num_devs)353 static void print_dev_info(const struct cras_iodev_info *devs, int num_devs)
354 {
355 	unsigned i;
356 
357 	printf("\tID\tName\n");
358 	for (i = 0; i < num_devs; i++)
359 		printf("\t%u\t%s\n", devs[i].idx, devs[i].name);
360 }
361 
print_node_info(const struct cras_ionode_info * nodes,int num_nodes,int is_input)362 static void print_node_info(const struct cras_ionode_info *nodes, int num_nodes,
363 			    int is_input)
364 {
365 	unsigned i;
366 
367 	printf("\tStable Id\t ID\t%4s   Plugged\tL/R swapped\t      "
368 	       "Time Hotword\tType\t\t Name\n",
369 	       is_input ? "Gain" : " Vol");
370 	for (i = 0; i < num_nodes; i++)
371 		printf("\t(%08x)\t%u:%u\t%5g  %7s\t%14s\t%10ld %-7s\t%-16s%c%s\n",
372 		       nodes[i].stable_id, nodes[i].iodev_idx,
373 		       nodes[i].ionode_idx,
374 		       is_input ? nodes[i].capture_gain / 100.0 :
375 				  (double)nodes[i].volume,
376 		       nodes[i].plugged ? "yes" : "no",
377 		       nodes[i].left_right_swapped ? "yes" : "no",
378 		       (long)nodes[i].plugged_time.tv_sec,
379 		       nodes[i].active_hotword_model, nodes[i].type,
380 		       nodes[i].active ? '*' : ' ', nodes[i].name);
381 }
382 
print_device_lists(struct cras_client * client)383 static void print_device_lists(struct cras_client *client)
384 {
385 	struct cras_iodev_info devs[MAX_IODEVS];
386 	struct cras_ionode_info nodes[MAX_IONODES];
387 	size_t num_devs, num_nodes;
388 	int rc;
389 
390 	num_devs = MAX_IODEVS;
391 	num_nodes = MAX_IONODES;
392 	rc = cras_client_get_output_devices(client, devs, nodes, &num_devs,
393 					    &num_nodes);
394 	if (rc < 0)
395 		return;
396 	printf("Output Devices:\n");
397 	print_dev_info(devs, num_devs);
398 	printf("Output Nodes:\n");
399 	print_node_info(nodes, num_nodes, 0);
400 
401 	num_devs = MAX_IODEVS;
402 	num_nodes = MAX_IONODES;
403 	rc = cras_client_get_input_devices(client, devs, nodes, &num_devs,
404 					   &num_nodes);
405 	printf("Input Devices:\n");
406 	print_dev_info(devs, num_devs);
407 	printf("Input Nodes:\n");
408 	print_node_info(nodes, num_nodes, 1);
409 }
410 
print_attached_client_list(struct cras_client * client)411 static void print_attached_client_list(struct cras_client *client)
412 {
413 	struct cras_attached_client_info clients[MAX_ATTACHED_CLIENTS];
414 	size_t i;
415 	int num_clients;
416 
417 	num_clients = cras_client_get_attached_clients(client, clients,
418 						       MAX_ATTACHED_CLIENTS);
419 	if (num_clients < 0)
420 		return;
421 	num_clients = MIN(num_clients, MAX_ATTACHED_CLIENTS);
422 	printf("Attached clients:\n");
423 	printf("\tID\tpid\tuid\n");
424 	for (i = 0; i < num_clients; i++)
425 		printf("\t%u\t%d\t%d\n", clients[i].id, clients[i].pid,
426 		       clients[i].gid);
427 }
428 
print_active_stream_info(struct cras_client * client)429 static void print_active_stream_info(struct cras_client *client)
430 {
431 	struct timespec ts;
432 	unsigned num_streams;
433 
434 	num_streams = cras_client_get_num_active_streams(client, &ts);
435 	printf("Num active streams: %u\n", num_streams);
436 	printf("Last audio active time: %llu, %llu\n", (long long)ts.tv_sec,
437 	       (long long)ts.tv_nsec);
438 }
439 
print_system_volumes(struct cras_client * client)440 static void print_system_volumes(struct cras_client *client)
441 {
442 	printf("System Volume (0-100): %zu %s\n"
443 	       "Capture Gain (%.2f - %.2f): %.2fdB %s\n",
444 	       cras_client_get_system_volume(client),
445 	       cras_client_get_system_muted(client) ? "(Muted)" : "",
446 	       cras_client_get_system_min_capture_gain(client) / 100.0,
447 	       cras_client_get_system_max_capture_gain(client) / 100.0,
448 	       cras_client_get_system_capture_gain(client) / 100.0,
449 	       cras_client_get_system_capture_muted(client) ? "(Muted)" : "");
450 }
451 
print_user_muted(struct cras_client * client)452 static void print_user_muted(struct cras_client *client)
453 {
454 	printf("User muted: %s\n",
455 	       cras_client_get_user_muted(client) ? "Muted" : "Not muted");
456 }
457 
458 /*
459  * Convert time value from one clock to the other using given offset
460  * in sec and nsec.
461  */
convert_time(unsigned int * sec,unsigned int * nsec,time_t sec_offset,int32_t nsec_offset)462 static void convert_time(unsigned int *sec, unsigned int *nsec,
463 			 time_t sec_offset, int32_t nsec_offset)
464 {
465 	sec_offset += *sec;
466 	nsec_offset += *nsec;
467 	if (nsec_offset >= 1000000000L) {
468 		sec_offset++;
469 		nsec_offset -= 1000000000L;
470 	} else if (nsec_offset < 0) {
471 		sec_offset--;
472 		nsec_offset += 1000000000L;
473 	}
474 	*sec = sec_offset;
475 	*nsec = nsec_offset;
476 }
477 
show_alog_tag(const struct audio_thread_event_log * log,unsigned int tag_idx,int32_t sec_offset,int32_t nsec_offset)478 static void show_alog_tag(const struct audio_thread_event_log *log,
479 			  unsigned int tag_idx, int32_t sec_offset,
480 			  int32_t nsec_offset)
481 {
482 	unsigned int tag = (log->log[tag_idx].tag_sec >> 24) & 0xff;
483 	unsigned int sec = log->log[tag_idx].tag_sec & 0x00ffffff;
484 	unsigned int nsec = log->log[tag_idx].nsec;
485 	unsigned int data1 = log->log[tag_idx].data1;
486 	unsigned int data2 = log->log[tag_idx].data2;
487 	unsigned int data3 = log->log[tag_idx].data3;
488 	time_t lt;
489 	struct tm *t;
490 
491 	/* Skip unused log entries. */
492 	if (log->log[tag_idx].tag_sec == 0 && log->log[tag_idx].nsec == 0)
493 		return;
494 
495 	/* Convert from monotomic raw clock to realtime clock. */
496 	convert_time(&sec, &nsec, sec_offset, nsec_offset);
497 	lt = sec;
498 	t = localtime(&lt);
499 	strftime(time_str, 128, "%Y-%m-%dT%H:%M:%S", t);
500 
501 	printf("%s.%09u cras atlog  ", time_str, nsec);
502 
503 	/* Prepare realtime string for arguments. */
504 	switch (tag) {
505 	case AUDIO_THREAD_READ_AUDIO_TSTAMP:
506 	case AUDIO_THREAD_FILL_AUDIO_TSTAMP:
507 	case AUDIO_THREAD_STREAM_RESCHEDULE:
508 	case AUDIO_THREAD_STREAM_SLEEP_TIME:
509 	case AUDIO_THREAD_STREAM_SLEEP_ADJUST:
510 	case AUDIO_THREAD_DEV_SLEEP_TIME:
511 		sec = data2;
512 		nsec = data3;
513 		break;
514 	}
515 	convert_time(&sec, &nsec, sec_offset, nsec_offset);
516 	lt = sec;
517 	t = localtime(&lt);
518 	strftime(time_str, 128, " %H:%M:%S", t);
519 
520 	switch (tag) {
521 	case AUDIO_THREAD_WAKE:
522 		printf("%-30s num_fds:%d\n", "WAKE", (int)data1);
523 		break;
524 	case AUDIO_THREAD_SLEEP:
525 		printf("%-30s sleep:%09d.%09d\n", "SLEEP", (int)data1,
526 		       (int)data2);
527 		break;
528 	case AUDIO_THREAD_READ_AUDIO:
529 		printf("%-30s dev:%u hw_level:%u read:%u\n", "READ_AUDIO",
530 		       data1, data2, data3);
531 		break;
532 	case AUDIO_THREAD_READ_AUDIO_TSTAMP:
533 		printf("%-30s dev:%u tstamp:%s.%09u\n", "READ_AUDIO_TSTAMP",
534 		       data1, time_str, nsec);
535 		break;
536 	case AUDIO_THREAD_READ_AUDIO_DONE:
537 		printf("%-30s read_remainder:%u\n", "READ_AUDIO_DONE", data1);
538 		break;
539 	case AUDIO_THREAD_READ_OVERRUN:
540 		printf("%-30s dev:%u stream:%x num_overruns:%u\n",
541 		       "READ_AUDIO_OVERRUN", data1, data2, data3);
542 		break;
543 	case AUDIO_THREAD_FILL_AUDIO:
544 		printf("%-30s dev:%u hw_level:%u\n", "FILL_AUDIO", data1,
545 		       data2);
546 		break;
547 	case AUDIO_THREAD_FILL_AUDIO_TSTAMP:
548 		printf("%-30s dev:%u tstamp:%s.%09u\n", "FILL_AUDIO_TSTAMP",
549 		       data1, time_str, nsec);
550 		break;
551 	case AUDIO_THREAD_FILL_AUDIO_DONE:
552 		printf("%-30s hw_level:%u total_written:%u min_cb_level:%u\n",
553 		       "FILL_AUDIO_DONE", data1, data2, data3);
554 		break;
555 	case AUDIO_THREAD_WRITE_STREAMS_WAIT:
556 		printf("%-30s stream:%x\n", "WRITE_STREAMS_WAIT", data1);
557 		break;
558 	case AUDIO_THREAD_WRITE_STREAMS_WAIT_TO:
559 		printf("%-30s\n", "WRITE_STREAMS_WAIT_TO");
560 		break;
561 	case AUDIO_THREAD_WRITE_STREAMS_MIX:
562 		printf("%-30s write_limit:%u max_offset:%u\n",
563 		       "WRITE_STREAMS_MIX", data1, data2);
564 		break;
565 	case AUDIO_THREAD_WRITE_STREAMS_MIXED:
566 		printf("%-30s write_limit:%u\n", "WRITE_STREAMS_MIXED", data1);
567 		break;
568 	case AUDIO_THREAD_WRITE_STREAMS_STREAM:
569 		printf("%-30s id:%x shm_frames:%u cb_pending:%u\n",
570 		       "WRITE_STREAMS_STREAM", data1, data2, data3);
571 		break;
572 	case AUDIO_THREAD_FETCH_STREAM:
573 		printf("%-30s id:%x cbth:%u delay:%u\n",
574 		       "WRITE_STREAMS_FETCH_STREAM", data1, data2, data3);
575 		break;
576 	case AUDIO_THREAD_STREAM_ADDED:
577 		printf("%-30s id:%x dev:%u\n", "STREAM_ADDED", data1, data2);
578 		break;
579 	case AUDIO_THREAD_STREAM_REMOVED:
580 		printf("%-30s id:%x\n", "STREAM_REMOVED", data1);
581 		break;
582 	case AUDIO_THREAD_A2DP_ENCODE:
583 		printf("%-30s proc:%d queued:%u readable:%u\n", "A2DP_ENCODE",
584 		       data1, data2, data3);
585 		break;
586 	case AUDIO_THREAD_A2DP_WRITE:
587 		printf("%-30s written:%d queued:%u\n", "A2DP_WRITE", data1,
588 		       data2);
589 		break;
590 	case AUDIO_THREAD_DEV_STREAM_MIX:
591 		printf("%-30s written:%u read:%u\n", "DEV_STREAM_MIX", data1,
592 		       data2);
593 		break;
594 	case AUDIO_THREAD_CAPTURE_POST:
595 		printf("%-30s stream:%x thresh:%u rd_buf:%u\n", "CAPTURE_POST",
596 		       data1, data2, data3);
597 		break;
598 	case AUDIO_THREAD_CAPTURE_WRITE:
599 		printf("%-30s stream:%x write:%u shm_fr:%u\n", "CAPTURE_WRITE",
600 		       data1, data2, data3);
601 		break;
602 	case AUDIO_THREAD_CONV_COPY:
603 		printf("%-30s wr_buf:%u shm_writable:%u offset:%u\n",
604 		       "CONV_COPY", data1, data2, data3);
605 		break;
606 	case AUDIO_THREAD_STREAM_FETCH_PENDING:
607 		printf("%-30s id:%x\n", "STREAM_FETCH_PENGING", data1);
608 		break;
609 	case AUDIO_THREAD_STREAM_RESCHEDULE:
610 		printf("%-30s id:%x next_cb_ts:%s.%09u\n", "STREAM_RESCHEDULE",
611 		       data1, time_str, nsec);
612 		break;
613 	case AUDIO_THREAD_STREAM_SLEEP_TIME:
614 		printf("%-30s id:%x wake:%s.%09u\n", "STREAM_SLEEP_TIME", data1,
615 		       time_str, nsec);
616 		break;
617 	case AUDIO_THREAD_STREAM_SLEEP_ADJUST:
618 		printf("%-30s id:%x from:%s.%09u\n", "STREAM_SLEEP_ADJUST",
619 		       data1, time_str, nsec);
620 		break;
621 	case AUDIO_THREAD_STREAM_SKIP_CB:
622 		printf("%-30s id:%x write_offset_0:%u write_offset_1:%u\n",
623 		       "STREAM_SKIP_CB", data1, data2, data3);
624 		break;
625 	case AUDIO_THREAD_DEV_SLEEP_TIME:
626 		printf("%-30s dev:%u wake:%s.%09u\n", "DEV_SLEEP_TIME", data1,
627 		       time_str, nsec);
628 		break;
629 	case AUDIO_THREAD_SET_DEV_WAKE:
630 		printf("%-30s dev:%u hw_level:%u sleep:%u\n", "SET_DEV_WAKE",
631 		       data1, data2, data3);
632 		break;
633 	case AUDIO_THREAD_DEV_ADDED:
634 		printf("%-30s dev:%u\n", "DEV_ADDED", data1);
635 		break;
636 	case AUDIO_THREAD_DEV_REMOVED:
637 		printf("%-30s dev:%u\n", "DEV_REMOVED", data1);
638 		break;
639 	case AUDIO_THREAD_IODEV_CB:
640 		printf("%-30s is_write:%u\n", "IODEV_CB", data1);
641 		break;
642 	case AUDIO_THREAD_PB_MSG:
643 		printf("%-30s msg_id:%u\n", "PB_MSG", data1);
644 		break;
645 	case AUDIO_THREAD_ODEV_NO_STREAMS:
646 		printf("%-30s dev:%u\n", "ODEV_NO_STREAMS", data1);
647 		break;
648 	case AUDIO_THREAD_ODEV_LEAVE_NO_STREAMS:
649 		printf("%-30s dev:%u\n", "ODEV_LEAVE_NO_STREAMS", data1);
650 		break;
651 	case AUDIO_THREAD_ODEV_START:
652 		printf("%-30s dev:%u min_cb_level:%u\n", "ODEV_START", data1,
653 		       data2);
654 		break;
655 	case AUDIO_THREAD_FILL_ODEV_ZEROS:
656 		printf("%-30s dev:%u write:%u\n", "FILL_ODEV_ZEROS", data1,
657 		       data2);
658 		break;
659 	case AUDIO_THREAD_ODEV_DEFAULT_NO_STREAMS:
660 		printf("%-30s dev:%u hw_level:%u target:%u\n",
661 		       "DEFAULT_NO_STREAMS", data1, data2, data3);
662 		break;
663 	case AUDIO_THREAD_UNDERRUN:
664 		printf("%-30s dev:%u hw_level:%u total_written:%u\n",
665 		       "UNDERRUN", data1, data2, data3);
666 		break;
667 	case AUDIO_THREAD_SEVERE_UNDERRUN:
668 		printf("%-30s dev:%u\n", "SEVERE_UNDERRUN", data1);
669 		break;
670 	case AUDIO_THREAD_CAPTURE_DROP_TIME:
671 		printf("%-30s time:%09u.%09d\n", "CAPTURE_DROP_TIME", data1,
672 		       data2);
673 		break;
674 	case AUDIO_THREAD_DEV_DROP_FRAMES:
675 		printf("%-30s dev:%u frames:%u\n", "DEV_DROP_FRAMES", data1,
676 		       data2);
677 		break;
678 	default:
679 		printf("%-30s tag:%u\n", "UNKNOWN", tag);
680 		break;
681 	}
682 }
683 
print_audio_debug_info(const struct audio_debug_info * info)684 static void print_audio_debug_info(const struct audio_debug_info *info)
685 {
686 	time_t sec_offset;
687 	int32_t nsec_offset;
688 	int i, j;
689 
690 	printf("Audio Debug Stats:\n");
691 	printf("-------------devices------------\n");
692 	if (info->num_devs > MAX_DEBUG_DEVS)
693 		return;
694 
695 	for (i = 0; i < info->num_devs; i++) {
696 		printf("%s dev: %s\n",
697 		       (info->devs[i].direction == CRAS_STREAM_INPUT) ?
698 			       "Input" :
699 			       "Output",
700 		       info->devs[i].dev_name);
701 		printf("buffer_size: %u\n"
702 		       "min_buffer_level: %u\n"
703 		       "min_cb_level: %u\n"
704 		       "max_cb_level: %u\n"
705 		       "frame_rate: %u\n"
706 		       "num_channels: %u\n"
707 		       "est_rate_ratio: %lf\n"
708 		       "num_underruns: %u\n"
709 		       "num_severe_underruns: %u\n"
710 		       "highest_hw_level: %u\n"
711 		       "runtime: %u.%09u\n"
712 		       "longest_wake: %u.%09u\n"
713 		       "software_gain_scaler: %lf\n",
714 		       (unsigned int)info->devs[i].buffer_size,
715 		       (unsigned int)info->devs[i].min_buffer_level,
716 		       (unsigned int)info->devs[i].min_cb_level,
717 		       (unsigned int)info->devs[i].max_cb_level,
718 		       (unsigned int)info->devs[i].frame_rate,
719 		       (unsigned int)info->devs[i].num_channels,
720 		       info->devs[i].est_rate_ratio,
721 		       (unsigned int)info->devs[i].num_underruns,
722 		       (unsigned int)info->devs[i].num_severe_underruns,
723 		       (unsigned int)info->devs[i].highest_hw_level,
724 		       (unsigned int)info->devs[i].runtime_sec,
725 		       (unsigned int)info->devs[i].runtime_nsec,
726 		       (unsigned int)info->devs[i].longest_wake_sec,
727 		       (unsigned int)info->devs[i].longest_wake_nsec,
728 		       info->devs[i].software_gain_scaler);
729 		printf("\n");
730 	}
731 
732 	printf("-------------stream_dump------------\n");
733 	if (info->num_streams > MAX_DEBUG_STREAMS)
734 		return;
735 
736 	for (i = 0; i < info->num_streams; i++) {
737 		int channel;
738 		printf("stream: %llu dev: %u\n",
739 		       (unsigned long long)info->streams[i].stream_id,
740 		       (unsigned int)info->streams[i].dev_idx);
741 		printf("direction: %s\n",
742 		       (info->streams[i].direction == CRAS_STREAM_INPUT) ?
743 			       "Input" :
744 			       "Output");
745 		printf("stream_type: %s\n",
746 		       cras_stream_type_str(info->streams[i].stream_type));
747 		printf("client_type: %s\n",
748 		       cras_client_type_str(info->streams[i].client_type));
749 		printf("buffer_frames: %u\n"
750 		       "cb_threshold: %u\n"
751 		       "effects: 0x%.4x\n"
752 		       "frame_rate: %u\n"
753 		       "num_channels: %u\n"
754 		       "longest_fetch_sec: %u.%09u\n"
755 		       "num_overruns: %u\n"
756 		       "is_pinned: %x\n"
757 		       "pinned_dev_idx: %x\n"
758 		       "num_missed_cb: %u\n"
759 		       "%s: %lf\n"
760 		       "runtime: %u.%09u\n",
761 		       (unsigned int)info->streams[i].buffer_frames,
762 		       (unsigned int)info->streams[i].cb_threshold,
763 		       (unsigned int)info->streams[i].effects,
764 		       (unsigned int)info->streams[i].frame_rate,
765 		       (unsigned int)info->streams[i].num_channels,
766 		       (unsigned int)info->streams[i].longest_fetch_sec,
767 		       (unsigned int)info->streams[i].longest_fetch_nsec,
768 		       (unsigned int)info->streams[i].num_overruns,
769 		       (unsigned int)info->streams[i].is_pinned,
770 		       (unsigned int)info->streams[i].pinned_dev_idx,
771 		       (unsigned int)info->streams[i].num_missed_cb,
772 		       (info->streams[i].direction == CRAS_STREAM_INPUT) ?
773 			       "gain" :
774 			       "volume",
775 		       info->streams[i].stream_volume,
776 		       (unsigned int)info->streams[i].runtime_sec,
777 		       (unsigned int)info->streams[i].runtime_nsec);
778 		printf("channel map:");
779 		for (channel = 0; channel < CRAS_CH_MAX; channel++)
780 			printf("%d ", info->streams[i].channel_layout[channel]);
781 		printf("\n\n");
782 	}
783 
784 	printf("Audio Thread Event Log:\n");
785 
786 	fill_time_offset(&sec_offset, &nsec_offset);
787 	j = info->log.write_pos % info->log.len;
788 	i = 0;
789 	printf("start at %d\n", j);
790 	for (; i < info->log.len; i++) {
791 		show_alog_tag(&info->log, j, sec_offset, nsec_offset);
792 		j++;
793 		j %= info->log.len;
794 	}
795 }
796 
audio_debug_info(struct cras_client * client)797 static void audio_debug_info(struct cras_client *client)
798 {
799 	const struct audio_debug_info *info;
800 	info = cras_client_get_audio_debug_info(client);
801 	if (!info)
802 		return;
803 	print_audio_debug_info(info);
804 
805 	/* Signal main thread we are done after the last chunk. */
806 	pthread_mutex_lock(&done_mutex);
807 	pthread_cond_signal(&done_cond);
808 	pthread_mutex_unlock(&done_mutex);
809 }
810 
show_btlog_tag(const struct cras_bt_event_log * log,unsigned int tag_idx,int32_t sec_offset,int32_t nsec_offset)811 static void show_btlog_tag(const struct cras_bt_event_log *log,
812 			   unsigned int tag_idx, int32_t sec_offset,
813 			   int32_t nsec_offset)
814 {
815 	unsigned int tag = (log->log[tag_idx].tag_sec >> 24) & 0xff;
816 	unsigned int sec = log->log[tag_idx].tag_sec & 0x00ffffff;
817 	unsigned int nsec = log->log[tag_idx].nsec;
818 	unsigned int data1 = log->log[tag_idx].data1;
819 	unsigned int data2 = log->log[tag_idx].data2;
820 	time_t lt;
821 	struct tm *t;
822 
823 	/* Skip unused log entries. */
824 	if (log->log[tag_idx].tag_sec == 0 && log->log[tag_idx].nsec == 0)
825 		return;
826 
827 	/* Convert from monotomic raw clock to realtime clock. */
828 	convert_time(&sec, &nsec, sec_offset, nsec_offset);
829 	lt = sec;
830 	t = localtime(&lt);
831 	strftime(time_str, 128, "%Y-%m-%dT%H:%M:%S", t);
832 
833 	printf("%s.%09u cras btlog  ", time_str, nsec);
834 
835 	switch (tag) {
836 	case BT_ADAPTER_ADDED:
837 		printf("%-30s\n", "ADAPTER_ADDED");
838 		break;
839 	case BT_ADAPTER_REMOVED:
840 		printf("%-30s\n", "ADAPTER_REMOVED");
841 		break;
842 	case BT_A2DP_CONFIGURED:
843 		printf("%-30s connected profiles %u\n", "A2DP_CONFIGURED",
844 		       data1);
845 		break;
846 	case BT_A2DP_START:
847 		printf("%-30s\n", "A2DP_START");
848 		break;
849 	case BT_A2DP_SUSPENDED:
850 		printf("%-30s\n", "A2DP_SUSPENDED");
851 		break;
852 	case BT_AUDIO_GATEWAY_INIT:
853 		printf("%-30s supported profiles %u\n", "AUDIO_GATEWAY_INIT",
854 		       data1);
855 		break;
856 	case BT_AUDIO_GATEWAY_START:
857 		printf("%-30s \n", "AUDIO_GATEWAY_START");
858 		break;
859 	case BT_AVAILABLE_CODECS:
860 		printf("%-30s codec #%u id %u\n", "AVAILABLE_CODECS", data1,
861 		       data2);
862 		break;
863 	case BT_CODEC_SELECTION:
864 		printf("%-30s dir %u codec id %u\n", "CODEC_SELECTION", data1,
865 		       data2);
866 		break;
867 	case BT_DEV_CONNECTED_CHANGE:
868 		printf("%-30s profiles %u now %u\n", "DEV_CONENCTED_CHANGE",
869 		       data1, data2);
870 		break;
871 	case BT_DEV_CONN_WATCH_CB:
872 		printf("%-30s %u retries left, supported profiles %u\n",
873 		       "DEV_CONN_WATCH_CB", data1, data2);
874 		break;
875 	case BT_DEV_SUSPEND_CB:
876 		printf("%-30s profiles supported %u, connected %u\n",
877 		       "DEV_SUSPEND_CB", data1, data2);
878 		break;
879 	case BT_HFP_NEW_CONNECTION:
880 		printf("%-30s\n", "HFP_NEW_CONNECTION");
881 		break;
882 	case BT_HFP_REQUEST_DISCONNECT:
883 		printf("%-30s\n", "HFP_REQUEST_DISCONNECT");
884 		break;
885 	case BT_HFP_SUPPORTED_FEATURES:
886 		printf("%-30s role %s features %u\n", "HFP_SUPPORTED_FEATURES",
887 		       data1 ? "AG" : "HF", data2);
888 		break;
889 	case BT_HSP_NEW_CONNECTION:
890 		printf("%-30s\n", "HSP_NEW_CONNECTION");
891 		break;
892 	case BT_HSP_REQUEST_DISCONNECT:
893 		printf("%-30s\n", "HSP_REQUEST_DISCONNECT");
894 		break;
895 	case BT_NEW_AUDIO_PROFILE_AFTER_CONNECT:
896 		printf("%-30s old %u, new %u\n",
897 		       "NEW_AUDIO_PROFILE_AFTER_CONNECT", data1, data2);
898 		break;
899 	case BT_RESET:
900 		printf("%-30s\n", "RESET");
901 		break;
902 	case BT_SCO_CONNECT:
903 		printf("%-30s %s sk %d\n", "SCO_CONNECT",
904 		       data1 ? "success" : "failed", (int)data2);
905 		break;
906 	case BT_TRANSPORT_ACQUIRE:
907 		printf("%-30s %s fd %d\n", "TRANSPORT_ACQUIRE",
908 		       data1 ? "success" : "failed", (int)data2);
909 		break;
910 	case BT_TRANSPORT_RELEASE:
911 		printf("%-30s\n", "TRANSPORT_RELEASE");
912 		break;
913 	default:
914 		printf("%-30s\n", "UNKNOWN");
915 		break;
916 	}
917 }
918 
cras_bt_debug_info(struct cras_client * client)919 static void cras_bt_debug_info(struct cras_client *client)
920 {
921 	const struct cras_bt_debug_info *info;
922 	time_t sec_offset;
923 	int32_t nsec_offset;
924 	int i, j;
925 
926 	info = cras_client_get_bt_debug_info(client);
927 	fill_time_offset(&sec_offset, &nsec_offset);
928 	j = info->bt_log.write_pos;
929 	i = 0;
930 	printf("BT debug log:\n");
931 	for (; i < info->bt_log.len; i++) {
932 		show_btlog_tag(&info->bt_log, j, sec_offset, nsec_offset);
933 		j++;
934 		j %= info->bt_log.len;
935 	}
936 
937 	/* Signal main thread we are done after the last chunk. */
938 	pthread_mutex_lock(&done_mutex);
939 	pthread_cond_signal(&done_cond);
940 	pthread_mutex_unlock(&done_mutex);
941 }
942 
print_cras_audio_thread_snapshot(const struct cras_audio_thread_snapshot * snapshot)943 static void print_cras_audio_thread_snapshot(
944 	const struct cras_audio_thread_snapshot *snapshot)
945 {
946 	printf("-------------snapshot------------\n");
947 	printf("Event time: %" PRId64 ".%ld\n",
948 	       (int64_t)snapshot->timestamp.tv_sec,
949 	       snapshot->timestamp.tv_nsec);
950 
951 	printf("Event type: ");
952 	switch (snapshot->event_type) {
953 	case AUDIO_THREAD_EVENT_BUSYLOOP:
954 		printf("busyloop\n");
955 		break;
956 	case AUDIO_THREAD_EVENT_UNDERRUN:
957 		printf("underrun\n");
958 		break;
959 	case AUDIO_THREAD_EVENT_SEVERE_UNDERRUN:
960 		printf("severe underrun\n");
961 		break;
962 	case AUDIO_THREAD_EVENT_DROP_SAMPLES:
963 		printf("drop samples\n");
964 		break;
965 	case AUDIO_THREAD_EVENT_DEBUG:
966 		printf("debug\n");
967 		break;
968 	default:
969 		printf("no such type\n");
970 	}
971 	print_audio_debug_info(&snapshot->audio_debug_info);
972 }
973 
audio_thread_snapshots(struct cras_client * client)974 static void audio_thread_snapshots(struct cras_client *client)
975 {
976 	const struct cras_audio_thread_snapshot_buffer *snapshot_buffer;
977 	uint32_t i;
978 	int j;
979 	int count = 0;
980 
981 	snapshot_buffer = cras_client_get_audio_thread_snapshot_buffer(client);
982 	i = snapshot_buffer->pos;
983 	for (j = 0; j < CRAS_MAX_AUDIO_THREAD_SNAPSHOTS; j++) {
984 		if (snapshot_buffer->snapshots[i].timestamp.tv_sec ||
985 		    snapshot_buffer->snapshots[i].timestamp.tv_nsec) {
986 			print_cras_audio_thread_snapshot(
987 				&snapshot_buffer->snapshots[i]);
988 			count++;
989 		}
990 		i++;
991 		i %= CRAS_MAX_AUDIO_THREAD_SNAPSHOTS;
992 	}
993 	printf("There are %d, snapshots.\n", count);
994 
995 	/* Signal main thread we are done after the last chunk. */
996 	pthread_mutex_lock(&done_mutex);
997 	pthread_cond_signal(&done_cond);
998 	pthread_mutex_unlock(&done_mutex);
999 }
1000 
start_stream(struct cras_client * client,cras_stream_id_t * stream_id,struct cras_stream_params * params,float stream_volume)1001 static int start_stream(struct cras_client *client, cras_stream_id_t *stream_id,
1002 			struct cras_stream_params *params, float stream_volume)
1003 {
1004 	int rc;
1005 
1006 	if (pin_device_id)
1007 		rc = cras_client_add_pinned_stream(client, pin_device_id,
1008 						   stream_id, params);
1009 	else
1010 		rc = cras_client_add_stream(client, stream_id, params);
1011 	if (rc < 0) {
1012 		fprintf(stderr, "adding a stream %d\n", rc);
1013 		return rc;
1014 	}
1015 	return cras_client_set_stream_volume(client, *stream_id, stream_volume);
1016 }
1017 
parse_channel_layout(char * channel_layout_str,int8_t channel_layout[CRAS_CH_MAX])1018 static int parse_channel_layout(char *channel_layout_str,
1019 				int8_t channel_layout[CRAS_CH_MAX])
1020 {
1021 	int i = 0;
1022 	char *chp;
1023 
1024 	chp = strtok(channel_layout_str, ",");
1025 	while (chp && i < CRAS_CH_MAX) {
1026 		channel_layout[i++] = atoi(chp);
1027 		chp = strtok(NULL, ",");
1028 	}
1029 
1030 	return 0;
1031 }
1032 
run_aecdump(struct cras_client * client,uint64_t stream_id,int start)1033 static void run_aecdump(struct cras_client *client, uint64_t stream_id,
1034 			int start)
1035 {
1036 	int aecdump_fd;
1037 	if (start) {
1038 		aecdump_fd =
1039 			open(aecdump_file, O_CREAT | O_RDWR | O_TRUNC, 0666);
1040 		if (aecdump_fd == -1) {
1041 			printf("Fail to open file %s", aecdump_file);
1042 			return;
1043 		}
1044 
1045 		printf("Dumping AEC info to %s, stream %" PRId64 ", fd %d\n",
1046 		       aecdump_file, stream_id, aecdump_fd);
1047 		cras_client_set_aec_dump(client, stream_id, 1, aecdump_fd);
1048 	} else {
1049 		cras_client_set_aec_dump(client, stream_id, 0, -1);
1050 		printf("Close AEC dump file %s\n", aecdump_file);
1051 	}
1052 }
1053 
run_file_io_stream(struct cras_client * client,int fd,enum CRAS_STREAM_DIRECTION direction,size_t block_size,enum CRAS_STREAM_TYPE stream_type,size_t rate,snd_pcm_format_t format,size_t num_channels,uint32_t flags,int is_loopback,int is_post_dsp)1054 static int run_file_io_stream(struct cras_client *client, int fd,
1055 			      enum CRAS_STREAM_DIRECTION direction,
1056 			      size_t block_size,
1057 			      enum CRAS_STREAM_TYPE stream_type, size_t rate,
1058 			      snd_pcm_format_t format, size_t num_channels,
1059 			      uint32_t flags, int is_loopback, int is_post_dsp)
1060 {
1061 	int rc, tty;
1062 	struct cras_stream_params *params;
1063 	cras_unified_cb_t aud_cb;
1064 	cras_stream_id_t stream_id = 0;
1065 	int stream_playing = 0;
1066 	int *pfd = malloc(sizeof(*pfd));
1067 	*pfd = fd;
1068 	fd_set poll_set;
1069 	struct timespec sleep_ts;
1070 	float volume_scaler = 1.0;
1071 	size_t sys_volume = 100;
1072 	long cap_gain = 0;
1073 	int mute = 0;
1074 	int8_t layout[CRAS_CH_MAX];
1075 
1076 	/* Set the sleep interval between latency/RMS prints. */
1077 	sleep_ts.tv_sec = 1;
1078 	sleep_ts.tv_nsec = 0;
1079 
1080 	/* Open the pipe file descriptor. */
1081 	rc = pipe(pipefd);
1082 	if (rc == -1) {
1083 		perror("failed to open pipe");
1084 		return -errno;
1085 	}
1086 
1087 	/* Reset the total RMS value. */
1088 	total_rms_sqr_sum = 0;
1089 	total_rms_size = 0;
1090 
1091 	if (direction == CRAS_STREAM_INPUT)
1092 		aud_cb = got_samples;
1093 	else
1094 		aud_cb = put_samples;
1095 
1096 	if (fd == 0) {
1097 		if (direction != CRAS_STREAM_OUTPUT)
1098 			return -EINVAL;
1099 		aud_cb = put_stdin_samples;
1100 	}
1101 
1102 	aud_format = cras_audio_format_create(format, rate, num_channels);
1103 	if (aud_format == NULL)
1104 		return -ENOMEM;
1105 
1106 	if (channel_layout) {
1107 		/* Set channel layout to format */
1108 		parse_channel_layout(channel_layout, layout);
1109 		cras_audio_format_set_channel_layout(aud_format, layout);
1110 	}
1111 
1112 	params = cras_client_unified_params_create(direction, block_size,
1113 						   stream_type, flags, pfd,
1114 						   aud_cb, stream_error,
1115 						   aud_format);
1116 	if (params == NULL)
1117 		return -ENOMEM;
1118 
1119 	cras_client_stream_params_set_client_type(params,
1120 						  CRAS_CLIENT_TYPE_TEST);
1121 
1122 	if (effect_aec)
1123 		cras_client_stream_params_enable_aec(params);
1124 	if (effect_ns)
1125 		cras_client_stream_params_enable_ns(params);
1126 	if (effect_agc)
1127 		cras_client_stream_params_enable_agc(params);
1128 	if (effect_vad)
1129 		cras_client_stream_params_enable_vad(params);
1130 
1131 	cras_client_run_thread(client);
1132 	if (is_loopback) {
1133 		enum CRAS_NODE_TYPE type =
1134 			(is_post_dsp ? CRAS_NODE_TYPE_POST_DSP :
1135 				       CRAS_NODE_TYPE_POST_MIX_PRE_DSP);
1136 
1137 		cras_client_connected_wait(client);
1138 		pin_device_id = cras_client_get_first_dev_type_idx(
1139 			client, type, CRAS_STREAM_INPUT);
1140 	}
1141 
1142 	stream_playing =
1143 		start_stream(client, &stream_id, params, volume_scaler) == 0;
1144 
1145 	tty = open("/dev/tty", O_RDONLY);
1146 
1147 	// There could be no terminal available when run in autotest.
1148 	if (tty == -1)
1149 		perror("warning: failed to open /dev/tty");
1150 
1151 	while (keep_looping) {
1152 		char input;
1153 		int nread;
1154 
1155 		FD_ZERO(&poll_set);
1156 		if (tty >= 0)
1157 			FD_SET(tty, &poll_set);
1158 		FD_SET(pipefd[0], &poll_set);
1159 		pselect(MAX(tty, pipefd[0]) + 1, &poll_set, NULL, NULL,
1160 			show_latency || show_rms ? &sleep_ts : NULL, NULL);
1161 
1162 		if (stream_playing && show_latency)
1163 			print_last_latency();
1164 
1165 		if (stream_playing && show_rms)
1166 			print_last_rms();
1167 
1168 		if (tty < 0 || !FD_ISSET(tty, &poll_set))
1169 			continue;
1170 
1171 		nread = read(tty, &input, 1);
1172 		if (nread < 1) {
1173 			fprintf(stderr, "Error reading stdin\n");
1174 			return nread;
1175 		}
1176 		switch (input) {
1177 		case 'p':
1178 			pause_client = !pause_client;
1179 			break;
1180 		case 'i':
1181 			pause_a_reply = 1;
1182 			break;
1183 		case 'q':
1184 			terminate_stream_loop();
1185 			break;
1186 		case 's':
1187 			if (stream_playing)
1188 				break;
1189 
1190 			/* If started by hand keep running after it finishes. */
1191 			exit_after_done_playing = 0;
1192 
1193 			stream_playing =
1194 				start_stream(client, &stream_id, params,
1195 					     volume_scaler) == 0;
1196 			break;
1197 		case 'r':
1198 			if (!stream_playing)
1199 				break;
1200 			cras_client_rm_stream(client, stream_id);
1201 			stream_playing = 0;
1202 			break;
1203 		case 'u':
1204 			volume_scaler = MIN(volume_scaler + 0.1, 1.0);
1205 			cras_client_set_stream_volume(client, stream_id,
1206 						      volume_scaler);
1207 			break;
1208 		case 'd':
1209 			volume_scaler = MAX(volume_scaler - 0.1, 0.0);
1210 			cras_client_set_stream_volume(client, stream_id,
1211 						      volume_scaler);
1212 			break;
1213 		case 'k':
1214 			sys_volume = MIN(sys_volume + 1, 100);
1215 			cras_client_set_system_volume(client, sys_volume);
1216 			break;
1217 		case 'j':
1218 			sys_volume = sys_volume == 0 ? 0 : sys_volume - 1;
1219 			cras_client_set_system_volume(client, sys_volume);
1220 			break;
1221 		case 'K':
1222 			cap_gain = MIN(cap_gain + 100, 5000);
1223 			cras_client_set_system_capture_gain(client, cap_gain);
1224 			break;
1225 		case 'J':
1226 			cap_gain = cap_gain == -5000 ? -5000 : cap_gain - 100;
1227 			cras_client_set_system_capture_gain(client, cap_gain);
1228 			break;
1229 		case 'm':
1230 			mute = !mute;
1231 			cras_client_set_system_mute(client, mute);
1232 			break;
1233 		case '@':
1234 			print_device_lists(client);
1235 			break;
1236 		case '#':
1237 			print_attached_client_list(client);
1238 			break;
1239 		case 'v':
1240 			printf("Volume: %zu%s Min dB: %ld Max dB: %ld\n"
1241 			       "Capture: %ld%s Min dB: %ld Max dB: %ld\n",
1242 			       cras_client_get_system_volume(client),
1243 			       cras_client_get_system_muted(client) ?
1244 				       "(Muted)" :
1245 				       "",
1246 			       cras_client_get_system_min_volume(client),
1247 			       cras_client_get_system_max_volume(client),
1248 			       cras_client_get_system_capture_gain(client),
1249 			       cras_client_get_system_capture_muted(client) ?
1250 				       "(Muted)" :
1251 				       "",
1252 			       cras_client_get_system_min_capture_gain(client),
1253 			       cras_client_get_system_max_capture_gain(client));
1254 			break;
1255 		case '\'':
1256 			play_short_sound_periods_left =
1257 				play_short_sound_periods;
1258 			break;
1259 		case '\n':
1260 			break;
1261 		default:
1262 			printf("Invalid key\n");
1263 			break;
1264 		}
1265 	}
1266 
1267 	if (show_total_rms)
1268 		print_total_rms();
1269 
1270 	cras_client_stop(client);
1271 
1272 	cras_audio_format_destroy(aud_format);
1273 	cras_client_stream_params_destroy(params);
1274 	free(pfd);
1275 
1276 	close(pipefd[0]);
1277 	close(pipefd[1]);
1278 
1279 	return 0;
1280 }
1281 
run_capture(struct cras_client * client,const char * file,size_t block_size,enum CRAS_STREAM_TYPE stream_type,size_t rate,snd_pcm_format_t format,size_t num_channels,uint32_t flags,int is_loopback,int is_post_dsp)1282 static int run_capture(struct cras_client *client, const char *file,
1283 		       size_t block_size, enum CRAS_STREAM_TYPE stream_type,
1284 		       size_t rate, snd_pcm_format_t format,
1285 		       size_t num_channels, uint32_t flags, int is_loopback,
1286 		       int is_post_dsp)
1287 {
1288 	int fd = open(file, O_CREAT | O_RDWR | O_TRUNC, 0666);
1289 	if (fd == -1) {
1290 		perror("failed to open file");
1291 		return -errno;
1292 	}
1293 
1294 	run_file_io_stream(client, fd, CRAS_STREAM_INPUT, block_size,
1295 			   stream_type, rate, format, num_channels, flags,
1296 			   is_loopback, is_post_dsp);
1297 
1298 	close(fd);
1299 	return 0;
1300 }
1301 
run_playback(struct cras_client * client,const char * file,size_t block_size,enum CRAS_STREAM_TYPE stream_type,size_t rate,snd_pcm_format_t format,size_t num_channels)1302 static int run_playback(struct cras_client *client, const char *file,
1303 			size_t block_size, enum CRAS_STREAM_TYPE stream_type,
1304 			size_t rate, snd_pcm_format_t format,
1305 			size_t num_channels)
1306 {
1307 	int fd;
1308 
1309 	fd = open(file, O_RDONLY);
1310 	if (fd == -1) {
1311 		perror("failed to open file");
1312 		return -errno;
1313 	}
1314 
1315 	run_file_io_stream(client, fd, CRAS_STREAM_OUTPUT, block_size,
1316 			   stream_type, rate, format, num_channels, 0, 0, 0);
1317 
1318 	close(fd);
1319 	return 0;
1320 }
1321 
print_server_info(struct cras_client * client)1322 static void print_server_info(struct cras_client *client)
1323 {
1324 	cras_client_run_thread(client);
1325 	cras_client_connected_wait(client); /* To synchronize data. */
1326 	print_system_volumes(client);
1327 	print_user_muted(client);
1328 	print_device_lists(client);
1329 	print_attached_client_list(client);
1330 	print_active_stream_info(client);
1331 }
1332 
show_audio_thread_snapshots(struct cras_client * client)1333 static void show_audio_thread_snapshots(struct cras_client *client)
1334 {
1335 	struct timespec wait_time;
1336 
1337 	cras_client_run_thread(client);
1338 	cras_client_connected_wait(client); /* To synchronize data. */
1339 	cras_client_update_audio_thread_snapshots(client,
1340 						  audio_thread_snapshots);
1341 
1342 	clock_gettime(CLOCK_REALTIME, &wait_time);
1343 	wait_time.tv_sec += 2;
1344 
1345 	pthread_mutex_lock(&done_mutex);
1346 	pthread_cond_timedwait(&done_cond, &done_mutex, &wait_time);
1347 	pthread_mutex_unlock(&done_mutex);
1348 }
1349 
show_audio_debug_info(struct cras_client * client)1350 static void show_audio_debug_info(struct cras_client *client)
1351 {
1352 	struct timespec wait_time;
1353 
1354 	cras_client_run_thread(client);
1355 	cras_client_connected_wait(client); /* To synchronize data. */
1356 	cras_client_update_audio_debug_info(client, audio_debug_info);
1357 
1358 	clock_gettime(CLOCK_REALTIME, &wait_time);
1359 	wait_time.tv_sec += 2;
1360 
1361 	pthread_mutex_lock(&done_mutex);
1362 	pthread_cond_timedwait(&done_cond, &done_mutex, &wait_time);
1363 	pthread_mutex_unlock(&done_mutex);
1364 }
1365 
show_cras_bt_debug_info(struct cras_client * client)1366 static void show_cras_bt_debug_info(struct cras_client *client)
1367 {
1368 	struct timespec wait_time;
1369 
1370 	cras_client_run_thread(client);
1371 	cras_client_connected_wait(client); /* To synchronize data. */
1372 	cras_client_update_bt_debug_info(client, cras_bt_debug_info);
1373 
1374 	clock_gettime(CLOCK_REALTIME, &wait_time);
1375 	wait_time.tv_sec += 2;
1376 
1377 	pthread_mutex_lock(&done_mutex);
1378 	pthread_cond_timedwait(&done_cond, &done_mutex, &wait_time);
1379 	pthread_mutex_unlock(&done_mutex);
1380 }
1381 
hotword_models_cb(struct cras_client * client,const char * hotword_models)1382 static void hotword_models_cb(struct cras_client *client,
1383 			      const char *hotword_models)
1384 {
1385 	printf("Hotword models: %s\n", hotword_models);
1386 }
1387 
print_hotword_models(struct cras_client * client,cras_node_id_t id)1388 static void print_hotword_models(struct cras_client *client, cras_node_id_t id)
1389 {
1390 	struct timespec wait_time;
1391 
1392 	cras_client_run_thread(client);
1393 	cras_client_connected_wait(client);
1394 	cras_client_get_hotword_models(client, id, hotword_models_cb);
1395 
1396 	clock_gettime(CLOCK_REALTIME, &wait_time);
1397 	wait_time.tv_sec += 2;
1398 
1399 	pthread_mutex_lock(&done_mutex);
1400 	pthread_cond_timedwait(&done_cond, &done_mutex, &wait_time);
1401 	pthread_mutex_unlock(&done_mutex);
1402 }
1403 
check_output_plugged(struct cras_client * client,const char * name)1404 static void check_output_plugged(struct cras_client *client, const char *name)
1405 {
1406 	cras_client_run_thread(client);
1407 	cras_client_connected_wait(client); /* To synchronize data. */
1408 	printf("%s\n",
1409 	       cras_client_output_dev_plugged(client, name) ? "Yes" : "No");
1410 }
1411 
1412 /* Repeatedly mute and unmute the output until there is an error. */
mute_loop_test(struct cras_client * client,int auto_reconnect)1413 static void mute_loop_test(struct cras_client *client, int auto_reconnect)
1414 {
1415 	int mute = 0;
1416 	int rc;
1417 
1418 	if (auto_reconnect)
1419 		cras_client_run_thread(client);
1420 	while (1) {
1421 		rc = cras_client_set_user_mute(client, mute);
1422 		printf("cras_client_set_user_mute(%d): %d\n", mute, rc);
1423 		if (rc != 0 && !auto_reconnect)
1424 			return;
1425 		mute = !mute;
1426 		sleep(2);
1427 	}
1428 }
1429 
show_atlog(time_t sec_offset,int32_t nsec_offset,struct audio_thread_event_log * log,int len,uint64_t missing)1430 static void show_atlog(time_t sec_offset, int32_t nsec_offset,
1431 		       struct audio_thread_event_log *log, int len,
1432 		       uint64_t missing)
1433 {
1434 	int i;
1435 	printf("Audio Thread Event Log:\n");
1436 
1437 	if (missing)
1438 		printf("%" PRIu64 " logs are missing.\n", missing);
1439 
1440 	for (i = 0; i < len; ++i) {
1441 		show_alog_tag(log, i, sec_offset, nsec_offset);
1442 	}
1443 }
1444 
unlock_main_thread(struct cras_client * client)1445 static void unlock_main_thread(struct cras_client *client)
1446 {
1447 	pthread_mutex_lock(&done_mutex);
1448 	pthread_cond_signal(&done_cond);
1449 	pthread_mutex_unlock(&done_mutex);
1450 }
1451 
cras_show_continuous_atlog(struct cras_client * client)1452 static void cras_show_continuous_atlog(struct cras_client *client)
1453 {
1454 	struct audio_thread_event_log log;
1455 	struct timespec wait_time;
1456 	static time_t sec_offset;
1457 	static int32_t nsec_offset;
1458 	static uint64_t atlog_read_idx = 0, missing;
1459 	int len, rc;
1460 
1461 	cras_client_run_thread(client);
1462 	cras_client_connected_wait(client); /* To synchronize data. */
1463 	cras_client_get_atlog_access(client, unlock_main_thread);
1464 
1465 	clock_gettime(CLOCK_REALTIME, &wait_time);
1466 	wait_time.tv_sec += 2;
1467 
1468 	pthread_mutex_lock(&done_mutex);
1469 	rc = pthread_cond_timedwait(&done_cond, &done_mutex, &wait_time);
1470 	pthread_mutex_unlock(&done_mutex);
1471 
1472 	if (rc)
1473 		goto fail;
1474 
1475 	fill_time_offset(&sec_offset, &nsec_offset);
1476 
1477 	while (1) {
1478 		len = cras_client_read_atlog(client, &atlog_read_idx, &missing,
1479 					     &log);
1480 
1481 		if (len < 0)
1482 			break;
1483 		if (len > 0)
1484 			show_atlog(sec_offset, nsec_offset, &log, len, missing);
1485 		nanosleep(&follow_atlog_sleep_ts, NULL);
1486 	}
1487 fail:
1488 	printf("Failed to get audio thread log.\n");
1489 }
1490 
1491 // clang-format off
1492 static struct option long_options[] = {
1493 	{"show_latency",        no_argument,            &show_latency, 1},
1494 	{"show_rms",            no_argument,            &show_rms, 1},
1495 	{"show_total_rms",      no_argument,            &show_total_rms, 1},
1496 	{"select_input",        required_argument,      0, 'a'},
1497 	{"block_size",          required_argument,      0, 'b'},
1498 	{"num_channels",        required_argument,      0, 'c'},
1499 	{"duration_seconds",    required_argument,      0, 'd'},
1500 	{"dump_events",         no_argument,            0, 'e'},
1501 	{"format",              required_argument,      0, 'f'},
1502 	{"capture_gain",        required_argument,      0, 'g'},
1503 	{"help",                no_argument,            0, 'h'},
1504 	{"dump_server_info",    no_argument,            0, 'i'},
1505 	{"check_output_plugged",required_argument,      0, 'j'},
1506 	{"add_active_input",    required_argument,      0, 'k'},
1507 	{"dump_dsp",            no_argument,            0, 'l'},
1508 	{"dump_audio_thread",   no_argument,            0, 'm'},
1509 	{"syslog_mask",         required_argument,      0, 'n'},
1510 	{"channel_layout",      required_argument,      0, 'o'},
1511 	{"get_aec_group_id",    no_argument,            0, 'p'},
1512 	{"user_mute",           required_argument,      0, 'q'},
1513 	{"rate",                required_argument,      0, 'r'},
1514 	{"reload_dsp",          no_argument,            0, 's'},
1515 	{"add_active_output",   required_argument,      0, 't'},
1516 	{"mute",                required_argument,      0, 'u'},
1517 	{"volume",              required_argument,      0, 'v'},
1518 	{"set_node_volume",     required_argument,      0, 'w'},
1519 	{"plug",                required_argument,      0, 'x'},
1520 	{"select_output",       required_argument,      0, 'y'},
1521 	{"playback_delay_us",   required_argument,      0, 'z'},
1522 	{"capture_mute",        required_argument,      0, '0'},
1523 	{"rm_active_input",     required_argument,      0, '1'},
1524 	{"rm_active_output",    required_argument,      0, '2'},
1525 	{"swap_left_right",     required_argument,      0, '3'},
1526 	{"version",             no_argument,            0, '4'},
1527 	{"add_test_dev",        required_argument,      0, '5'},
1528 	{"test_hotword_file",   required_argument,      0, '6'},
1529 	{"listen_for_hotword",  required_argument,      0, '7'},
1530 	{"pin_device",          required_argument,      0, '8'},
1531 	{"suspend",             required_argument,      0, '9'},
1532 	{"set_node_gain",       required_argument,      0, ':'},
1533 	{"play_short_sound",    required_argument,      0, '!'},
1534 	{"config_global_remix", required_argument,      0, ';'},
1535 	{"set_hotword_model",   required_argument,      0, '<'},
1536 	{"get_hotword_models",  required_argument,      0, '>'},
1537 	{"post_dsp",            required_argument,      0, 'A'},
1538 	{"stream_id",           required_argument,      0, 'B'},
1539 	{"capture_file",        required_argument,      0, 'C'},
1540 	{"reload_aec_config",   no_argument,            0, 'D'},
1541 	{"effects",             required_argument,      0, 'E'},
1542 	{"get_aec_supported",   no_argument,            0, 'F'},
1543 	{"aecdump",             required_argument,      0, 'G'},
1544 	{"dump_bt",             no_argument,            0, 'H'},
1545 	{"set_wbs_enabled",     required_argument,      0, 'I'},
1546 	{"follow_atlog",	no_argument,		0, 'J'},
1547 	{"connection_type",     required_argument,      0, 'K'},
1548 	{"loopback_file",       required_argument,      0, 'L'},
1549 	{"mute_loop_test",      required_argument,      0, 'M'},
1550 	{"playback_file",       required_argument,      0, 'P'},
1551 	{"stream_type",         required_argument,      0, 'T'},
1552 	{0, 0, 0, 0}
1553 };
1554 // clang-format on
1555 
show_usage()1556 static void show_usage()
1557 {
1558 	int i;
1559 
1560 	printf("--add_active_input <N>:<M> - "
1561 	       "Add the ionode with the given id to active input device "
1562 	       "list\n");
1563 	printf("--add_active_output <N>:<M> - "
1564 	       "Add the ionode with the given id to active output device "
1565 	       "list\n");
1566 	printf("--add_test_dev <type> - "
1567 	       "Add a test iodev.\n");
1568 	printf("--block_size <N> - "
1569 	       "The number for frames per callback(dictates latency).\n");
1570 	printf("--capture_file <name> - "
1571 	       "Name of file to record to.\n");
1572 	printf("--capture_gain <dB> - "
1573 	       "Set system caputre gain in dB*100 (100 = 1dB).\n");
1574 	printf("--capture_mute <0|1> - "
1575 	       "Set capture mute state.\n");
1576 	printf("--channel_layout <layout_str> - "
1577 	       "Set multiple channel layout.\n");
1578 	printf("--check_output_plugged <output name> - "
1579 	       "Check if the output is plugged in\n");
1580 	printf("--connection_type <connection_type> - "
1581 	       "Set cras_client connection_type (default to 0).\n"
1582 	       "                                      "
1583 	       "Argument: 0 - For control client.\n"
1584 	       "                                      "
1585 	       "          1 - For playback client.\n"
1586 	       "                                      "
1587 	       "          2 - For capture client.\n");
1588 	printf("--dump_audio_thread - "
1589 	       "Dumps audio thread info.\n");
1590 	printf("--dump_bt - "
1591 	       "Dumps debug info for bt audio\n");
1592 	printf("--dump_dsp - "
1593 	       "Print status of dsp to syslog.\n");
1594 	printf("--dump_server_info - "
1595 	       "Print status of the server.\n");
1596 	printf("--duration_seconds <N> - "
1597 	       "Seconds to record or playback.\n");
1598 	printf("--follow_atlog - "
1599 	       "Continuously dumps audio thread event log.\n");
1600 	printf("--format <name> - "
1601 	       "The sample format. Either ");
1602 	for (i = 0; supported_formats[i].name; ++i)
1603 		printf("%s ", supported_formats[i].name);
1604 	printf("(default to S16_LE).\n");
1605 	printf("--get_hotword_models <N>:<M> - "
1606 	       "Get the supported hotword models of node\n");
1607 	printf("--help - "
1608 	       "Print this message.\n");
1609 	printf("--listen_for_hotword <name> - "
1610 	       "Listen and capture hotword stream if supported\n");
1611 	printf("--loopback_file <name> - "
1612 	       "Name of file to record from loopback device.\n");
1613 	printf("--mute <0|1> - "
1614 	       "Set system mute state.\n");
1615 	printf("--mute_loop_test <0|1> - "
1616 	       "Continuously loop mute/umute.\n"
1617 	       "                         "
1618 	       "Argument: 0 - stop on error.\n"
1619 	       "                         "
1620 	       "          1 - automatically reconnect to CRAS.\n");
1621 	printf("--num_channels <N> - "
1622 	       "Two for stereo.\n");
1623 	printf("--pin_device <N> - "
1624 	       "Playback/Capture only on the given device.\n");
1625 	printf("--playback_file <name> - "
1626 	       "Name of file to play, "
1627 	       "\"-\" to playback raw audio from stdin.\n");
1628 	printf("--play_short_sound <N> - "
1629 	       "Plays the content in the file for N periods when ' "
1630 	       "is pressed.\n");
1631 	printf("--plug <N>:<M>:<0|1> - "
1632 	       "Set the plug state (0 or 1) for the ionode with the given "
1633 	       "index M on the device with index N\n");
1634 	printf("--rate <N> - "
1635 	       "Specifies the sample rate in Hz.\n");
1636 	printf("--reload_dsp - "
1637 	       "Reload dsp configuration from the ini file\n");
1638 	printf("--rm_active_input <N>:<M> - "
1639 	       "Removes the ionode with the given id from active input device "
1640 	       "list\n");
1641 	printf("--rm_active_output <N>:<M> - "
1642 	       "Removes the ionode with the given id from active output device "
1643 	       "list\n");
1644 	printf("--select_input <N>:<M> - "
1645 	       "Select the ionode with the given id as preferred input\n");
1646 	printf("--select_output <N>:<M> - "
1647 	       "Select the ionode with the given id as preferred output\n");
1648 	printf("--set_hotword_model <N>:<M>:<model> - "
1649 	       "Set the model to node\n");
1650 	printf("--playback_delay_us <N> - "
1651 	       "Set the time in us to delay a reply for playback when i is "
1652 	       "pressed\n");
1653 	printf("--post_dsp <0|1> - "
1654 	       "Use this flag with --loopback_file. The default value is 0.\n"
1655 	       "                   "
1656 	       "Argument: 0 - Record from post-mix, pre-DSP loopback device.\n"
1657 	       "                   "
1658 	       "          1 - Record from post-DSP loopback device.\n");
1659 	printf("--set_node_volume <N>:<M>:<0-100> - "
1660 	       "Set the volume of the ionode with the given id\n");
1661 	printf("--show_latency - "
1662 	       "Display latency while playing or recording.\n");
1663 	printf("--show_rms - "
1664 	       "Display RMS value of loopback stream.\n");
1665 	printf("--show_total_rms - "
1666 	       "Display total RMS value of loopback stream at the end.\n");
1667 	printf("--suspend <0|1> - "
1668 	       "Set audio suspend state.\n");
1669 	printf("--swap_left_right <N>:<M>:<0|1> - "
1670 	       "Swap or unswap (1 or 0) the left and right channel for the "
1671 	       "ionode with the given index M on the device with index N\n");
1672 	printf("--stream_type <N> - "
1673 	       "Specify the type of the stream.\n");
1674 	printf("--syslog_mask <n> - "
1675 	       "Set the syslog mask to the given log level.\n");
1676 	printf("--test_hotword_file <N>:<filename> - "
1677 	       "Use filename as a hotword buffer for device N\n");
1678 	printf("--user_mute <0|1> - "
1679 	       "Set user mute state.\n");
1680 	printf("--version - "
1681 	       "Print the git commit ID that was used to build the client.\n");
1682 	printf("--volume <0-100> - "
1683 	       "Set system output volume.\n");
1684 }
1685 
cras_client_create_and_connect(struct cras_client ** client,enum CRAS_CONNECTION_TYPE conn_type)1686 static int cras_client_create_and_connect(struct cras_client **client,
1687 					  enum CRAS_CONNECTION_TYPE conn_type)
1688 {
1689 	int rc;
1690 
1691 	rc = cras_client_create_with_type(client, conn_type);
1692 	if (rc < 0) {
1693 		fprintf(stderr, "Couldn't create client.\n");
1694 		return rc;
1695 	}
1696 
1697 	rc = cras_client_connect_timeout(*client, 1000);
1698 	if (rc) {
1699 		fprintf(stderr, "Couldn't connect to server.\n");
1700 		cras_client_destroy(*client);
1701 		return rc;
1702 	}
1703 
1704 	return 0;
1705 }
1706 
main(int argc,char ** argv)1707 int main(int argc, char **argv)
1708 {
1709 	struct cras_client *client;
1710 	int c, option_index;
1711 	size_t block_size = NOT_ASSIGNED;
1712 	size_t rate = 48000;
1713 	size_t num_channels = 2;
1714 	float duration_seconds = 0;
1715 	const char *capture_file = NULL;
1716 	const char *playback_file = NULL;
1717 	const char *loopback_file = NULL;
1718 	int post_dsp = 0;
1719 	enum CRAS_STREAM_TYPE stream_type = CRAS_STREAM_TYPE_DEFAULT;
1720 	int rc = 0;
1721 	uint32_t stream_flags = 0;
1722 	cras_stream_id_t stream_id = 0;
1723 	snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
1724 	enum CRAS_CONNECTION_TYPE conn_type = CRAS_CONTROL;
1725 	enum CRAS_CONNECTION_TYPE new_conn_type;
1726 
1727 	option_index = 0;
1728 	openlog("cras_test_client", LOG_PERROR, LOG_USER);
1729 	setlogmask(LOG_UPTO(LOG_INFO));
1730 
1731 	rc = cras_client_create_and_connect(&client, conn_type);
1732 	if (rc) {
1733 		return rc;
1734 	}
1735 
1736 	if (argc == 1) {
1737 		/* Nothing specified, default to dump_server_info. */
1738 		print_server_info(client);
1739 		goto destroy_exit;
1740 	}
1741 
1742 	while (1) {
1743 		c = getopt_long(argc, argv, "o:s:P:C:r:c:f:h", long_options,
1744 				&option_index);
1745 		if (c == -1)
1746 			break;
1747 		switch (c) {
1748 		case 'y':
1749 		case 'a': {
1750 			cras_node_id_t id;
1751 			rc = parse_node_id(optarg, &id);
1752 			if (rc) {
1753 				show_usage();
1754 				return rc;
1755 			}
1756 
1757 			enum CRAS_STREAM_DIRECTION direction =
1758 				(c == 'y') ? CRAS_STREAM_OUTPUT :
1759 					     CRAS_STREAM_INPUT;
1760 			cras_client_select_node(client, direction, id);
1761 			break;
1762 		}
1763 		case 'b':
1764 			block_size = atoi(optarg);
1765 			break;
1766 		case 'c':
1767 			num_channels = atoi(optarg);
1768 			break;
1769 		case 'd':
1770 			duration_seconds = atof(optarg);
1771 			break;
1772 		case 'e':
1773 			show_audio_thread_snapshots(client);
1774 			break;
1775 		case 'f': {
1776 			int i;
1777 
1778 			for (i = 0; supported_formats[i].name; ++i) {
1779 				if (strcasecmp(optarg,
1780 					       supported_formats[i].name) ==
1781 				    0) {
1782 					format = supported_formats[i].format;
1783 					break;
1784 				}
1785 			}
1786 
1787 			if (!supported_formats[i].name) {
1788 				printf("Unsupported format: %s\n", optarg);
1789 				return -EINVAL;
1790 			}
1791 			break;
1792 		}
1793 		case 'g': {
1794 			long gain = atol(optarg);
1795 			rc = cras_client_set_system_capture_gain(client, gain);
1796 			if (rc < 0) {
1797 				fprintf(stderr, "problem setting capture\n");
1798 				goto destroy_exit;
1799 			}
1800 			break;
1801 		}
1802 		case 'h':
1803 			show_usage();
1804 			break;
1805 		case 'i':
1806 			print_server_info(client);
1807 			break;
1808 		case 'j':
1809 			check_output_plugged(client, optarg);
1810 			break;
1811 		case 'k':
1812 		case 't':
1813 		case '1':
1814 		case '2': {
1815 			cras_node_id_t id;
1816 			rc = parse_node_id(optarg, &id);
1817 			if (rc) {
1818 				show_usage();
1819 				return rc;
1820 			}
1821 
1822 			enum CRAS_STREAM_DIRECTION dir;
1823 			if (c == 't' || c == '2')
1824 				dir = CRAS_STREAM_OUTPUT;
1825 			else
1826 				dir = CRAS_STREAM_INPUT;
1827 
1828 			if (c == 'k' || c == 't')
1829 				cras_client_add_active_node(client, dir, id);
1830 			else
1831 				cras_client_rm_active_node(client, dir, id);
1832 			break;
1833 		}
1834 		case 'l':
1835 			cras_client_dump_dsp_info(client);
1836 			break;
1837 		case 'm':
1838 			show_audio_debug_info(client);
1839 			break;
1840 		case 'n': {
1841 			int log_level = atoi(optarg);
1842 
1843 			setlogmask(LOG_UPTO(log_level));
1844 			break;
1845 		}
1846 		case 'o':
1847 			channel_layout = optarg;
1848 			break;
1849 		case 'p':
1850 			printf("AEC group ID %d\n",
1851 			       cras_client_get_aec_group_id(client));
1852 			break;
1853 		case 'q': {
1854 			int mute = atoi(optarg);
1855 			rc = cras_client_set_user_mute(client, mute);
1856 			if (rc < 0) {
1857 				fprintf(stderr, "problem setting mute\n");
1858 				goto destroy_exit;
1859 			}
1860 			break;
1861 		}
1862 		case 'r':
1863 			rate = atoi(optarg);
1864 			break;
1865 		case 's':
1866 			cras_client_reload_dsp(client);
1867 			break;
1868 		case 'u': {
1869 			int mute = atoi(optarg);
1870 			rc = cras_client_set_system_mute(client, mute);
1871 			if (rc < 0) {
1872 				fprintf(stderr, "problem setting mute\n");
1873 				goto destroy_exit;
1874 			}
1875 			break;
1876 		}
1877 		case 'v': {
1878 			int volume = atoi(optarg);
1879 			volume = MIN(100, MAX(0, volume));
1880 			rc = cras_client_set_system_volume(client, volume);
1881 			if (rc < 0) {
1882 				fprintf(stderr, "problem setting volume\n");
1883 				goto destroy_exit;
1884 			}
1885 			break;
1886 		}
1887 		case ':':
1888 		case 'w': {
1889 			cras_node_id_t id;
1890 			int value;
1891 			rc = parse_node_id_with_value(optarg, &id, &value);
1892 			if (rc) {
1893 				show_usage();
1894 				return rc;
1895 			}
1896 
1897 			if (c == 'w')
1898 				cras_client_set_node_volume(client, id, value);
1899 			else
1900 				cras_client_set_node_capture_gain(client, id,
1901 								  value);
1902 			break;
1903 		}
1904 		case 'x': {
1905 			cras_node_id_t id;
1906 			int value;
1907 			rc = parse_node_id_with_value(optarg, &id, &value);
1908 			if (rc) {
1909 				show_usage();
1910 				return rc;
1911 			}
1912 
1913 			enum ionode_attr attr = IONODE_ATTR_PLUGGED;
1914 			cras_client_set_node_attr(client, id, attr, value);
1915 			break;
1916 		}
1917 		case 'z':
1918 			pause_in_playback_reply = atoi(optarg);
1919 			break;
1920 
1921 		case '0': {
1922 			int mute = atoi(optarg);
1923 			rc = cras_client_set_system_capture_mute(client, mute);
1924 			if (rc < 0) {
1925 				fprintf(stderr, "problem setting mute\n");
1926 				goto destroy_exit;
1927 			}
1928 			break;
1929 		}
1930 		case '3': {
1931 			cras_node_id_t id;
1932 			int value;
1933 			rc = parse_node_id_with_value(optarg, &id, &value);
1934 			if (rc) {
1935 				show_usage();
1936 				return rc;
1937 			}
1938 
1939 			cras_client_swap_node_left_right(client, id, value);
1940 			break;
1941 		}
1942 		case '4':
1943 			printf("%s\n", VCSID);
1944 			break;
1945 		case '5': {
1946 			cras_client_add_test_iodev(client, atoi(optarg));
1947 			break;
1948 		}
1949 		case '6': {
1950 			const char *s;
1951 			int dev_index;
1952 
1953 			s = strtok(optarg, ":");
1954 			if (!s) {
1955 				show_usage();
1956 				return -EINVAL;
1957 			}
1958 			dev_index = atoi(s);
1959 
1960 			const char *file_name = strtok(NULL, ":");
1961 			if (!file_name) {
1962 				show_usage();
1963 				return -EINVAL;
1964 			}
1965 			cras_client_test_iodev_command(
1966 				client, dev_index,
1967 				TEST_IODEV_CMD_HOTWORD_TRIGGER,
1968 				strlen(file_name) + 1, (uint8_t *)file_name);
1969 			break;
1970 		}
1971 		case '7': {
1972 			stream_flags = HOTWORD_STREAM;
1973 			capture_file = optarg;
1974 			break;
1975 		}
1976 		case '8':
1977 			pin_device_id = atoi(optarg);
1978 			break;
1979 		case '9': {
1980 			int suspend = atoi(optarg);
1981 			cras_client_set_suspend(client, suspend);
1982 			break;
1983 		}
1984 
1985 		case '!': {
1986 			play_short_sound = 1;
1987 			play_short_sound_periods = atoi(optarg);
1988 			break;
1989 		}
1990 		case ';': {
1991 			char *s;
1992 			int nch;
1993 			int size = 0;
1994 			float *coeff;
1995 
1996 			s = strtok(optarg, ":");
1997 			nch = atoi(s);
1998 			coeff = (float *)calloc(nch * nch, sizeof(*coeff));
1999 			for (size = 0; size < nch * nch; size++) {
2000 				s = strtok(NULL, ",");
2001 				if (NULL == s)
2002 					break;
2003 				coeff[size] = atof(s);
2004 			}
2005 			cras_client_config_global_remix(client, nch, coeff);
2006 			free(coeff);
2007 			break;
2008 		}
2009 		case '<':
2010 		case '>': {
2011 			char *s;
2012 			int dev_index;
2013 			int node_index;
2014 
2015 			s = strtok(optarg, ":");
2016 			if (!s) {
2017 				show_usage();
2018 				return -EINVAL;
2019 			}
2020 			dev_index = atoi(s);
2021 
2022 			s = strtok(NULL, ":");
2023 			if (!s) {
2024 				show_usage();
2025 				return -EINVAL;
2026 			}
2027 			node_index = atoi(s);
2028 
2029 			s = strtok(NULL, ":");
2030 			if (!s && c == ';') {
2031 				//TODO: c never == ';'
2032 				show_usage();
2033 				return -EINVAL;
2034 			}
2035 
2036 			cras_node_id_t id =
2037 				cras_make_node_id(dev_index, node_index);
2038 			if (c == '<')
2039 				cras_client_set_hotword_model(client, id, s);
2040 			else
2041 				print_hotword_models(client, id);
2042 			break;
2043 		}
2044 
2045 		case 'A':
2046 			post_dsp = atoi(optarg);
2047 			break;
2048 		case 'B':
2049 			stream_id = atoi(optarg);
2050 			break;
2051 		case 'C':
2052 			capture_file = optarg;
2053 			break;
2054 		case 'D':
2055 			cras_client_reload_aec_config(client);
2056 			break;
2057 		case 'E': {
2058 			char *s;
2059 
2060 			s = strtok(optarg, ",");
2061 			while (s) {
2062 				if (strcmp("aec", s) == 0)
2063 					effect_aec = 1;
2064 				else if (strcmp("ns", s) == 0)
2065 					effect_ns = 1;
2066 				else if (strcmp("agc", s) == 0)
2067 					effect_agc = 1;
2068 				else if (strcmp("vad", s) == 0)
2069 					effect_vad = 1;
2070 				else
2071 					printf("Unknown effect %s\n", s);
2072 				s = strtok(NULL, ",");
2073 			}
2074 			break;
2075 		}
2076 		case 'F':
2077 			printf("AEC supported %d\n",
2078 			       !!cras_client_get_aec_supported(client));
2079 			break;
2080 		case 'G':
2081 			aecdump_file = optarg;
2082 			break;
2083 		case 'H':
2084 			show_cras_bt_debug_info(client);
2085 			break;
2086 		case 'I':
2087 			cras_client_set_bt_wbs_enabled(client, atoi(optarg));
2088 			break;
2089 		case 'J':
2090 			cras_show_continuous_atlog(client);
2091 			break;
2092 		case 'K':
2093 			new_conn_type = atoi(optarg);
2094 			if (cras_validate_connection_type(new_conn_type)) {
2095 				if (new_conn_type != conn_type) {
2096 					cras_client_destroy(client);
2097 					client = NULL;
2098 					rc = cras_client_create_and_connect(
2099 						&client, new_conn_type);
2100 					if (rc) {
2101 						fprintf(stderr,
2102 							"Couldn't connect to "
2103 							"server.\n");
2104 						return rc;
2105 					}
2106 					conn_type = new_conn_type;
2107 				}
2108 			} else {
2109 				printf("Input connection type is not "
2110 				       "supported.\n");
2111 			}
2112 			break;
2113 		case 'L':
2114 			loopback_file = optarg;
2115 			break;
2116 		case 'M':
2117 			mute_loop_test(client, atoi(optarg));
2118 			break;
2119 		case 'P':
2120 			playback_file = optarg;
2121 			break;
2122 		case 'T':
2123 			stream_type = atoi(optarg);
2124 			break;
2125 
2126 		default:
2127 			break;
2128 		}
2129 	}
2130 
2131 	duration_frames = duration_seconds * rate;
2132 	if (block_size == NOT_ASSIGNED)
2133 		block_size = get_block_size(PLAYBACK_BUFFERED_TIME_IN_US, rate);
2134 
2135 	if (capture_file != NULL) {
2136 		if (strcmp(capture_file, "-") == 0)
2137 			rc = run_file_io_stream(client, 1, CRAS_STREAM_INPUT,
2138 						block_size, stream_type, rate,
2139 						format, num_channels,
2140 						stream_flags, 0, 0);
2141 		else
2142 			rc = run_capture(client, capture_file, block_size,
2143 					 stream_type, rate, format,
2144 					 num_channels, stream_flags, 0, 0);
2145 	} else if (playback_file != NULL) {
2146 		if (strcmp(playback_file, "-") == 0)
2147 			rc = run_file_io_stream(client, 0, CRAS_STREAM_OUTPUT,
2148 						block_size, stream_type, rate,
2149 						format, num_channels,
2150 						stream_flags, 0, 0);
2151 		else
2152 			rc = run_playback(client, playback_file, block_size,
2153 					  stream_type, rate, format,
2154 					  num_channels);
2155 	} else if (loopback_file != NULL) {
2156 		rc = run_capture(client, loopback_file, block_size, stream_type,
2157 				 rate, format, num_channels, stream_flags, 1,
2158 				 post_dsp);
2159 	} else if (aecdump_file != NULL) {
2160 		run_aecdump(client, stream_id, 1);
2161 		sleep(duration_seconds);
2162 		run_aecdump(client, stream_id, 0);
2163 	}
2164 
2165 destroy_exit:
2166 	cras_client_destroy(client);
2167 	return rc;
2168 }
2169