• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2017 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  *
5  * `dev_io` Handles playback to and capture from open devices.  It runs only on
6  * the audio thread.
7  */
8 
9 #ifndef DEV_IO_H_
10 #define DEV_IO_H_
11 
12 #include "cras_iodev.h"
13 #include "cras_types.h"
14 #include "polled_interval_checker.h"
15 
16 /*
17  * Open input/output devices.
18  *    dev - The device.
19  *    last_wake - The last timestamp audio thread woke up and there is stream
20  *        on this open device.
21  *    longest_wake - The longest time between consecutive audio thread wakes
22  *        in this open_dev's life cycle.
23  *    wake_ts - When callback is needed to avoid xrun.
24  *    last_non_empty_ts - The last time we know the device played/captured
25  *        non-empty (zero) audio.
26  *    coarse_rate_adjust - Hack for when the sample rate needs heavy correction.
27  */
28 struct open_dev {
29 	struct cras_iodev *dev;
30 	struct timespec last_wake;
31 	struct timespec longest_wake;
32 	struct timespec wake_ts;
33 	struct polled_interval *non_empty_check_pi;
34 	struct polled_interval *empty_pi;
35 	int coarse_rate_adjust;
36 	struct open_dev *prev, *next;
37 };
38 
39 /*
40  * Fetches streams from each device in `odev_list`.
41  *    odev_list - The list of open devices.
42  */
43 void dev_io_playback_fetch(struct open_dev *odev_list);
44 
45 /*
46  * Writes the samples fetched from the streams to the playback devices.
47  *    odev_list - The list of open devices.  Devices will be removed when
48  *                writing returns an error.
49  */
50 int dev_io_playback_write(struct open_dev **odevs,
51 			  struct cras_fmt_conv *output_converter);
52 
53 /* Only public for testing. */
54 int write_output_samples(struct open_dev **odevs, struct open_dev *adev,
55 			 struct cras_fmt_conv *output_converter);
56 
57 /*
58  * Captures samples from each device in the list.
59  *    list - Pointer to the list of input devices.  Devices that fail to read
60  *           will be removed from the list.
61  *    olist - Pointer to the list of output devices.
62  */
63 int dev_io_capture(struct open_dev **list, struct open_dev **olist);
64 
65 /*
66  * Send samples that have been captured to their streams.
67  */
68 int dev_io_send_captured_samples(struct open_dev *idev_list);
69 
70 /* Reads and/or writes audio samples from/to the devices. */
71 void dev_io_run(struct open_dev **odevs, struct open_dev **idevs,
72 		struct cras_fmt_conv *output_converter);
73 
74 /*
75  * Checks the non-empty device state in active output lists and return
76  * if there's at least one non-empty device.
77  */
78 int dev_io_check_non_empty_state_transition(struct open_dev *adevs);
79 
80 /*
81  * Fills min_ts with the next time the system should wake to service input.
82  * Returns the number of devices waiting.
83  */
84 int dev_io_next_input_wake(struct open_dev **idevs, struct timespec *min_ts);
85 
86 /*
87  * Fills min_ts with the next time the system should wake to service output.
88  * Returns the number of devices waiting.
89  */
90 int dev_io_next_output_wake(struct open_dev **odevs, struct timespec *min_ts);
91 
92 /*
93  * Removes a device from a list of devices.
94  *    odev_list - A pointer to the list to modify.
95  *    dev_to_rm - Find this device in the list and remove it.
96  */
97 void dev_io_rm_open_dev(struct open_dev **odev_list,
98 			struct open_dev *dev_to_rm);
99 
100 /* Returns a pointer to an open_dev if it is in the list, otherwise NULL. */
101 struct open_dev *dev_io_find_open_dev(struct open_dev *odev_list,
102 				      unsigned int dev_idx);
103 
104 /* Append a new stream to a specified set of iodevs. */
105 int dev_io_append_stream(struct open_dev **odevs, struct open_dev **idevs,
106 			 struct cras_rstream *stream,
107 			 struct cras_iodev **iodevs, unsigned int num_iodevs);
108 
109 /* Remove a stream from the provided list of devices. */
110 int dev_io_remove_stream(struct open_dev **dev_list,
111 			 struct cras_rstream *stream, struct cras_iodev *dev);
112 
113 #endif /* DEV_IO_H_ */
114