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