"Fossies" - the Fresh Open Source Software Archive

Member "alsa-lib-1.1.9/src/pcm/pcm_direct.h" (10 May 2019, 12869 Bytes) of package /linux/misc/alsa-lib-1.1.9.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "pcm_direct.h" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.1.7_vs_1.1.8.

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