Files
99_7018_lmx/include_lib/media/sound/pcm.h

331 lines
14 KiB
C
Raw Normal View History

2025-10-29 13:10:02 +08:00
/*****************************************************************
>file name : pcm.h
>create time : Mon 18 Jan 2021 02:04:15 PM CST
*****************************************************************/
#ifndef _SOUND_PCM_H_
#define _SOUND_PCM_H_
#include "audio_cfifo.h"
#include "os/os_api.h"
struct sound_pcm_hardware {
unsigned int info; /* SOUND_PCM_INFO_* */
unsigned int formats; /* SOUND_PCM_FMTBIT_* */
unsigned int rates; /* SOUND_PCM_RATE_* */
unsigned int rate_min; /* min rate */
unsigned int rate_max; /* max rate */
unsigned int channels_min; /* min channels */
unsigned int channels_max; /* max channels */
int buffer_bytes_max; /* max buffer size */
int period_bytes_min; /* min period size */
int period_bytes_max; /* max period size */
unsigned int periods_min; /* min # of periods */
unsigned int periods_max; /* max # of periods */
int fifo_size; /* fifo size in bytes */
};
struct sound_pcm_substream;
struct sound_pcm_hw_params;
/*****************************************************************************/
/* SOUND PCM逻辑设备错误返回值*/
#define ESNDPCM_NOMEM 1 /* PCM设备申请不到内存 */
#define ESNDPCM_NODEV 2 /* 找不到PCM设备 */
#define ESNDPCM_INVAL 3 /* 无效的设备平台(未初始化) */
#define ESNDPCM_UNKNOWN_RATE 4 /* PCM设备不支持的采样率 */
#define ESNDPCM_CONFLICT_RATE 5 /* PCM设备与设置采样率冲突 */
#define ESNDPCM_NOFIFO 6 /* PCM设备中没有设置runtime的fifo */
/*****************************************************************************/
#define SOUND_PCM_TRIGGER_START 1 /* 触发DMA/CODEC开启 */
#define SOUND_PCM_TRIGGER_STOP 2 /* 触发DMA/CODEC停止 */
#define SOUND_PCM_TRIGGER_IRQ 3 /* 触发DMA下一个中断外传 */
#define SOUND_PCM_GET_HW_PARAMS _IOR('P', 1, sizeof(struct sound_pcm_hw_params)) /* Get硬件参数 */
#define SOUND_PCM_SET_HW_PARAMS _IOW('P', 2, sizeof(struct sound_pcm_hw_params)) /* Set硬件参数 */
#define SOUND_PCM_GET_HW_BUFFERED_LEN _IOR('P', 3, sizeof(unsigned int)) /* Get硬件参数 */
#define SOUND_PCM_WAIT_SWN_MOVE _IOR('P', 4, sizeof(unsigned int)) /* 等待dac swn 输出一个点后,再往后走硬件参数 */
#define SOUND_PCM_GET_HW_HRP _IOR('P', 5, sizeof(unsigned int)) /* Get硬件读指针 */
enum pcm_state {
SOUND_PCM_STATE_IDLE = 0, /* PCM设备空闲 */
SOUND_PCM_STATE_PREPARED, /* PCM设备硬件准备就绪 */
SOUND_PCM_STATE_RUNNING, /* PCM设备DMA/CODEC运行中 */
SOUND_PCM_STATE_SUSPENDED, /* PCM设备挂起 */
};
/*
* Sound PCM设备支持标准sample rate定义
* */
#define SOUND_PCM_RATE_8000 (1<<0) /* 8000Hz */
#define SOUND_PCM_RATE_11025 (1<<1) /* 11025Hz */
#define SOUND_PCM_RATE_12000 (1<<2) /* 12000Hz */
#define SOUND_PCM_RATE_16000 (1<<3) /* 16000Hz */
#define SOUND_PCM_RATE_22050 (1<<4) /* 22050Hz */
#define SOUND_PCM_RATE_24000 (1<<5) /* 24000Hz */
#define SOUND_PCM_RATE_32000 (1<<6) /* 32000Hz */
#define SOUND_PCM_RATE_44100 (1<<7) /* 44100Hz */
#define SOUND_PCM_RATE_48000 (1<<8) /* 48000Hz */
#define SOUND_PCM_RATE_64000 (1<<9) /* 64000Hz */
#define SOUND_PCM_RATE_88200 (1<<10) /* 88200Hz */
#define SOUND_PCM_RATE_96000 (1<<11) /* 96000Hz */
#define SOUND_PCM_RATE_128000 (1<<12) /* 128000Hz */
#define SOUND_PCM_RATE_176400 (1<<13) /* 176400Hz */
#define SOUND_PCM_RATE_192000 (1<<14) /* 192000Hz */
#define SOUND_PCM_RATE_UNKNOWN (1<<15) /* Unknown sample rate */
#define SOUND_PCM_RATE_8000_44100 (SOUND_PCM_RATE_8000|SOUND_PCM_RATE_11025|SOUND_PCM_RATE_12000|\
SOUND_PCM_RATE_16000|SOUND_PCM_RATE_22050|SOUND_PCM_RATE_24000|\
SOUND_PCM_RATE_32000|SOUND_PCM_RATE_44100)
#define SOUND_PCM_RATE_8000_48000 (SOUND_PCM_RATE_8000_44100|SOUND_PCM_RATE_48000)
#define SOUND_PCM_RATE_8000_96000 (SOUND_PCM_RATE_8000_48000|SOUND_PCM_RATE_64000|\
SOUND_PCM_RATE_88200|SOUND_PCM_RATE_96000)
#define SOUND_PCM_RATE_8000_192000 (SOUND_PCM_RATE_8000_96000|SOUND_PCM_RATE_128000|SOUND_PCM_RATE_176400|\
SOUND_PCM_RATE_192000)
/*
* PCM设备与硬件DMA同步flag
*/
#define DMA_SYNC_R (1 << 0) /* 读同步 */
#define DMA_SYNC_W (1 << 1) /* 写同步 */
#define DMA_SYNC_RW (DMA_SYNC_R | DMA_SYNC_W) /* 读写同步 */
/*
* Sound运行时间单位
*/
#define SOUND_TIME_MS 0
#define SOUND_TIME_US 1
/*
* PCM设备操作函数
*/
struct sound_pcm_ops {
int (*open)(struct sound_pcm_substream *substream);
int (*close)(struct sound_pcm_substream *substream);
int (*ioctl)(struct sound_pcm_substream *substream,
unsigned int cmd, void *arg);
int (*prepare)(struct sound_pcm_substream *substream);
int (*trigger)(struct sound_pcm_substream *substream, int cmd);
int (*pointer)(struct sound_pcm_substream *substream);
int (*silence)(struct sound_pcm_substream *substream, int channel, u32 pos, u32 count);
};
struct sound_pcm_hw_params {
u32 rates;
int sample_rate;
u8 sample_bits;
u8 channels;
};
struct sound_dma_buffer {
u8 mode;
void *addr;
s16 size;
struct audio_cfifo fifo;
};
struct sound_pcm_map_status {
u8 state;
u8 ref_count;
};
struct sound_pcm_map_fifo {
void *addr; /* FIFO地址 */
u16 bytes; /* FIFO大小(bytes) */
u16 frame_len; /* FIFO帧总长度(bytes / ch / 2) */
struct audio_cfifo cfifo; /* FIFO结构实体 */
void (*sync)(struct sound_pcm_substream *substream, u8 flag); /* FIFO同步 */
};
struct sound_pcm_runtime {
/*fifo*/
u32 hw_ptr; /* 当前硬件位置 */
u32 sw_ptr; /* 当前软件位置 */
u32 hw_ptr_jiffies; /* 当前硬件位置对应的时间 */
u32 dma_irq_ptr; /* 设置的dma到达该ptr起中断 */
u32(*sound_current_time)(void); /* 当前采样时间获取 */
struct sound_pcm_map_fifo *fifo;
u8 time_type; /* 采样指针位置的时钟类型 */
/* -- HW params -- */
u8 channels; /* 采样通道 */
u8 sample_bits;
u16 period_size; /* 采样周期块大小(pingpong buffer模式) */
u32 periods; /* 采样周期个数 */
int sample_rate; /* sample_rate */
/* -- SW params -- */
u8 run_mode; /*OVERRUN或非OVERRUN*/
//u32 start_threshold; [>启动DMA的阈值<]
//u32 stop_threshold; [>停止DMA的阈值<]
//u32 silence_threshold; [>静音数据阈值 <]
//u32 silence_size; [>填充静音数据的大小 <]
u32 silence_start; /* 静音起始位置 */
u32 silence_filled; /* 已填充的静音数据 */
int buffer_delay;
struct sound_pcm_map_status *status; /*映射硬件中的状态*/
/* -- DMA -- */
struct sound_dma_buffer *dma; /* DMA缓冲 */
OS_MUTEX *mutex;
};
struct sound_pcm_stream;
struct sound_pcm_substream {
struct sound_pcm_stream *stream;
struct sound_pcm_runtime *runtime; /* 数据流运行结构 */
struct audio_cfifo_channel fifo; /* fifo缓冲 */
void *private_data;
struct list_head entry;
void *irq_priv;
void (*irq_handler)(void *priv);
u8 direction; /* 数据流方向 */
unsigned int hw_opened: 1;
};
struct sound_pcm_stream {
struct sound_pcm_substream *substream; /* 与设备共享的子数据流 */
const struct sound_pcm_ops *ops; /* PCM操作函数 */
void *platform_device;
void *syncts;
};
/*************************************************************************
* bit表示
* Input : sample_rate -
* Output : bit表示
* Notes :
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_match_standard_rate(int sample_rate);
/*************************************************************************
* sound pcm数据流
* Input : stream - sound_pcm_stream二级指针
* name -
* direction - .
* Output : 0 - 0 - .
* Notes :
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_create(struct sound_pcm_stream **stream, const char *name, u8 direction);
/*************************************************************************
* pcm设备中断处理函数
* Input : stream - sound_pcm_stream指针
* priv -
* handler - .
* Output : .
* Notes : pingpong模式可以用来处理音频采样定时
* 使
* History : 2021/03/11 by Lichao.
*=======================================================================*/
void sound_pcm_set_irq_handler(struct sound_pcm_stream *stream, void *priv, void (*handler)(void *));
/*************************************************************************
* pcm设备数据流准备
* Input : stream - sound_pcm_stream指针
* sample_rate -
* delay -
* mode - overrun/block模式选择.
* Output : 0 - 0 - .
* Notes :
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_prepare(struct sound_pcm_stream *stream, int sample_rate, int delay, int mode);
/*************************************************************************
* pcm设备数据流开启采样
* Input : stream - sound_pcm_stream指针.
* Output : 0 - 0 - .
* Notes :
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_start(struct sound_pcm_stream *stream);
/*************************************************************************
* pcm设备数据流停止采样
* Input : stream - sound_pcm_stream指针.
* Output : 0 - 0 - .
* Notes :
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_stop(struct sound_pcm_stream *stream);
/*************************************************************************
* pcm设备数据流触发一次中断
* Input : stream - sound_pcm_stream指针,
* time_unit -
* time - .
* Output : 0 - 0 - .
* Notes :
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_trigger_interrupt(struct sound_pcm_stream *stream, u8 time_unit, int time);
/*************************************************************************
* pcm设备数据子流中断处理函数
* Input : substream - sound_pcm_substream指针.
* Output : 0 - 0 - .
* Notes : DMA中断调用该函数进行中断分配和更新DMA信息.
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_substream_irq_handler(struct sound_pcm_substream *substream);
/*************************************************************************
* pcm设备设置数据声道分布
* Input : stream - sound_pcm_stream指针,
* map - .
* Output : 0 - 0 - .
* Notes :
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_set_data_map(struct sound_pcm_stream *stream, u16 map);
/*************************************************************************
* pcm设备写入数据
* Input : stream - sound_pcm_stream指针,
* data - ,
* len - .
* Output : .
* Notes :
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_write(struct sound_pcm_stream *stream, void *data, int len);
/*************************************************************************
* pcm设备io控制函数
* Input : stream - sound_pcm_stream指针,
* cmd - ,
* arg - .
* Output : 0 - 0 - .
* Notes : PCM数据流的ioctl函数()
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_iotcl(struct sound_pcm_stream *stream, int cmd, void *arg);
/*************************************************************************
* pcm设备控制器io控制函数
* Input : stream - sound_pcm_stream指针,
* cmd - ,
* arg - .
* Output : 0 - 0 - .
* Notes : PCM设备的控制器ioctl函数(/)
* History : 2021/03/11 by Lichao.
*=======================================================================*/
int sound_pcm_ctl_ioctl(struct sound_pcm_stream *stream, int cmd, void *arg);
int sound_pcm_read(struct sound_pcm_stream *stream, void *data, int len);
void sound_pcm_free(struct sound_pcm_stream *stream);
void sound_pcm_set_syncts(struct sound_pcm_stream *stream, void *syncts);
#endif