summaryrefslogtreecommitdiff
path: root/cras/src/server/dev_io.h
blob: 259bbabdb0682f764bfeccf8849da63cf3455dbe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* Copyright 2017 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * `dev_io` Handles playback to and capture from open devices.  It runs only on
 * the audio thread.
 */

#ifndef DEV_IO_H_
#define DEV_IO_H_

#include "cras_iodev.h"
#include "cras_types.h"
#include "polled_interval_checker.h"

/*
 * Open input/output devices.
 *    dev - The device.
 *    last_wake - The last timestamp audio thread woke up and there is stream
 *        on this open device.
 *    longest_wake - The longest time between consecutive audio thread wakes
 *        in this open_dev's life cycle.
 *    wake_ts - When callback is needed to avoid xrun.
 *    last_non_empty_ts - The last time we know the device played/captured
 *        non-empty (zero) audio.
 *    coarse_rate_adjust - Hack for when the sample rate needs heavy correction.
 */
struct open_dev {
	struct cras_iodev *dev;
	struct timespec last_wake;
	struct timespec longest_wake;
	struct timespec wake_ts;
	struct polled_interval *non_empty_check_pi;
	struct polled_interval *empty_pi;
	int coarse_rate_adjust;
	struct open_dev *prev, *next;
};

/*
 * Fetches streams from each device in `odev_list`.
 *    odev_list - The list of open devices.
 */
void dev_io_playback_fetch(struct open_dev *odev_list);

/*
 * Writes the samples fetched from the streams to the playback devices.
 *    odev_list - The list of open devices.  Devices will be removed when
 *                writing returns an error.
 */
int dev_io_playback_write(struct open_dev **odevs,
			  struct cras_fmt_conv *output_converter);

/* Only public for testing. */
int write_output_samples(struct open_dev **odevs, struct open_dev *adev,
			 struct cras_fmt_conv *output_converter);

/*
 * Captures samples from each device in the list.
 *    list - Pointer to the list of input devices.  Devices that fail to read
 *           will be removed from the list.
 */
int dev_io_capture(struct open_dev **list);

/*
 * Send samples that have been captured to their streams.
 */
int dev_io_send_captured_samples(struct open_dev *idev_list);

/* Reads and/or writes audio samples from/to the devices. */
void dev_io_run(struct open_dev **odevs, struct open_dev **idevs,
		struct cras_fmt_conv *output_converter);

/*
 * Checks the non-empty device state in active output lists and return
 * if there's at least one non-empty device.
 */
int dev_io_check_non_empty_state_transition(struct open_dev *adevs);

/*
 * Fills min_ts with the next time the system should wake to service input.
 * Returns the number of devices waiting.
 */
int dev_io_next_input_wake(struct open_dev **idevs, struct timespec *min_ts);

/*
 * Fills min_ts with the next time the system should wake to service output.
 * Returns the number of devices waiting.
 */
int dev_io_next_output_wake(struct open_dev **odevs, struct timespec *min_ts);

/*
 * Removes a device from a list of devices.
 *    odev_list - A pointer to the list to modify.
 *    dev_to_rm - Find this device in the list and remove it.
 */
void dev_io_rm_open_dev(struct open_dev **odev_list,
			struct open_dev *dev_to_rm);

/* Returns a pointer to an open_dev if it is in the list, otherwise NULL. */
struct open_dev *dev_io_find_open_dev(struct open_dev *odev_list,
				      unsigned int dev_idx);

/* Append a new stream to a specified set of iodevs. */
int dev_io_append_stream(struct open_dev **dev_list,
			 struct cras_rstream *stream,
			 struct cras_iodev **iodevs, unsigned int num_iodevs);

/* Remove a stream from the provided list of devices. */
int dev_io_remove_stream(struct open_dev **dev_list,
			 struct cras_rstream *stream, struct cras_iodev *dev);

#endif /* DEV_IO_H_ */