1 /* 2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved. 3 * 4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in 5 * the the people's Republic of China and other countries. 6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission. 7 * 8 * DISCLAIMER 9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT. 10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.) 11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN 12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES. 13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS 14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE. 15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY. 16 * 17 * 18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT 19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND, 20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING 21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE 22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 30 * OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 #ifndef __AW_ALSA_PCM_H 33 #define __AW_ALSA_PCM_H 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 #include <sound/ksound.h> 39 #include <sound/card.h> 40 #include <sound/pcm_common.h> 41 #include <alloca.h> 42 #include <string.h> 43 #include <sys/types.h> 44 #include <hal_mutex.h> 45 46 #ifndef snd_malloc 47 #define snd_malloc(size) calloc(size, 1) 48 #endif 49 50 #ifndef snd_free 51 #define snd_free(ptr) free(ptr) 52 #endif 53 54 55 /* debug option */ 56 #define AW_ALSA_LOG_COLOR_NONE "\e[0m" 57 #define AW_ALSA_LOG_COLOR_RED "\e[31m" 58 #define AW_ALSA_LOG_COLOR_GREEN "\e[32m" 59 #define AW_ALSA_LOG_COLOR_YELLOW "\e[33m" 60 #define AW_ALSA_LOG_COLOR_BLUE "\e[34m" 61 62 //#define AW_ALSA_DEBUG 63 #ifdef AW_ALSA_DEBUG 64 #define awalsa_debug(fmt, args...) \ 65 printf(AW_ALSA_LOG_COLOR_GREEN "[AWALSA_DEBUG][%s:%u]" fmt \ 66 AW_ALSA_LOG_COLOR_NONE, __FUNCTION__, __LINE__, ##args) 67 #else 68 #define awalsa_debug(fmt, args...) 69 #endif 70 71 //#define AW_ALSA_PRINT 72 #ifdef AW_ALSA_PRINT 73 #define awalsa_print(fmt, args...) \ 74 printf("[AWALSA_PRINT][%s:%u]" fmt, \ 75 __FUNCTION__, __LINE__, ##args) 76 #else 77 #define awalsa_print(fmt, args...) 78 #endif 79 80 #define awalsa_info(fmt, args...) \ 81 printf(AW_ALSA_LOG_COLOR_BLUE "[AWALSA_INFO][%s:%u]" fmt \ 82 AW_ALSA_LOG_COLOR_NONE, __FUNCTION__, __LINE__, ##args) 83 84 #define awalsa_err(fmt, args...) \ 85 printf(AW_ALSA_LOG_COLOR_RED "[AWALSA_ERR][%s:%u]" fmt \ 86 AW_ALSA_LOG_COLOR_NONE, __FUNCTION__, __LINE__, ##args) 87 /* end debug option */ 88 89 /** Non blocking mode (flag for open mode) \hideinitializer */ 90 //#define SND_PCM_NONBLOCK 0x00000001 91 /** Async notification (flag for open mode) \hideinitializer */ 92 //#define SND_PCM_ASYNC 0x00000002 93 /** In an abort state (internal, not allowed for open) */ 94 //#define SND_PCM_ABORT 0x00008000 95 /** Disable automatic (but not forced!) rate resamplinig */ 96 #define SND_PCM_NO_AUTO_RESAMPLE 0x00010000 97 /** Disable automatic (but not forced!) channel conversion */ 98 #define SND_PCM_NO_AUTO_CHANNELS 0x00020000 99 /** Disable automatic (but not forced!) format conversion */ 100 #define SND_PCM_NO_AUTO_FORMAT 0x00040000 101 /** Disable soft volume control */ 102 //#define SND_PCM_NO_SOFTVOL 0x00080000 103 104 typedef struct _snd_pcm snd_pcm_t; 105 106 enum _snd_pcm_type { 107 /** Kernel level PCM */ 108 SND_PCM_TYPE_HW = 0, 109 /** One or more linked PCM with exclusive access to selected 110 channels */ 111 SND_PCM_TYPE_MULTI, 112 /** File writing plugin */ 113 SND_PCM_TYPE_FILE, 114 /** Linear format conversion PCM */ 115 SND_PCM_TYPE_LINEAR, 116 /** Rate conversion PCM */ 117 SND_PCM_TYPE_RATE, 118 /** Attenuated static route PCM */ 119 SND_PCM_TYPE_ROUTE, 120 /** Format adjusted PCM */ 121 SND_PCM_TYPE_PLUG, 122 /** Direct Mixing plugin */ 123 SND_PCM_TYPE_DMIX, 124 /** Direct Snooping plugin */ 125 SND_PCM_TYPE_DSNOOP, 126 /** Soft volume plugin */ 127 SND_PCM_TYPE_SOFTVOL, 128 /** External filter plugin */ 129 SND_PCM_TYPE_EXTPLUG, 130 SND_PCM_TYPE_LAST = SND_PCM_TYPE_EXTPLUG 131 }; 132 133 /** PCM type */ 134 typedef enum _snd_pcm_type snd_pcm_type_t; 135 136 /** PCM state */ 137 typedef enum _snd_pcm_state { 138 /** Open */ 139 SND_PCM_STATE_OPEN = 0, 140 /** Setup installed */ 141 SND_PCM_STATE_SETUP, 142 /** Ready to start */ 143 SND_PCM_STATE_PREPARED, 144 /** Running */ 145 SND_PCM_STATE_RUNNING, 146 /** Stopped: underrun (playback) or overrun (capture) detected */ 147 SND_PCM_STATE_XRUN, 148 /** Draining: running (playback) or stopped (capture) */ 149 SND_PCM_STATE_DRAINING, 150 /** Paused */ 151 SND_PCM_STATE_PAUSED, 152 /** Hardware is suspended */ 153 SND_PCM_STATE_SUSPENDED, 154 /** Hardware is disconnected */ 155 SND_PCM_STATE_DISCONNECTED, 156 SND_PCM_STATE_LAST = 1024, 157 } snd_pcm_state_t; 158 159 /** PCM stream (direction) */ 160 typedef enum _snd_pcm_stream { 161 /** Playback stream */ 162 SND_PCM_STREAM_PLAYBACK = 0, 163 /** Capture stream */ 164 SND_PCM_STREAM_CAPTURE, 165 SND_PCM_STREAM_LAST = SND_PCM_STREAM_CAPTURE 166 } snd_pcm_stream_t; 167 168 169 /** PCM area specification */ 170 typedef struct _snd_pcm_channel_area { 171 /** base address of channel samples */ 172 void *addr; 173 /** offset to first sample in bits */ 174 unsigned int first; 175 /** samples distance in bits */ 176 unsigned int step; 177 } snd_pcm_channel_area_t; 178 179 180 int snd_pcm_open(snd_pcm_t **pcm, const char *name, 181 snd_pcm_stream_t stream, int mode); 182 int snd_pcm_close(snd_pcm_t *pcm); 183 184 int snd_pcm_hw_params_malloc(snd_pcm_hw_params_t **ptr); 185 void snd_pcm_hw_params_free(snd_pcm_hw_params_t *obj); 186 int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 187 int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 188 int snd_pcm_hw_free(snd_pcm_t *pcm); 189 int snd_pcm_reset(snd_pcm_t *pcm); 190 int snd_pcm_start(snd_pcm_t *pcm); 191 int snd_pcm_prepare(snd_pcm_t *pcm); 192 int snd_pcm_drop(snd_pcm_t *pcm); 193 int snd_pcm_drain(snd_pcm_t *pcm); 194 int snd_pcm_pause(snd_pcm_t *pcm, int enable); 195 int snd_pcm_recover(snd_pcm_t *pcm, int err, int silent); 196 int snd_pcm_resume(snd_pcm_t *pcm); 197 snd_pcm_state_t snd_pcm_state(snd_pcm_t *pcm); 198 snd_pcm_stream_t snd_pcm_stream(snd_pcm_t *pcm); 199 int snd_pcm_hwsync(snd_pcm_t *pcm); 200 int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp); 201 snd_pcm_sframes_t snd_pcm_avail_update(snd_pcm_t *pcm); 202 int snd_pcm_hw_params_can_pause(const snd_pcm_hw_params_t *params); 203 snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames); 204 int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2); 205 int snd_pcm_unlink(snd_pcm_t *pcm); 206 207 snd_pcm_sframes_t snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); 208 snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size); 209 210 int snd_pcm_wait(snd_pcm_t *pcm, int timeout); 211 212 int snd_pcm_dump(snd_pcm_t *pcm); 213 int snd_pcm_dump_setup(snd_pcm_t *pcm); 214 int snd_pcm_dump_hw_setup(snd_pcm_t *pcm); 215 int snd_pcm_dump_sw_setup(snd_pcm_t *pcm); 216 int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params); 217 218 /** channel positions */ 219 enum snd_pcm_chmap_position { 220 SND_CHMAP_UNKNOWN = 0, /**< unspecified */ 221 SND_CHMAP_NA, /**< N/A, silent */ 222 SND_CHMAP_MONO, /**< mono stream */ 223 SND_CHMAP_FL, /**< front left */ 224 SND_CHMAP_FR, /**< front right */ 225 SND_CHMAP_RL, /**< rear left */ 226 SND_CHMAP_RR, /**< rear right */ 227 SND_CHMAP_FC, /**< front center */ 228 SND_CHMAP_LFE, /**< LFE */ 229 SND_CHMAP_SL, /**< side left */ 230 SND_CHMAP_SR, /**< side right */ 231 SND_CHMAP_RC, /**< rear center */ 232 SND_CHMAP_FLC, /**< front left center */ 233 SND_CHMAP_FRC, /**< front right center */ 234 SND_CHMAP_RLC, /**< rear left center */ 235 SND_CHMAP_RRC, /**< rear right center */ 236 SND_CHMAP_FLW, /**< front left wide */ 237 SND_CHMAP_FRW, /**< front right wide */ 238 SND_CHMAP_FLH, /**< front left high */ 239 SND_CHMAP_FCH, /**< front center high */ 240 SND_CHMAP_FRH, /**< front right high */ 241 SND_CHMAP_TC, /**< top center */ 242 SND_CHMAP_TFL, /**< top front left */ 243 SND_CHMAP_TFR, /**< top front right */ 244 SND_CHMAP_TFC, /**< top front center */ 245 SND_CHMAP_TRL, /**< top rear left */ 246 SND_CHMAP_TRR, /**< top rear right */ 247 SND_CHMAP_TRC, /**< top rear center */ 248 SND_CHMAP_TFLC, /**< top front left center */ 249 SND_CHMAP_TFRC, /**< top front right center */ 250 SND_CHMAP_TSL, /**< top side left */ 251 SND_CHMAP_TSR, /**< top side right */ 252 SND_CHMAP_LLFE, /**< left LFE */ 253 SND_CHMAP_RLFE, /**< right LFE */ 254 SND_CHMAP_BC, /**< bottom center */ 255 SND_CHMAP_BLC, /**< bottom left center */ 256 SND_CHMAP_BRC, /**< bottom right center */ 257 SND_CHMAP_LAST = SND_CHMAP_BRC, 258 }; 259 260 /** channel map list type */ 261 enum snd_pcm_chmap_type { 262 SND_CHMAP_TYPE_NONE = 0,/**< unspecified channel position */ 263 SND_CHMAP_TYPE_FIXED, /**< fixed channel position */ 264 SND_CHMAP_TYPE_VAR, /**< freely swappable channel position */ 265 SND_CHMAP_TYPE_PAIRED, /**< pair-wise swappable channel position */ 266 SND_CHMAP_TYPE_LAST = SND_CHMAP_TYPE_PAIRED, /**< last entry */ 267 }; 268 269 /** the channel map header */ 270 typedef struct snd_pcm_chmap { 271 unsigned int channels; /**< number of channels */ 272 unsigned int pos[0]; /**< channel position array */ 273 } snd_pcm_chmap_t; 274 275 /** the header of array items returned from snd_pcm_query_chmaps() */ 276 typedef struct snd_pcm_chmap_query { 277 enum snd_pcm_chmap_type type; /**< channel map type */ 278 snd_pcm_chmap_t map; /**< available channel map */ 279 } snd_pcm_chmap_query_t; 280 281 snd_pcm_chmap_query_t **snd_pcm_query_chmaps(snd_pcm_t *pcm); 282 void snd_pcm_free_chmaps(snd_pcm_chmap_query_t **maps); 283 snd_pcm_chmap_t *snd_pcm_get_chmap(snd_pcm_t *pcm); 284 int snd_pcm_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map); 285 286 /* for pthread mutex lock */ 287 typedef hal_mutex_t snd_pcm_mutex_t; 288 snd_pcm_mutex_t snd_thread_mutex_init(void); 289 int snd_thread_mutex_lock_timeout(snd_pcm_mutex_t mutex, long ms); 290 int snd_thread_mutex_lock(snd_pcm_mutex_t mutex); 291 int snd_thread_mutex_unlock(snd_pcm_mutex_t mutex); 292 void snd_thread_mutex_destroy(snd_pcm_mutex_t mutex); 293 294 size_t snd_pcm_hw_params_sizeof(void); 295 size_t snd_pcm_sw_params_sizeof(void); 296 297 #define __snd_alloca(ptr,type) do { *ptr = (type##_t *) alloca(type##_sizeof()); memset(*ptr, 0, type##_sizeof()); } while (0) 298 #define snd_pcm_hw_params_alloca(ptr) __snd_alloca(ptr, snd_pcm_hw_params) 299 300 int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 301 302 int snd_pcm_hw_params_set_format(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val); 303 int snd_pcm_hw_params_get_format(const snd_pcm_hw_params_t *params, snd_pcm_format_t *format); 304 305 int snd_pcm_hw_params_set_channels(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val); 306 int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params, unsigned int *val); 307 308 int snd_pcm_hw_params_set_rate(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 309 int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 310 311 int snd_pcm_hw_params_set_period_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int us, int dir); 312 int snd_pcm_hw_params_set_period_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 313 int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 314 315 int snd_pcm_hw_params_set_period_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val, int dir); 316 int snd_pcm_hw_params_set_period_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); 317 int snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val, int *dir); 318 319 int snd_pcm_hw_params_set_periods(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int dir); 320 int snd_pcm_hw_params_set_periods_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 321 int snd_pcm_hw_params_get_periods(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 322 323 int snd_pcm_hw_params_set_buffer_size(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val); 324 int snd_pcm_hw_params_set_buffer_size_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 325 int snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params, snd_pcm_uframes_t *val); 326 327 int snd_pcm_hw_params_set_buffer_time(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int us); 328 int snd_pcm_hw_params_set_buffer_time_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir); 329 330 int snd_pcm_hw_params_set_access(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access); 331 int snd_pcm_hw_params_get_access(const snd_pcm_hw_params_t *params, snd_pcm_access_t *access); 332 333 #define snd_pcm_sw_params_alloca(ptr) __snd_alloca(ptr, snd_pcm_sw_params) 334 335 int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); 336 int snd_pcm_sw_params_set_start_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); 337 int snd_pcm_sw_params_get_start_threshold(snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); 338 int snd_pcm_sw_params_set_stop_threshold(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); 339 int snd_pcm_sw_params_get_stop_threshold(snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); 340 int snd_pcm_sw_params_set_silence_size(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); 341 int snd_pcm_sw_params_get_silence_size(snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); 342 int snd_pcm_sw_params_set_avail_min(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val); 343 int snd_pcm_sw_params_get_avail_min(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); 344 int snd_pcm_sw_params_get_boundary(const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val); 345 int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); 346 347 348 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples); 349 snd_pcm_sframes_t snd_pcm_bytes_to_frames(snd_pcm_t *pcm, ssize_t bytes); 350 ssize_t snd_pcm_frames_to_bytes(snd_pcm_t *pcm, snd_pcm_sframes_t frames); 351 352 snd_pcm_type_t snd_pcm_type(snd_pcm_t *pcm); 353 354 const char *snd_pcm_type_name(snd_pcm_type_t type); 355 const char *snd_pcm_stream_name(snd_pcm_stream_t stream); 356 const char *snd_pcm_access_name(const snd_pcm_access_t _access); 357 const char *snd_pcm_format_name(const snd_pcm_format_t format); 358 const char *snd_pcm_state_name(const snd_pcm_state_t state); 359 360 /* Direct Access (MMAP) functions */ 361 int snd_pcm_mmap_begin(snd_pcm_t *pcm, 362 const snd_pcm_channel_area_t **areas, 363 snd_pcm_uframes_t *offset, 364 snd_pcm_uframes_t *frames); 365 snd_pcm_sframes_t snd_pcm_mmap_commit(snd_pcm_t *pcm, 366 snd_pcm_uframes_t offset, 367 snd_pcm_uframes_t frames); 368 snd_pcm_sframes_t snd_pcm_mmap_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size); 369 snd_pcm_sframes_t snd_pcm_mmap_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size); 370 371 int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset, 372 unsigned int samples, snd_pcm_format_t format); 373 int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, 374 unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format); 375 int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_channel, snd_pcm_uframes_t dst_offset, 376 const snd_pcm_channel_area_t *src_channel, snd_pcm_uframes_t src_offset, 377 unsigned int samples, snd_pcm_format_t format); 378 int snd_pcm_areas_copy(const snd_pcm_channel_area_t *dst_channels, snd_pcm_uframes_t dst_offset, 379 const snd_pcm_channel_area_t *src_channels, snd_pcm_uframes_t src_offset, 380 unsigned int channels, snd_pcm_uframes_t frames, snd_pcm_format_t format); 381 382 #ifdef __cplusplus 383 } 384 #endif 385 386 #endif /* __AW_ALSA_PCM_H */ 387