You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
8.0 KiB
228 lines
8.0 KiB
/* 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.
|
|
*/
|
|
|
|
/*
|
|
* Alsa Helpers - Keeps the interface to alsa localized to this file.
|
|
*/
|
|
|
|
#ifndef _CRAS_ALSA_HELPERS_H
|
|
#define _CRAS_ALSA_HELPERS_H
|
|
|
|
#include <alsa/asoundlib.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
|
|
struct cras_audio_format;
|
|
|
|
/* Sets the channel layout from given format to the pcm handle.
|
|
* Args:
|
|
* handle - Pointer to the opened pcm to set channel map to.
|
|
* fmt - The format containing the channel layout info.
|
|
* Returns:
|
|
* 0 if a matched channel map is set to HW, -1 otherwise.
|
|
*/
|
|
int cras_alsa_set_channel_map(snd_pcm_t *handle, struct cras_audio_format *fmt);
|
|
|
|
/* Gets the supported channel mapping of the pcm handle which matches
|
|
* the channel layout in the format.
|
|
* Args:
|
|
* handle - Pointer to the opened pcm to get channel map info.
|
|
* fmt - The format to fill channel layout into.
|
|
* Returns:
|
|
* 0 if an exactly matched channel map is found, -1 otherwise.
|
|
*/
|
|
int cras_alsa_get_channel_map(snd_pcm_t *handle, struct cras_audio_format *fmt);
|
|
|
|
/* Opens an alsa device, thin wrapper to snd_pcm_open.
|
|
* Args:
|
|
* handle - Filled with a pointer to the opened pcm.
|
|
* dev - Path to the alsa device to test.
|
|
* stream - Alsa stream type, input or output.
|
|
* Returns:
|
|
* See docs for snd_pcm_open.
|
|
*/
|
|
int cras_alsa_pcm_open(snd_pcm_t **handle, const char *dev,
|
|
snd_pcm_stream_t stream);
|
|
|
|
/* Closes an alsa device, thin wrapper to snd_pcm_close.
|
|
* Args:
|
|
* handle - Filled with a pointer to the opened pcm.
|
|
* Returns:
|
|
* See docs for snd_pcm_close.
|
|
*/
|
|
int cras_alsa_pcm_close(snd_pcm_t *handle);
|
|
|
|
/* Starts an alsa device, thin wrapper to snd_pcm_start.
|
|
* Args:
|
|
* handle - Filled with a pointer to the opened pcm.
|
|
* Returns:
|
|
* See docs for snd_pcm_start.
|
|
*/
|
|
int cras_alsa_pcm_start(snd_pcm_t *handle);
|
|
|
|
/* Drains an alsa device, thin wrapper to snd_pcm_drain.
|
|
* Args:
|
|
* handle - Filled with a pointer to the opened pcm.
|
|
* Returns:
|
|
* See docs for snd_pcm_drain.
|
|
*/
|
|
int cras_alsa_pcm_drain(snd_pcm_t *handle);
|
|
|
|
/* Forward/rewind appl_ptr so it becomes ahead of hw_ptr by fuzz samples.
|
|
* After moving appl_ptr, device can play the new samples as quick as possible.
|
|
* avail = buffer_frames - appl_ptr + hw_ptr
|
|
* => hw_ptr - appl_ptr = avail - buffer_frames.
|
|
* The difference between hw_ptr and app_ptr can be inferred from snd_pcm_avail.
|
|
* So the amount of frames to forward appl_ptr is
|
|
* avail - buffer_frames + fuzz.
|
|
* When hw_ptr is wrapped around boundary, this value may be negative. Use
|
|
* snd_pcm_rewind to move appl_ptr backward.
|
|
*
|
|
* Case 1: avail - buffer_frames + fuzz > 0
|
|
*
|
|
* -------|----------|-----------------------------------
|
|
* app_ptr hw_ptr
|
|
* |------------->| forward target
|
|
*
|
|
* Case 2: avail - buffer_frames + fuzz < 0
|
|
*
|
|
* -------|----------|-----------------------------------
|
|
* hw_ptr app_ptr
|
|
* |<------| rewind target
|
|
*
|
|
* Args:
|
|
* handle - Filled with a pointer to the opened pcm.
|
|
* ahead - Number of frames appl_ptr should be ahead of hw_ptr.
|
|
* Returns:
|
|
* 0 on success. A negative error code on failure.
|
|
*/
|
|
int cras_alsa_resume_appl_ptr(snd_pcm_t *handle, snd_pcm_uframes_t ahead);
|
|
|
|
/* Probes properties of the alsa device.
|
|
* Args:
|
|
* handle - The open PCM to configure.
|
|
* rates - Pointer that will be set to the arrary of valid samples rates.
|
|
* Must be freed by the caller.
|
|
* channel_counts - Pointer that will be set to the array of valid channel
|
|
* counts. Must be freed by the caller.
|
|
* formats - Pointer that will be set to the arrary of valid PCM formats.
|
|
* Must be freed by the caller.
|
|
* Returns:
|
|
* 0 on success. On failure an error code from alsa or -ENOMEM.
|
|
*/
|
|
int cras_alsa_fill_properties(snd_pcm_t *handle, size_t **rates,
|
|
size_t **channel_counts,
|
|
snd_pcm_format_t **formats);
|
|
|
|
/* Sets up the hwparams to alsa.
|
|
* Args:
|
|
* handle - The open PCM to configure.
|
|
* format - The audio format desired for playback/capture.
|
|
* buffer_frames - Number of frames in the ALSA buffer.
|
|
* period_wakeup - Flag to determine if period_wakeup is required
|
|
* 0 - disable, 1 - enable
|
|
* dma_period_time - If non-zero, set the dma period time to this value
|
|
* (in microseconds).
|
|
* Returns:
|
|
* 0 on success, negative error on failure.
|
|
*/
|
|
int cras_alsa_set_hwparams(snd_pcm_t *handle, struct cras_audio_format *format,
|
|
snd_pcm_uframes_t *buffer_frames, int period_wakeup,
|
|
unsigned int dma_period_time);
|
|
|
|
/* Sets up the swparams to alsa.
|
|
* Args:
|
|
* handle - The open PCM to configure.
|
|
* Returns:
|
|
* 0 on success, negative error on failure.
|
|
*/
|
|
int cras_alsa_set_swparams(snd_pcm_t *handle);
|
|
|
|
/* Get the number of used frames in the alsa buffer.
|
|
*
|
|
* When underrun is not severe, this function masks the underrun situation
|
|
* and set avail as 0. When underrun is severe, returns -EPIPE so caller
|
|
* can handle it.
|
|
* Args:
|
|
* handle[in] - The open PCM to configure.
|
|
* buf_size[in] - Number of frames in the ALSA buffer.
|
|
* severe_underrun_frames[in] - Number of frames as the threshold for severe
|
|
* underrun.
|
|
* dev_name[in] - Device name for logging.
|
|
* avail[out] - Filled with the number of frames available in the buffer.
|
|
* tstamp[out] - Filled with the hardware timestamp for the available frames.
|
|
* This value is {0, 0} when the device hasn't actually started
|
|
* reading or writing frames.
|
|
* Returns:
|
|
* 0 on success, negative error on failure. -EPIPE if severe underrun
|
|
* happens.
|
|
*/
|
|
int cras_alsa_get_avail_frames(snd_pcm_t *handle, snd_pcm_uframes_t buf_size,
|
|
snd_pcm_uframes_t severe_underrun_frames,
|
|
const char *dev_name, snd_pcm_uframes_t *avail,
|
|
struct timespec *tstamp);
|
|
|
|
/* Get the current alsa delay, make sure it's no bigger than the buffer size.
|
|
* Args:
|
|
* handle - The open PCM to configure.
|
|
* buf_size - Number of frames in the ALSA buffer.
|
|
* delay - Filled with the number of delay frames.
|
|
* Returns:
|
|
* 0 on success, negative error on failure.
|
|
*/
|
|
int cras_alsa_get_delay_frames(snd_pcm_t *handle, snd_pcm_uframes_t buf_size,
|
|
snd_pcm_sframes_t *delay);
|
|
|
|
/* Wrapper for snd_pcm_mmap_begin where only buffer is concerned.
|
|
* Offset and frames from cras_alsa_mmap_begin are neglected.
|
|
* Args:
|
|
* handle - The open PCM to configure.
|
|
* dst - Pointer set to the area for reading/writing the audio.
|
|
* Returns:
|
|
* zero on success, negative error code for fatal errors.
|
|
*/
|
|
int cras_alsa_mmap_get_whole_buffer(snd_pcm_t *handle, uint8_t **dst);
|
|
|
|
/* Wrapper for snd_pcm_mmap_begin
|
|
* Args:
|
|
* handle - The open PCM to configure.
|
|
* format_bytes - Number of bytes in a single frame.
|
|
* dst - Pointer set to the area for reading/writing the audio.
|
|
* offset - Filled with the offset to pass back to commit.
|
|
* frames - Passed with the max number of frames to request. Filled with the
|
|
* max number to use.
|
|
* Returns:
|
|
* zero on success, negative error code for fatal
|
|
* errors.
|
|
*/
|
|
int cras_alsa_mmap_begin(snd_pcm_t *handle, unsigned int format_bytes,
|
|
uint8_t **dst, snd_pcm_uframes_t *offset,
|
|
snd_pcm_uframes_t *frames);
|
|
|
|
/* Wrapper for snd_pcm_mmap_commit
|
|
* Args:
|
|
* handle - The open PCM to configure.
|
|
* offset - offset from call to mmap_begin.
|
|
* frames - # of frames written/read.
|
|
* Returns:
|
|
* zero on success, negative error code for fatal
|
|
* errors.
|
|
*/
|
|
int cras_alsa_mmap_commit(snd_pcm_t *handle, snd_pcm_uframes_t offset,
|
|
snd_pcm_uframes_t frames);
|
|
|
|
/* When the stream is suspended, due to a system suspend, loop until we can
|
|
* resume it. Won't actually loop very much because the system will be
|
|
* suspended.
|
|
* Args:
|
|
* handle - The open PCM to configure.
|
|
* Returns:
|
|
* zero on success, negative error code for fatal
|
|
* errors.
|
|
*/
|
|
int cras_alsa_attempt_resume(snd_pcm_t *handle);
|
|
|
|
#endif /* _CRAS_ALSA_HELPERS_H */
|