/* Copyright (c) 2012 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. */ #ifndef AUDIO_THREAD_H_ #define AUDIO_THREAD_H_ #include <pthread.h> #include <stdint.h> #include "cras_iodev.h" #include "cras_types.h" struct buffer_share; struct cras_iodev; struct cras_rstream; struct dev_stream; /* Open input/output devices. * dev - The device. * wake_ts - When callback is needed to avoid xrun. * coarse_rate_adjust - Hack for when the sample rate needs heavy correction. * input_streaming - For capture, has the input started? */ struct open_dev { struct cras_iodev *dev; struct timespec wake_ts; int coarse_rate_adjust; int input_streaming; struct open_dev *prev, *next; }; /* Hold communication pipes and pthread info for the thread used to play or * record audio. * to_thread_fds - Send a message from main to running thread. * to_main_fds - Send a synchronous response to main from running thread. * tid - Thread ID of the running playback/capture thread. * started - Non-zero if the thread has started successfully. * suspended - Non-zero if the thread is suspended. * open_devs - Lists of open input and output devices. */ struct audio_thread { int to_thread_fds[2]; int to_main_fds[2]; pthread_t tid; int started; int suspended; struct open_dev *open_devs[CRAS_NUM_DIRECTIONS]; }; /* Callback function to be handled in main loop in audio thread. * Args: * data - The data for callback function. */ typedef int (*thread_callback)(void *data); /* Creates an audio thread. * Returns: * A pointer to the newly create audio thread. It must be freed by calling * audio_thread_destroy(). Returns NULL on error. */ struct audio_thread *audio_thread_create(); /* Adds an open device. * Args: * thread - The thread to add open device to. * dev - The open device to add. */ int audio_thread_add_open_dev(struct audio_thread *thread, struct cras_iodev *dev); /* Removes an open device. * Args: * thread - The thread to remove open device from. * dev - The open device to remove. */ int audio_thread_rm_open_dev(struct audio_thread *thread, struct cras_iodev *dev); /* Adds an thread_callback to audio thread. * Args: * fd - The file descriptor to be polled for the callback. * The callback will be called when fd is readable. * cb - The callback function. * data - The data for the callback function. */ void audio_thread_add_callback(int fd, thread_callback cb, void *data); /* Adds an thread_callback to audio thread. * Args: * fd - The file descriptor to be polled for the callback. * The callback will be called when fd is writeable. * cb - The callback function. * data - The data for the callback function. */ void audio_thread_add_write_callback(int fd, thread_callback cb, void *data); /* Removes an thread_callback from audio thread. * Args: * fd - The file descriptor of the previous added callback. */ void audio_thread_rm_callback(int fd); /* Removes a thread_callback from main thread. * Args: * thread - The thread to remove callback from. * fd - The file descriptor of the previous added callback. */ int audio_thread_rm_callback_sync(struct audio_thread *thread, int fd); /* Enables or Disabled the callback associated with fd. */ void audio_thread_enable_callback(int fd, int enabled); /* Starts a thread created with audio_thread_create. * Args: * thread - The thread to start. * Returns: * 0 on success, return code from pthread_crate on failure. */ int audio_thread_start(struct audio_thread *thread); /* Frees an audio thread created with audio_thread_create(). */ void audio_thread_destroy(struct audio_thread *thread); /* Add a stream to the thread. After this call, the ownership of the stream will * be passed to the audio thread. Audio thread is responsible to release the * stream's resources. * Args: * thread - a pointer to the audio thread. * stream - the new stream to add. * devs - an array of devices to attach stream. * num_devs - number of devices in the array pointed by devs * Returns: * zero on success, negative error from the AUDIO_THREAD enum above when an * the thread can't be added. */ int audio_thread_add_stream(struct audio_thread *thread, struct cras_rstream *stream, struct cras_iodev **devs, unsigned int num_devs); /* Begin draining a stream and check the draining status. * Args: * thread - a pointer to the audio thread. * stream - the stream to drain/remove. * Returns: * zero if the stream is drained and can be deleted. If the stream is not * completely drained, then the number of milliseconds until is is drained * are returned. */ int audio_thread_drain_stream(struct audio_thread *thread, struct cras_rstream *stream); /* Disconnect a stream from the client. * Args: * thread - a pointer to the audio thread. * stream - the stream to be disconnected. * iodev - the device to disconnect from. * Returns: * 0 on success, negative if error. */ int audio_thread_disconnect_stream(struct audio_thread *thread, struct cras_rstream *stream, struct cras_iodev *iodev); /* Dumps information about all active streams to syslog. */ int audio_thread_dump_thread_info(struct audio_thread *thread, struct audio_debug_info *info); /* Configures the global converter for output remixing. Called by main * thread. */ int audio_thread_config_global_remix(struct audio_thread *thread, unsigned int num_channels, const float *coefficient); /* Gets the global remix converter. */ struct cras_fmt_conv *audio_thread_get_global_remix_converter(); /* Start ramping on a device. * * Ramping is started/updated in audio thread. This function lets the main * thread request that the audio thread start ramping. * * Args: * thread - a pointer to the audio thread. * dev - the device to start ramping. * request - Check the docstrings of CRAS_IODEV_RAMP_REQUEST. * Returns: * 0 on success, negative if error. */ int audio_thread_dev_start_ramp(struct audio_thread *thread, struct cras_iodev *dev, enum CRAS_IODEV_RAMP_REQUEST request); #endif /* AUDIO_THREAD_H_ */