1 /* 2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited 3 */ 4 5 #ifndef SOUND_PCM_H 6 #define SOUND_PCM_H 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <fcntl.h> 11 #include <stdarg.h> 12 #include <string.h> 13 #include <errno.h> 14 #include <unistd.h> 15 #include <aos/list.h> 16 #include <aos/kernel.h> 17 #ifndef HAAS_AUDIO_DEMO 18 #include <sys/ioctl.h> 19 #endif 20 #include "audio_drv.h" 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 /** @defgroup a2sa_pcm_api pcm 27 * @ingroup a2sa_api 28 * @{ 29 */ 30 31 typedef unsigned long aos_pcm_uframes_t; 32 typedef signed long aos_pcm_sframes_t; 33 34 /* AOS_PCM常用宏定义 */ 35 #define AOS_PCM_BLOCK 0x00000000 /**< Blocking mode (flag for open mode) */ 36 #define AOS_PCM_NONBLOCK 0x00000001 /**< Non blocking mode (flag for open mode) */ 37 #define AOS_PCM_ASYNC 0x00000002 /**< Async notification (flag for open mode) */ 38 #define AOS_PCM_ABORT 0x00008000 /**< In an abort state (internal, not allowed for open) */ 39 #define AOS_PCM_NO_AUTO_RESAMPLE 0x00010000 /**< Disable automatic (but not forced!) rate resamplinig */ 40 #define AOS_PCM_NO_AUTO_CHANNELS 0x00020000 /**< Disable automatic (but not forced!) channel conversion */ 41 #define AOS_PCM_NO_AUTO_FORMAT 0x00040000 /**< Disable automatic (but not forced!) format conversion */ 42 #define AOS_PCM_NO_SOFTVOL 0x00080000 /**< Disable soft volume control */ 43 #define AOS_PCM_EVT_WRITE (1 << 0) /**< playback resource available event */ 44 #define AOS_PCM_EVT_READ (1 << 1) /**< capture data available event */ 45 #define AOS_PCM_EVT_XRUN (1 << 2) /**< underrun (playback) or overrun (capture) detected */ 46 47 /* PCM stream 类型定义 */ 48 typedef enum { 49 AOS_PCM_STREAM_PLAYBACK = 0, /**< Playback stream */ 50 AOS_PCM_STREAM_CAPTURE, /**< Capture stream */ 51 AOS_PCM_STREAM_LAST = AOS_PCM_STREAM_CAPTURE 52 } aos_pcm_stream_t; 53 54 /* PCM stream 状态定义 */ 55 typedef enum { 56 AOS_PCM_STATE_IDLE = 0, /**< IDLE */ 57 AOS_PCM_STATE_OPEN, /**< Open */ 58 AOS_PCM_STATE_PREPARED, /**< Ready to start */ 59 AOS_PCM_STATE_RUNNING, /**< Running */ 60 AOS_PCM_STATE_XRUN, /**< Stopped: underrun (playback) or overrun (capture) detected */ 61 AOS_PCM_STATE_DRAINING, /**< Draining: running (playback) or stopped (capture) */ 62 AOS_PCM_STATE_PAUSED, /**< Paused */ 63 AOS_PCM_STATE_SUSPENDED, /**< Hardware is suspended */ 64 AOS_PCM_STATE_DISCONNECTED, /**< Hardware is disconnected */ 65 AOS_PCM_STATE_LAST = AOS_PCM_STATE_DISCONNECTED, /**< Last state */ 66 AOS_PCM_STATE_PRIVATE1 = 1024 /**< Private - used internally in the library - do not use*/ 67 } aos_pcm_state_t; 68 69 /* PCM stream 格式定义 */ 70 typedef enum { 71 AOSRV_PCM_FORMAT_S8 = 1, /**< Signed 8-bit */ 72 AOSRV_PCM_FORMAT_S16_LE = 2, /**< Signed 16-bit, little endian */ 73 AOSRV_PCM_FORMAT_S24_LE = 3, /**< Signed 24-bit, little endian */ 74 AOSRV_PCM_FORMAT_S32_LE = 4, /**< Signed 32-bit, little endian */ 75 AOSRV_PCM_FORMAT_ALL 76 } aos_pcm_format_t; 77 78 /* PCM stream 访问模式定义 */ 79 typedef enum { 80 AOS_PCM_ACCESS_MMAP_INTERLEAVED = 0, /**< MMAP RW interleaved access */ 81 AOS_PCM_ACCESS_MMAP_NONINTERLEAVED, /**< MMAP RW non-interleaved access */ 82 AOS_PCM_ACCESS_RW_INTERLEAVED, /**< RW interleaved access, e.g. writei/readi */ 83 AOS_PCM_ACCESS_RW_NONINTERLEAVED /**< RW non-interleaved access, e.g. writen/readn */ 84 } aos_pcm_access_t; 85 86 /* PCM stream 硬件参数类型 */ 87 typedef struct { 88 aos_pcm_access_t access; /**< aos_pcm_access_t 类型 */ 89 aos_pcm_format_t format; /**< aos_pcm_format_t 类型 */ 90 unsigned int sample_bits; /**< 采样精度 */ 91 unsigned int frame_bits; /**< frame 位宽大小 */ 92 unsigned int channels; /**< channel 通道数 */ 93 unsigned int rate; /**< 采样率 */ 94 unsigned int period_time; 95 unsigned int period_size; 96 unsigned int period_bytes; 97 unsigned int periods; 98 unsigned int buffer_time; 99 unsigned int buffer_size; 100 unsigned int buffer_bytes; 101 unsigned int tick_time; 102 } aos_pcm_hw_params_t; 103 104 /* PCM stream 软件参数类型 */ 105 typedef struct { 106 int tstamp_mode; /*< timestamp mode */ 107 unsigned int period_step; 108 unsigned int sleep_min; /*< min ticks to sleep */ 109 aos_pcm_uframes_t avail_min; /*< min avail frames for wakeup */ 110 aos_pcm_uframes_t xfer_align; /*< obsolete: xfer size need to be a multiple */ 111 aos_pcm_uframes_t start_threshold; /*< min hw_avail frames for automatic start */ 112 aos_pcm_uframes_t stop_threshold; /*< min avail frames for automatic stop */ 113 aos_pcm_uframes_t silence_threshold; /*< min distance from noise for silence filling */ 114 aos_pcm_uframes_t silence_size; /*< silence block size */ 115 aos_pcm_uframes_t boundary; /*< pointers wrap point */ 116 unsigned int proto; /*< protocol version */ 117 unsigned int tstamp_type; /*< timestamp type (req. proto >= 2.0.12) */ 118 unsigned char reserved[56]; /*< reserved for future */ 119 } aos_pcm_sw_params_t; 120 121 /* PCM stream 类型 */ 122 typedef struct { 123 /* mandatory */ 124 int fd; /*< 该pcm设备节点的fd,通过open()获取 */ 125 aos_pcm_stream_t stream; /*< aos_pcm_stream_t 类型 */ 126 aos_pcm_state_t state; /*< aos_pcm_state_t 类型 */ 127 char *name; /*< pcm stream name */ 128 int mode; 129 int card; /*< pcm stream 所属的card id */ 130 int device; /*< pcm stream device id */ 131 aos_hdl_t mutex; 132 aos_hdl_t evt; 133 aos_pcm_hw_params_t *hw_params; /*< pcm stream 硬件参数 */ 134 aos_pcm_sw_params_t *sw_params; /*< pcm stream 软件参数 */ 135 136 /* options */ 137 void *open_func; 138 long minperiodtime; 139 int poll_fd_count; 140 unsigned short poll_events; 141 int setup: 1, 142 compat: 1; 143 unsigned int mmap_rw: 1; 144 unsigned int mmap_shadow: 1; 145 unsigned int donot_close: 1; 146 unsigned int own_state_check:1; 147 void *private_data; 148 } aos_pcm_t; 149 150 /* 所有声卡的PCM stream汇总 */ 151 typedef struct { 152 dlist_t list; /*< 列表 */ 153 unsigned int count; /*< 列表中PCM Stream个数 */ 154 unsigned int allocated; 155 const char *siface; /*< 默认: AOS_CTL_ELEM_IFACE_MIXER */ 156 int card; /*< 当前声卡ID */ 157 int device; /*< 在当前声中的设备ID */ 158 long device_input; 159 long device_output; 160 int stream; /*< 0: Capture Stream 类型,1: Playback Stream 类型 */ 161 int show_all; 162 char name[100]; /*< 当前设备名 */ 163 } hint_list_t; 164 165 /** 166 * 获取声卡card下属所有的PCM Stream 167 * 168 * @param[in] card 声卡ID 169 * @param[out] hints hint_list_t类型列表 170 * 171 * @return 0 on success, negative error on failure. 172 */ 173 int aos_device_name_hint(int card, void *hints); 174 175 /** 176 * 获取声卡card下属所有的PCM Stream 177 * 178 * @param[out] **pcm aos_pcm_t 句柄指针 179 * @param[in] *name pcm stream name 180 * @param[in] stream aos_pcm_stream_t 类型 181 * @param[in] mode AOS_PCM_BLOCK 或者 AOS_PCM_NONBLOCK 182 * 183 * @return 0 on success, negative error on failure. 184 */ 185 int aos_pcm_open(aos_pcm_t **pcm, const char *name, aos_pcm_stream_t stream, int mode); 186 187 /** 188 * 设置PCM Stream为prepared状态 189 * 190 * @param[in] *pcm aos_pcm_t 句柄 191 * 192 * @return 0 on success, negative error on failure. 193 */ 194 int aos_pcm_prepare(aos_pcm_t *pcm); 195 196 /** 197 * 设置PCM Stream为START状态 198 * 199 * @param[in] *pcm aos_pcm_t 句柄 200 * 201 * @return 0 on success, negative error on failure. 202 */ 203 int aos_pcm_start(aos_pcm_t *pcm); 204 205 /** 206 * 设置PCM Stream为wait状态, 最大超时时间timeout milisecond 207 * 208 * @param[in] *pcm aos_pcm_t 句柄 209 * @param[in] timeout 超时时间,毫秒为单位 210 * 211 * @return 0 on success, negative error on failure. 212 */ 213 int aos_pcm_wait(aos_pcm_t *pcm, int timeout); 214 215 /** 216 * 停止PCM Stream 217 * 218 * @param[in] *pcm aos_pcm_t 句柄 219 * 220 * @return 0 on success, negative error on failure. 221 */ 222 int aos_pcm_stop(aos_pcm_t *pcm); 223 224 /** 225 * 等待Playback PCM Stream buffer中的数据播放完成 226 * 227 * @param[in] *pcm aos_pcm_t 句柄 228 * 229 * @return 0 on success, negative error on failure. 230 */ 231 int aos_pcm_drain(aos_pcm_t *pcm); 232 233 /** 234 * 暂停 PCM Stream 235 * 236 * @param[in] *pcm aos_pcm_t 句柄 237 * 238 * @return 0 on success, negative error on failure. 239 */ 240 int aos_pcm_pause(aos_pcm_t *pcm, int enable); 241 242 /** 243 * 关闭 PCM Stream 244 * 245 * @param[in] *pcm aos_pcm_t 句柄 246 * 247 * @return 0 on success, negative error on failure. 248 */ 249 int aos_pcm_close(aos_pcm_t *pcm); 250 251 /** 252 * 恢复 PCM Stream 底层硬件状态(可选) 253 * 254 * @param[in] *pcm aos_pcm_t 句柄 255 * 256 * @return 0 on success, negative error on failure. 257 */ 258 int aos_pcm_recover(aos_pcm_t *pcm); 259 260 /** 261 * 分配 aos_pcm_hw_params_t 类型缓存区 262 * 263 * @param[out] **p aos_pcm_hw_params_t 类型2级指针 264 * 265 * @return 0 on success, negative error on failure. 266 */ 267 int aos_pcm_hw_params_alloca(aos_pcm_hw_params_t **p); 268 269 /** 270 * 设置aos_pcm_hw_params_t 类型参数为默认参数 271 * 272 * @param[in] *params aos_pcm_hw_params_t* 类型 273 * 274 * @return 0 on success, negative error on failure. 275 */ 276 int aos_pcm_hw_params_any(aos_pcm_hw_params_t *params); 277 278 /** 279 * 设置pcm stream的硬件参数为 *p 指向的参数 280 * 281 * @param[in] *pcm aos_pcm_t* 类型 282 * @param[in] *p aos_pcm_hw_params_t* 类型 283 * 284 * @return 0 on success, negative error on failure. 285 */ 286 int aos_pcm_hw_params(aos_pcm_t *pcm, aos_pcm_hw_params_t *p); 287 288 /** 289 * 根据输入参数设置pcm stream的硬件参数 290 * 291 * @param[in] *pcm aos_pcm_t* 类型 292 * @param[in] format aos_pcm_format_t 类型 293 * @param[in] access aos_pcm_access_t 类型 294 * @param[in] channels unsigned int 类型, 通道数 295 * @param[in] rate unsigned int 类型, 采样率 296 * @param[in] soft_resample int 类型 297 * @param[in] latency unsigned int 类型 298 * 299 * @return 0 on success, negative error on failure. 300 */ 301 int aos_pcm_set_params(aos_pcm_t *pcm, aos_pcm_format_t format, aos_pcm_access_t access, unsigned int channels, 302 unsigned int rate, int soft_resample, unsigned int latency); 303 304 /** 305 * 分配 aos_pcm_sw_params_t 类型缓存区 306 * 307 * @param[in] **p aos_pcm_sw_params_t* 类型 308 * 309 * @return 0 on success, negative error on failure. 310 */ 311 int aos_pcm_sw_params_alloca(aos_pcm_sw_params_t **p); 312 313 /** 314 * 设置 aos_pcm_sw_params_t 类型参数为默认参数 315 * 316 * @param[in] *params aos_pcm_sw_params_t* 类型 317 * 318 * @return 0 on success, negative error on failure. 319 */ 320 int aos_pcm_sw_params_any(aos_pcm_sw_params_t *params); 321 322 /** 323 * 设置pcm stream的软件参数为 *params 指向的参数 324 * 325 * @param[in] *pcm aos_pcm_t* 类型 326 * @param[in] *params aos_pcm_sw_params_t* 类型 327 * 328 * @return 0 on success, negative error on failure. 329 */ 330 int aos_pcm_sw_params(aos_pcm_t *pcm, aos_pcm_sw_params_t *params); 331 332 /** 333 * 以interleave格式往pcm stream写数据(e.g. CH0 -> CH1 -> CH2 -> CH0 ...) 334 * 335 * @param[in] *pcm aos_pcm_t* 类型 336 * @param[in] *buffer 待写入的数据buffer 337 * @param[in] *size 待写入的数据buffer大小,以字节为单位 338 * 339 * @return writen bytes number on success, negative error on failure. 340 */ 341 aos_pcm_sframes_t aos_pcm_writei(aos_pcm_t *pcm, const void *buffer, aos_pcm_uframes_t size); 342 343 /** 344 * 以interleave格式从pcm stream读数据(e.g. CH0 -> CH1 -> CH2 -> CH0 ...) 345 * 346 * @param[in] *pcm aos_pcm_t* 类型 347 * @param[in] *buffer 存储读出数据的buffer 348 * @param[in] *size 待读出的数据大小,以字节为单位 349 * 350 * @return read bytes number on success, negative error on failure. 351 */ 352 aos_pcm_sframes_t aos_pcm_readi(aos_pcm_t *pcm, void *buffer, aos_pcm_uframes_t size); 353 354 /** 355 * 以non-interleave格式往pcm stream写数据(e.g. CH0 -> CH0 ...-> CH0 (size 单位数据全部写完) -> CH1 -> CH1 ...) 356 * 357 * @param[in] *pcm aos_pcm_t* 类型 358 * @param[in] *buffer 待写入的数据buffer 359 * @param[in] *size 待写入的数据buffer大小,以字节为单位 360 * 361 * @return writen bytes number on success, negative error on failure. 362 */ 363 aos_pcm_sframes_t aos_pcm_writen(aos_pcm_t *pcm, void **bufs, aos_pcm_uframes_t size); 364 365 /** 366 * 以non-interleave格式从pcm stream读数据(e.g. CH0 -> CH0 ...-> CH0 (size 单位数据全部读完) -> CH1 -> CH1 ...) 367 * 368 * @param[in] *pcm aos_pcm_t* 类型 369 * @param[in] *buffer 存储读出数据的buffer 370 * @param[in] *size 待读出的数据大小,以字节为单位 371 * 372 * @return read bytes number on success, negative error on failure. 373 */ 374 aos_pcm_sframes_t aos_pcm_readn(aos_pcm_t *pcm, void **bufs, aos_pcm_uframes_t size); 375 376 /** 377 * 暂停pcm stream,buffer中的数据仍然保留 378 * 379 * @param[in] *pcm aos_pcm_t* 类型 380 * 381 * @return 0 on success, negative error on failure. 382 */ 383 int aos_pcm_suspend(aos_pcm_t *pcm); 384 385 /** 386 * 恢复pcm stream,buffer中遗留的数据继续读写 387 * 388 * @param[in] *pcm aos_pcm_t* 类型 389 * 390 * @return 0 on success, negative error on failure. 391 */ 392 int aos_pcm_resume(aos_pcm_t *pcm); 393 394 /** 395 * 根据pcm stream的参数配置计算bytes个字节对应的frame帧数 396 * 397 * @param[in] *pcm aos_pcm_t* 类型 398 * @param[in] bytes 字节数 399 * 400 * @return aos_pcm_sframes_t on success, negative error on failure. 401 */ 402 aos_pcm_sframes_t aos_pcm_bytes_to_frames(aos_pcm_t *pcm, int bytes); 403 404 /** 405 * 根据pcm stream的参数配置计算frame帧数对应的bytes字节数 406 * 407 * @param[in] *pcm aos_pcm_t* 类型 408 * @param[in] *frames 帧数 409 * 410 * @return unsigned int on success, negative error on failure. 411 */ 412 int aos_pcm_frames_to_bytes(aos_pcm_t *pcm, aos_pcm_sframes_t frames); 413 414 /** 415 * @} 416 */ 417 418 #ifdef __cplusplus 419 } 420 #endif 421 #endif /* SOUND_PCM_H */ 422 423