1b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid * Use of this source code is governed by a BSD-style license that can be
3b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid * found in the LICENSE file.
4b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid */
5b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
61770e1c74e2723f09ca6c8d373072346fd5b9336Chinyue Chen#include <errno.h>
71770e1c74e2723f09ca6c8d373072346fd5b9336Chinyue Chen#include <fcntl.h>
8b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid#include <getopt.h>
99f8382e1e824fd96fbab604968e35a2a99569165Adrian Li#include <math.h>
106d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid#include <pthread.h>
11b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid#include <stdio.h>
12b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid#include <stdint.h>
13f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao#include <stdlib.h>
14b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid#include <string.h>
157c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir#include <syslog.h>
162c1e4a94b93ea1ca23ae1ab177a80ad769a7c18aDylan Reid#include <sys/param.h>
17b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid#include <sys/select.h>
181770e1c74e2723f09ca6c8d373072346fd5b9336Chinyue Chen#include <sys/stat.h>
191770e1c74e2723f09ca6c8d373072346fd5b9336Chinyue Chen#include <sys/types.h>
20b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid#include <unistd.h>
21b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
22b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid#include "cras_client.h"
23ce895e7bb75a63c593bec7a5a36bfed3241ab829Dylan Reid#include "cras_types.h"
240f4794e9bd3c4fbd5f3f5bebe96df4314408bf2aDylan Reid#include "cras_util.h"
254d83eef81b919e6e680477ed2015959a6d035b29Nicolas Boichat#include "cras_version.h"
26b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
27409ea118efe24ac2eb48097bdbea453fdd34399fOwen Lin#define NOT_ASSIGNED (0)
28409ea118efe24ac2eb48097bdbea453fdd34399fOwen Lin#define PLAYBACK_BUFFERED_TIME_IN_US (5000)
29b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
30e5f14b47665e5cc44a9491a59ea35b3a7f236994Hsin-Yu Chao#define BUF_SIZE 32768
31e5f14b47665e5cc44a9491a59ea35b3a7f236994Hsin-Yu Chao
3254fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reidstatic const size_t MAX_IODEVS = 10; /* Max devices to print out. */
33089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Changstatic const size_t MAX_IONODES = 20; /* Max ionodes to print out. */
3439f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reidstatic const size_t MAX_ATTACHED_CLIENTS = 10; /* Max clients to print out. */
3554fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reid
3657f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Listatic int pipefd[2];
37b229192892ca72a981813340d54b09b0ac8848d7Dylan Reidstatic struct timespec last_latency;
38b229192892ca72a981813340d54b09b0ac8848d7Dylan Reidstatic int show_latency;
399f8382e1e824fd96fbab604968e35a2a99569165Adrian Listatic float last_rms_sqr_sum;
409f8382e1e824fd96fbab604968e35a2a99569165Adrian Listatic int last_rms_size;
419f8382e1e824fd96fbab604968e35a2a99569165Adrian Listatic float total_rms_sqr_sum;
429f8382e1e824fd96fbab604968e35a2a99569165Adrian Listatic int total_rms_size;
439f8382e1e824fd96fbab604968e35a2a99569165Adrian Listatic int show_rms;
449f8382e1e824fd96fbab604968e35a2a99569165Adrian Listatic int show_total_rms;
45b229192892ca72a981813340d54b09b0ac8848d7Dylan Reidstatic int keep_looping = 1;
4698bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reidstatic int exit_after_done_playing = 1;
47c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reidstatic size_t duration_frames;
486dac2de41754d749d04d727c42b58aff43d12248Hsin-Yu Chaostatic int pause_client = 0;
490c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiangstatic int pause_a_reply = 0;
500c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiangstatic int pause_in_playback_reply = 1000;
51b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
526bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chaostatic char *channel_layout = NULL;
53883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chenstatic int pin_device_id;
54e5f14b47665e5cc44a9491a59ea35b3a7f236994Hsin-Yu Chao
555a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnettestatic int play_short_sound = 0;
565a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnettestatic int play_short_sound_periods = 0;
575a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnettestatic int play_short_sound_periods_left = 0;
585a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette
596d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid/* Conditional so the client thread can signal that main should exit. */
606d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reidstatic pthread_mutex_t done_mutex = PTHREAD_MUTEX_INITIALIZER;
616d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reidstatic pthread_cond_t done_cond = PTHREAD_COND_INITIALIZER;
626d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
630cee67e5cc56b7bb56f520b7ed0814aefa78b1d9Dylan Reidstruct cras_audio_format *aud_format;
640cee67e5cc56b7bb56f520b7ed0814aefa78b1d9Dylan Reid
6557f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Listatic int terminate_stream_loop()
6657f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li{
6757f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	keep_looping = 0;
6857f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	return write(pipefd[1], "1", 1);
6957f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li}
7057f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li
7164732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Linstatic size_t get_block_size(uint64_t buffer_time_in_us, size_t rate)
72409ea118efe24ac2eb48097bdbea453fdd34399fOwen Lin{
73409ea118efe24ac2eb48097bdbea453fdd34399fOwen Lin	return (size_t)(buffer_time_in_us * rate / 1000000);
74409ea118efe24ac2eb48097bdbea453fdd34399fOwen Lin}
75409ea118efe24ac2eb48097bdbea453fdd34399fOwen Lin
76c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reidstatic void check_stream_terminate(size_t frames)
77c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid{
78c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid	if (duration_frames) {
79c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid		if (duration_frames <= frames)
8057f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li			terminate_stream_loop();
81c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid		else
82c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid			duration_frames -= frames;
83c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid	}
84c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid}
85c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid
869f8382e1e824fd96fbab604968e35a2a99569165Adrian Li/* Compute square sum of samples (for calculation of RMS value). */
879f8382e1e824fd96fbab604968e35a2a99569165Adrian Lifloat compute_sqr_sum_16(const int16_t *samples, int size)
889f8382e1e824fd96fbab604968e35a2a99569165Adrian Li{
899f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	unsigned i;
909f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	float sqr_sum = 0;
919f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
929f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	for (i = 0; i < size; i++)
939f8382e1e824fd96fbab604968e35a2a99569165Adrian Li		sqr_sum += samples[i] * samples[i];
949f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
959f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	return sqr_sum;
969f8382e1e824fd96fbab604968e35a2a99569165Adrian Li}
979f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
989f8382e1e824fd96fbab604968e35a2a99569165Adrian Li/* Update the RMS values with the given samples. */
999f8382e1e824fd96fbab604968e35a2a99569165Adrian Liint update_rms(const uint8_t *samples, int size)
1009f8382e1e824fd96fbab604968e35a2a99569165Adrian Li{
1019f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	switch (aud_format->format) {
1029f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	case SND_PCM_FORMAT_S16_LE: {
1039f8382e1e824fd96fbab604968e35a2a99569165Adrian Li		last_rms_sqr_sum = compute_sqr_sum_16((int16_t *)samples, size / 2);
1049f8382e1e824fd96fbab604968e35a2a99569165Adrian Li		last_rms_size = size / 2;
1059f8382e1e824fd96fbab604968e35a2a99569165Adrian Li		break;
1069f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	}
1079f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	default:
1089f8382e1e824fd96fbab604968e35a2a99569165Adrian Li		return -EINVAL;
1099f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	}
1109f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
1119f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	total_rms_sqr_sum += last_rms_sqr_sum;
1129f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	total_rms_size += last_rms_size;
1139f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
1149f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	return 0;
1159f8382e1e824fd96fbab604968e35a2a99569165Adrian Li}
1169f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
117b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid/* Run from callback thread. */
118092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reidstatic int got_samples(struct cras_client *client,
119092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       cras_stream_id_t stream_id,
120092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       uint8_t *captured_samples,
121092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       uint8_t *playback_samples,
122092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       unsigned int frames,
123092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       const struct timespec *captured_time,
124092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       const struct timespec *playback_time,
125092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       void *user_arg)
126b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid{
127092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid	int *fd = (int *)user_arg;
128b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	int ret;
129894f8c1ccb9936091a94ebcb0b6625e4e9840ff6Dylan Reid	int write_size;
130a930d7e2e7028854751f604bc43763c10f10465cNicolas Boichat	int frame_bytes;
131b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
132443a8d0eb551cc101e6354c668765b2e3d2371d9Hsin-Yu Chao	while (pause_client)
133443a8d0eb551cc101e6354c668765b2e3d2371d9Hsin-Yu Chao		usleep(10000);
134443a8d0eb551cc101e6354c668765b2e3d2371d9Hsin-Yu Chao
135092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid	cras_client_calc_capture_latency(captured_time, &last_latency);
136b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
137e5f14b47665e5cc44a9491a59ea35b3a7f236994Hsin-Yu Chao	frame_bytes = cras_client_format_bytes_per_frame(aud_format);
138e5f14b47665e5cc44a9491a59ea35b3a7f236994Hsin-Yu Chao	write_size = frames * frame_bytes;
139e5f14b47665e5cc44a9491a59ea35b3a7f236994Hsin-Yu Chao
1409f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	/* Update RMS values with all available frames. */
141092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid	if (keep_looping) {
142092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		update_rms(captured_samples,
1432c1e4a94b93ea1ca23ae1ab177a80ad769a7c18aDylan Reid			   MIN(write_size, duration_frames * frame_bytes));
144092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid	}
1459f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
1469f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	check_stream_terminate(frames);
1479f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
148a930d7e2e7028854751f604bc43763c10f10465cNicolas Boichat	ret = write(*fd, captured_samples, write_size);
149a930d7e2e7028854751f604bc43763c10f10465cNicolas Boichat	if (ret != write_size)
150a930d7e2e7028854751f604bc43763c10f10465cNicolas Boichat		printf("Error writing file\n");
151a930d7e2e7028854751f604bc43763c10f10465cNicolas Boichat	return frames;
152b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid}
153b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
154b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid/* Run from callback thread. */
1558900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reidstatic int got_hotword(struct cras_client *client,
1568900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		       cras_stream_id_t stream_id,
1578900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		       uint8_t *captured_samples,
1588900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		       uint8_t *playback_samples,
1598900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		       unsigned int frames,
1608900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		       const struct timespec *captured_time,
1618900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		       const struct timespec *playback_time,
1628900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		       void *user_arg)
1638900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid{
1648900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid	printf("got hotword %u frames\n", frames);
1658900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid
1668900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid	return frames;
1678900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid}
1688900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid
1698900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid/* Run from callback thread. */
170092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reidstatic int put_samples(struct cras_client *client,
171092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       cras_stream_id_t stream_id,
172092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       uint8_t *captured_samples,
173092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       uint8_t *playback_samples,
174092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       unsigned int frames,
175092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       const struct timespec *captured_time,
176092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       const struct timespec *playback_time,
177092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid		       void *user_arg)
178b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid{
1790cee67e5cc56b7bb56f520b7ed0814aefa78b1d9Dylan Reid	uint32_t frame_bytes = cras_client_format_bytes_per_frame(aud_format);
180d99453f0fdd4898c8ad9b1de71dcd373eb60802cDylan Reid	int fd = *(int *)user_arg;
181d99453f0fdd4898c8ad9b1de71dcd373eb60802cDylan Reid	uint8_t buff[BUF_SIZE];
182d99453f0fdd4898c8ad9b1de71dcd373eb60802cDylan Reid	int nread;
183b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
1846dac2de41754d749d04d727c42b58aff43d12248Hsin-Yu Chao	while (pause_client)
1856dac2de41754d749d04d727c42b58aff43d12248Hsin-Yu Chao		usleep(10000);
1866dac2de41754d749d04d727c42b58aff43d12248Hsin-Yu Chao
1870c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang	if (pause_a_reply) {
1880c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang		usleep(pause_in_playback_reply);
1890c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang		pause_a_reply = 0;
1900c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang	}
1910c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang
192c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid	check_stream_terminate(frames);
193c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid
194092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid	cras_client_calc_playback_latency(playback_time, &last_latency);
195b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
1965a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette	if (play_short_sound) {
1975a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette		if (play_short_sound_periods_left)
1985a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			/* Play a period from file. */
1995a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			play_short_sound_periods_left--;
2005a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette		else {
2015a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			/* Fill zeros to play silence. */
2025a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			memset(playback_samples, 0,
2035a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			       MIN(frames * frame_bytes, BUF_SIZE));
2045a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			return frames;
2055a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette		}
2065a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette	}
2075a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette
208d99453f0fdd4898c8ad9b1de71dcd373eb60802cDylan Reid	nread = read(fd, buff, MIN(frames * frame_bytes, BUF_SIZE));
209e22e543cb49ed2d0d9c81a424b4d5df8758c520aCheng-Yi Chiang	if (nread <= 0) {
210e22e543cb49ed2d0d9c81a424b4d5df8758c520aCheng-Yi Chiang		if (exit_after_done_playing)
211e22e543cb49ed2d0d9c81a424b4d5df8758c520aCheng-Yi Chiang			terminate_stream_loop();
212d99453f0fdd4898c8ad9b1de71dcd373eb60802cDylan Reid		return nread;
213e22e543cb49ed2d0d9c81a424b4d5df8758c520aCheng-Yi Chiang	}
214d99453f0fdd4898c8ad9b1de71dcd373eb60802cDylan Reid
215a930d7e2e7028854751f604bc43763c10f10465cNicolas Boichat	memcpy(playback_samples, buff, nread);
216a930d7e2e7028854751f604bc43763c10f10465cNicolas Boichat	return nread / frame_bytes;
217b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid}
218b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
219b605206031fc9c9bc3fef7bd47225690f7fc3f49Dylan Reid/* Run from callback thread. */
2206758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chaostatic int put_stdin_samples(struct cras_client *client,
2216758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		       cras_stream_id_t stream_id,
2226758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		       uint8_t *captured_samples,
2236758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		       uint8_t *playback_samples,
2246758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		       unsigned int frames,
2256758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		       const struct timespec *captured_time,
2266758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		       const struct timespec *playback_time,
2276758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		       void *user_arg)
2286758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao{
2296758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao	int rc = 0;
2306758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao	uint32_t frame_bytes = cras_client_format_bytes_per_frame(aud_format);
2316758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao
2326758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao	rc = read(0, playback_samples, frames * frame_bytes);
2333040759af430fd30ba4c8f35c18b7dbe9c98371dOwen Lin	if (rc <= 0) {
2343040759af430fd30ba4c8f35c18b7dbe9c98371dOwen Lin		terminate_stream_loop();
2356758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		return -1;
2366758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao	}
2376758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao
2386758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao	return rc / frame_bytes;
2396758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao}
2406758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao
241c386512207e89e35a5ee7a0d2cbbe4bcae655122Dylan Reidstatic int stream_error(struct cras_client *client,
242c386512207e89e35a5ee7a0d2cbbe4bcae655122Dylan Reid			cras_stream_id_t stream_id,
243c386512207e89e35a5ee7a0d2cbbe4bcae655122Dylan Reid			int err,
244c386512207e89e35a5ee7a0d2cbbe4bcae655122Dylan Reid			void *arg)
245b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid{
246b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	printf("Stream error %d\n", err);
24757f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	terminate_stream_loop();
248b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	return 0;
249b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid}
250b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
251b229192892ca72a981813340d54b09b0ac8848d7Dylan Reidstatic void print_last_latency()
252b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid{
2532df371d800415d088742fed6b7e3ec00930837b6Hsinyu Chao	if (last_latency.tv_sec > 0 || last_latency.tv_nsec > 0)
2542df371d800415d088742fed6b7e3ec00930837b6Hsinyu Chao		printf("%u.%09u\n", (unsigned)last_latency.tv_sec,
2552df371d800415d088742fed6b7e3ec00930837b6Hsinyu Chao		       (unsigned)last_latency.tv_nsec);
2562df371d800415d088742fed6b7e3ec00930837b6Hsinyu Chao	else {
257656dc496f54a2ebb4f03aad42b49cea9ef2d1e64Mike Frysinger		printf("-%lld.%09lld\n", (long long)-last_latency.tv_sec,
258656dc496f54a2ebb4f03aad42b49cea9ef2d1e64Mike Frysinger		       (long long)-last_latency.tv_nsec);
2592df371d800415d088742fed6b7e3ec00930837b6Hsinyu Chao	}
260b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid}
261b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
2629f8382e1e824fd96fbab604968e35a2a99569165Adrian Listatic void print_last_rms()
2639f8382e1e824fd96fbab604968e35a2a99569165Adrian Li{
2649f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	if (last_rms_size != 0)
2659f8382e1e824fd96fbab604968e35a2a99569165Adrian Li		printf("%.9f\n", sqrt(last_rms_sqr_sum / last_rms_size));
2669f8382e1e824fd96fbab604968e35a2a99569165Adrian Li}
2679f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
2689f8382e1e824fd96fbab604968e35a2a99569165Adrian Listatic void print_total_rms()
2699f8382e1e824fd96fbab604968e35a2a99569165Adrian Li{
2709f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	if (total_rms_size != 0)
2719f8382e1e824fd96fbab604968e35a2a99569165Adrian Li		printf("%.9f\n", sqrt(total_rms_sqr_sum / total_rms_size));
2729f8382e1e824fd96fbab604968e35a2a99569165Adrian Li}
2739f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
27404d859384c29e7e6bc4fb95d11bcea12c97755dcDylan Reidstatic void print_dev_info(const struct cras_iodev_info *devs, int num_devs)
27504d859384c29e7e6bc4fb95d11bcea12c97755dcDylan Reid{
27604d859384c29e7e6bc4fb95d11bcea12c97755dcDylan Reid	unsigned i;
27704d859384c29e7e6bc4fb95d11bcea12c97755dcDylan Reid
27851d2ed0de586c379c39327174944e6d6244cb11bHsin-Yu Chao	printf("\tID\tName\n");
27951d2ed0de586c379c39327174944e6d6244cb11bHsin-Yu Chao	for (i = 0; i < num_devs; i++)
28051d2ed0de586c379c39327174944e6d6244cb11bHsin-Yu Chao		printf("\t%u\t%s\n", devs[i].idx, devs[i].name);
28104d859384c29e7e6bc4fb95d11bcea12c97755dcDylan Reid}
28204d859384c29e7e6bc4fb95d11bcea12c97755dcDylan Reid
2830d748981c4e191b7dad6022bef70da432314a19aChih-Chung Changstatic void print_node_info(const struct cras_ionode_info *nodes, int num_nodes,
2840d748981c4e191b7dad6022bef70da432314a19aChih-Chung Chang			    int is_input)
285089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang{
286089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	unsigned i;
287089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang
28851d2ed0de586c379c39327174944e6d6244cb11bHsin-Yu Chao	printf("\tStable Id\t ID\t%4s   Plugged\tL/R swapped\t      "
2896235e8711de364773168da141c71bc21ef656121Ben Zhang	       "Time Hotword\tType\t\t Name\n", is_input ? "Gain" : " Vol");
290089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	for (i = 0; i < num_nodes; i++)
2916235e8711de364773168da141c71bc21ef656121Ben Zhang		printf("\t(%08x)\t%u:%u\t%5g  %7s\t%14s\t%10ld %-7s\t%-16s%c%s\n",
29251d2ed0de586c379c39327174944e6d6244cb11bHsin-Yu Chao		       nodes[i].stable_id,
293089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang		       nodes[i].iodev_idx,
294089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang		       nodes[i].ionode_idx,
2950d748981c4e191b7dad6022bef70da432314a19aChih-Chung Chang		       is_input ? nodes[i].capture_gain / 100.0
2960d748981c4e191b7dad6022bef70da432314a19aChih-Chung Chang		       : (double) nodes[i].volume,
297089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang		       nodes[i].plugged ? "yes" : "no",
298de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang		       nodes[i].left_right_swapped ? "yes" : "no",
29983281aac4fbd44bce5a2a818b819bb657d5cfb77Chih-Chung Chang		       (long) nodes[i].plugged_time.tv_sec,
3006235e8711de364773168da141c71bc21ef656121Ben Zhang		       nodes[i].active_hotword_model,
30155a711534f451e769f32e8f4f0c8af1f2e8169b3Chih-Chung Chang		       nodes[i].type,
30231426461ec77c5a7ee613d52d0a93db6b68e7b7cChih-Chung Chang		       nodes[i].active ? '*' : ' ',
303089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang		       nodes[i].name);
304089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang}
305089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang
30654fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reidstatic void print_device_lists(struct cras_client *client)
30754fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reid{
30854fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reid	struct cras_iodev_info devs[MAX_IODEVS];
309089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	struct cras_ionode_info nodes[MAX_IONODES];
310089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	size_t num_devs, num_nodes;
311089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	int rc;
312089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang
313089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	num_devs = MAX_IODEVS;
314089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	num_nodes = MAX_IONODES;
315089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	rc = cras_client_get_output_devices(client, devs, nodes, &num_devs,
316089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang					    &num_nodes);
317089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	if (rc < 0)
31854fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reid		return;
3195263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	printf("Output Devices:\n");
32004d859384c29e7e6bc4fb95d11bcea12c97755dcDylan Reid	print_dev_info(devs, num_devs);
321089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	printf("Output Nodes:\n");
3220d748981c4e191b7dad6022bef70da432314a19aChih-Chung Chang	print_node_info(nodes, num_nodes, 0);
323089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang
324089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	num_devs = MAX_IODEVS;
325089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	num_nodes = MAX_IONODES;
326089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	rc = cras_client_get_input_devices(client, devs, nodes, &num_devs,
327089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang					   &num_nodes);
3285263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	printf("Input Devices:\n");
32904d859384c29e7e6bc4fb95d11bcea12c97755dcDylan Reid	print_dev_info(devs, num_devs);
330089527f93ebf64542d50ce5d69fa40833d788ad1Chih-Chung Chang	printf("Input Nodes:\n");
3310d748981c4e191b7dad6022bef70da432314a19aChih-Chung Chang	print_node_info(nodes, num_nodes, 1);
33254fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reid}
33354fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reid
33439f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reidstatic void print_attached_client_list(struct cras_client *client)
33539f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid{
33639f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid	struct cras_attached_client_info clients[MAX_ATTACHED_CLIENTS];
33739f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid	size_t i;
33839f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid	int num_clients;
33939f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid
34039f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid	num_clients = cras_client_get_attached_clients(client,
34139f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid						       clients,
34239f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid						       MAX_ATTACHED_CLIENTS);
34339f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid	if (num_clients < 0)
34439f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid		return;
3452c1e4a94b93ea1ca23ae1ab177a80ad769a7c18aDylan Reid	num_clients = MIN(num_clients, MAX_ATTACHED_CLIENTS);
34639f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid	printf("Attached clients:\n");
3475263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	printf("\tID\tpid\tuid\n");
34839f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid	for (i = 0; i < num_clients; i++)
349aed6ee2f614bcb3b6e325828abd9780784967b3cNicolas Boichat		printf("\t%u\t%d\t%d\n",
35039f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid		       clients[i].id,
35139f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid		       clients[i].pid,
35239f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid		       clients[i].gid);
35339f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid}
35439f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid
355efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reidstatic void print_active_stream_info(struct cras_client *client)
356efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reid{
357efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reid	struct timespec ts;
358efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reid	unsigned num_streams;
359efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reid
360efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reid	num_streams = cras_client_get_num_active_streams(client, &ts);
361efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reid	printf("Num active streams: %u\n", num_streams);
362656dc496f54a2ebb4f03aad42b49cea9ef2d1e64Mike Frysinger	printf("Last audio active time: %llu, %llu\n",
363656dc496f54a2ebb4f03aad42b49cea9ef2d1e64Mike Frysinger	       (long long)ts.tv_sec, (long long)ts.tv_nsec);
364efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reid}
365efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reid
3665263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reidstatic void print_system_volumes(struct cras_client *client)
3675263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid{
3685263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	printf("System Volume (0-100): %zu %s\n"
36904f7b3bfd4a500b5b7704d7a04a55b2242bf9dd1Dylan Reid	       "Capture Gain (%.2f - %.2f): %.2fdB %s\n",
3705263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	       cras_client_get_system_volume(client),
3715263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	       cras_client_get_system_muted(client) ? "(Muted)" : "",
37204f7b3bfd4a500b5b7704d7a04a55b2242bf9dd1Dylan Reid	       cras_client_get_system_min_capture_gain(client) / 100.0,
37304f7b3bfd4a500b5b7704d7a04a55b2242bf9dd1Dylan Reid	       cras_client_get_system_max_capture_gain(client) / 100.0,
3746600778e38e67dc0ffe7247e9a0ab1fd86921675Dylan Reid	       cras_client_get_system_capture_gain(client) / 100.0,
3755263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	       cras_client_get_system_capture_muted(client) ? "(Muted)" : "");
3765263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid}
3775263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid
3789ee566e5cb9253fc173df35cb114914ff3d13ba9Cheng-Yi Chiangstatic void print_user_muted(struct cras_client *client)
3799ee566e5cb9253fc173df35cb114914ff3d13ba9Cheng-Yi Chiang{
3809ee566e5cb9253fc173df35cb114914ff3d13ba9Cheng-Yi Chiang	printf("User muted: %s\n",
3819ee566e5cb9253fc173df35cb114914ff3d13ba9Cheng-Yi Chiang	       cras_client_get_user_muted(client) ? "Muted" : "Not muted");
3829ee566e5cb9253fc173df35cb114914ff3d13ba9Cheng-Yi Chiang}
3839ee566e5cb9253fc173df35cb114914ff3d13ba9Cheng-Yi Chiang
38430adbd171d53723268e88e24dcc46383d7900945Dylan Reidstatic void show_alog_tag(const struct audio_thread_event_log *log,
38530adbd171d53723268e88e24dcc46383d7900945Dylan Reid			  unsigned int tag_idx)
38630adbd171d53723268e88e24dcc46383d7900945Dylan Reid{
38702d90444713f791c693d04a01ac7fca55534d61bCheng-Yi Chiang	unsigned int tag = (log->log[tag_idx].tag_sec >> 24) & 0xff;
38830adbd171d53723268e88e24dcc46383d7900945Dylan Reid	unsigned int sec = log->log[tag_idx].tag_sec & 0x00ffffff;
38930adbd171d53723268e88e24dcc46383d7900945Dylan Reid	unsigned int nsec = log->log[tag_idx].nsec;
39030adbd171d53723268e88e24dcc46383d7900945Dylan Reid	unsigned int data1 = log->log[tag_idx].data1;
39130adbd171d53723268e88e24dcc46383d7900945Dylan Reid	unsigned int data2 = log->log[tag_idx].data2;
39230adbd171d53723268e88e24dcc46383d7900945Dylan Reid	unsigned int data3 = log->log[tag_idx].data3;
39330adbd171d53723268e88e24dcc46383d7900945Dylan Reid
394caab9c5542f4858aca4de994b0eed78aafe5675aChinyue Chen	/* Skip unused log entries. */
395caab9c5542f4858aca4de994b0eed78aafe5675aChinyue Chen	if (log->log[tag_idx].tag_sec == 0 && log->log[tag_idx].nsec == 0)
396caab9c5542f4858aca4de994b0eed78aafe5675aChinyue Chen		return;
397caab9c5542f4858aca4de994b0eed78aafe5675aChinyue Chen
39807ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang	printf("%10u.%09u  ", sec, nsec);
39907ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang
40030adbd171d53723268e88e24dcc46383d7900945Dylan Reid	switch (tag) {
40130adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_WAKE:
40207ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s num_fds:%d\n", "WAKE", (int)data1);
40330adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
40430adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_SLEEP:
40507ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s sleep:%09d.%09d longest_wake:%09d\n",
40607ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "SLEEP", (int)data1, (int)data2, (int)data3);
40730adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
40830adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_READ_AUDIO:
409a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u hw_level:%u read:%u\n",
41007ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "READ_AUDIO", data1, data2, data3);
41130adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
412fa4cd9766aec6eae544b1078ed835687c4e74617John Muir	case AUDIO_THREAD_READ_AUDIO_TSTAMP:
413a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u tstamp:%09d.%09d\n",
414fa4cd9766aec6eae544b1078ed835687c4e74617John Muir		       "READ_AUDIO_TSTAMP", data1, (int)data2, (int)data3);
415fa4cd9766aec6eae544b1078ed835687c4e74617John Muir		break;
41630adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_READ_AUDIO_DONE:
41707ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s read_remainder:%u\n", "READ_AUDIO_DONE", data1);
41830adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
419fe3b32adb850b6637934195ec2a0055fb9199ce5Hsin-Yu Chao	case AUDIO_THREAD_READ_OVERRUN:
420a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u stream:%x num_overruns:%u\n",
421fe3b32adb850b6637934195ec2a0055fb9199ce5Hsin-Yu Chao		       "READ_AUDIO_OVERRUN", data1, data2, data3);
422fe3b32adb850b6637934195ec2a0055fb9199ce5Hsin-Yu Chao		break;
42330adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_FILL_AUDIO:
424a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u hw_level:%u\n",
42507ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "FILL_AUDIO", data1, data2);
42630adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
427fa4cd9766aec6eae544b1078ed835687c4e74617John Muir	case AUDIO_THREAD_FILL_AUDIO_TSTAMP:
428a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u tstamp:%09d.%09d\n",
429fa4cd9766aec6eae544b1078ed835687c4e74617John Muir		       "FILL_AUDIO_TSTAMP", data1, (int)data2, (int)data3);
430fa4cd9766aec6eae544b1078ed835687c4e74617John Muir		break;
43130adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_FILL_AUDIO_DONE:
432ea3ee4a5d8cc75a9307e13c0756192f26b4f9f41Cheng-Yi Chiang		printf("%-30s hw_level:%u total_written:%u min_cb_level:%u\n",
433ea3ee4a5d8cc75a9307e13c0756192f26b4f9f41Cheng-Yi Chiang		       "FILL_AUDIO_DONE", data1, data2, data3);
43430adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
43530adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_WRITE_STREAMS_WAIT:
43607ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s stream:%x\n", "WRITE_STREAMS_WAIT", data1);
43730adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
43830adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_WRITE_STREAMS_WAIT_TO:
43907ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s\n", "WRITE_STREAMS_WAIT_TO");
44030adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
44130adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_WRITE_STREAMS_MIX:
44207ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s write_limit:%u max_offset:%u\n",
44307ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "WRITE_STREAMS_MIX", data1, data2);
44430adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
44530adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_WRITE_STREAMS_MIXED:
44607ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s write_limit:%u\n", "WRITE_STREAMS_MIXED", data1);
44730adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
44830adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_WRITE_STREAMS_STREAM:
44907ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s id:%x shm_frames:%u cb_pending:%u\n",
45007ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "WRITE_STREAMS_STREAM", data1, data2, data3);
45130adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
45230adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_FETCH_STREAM:
45307ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s id:%x cbth:%u delay:%u\n",
45407ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "WRITE_STREAMS_FETCH_STREAM", data1, data2, data3);
45530adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
45630adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_STREAM_ADDED:
457a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s id:%x dev:%u\n",
45807ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "STREAM_ADDED", data1, data2);
45930adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
46030adbd171d53723268e88e24dcc46383d7900945Dylan Reid	case AUDIO_THREAD_STREAM_REMOVED:
46107ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s id:%x\n", "STREAM_REMOVED", data1);
46230adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
463c9452136e619b69333dc3bd5fb87e5168793c9c0Dylan Reid	case AUDIO_THREAD_A2DP_ENCODE:
46407ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s proc:%d queued:%u readable:%u\n",
46507ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "A2DP_ENCODE", data1, data2, data3);
466c9452136e619b69333dc3bd5fb87e5168793c9c0Dylan Reid		break;
467c9452136e619b69333dc3bd5fb87e5168793c9c0Dylan Reid	case AUDIO_THREAD_A2DP_WRITE:
46807ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s written:%d queued:%u\n",
46907ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "A2DP_WRITE", data1, data2);
470c9452136e619b69333dc3bd5fb87e5168793c9c0Dylan Reid		break;
471f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid	case AUDIO_THREAD_DEV_STREAM_MIX:
47207ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s written:%u read:%u\n",
47307ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "DEV_STREAM_MIX", data1, data2);
474f5678f0806610f1778f3d9f6d4e65a13e3f73c1eDylan Reid		break;
4757180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid	case AUDIO_THREAD_CAPTURE_POST:
47607ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s stream:%x thresh:%u rd_buf:%u\n",
47707ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "CAPTURE_POST", data1, data2, data3);
4787180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid		break;
4797180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid	case AUDIO_THREAD_CAPTURE_WRITE:
48007ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s stream:%x write:%u shm_fr:%u\n",
48107ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "CAPTURE_WRITE", data1, data2, data3);
4827180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid		break;
4837180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid	case AUDIO_THREAD_CONV_COPY:
48407ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s wr_buf:%u shm_writable:%u offset:%u\n",
48507ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "CONV_COPY", data1, data2, data3);
4867180fbd487d1ed4ad398fbb5523ba46e129663efDylan Reid		break;
487d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid	case AUDIO_THREAD_STREAM_SLEEP_TIME:
48807ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s id:%x wake:%09u.%09d\n",
48907ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "STREAM_SLEEP_TIME", data1, (int)data2, (int)data3);
490d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid		break;
491d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid	case AUDIO_THREAD_STREAM_SLEEP_ADJUST:
49207ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s id:%x from:%09u.%09d\n",
49307ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "STREAM_SLEEP_ADJUST", data1, data2, data3);
494d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid		break;
495d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid	case AUDIO_THREAD_STREAM_SKIP_CB:
49607ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s id:%x write_offset_0:%u write_offset_1:%u\n",
49707ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "STREAM_SKIP_CB", data1, data2, data3);
498d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid		break;
499d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid	case AUDIO_THREAD_DEV_SLEEP_TIME:
500a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u wake:%09u.%09d\n",
50107ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "DEV_SLEEP_TIME", data1, data2, data3);
502d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid		break;
503d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid	case AUDIO_THREAD_SET_DEV_WAKE:
504a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u hw_level:%u sleep:%u\n",
50507ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		       "SET_DEV_WAKE", data1, data2, data3);
506d181423fe627ea344c57d7dad22f02fb65330fcdDylan Reid		break;
5077d14eca9008fda484e4e3e34be33915480c3d436Dylan Reid	case AUDIO_THREAD_DEV_ADDED:
508a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u\n", "DEV_ADDED", data1);
5097d14eca9008fda484e4e3e34be33915480c3d436Dylan Reid		break;
5107d14eca9008fda484e4e3e34be33915480c3d436Dylan Reid	case AUDIO_THREAD_DEV_REMOVED:
511a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u\n", "DEV_REMOVED", data1);
5127d14eca9008fda484e4e3e34be33915480c3d436Dylan Reid		break;
513b5a0ba8a481fe6c75c5091305b38430cf8ff4ba3Dylan Reid	case AUDIO_THREAD_IODEV_CB:
51407ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s is_write:%u\n", "IODEV_CB", data1);
515b5a0ba8a481fe6c75c5091305b38430cf8ff4ba3Dylan Reid		break;
51666f39f1d8262945194eb685570f95909d4323208Dylan Reid	case AUDIO_THREAD_PB_MSG:
51707ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s msg_id:%u\n", "PB_MSG", data1);
51866f39f1d8262945194eb685570f95909d4323208Dylan Reid		break;
519b727fc35b8c0eb0f25aa3dd69146fd64a449cabaDylan Reid	case AUDIO_THREAD_ODEV_NO_STREAMS:
520a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u\n",
52139c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang		       "ODEV_NO_STREAMS", data1);
52239c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang		break;
52339c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang	case AUDIO_THREAD_ODEV_LEAVE_NO_STREAMS:
524a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u\n",
52539c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang		       "ODEV_LEAVE_NO_STREAMS", data1);
526e8671a3b6e6833a430cd1c9b5effde1a10abf035Dylan Reid		break;
52719363f71216cd60a189e96bb0cae2e82013c3d81Cheng-Yi Chiang	case AUDIO_THREAD_ODEV_START:
528a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u min_cb_level:%u\n",
529f8b62e7bf4cf906401bb46f31080a0b955ca57bbCheng-Yi Chiang		       "ODEV_START", data1, data2);
53019363f71216cd60a189e96bb0cae2e82013c3d81Cheng-Yi Chiang		break;
53139c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang	case AUDIO_THREAD_FILL_ODEV_ZEROS:
532a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u write:%u\n",
53339c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang		       "FILL_ODEV_ZEROS", data1, data2);
53439c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang		break;
53539c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang	case AUDIO_THREAD_ODEV_DEFAULT_NO_STREAMS:
536a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u hw_level:%u target:%u\n",
53739c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang		       "DEFAULT_NO_STREAMS", data1, data2, data3);
53839c60b6d0f9050a9a62cd9d5dd6fd1b0def49c95Cheng-Yi Chiang		break;
53994f07550848b7e387bf063949c939866acc0225cCheng-Yi Chiang	case AUDIO_THREAD_SEVERE_UNDERRUN:
540a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("%-30s dev:%u\n", "SEVERE_UNDERRUN", data1);
54194f07550848b7e387bf063949c939866acc0225cCheng-Yi Chiang		break;
54230adbd171d53723268e88e24dcc46383d7900945Dylan Reid	default:
54307ec4d195bd8351dc7a9f0f3100d038379b8ce9bCheng-Yi Chiang		printf("%-30s tag:%u\n","UNKNOWN", tag);
54430adbd171d53723268e88e24dcc46383d7900945Dylan Reid		break;
54530adbd171d53723268e88e24dcc46383d7900945Dylan Reid	}
54630adbd171d53723268e88e24dcc46383d7900945Dylan Reid}
54730adbd171d53723268e88e24dcc46383d7900945Dylan Reid
5486d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reidstatic void audio_debug_info(struct cras_client *client)
5496d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid{
5506d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	const struct audio_debug_info *info;
5513c194bb9bf7e2cf8a3bdf5c8378ef47794585b51Dylan Reid	int i, j;
5526d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
5536d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	info = cras_client_get_audio_debug_info(client);
5546d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	if (!info)
5556d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid		return;
5566d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
5576d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	printf("Audio Debug Stats:\n");
5586d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	printf("-------------devices------------\n");
559b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao	if (info->num_devs > MAX_DEBUG_DEVS)
560b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao		return;
561b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao
562b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao	for (i = 0; i < info->num_devs; i++) {
563b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao		printf("%s dev: %s\n",
564b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao		       (info->devs[i].direction == CRAS_STREAM_INPUT)
565b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao				? "Input" : "Output",
566b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao		       info->devs[i].dev_name);
567595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang		printf("buffer_size: %u\n"
568595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang		       "min_buffer_level: %u\n"
569595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang		       "min_cb_level: %u\n"
570595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang		       "max_cb_level: %u\n"
571595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang		       "frame_rate: %u\n"
572595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang		       "num_channels: %u\n"
573595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang		       "est_rate_ratio: %lf\n"
574d34bdb1fada946db0fb8e3360110b2cf9e16c09fCheng-Yi Chiang		       "num_underruns: %u\n"
575d34bdb1fada946db0fb8e3360110b2cf9e16c09fCheng-Yi Chiang		       "num_severe_underruns: %u\n",
576b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao		       (unsigned int)info->devs[i].buffer_size,
577b9e9f6cec05e82d35ade097a31f31f20e1049cf9Hsin-Yu Chao		       (unsigned int)info->devs[i].min_buffer_level,
578b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao		       (unsigned int)info->devs[i].min_cb_level,
579b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao		       (unsigned int)info->devs[i].max_cb_level,
580b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao		       (unsigned int)info->devs[i].frame_rate,
581b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao		       (unsigned int)info->devs[i].num_channels,
582595b415568beb0048c31e3111c5c935530be1032Cheng-Yi Chiang		       info->devs[i].est_rate_ratio,
583d34bdb1fada946db0fb8e3360110b2cf9e16c09fCheng-Yi Chiang		       (unsigned int)info->devs[i].num_underruns,
584d34bdb1fada946db0fb8e3360110b2cf9e16c09fCheng-Yi Chiang		       (unsigned int)info->devs[i].num_severe_underruns);
585bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		printf("\n");
586b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao	}
587b629582f1e59ce952147d6239da35f86166b8a98Hsin-Yu Chao
5886d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	printf("-------------stream_dump------------\n");
5896d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	if (info->num_streams > MAX_DEBUG_STREAMS)
5906d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid		return;
5916d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
5926d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	for (i = 0; i < info->num_streams; i++) {
5936d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid		int channel;
594a260b3aaaff38cb3972158739436ad32db15a8a8Chinyue Chen		printf("stream: %llx dev: %u\n",
5954021be1c5d578d8f0d84dfc33fcfa1633964a970Dylan Reid		       (unsigned long long)info->streams[i].stream_id,
5964021be1c5d578d8f0d84dfc33fcfa1633964a970Dylan Reid		       (unsigned int)info->streams[i].dev_idx);
597bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		printf("direction: %s\n",
598bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		       (info->streams[i].direction == CRAS_STREAM_INPUT)
599bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang				? "Input" : "Output");
6005082f2462775c1e215d187496cc8fda3058ddd86Chinyue Chen		printf("stream_type: %s\n",
6015082f2462775c1e215d187496cc8fda3058ddd86Chinyue Chen		       cras_stream_type_str(info->streams[i].stream_type));
602bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		printf("buffer_frames: %u\n"
603bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		       "cb_threshold: %u\n"
604bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		       "frame_rate: %u\n"
605bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		       "num_channels: %u\n"
606bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		       "longest_fetch_sec: %u.%09u\n"
607bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		       "num_overruns: %u\n",
6086d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid		       (unsigned int)info->streams[i].buffer_frames,
6096d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid		       (unsigned int)info->streams[i].cb_threshold,
6106d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid		       (unsigned int)info->streams[i].frame_rate,
611d08e074704529f63cffed728e446fd0790a7aeffHsin-Yu Chao		       (unsigned int)info->streams[i].num_channels,
612d08e074704529f63cffed728e446fd0790a7aeffHsin-Yu Chao		       (unsigned int)info->streams[i].longest_fetch_sec,
613bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		       (unsigned int)info->streams[i].longest_fetch_nsec,
614bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		       (unsigned int)info->streams[i].num_overruns);
615bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		printf("channel map:");
6166d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid		for (channel = 0; channel < CRAS_CH_MAX; channel++)
6176d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid			printf("%d ", info->streams[i].channel_layout[channel]);
618bd7dee79e32fcd3452599f8e75d3599152369ddbCheng-Yi Chiang		printf("\n\n");
6196d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	}
6206d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
6216d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	printf("Audio Thread Event Log:\n");
6226d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
6233c194bb9bf7e2cf8a3bdf5c8378ef47794585b51Dylan Reid	j = info->log.write_pos;
62430adbd171d53723268e88e24dcc46383d7900945Dylan Reid	i = 0;
62530adbd171d53723268e88e24dcc46383d7900945Dylan Reid	printf("start at %d\n", j);
62630adbd171d53723268e88e24dcc46383d7900945Dylan Reid	for (; i < info->log.len; i++) {
62730adbd171d53723268e88e24dcc46383d7900945Dylan Reid		show_alog_tag(&info->log, j);
6283c194bb9bf7e2cf8a3bdf5c8378ef47794585b51Dylan Reid		j++;
62951e35b1f5e1622f47ef62b1a4f66dba954fdcbc3Dylan Reid		j %= info->log.len;
6303c194bb9bf7e2cf8a3bdf5c8378ef47794585b51Dylan Reid	}
6313c194bb9bf7e2cf8a3bdf5c8378ef47794585b51Dylan Reid
6326d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	/* Signal main thread we are done after the last chunk. */
6336d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	pthread_mutex_lock(&done_mutex);
6346d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	pthread_cond_signal(&done_cond);
6356d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	pthread_mutex_unlock(&done_mutex);
6366d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid}
6376d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
63898bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reidstatic int start_stream(struct cras_client *client,
63998bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			cras_stream_id_t *stream_id,
64098bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			struct cras_stream_params *params,
64198bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			float stream_volume)
64298bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid{
64398bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid	int rc;
64498bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid
645883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chen	if (pin_device_id)
646883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chen		rc = cras_client_add_pinned_stream(client, pin_device_id,
647883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chen						   stream_id, params);
648883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chen	else
649883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chen		rc = cras_client_add_stream(client, stream_id, params);
65098bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid	if (rc < 0) {
651b605206031fc9c9bc3fef7bd47225690f7fc3f49Dylan Reid		fprintf(stderr, "adding a stream %d\n", rc);
65298bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid		return rc;
65398bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid	}
65498bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid	return cras_client_set_stream_volume(client, *stream_id, stream_volume);
65598bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid}
65698bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid
6576bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chaostatic int parse_channel_layout(char *channel_layout_str,
6586bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao				int8_t channel_layout[CRAS_CH_MAX])
6596bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao{
6606bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao	int i = 0;
6616bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao	char *chp;
6626bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao
6636bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao	chp = strtok(channel_layout_str, ",");
6646bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao	while (chp && i < CRAS_CH_MAX) {
6656bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao		channel_layout[i++] = atoi(chp);
6666bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao		chp = strtok(NULL, ",");
6676bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao	}
6686bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao
6696bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao	return 0;
6706bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao}
6716bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao
672b229192892ca72a981813340d54b09b0ac8848d7Dylan Reidstatic int run_file_io_stream(struct cras_client *client,
673b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			      int fd,
674ce895e7bb75a63c593bec7a5a36bfed3241ab829Dylan Reid			      enum CRAS_STREAM_DIRECTION direction,
67564732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin			      size_t block_size,
6768c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			      enum CRAS_STREAM_TYPE stream_type,
677718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid			      size_t rate,
6788900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid			      size_t num_channels,
679179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid			      uint32_t flags,
680179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid			      int is_loopback)
681b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid{
682f66f20de28dbd1d1d2a42faa270d2bdbc97883d1Hsin-Yu Chao	int rc, tty;
683b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	struct cras_stream_params *params;
684092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid	cras_unified_cb_t aud_cb;
685b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	cras_stream_id_t stream_id = 0;
686b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	int stream_playing = 0;
687b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	int *pfd = malloc(sizeof(*pfd));
688b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	*pfd = fd;
689b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	fd_set poll_set;
690b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	struct timespec sleep_ts;
69120e15b710035bec49c83af0003fe252c02cc2a39Dylan Reid	float volume_scaler = 1.0;
692960cc77cb4e51e4b4c69b81b56e52a26a2025457Dylan Reid	size_t sys_volume = 100;
6932cf95eaa55fc7a5121531bf6831a105d049c5e61Dylan Reid	long cap_gain = 0;
6946139c58ff9cecbbc386cf764b6d511b673b1e32dDylan Reid	int mute = 0;
6956bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao	int8_t layout[CRAS_CH_MAX];
696b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
69757f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	/* Set the sleep interval between latency/RMS prints. */
69857f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	sleep_ts.tv_sec = 1;
69957f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	sleep_ts.tv_nsec = 0;
70057f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li
70157f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	/* Open the pipe file descriptor. */
70257f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	rc = pipe(pipefd);
70357f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	if (rc == -1) {
70457f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li		perror("failed to open pipe");
70557f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li		return -errno;
70657f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	}
707b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
7089f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	/* Reset the total RMS value. */
7099f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	total_rms_sqr_sum = 0;
7109f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	total_rms_size = 0;
7119f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
7128900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid	if (direction == CRAS_STREAM_INPUT) {
7138900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		if (flags == HOTWORD_STREAM)
7148900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid			aud_cb = got_hotword;
7158900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		else
7168900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid			aud_cb = got_samples;
7178900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid	} else {
718b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		aud_cb = put_samples;
7198900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid	}
720b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
7216758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao	if (fd == 0) {
7226758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		if (direction != CRAS_STREAM_OUTPUT)
7236758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao			return -EINVAL;
7246758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		aud_cb = put_stdin_samples;
7256758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao	}
7266758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao
727718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid	aud_format = cras_audio_format_create(SND_PCM_FORMAT_S16_LE, rate,
728718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid					      num_channels);
729b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	if (aud_format == NULL)
730b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		return -ENOMEM;
731b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
7326bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao	if (channel_layout) {
7336bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao		/* Set channel layout to format */
7346bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao		parse_channel_layout(channel_layout, layout);
7356bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao		cras_audio_format_set_channel_layout(aud_format, layout);
7366bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao	}
7376bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao
738092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid	params = cras_client_unified_params_create(direction,
73964732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin						   block_size,
7408c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen						   stream_type,
7418900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid						   flags,
742092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid						   pfd,
743092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid						   aud_cb,
744092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid						   stream_error,
745092ee53f5a32d03d911a62df17c5b41613b28d95Dylan Reid						   aud_format);
746b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	if (params == NULL)
747b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		return -ENOMEM;
748b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
749b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	cras_client_run_thread(client);
750179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid	if (is_loopback) {
751179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid		cras_client_connected_wait(client);
752179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid		pin_device_id = cras_client_get_first_dev_type_idx(client,
753179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid				CRAS_NODE_TYPE_POST_MIX_PRE_DSP,
754179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid				CRAS_STREAM_INPUT);
755179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid	}
756b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
75798bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid	stream_playing =
758dc8c099f19a6b2dfbbdbf67d120f24c48ad134d8Hsinyu Chao		start_stream(client, &stream_id, params, volume_scaler) == 0;
75998bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid
760f66f20de28dbd1d1d2a42faa270d2bdbc97883d1Hsin-Yu Chao	tty = open("/dev/tty", O_RDONLY);
7616f9ee43cdf8fe64ee505f9c6dff82859eecf92f2Owen Lin
7626f9ee43cdf8fe64ee505f9c6dff82859eecf92f2Owen Lin	// There could be no terminal available when run in autotest.
7636f9ee43cdf8fe64ee505f9c6dff82859eecf92f2Owen Lin	if (tty == -1)
7646f9ee43cdf8fe64ee505f9c6dff82859eecf92f2Owen Lin		perror("warning: failed to open /dev/tty");
765f66f20de28dbd1d1d2a42faa270d2bdbc97883d1Hsin-Yu Chao
766b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	while (keep_looping) {
767b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		char input;
76898bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid		int nread;
769b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
770b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		FD_ZERO(&poll_set);
7716f9ee43cdf8fe64ee505f9c6dff82859eecf92f2Owen Lin		if (tty >= 0)
7726f9ee43cdf8fe64ee505f9c6dff82859eecf92f2Owen Lin			FD_SET(tty, &poll_set);
77357f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li		FD_SET(pipefd[0], &poll_set);
7742c1e4a94b93ea1ca23ae1ab177a80ad769a7c18aDylan Reid		pselect(MAX(tty, pipefd[0]) + 1,
77557f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li			&poll_set,
77657f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li			NULL,
77757f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li			NULL,
77857f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li			show_latency || show_rms ? &sleep_ts : NULL,
77957f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li			NULL);
780b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
781b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		if (stream_playing && show_latency)
782b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			print_last_latency();
783b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
7849f8382e1e824fd96fbab604968e35a2a99569165Adrian Li		if (stream_playing && show_rms)
7859f8382e1e824fd96fbab604968e35a2a99569165Adrian Li			print_last_rms();
7869f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
7876f9ee43cdf8fe64ee505f9c6dff82859eecf92f2Owen Lin		if (tty < 0 || !FD_ISSET(tty, &poll_set))
788b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			continue;
789b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
790f66f20de28dbd1d1d2a42faa270d2bdbc97883d1Hsin-Yu Chao		nread = read(tty, &input, 1);
791b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		if (nread < 1) {
792b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			fprintf(stderr, "Error reading stdin\n");
793b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			return nread;
794b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		}
795b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		switch (input) {
7966dac2de41754d749d04d727c42b58aff43d12248Hsin-Yu Chao		case 'p':
7976dac2de41754d749d04d727c42b58aff43d12248Hsin-Yu Chao			pause_client = !pause_client;
7986dac2de41754d749d04d727c42b58aff43d12248Hsin-Yu Chao			break;
7990c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang		case 'i':
8000c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang			pause_a_reply = 1;
8010c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang			break;
802b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		case 'q':
80357f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li			terminate_stream_loop();
804b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
805b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		case 's':
80698bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			if (stream_playing)
80798bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid				break;
80898bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid
80998bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			/* If started by hand keep running after it finishes. */
81098bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			exit_after_done_playing = 0;
81198bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid
81298bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			stream_playing = start_stream(client,
81398bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid						      &stream_id,
81498bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid						      params,
815dc8c099f19a6b2dfbbdbf67d120f24c48ad134d8Hsinyu Chao						      volume_scaler) == 0;
816b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
817b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		case 'r':
81898bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			if (!stream_playing)
81998bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid				break;
82098bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			cras_client_rm_stream(client, stream_id);
82198bd197641c3cb2f9c4fa05254fad22af70fd8e8Dylan Reid			stream_playing = 0;
822b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
8230f4794e9bd3c4fbd5f3f5bebe96df4314408bf2aDylan Reid		case 'u':
8242c1e4a94b93ea1ca23ae1ab177a80ad769a7c18aDylan Reid			volume_scaler = MIN(volume_scaler + 0.1, 1.0);
8250f4794e9bd3c4fbd5f3f5bebe96df4314408bf2aDylan Reid			cras_client_set_stream_volume(client,
8260f4794e9bd3c4fbd5f3f5bebe96df4314408bf2aDylan Reid						      stream_id,
82720e15b710035bec49c83af0003fe252c02cc2a39Dylan Reid						      volume_scaler);
8280f4794e9bd3c4fbd5f3f5bebe96df4314408bf2aDylan Reid			break;
8290f4794e9bd3c4fbd5f3f5bebe96df4314408bf2aDylan Reid		case 'd':
8302c1e4a94b93ea1ca23ae1ab177a80ad769a7c18aDylan Reid			volume_scaler = MAX(volume_scaler - 0.1, 0.0);
8310f4794e9bd3c4fbd5f3f5bebe96df4314408bf2aDylan Reid			cras_client_set_stream_volume(client,
8320f4794e9bd3c4fbd5f3f5bebe96df4314408bf2aDylan Reid						      stream_id,
83320e15b710035bec49c83af0003fe252c02cc2a39Dylan Reid						      volume_scaler);
8340f4794e9bd3c4fbd5f3f5bebe96df4314408bf2aDylan Reid			break;
835960cc77cb4e51e4b4c69b81b56e52a26a2025457Dylan Reid		case 'k':
8362c1e4a94b93ea1ca23ae1ab177a80ad769a7c18aDylan Reid			sys_volume = MIN(sys_volume + 1, 100);
837960cc77cb4e51e4b4c69b81b56e52a26a2025457Dylan Reid			cras_client_set_system_volume(client, sys_volume);
838960cc77cb4e51e4b4c69b81b56e52a26a2025457Dylan Reid			break;
839960cc77cb4e51e4b4c69b81b56e52a26a2025457Dylan Reid		case 'j':
840960cc77cb4e51e4b4c69b81b56e52a26a2025457Dylan Reid			sys_volume = sys_volume == 0 ? 0 : sys_volume - 1;
841960cc77cb4e51e4b4c69b81b56e52a26a2025457Dylan Reid			cras_client_set_system_volume(client, sys_volume);
842960cc77cb4e51e4b4c69b81b56e52a26a2025457Dylan Reid			break;
8432cf95eaa55fc7a5121531bf6831a105d049c5e61Dylan Reid		case 'K':
8442c1e4a94b93ea1ca23ae1ab177a80ad769a7c18aDylan Reid			cap_gain = MIN(cap_gain + 100, 5000);
8452cf95eaa55fc7a5121531bf6831a105d049c5e61Dylan Reid			cras_client_set_system_capture_gain(client, cap_gain);
8462cf95eaa55fc7a5121531bf6831a105d049c5e61Dylan Reid			break;
8472cf95eaa55fc7a5121531bf6831a105d049c5e61Dylan Reid		case 'J':
8482cf95eaa55fc7a5121531bf6831a105d049c5e61Dylan Reid			cap_gain = cap_gain == -5000 ? -5000 : cap_gain - 100;
8492cf95eaa55fc7a5121531bf6831a105d049c5e61Dylan Reid			cras_client_set_system_capture_gain(client, cap_gain);
8502cf95eaa55fc7a5121531bf6831a105d049c5e61Dylan Reid			break;
8516139c58ff9cecbbc386cf764b6d511b673b1e32dDylan Reid		case 'm':
8526139c58ff9cecbbc386cf764b6d511b673b1e32dDylan Reid			mute = !mute;
8536139c58ff9cecbbc386cf764b6d511b673b1e32dDylan Reid			cras_client_set_system_mute(client, mute);
8546139c58ff9cecbbc386cf764b6d511b673b1e32dDylan Reid			break;
85554fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reid		case '@':
85654fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reid			print_device_lists(client);
85754fdc334c9b3901887967f53fc55ebb01018bb1dDylan Reid			break;
85839f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid		case '#':
85939f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid			print_attached_client_list(client);
86039f934dc230415c6c6262d8edc6a9b5e28807754Dylan Reid			break;
861562252ba17b0d9284ccde9fd0caa9940e5cfa778Dylan Reid		case 'v':
86249453aa031a21a1793cfae948197ab934e17c6baDylan Reid			printf("Volume: %zu%s Min dB: %ld Max dB: %ld\n"
863b1783009dbc116799cf21615ed1356c55d4484f3Dylan Reid			       "Capture: %ld%s Min dB: %ld Max dB: %ld\n",
86449453aa031a21a1793cfae948197ab934e17c6baDylan Reid			       cras_client_get_system_volume(client),
86549453aa031a21a1793cfae948197ab934e17c6baDylan Reid			       cras_client_get_system_muted(client) ? "(Muted)"
86649453aa031a21a1793cfae948197ab934e17c6baDylan Reid								    : "",
86749453aa031a21a1793cfae948197ab934e17c6baDylan Reid			       cras_client_get_system_min_volume(client),
86849453aa031a21a1793cfae948197ab934e17c6baDylan Reid			       cras_client_get_system_max_volume(client),
86949453aa031a21a1793cfae948197ab934e17c6baDylan Reid			       cras_client_get_system_capture_gain(client),
87049453aa031a21a1793cfae948197ab934e17c6baDylan Reid			       cras_client_get_system_capture_muted(client) ?
871b1783009dbc116799cf21615ed1356c55d4484f3Dylan Reid						"(Muted)" : "",
872b1783009dbc116799cf21615ed1356c55d4484f3Dylan Reid			       cras_client_get_system_min_capture_gain(client),
873b1783009dbc116799cf21615ed1356c55d4484f3Dylan Reid			       cras_client_get_system_max_capture_gain(client));
874562252ba17b0d9284ccde9fd0caa9940e5cfa778Dylan Reid			break;
8755a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette		case '\'':
8765a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			play_short_sound_periods_left = play_short_sound_periods;
8775a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			break;
878b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		case '\n':
879b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
880b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		default:
881b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			printf("Invalid key\n");
882b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
883b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		}
884b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	}
8859f8382e1e824fd96fbab604968e35a2a99569165Adrian Li
8869f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	if (show_total_rms)
8879f8382e1e824fd96fbab604968e35a2a99569165Adrian Li		print_total_rms();
8886f9ee43cdf8fe64ee505f9c6dff82859eecf92f2Owen Lin
889b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	cras_client_stop(client);
890b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
891b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	cras_audio_format_destroy(aud_format);
892b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	cras_client_stream_params_destroy(params);
893b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	free(pfd);
894b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
89557f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	close(pipefd[0]);
89657f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li	close(pipefd[1]);
89757f84543a3ab60e7708bad7e8d4b9aecfde68befAdrian Li
898b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	return 0;
899b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid}
900b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
901b229192892ca72a981813340d54b09b0ac8848d7Dylan Reidstatic int run_capture(struct cras_client *client,
902b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		       const char *file,
90364732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin		       size_t block_size,
9048c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen		       enum CRAS_STREAM_TYPE stream_type,
905718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid		       size_t rate,
906179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid		       size_t num_channels,
907179f0470c5c9c34f400136c68403225d0bc8a4c9Dylan Reid		       int is_loopback)
908b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid{
90986f3a96ab778047418533e4037f888e27670147eOwen Lin	int fd = open(file, O_CREAT | O_RDWR | O_TRUNC, 0666);
91067738d7c78e99b887aab106efb0108edf9997da1Derek Basehore	if (fd == -1) {
91167738d7c78e99b887aab106efb0108edf9997da1Derek Basehore		perror("failed to open file");
91267738d7c78e99b887aab106efb0108edf9997da1Derek Basehore		return -errno;
91367738d7c78e99b887aab106efb0108edf9997da1Derek Basehore	}
914b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
9158c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen	run_file_io_stream(client, fd, CRAS_STREAM_INPUT, block_size,
9168c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			   stream_type, rate, num_channels, 0, is_loopback);
917b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
918b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	close(fd);
919b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	return 0;
920b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid}
921b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
922b229192892ca72a981813340d54b09b0ac8848d7Dylan Reidstatic int run_playback(struct cras_client *client,
923b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			const char *file,
92464732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin			size_t block_size,
9258c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			enum CRAS_STREAM_TYPE stream_type,
926718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid			size_t rate,
927e2ed6c93d9a42730003cd5066c4167984f157a2eHsin-Yu Chao			size_t num_channels)
928b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid{
929b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	int fd;
930b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
931b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	fd = open(file, O_RDONLY);
93267738d7c78e99b887aab106efb0108edf9997da1Derek Basehore	if (fd == -1) {
93367738d7c78e99b887aab106efb0108edf9997da1Derek Basehore		perror("failed to open file");
93467738d7c78e99b887aab106efb0108edf9997da1Derek Basehore		return -errno;
93567738d7c78e99b887aab106efb0108edf9997da1Derek Basehore	}
936b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
9378c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen	run_file_io_stream(client, fd, CRAS_STREAM_OUTPUT, block_size,
9388c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			   stream_type, rate, num_channels, 0, 0);
939b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
940b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	close(fd);
941b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	return 0;
942b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid}
943b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
9448900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reidstatic int run_hotword(struct cras_client *client,
9458900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		       size_t block_size,
9468900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		       size_t rate)
9478900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid{
9488c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen	run_file_io_stream(client, -1, CRAS_STREAM_INPUT, block_size,
9498c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			   CRAS_STREAM_TYPE_DEFAULT, rate, 1, HOTWORD_STREAM,
9508c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			   0);
9518900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid	return 0;
9528900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid}
9535263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reidstatic void print_server_info(struct cras_client *client)
9545263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid{
9555263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	cras_client_run_thread(client);
9566e3cd7333fc4d7364e2f1d491e10d15c65c31c28Dylan Reid	cras_client_connected_wait(client); /* To synchronize data. */
9575263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	print_system_volumes(client);
9589ee566e5cb9253fc173df35cb114914ff3d13ba9Cheng-Yi Chiang	print_user_muted(client);
9595263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	print_device_lists(client);
9605263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid	print_attached_client_list(client);
961efa88c0641c0d536d343519b7ea2ca2f7b31773eDylan Reid	print_active_stream_info(client);
9625263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid}
9635263207ad5875e026caf3b19e4cd7a23f16d6d3dDylan Reid
9646d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reidstatic void print_audio_debug_info(struct cras_client *client)
9656d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid{
9666d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	struct timespec wait_time;
9676d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
9686d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	cras_client_run_thread(client);
9696d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	cras_client_connected_wait(client); /* To synchronize data. */
9706d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	cras_client_update_audio_debug_info(client, audio_debug_info);
9716d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
9726d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	clock_gettime(CLOCK_REALTIME, &wait_time);
9736d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	wait_time.tv_sec += 2;
9746d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
9756d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	pthread_mutex_lock(&done_mutex);
9766d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	pthread_cond_timedwait(&done_cond, &done_mutex, &wait_time);
9776d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid	pthread_mutex_unlock(&done_mutex);
9786d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid}
9796d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid
980c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chaostatic void hotword_models_cb(struct cras_client *client,
981c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			      const char *hotword_models)
982c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao{
983c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	printf("Hotword models: %s\n", hotword_models);
984c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao}
985c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao
986c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chaostatic void print_hotword_models(struct cras_client *client,
987c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				 cras_node_id_t id)
988c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao{
989c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	struct timespec wait_time;
990c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao
991c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	cras_client_run_thread(client);
992c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	cras_client_connected_wait(client);
993c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	cras_client_get_hotword_models(client, id,
994c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				       hotword_models_cb);
995c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao
996c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	clock_gettime(CLOCK_REALTIME, &wait_time);
997c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	wait_time.tv_sec += 2;
998c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao
999c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	pthread_mutex_lock(&done_mutex);
1000c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	pthread_cond_timedwait(&done_cond, &done_mutex, &wait_time);
1001c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	pthread_mutex_unlock(&done_mutex);
1002c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao}
1003c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao
1004e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reidstatic void check_output_plugged(struct cras_client *client, const char *name)
1005e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid{
1006e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid	cras_client_run_thread(client);
1007e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid	cras_client_connected_wait(client); /* To synchronize data. */
1008e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid	printf("%s\n",
1009e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid	       cras_client_output_dev_plugged(client, name) ? "Yes" : "No");
1010e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid}
1011e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid
10127c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir/* Repeatedly mute and unmute the output until there is an error. */
10137c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muirstatic void mute_loop_test(struct cras_client *client, int auto_reconnect)
10147c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir{
10157c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	int mute = 0;
10167c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	int rc;
10177c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir
10187c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	if (auto_reconnect)
10197c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir		cras_client_run_thread(client);
10207c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	while(1) {
10217c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir		rc = cras_client_set_user_mute(client, mute);
10227c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir		printf("cras_client_set_user_mute(%d): %d\n", mute, rc);
10237c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir		if (rc != 0 && !auto_reconnect)
10247c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir			return;
10257c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir		mute = !mute;
10267c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir		sleep(2);
10277c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	}
10287c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir}
10297c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir
1030b229192892ca72a981813340d54b09b0ac8848d7Dylan Reidstatic struct option long_options[] = {
1031b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	{"show_latency",	no_argument, &show_latency, 1},
10329f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	{"show_rms",            no_argument, &show_rms, 1},
10339f8382e1e824fd96fbab604968e35a2a99569165Adrian Li	{"show_total_rms",      no_argument, &show_total_rms, 1},
10342527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"select_input",        required_argument,      0, 'a'},
103564732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin	{"block_size",		required_argument,	0, 'b'},
10362527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"capture_file",	required_argument,	0, 'c'},
10372527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"duration_seconds",	required_argument,	0, 'd'},
10382527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"dump_dsp",            no_argument,            0, 'f'},
10392527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"capture_gain",        required_argument,      0, 'g'},
10402527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"help",                no_argument,            0, 'h'},
10412527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"dump_server_info",    no_argument,            0, 'i'},
10422527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"check_output_plugged",required_argument,      0, 'j'},
10437fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao	{"add_active_input",	required_argument,	0, 'k'},
10447fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao	{"add_active_output",	required_argument,	0, 't'},
10455a5b4890cd78757710364dc80231cb29d5472506Dylan Reid	{"loopback_file",	required_argument,	0, 'l'},
1046e7c47ff2f824c36e430b4bb7bfa324b8ab7e40e9Hsin-Yu Chao	{"dump_audio_thread",   no_argument,            0, 'm'},
1047718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid	{"num_channels",        required_argument,      0, 'n'},
1048e7c47ff2f824c36e430b4bb7bfa324b8ab7e40e9Hsin-Yu Chao	{"channel_layout",      required_argument,      0, 'o'},
1049b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	{"playback_file",	required_argument,	0, 'p'},
10502527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"user_mute",           required_argument,      0, 'q'},
10512527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"rate",		required_argument,	0, 'r'},
10522527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"reload_dsp",          no_argument,            0, 's'},
105326901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid	{"mute",                required_argument,      0, 'u'},
105426901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid	{"volume",              required_argument,      0, 'v'},
10552527379cf0c1b98fb91825c88926748a96f166f0Dylan Reid	{"set_node_volume",	required_argument,      0, 'w'},
1056741ad2848629417c45ce2064b77cde0e26538f04Chih-Chung Chang	{"plug",                required_argument,      0, 'x'},
1057ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang	{"select_output",       required_argument,      0, 'y'},
10580c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang	{"playback_delay_us",   required_argument,      0, 'z'},
1059b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid	{"capture_mute",        required_argument,      0, '0'},
10607fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao	{"rm_active_input",	required_argument,	0, '1'},
10617fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao	{"rm_active_output",	required_argument,	0, '2'},
1062de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang	{"swap_left_right",     required_argument,      0, '3'},
10634d83eef81b919e6e680477ed2015959a6d035b29Nicolas Boichat	{"version",             no_argument,            0, '4'},
1064cc13562bff05f6b254983c450a32a34090ee3a7fDylan Reid	{"add_test_dev",        required_argument,      0, '5'},
1065a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid	{"test_hotword_file",   required_argument,      0, '6'},
10668900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid	{"listen_for_hotword",  no_argument,            0, '7'},
1067883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chen	{"pin_device",		required_argument,	0, '8'},
1068667f5817aa3033c437253a484f9b6844b62220a9Dylan Reid	{"suspend",		required_argument,	0, '9'},
1069f8d972341e35409197795ce12c708fdbc14bfee0Hsin-Yu Chao	{"set_node_gain",	required_argument,	0, ':'},
10705a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette	{"play_short_sound",	required_argument,	0, '!'},
1071f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao	{"config_global_remix", required_argument,	0, ';'},
1072c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	{"set_hotword_model",	required_argument,	0, '<'},
1073c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	{"get_hotword_models",	required_argument,	0, '>'},
10747c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	{"syslog_mask",		required_argument,	0, 'L'},
10757c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	{"mute_loop_test",	required_argument,	0, 'M'},
10768c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen	{"stream_type",		required_argument,	0, 'T'},
1077b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	{0, 0, 0, 0}
1078b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid};
1079b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
1080c2315e4c493c7c4d40ca29a0daa370fd12bb9c6fDylan Reidstatic void show_usage()
1081c2315e4c493c7c4d40ca29a0daa370fd12bb9c6fDylan Reid{
108236d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--add_active_input <N>:<M> - Add the ionode with the given id"
108336d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	       "to active input device list\n");
108436d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--add_active_output <N>:<M> - Add the ionode with the given id"
108536d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	       "to active output device list\n");
108636d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--add_test_dev <type> - add a test iodev.\n");
108764732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin	printf("--block_size <N> - The number for frames per callback(dictates latency).\n");
108836d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--capture_file <name> - Name of file to record to.\n");
1089474421f8ee8199748e9bcc1ae933919c6dbe72cbDylan Reid	printf("--capture_gain <dB> - Set system caputre gain in dB*100 (100 = 1dB).\n");
109036d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--capture_mute <0|1> - Set capture mute state.\n");
109136d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--channel_layout <layout_str> - Set multiple channel layout.\n");
1092e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid	printf("--check_output_plugged <output name> - Check if the output is plugged in\n");
109336d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--dump_audio_thread - Dumps audio thread info.\n");
1094741ad2848629417c45ce2064b77cde0e26538f04Chih-Chung Chang	printf("--dump_dsp - Print status of dsp to syslog.\n");
109536d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--dump_server_info - Print status of the server.\n");
109636d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--duration_seconds <N> - Seconds to record or playback.\n");
1097c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	printf("--get_hotword_models <N>:<M> - Get the supported hotword models of node\n");
109836d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--help - Print this message.\n");
109936d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--listen_for_hotword - Listen for a hotword if supported\n");
110036d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--loopback_file <name> - Name of file to record loopback to.\n");
110136d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--mute <0|1> - Set system mute state.\n");
11027c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	printf("--mute_loop_test <0|1> - Continuously loop mute/umute. Argument: 0 - stop on error.\n"
11037c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	       "                         1 - automatically reconnect to CRAS.\n");
110436d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--num_channels <N> - Two for stereo.\n");
110536d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--pin_device <N> - Playback/Capture only on the given device."
110636d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	       "\n");
110736d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--playback_file <name> - Name of file to play, "
110836d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	       "\"-\" to playback raw audio from stdin.\n");
11095a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette	printf("--play_short_sound <N> - Plays the content in the file for N periods when ' is pressed.\n");
1110741ad2848629417c45ce2064b77cde0e26538f04Chih-Chung Chang	printf("--plug <N>:<M>:<0|1> - Set the plug state (0 or 1) for the"
1111741ad2848629417c45ce2064b77cde0e26538f04Chih-Chung Chang	       " ionode with the given index M on the device with index N\n");
111236d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--rate <N> - Specifies the sample rate in Hz.\n");
111336d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--reload_dsp - Reload dsp configuration from the ini file\n");
11147fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao	printf("--rm_active_input <N>:<M> - Removes the ionode with the given"
11157fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao	       "id from active input device list\n");
11167fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao	printf("--rm_active_output <N>:<M> - Removes the ionode with the given"
11177fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao	       "id from active output device list\n");
111836d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--select_input <N>:<M> - Select the ionode with the given id as preferred input\n");
111936d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--select_output <N>:<M> - Select the ionode with the given id as preferred output\n");
1120c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao	printf("--set_hotword_model <N>:<M>:<model> - Set the model to node\n");
11210c2d7e7ea7ab4dc70ce34f2c5e6d5975ec6bec18Cheng-Yi Chiang	printf("--playback_delay_us <N> - Set the time in us to delay a reply for playback when i is pressed\n");
1122dbe3005b3de02ff2b78f6557062b360fe983a261Dylan Reid	printf("--set_node_volume <N>:<M>:<0-100> - Set the volume of the ionode with the given id\n");
112336d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--show_latency - Display latency while playing or recording.\n");
112436d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--show_rms - Display RMS value of loopback stream.\n");
112536d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--show_total_rms - Display total RMS value of loopback stream at the end.\n");
1126667f5817aa3033c437253a484f9b6844b62220a9Dylan Reid	printf("--suspend <0|1> - Set audio suspend state.\n");
112736d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--swap_left_right <N>:<M>:<0|1> - Swap or unswap (1 or 0) the"
112836d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	       " left and right channel for the ionode with the given index M"
112936d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	       " on the device with index N\n");
11308c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen	printf("--stream_type <N> - Specify the type of the stream.\n");
11317c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	printf("--syslog_mask <n> - Set the syslog mask to the given log level.\n");
113236d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--test_hotword_file <N>:<filename> - Use filename as a hotword buffer for device N\n");
113336d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--user_mute <0|1> - Set user mute state.\n");
113436d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--version - Print the git commit ID that was used to build the client.\n");
113536d130e0135d12bf53d294aa84f31f36beecf46cNicholas Bishop	printf("--volume <0-100> - Set system output volume.\n");
1136c2315e4c493c7c4d40ca29a0daa370fd12bb9c6fDylan Reid}
1137c2315e4c493c7c4d40ca29a0daa370fd12bb9c6fDylan Reid
1138b229192892ca72a981813340d54b09b0ac8848d7Dylan Reidint main(int argc, char **argv)
1139b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid{
1140b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	struct cras_client *client;
1141ea196aa3ad544953d557e9d229b1ba5ea8821da4Derek Basehore	int c, option_index;
114264732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin	size_t block_size = NOT_ASSIGNED;
1143718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid	size_t rate = 48000;
1144718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid	size_t num_channels = 2;
11452dc03903674fd421044ee186deab70defe52971cAdrian Li	float duration_seconds = 0;
1146b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	const char *capture_file = NULL;
1147b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	const char *playback_file = NULL;
1148be7ff2d0c0b07a74403fd4c4144f088f33ccb3d9Dylan Reid	const char *loopback_file = NULL;
11498c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen	enum CRAS_STREAM_TYPE stream_type = CRAS_STREAM_TYPE_DEFAULT;
1150ea196aa3ad544953d557e9d229b1ba5ea8821da4Derek Basehore	int rc = 0;
1151b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
1152b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	option_index = 0;
11537c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	openlog("cras_test_client", LOG_PERROR, LOG_USER);
11547c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	setlogmask(LOG_UPTO(LOG_INFO));
1155b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
1156ea196aa3ad544953d557e9d229b1ba5ea8821da4Derek Basehore	rc = cras_client_create(&client);
1157ea196aa3ad544953d557e9d229b1ba5ea8821da4Derek Basehore	if (rc < 0) {
115874347c1ebfa6ad17856a705dd41498d2354f6245Dylan Reid		fprintf(stderr, "Couldn't create client.\n");
1159ea196aa3ad544953d557e9d229b1ba5ea8821da4Derek Basehore		return rc;
116074347c1ebfa6ad17856a705dd41498d2354f6245Dylan Reid	}
116174347c1ebfa6ad17856a705dd41498d2354f6245Dylan Reid
11627c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir	rc = cras_client_connect_timeout(client, 1000);
1163ea196aa3ad544953d557e9d229b1ba5ea8821da4Derek Basehore	if (rc) {
116474347c1ebfa6ad17856a705dd41498d2354f6245Dylan Reid		fprintf(stderr, "Couldn't connect to server.\n");
11659d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore		goto destroy_exit;
116674347c1ebfa6ad17856a705dd41498d2354f6245Dylan Reid	}
116774347c1ebfa6ad17856a705dd41498d2354f6245Dylan Reid
1168b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	while (1) {
1169b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		c = getopt_long(argc, argv, "o:s:",
1170b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid				long_options, &option_index);
1171b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		if (c == -1)
1172b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
1173b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		switch (c) {
1174b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		case 'c':
1175b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			capture_file = optarg;
1176b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
1177b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		case 'p':
1178b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			playback_file = optarg;
1179b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
11805a5b4890cd78757710364dc80231cb29d5472506Dylan Reid		case 'l':
1181be7ff2d0c0b07a74403fd4c4144f088f33ccb3d9Dylan Reid			loopback_file = optarg;
1182be7ff2d0c0b07a74403fd4c4144f088f33ccb3d9Dylan Reid			break;
1183b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		case 'b':
118464732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin			block_size = atoi(optarg);
1185b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
1186b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		case 'r':
1187b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			rate = atoi(optarg);
1188b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
1189718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid		case 'n':
1190718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid			num_channels = atoi(optarg);
1191718e80aaa03d21460d541539dc37c7348607dd56Dylan Reid			break;
1192c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid		case 'd':
11932dc03903674fd421044ee186deab70defe52971cAdrian Li			duration_seconds = atof(optarg);
1194c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid			break;
119526901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid		case 'u': {
119626901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid			int mute = atoi(optarg);
11979d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore			rc = cras_client_set_system_mute(client, mute);
11989d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore			if (rc < 0) {
11999d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore				fprintf(stderr, "problem setting mute\n");
12009d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore				goto destroy_exit;
12019d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore			}
120226901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid			break;
120326901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid		}
120459d127ae6daef05f03dbd336a66dfbfa2f208c81Dylan Reid		case 'q': {
120559d127ae6daef05f03dbd336a66dfbfa2f208c81Dylan Reid			int mute = atoi(optarg);
120659d127ae6daef05f03dbd336a66dfbfa2f208c81Dylan Reid			rc = cras_client_set_user_mute(client, mute);
120759d127ae6daef05f03dbd336a66dfbfa2f208c81Dylan Reid			if (rc < 0) {
120859d127ae6daef05f03dbd336a66dfbfa2f208c81Dylan Reid				fprintf(stderr, "problem setting mute\n");
120959d127ae6daef05f03dbd336a66dfbfa2f208c81Dylan Reid				goto destroy_exit;
121059d127ae6daef05f03dbd336a66dfbfa2f208c81Dylan Reid			}
121159d127ae6daef05f03dbd336a66dfbfa2f208c81Dylan Reid			break;
121259d127ae6daef05f03dbd336a66dfbfa2f208c81Dylan Reid		}
121326901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid		case 'v': {
121426901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid			int volume = atoi(optarg);
12152c1e4a94b93ea1ca23ae1ab177a80ad769a7c18aDylan Reid			volume = MIN(100, MAX(0, volume));
12169d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore			rc = cras_client_set_system_volume(client, volume);
12179d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore			if (rc < 0) {
12189d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore				fprintf(stderr, "problem setting volume\n");
12199d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore				goto destroy_exit;
12209d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore			}
122126901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid			break;
122226901d9aa3cab7e661ed922b866e01506b1fd863Dylan Reid		}
1223474421f8ee8199748e9bcc1ae933919c6dbe72cbDylan Reid		case 'g': {
1224474421f8ee8199748e9bcc1ae933919c6dbe72cbDylan Reid			long gain = atol(optarg);
12259d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore			rc = cras_client_set_system_capture_gain(client, gain);
12269d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore			if (rc < 0) {
12279d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore				fprintf(stderr, "problem setting capture\n");
12289d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore				goto destroy_exit;
12299d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore			}
1230474421f8ee8199748e9bcc1ae933919c6dbe72cbDylan Reid			break;
1231474421f8ee8199748e9bcc1ae933919c6dbe72cbDylan Reid		}
1232e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid		case 'j':
1233e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid			check_output_plugged(client, optarg);
1234e05d3164359a41eff01060af6247ad7cafe93d3fDylan Reid			break;
12359e26707b7ca729ea50eea2d2b69411f6ad036a04Chih-Chung Chang		case 's':
12369e26707b7ca729ea50eea2d2b69411f6ad036a04Chih-Chung Chang			cras_client_reload_dsp(client);
12379e26707b7ca729ea50eea2d2b69411f6ad036a04Chih-Chung Chang			break;
12388e0d4c5910a5ccd329a14515abd52275c20a7802Chih-Chung Chang		case 'f':
12398e0d4c5910a5ccd329a14515abd52275c20a7802Chih-Chung Chang			cras_client_dump_dsp_info(client);
12408e0d4c5910a5ccd329a14515abd52275c20a7802Chih-Chung Chang			break;
12410af5340f4de10d84ad15561fb1441405a77d0df1Dylan Reid		case 'i':
12420af5340f4de10d84ad15561fb1441405a77d0df1Dylan Reid			print_server_info(client);
12430af5340f4de10d84ad15561fb1441405a77d0df1Dylan Reid			break;
1244c2315e4c493c7c4d40ca29a0daa370fd12bb9c6fDylan Reid		case 'h':
1245c2315e4c493c7c4d40ca29a0daa370fd12bb9c6fDylan Reid			show_usage();
1246c2315e4c493c7c4d40ca29a0daa370fd12bb9c6fDylan Reid			break;
1247ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang		case 'x': {
1248741ad2848629417c45ce2064b77cde0e26538f04Chih-Chung Chang			int dev_index = atoi(strtok(optarg, ":"));
1249741ad2848629417c45ce2064b77cde0e26538f04Chih-Chung Chang			int node_index = atoi(strtok(NULL, ":"));
125031426461ec77c5a7ee613d52d0a93db6b68e7b7cChih-Chung Chang			int value = atoi(strtok(NULL, ":")) ;
1251770ea30175b730e5b771eeae808bbf959e132c3eChih-Chung Chang			cras_node_id_t id = cras_make_node_id(dev_index,
1252770ea30175b730e5b771eeae808bbf959e132c3eChih-Chung Chang							      node_index);
1253ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang			enum ionode_attr attr = IONODE_ATTR_PLUGGED;
1254770ea30175b730e5b771eeae808bbf959e132c3eChih-Chung Chang			cras_client_set_node_attr(client, id, attr, value);
1255741ad2848629417c45ce2064b77cde0e26538f04Chih-Chung Chang			break;
1256741ad2848629417c45ce2064b77cde0e26538f04Chih-Chung Chang		}
1257ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang		case 'y':
1258ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang		case 'a': {
1259ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang			int dev_index = atoi(strtok(optarg, ":"));
1260ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang			int node_index = atoi(strtok(NULL, ":"));
1261ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang			cras_node_id_t id = cras_make_node_id(dev_index,
1262ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang							      node_index);
1263ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang
1264ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang			enum CRAS_STREAM_DIRECTION direction = (c == 'y') ?
1265ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang				CRAS_STREAM_OUTPUT : CRAS_STREAM_INPUT;
1266ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang			cras_client_select_node(client, direction, id);
1267b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			break;
1268b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid		}
12696a83ca08e572c6495238c21e8f2420ed772a144cCheng-Yi Chiang		case 'z':
12706a83ca08e572c6495238c21e8f2420ed772a144cCheng-Yi Chiang			pause_in_playback_reply = atoi(optarg);
12716a83ca08e572c6495238c21e8f2420ed772a144cCheng-Yi Chiang			break;
12727fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao		case 'k':
12737fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao		case 't':
12747fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao		case '1':
12757fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao		case '2':{
12767fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao			int dev_index = atoi(strtok(optarg, ":"));
12777fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao			int node_index = atoi(strtok(NULL, ":"));
127802f415d1cdb42d4257323d8941bd44379e034b6aHsin-Yu Chao			enum CRAS_STREAM_DIRECTION dir;
12797fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao			cras_node_id_t id = cras_make_node_id(dev_index,
12807fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao							      node_index);
128102f415d1cdb42d4257323d8941bd44379e034b6aHsin-Yu Chao
128202f415d1cdb42d4257323d8941bd44379e034b6aHsin-Yu Chao			if (c == 't' || c == '2')
128302f415d1cdb42d4257323d8941bd44379e034b6aHsin-Yu Chao				dir = CRAS_STREAM_OUTPUT;
128402f415d1cdb42d4257323d8941bd44379e034b6aHsin-Yu Chao			else
128502f415d1cdb42d4257323d8941bd44379e034b6aHsin-Yu Chao				dir = CRAS_STREAM_INPUT;
128602f415d1cdb42d4257323d8941bd44379e034b6aHsin-Yu Chao
12877fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao			if (c == 'k' || c == 't')
128802f415d1cdb42d4257323d8941bd44379e034b6aHsin-Yu Chao				cras_client_add_active_node(client, dir, id);
12897fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao			else
129002f415d1cdb42d4257323d8941bd44379e034b6aHsin-Yu Chao				cras_client_rm_active_node(client, dir, id);
12917fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao			break;
12927fe6cf81920c6bc6631a932f238f9106bd0b1671Hsin-Yu Chao		}
1293f8d972341e35409197795ce12c708fdbc14bfee0Hsin-Yu Chao		case ':':
1294b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid		case 'w': {
1295b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			const char *s;
1296b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			int dev_index;
1297b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			int node_index;
1298b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			int value;
1299b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid
1300b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			s = strtok(optarg, ":");
1301b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			if (!s) {
1302b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid				show_usage();
1303b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid				return -EINVAL;
1304b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			}
1305b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			dev_index = atoi(s);
1306b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid
1307b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			s = strtok(NULL, ":");
1308b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			if (!s) {
1309b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid				show_usage();
1310b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid				return -EINVAL;
1311b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			}
1312b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			node_index = atoi(s);
1313b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid
1314b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			s = strtok(NULL, ":");
1315b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			if (!s) {
1316b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid				show_usage();
1317b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid				return -EINVAL;
1318b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			}
1319b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			value = atoi(s) ;
1320b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid
1321b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			cras_node_id_t id = cras_make_node_id(dev_index,
1322b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid							      node_index);
1323b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid
1324f8d972341e35409197795ce12c708fdbc14bfee0Hsin-Yu Chao			if (c == 'w')
1325f8d972341e35409197795ce12c708fdbc14bfee0Hsin-Yu Chao				cras_client_set_node_volume(client, id, value);
1326f8d972341e35409197795ce12c708fdbc14bfee0Hsin-Yu Chao			else
1327f8d972341e35409197795ce12c708fdbc14bfee0Hsin-Yu Chao				cras_client_set_node_capture_gain(
1328f8d972341e35409197795ce12c708fdbc14bfee0Hsin-Yu Chao						client, id, value);
1329b7fb7aad1bb54683361c3beda234e01bcf455becDylan Reid			break;
1330ea1b78a018d72fd22f5ce5650121f5e4b8325a1dChih-Chung Chang		}
1331b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid		case '0': {
1332b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid			int mute = atoi(optarg);
1333b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid			rc = cras_client_set_system_capture_mute(client, mute);
1334b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid			if (rc < 0) {
1335b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid				fprintf(stderr, "problem setting mute\n");
1336b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid				goto destroy_exit;
1337b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid			}
1338b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid			break;
1339b7e1ea2df238b186bb0c489727df4708238b52d1Dylan Reid		}
1340e7c47ff2f824c36e430b4bb7bfa324b8ab7e40e9Hsin-Yu Chao		case 'm':
13416d785f2e9175478aac2cdd4962b6175f8dee5b34Dylan Reid			print_audio_debug_info(client);
13428906982340dde76df621f568f52c267b62ea76c1Dylan Reid			break;
1343e7c47ff2f824c36e430b4bb7bfa324b8ab7e40e9Hsin-Yu Chao		case 'o':
13446bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao			channel_layout = optarg;
13456bf026691ceb74ea2ae1369ce97ae68a51f589eeHsin-Yu Chao			break;
1346de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang		case '3': {
1347de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang			int dev_index = atoi(strtok(optarg, ":"));
1348de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang			int node_index = atoi(strtok(NULL, ":"));
1349de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang			int value = atoi(strtok(NULL, ":")) ;
1350de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang			cras_node_id_t id = cras_make_node_id(dev_index,
1351de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang							      node_index);
1352de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang			cras_client_swap_node_left_right(client, id, value);
1353de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang			break;
1354de72fcd9148241d184c7695ad562a034733cb8d9Cheng-Yi Chiang		}
13554d83eef81b919e6e680477ed2015959a6d035b29Nicolas Boichat		case '4':
13564d83eef81b919e6e680477ed2015959a6d035b29Nicolas Boichat			printf("%s\n", VCSID);
13574d83eef81b919e6e680477ed2015959a6d035b29Nicolas Boichat			break;
1358cc13562bff05f6b254983c450a32a34090ee3a7fDylan Reid		case '5': {
1359cc13562bff05f6b254983c450a32a34090ee3a7fDylan Reid			cras_client_add_test_iodev(client, atoi(optarg));
1360cc13562bff05f6b254983c450a32a34090ee3a7fDylan Reid			break;
1361cc13562bff05f6b254983c450a32a34090ee3a7fDylan Reid		}
1362a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid		case '6': {
1363a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid			int dev_index = atoi(strtok(optarg, ":"));
1364a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid			const char *file_name = strtok(NULL, ":");
1365a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid			cras_client_test_iodev_command(client, dev_index,
1366a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid					TEST_IODEV_CMD_HOTWORD_TRIGGER,
1367a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid					strlen(file_name) + 1,
1368a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid					(uint8_t *)file_name);
1369a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid			break;
1370a37abd9b84aefd5758d18579a930c9b38b5ad65eDylan Reid		}
13718900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		case '7': {
13728900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid			run_hotword(client, 4096, 16000);
13738900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid			break;
13748900b7e1bdf85af1266099538ce625d85aee7b02Dylan Reid		}
1375883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chen		case '8':
1376883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chen			pin_device_id = atoi(optarg);
1377883db6e97198f6ee1919eb5e4aa167e738261d18Chinyue Chen			break;
1378667f5817aa3033c437253a484f9b6844b62220a9Dylan Reid		case '9': {
1379667f5817aa3033c437253a484f9b6844b62220a9Dylan Reid			int suspend = atoi(optarg);
1380667f5817aa3033c437253a484f9b6844b62220a9Dylan Reid			cras_client_set_suspend(client, suspend);
1381667f5817aa3033c437253a484f9b6844b62220a9Dylan Reid			break;
1382667f5817aa3033c437253a484f9b6844b62220a9Dylan Reid		}
13835a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette		case '!': {
13845a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			play_short_sound = 1;
13855a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			play_short_sound_periods = atoi(optarg);
13865a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette			break;
13875a06fea15886b4a3ac4782990d30b1f7ca8bb755Richard Barnette		}
1388f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao		case ';': {
1389f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			char *s;
1390f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			int nch;
1391f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			int size = 0;
1392f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			float *coeff;
1393f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao
1394f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			s = strtok(optarg, ":");
1395f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			nch = atoi(s);
1396f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			coeff = (float *)calloc(nch * nch,
1397f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao						sizeof(*coeff));
1398f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			for (size = 0; size < nch * nch; size++) {
1399f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao				s = strtok(NULL, ",");
1400f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao				if (NULL == s)
1401f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao					break;
1402f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao				coeff[size] = atof(s);
1403f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			}
1404f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			cras_client_config_global_remix(client, nch, coeff);
1405f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			free(coeff);
1406f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao			break;
1407f4d68a96948ce913348cc35ba34d9202014a9bdbHsin-Yu Chao		}
1408c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao		case '<':
1409c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao		case '>': {
1410c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			char *s;
1411c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			int dev_index;
1412c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			int node_index;
1413c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao
1414c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			s = strtok(optarg, ":");
1415c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			if (!s) {
1416c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				show_usage();
1417c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				return -EINVAL;
1418c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			}
1419c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			dev_index = atoi(s);
1420c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao
1421c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			s = strtok(NULL, ":");
1422c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			if (!s) {
1423c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				show_usage();
1424c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				return -EINVAL;
1425c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			}
1426c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			node_index = atoi(s);
1427c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao
1428c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			s = strtok(NULL, ":");
1429c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			if (!s && c == ';') {
1430c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				show_usage();
1431c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				return -EINVAL;
1432c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			}
1433c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao
1434c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			cras_node_id_t id = cras_make_node_id(dev_index,
1435c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao							      node_index);
143628348f8ce8bca72ebb8bc4f363338bb7b87a2258Yong Zhi			if (c == '<')
1437c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				cras_client_set_hotword_model(client, id, s);
1438c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			else
1439c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao				print_hotword_models(client, id);
1440c80e8ab8f2e74a19f2050c0d3364d4f6ccae5f52Hsin-Yu Chao			break;
14412de7350aae4c2ace634854cdc85066179dbffa85Chinyue Chen		}
14427c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir		case 'L': {
14437c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir			int log_level = atoi(optarg);
14447c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir
14457c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir			setlogmask(LOG_UPTO(log_level));
14467c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir			break;
14477c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir		}
14487c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir		case 'M':
14497c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir			mute_loop_test(client, atoi(optarg));
14507c5f107ffba37f4679abc46cffe296af3fc7aa3dJohn Muir			break;
14518c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen		case 'T':
14528c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			stream_type = atoi(optarg);
14538c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			break;
1454b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		default:
1455b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid			break;
1456b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid		}
1457b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	}
1458b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
1459c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid	duration_frames = duration_seconds * rate;
146064732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin	if (block_size == NOT_ASSIGNED)
146164732674dfde25bcd9a56f0d9fce5df5d60eeb12Owen Lin		block_size = get_block_size(PLAYBACK_BUFFERED_TIME_IN_US, rate);
1462c60d0e2ed65689373745ee23c6ba372b72b815b4Dylan Reid
14631faaa6356ecb0832df55c59e3daa1f6cf8b915b8Dylan Reid	if (capture_file != NULL) {
14641faaa6356ecb0832df55c59e3daa1f6cf8b915b8Dylan Reid		if (strcmp(capture_file, "-") == 0)
14651faaa6356ecb0832df55c59e3daa1f6cf8b915b8Dylan Reid			rc = run_file_io_stream(client, 1, CRAS_STREAM_INPUT,
14668c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen					block_size, stream_type, rate,
14678c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen					num_channels, 0, 0);
14681faaa6356ecb0832df55c59e3daa1f6cf8b915b8Dylan Reid		else
14698c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			rc = run_capture(client, capture_file, block_size,
14708c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen					 stream_type, rate, num_channels, 0);
14711faaa6356ecb0832df55c59e3daa1f6cf8b915b8Dylan Reid	} else if (playback_file != NULL) {
14726758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		if (strcmp(playback_file, "-") == 0)
14736758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao			rc = run_file_io_stream(client, 0, CRAS_STREAM_OUTPUT,
14748c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen					block_size, stream_type, rate,
14758c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen					num_channels, 0, 0);
14766758296c4be50d952c2b53a6ee2f8ee918a8f527Hsin-Yu Chao		else
14778c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen			rc = run_playback(client, playback_file, block_size,
14788c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen					  stream_type, rate, num_channels);
14791faaa6356ecb0832df55c59e3daa1f6cf8b915b8Dylan Reid	} else if (loopback_file != NULL) {
14808c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen		rc = run_capture(client, loopback_file, block_size,
14818c14662b903b2cd16358ebdc060dce77a6fc98d7Chinyue Chen				 stream_type, rate, num_channels, 1);
14821faaa6356ecb0832df55c59e3daa1f6cf8b915b8Dylan Reid	}
1483b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid
14849d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehoredestroy_exit:
1485b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid	cras_client_destroy(client);
14869d94ff2db5bfc5bdefcb28e2736b7a787135543eDerek Basehore	return rc;
1487b229192892ca72a981813340d54b09b0ac8848d7Dylan Reid}
1488