OSDN Git Service

dmix - Allow more flexible buffer sizes
[android-x86/external-alsa-lib.git] / src / pcm / pcm_direct.h
1 /*
2  *  PCM - Direct Stream Mixing
3  *  Copyright (c) 2003 by Jaroslav Kysela <perex@suse.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  *
20  */
21
22 #include "pcm_local.h"  
23
24 #define DIRECT_IPC_SEMS         1
25 #define DIRECT_IPC_SEM_CLIENT   0
26
27 typedef void (mix_areas1_t)(unsigned int size,
28                         volatile signed short *dst, signed short *src,
29                         volatile signed int *sum, size_t dst_step,
30                         size_t src_step, size_t sum_step);
31
32 typedef void (mix_areas2_t)(unsigned int size,
33                         volatile signed int *dst, signed int *src,
34                         volatile signed int *sum, size_t dst_step,
35                         size_t src_step, size_t sum_step);
36
37 typedef void (mix_areas3_t)(unsigned int size,
38                         volatile unsigned char *dst, unsigned char *src,
39                         volatile signed int *sum, size_t dst_step,
40                         size_t src_step, size_t sum_step);
41
42 struct slave_params {
43         snd_pcm_format_t format;
44         int rate;
45         int channels;
46         int period_time;
47         int buffer_time;
48         snd_pcm_sframes_t period_size;
49         snd_pcm_sframes_t buffer_size;
50         unsigned int periods;
51 };
52
53 typedef struct {
54         char socket_name[256];                  /* name of communication socket */
55         snd_pcm_type_t type;                    /* PCM type (currently only hw) */
56         struct {
57                 unsigned int format;
58                 snd_interval_t rate;
59                 snd_interval_t buffer_size;
60                 snd_interval_t buffer_time;
61                 snd_interval_t period_size;
62                 snd_interval_t period_time;
63                 snd_interval_t periods;
64         } hw;
65         struct {
66                 unsigned int buffer_size;
67                 unsigned int period_size;
68                 unsigned long long boundary;
69                 unsigned int channels;
70                 unsigned int sample_bits;
71                 unsigned int rate;
72                 snd_pcm_format_t format;
73                 unsigned int info;
74                 unsigned int msbits;
75         } s;
76         union {
77                 struct {
78                         unsigned long long chn_mask;
79                 } dshare;
80         } u;
81 } snd_pcm_direct_share_t;
82
83 typedef struct snd_pcm_direct snd_pcm_direct_t;
84
85 struct snd_pcm_direct {
86         snd_pcm_type_t type;            /* type (dmix, dsnoop, dshare) */
87         key_t ipc_key;                  /* IPC key for semaphore and memory */
88         mode_t ipc_perm;                /* IPC socket permissions */
89         int ipc_gid;                    /* IPC socket gid */
90         int semid;                      /* IPC global semaphore identification */
91         int shmid;                      /* IPC global shared memory identification */
92         snd_pcm_direct_share_t *shmptr; /* pointer to shared memory area */
93         snd_pcm_t *spcm;                /* slave PCM handle */
94         snd_pcm_uframes_t appl_ptr;
95         snd_pcm_uframes_t last_appl_ptr;
96         snd_pcm_uframes_t hw_ptr;
97         snd_pcm_uframes_t avail_max;
98         snd_pcm_uframes_t slave_appl_ptr;
99         snd_pcm_uframes_t slave_hw_ptr;
100         snd_pcm_uframes_t slave_period_size;
101         snd_pcm_uframes_t slave_buffer_size;
102         snd_pcm_uframes_t slave_boundary;
103         int (*sync_ptr)(snd_pcm_t *pcm);
104         snd_pcm_state_t state;
105         snd_htimestamp_t trigger_tstamp;
106         int server, client;
107         int comm_fd;                    /* communication file descriptor (socket) */
108         int hw_fd;                      /* hardware file descriptor */
109         struct pollfd timer_fd;
110         int poll_fd;
111         int tread;
112         int timer_need_poll;
113         unsigned int timer_event_suspend;
114         unsigned int timer_event_resume;
115         int server_fd;
116         pid_t server_pid;
117         snd_timer_t *timer;             /* timer used as poll_fd */
118         int interleaved;                /* we have interleaved buffer */
119         int slowptr;                    /* use slow but more precise ptr updates */
120         int variable_buffer_size;       /* allow the variable buffer size */
121         unsigned int channels;          /* client's channels */
122         unsigned int *bindings;
123         union {
124                 struct {
125                         int shmid_sum;                  /* IPC global sum ring buffer memory identification */
126                         signed int *sum_buffer;         /* shared sum buffer */
127                         mix_areas1_t *mix_areas1;
128                         mix_areas2_t *mix_areas2;
129                         mix_areas3_t *mix_areas3;
130                 } dmix;
131                 struct {
132                 } dsnoop;
133                 struct {
134                         unsigned long long chn_mask;
135                 } dshare;
136         } u;
137         void (*server_free)(snd_pcm_direct_t *direct);
138 };
139
140 int snd_pcm_direct_semaphore_create_or_connect(snd_pcm_direct_t *dmix);
141
142 static inline int snd_pcm_direct_semaphore_discard(snd_pcm_direct_t *dmix)
143 {
144         if (dmix->semid >= 0) {
145                 if (semctl(dmix->semid, 0, IPC_RMID, NULL) < 0)
146                         return -errno;
147                 dmix->semid = -1;
148         }
149         return 0;
150 }
151
152 static inline int snd_pcm_direct_semaphore_down(snd_pcm_direct_t *dmix, int sem_num)
153 {
154         struct sembuf op[2] = { { sem_num, 0, 0 }, { sem_num, 1, SEM_UNDO } };
155         return semop(dmix->semid, op, 2);
156 }
157
158 static inline int snd_pcm_direct_semaphore_up(snd_pcm_direct_t *dmix, int sem_num)
159 {
160         struct sembuf op = { sem_num, -1, SEM_UNDO | IPC_NOWAIT };
161         return semop(dmix->semid, &op, 1);
162 }
163
164 int snd_pcm_direct_shm_create_or_connect(snd_pcm_direct_t *dmix);
165 int snd_pcm_direct_shm_discard(snd_pcm_direct_t *dmix);
166 int snd_pcm_direct_server_create(snd_pcm_direct_t *dmix);
167 int snd_pcm_direct_server_discard(snd_pcm_direct_t *dmix);
168 int snd_pcm_direct_client_connect(snd_pcm_direct_t *dmix);
169 int snd_pcm_direct_client_discard(snd_pcm_direct_t *dmix);
170 int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, struct slave_params *params);
171 int snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix);
172 int snd_pcm_direct_check_interleave(snd_pcm_direct_t *dmix, snd_pcm_t *pcm);
173 int snd_pcm_direct_parse_bindings(snd_pcm_direct_t *dmix, snd_config_t *cfg);
174 int snd_pcm_direct_nonblock(snd_pcm_t *pcm, int nonblock);
175 int snd_pcm_direct_async(snd_pcm_t *pcm, int sig, pid_t pid);
176 int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
177 int snd_pcm_direct_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
178 int snd_pcm_direct_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
179 int snd_pcm_direct_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params);
180 int snd_pcm_direct_hw_free(snd_pcm_t *pcm);
181 int snd_pcm_direct_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params);
182 int snd_pcm_direct_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
183 int snd_pcm_direct_mmap(snd_pcm_t *pcm);
184 int snd_pcm_direct_munmap(snd_pcm_t *pcm);
185 int snd_pcm_direct_resume(snd_pcm_t *pcm);
186 int snd_pcm_direct_timer_stop(snd_pcm_direct_t *dmix);
187 void snd_pcm_direct_clear_timer_queue(snd_pcm_direct_t *dmix);
188 int snd_pcm_direct_set_timer_params(snd_pcm_direct_t *dmix);
189 int snd_pcm_direct_open_secondary_client(snd_pcm_t **spcmp, snd_pcm_direct_t *dmix, const char *client_name);
190 int snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root, snd_config_t *sconf, int direction);
191
192 int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid);
193 struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm);
194
195 struct snd_pcm_direct_open_conf {
196         key_t ipc_key;
197         mode_t ipc_perm;
198         int ipc_gid;
199         int slowptr;
200         int variable_buffer_size;
201         snd_config_t *slave;
202         snd_config_t *bindings;
203 };
204
205 int snd_pcm_direct_parse_open_conf(snd_config_t *conf, struct snd_pcm_direct_open_conf *rec);