Initial Import
[profile/ivi/alsa-lib.git] / src / pcm / pcm_share.c
1 /**
2  * \file pcm/pcm_share.c
3  * \ingroup PCM_Plugins
4  * \brief PCM Share Plugin Interface
5  * \author Abramo Bagnara <abramo@alsa-project.org>
6  * \date 2000-2001
7  */
8 /*
9  *  PCM - Share
10  *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
11  *
12  *
13  *   This library is free software; you can redistribute it and/or modify
14  *   it under the terms of the GNU Lesser General Public License as
15  *   published by the Free Software Foundation; either version 2.1 of
16  *   the License, or (at your option) any later version.
17  *
18  *   This program is distributed in the hope that it will be useful,
19  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *   GNU Lesser General Public License for more details.
22  *
23  *   You should have received a copy of the GNU Lesser General Public
24  *   License along with this library; if not, write to the Free Software
25  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
26  *
27  */
28   
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <limits.h>
32 #include <unistd.h>
33 #include <string.h>
34 #include <signal.h>
35 #include <math.h>
36 #include <sys/socket.h>
37 #include <sys/poll.h>
38 #include <sys/shm.h>
39 #include <pthread.h>
40 #include "pcm_local.h"
41
42 #ifndef PIC
43 /* entry for static linking */
44 const char *_snd_module_pcm_share = "";
45 #endif
46
47 #ifndef DOC_HIDDEN
48
49 static LIST_HEAD(snd_pcm_share_slaves);
50 static pthread_mutex_t snd_pcm_share_slaves_mutex = PTHREAD_MUTEX_INITIALIZER;
51
52 #ifdef MUTEX_DEBUG
53 #define Pthread_mutex_lock(mutex) \
54 char *snd_pcm_share_slaves_mutex_holder;
55 do { \
56         int err = pthread_mutex_trylock(mutex); \
57         if (err < 0) { \
58                 fprintf(stderr, "lock " #mutex " is busy (%s): waiting in " __FUNCTION__ "\n", *(mutex##_holder)); \
59                 pthread_mutex_lock(mutex); \
60                 fprintf(stderr, "... got\n"); \
61         } \
62         *(mutex##_holder) = __FUNCTION__; \
63 } while (0)
64
65 #define Pthread_mutex_unlock(mutex) \
66 do { \
67         *(mutex##_holder) = 0; \
68         pthread_mutex_unlock(mutex); \
69 } while (0)
70 #else
71 #define Pthread_mutex_lock(mutex) pthread_mutex_lock(mutex)
72 #define Pthread_mutex_unlock(mutex) pthread_mutex_unlock(mutex)
73 #endif
74
75 typedef struct {
76         struct list_head clients;
77         struct list_head list;
78         snd_pcm_t *pcm;
79         snd_pcm_format_t format;
80         int rate;
81         unsigned int channels;
82         snd_pcm_sframes_t period_time;
83         snd_pcm_sframes_t buffer_time;
84         unsigned int open_count;
85         unsigned int setup_count;
86         unsigned int prepared_count;
87         unsigned int running_count;
88         snd_pcm_uframes_t safety_threshold;
89         snd_pcm_uframes_t silence_frames;
90         snd_pcm_sw_params_t sw_params;
91         snd_pcm_uframes_t hw_ptr;
92         int poll[2];
93         int polling;
94         pthread_t thread;
95         pthread_mutex_t mutex;
96 #ifdef MUTEX_DEBUG
97         char *mutex_holder;
98 #endif
99         pthread_cond_t poll_cond;
100 } snd_pcm_share_slave_t;
101
102 typedef struct {
103         struct list_head list;
104         snd_pcm_t *pcm;
105         snd_pcm_share_slave_t *slave;
106         unsigned int channels;
107         unsigned int *slave_channels;
108         int drain_silenced;
109         snd_htimestamp_t trigger_tstamp;
110         snd_pcm_state_t state;
111         snd_pcm_uframes_t hw_ptr;
112         snd_pcm_uframes_t appl_ptr;
113         int ready;
114         int client_socket;
115         int slave_socket;
116 } snd_pcm_share_t;
117
118 #endif /* DOC_HIDDEN */
119
120 static void _snd_pcm_share_stop(snd_pcm_t *pcm, snd_pcm_state_t state);
121
122 static snd_pcm_uframes_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
123 {
124         snd_pcm_sframes_t avail;
125         snd_pcm_t *pcm = slave->pcm;
126         avail = slave->hw_ptr - *pcm->appl.ptr;
127         if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
128                 avail += pcm->buffer_size;
129         if (avail < 0)
130                 avail += pcm->boundary;
131         return avail;
132 }
133
134 /* Warning: take the mutex before to call this */
135 /* Return number of frames to mmap_commit the slave */
136 static snd_pcm_uframes_t _snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
137 {
138         struct list_head *i;
139         snd_pcm_uframes_t buffer_size, boundary;
140         snd_pcm_uframes_t slave_appl_ptr;
141         snd_pcm_sframes_t frames, safety_frames;
142         snd_pcm_sframes_t min_frames, max_frames;
143         snd_pcm_uframes_t avail, slave_avail;
144         snd_pcm_uframes_t slave_hw_avail;
145         slave_avail = snd_pcm_share_slave_avail(slave);
146         boundary = slave->pcm->boundary;
147         buffer_size = slave->pcm->buffer_size;
148         min_frames = slave_avail;
149         max_frames = 0;
150         slave_appl_ptr = *slave->pcm->appl.ptr;
151         list_for_each(i, &slave->clients) {
152                 snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
153                 snd_pcm_t *pcm = share->pcm;
154                 switch (share->state) {
155                 case SND_PCM_STATE_RUNNING:
156                         break;
157                 case SND_PCM_STATE_DRAINING:
158                         if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
159                                 continue;
160                         break;
161                 default:
162                         continue;
163                 }
164                 avail = snd_pcm_mmap_avail(pcm);
165                 frames = slave_avail - avail;
166                 if (frames > max_frames)
167                         max_frames = frames;
168                 if (share->state != SND_PCM_STATE_RUNNING)
169                         continue;
170                 if (frames < min_frames)
171                         min_frames = frames;
172         }
173         if (max_frames == 0)
174                 return 0;
175         frames = min_frames;
176         /* Slave xrun prevention */
177         slave_hw_avail = buffer_size - slave_avail;
178         safety_frames = slave->safety_threshold - slave_hw_avail;
179         if (safety_frames > 0 &&
180             frames < safety_frames) {
181                 /* Avoid to pass over the last */
182                 if (max_frames < safety_frames)
183                         frames = max_frames;
184                 else
185                         frames = safety_frames;
186         }
187         if (frames < 0)
188                 return 0;
189         return frames;
190 }
191
192
193 /* 
194    - stop PCM on xrun
195    - update poll status
196    - draining silencing
197    - return distance in frames to next event
198 */
199 static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm)
200 {
201         snd_pcm_share_t *share = pcm->private_data;
202         snd_pcm_share_slave_t *slave = share->slave;
203         snd_pcm_t *spcm = slave->pcm;
204         snd_pcm_uframes_t buffer_size = spcm->buffer_size;
205         int ready = 1, running = 0;
206         snd_pcm_uframes_t avail = 0, slave_avail;
207         snd_pcm_sframes_t hw_avail;
208         snd_pcm_uframes_t missing = INT_MAX;
209         snd_pcm_sframes_t ready_missing;
210         // printf("state=%s hw_ptr=%ld appl_ptr=%ld slave appl_ptr=%ld safety=%ld silence=%ld\n", snd_pcm_state_name(share->state), slave->hw_ptr, share->appl_ptr, *slave->pcm->appl_ptr, slave->safety_threshold, slave->silence_frames);
211         switch (share->state) {
212         case SND_PCM_STATE_RUNNING:
213                 break;
214         case SND_PCM_STATE_DRAINING:
215                 if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
216                         break;
217                 /* Fall through */
218         default:
219                 return INT_MAX;
220         }
221         share->hw_ptr = slave->hw_ptr;
222         avail = snd_pcm_mmap_avail(pcm);
223         if (avail >= pcm->stop_threshold) {
224                 _snd_pcm_share_stop(pcm, share->state == SND_PCM_STATE_DRAINING ? SND_PCM_STATE_SETUP : SND_PCM_STATE_XRUN);
225                 goto update_poll;
226         }
227         hw_avail = buffer_size - avail;
228         slave_avail = snd_pcm_share_slave_avail(slave);
229         if (avail < slave_avail) {
230                 /* Some frames need still to be transferred */
231                 snd_pcm_sframes_t slave_hw_avail = buffer_size - slave_avail;
232                 snd_pcm_sframes_t safety_missing = slave_hw_avail - slave->safety_threshold;
233                 if (safety_missing < 0) {
234                         snd_pcm_sframes_t err;
235                         snd_pcm_sframes_t frames = slave_avail - avail;
236                         if (-safety_missing <= frames) {
237                                 frames = -safety_missing;
238                                 missing = 1;
239                         }
240                         err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames);
241                         if (err < 0) {
242                                 SYSMSG("snd_pcm_mmap_commit error");
243                                 return INT_MAX;
244                         }
245                         if (err != frames)
246                                 SYSMSG("commit returns %ld for size %ld", err, frames);
247                         slave_avail -= err;
248                 } else {
249                         if (safety_missing == 0)
250                                 missing = 1;
251                         else
252                                 missing = safety_missing;
253                 }
254         }
255         switch (share->state) {
256         case SND_PCM_STATE_DRAINING:
257                 if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
258                         if (hw_avail <= 0) {
259                                 _snd_pcm_share_stop(pcm, SND_PCM_STATE_SETUP);
260                                 break;
261                         }
262                         if ((snd_pcm_uframes_t)hw_avail < missing)
263                                 missing = hw_avail;
264                         running = 1;
265                         ready = 0;
266                 }
267                 break;
268         case SND_PCM_STATE_RUNNING:
269                 if (avail >= pcm->stop_threshold) {
270                         _snd_pcm_share_stop(pcm, SND_PCM_STATE_XRUN);
271                         break;
272                 } else {
273                         snd_pcm_uframes_t xrun_missing = pcm->stop_threshold - avail;
274                         if (missing > xrun_missing)
275                                 missing = xrun_missing;
276                 }
277                 ready_missing = pcm->avail_min - avail;
278                 if (ready_missing > 0) {
279                         ready = 0;
280                         if (missing > (snd_pcm_uframes_t)ready_missing)
281                                 missing = ready_missing;
282                 }
283                 running = 1;
284                 break;
285         default:
286                 SNDERR("invalid shared PCM state %d", share->state);
287                 return INT_MAX;
288         }
289
290  update_poll:
291         if (ready != share->ready) {
292                 char buf[1];
293                 if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
294                         if (ready)
295                                 read(share->slave_socket, buf, 1);
296                         else
297                                 write(share->client_socket, buf, 1);
298                 } else {
299                         if (ready)
300                                 write(share->slave_socket, buf, 1);
301                         else
302                                 read(share->client_socket, buf, 1);
303                 }
304                 share->ready = ready;
305         }
306         if (!running)
307                 return INT_MAX;
308         if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
309             share->state == SND_PCM_STATE_DRAINING &&
310             !share->drain_silenced) {
311                 /* drain silencing */
312                 if (avail >= slave->silence_frames) {
313                         snd_pcm_uframes_t offset = share->appl_ptr % buffer_size;
314                         snd_pcm_uframes_t xfer = 0;
315                         snd_pcm_uframes_t size = slave->silence_frames;
316                         while (xfer < size) {
317                                 snd_pcm_uframes_t frames = size - xfer;
318                                 snd_pcm_uframes_t cont = buffer_size - offset;
319                                 if (cont < frames)
320                                         frames = cont;
321                                 snd_pcm_areas_silence(pcm->running_areas, offset, pcm->channels, frames, pcm->format);
322                                 offset += frames;
323                                 if (offset >= buffer_size)
324                                         offset = 0;
325                                 xfer += frames;
326                         }
327                         share->drain_silenced = 1;
328                 } else {
329                         snd_pcm_uframes_t silence_missing;
330                         silence_missing = slave->silence_frames - avail;
331                         if (silence_missing < missing)
332                                 missing = silence_missing;
333                 }
334         }
335         // printf("missing=%d\n", missing);
336         return missing;
337 }
338
339 static snd_pcm_uframes_t _snd_pcm_share_slave_missing(snd_pcm_share_slave_t *slave)
340 {
341         snd_pcm_uframes_t missing = INT_MAX;
342         struct list_head *i;
343         /* snd_pcm_sframes_t avail = */ snd_pcm_avail_update(slave->pcm);
344         slave->hw_ptr = *slave->pcm->hw.ptr;
345         list_for_each(i, &slave->clients) {
346                 snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
347                 snd_pcm_t *pcm = share->pcm;
348                 snd_pcm_uframes_t m = _snd_pcm_share_missing(pcm);
349                 if (m < missing)
350                         missing = m;
351         }
352         return missing;
353 }
354
355 static void *snd_pcm_share_thread(void *data)
356 {
357         snd_pcm_share_slave_t *slave = data;
358         snd_pcm_t *spcm = slave->pcm;
359         struct pollfd pfd[2];
360         int err;
361
362         pfd[0].fd = slave->poll[0];
363         pfd[0].events = POLLIN;
364         err = snd_pcm_poll_descriptors(spcm, &pfd[1], 1);
365         if (err != 1) {
366                 SNDERR("invalid poll descriptors %d", err);
367                 return NULL;
368         }
369         Pthread_mutex_lock(&slave->mutex);
370         err = pipe(slave->poll);
371         if (err < 0) {
372                 SYSERR("can't create a pipe");
373                 return NULL;
374         }
375         while (slave->open_count > 0) {
376                 snd_pcm_uframes_t missing;
377                 // printf("begin min_missing\n");
378                 missing = _snd_pcm_share_slave_missing(slave);
379                 // printf("min_missing=%ld\n", missing);
380                 if (missing < INT_MAX) {
381                         snd_pcm_uframes_t hw_ptr;
382                         snd_pcm_sframes_t avail_min;
383                         hw_ptr = slave->hw_ptr + missing;
384                         hw_ptr += spcm->period_size - 1;
385                         if (hw_ptr >= spcm->boundary)
386                                 hw_ptr -= spcm->boundary;
387                         hw_ptr -= hw_ptr % spcm->period_size;
388                         avail_min = hw_ptr - *spcm->appl.ptr;
389                         if (spcm->stream == SND_PCM_STREAM_PLAYBACK)
390                                 avail_min += spcm->buffer_size;
391                         if (avail_min < 0)
392                                 avail_min += spcm->boundary;
393                         // printf("avail_min=%d\n", avail_min);
394                         if ((snd_pcm_uframes_t)avail_min != spcm->avail_min) {
395                                 snd_pcm_sw_params_set_avail_min(spcm, &slave->sw_params, avail_min);
396                                 err = snd_pcm_sw_params(spcm, &slave->sw_params);
397                                 if (err < 0) {
398                                         SYSERR("snd_pcm_sw_params error");
399                                         return NULL;
400                                 }
401                         }
402                         slave->polling = 1;
403                         Pthread_mutex_unlock(&slave->mutex);
404                         err = poll(pfd, 2, -1);
405                         Pthread_mutex_lock(&slave->mutex);
406                         if (pfd[0].revents & POLLIN) {
407                                 char buf[1];
408                                 read(pfd[0].fd, buf, 1);
409                         }
410                 } else {
411                         slave->polling = 0;
412                         pthread_cond_wait(&slave->poll_cond, &slave->mutex);
413                 }
414         }
415         Pthread_mutex_unlock(&slave->mutex);
416         return NULL;
417 }
418
419 static void _snd_pcm_share_update(snd_pcm_t *pcm)
420 {
421         snd_pcm_share_t *share = pcm->private_data;
422         snd_pcm_share_slave_t *slave = share->slave;
423         snd_pcm_t *spcm = slave->pcm;
424         snd_pcm_uframes_t missing;
425         /* snd_pcm_sframes_t avail = */ snd_pcm_avail_update(spcm);
426         slave->hw_ptr = *slave->pcm->hw.ptr;
427         missing = _snd_pcm_share_missing(pcm);
428         // printf("missing %ld\n", missing);
429         if (!slave->polling) {
430                 pthread_cond_signal(&slave->poll_cond);
431                 return;
432         }
433         if (missing < INT_MAX) {
434                 snd_pcm_uframes_t hw_ptr;
435                 snd_pcm_sframes_t avail_min;
436                 hw_ptr = slave->hw_ptr + missing;
437                 hw_ptr += spcm->period_size - 1;
438                 if (hw_ptr >= spcm->boundary)
439                         hw_ptr -= spcm->boundary;
440                 hw_ptr -= hw_ptr % spcm->period_size;
441                 avail_min = hw_ptr - *spcm->appl.ptr;
442                 if (spcm->stream == SND_PCM_STREAM_PLAYBACK)
443                         avail_min += spcm->buffer_size;
444                 if (avail_min < 0)
445                         avail_min += spcm->boundary;
446                 if ((snd_pcm_uframes_t)avail_min < spcm->avail_min) {
447                         int err;
448                         snd_pcm_sw_params_set_avail_min(spcm, &slave->sw_params, avail_min);
449                         err = snd_pcm_sw_params(spcm, &slave->sw_params);
450                         if (err < 0) {
451                                 SYSERR("snd_pcm_sw_params error");
452                                 return;
453                         }
454                 }
455         }
456 }
457
458 static int snd_pcm_share_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
459 {
460         return 0;
461 }
462
463 static int snd_pcm_share_async(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int sig ATTRIBUTE_UNUSED, pid_t pid ATTRIBUTE_UNUSED)
464 {
465         return -ENOSYS;
466 }
467
468 static int snd_pcm_share_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
469 {
470         snd_pcm_share_t *share = pcm->private_data;
471         return snd_pcm_info(share->slave->pcm, info);
472 }
473
474 static int snd_pcm_share_hw_refine_cprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
475 {
476         snd_pcm_share_t *share = pcm->private_data;
477         snd_pcm_share_slave_t *slave = share->slave;
478         snd_pcm_access_mask_t access_mask;
479         int err;
480         snd_pcm_access_mask_any(&access_mask);
481         snd_pcm_access_mask_reset(&access_mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
482         err = _snd_pcm_hw_param_set_mask(params, SND_PCM_HW_PARAM_ACCESS,
483                                          &access_mask);
484         if (err < 0)
485                 return err;
486         err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_CHANNELS,
487                                     share->channels, 0);
488         if (err < 0)
489                 return err;
490         if (slave->format != SND_PCM_FORMAT_UNKNOWN) {
491                 err = _snd_pcm_hw_params_set_format(params, slave->format);
492                 if (err < 0)
493                         return err;
494         }
495
496         if (slave->rate >= 0) {
497                 err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_RATE,
498                                             slave->rate, 0);
499                 if (err < 0)
500                         return err;
501         }
502         if (slave->period_time >= 0) {
503                 err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_PERIOD_TIME,
504                                             slave->period_time, 0);
505                 if (err < 0)
506                         return err;
507         }
508         if (slave->buffer_time >= 0) {
509                 err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_BUFFER_TIME,
510                                             slave->buffer_time, 0);
511                 if (err < 0)
512                         return err;
513         }
514         params->info |= SND_PCM_INFO_DOUBLE;
515         return 0;
516 }
517
518 static int snd_pcm_share_hw_refine_sprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *sparams)
519 {
520         snd_pcm_share_t *share = pcm->private_data;
521         snd_pcm_share_slave_t *slave = share->slave;
522         snd_pcm_access_mask_t saccess_mask = { SND_PCM_ACCBIT_MMAP };
523         _snd_pcm_hw_params_any(sparams);
524         _snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
525                                    &saccess_mask);
526         _snd_pcm_hw_param_set(sparams, SND_PCM_HW_PARAM_CHANNELS,
527                               slave->channels, 0);
528         return 0;
529 }
530
531 static int snd_pcm_share_hw_refine_schange(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params,
532                                           snd_pcm_hw_params_t *sparams)
533 {
534         int err;
535         unsigned int links = (SND_PCM_HW_PARBIT_FORMAT |
536                               SND_PCM_HW_PARBIT_SUBFORMAT |
537                               SND_PCM_HW_PARBIT_RATE |
538                               SND_PCM_HW_PARBIT_PERIOD_SIZE |
539                               SND_PCM_HW_PARBIT_PERIOD_TIME |
540                               SND_PCM_HW_PARBIT_BUFFER_SIZE |
541                               SND_PCM_HW_PARBIT_BUFFER_TIME |
542                               SND_PCM_HW_PARBIT_PERIODS);
543         const snd_pcm_access_mask_t *access_mask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS);
544         if (!snd_pcm_access_mask_test(access_mask, SND_PCM_ACCESS_RW_INTERLEAVED) &&
545             !snd_pcm_access_mask_test(access_mask, SND_PCM_ACCESS_RW_NONINTERLEAVED) &&
546             !snd_pcm_access_mask_test(access_mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED)) {
547                 snd_pcm_access_mask_t saccess_mask;
548                 snd_pcm_access_mask_any(&saccess_mask);
549                 snd_pcm_access_mask_reset(&saccess_mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
550                 err = _snd_pcm_hw_param_set_mask(sparams, SND_PCM_HW_PARAM_ACCESS,
551                                                  &saccess_mask);
552                 if (err < 0)
553                         return err;
554         }
555         err = _snd_pcm_hw_params_refine(sparams, links, params);
556         if (err < 0)
557                 return err;
558         return 0;
559 }
560         
561 static int snd_pcm_share_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params,
562                                            snd_pcm_hw_params_t *sparams)
563 {
564         int err;
565         unsigned int links = (SND_PCM_HW_PARBIT_FORMAT |
566                               SND_PCM_HW_PARBIT_SUBFORMAT |
567                               SND_PCM_HW_PARBIT_RATE |
568                               SND_PCM_HW_PARBIT_PERIOD_SIZE |
569                               SND_PCM_HW_PARBIT_PERIOD_TIME |
570                               SND_PCM_HW_PARBIT_BUFFER_SIZE |
571                               SND_PCM_HW_PARBIT_BUFFER_TIME |
572                               SND_PCM_HW_PARBIT_PERIODS);
573         snd_pcm_access_mask_t access_mask;
574         const snd_pcm_access_mask_t *saccess_mask = snd_pcm_hw_param_get_mask(sparams, SND_PCM_HW_PARAM_ACCESS);
575         snd_pcm_access_mask_any(&access_mask);
576         snd_pcm_access_mask_reset(&access_mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
577         if (!snd_pcm_access_mask_test(saccess_mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED))
578                 snd_pcm_access_mask_reset(&access_mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
579         if (!snd_pcm_access_mask_test(saccess_mask, SND_PCM_ACCESS_MMAP_COMPLEX) &&
580             !snd_pcm_access_mask_test(saccess_mask, SND_PCM_ACCESS_MMAP_INTERLEAVED))
581                 snd_pcm_access_mask_reset(&access_mask, SND_PCM_ACCESS_MMAP_COMPLEX);
582         err = _snd_pcm_hw_param_set_mask(params, SND_PCM_HW_PARAM_ACCESS,
583                                          &access_mask);
584         if (err < 0)
585                 return err;
586         err = _snd_pcm_hw_params_refine(params, links, sparams);
587         if (err < 0)
588                 return err;
589         return 0;
590 }
591
592 static int snd_pcm_share_hw_refine_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
593 {
594         snd_pcm_share_t *share = pcm->private_data;
595         return snd_pcm_hw_refine(share->slave->pcm, params);
596 }
597
598 static int snd_pcm_share_hw_params_slave(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
599 {
600         snd_pcm_share_t *share = pcm->private_data;
601         return _snd_pcm_hw_params(share->slave->pcm, params);
602 }
603
604 static int snd_pcm_share_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
605 {
606         return snd_pcm_hw_refine_slave(pcm, params,
607                                        snd_pcm_share_hw_refine_cprepare,
608                                        snd_pcm_share_hw_refine_cchange,
609                                        snd_pcm_share_hw_refine_sprepare,
610                                        snd_pcm_share_hw_refine_schange,
611                                        snd_pcm_share_hw_refine_slave);
612 }
613
614 static int snd_pcm_share_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
615 {
616         snd_pcm_share_t *share = pcm->private_data;
617         snd_pcm_share_slave_t *slave = share->slave;
618         snd_pcm_t *spcm = slave->pcm;
619         int err = 0;
620         Pthread_mutex_lock(&slave->mutex);
621         if (slave->setup_count) {
622                 err = _snd_pcm_hw_params_set_format(params, spcm->format);
623                 if (err < 0)
624                         goto _err;
625                 err = _snd_pcm_hw_params_set_subformat(params, spcm->subformat);
626                 if (err < 0)
627                         goto _err;
628                 err = _snd_pcm_hw_param_set_minmax(params, SND_PCM_HW_PARAM_RATE,
629                                                    spcm->rate, 0, 
630                                                    spcm->rate, 1);
631                 if (err < 0)
632                         goto _err;
633                 err = _snd_pcm_hw_param_set_minmax(params, SND_PCM_HW_PARAM_PERIOD_TIME,
634                                                    spcm->period_time, 0,
635                                                    spcm->period_time, 1);
636                 if (err < 0)
637                         goto _err;
638                 err = _snd_pcm_hw_param_set(params, SND_PCM_HW_PARAM_BUFFER_SIZE,
639                                             spcm->buffer_size, 0);
640         _err:
641                 if (err < 0) {
642                         SNDERR("slave is already running with incompatible setup");
643                         err = -EBUSY;
644                         goto _end;
645                 }
646         } else {
647                 err = snd_pcm_hw_params_slave(pcm, params,
648                                               snd_pcm_share_hw_refine_cchange,
649                                               snd_pcm_share_hw_refine_sprepare,
650                                               snd_pcm_share_hw_refine_schange,
651                                               snd_pcm_share_hw_params_slave);
652                 if (err < 0)
653                         goto _end;
654                 snd_pcm_sw_params_current(slave->pcm, &slave->sw_params);
655                 /* >= 30 ms */
656                 slave->safety_threshold = slave->pcm->rate * 30 / 1000;
657                 slave->safety_threshold += slave->pcm->period_size - 1;
658                 slave->safety_threshold -= slave->safety_threshold % slave->pcm->period_size;
659                 slave->silence_frames = slave->safety_threshold;
660                 if (slave->pcm->stream == SND_PCM_STREAM_PLAYBACK)
661                         snd_pcm_areas_silence(slave->pcm->running_areas, 0, slave->pcm->channels, slave->pcm->buffer_size, slave->pcm->format);
662         }
663         share->state = SND_PCM_STATE_SETUP;
664         slave->setup_count++;
665  _end:
666         Pthread_mutex_unlock(&slave->mutex);
667         return err;
668 }
669
670 static int snd_pcm_share_hw_free(snd_pcm_t *pcm)
671 {
672         snd_pcm_share_t *share = pcm->private_data;
673         snd_pcm_share_slave_t *slave = share->slave;
674         int err = 0;
675         Pthread_mutex_lock(&slave->mutex);
676         slave->setup_count--;
677         if (slave->setup_count == 0)
678                 err = snd_pcm_hw_free(slave->pcm);
679         share->state = SND_PCM_STATE_OPEN;
680         Pthread_mutex_unlock(&slave->mutex);
681         return err;
682 }
683
684 static int snd_pcm_share_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED)
685 {
686         return 0;
687 }
688
689 static int snd_pcm_share_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
690 {
691         snd_pcm_share_t *share = pcm->private_data;
692         snd_pcm_share_slave_t *slave = share->slave;
693         int err = 0;
694         snd_pcm_sframes_t sd = 0, d = 0;
695         Pthread_mutex_lock(&slave->mutex);
696         if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
697                 status->avail = snd_pcm_mmap_playback_avail(pcm);
698                 if (share->state != SND_PCM_STATE_RUNNING &&
699                     share->state != SND_PCM_STATE_DRAINING)
700                         goto _notrunning;
701                 d = pcm->buffer_size - status->avail;
702         } else {
703                 status->avail = snd_pcm_mmap_capture_avail(pcm);
704                 if (share->state != SND_PCM_STATE_RUNNING)
705                         goto _notrunning;
706                 d = status->avail;
707         }
708         err = snd_pcm_delay(slave->pcm, &sd);
709         if (err < 0)
710                 goto _end;
711  _notrunning:
712         status->delay = sd + d;
713         status->state = share->state;
714         status->trigger_tstamp = share->trigger_tstamp;
715  _end:
716         Pthread_mutex_unlock(&slave->mutex);
717         return err;
718 }
719
720 static snd_pcm_state_t snd_pcm_share_state(snd_pcm_t *pcm)
721 {
722         snd_pcm_share_t *share = pcm->private_data;
723         return share->state;
724 }
725
726 static int _snd_pcm_share_hwsync(snd_pcm_t *pcm)
727 {
728         snd_pcm_share_t *share = pcm->private_data;
729         snd_pcm_share_slave_t *slave = share->slave;
730         switch (share->state) {
731         case SND_PCM_STATE_XRUN:
732                 return -EPIPE;
733         default:
734                 break;
735         }
736         return snd_pcm_hwsync(slave->pcm);
737 }
738
739 static int snd_pcm_share_hwsync(snd_pcm_t *pcm)
740 {
741         snd_pcm_share_t *share = pcm->private_data;
742         snd_pcm_share_slave_t *slave = share->slave;
743         int err;
744         Pthread_mutex_lock(&slave->mutex);
745         err = _snd_pcm_share_hwsync(pcm);
746         Pthread_mutex_unlock(&slave->mutex);
747         return err;
748 }
749
750 static int _snd_pcm_share_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
751 {
752         snd_pcm_share_t *share = pcm->private_data;
753         snd_pcm_share_slave_t *slave = share->slave;
754         switch (share->state) {
755         case SND_PCM_STATE_XRUN:
756                 return -EPIPE;
757         case SND_PCM_STATE_RUNNING:
758                 break;
759         case SND_PCM_STATE_DRAINING:
760                 if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
761                         break;
762                 /* Fall through */
763         default:
764                 return -EBADFD;
765         }
766         return snd_pcm_delay(slave->pcm, delayp);
767 }
768
769 static int snd_pcm_share_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
770 {
771         snd_pcm_share_t *share = pcm->private_data;
772         snd_pcm_share_slave_t *slave = share->slave;
773         int err;
774         Pthread_mutex_lock(&slave->mutex);
775         err = _snd_pcm_share_delay(pcm, delayp);
776         Pthread_mutex_unlock(&slave->mutex);
777         return err;
778 }
779
780 static snd_pcm_sframes_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
781 {
782         snd_pcm_share_t *share = pcm->private_data;
783         snd_pcm_share_slave_t *slave = share->slave;
784         snd_pcm_sframes_t avail;
785         Pthread_mutex_lock(&slave->mutex);
786         if (share->state == SND_PCM_STATE_RUNNING) {
787                 avail = snd_pcm_avail_update(slave->pcm);
788                 if (avail < 0) {
789                         Pthread_mutex_unlock(&slave->mutex);
790                         return avail;
791                 }
792                 share->hw_ptr = *slave->pcm->hw.ptr;
793         }
794         Pthread_mutex_unlock(&slave->mutex);
795         avail = snd_pcm_mmap_avail(pcm);
796         if ((snd_pcm_uframes_t)avail > pcm->buffer_size)
797                 return -EPIPE;
798         return avail;
799 }
800
801 static int snd_pcm_share_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
802                                     snd_htimestamp_t *tstamp)
803 {
804         snd_pcm_share_t *share = pcm->private_data;
805         snd_pcm_share_slave_t *slave = share->slave;
806         int err;
807         Pthread_mutex_lock(&slave->mutex);
808         err = snd_pcm_htimestamp(slave->pcm, avail, tstamp);
809         Pthread_mutex_unlock(&slave->mutex);
810         return err;
811 }
812
813 /* Call it with mutex held */
814 static snd_pcm_sframes_t _snd_pcm_share_mmap_commit(snd_pcm_t *pcm,
815                                                     snd_pcm_uframes_t offset ATTRIBUTE_UNUSED,
816                                                     snd_pcm_uframes_t size)
817 {
818         snd_pcm_share_t *share = pcm->private_data;
819         snd_pcm_share_slave_t *slave = share->slave;
820         snd_pcm_t *spcm = slave->pcm;
821         snd_pcm_sframes_t ret;
822         snd_pcm_sframes_t frames;
823         if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
824             share->state == SND_PCM_STATE_RUNNING) {
825                 frames = *spcm->appl.ptr - share->appl_ptr;
826                 if (frames > (snd_pcm_sframes_t)pcm->buffer_size)
827                         frames -= pcm->boundary;
828                 else if (frames < -(snd_pcm_sframes_t)pcm->buffer_size)
829                         frames += pcm->boundary;
830                 if (frames > 0) {
831                         /* Latecomer PCM */
832                         ret = snd_pcm_rewind(spcm, frames);
833                         if (ret < 0)
834                                 return ret;
835                 }
836         }
837         snd_pcm_mmap_appl_forward(pcm, size);
838         if (share->state == SND_PCM_STATE_RUNNING) {
839                 frames = _snd_pcm_share_slave_forward(slave);
840                 if (frames > 0) {
841                         snd_pcm_sframes_t err;
842                         err = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), frames);
843                         if (err < 0) {
844                                 SYSMSG("snd_pcm_mmap_commit error");
845                                 return err;
846                         }
847                         if (err != frames) {
848                                 SYSMSG("commit returns %ld for size %ld", err, frames);
849                                 return err;
850                         }
851                 }
852                 _snd_pcm_share_update(pcm);
853         }
854         return size;
855 }
856
857 static snd_pcm_sframes_t snd_pcm_share_mmap_commit(snd_pcm_t *pcm,
858                                                    snd_pcm_uframes_t offset,
859                                                    snd_pcm_uframes_t size)
860 {
861         snd_pcm_share_t *share = pcm->private_data;
862         snd_pcm_share_slave_t *slave = share->slave;
863         snd_pcm_sframes_t ret;
864         Pthread_mutex_lock(&slave->mutex);
865         ret = _snd_pcm_share_mmap_commit(pcm, offset, size);
866         Pthread_mutex_unlock(&slave->mutex);
867         return ret;
868 }
869
870 static int snd_pcm_share_prepare(snd_pcm_t *pcm)
871 {
872         snd_pcm_share_t *share = pcm->private_data;
873         snd_pcm_share_slave_t *slave = share->slave;
874         int err = 0;
875         Pthread_mutex_lock(&slave->mutex);
876         switch (share->state) {
877         case SND_PCM_STATE_OPEN:
878                 err = -EBADFD;
879                 goto _end;
880         case SND_PCM_STATE_RUNNING:
881                 err = -EBUSY;
882                 goto _end;
883         case SND_PCM_STATE_PREPARED:
884                 err = 0;
885                 goto _end;
886         default:        /* nothing todo */
887                 break;
888         }
889         if (slave->prepared_count == 0) {
890                 err = snd_pcm_prepare(slave->pcm);
891                 if (err < 0)
892                         goto _end;
893         }
894         slave->prepared_count++;
895         share->hw_ptr = 0;
896         share->appl_ptr = 0;
897         share->state = SND_PCM_STATE_PREPARED;
898  _end:
899         Pthread_mutex_unlock(&slave->mutex);
900         return err;
901 }
902
903 static int snd_pcm_share_reset(snd_pcm_t *pcm)
904 {
905         snd_pcm_share_t *share = pcm->private_data;
906         snd_pcm_share_slave_t *slave = share->slave;
907         int err = 0;
908         /* FIXME? */
909         Pthread_mutex_lock(&slave->mutex);
910         snd_pcm_areas_silence(pcm->running_areas, 0, pcm->channels, pcm->buffer_size, pcm->format);
911         share->hw_ptr = *slave->pcm->hw.ptr;
912         share->appl_ptr = share->hw_ptr;
913         Pthread_mutex_unlock(&slave->mutex);
914         return err;
915 }
916
917 static int snd_pcm_share_start(snd_pcm_t *pcm)
918 {
919         snd_pcm_share_t *share = pcm->private_data;
920         snd_pcm_share_slave_t *slave = share->slave;
921         snd_pcm_t *spcm = slave->pcm;
922         int err = 0;
923         if (share->state != SND_PCM_STATE_PREPARED)
924                 return -EBADFD;
925         Pthread_mutex_lock(&slave->mutex);
926         share->state = SND_PCM_STATE_RUNNING;
927         if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
928                 snd_pcm_uframes_t hw_avail = snd_pcm_mmap_playback_hw_avail(pcm);
929                 snd_pcm_uframes_t xfer = 0;
930                 if (hw_avail == 0) {
931                         err = -EPIPE;
932                         goto _end;
933                 }
934                 if (slave->running_count) {
935                         snd_pcm_sframes_t sd;
936                         err = snd_pcm_delay(spcm, &sd);
937                         if (err < 0)
938                                 goto _end;
939                         err = snd_pcm_rewind(spcm, sd);
940                         if (err < 0)
941                                 goto _end;
942                 }
943                 assert(share->hw_ptr == 0);
944                 share->hw_ptr = *spcm->hw.ptr;
945                 share->appl_ptr = *spcm->appl.ptr;
946                 while (xfer < hw_avail) {
947                         snd_pcm_uframes_t frames = hw_avail - xfer;
948                         snd_pcm_uframes_t offset = snd_pcm_mmap_offset(pcm);
949                         snd_pcm_uframes_t cont = pcm->buffer_size - offset;
950                         if (cont < frames)
951                                 frames = cont;
952                         if (pcm->stopped_areas != NULL)
953                                 snd_pcm_areas_copy(pcm->running_areas, offset,
954                                                    pcm->stopped_areas, xfer,
955                                                    pcm->channels, frames,
956                                                    pcm->format);
957                         xfer += frames;
958                 }
959                 snd_pcm_mmap_appl_forward(pcm, hw_avail);
960                 if (slave->running_count == 0) {
961                         snd_pcm_sframes_t res;
962                         res = snd_pcm_mmap_commit(spcm, snd_pcm_mmap_offset(spcm), hw_avail);
963                         if (res < 0) {
964                                 err = res;
965                                 goto _end;
966                         }
967                         assert((snd_pcm_uframes_t)res == hw_avail);
968                 }
969         }
970         if (slave->running_count == 0) {
971                 err = snd_pcm_start(spcm);
972                 if (err < 0)
973                         goto _end;
974         }
975         slave->running_count++;
976         _snd_pcm_share_update(pcm);
977         gettimestamp(&share->trigger_tstamp, pcm->monotonic);
978  _end:
979         Pthread_mutex_unlock(&slave->mutex);
980         return err;
981 }
982
983 static int snd_pcm_share_pause(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int enable ATTRIBUTE_UNUSED)
984 {
985         return -ENOSYS;
986 }
987
988 static int snd_pcm_share_resume(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
989 {
990         return -ENXIO;
991 }
992
993 static int snd_pcm_share_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
994 {
995         snd_pcm_share_t *share = pcm->private_data;
996         snd_pcm_share_slave_t *slave = share->slave;
997         unsigned int channel = info->channel;
998         int c = share->slave_channels[channel];
999         int err;
1000         info->channel = c;
1001         err = snd_pcm_channel_info(slave->pcm, info);
1002         info->channel = channel;
1003         return err;
1004 }
1005
1006 static snd_pcm_sframes_t _snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1007 {
1008         snd_pcm_share_t *share = pcm->private_data;
1009         snd_pcm_share_slave_t *slave = share->slave;
1010         snd_pcm_sframes_t n;
1011         switch (share->state) {
1012         case SND_PCM_STATE_RUNNING:
1013                 break;
1014         case SND_PCM_STATE_PREPARED:
1015                 if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
1016                         return -EBADFD;
1017                 break;
1018         case SND_PCM_STATE_DRAINING:
1019                 if (pcm->stream != SND_PCM_STREAM_CAPTURE)
1020                         return -EBADFD;
1021                 break;
1022         case SND_PCM_STATE_XRUN:
1023                 return -EPIPE;
1024         default:
1025                 return -EBADFD;
1026         }
1027         n = snd_pcm_mmap_hw_avail(pcm);
1028         assert(n >= 0);
1029         if ((snd_pcm_uframes_t)n > frames)
1030                 frames = n;
1031         if (share->state == SND_PCM_STATE_RUNNING && frames > 0) {
1032                 snd_pcm_sframes_t ret = snd_pcm_rewind(slave->pcm, frames);
1033                 if (ret < 0)
1034                         return ret;
1035                 frames = ret;
1036         }
1037         snd_pcm_mmap_appl_backward(pcm, frames);
1038         _snd_pcm_share_update(pcm);
1039         return n;
1040 }
1041
1042 static snd_pcm_sframes_t snd_pcm_share_rewindable(snd_pcm_t *pcm)
1043 {
1044         snd_pcm_share_t *share = pcm->private_data;
1045         snd_pcm_share_slave_t *slave = share->slave;
1046         snd_pcm_sframes_t ret;
1047         Pthread_mutex_lock(&slave->mutex);
1048         ret = snd_pcm_rewindable(slave->pcm);
1049         Pthread_mutex_unlock(&slave->mutex);
1050         return ret;
1051 }
1052
1053 static snd_pcm_sframes_t snd_pcm_share_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1054 {
1055         snd_pcm_share_t *share = pcm->private_data;
1056         snd_pcm_share_slave_t *slave = share->slave;
1057         snd_pcm_sframes_t ret;
1058         Pthread_mutex_lock(&slave->mutex);
1059         ret = _snd_pcm_share_rewind(pcm, frames);
1060         Pthread_mutex_unlock(&slave->mutex);
1061         return ret;
1062 }
1063
1064 static snd_pcm_sframes_t _snd_pcm_share_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1065 {
1066         snd_pcm_share_t *share = pcm->private_data;
1067         snd_pcm_share_slave_t *slave = share->slave;
1068         snd_pcm_sframes_t n;
1069         switch (share->state) {
1070         case SND_PCM_STATE_RUNNING:
1071                 break;
1072         case SND_PCM_STATE_PREPARED:
1073                 if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
1074                         return -EBADFD;
1075                 break;
1076         case SND_PCM_STATE_DRAINING:
1077                 if (pcm->stream != SND_PCM_STREAM_CAPTURE)
1078                         return -EBADFD;
1079                 break;
1080         case SND_PCM_STATE_XRUN:
1081                 return -EPIPE;
1082         default:
1083                 return -EBADFD;
1084         }
1085         n = snd_pcm_mmap_avail(pcm);
1086         if ((snd_pcm_uframes_t)n > frames)
1087                 frames = n;
1088         if (share->state == SND_PCM_STATE_RUNNING && frames > 0) {
1089                 snd_pcm_sframes_t ret = INTERNAL(snd_pcm_forward)(slave->pcm, frames);
1090                 if (ret < 0)
1091                         return ret;
1092                 frames = ret;
1093         }
1094         snd_pcm_mmap_appl_forward(pcm, frames);
1095         _snd_pcm_share_update(pcm);
1096         return n;
1097 }
1098
1099 static snd_pcm_sframes_t snd_pcm_share_forwardable(snd_pcm_t *pcm)
1100 {
1101         snd_pcm_share_t *share = pcm->private_data;
1102         snd_pcm_share_slave_t *slave = share->slave;
1103         snd_pcm_sframes_t ret;
1104         Pthread_mutex_lock(&slave->mutex);
1105         ret = snd_pcm_forwardable(slave->pcm);
1106         Pthread_mutex_unlock(&slave->mutex);
1107         return ret;
1108 }
1109
1110 static snd_pcm_sframes_t snd_pcm_share_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
1111 {
1112         snd_pcm_share_t *share = pcm->private_data;
1113         snd_pcm_share_slave_t *slave = share->slave;
1114         snd_pcm_sframes_t ret;
1115         Pthread_mutex_lock(&slave->mutex);
1116         ret = _snd_pcm_share_forward(pcm, frames);
1117         Pthread_mutex_unlock(&slave->mutex);
1118         return ret;
1119 }
1120
1121 /* Warning: take the mutex before to call this */
1122 static void _snd_pcm_share_stop(snd_pcm_t *pcm, snd_pcm_state_t state)
1123 {
1124         snd_pcm_share_t *share = pcm->private_data;
1125         snd_pcm_share_slave_t *slave = share->slave;
1126 #if 0
1127         if (!pcm->mmap_channels) {
1128                 /* PCM closing already begun in the main thread */
1129                 return;
1130         }
1131 #endif
1132         gettimestamp(&share->trigger_tstamp, pcm->monotonic);
1133         if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
1134                 snd_pcm_areas_copy(pcm->stopped_areas, 0,
1135                                    pcm->running_areas, 0,
1136                                    pcm->channels, pcm->buffer_size,
1137                                    pcm->format);
1138         } else if (slave->running_count > 1) {
1139                 int err;
1140                 snd_pcm_sframes_t delay;
1141                 snd_pcm_areas_silence(pcm->running_areas, 0, pcm->channels,
1142                                       pcm->buffer_size, pcm->format);
1143                 err = snd_pcm_delay(slave->pcm, &delay);
1144                 if (err >= 0 && delay > 0)
1145                         snd_pcm_rewind(slave->pcm, delay);
1146                 share->drain_silenced = 0;
1147         }
1148         share->state = state;
1149         slave->prepared_count--;
1150         slave->running_count--;
1151         if (slave->running_count == 0) {
1152                 int err = snd_pcm_drop(slave->pcm);
1153                 assert(err >= 0);
1154         }
1155 }
1156
1157 static int snd_pcm_share_drain(snd_pcm_t *pcm)
1158 {
1159         snd_pcm_share_t *share = pcm->private_data;
1160         snd_pcm_share_slave_t *slave = share->slave;
1161         int err = 0;
1162         Pthread_mutex_lock(&slave->mutex);
1163         switch (share->state) {
1164         case SND_PCM_STATE_OPEN:
1165                 err = -EBADFD;
1166                 goto _end;
1167         case SND_PCM_STATE_PREPARED:
1168                 share->state = SND_PCM_STATE_SETUP;
1169                 goto _end;
1170         case SND_PCM_STATE_SETUP:
1171                 goto _end;
1172         default:
1173                 break;
1174         }
1175         if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
1176                 switch (share->state) {
1177                 case SND_PCM_STATE_XRUN:
1178                         share->state = SND_PCM_STATE_SETUP;
1179                         goto _end;
1180                 case SND_PCM_STATE_DRAINING:
1181                 case SND_PCM_STATE_RUNNING:
1182                         share->state = SND_PCM_STATE_DRAINING;
1183                         _snd_pcm_share_update(pcm);
1184                         Pthread_mutex_unlock(&slave->mutex);
1185                         if (!(pcm->mode & SND_PCM_NONBLOCK))
1186                                 snd_pcm_wait(pcm, -1);
1187                         return 0;
1188                 default:
1189                         assert(0);
1190                         break;
1191                 }
1192         } else {
1193                 switch (share->state) {
1194                 case SND_PCM_STATE_RUNNING:
1195                         _snd_pcm_share_stop(pcm, SND_PCM_STATE_DRAINING);
1196                         _snd_pcm_share_update(pcm);
1197                         /* Fall through */
1198                 case SND_PCM_STATE_XRUN:
1199                 case SND_PCM_STATE_DRAINING:
1200                         if (snd_pcm_mmap_capture_avail(pcm) <= 0)
1201                                 share->state = SND_PCM_STATE_SETUP;
1202                         else
1203                                 share->state = SND_PCM_STATE_DRAINING;
1204                         break;
1205                 default:
1206                         assert(0);
1207                         break;
1208                 }
1209         }
1210  _end:
1211         Pthread_mutex_unlock(&slave->mutex);
1212         return err;
1213 }
1214
1215 static int snd_pcm_share_drop(snd_pcm_t *pcm)
1216 {
1217         snd_pcm_share_t *share = pcm->private_data;
1218         snd_pcm_share_slave_t *slave = share->slave;
1219         int err = 0;
1220         Pthread_mutex_lock(&slave->mutex);
1221         switch (share->state) {
1222         case SND_PCM_STATE_OPEN:
1223                 err = -EBADFD;
1224                 goto _end;
1225         case SND_PCM_STATE_SETUP:
1226                 break;
1227         case SND_PCM_STATE_DRAINING:
1228                 if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
1229                         share->state = SND_PCM_STATE_SETUP;
1230                         break;
1231                 }
1232                 /* Fall through */
1233         case SND_PCM_STATE_RUNNING:
1234                 _snd_pcm_share_stop(pcm, SND_PCM_STATE_SETUP);
1235                 _snd_pcm_share_update(pcm);
1236                 break;
1237         case SND_PCM_STATE_PREPARED:
1238         case SND_PCM_STATE_XRUN:
1239                 share->state = SND_PCM_STATE_SETUP;
1240                 break;
1241         default:
1242                 assert(0);
1243                 break;
1244         }
1245         
1246         share->appl_ptr = share->hw_ptr = 0;
1247  _end:
1248         Pthread_mutex_unlock(&slave->mutex);
1249         return err;
1250 }
1251
1252 static int snd_pcm_share_close(snd_pcm_t *pcm)
1253 {
1254         snd_pcm_share_t *share = pcm->private_data;
1255         snd_pcm_share_slave_t *slave = share->slave;
1256         int err = 0;
1257
1258         Pthread_mutex_lock(&snd_pcm_share_slaves_mutex);
1259         Pthread_mutex_lock(&slave->mutex);
1260         slave->open_count--;
1261         if (slave->open_count == 0) {
1262                 pthread_cond_signal(&slave->poll_cond);
1263                 Pthread_mutex_unlock(&slave->mutex);
1264                 err = pthread_join(slave->thread, 0);
1265                 assert(err == 0);
1266                 err = snd_pcm_close(slave->pcm);
1267                 pthread_mutex_destroy(&slave->mutex);
1268                 pthread_cond_destroy(&slave->poll_cond);
1269                 list_del(&slave->list);
1270                 free(slave);
1271                 list_del(&share->list);
1272         } else {
1273                 list_del(&share->list);
1274                 Pthread_mutex_unlock(&slave->mutex);
1275         }
1276         Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
1277         close(share->client_socket);
1278         close(share->slave_socket);
1279         free(share->slave_channels);
1280         free(share);
1281         return err;
1282 }
1283
1284 static int snd_pcm_share_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
1285 {
1286         return 0;
1287 }
1288
1289 static int snd_pcm_share_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
1290 {
1291         return 0;
1292 }
1293
1294 static void snd_pcm_share_dump(snd_pcm_t *pcm, snd_output_t *out)
1295 {
1296         snd_pcm_share_t *share = pcm->private_data;
1297         snd_pcm_share_slave_t *slave = share->slave;
1298         unsigned int k;
1299         snd_output_printf(out, "Share PCM\n");
1300         snd_output_printf(out, "  Channel bindings:\n");
1301         for (k = 0; k < share->channels; ++k)
1302                 snd_output_printf(out, "    %d: %d\n", k, share->slave_channels[k]);
1303         if (pcm->setup) {
1304                 snd_output_printf(out, "Its setup is:\n");
1305                 snd_pcm_dump_setup(pcm, out);
1306         }
1307         snd_output_printf(out, "Slave: ");
1308         snd_pcm_dump(slave->pcm, out);
1309 }
1310
1311 static const snd_pcm_ops_t snd_pcm_share_ops = {
1312         .close = snd_pcm_share_close,
1313         .info = snd_pcm_share_info,
1314         .hw_refine = snd_pcm_share_hw_refine,
1315         .hw_params = snd_pcm_share_hw_params,
1316         .hw_free = snd_pcm_share_hw_free,
1317         .sw_params = snd_pcm_share_sw_params,
1318         .channel_info = snd_pcm_share_channel_info,
1319         .dump = snd_pcm_share_dump,
1320         .nonblock = snd_pcm_share_nonblock,
1321         .async = snd_pcm_share_async,
1322         .mmap = snd_pcm_share_mmap,
1323         .munmap = snd_pcm_share_munmap,
1324 };
1325
1326 static const snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
1327         .status = snd_pcm_share_status,
1328         .state = snd_pcm_share_state,
1329         .hwsync = snd_pcm_share_hwsync,
1330         .delay = snd_pcm_share_delay,
1331         .prepare = snd_pcm_share_prepare,
1332         .reset = snd_pcm_share_reset,
1333         .start = snd_pcm_share_start,
1334         .drop = snd_pcm_share_drop,
1335         .drain = snd_pcm_share_drain,
1336         .pause = snd_pcm_share_pause,
1337         .writei = snd_pcm_mmap_writei,
1338         .writen = snd_pcm_mmap_writen,
1339         .readi = snd_pcm_mmap_readi,
1340         .readn = snd_pcm_mmap_readn,
1341         .rewindable = snd_pcm_share_rewindable,
1342         .rewind = snd_pcm_share_rewind,
1343         .forwardable = snd_pcm_share_forwardable,
1344         .forward = snd_pcm_share_forward,
1345         .resume = snd_pcm_share_resume,
1346         .avail_update = snd_pcm_share_avail_update,
1347         .htimestamp = snd_pcm_share_htimestamp,
1348         .mmap_commit = snd_pcm_share_mmap_commit,
1349 };
1350
1351 /**
1352  * \brief Creates a new Share PCM
1353  * \param pcmp Returns created PCM handle
1354  * \param name Name of PCM
1355  * \param sname Slave name
1356  * \param sformat Slave format
1357  * \param srate Slave rate
1358  * \param schannels Slave channels
1359  * \param speriod_time Slave period time
1360  * \param sbuffer_time Slave buffer time
1361  * \param channels Count of channels
1362  * \param channels_map Map of channels
1363  * \param stream Direction
1364  * \param mode PCM mode
1365  * \retval zero on success otherwise a negative error code
1366  * \warning Using of this function might be dangerous in the sense
1367  *          of compatibility reasons. The prototype might be freely
1368  *          changed in future.
1369  */
1370 int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
1371                        snd_pcm_format_t sformat, int srate,
1372                        unsigned int schannels,
1373                        int speriod_time, int sbuffer_time,
1374                        unsigned int channels, unsigned int *channels_map,
1375                        snd_pcm_stream_t stream, int mode)
1376 {
1377         snd_pcm_t *pcm;
1378         snd_pcm_share_t *share;
1379         int err;
1380         struct list_head *i;
1381         char slave_map[32] = { 0 };
1382         unsigned int k;
1383         snd_pcm_share_slave_t *slave = NULL;
1384         int sd[2];
1385
1386         assert(pcmp);
1387         assert(channels > 0 && sname && channels_map);
1388
1389         for (k = 0; k < channels; ++k) {
1390                 if (channels_map[k] >= sizeof(slave_map) / sizeof(slave_map[0])) {
1391                         SNDERR("Invalid slave channel (%d) in binding", channels_map[k]);
1392                         return -EINVAL;
1393                 }
1394                 if (slave_map[channels_map[k]]) {
1395                         SNDERR("Repeated slave channel (%d) in binding", channels_map[k]);
1396                         return -EINVAL;
1397                 }
1398                 slave_map[channels_map[k]] = 1;
1399                 assert((unsigned)channels_map[k] < schannels);
1400         }
1401
1402         share = calloc(1, sizeof(snd_pcm_share_t));
1403         if (!share)
1404                 return -ENOMEM;
1405
1406         share->channels = channels;
1407         share->slave_channels = calloc(channels, sizeof(*share->slave_channels));
1408         if (!share->slave_channels) {
1409                 free(share);
1410                 return -ENOMEM;
1411         }
1412         memcpy(share->slave_channels, channels_map, channels * sizeof(*share->slave_channels));
1413
1414         err = snd_pcm_new(&pcm, SND_PCM_TYPE_SHARE, name, stream, mode);
1415         if (err < 0) {
1416                 free(share->slave_channels);
1417                 free(share);
1418                 return err;
1419         }
1420         err = socketpair(AF_LOCAL, SOCK_STREAM, 0, sd);
1421         if (err < 0) {
1422                 snd_pcm_free(pcm);
1423                 free(share->slave_channels);
1424                 free(share);
1425                 return -errno;
1426         }
1427                 
1428         if (stream == SND_PCM_STREAM_PLAYBACK) {
1429                 int bufsize = 1;
1430                 err = setsockopt(sd[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
1431                 if (err >= 0) {
1432                         struct pollfd pfd;
1433                         pfd.fd = sd[0];
1434                         pfd.events = POLLOUT;
1435                         while ((err = poll(&pfd, 1, 0)) == 1) {
1436                                 char buf[1];
1437                                 err = write(sd[0], buf, 1);
1438                                 assert(err != 0);
1439                                 if (err != 1)
1440                                         break;
1441                         }
1442                 }
1443         }
1444         if (err < 0) {
1445                 err = -errno;
1446                 close(sd[0]);
1447                 close(sd[1]);
1448                 snd_pcm_free(pcm);
1449                 free(share->slave_channels);
1450                 free(share);
1451                 return err;
1452         }
1453
1454         Pthread_mutex_lock(&snd_pcm_share_slaves_mutex);
1455         list_for_each(i, &snd_pcm_share_slaves) {
1456                 snd_pcm_share_slave_t *s = list_entry(i, snd_pcm_share_slave_t, list);
1457                 if (s->pcm->name && strcmp(s->pcm->name, sname) == 0) {
1458                         slave = s;
1459                         break;
1460                 }
1461         }
1462         if (!slave) {
1463                 snd_pcm_t *spcm;
1464                 err = snd_pcm_open(&spcm, sname, stream, mode);
1465                 if (err < 0) {
1466                         Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
1467                         close(sd[0]);
1468                         close(sd[1]);
1469                         snd_pcm_free(pcm);
1470                         free(share->slave_channels);
1471                         free(share);
1472                         return err;
1473                 }
1474                 /* FIXME: bellow is a real ugly hack to get things working */
1475                 /* there is a memory leak somewhere, but I'm unable to trace it --jk */
1476                 slave = calloc(1, sizeof(snd_pcm_share_slave_t) * 8);
1477                 if (!slave) {
1478                         Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
1479                         snd_pcm_close(spcm);
1480                         close(sd[0]);
1481                         close(sd[1]);
1482                         snd_pcm_free(pcm);
1483                         free(share->slave_channels);
1484                         free(share);
1485                         return err;
1486                 }
1487                 INIT_LIST_HEAD(&slave->clients);
1488                 slave->pcm = spcm;
1489                 slave->channels = schannels;
1490                 slave->format = sformat;
1491                 slave->rate = srate;
1492                 slave->period_time = speriod_time;
1493                 slave->buffer_time = sbuffer_time;
1494                 pthread_mutex_init(&slave->mutex, NULL);
1495                 pthread_cond_init(&slave->poll_cond, NULL);
1496                 list_add_tail(&slave->list, &snd_pcm_share_slaves);
1497                 Pthread_mutex_lock(&slave->mutex);
1498                 err = pthread_create(&slave->thread, NULL, snd_pcm_share_thread, slave);
1499                 assert(err == 0);
1500                 Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
1501         } else {
1502                 Pthread_mutex_lock(&slave->mutex);
1503                 Pthread_mutex_unlock(&snd_pcm_share_slaves_mutex);
1504                 list_for_each(i, &slave->clients) {
1505                         snd_pcm_share_t *sh = list_entry(i, snd_pcm_share_t, list);
1506                         for (k = 0; k < sh->channels; ++k) {
1507                                 if (slave_map[sh->slave_channels[k]]) {
1508                                         SNDERR("Slave channel %d is already in use", sh->slave_channels[k]);
1509                                         Pthread_mutex_unlock(&slave->mutex);
1510                                         close(sd[0]);
1511                                         close(sd[1]);
1512                                         snd_pcm_free(pcm);
1513                                         free(share->slave_channels);
1514                                         free(share);
1515                                         return -EBUSY;
1516                                 }
1517                         }
1518                 }
1519         }
1520
1521         share->slave = slave;
1522         share->pcm = pcm;
1523         share->client_socket = sd[0];
1524         share->slave_socket = sd[1];
1525         
1526         pcm->mmap_rw = 1;
1527         pcm->ops = &snd_pcm_share_ops;
1528         pcm->fast_ops = &snd_pcm_share_fast_ops;
1529         pcm->private_data = share;
1530         pcm->poll_fd = share->client_socket;
1531         pcm->poll_events = stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN;
1532         pcm->monotonic = slave->pcm->monotonic;
1533         snd_pcm_set_hw_ptr(pcm, &share->hw_ptr, -1, 0);
1534         snd_pcm_set_appl_ptr(pcm, &share->appl_ptr, -1, 0);
1535
1536         slave->open_count++;
1537         list_add_tail(&share->list, &slave->clients);
1538
1539         Pthread_mutex_unlock(&slave->mutex);
1540
1541         *pcmp = pcm;
1542         return 0;
1543 }
1544
1545 /*! \page pcm_plugins
1546
1547 \section pcm_plugins_share Plugin: Share
1548
1549 This plugin allows sharing of multiple channels with more clients. The access
1550 to each channel is exlusive (samples are not mixed together). It means, if
1551 the channel zero is used with first client, the channel cannot be used with
1552 second one. If you are looking for a mixing plugin, use the
1553 \ref pcm_plugins_dmix "dmix plugin".
1554
1555 The difference from \ref pcm_plugins_dshare "dshare plugin" is that
1556 share plugin requires the server program "aserver", while dshare plugin
1557 doesn't need the explicit server but access to the shared buffer.
1558
1559 \code
1560 pcm.name {
1561         type share              # Share PCM
1562         slave STR               # Slave name
1563         # or
1564         slave {                 # Slave definition
1565                 pcm STR         # Slave PCM name
1566                 [format STR]    # Slave format
1567                 [channels INT]  # Slave channels
1568                 [rate INT]      # Slave rate
1569                 [period_time INT] # Slave period time in us
1570                 [buffer_time INT] # Slave buffer time in us
1571         }
1572         bindings {
1573                 N INT           # Slave channel INT for client channel N
1574         }
1575 }
1576 \endcode
1577
1578 \subsection pcm_plugins_share_funcref Function reference
1579
1580 <UL>
1581   <LI>snd_pcm_share_open()
1582   <LI>_snd_pcm_share_open()
1583 </UL>
1584
1585 */
1586
1587 /**
1588  * \brief Creates a new Share PCM
1589  * \param pcmp Returns created PCM handle
1590  * \param name Name of PCM
1591  * \param root Root configuration node
1592  * \param conf Configuration node with Share PCM description
1593  * \param stream Stream type
1594  * \param mode Stream mode
1595  * \retval zero on success otherwise a negative error code
1596  * \warning Using of this function might be dangerous in the sense
1597  *          of compatibility reasons. The prototype might be freely
1598  *          changed in future.
1599  */
1600 int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
1601                         snd_config_t *root, snd_config_t *conf,
1602                         snd_pcm_stream_t stream, int mode)
1603 {
1604         snd_config_iterator_t i, next;
1605         const char *sname = NULL;
1606         snd_config_t *bindings = NULL;
1607         int err;
1608         snd_config_t *slave = NULL, *sconf;
1609         unsigned int *channels_map = NULL;
1610         unsigned int channels = 0;
1611         snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
1612         int schannels = -1;
1613         int srate = -1;
1614         int speriod_time= -1, sbuffer_time = -1;
1615         unsigned int schannel_max = 0;
1616         
1617         snd_config_for_each(i, next, conf) {
1618                 snd_config_t *n = snd_config_iterator_entry(i);
1619                 const char *id;
1620                 if (snd_config_get_id(n, &id) < 0)
1621                         continue;
1622                 if (snd_pcm_conf_generic_id(id))
1623                         continue;
1624                 if (strcmp(id, "slave") == 0) {
1625                         slave = n;
1626                         continue;
1627                 }
1628                 if (strcmp(id, "bindings") == 0) {
1629                         if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
1630                                 SNDERR("Invalid type for %s", id);
1631                                 return -EINVAL;
1632                         }
1633                         bindings = n;
1634                         continue;
1635                 }
1636                 SNDERR("Unknown field %s", id);
1637                 return -EINVAL;
1638         }
1639         if (!slave) {
1640                 SNDERR("slave is not defined");
1641                 return -EINVAL;
1642         }
1643         err = snd_pcm_slave_conf(root, slave, &sconf, 5,
1644                                  SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
1645                                  SND_PCM_HW_PARAM_CHANNELS, 0, &schannels,
1646                                  SND_PCM_HW_PARAM_RATE, 0, &srate,
1647                                  SND_PCM_HW_PARAM_PERIOD_TIME, 0, &speriod_time,
1648                                  SND_PCM_HW_PARAM_BUFFER_TIME, 0, &sbuffer_time);
1649         if (err < 0)
1650                 return err;
1651
1652         /* FIXME: nothing strictly forces to have named definition */
1653         err = snd_config_get_string(sconf, &sname);
1654         sname = err >= 0 && sname ? strdup(sname) : NULL;
1655         snd_config_delete(sconf);
1656         if (sname == NULL) {
1657                 SNDERR("slave.pcm is not a string");
1658                 return err;
1659         }
1660
1661         if (!bindings) {
1662                 SNDERR("bindings is not defined");
1663                 err = -EINVAL;
1664                 goto _free;
1665         }
1666         snd_config_for_each(i, next, bindings) {
1667                 long cchannel = -1;
1668                 snd_config_t *n = snd_config_iterator_entry(i);
1669                 const char *id;
1670                 if (snd_config_get_id(n, &id) < 0)
1671                         continue;
1672                 err = safe_strtol(id, &cchannel);
1673                 if (err < 0 || cchannel < 0) {
1674                         SNDERR("Invalid client channel in binding: %s", id);
1675                         err = -EINVAL;
1676                         goto _free;
1677                 }
1678                 if ((unsigned)cchannel >= channels)
1679                         channels = cchannel + 1;
1680         }
1681         if (channels == 0) {
1682                 SNDERR("No bindings defined");
1683                 err = -EINVAL;
1684                 goto _free;
1685         }
1686         channels_map = calloc(channels, sizeof(*channels_map));
1687         if (! channels_map) {
1688                 err = -ENOMEM;
1689                 goto _free;
1690         }
1691
1692         snd_config_for_each(i, next, bindings) {
1693                 snd_config_t *n = snd_config_iterator_entry(i);
1694                 const char *id;
1695                 long cchannel;
1696                 long schannel = -1;
1697                 if (snd_config_get_id(n, &id) < 0)
1698                         continue;
1699                 cchannel = atoi(id);
1700                 err = snd_config_get_integer(n, &schannel);
1701                 if (err < 0) {
1702                         goto _free;
1703                 }
1704                 assert(schannel >= 0);
1705                 assert(schannels <= 0 || schannel < schannels);
1706                 channels_map[cchannel] = schannel;
1707                 if ((unsigned)schannel > schannel_max)
1708                         schannel_max = schannel;
1709         }
1710         if (schannels <= 0)
1711                 schannels = schannel_max + 1;
1712         err = snd_pcm_share_open(pcmp, name, sname, sformat, srate, 
1713                                  (unsigned int) schannels,
1714                                  speriod_time, sbuffer_time,
1715                                  channels, channels_map, stream, mode);
1716 _free:
1717         free(channels_map);
1718         free((char *)sname);
1719         return err;
1720 }
1721 #ifndef DOC_HIDDEN
1722 SND_DLSYM_BUILD_VERSION(_snd_pcm_share_open, SND_PCM_DLSYM_VERSION);
1723 #endif