1d5ac70f0Sopenharmony_ci/* 2d5ac70f0Sopenharmony_ci * PCM - Direct Stream Mixing 3d5ac70f0Sopenharmony_ci * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz> 4d5ac70f0Sopenharmony_ci * 5d5ac70f0Sopenharmony_ci * 6d5ac70f0Sopenharmony_ci * This library is free software; you can redistribute it and/or modify 7d5ac70f0Sopenharmony_ci * it under the terms of the GNU Lesser General Public License as 8d5ac70f0Sopenharmony_ci * published by the Free Software Foundation; either version 2.1 of 9d5ac70f0Sopenharmony_ci * the License, or (at your option) any later version. 10d5ac70f0Sopenharmony_ci * 11d5ac70f0Sopenharmony_ci * This program is distributed in the hope that it will be useful, 12d5ac70f0Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13d5ac70f0Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14d5ac70f0Sopenharmony_ci * GNU Lesser General Public License for more details. 15d5ac70f0Sopenharmony_ci * 16d5ac70f0Sopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17d5ac70f0Sopenharmony_ci * License along with this library; if not, write to the Free Software 18d5ac70f0Sopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19d5ac70f0Sopenharmony_ci * 20d5ac70f0Sopenharmony_ci */ 21d5ac70f0Sopenharmony_ci 22d5ac70f0Sopenharmony_ci#include "pcm_local.h" 23d5ac70f0Sopenharmony_ci#include "../timer/timer_local.h" 24d5ac70f0Sopenharmony_ci 25d5ac70f0Sopenharmony_ci#define DIRECT_IPC_SEMS 1 26d5ac70f0Sopenharmony_ci#define DIRECT_IPC_SEM_CLIENT 0 27d5ac70f0Sopenharmony_ci/* Seconds representing in Milli seconds */ 28d5ac70f0Sopenharmony_ci#define SEC_TO_MS 1000 29d5ac70f0Sopenharmony_ci/* slave_period time for low latency requirements in ms */ 30d5ac70f0Sopenharmony_ci#define LOW_LATENCY_PERIOD_TIME 10 31d5ac70f0Sopenharmony_ci 32d5ac70f0Sopenharmony_ci 33d5ac70f0Sopenharmony_citypedef void (mix_areas_t)(unsigned int size, 34d5ac70f0Sopenharmony_ci volatile void *dst, void *src, 35d5ac70f0Sopenharmony_ci volatile signed int *sum, size_t dst_step, 36d5ac70f0Sopenharmony_ci size_t src_step, size_t sum_step); 37d5ac70f0Sopenharmony_ci 38d5ac70f0Sopenharmony_citypedef void (mix_areas_16_t)(unsigned int size, 39d5ac70f0Sopenharmony_ci volatile signed short *dst, signed short *src, 40d5ac70f0Sopenharmony_ci volatile signed int *sum, size_t dst_step, 41d5ac70f0Sopenharmony_ci size_t src_step, size_t sum_step); 42d5ac70f0Sopenharmony_ci 43d5ac70f0Sopenharmony_citypedef void (mix_areas_32_t)(unsigned int size, 44d5ac70f0Sopenharmony_ci volatile signed int *dst, signed int *src, 45d5ac70f0Sopenharmony_ci volatile signed int *sum, size_t dst_step, 46d5ac70f0Sopenharmony_ci size_t src_step, size_t sum_step); 47d5ac70f0Sopenharmony_ci 48d5ac70f0Sopenharmony_citypedef void (mix_areas_24_t)(unsigned int size, 49d5ac70f0Sopenharmony_ci volatile unsigned char *dst, unsigned char *src, 50d5ac70f0Sopenharmony_ci volatile signed int *sum, size_t dst_step, 51d5ac70f0Sopenharmony_ci size_t src_step, size_t sum_step); 52d5ac70f0Sopenharmony_ci 53d5ac70f0Sopenharmony_citypedef void (mix_areas_u8_t)(unsigned int size, 54d5ac70f0Sopenharmony_ci volatile unsigned char *dst, unsigned char *src, 55d5ac70f0Sopenharmony_ci volatile signed int *sum, size_t dst_step, 56d5ac70f0Sopenharmony_ci size_t src_step, size_t sum_step); 57d5ac70f0Sopenharmony_ci 58d5ac70f0Sopenharmony_citypedef enum snd_pcm_direct_hw_ptr_alignment { 59d5ac70f0Sopenharmony_ci SND_PCM_HW_PTR_ALIGNMENT_NO = 0, /* use the hw_ptr as is and do no rounding */ 60d5ac70f0Sopenharmony_ci SND_PCM_HW_PTR_ALIGNMENT_ROUNDUP = 1, /* round the slave_appl_ptr up to slave_period */ 61d5ac70f0Sopenharmony_ci SND_PCM_HW_PTR_ALIGNMENT_ROUNDDOWN = 2, /* round slave_hw_ptr and slave_appl_ptr down to slave_period */ 62d5ac70f0Sopenharmony_ci SND_PCM_HW_PTR_ALIGNMENT_AUTO = 3 /* automatic selection */ 63d5ac70f0Sopenharmony_ci} snd_pcm_direct_hw_ptr_alignment_t; 64d5ac70f0Sopenharmony_ci 65d5ac70f0Sopenharmony_cistruct slave_params { 66d5ac70f0Sopenharmony_ci snd_pcm_format_t format; 67d5ac70f0Sopenharmony_ci int rate; 68d5ac70f0Sopenharmony_ci int channels; 69d5ac70f0Sopenharmony_ci int period_time; 70d5ac70f0Sopenharmony_ci int buffer_time; 71d5ac70f0Sopenharmony_ci snd_pcm_sframes_t period_size; 72d5ac70f0Sopenharmony_ci snd_pcm_sframes_t buffer_size; 73d5ac70f0Sopenharmony_ci unsigned int periods; 74d5ac70f0Sopenharmony_ci}; 75d5ac70f0Sopenharmony_ci 76d5ac70f0Sopenharmony_ci/* shared among direct plugin clients - be careful to be 32/64bit compatible! */ 77d5ac70f0Sopenharmony_citypedef struct { 78d5ac70f0Sopenharmony_ci unsigned int magic; /* magic number */ 79d5ac70f0Sopenharmony_ci char socket_name[256]; /* name of communication socket */ 80d5ac70f0Sopenharmony_ci snd_pcm_type_t type; /* PCM type (currently only hw) */ 81d5ac70f0Sopenharmony_ci int use_server; 82d5ac70f0Sopenharmony_ci struct { 83d5ac70f0Sopenharmony_ci unsigned int format; 84d5ac70f0Sopenharmony_ci snd_interval_t rate; 85d5ac70f0Sopenharmony_ci snd_interval_t buffer_size; 86d5ac70f0Sopenharmony_ci snd_interval_t buffer_time; 87d5ac70f0Sopenharmony_ci snd_interval_t period_size; 88d5ac70f0Sopenharmony_ci snd_interval_t period_time; 89d5ac70f0Sopenharmony_ci snd_interval_t periods; 90d5ac70f0Sopenharmony_ci } hw; 91d5ac70f0Sopenharmony_ci struct { 92d5ac70f0Sopenharmony_ci /* copied to slave PCMs */ 93d5ac70f0Sopenharmony_ci snd_pcm_access_t access; 94d5ac70f0Sopenharmony_ci snd_pcm_format_t format; 95d5ac70f0Sopenharmony_ci snd_pcm_subformat_t subformat; 96d5ac70f0Sopenharmony_ci unsigned int channels; 97d5ac70f0Sopenharmony_ci unsigned int rate; 98d5ac70f0Sopenharmony_ci unsigned int period_size; 99d5ac70f0Sopenharmony_ci unsigned int period_time; 100d5ac70f0Sopenharmony_ci snd_interval_t periods; 101d5ac70f0Sopenharmony_ci snd_pcm_tstamp_t tstamp_mode; 102d5ac70f0Sopenharmony_ci snd_pcm_tstamp_type_t tstamp_type; 103d5ac70f0Sopenharmony_ci unsigned int period_step; 104d5ac70f0Sopenharmony_ci unsigned int sleep_min; /* not used */ 105d5ac70f0Sopenharmony_ci unsigned int avail_min; 106d5ac70f0Sopenharmony_ci unsigned int start_threshold; 107d5ac70f0Sopenharmony_ci unsigned int stop_threshold; 108d5ac70f0Sopenharmony_ci unsigned int silence_threshold; 109d5ac70f0Sopenharmony_ci unsigned int silence_size; 110d5ac70f0Sopenharmony_ci unsigned int recoveries; /* no of executed recoveries on slave*/ 111d5ac70f0Sopenharmony_ci unsigned long long boundary; 112d5ac70f0Sopenharmony_ci unsigned int info; 113d5ac70f0Sopenharmony_ci unsigned int msbits; 114d5ac70f0Sopenharmony_ci unsigned int rate_num; 115d5ac70f0Sopenharmony_ci unsigned int rate_den; 116d5ac70f0Sopenharmony_ci unsigned int hw_flags; 117d5ac70f0Sopenharmony_ci unsigned int fifo_size; 118d5ac70f0Sopenharmony_ci unsigned int buffer_size; 119d5ac70f0Sopenharmony_ci snd_interval_t buffer_time; 120d5ac70f0Sopenharmony_ci unsigned int sample_bits; 121d5ac70f0Sopenharmony_ci unsigned int frame_bits; 122d5ac70f0Sopenharmony_ci } s; 123d5ac70f0Sopenharmony_ci union { 124d5ac70f0Sopenharmony_ci struct { 125d5ac70f0Sopenharmony_ci unsigned long long chn_mask; 126d5ac70f0Sopenharmony_ci } dshare; 127d5ac70f0Sopenharmony_ci } u; 128d5ac70f0Sopenharmony_ci} snd_pcm_direct_share_t; 129d5ac70f0Sopenharmony_ci 130d5ac70f0Sopenharmony_citypedef struct snd_pcm_direct snd_pcm_direct_t; 131d5ac70f0Sopenharmony_ci 132d5ac70f0Sopenharmony_cistruct snd_pcm_direct { 133d5ac70f0Sopenharmony_ci snd_pcm_type_t type; /* type (dmix, dsnoop, dshare) */ 134d5ac70f0Sopenharmony_ci key_t ipc_key; /* IPC key for semaphore and memory */ 135d5ac70f0Sopenharmony_ci mode_t ipc_perm; /* IPC socket permissions */ 136d5ac70f0Sopenharmony_ci int ipc_gid; /* IPC socket gid */ 137d5ac70f0Sopenharmony_ci int semid; /* IPC global semaphore identification */ 138d5ac70f0Sopenharmony_ci int locked[DIRECT_IPC_SEMS]; /* local lock counter */ 139d5ac70f0Sopenharmony_ci int shmid; /* IPC global shared memory identification */ 140d5ac70f0Sopenharmony_ci snd_pcm_direct_share_t *shmptr; /* pointer to shared memory area */ 141d5ac70f0Sopenharmony_ci snd_pcm_t *spcm; /* slave PCM handle */ 142d5ac70f0Sopenharmony_ci snd_pcm_uframes_t appl_ptr; 143d5ac70f0Sopenharmony_ci snd_pcm_uframes_t last_appl_ptr; 144d5ac70f0Sopenharmony_ci snd_pcm_uframes_t hw_ptr; 145d5ac70f0Sopenharmony_ci snd_pcm_uframes_t avail_max; 146d5ac70f0Sopenharmony_ci snd_pcm_uframes_t slave_appl_ptr; 147d5ac70f0Sopenharmony_ci snd_pcm_uframes_t slave_hw_ptr; 148d5ac70f0Sopenharmony_ci snd_pcm_uframes_t slave_period_size; 149d5ac70f0Sopenharmony_ci snd_pcm_uframes_t slave_buffer_size; 150d5ac70f0Sopenharmony_ci snd_pcm_uframes_t slave_boundary; 151d5ac70f0Sopenharmony_ci int (*sync_ptr)(snd_pcm_t *pcm); 152d5ac70f0Sopenharmony_ci snd_pcm_state_t state; 153d5ac70f0Sopenharmony_ci snd_htimestamp_t trigger_tstamp; 154d5ac70f0Sopenharmony_ci snd_htimestamp_t update_tstamp; 155d5ac70f0Sopenharmony_ci int server, client; 156d5ac70f0Sopenharmony_ci int comm_fd; /* communication file descriptor (socket) */ 157d5ac70f0Sopenharmony_ci int hw_fd; /* hardware file descriptor */ 158d5ac70f0Sopenharmony_ci struct pollfd timer_fd; 159d5ac70f0Sopenharmony_ci int poll_fd; 160d5ac70f0Sopenharmony_ci int tread: 1; 161d5ac70f0Sopenharmony_ci int timer_need_poll: 1; 162d5ac70f0Sopenharmony_ci unsigned int timer_events; 163d5ac70f0Sopenharmony_ci unsigned int timer_ticks; 164d5ac70f0Sopenharmony_ci int server_fd; 165d5ac70f0Sopenharmony_ci pid_t server_pid; 166d5ac70f0Sopenharmony_ci snd_timer_t *timer; /* timer used as poll_fd */ 167d5ac70f0Sopenharmony_ci int interleaved; /* we have interleaved buffer */ 168d5ac70f0Sopenharmony_ci int slowptr; /* use slow but more precise ptr updates */ 169d5ac70f0Sopenharmony_ci int max_periods; /* max periods (-1 = fixed periods, 0 = max buffer size) */ 170d5ac70f0Sopenharmony_ci int var_periodsize; /* allow variable period size if max_periods is != -1*/ 171d5ac70f0Sopenharmony_ci unsigned int channels; /* client's channels */ 172d5ac70f0Sopenharmony_ci unsigned int *bindings; 173d5ac70f0Sopenharmony_ci unsigned int recoveries; /* mirror of executed recoveries on slave */ 174d5ac70f0Sopenharmony_ci int direct_memory_access; /* use arch-optimized buffer RW */ 175d5ac70f0Sopenharmony_ci snd_pcm_direct_hw_ptr_alignment_t hw_ptr_alignment; 176d5ac70f0Sopenharmony_ci int tstamp_type; /* cached from conf, can be -1(default) on top of real types */ 177d5ac70f0Sopenharmony_ci union { 178d5ac70f0Sopenharmony_ci struct { 179d5ac70f0Sopenharmony_ci int shmid_sum; /* IPC global sum ring buffer memory identification */ 180d5ac70f0Sopenharmony_ci signed int *sum_buffer; /* shared sum buffer */ 181d5ac70f0Sopenharmony_ci mix_areas_16_t *mix_areas_16; 182d5ac70f0Sopenharmony_ci mix_areas_32_t *mix_areas_32; 183d5ac70f0Sopenharmony_ci mix_areas_24_t *mix_areas_24; 184d5ac70f0Sopenharmony_ci mix_areas_u8_t *mix_areas_u8; 185d5ac70f0Sopenharmony_ci mix_areas_16_t *remix_areas_16; 186d5ac70f0Sopenharmony_ci mix_areas_32_t *remix_areas_32; 187d5ac70f0Sopenharmony_ci mix_areas_24_t *remix_areas_24; 188d5ac70f0Sopenharmony_ci mix_areas_u8_t *remix_areas_u8; 189d5ac70f0Sopenharmony_ci unsigned int use_sem; 190d5ac70f0Sopenharmony_ci } dmix; 191d5ac70f0Sopenharmony_ci struct { 192d5ac70f0Sopenharmony_ci unsigned long long chn_mask; 193d5ac70f0Sopenharmony_ci } dshare; 194d5ac70f0Sopenharmony_ci } u; 195d5ac70f0Sopenharmony_ci void (*server_free)(snd_pcm_direct_t *direct); 196d5ac70f0Sopenharmony_ci}; 197d5ac70f0Sopenharmony_ci 198d5ac70f0Sopenharmony_ci/* make local functions really local */ 199d5ac70f0Sopenharmony_ci#define snd_pcm_direct_semaphore_create_or_connect \ 200d5ac70f0Sopenharmony_ci snd1_pcm_direct_semaphore_create_or_connect 201d5ac70f0Sopenharmony_ci#define snd_pcm_direct_shm_create_or_connect \ 202d5ac70f0Sopenharmony_ci snd1_pcm_direct_shm_create_or_connect 203d5ac70f0Sopenharmony_ci#define snd_pcm_direct_shm_discard \ 204d5ac70f0Sopenharmony_ci snd1_pcm_direct_shm_discard 205d5ac70f0Sopenharmony_ci#define snd_pcm_direct_server_create \ 206d5ac70f0Sopenharmony_ci snd1_pcm_direct_server_create 207d5ac70f0Sopenharmony_ci#define snd_pcm_direct_server_discard \ 208d5ac70f0Sopenharmony_ci snd1_pcm_direct_server_discard 209d5ac70f0Sopenharmony_ci#define snd_pcm_direct_client_connect \ 210d5ac70f0Sopenharmony_ci snd1_pcm_direct_client_connect 211d5ac70f0Sopenharmony_ci#define snd_pcm_direct_client_discard \ 212d5ac70f0Sopenharmony_ci snd1_pcm_direct_client_discard 213d5ac70f0Sopenharmony_ci#define snd_pcm_direct_initialize_slave \ 214d5ac70f0Sopenharmony_ci snd1_pcm_direct_initialize_slave 215d5ac70f0Sopenharmony_ci#define snd_pcm_direct_initialize_secondary_slave \ 216d5ac70f0Sopenharmony_ci snd1_pcm_direct_initialize_secondary_slave 217d5ac70f0Sopenharmony_ci#define snd_pcm_direct_initialize_poll_fd \ 218d5ac70f0Sopenharmony_ci snd1_pcm_direct_initialize_poll_fd 219d5ac70f0Sopenharmony_ci#define snd_pcm_direct_check_interleave \ 220d5ac70f0Sopenharmony_ci snd1_pcm_direct_check_interleave 221d5ac70f0Sopenharmony_ci#define snd_pcm_direct_parse_bindings \ 222d5ac70f0Sopenharmony_ci snd1_pcm_direct_parse_bindings 223d5ac70f0Sopenharmony_ci#define snd_pcm_direct_nonblock \ 224d5ac70f0Sopenharmony_ci snd1_pcm_direct_nonblock 225d5ac70f0Sopenharmony_ci#define snd_pcm_direct_async \ 226d5ac70f0Sopenharmony_ci snd1_pcm_direct_async 227d5ac70f0Sopenharmony_ci#define snd_pcm_direct_poll_descriptors \ 228d5ac70f0Sopenharmony_ci snd1_pcm_direct_poll_descriptors 229d5ac70f0Sopenharmony_ci#define snd_pcm_direct_poll_revents \ 230d5ac70f0Sopenharmony_ci snd1_pcm_direct_poll_revents 231d5ac70f0Sopenharmony_ci#define snd_pcm_direct_info \ 232d5ac70f0Sopenharmony_ci snd1_pcm_direct_info 233d5ac70f0Sopenharmony_ci#define snd_pcm_direct_hw_refine \ 234d5ac70f0Sopenharmony_ci snd1_pcm_direct_hw_refine 235d5ac70f0Sopenharmony_ci#define snd_pcm_direct_hw_params \ 236d5ac70f0Sopenharmony_ci snd1_pcm_direct_hw_params 237d5ac70f0Sopenharmony_ci#define snd_pcm_direct_hw_free \ 238d5ac70f0Sopenharmony_ci snd1_pcm_direct_hw_free 239d5ac70f0Sopenharmony_ci#define snd_pcm_direct_sw_params \ 240d5ac70f0Sopenharmony_ci snd1_pcm_direct_sw_params 241d5ac70f0Sopenharmony_ci#define snd_pcm_direct_channel_info \ 242d5ac70f0Sopenharmony_ci snd1_pcm_direct_channel_info 243d5ac70f0Sopenharmony_ci#define snd_pcm_direct_mmap \ 244d5ac70f0Sopenharmony_ci snd1_pcm_direct_mmap 245d5ac70f0Sopenharmony_ci#define snd_pcm_direct_munmap \ 246d5ac70f0Sopenharmony_ci snd1_pcm_direct_munmap 247d5ac70f0Sopenharmony_ci#define snd_pcm_direct_prepare \ 248d5ac70f0Sopenharmony_ci snd1_pcm_direct_prepare 249d5ac70f0Sopenharmony_ci#define snd_pcm_direct_resume \ 250d5ac70f0Sopenharmony_ci snd1_pcm_direct_resume 251d5ac70f0Sopenharmony_ci#define snd_pcm_direct_timer_stop \ 252d5ac70f0Sopenharmony_ci snd1_pcm_direct_timer_stop 253d5ac70f0Sopenharmony_ci#define snd_pcm_direct_clear_timer_queue \ 254d5ac70f0Sopenharmony_ci snd1_pcm_direct_clear_timer_queue 255d5ac70f0Sopenharmony_ci#define snd_pcm_direct_set_timer_params \ 256d5ac70f0Sopenharmony_ci snd1_pcm_direct_set_timer_params 257d5ac70f0Sopenharmony_ci#define snd_pcm_direct_open_secondary_client \ 258d5ac70f0Sopenharmony_ci snd1_pcm_direct_open_secondary_client 259d5ac70f0Sopenharmony_ci#define snd_pcm_direct_parse_open_conf \ 260d5ac70f0Sopenharmony_ci snd1_pcm_direct_parse_open_conf 261d5ac70f0Sopenharmony_ci#define snd_pcm_direct_query_chmaps \ 262d5ac70f0Sopenharmony_ci snd1_pcm_direct_query_chmaps 263d5ac70f0Sopenharmony_ci#define snd_pcm_direct_get_chmap \ 264d5ac70f0Sopenharmony_ci snd1_pcm_direct_get_chmap 265d5ac70f0Sopenharmony_ci#define snd_pcm_direct_set_chmap \ 266d5ac70f0Sopenharmony_ci snd1_pcm_direct_set_chmap 267d5ac70f0Sopenharmony_ci#define snd_pcm_direct_reset_slave_ptr \ 268d5ac70f0Sopenharmony_ci snd1_pcm_direct_reset_slave_ptr 269d5ac70f0Sopenharmony_ci#define snd_pcm_direct_check_xrun \ 270d5ac70f0Sopenharmony_ci snd1_pcm_direct_check_xrun 271d5ac70f0Sopenharmony_ci#define snd_pcm_direct_slave_recover \ 272d5ac70f0Sopenharmony_ci snd1_pcm_direct_slave_recover 273d5ac70f0Sopenharmony_ci 274d5ac70f0Sopenharmony_ciint snd_pcm_direct_semaphore_create_or_connect(snd_pcm_direct_t *dmix); 275d5ac70f0Sopenharmony_ci 276d5ac70f0Sopenharmony_cistatic inline int snd_pcm_direct_semaphore_discard(snd_pcm_direct_t *dmix) 277d5ac70f0Sopenharmony_ci{ 278d5ac70f0Sopenharmony_ci if (dmix->semid >= 0) { 279d5ac70f0Sopenharmony_ci if (semctl(dmix->semid, 0, IPC_RMID, NULL) < 0) 280d5ac70f0Sopenharmony_ci return -errno; 281d5ac70f0Sopenharmony_ci dmix->semid = -1; 282d5ac70f0Sopenharmony_ci } 283d5ac70f0Sopenharmony_ci return 0; 284d5ac70f0Sopenharmony_ci} 285d5ac70f0Sopenharmony_ci 286d5ac70f0Sopenharmony_cistatic inline int snd_pcm_direct_semaphore_down(snd_pcm_direct_t *dmix, int sem_num) 287d5ac70f0Sopenharmony_ci{ 288d5ac70f0Sopenharmony_ci struct sembuf op[2] = { { sem_num, 0, 0 }, { sem_num, 1, SEM_UNDO } }; 289d5ac70f0Sopenharmony_ci int err = semop(dmix->semid, op, 2); 290d5ac70f0Sopenharmony_ci if (err == 0) 291d5ac70f0Sopenharmony_ci dmix->locked[sem_num]++; 292d5ac70f0Sopenharmony_ci else if (err == -1) 293d5ac70f0Sopenharmony_ci err = -errno; 294d5ac70f0Sopenharmony_ci return err; 295d5ac70f0Sopenharmony_ci} 296d5ac70f0Sopenharmony_ci 297d5ac70f0Sopenharmony_cistatic inline int snd_pcm_direct_semaphore_up(snd_pcm_direct_t *dmix, int sem_num) 298d5ac70f0Sopenharmony_ci{ 299d5ac70f0Sopenharmony_ci struct sembuf op = { sem_num, -1, SEM_UNDO | IPC_NOWAIT }; 300d5ac70f0Sopenharmony_ci int err = semop(dmix->semid, &op, 1); 301d5ac70f0Sopenharmony_ci if (err == 0) 302d5ac70f0Sopenharmony_ci dmix->locked[sem_num]--; 303d5ac70f0Sopenharmony_ci else if (err == -1) 304d5ac70f0Sopenharmony_ci err = -errno; 305d5ac70f0Sopenharmony_ci return err; 306d5ac70f0Sopenharmony_ci} 307d5ac70f0Sopenharmony_ci 308d5ac70f0Sopenharmony_cistatic inline int snd_pcm_direct_semaphore_final(snd_pcm_direct_t *dmix, int sem_num) 309d5ac70f0Sopenharmony_ci{ 310d5ac70f0Sopenharmony_ci if (dmix->locked[sem_num] != 1) { 311d5ac70f0Sopenharmony_ci SNDMSG("invalid semaphore count to finalize %d: %d", sem_num, dmix->locked[sem_num]); 312d5ac70f0Sopenharmony_ci return -EBUSY; 313d5ac70f0Sopenharmony_ci } 314d5ac70f0Sopenharmony_ci return snd_pcm_direct_semaphore_up(dmix, sem_num); 315d5ac70f0Sopenharmony_ci} 316d5ac70f0Sopenharmony_ci 317d5ac70f0Sopenharmony_ciint snd_pcm_direct_shm_create_or_connect(snd_pcm_direct_t *dmix); 318d5ac70f0Sopenharmony_ciint snd_pcm_direct_shm_discard(snd_pcm_direct_t *dmix); 319d5ac70f0Sopenharmony_ciint snd_pcm_direct_server_create(snd_pcm_direct_t *dmix); 320d5ac70f0Sopenharmony_ciint snd_pcm_direct_server_discard(snd_pcm_direct_t *dmix); 321d5ac70f0Sopenharmony_ciint snd_pcm_direct_client_connect(snd_pcm_direct_t *dmix); 322d5ac70f0Sopenharmony_ciint snd_pcm_direct_client_discard(snd_pcm_direct_t *dmix); 323d5ac70f0Sopenharmony_ciint snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, struct slave_params *params); 324d5ac70f0Sopenharmony_ciint snd_pcm_direct_initialize_secondary_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, struct slave_params *params); 325d5ac70f0Sopenharmony_ciint snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix); 326d5ac70f0Sopenharmony_ciint snd_pcm_direct_check_interleave(snd_pcm_direct_t *dmix, snd_pcm_t *pcm); 327d5ac70f0Sopenharmony_ciint snd_pcm_direct_parse_bindings(snd_pcm_direct_t *dmix, 328d5ac70f0Sopenharmony_ci struct slave_params *params, 329d5ac70f0Sopenharmony_ci snd_config_t *cfg); 330d5ac70f0Sopenharmony_ciint snd_pcm_direct_nonblock(snd_pcm_t *pcm, int nonblock); 331d5ac70f0Sopenharmony_ciint snd_pcm_direct_async(snd_pcm_t *pcm, int sig, pid_t pid); 332d5ac70f0Sopenharmony_ciint snd_pcm_direct_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, 333d5ac70f0Sopenharmony_ci unsigned int space); 334d5ac70f0Sopenharmony_ciint snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); 335d5ac70f0Sopenharmony_ciint snd_pcm_direct_info(snd_pcm_t *pcm, snd_pcm_info_t * info); 336d5ac70f0Sopenharmony_ciint snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); 337d5ac70f0Sopenharmony_ciint snd_pcm_direct_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params); 338d5ac70f0Sopenharmony_ciint snd_pcm_direct_hw_free(snd_pcm_t *pcm); 339d5ac70f0Sopenharmony_ciint snd_pcm_direct_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params); 340d5ac70f0Sopenharmony_ciint snd_pcm_direct_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info); 341d5ac70f0Sopenharmony_ciint snd_pcm_direct_mmap(snd_pcm_t *pcm); 342d5ac70f0Sopenharmony_ciint snd_pcm_direct_munmap(snd_pcm_t *pcm); 343d5ac70f0Sopenharmony_ciint snd_pcm_direct_prepare(snd_pcm_t *pcm); 344d5ac70f0Sopenharmony_ciint snd_pcm_direct_resume(snd_pcm_t *pcm); 345d5ac70f0Sopenharmony_ciint snd_pcm_direct_timer_stop(snd_pcm_direct_t *dmix); 346d5ac70f0Sopenharmony_ciint snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix); 347d5ac70f0Sopenharmony_ciint snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix); 348d5ac70f0Sopenharmony_ciint snd_pcm_direct_open_secondary_client(snd_pcm_t **spcmp, snd_pcm_direct_t *dmix, const char *client_name); 349d5ac70f0Sopenharmony_ci 350d5ac70f0Sopenharmony_cisnd_pcm_chmap_query_t **snd_pcm_direct_query_chmaps(snd_pcm_t *pcm); 351d5ac70f0Sopenharmony_cisnd_pcm_chmap_t *snd_pcm_direct_get_chmap(snd_pcm_t *pcm); 352d5ac70f0Sopenharmony_ciint snd_pcm_direct_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map); 353d5ac70f0Sopenharmony_ciint snd_pcm_direct_slave_recover(snd_pcm_direct_t *direct); 354d5ac70f0Sopenharmony_ciint snd_pcm_direct_check_xrun(snd_pcm_direct_t *direct, snd_pcm_t *pcm); 355d5ac70f0Sopenharmony_ciint snd_timer_async(snd_timer_t *timer, int sig, pid_t pid); 356d5ac70f0Sopenharmony_cistruct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm); 357d5ac70f0Sopenharmony_civoid snd_pcm_direct_reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix, snd_pcm_uframes_t hw_ptr); 358d5ac70f0Sopenharmony_ci 359d5ac70f0Sopenharmony_cistruct snd_pcm_direct_open_conf { 360d5ac70f0Sopenharmony_ci key_t ipc_key; 361d5ac70f0Sopenharmony_ci mode_t ipc_perm; 362d5ac70f0Sopenharmony_ci int ipc_gid; 363d5ac70f0Sopenharmony_ci int slowptr; 364d5ac70f0Sopenharmony_ci int max_periods; 365d5ac70f0Sopenharmony_ci int var_periodsize; 366d5ac70f0Sopenharmony_ci int direct_memory_access; 367d5ac70f0Sopenharmony_ci snd_pcm_direct_hw_ptr_alignment_t hw_ptr_alignment; 368d5ac70f0Sopenharmony_ci int tstamp_type; 369d5ac70f0Sopenharmony_ci snd_config_t *slave; 370d5ac70f0Sopenharmony_ci snd_config_t *bindings; 371d5ac70f0Sopenharmony_ci}; 372d5ac70f0Sopenharmony_ci 373d5ac70f0Sopenharmony_ciint snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf, int stream, struct snd_pcm_direct_open_conf *rec); 374d5ac70f0Sopenharmony_ci 375d5ac70f0Sopenharmony_ciint _snd_pcm_direct_new(snd_pcm_t **pcmp, snd_pcm_direct_t **_dmix, int type, 376d5ac70f0Sopenharmony_ci const char *name, struct snd_pcm_direct_open_conf *opts, 377d5ac70f0Sopenharmony_ci struct slave_params *params, snd_pcm_stream_t stream, int mode); 378