OSDN Git Service

Fixed mmap wrt shm. Renamed pcm_client, control_client to shm. More error messages...
[android-x86/external-alsa-lib.git] / src / pcm / pcm_share.c
1 /*
2  *  PCM - Share
3  *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
4  *
5  *
6  *   This library is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU Library General Public License as
8  *   published by the Free Software Foundation; either version 2 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 Library General Public License for more details.
15  *
16  *   You should have received a copy of the GNU Library General Public
17  *   License along with this library; if not, write to the Free Software
18  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  */
21   
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <signal.h>
27 #include <errno.h>
28 #include <math.h>
29 #include <sys/socket.h>
30 #include <sys/poll.h>
31 #include <pthread.h>
32 #include "pcm_local.h"
33 #include "list.h"
34
35 static LIST_HEAD(slaves);
36 static pthread_mutex_t slaves_mutex = PTHREAD_MUTEX_INITIALIZER;
37
38 typedef struct {
39         struct list_head clients;
40         struct list_head list;
41         snd_pcm_t *pcm;
42         size_t channels_count;
43         size_t open_count;
44         size_t setup_count;
45         size_t mmap_count;
46         size_t prepared_count;
47         size_t running_count;
48         size_t safety_threshold;
49         pthread_t thread;
50         pthread_mutex_t mutex;
51 } snd_pcm_share_slave_t;
52
53 typedef struct {
54         struct list_head list;
55         snd_pcm_t *pcm;
56         snd_pcm_share_slave_t *slave;
57         size_t channels_count;
58         int *slave_channels;
59         int xfer_mode;
60         int xrun_mode;
61         int async_sig;
62         pid_t async_pid;
63         struct timeval trigger_time;
64         size_t draining_silence;
65         int state;
66         size_t hw_ptr;
67         size_t appl_ptr;
68         int ready;
69         int client_socket;
70         int slave_socket;
71         void *stopped_data;
72 } snd_pcm_share_t;
73
74
75 static void snd_pcm_share_interrupt(snd_pcm_share_slave_t *slave)
76 {
77         struct list_head *i;
78         pthread_mutex_lock(&slave->mutex);
79         /* Update poll status */
80         for (i = slave->clients.next; i != &slave->clients; i = i->next) {
81                 snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
82                 snd_pcm_t *pcm = share->pcm;
83                 int ready;
84                 switch (share->state) {
85                 case SND_PCM_STATE_DRAINING:
86                         if (pcm->stream == SND_PCM_STREAM_CAPTURE)
87                                 ready = 1;
88                         else {
89                                 if (pcm->mode & SND_PCM_ASYNC)
90                                         kill(share->async_pid, share->async_sig);
91                                 ready = 0;
92                         }
93                         break;
94                 case SND_PCM_STATE_RUNNING:
95                         if (pcm->mode & SND_PCM_ASYNC)
96                                 kill(share->async_pid, share->async_sig);
97                         ready = (snd_pcm_mmap_avail(pcm) >= pcm->setup.avail_min);
98                         break;
99                 default:
100                         ready = 1;
101                 }
102                 if (ready != share->ready) {
103                         char buf[1];
104                         if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
105                                 if (ready)
106                                         read(share->slave_socket, buf, 1);
107                                 else
108                                         write(share->client_socket, buf, 1);
109                         } else {
110                                 if (ready)
111                                         write(share->slave_socket, buf, 1);
112                                 else
113                                         read(share->client_socket, buf, 1);
114                         }
115                         share->ready = ready;
116                 }
117         }
118         pthread_mutex_unlock(&slave->mutex);
119 }
120
121
122 void sigio_handler(int sig ATTRIBUTE_UNUSED)
123 {
124 }
125
126 void *snd_pcm_share_slave_thread(void *data)
127 {
128         snd_pcm_share_slave_t *slave = data;
129         int err;
130         struct sigaction act;
131         err = snd_pcm_async(slave->pcm, SIGIO, 0);
132         assert(err == 0);
133         act.sa_handler = sigio_handler;
134         sigemptyset(&act.sa_mask);
135         sigaddset(&act.sa_mask, SIGIO);
136         act.sa_flags = 0;
137         err = sigaction(SIGIO, &act, NULL);
138         assert(err == 0);
139         while (1) {
140                 pause();
141                 snd_pcm_share_interrupt(slave);
142         }
143         return NULL;
144 }
145
146 /* Warning: take the mutex before to call this */
147 static void snd_pcm_share_stop(snd_pcm_t *pcm, int state)
148 {
149         snd_pcm_share_t *share = pcm->private;
150         snd_pcm_share_slave_t *slave = share->slave;
151         share->state = state;
152         gettimeofday(&share->trigger_time, 0);
153         slave->prepared_count--;
154         slave->running_count--;
155         if (slave->running_count == 0) {
156                 int err = snd_pcm_drop(slave->pcm);
157                 assert(err >= 0);
158         }
159         if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
160                 snd_pcm_areas_copy(pcm->running_areas, 0,
161                                    pcm->stopped_areas, 0,
162                                    pcm->setup.format.channels, pcm->setup.buffer_size,
163                                    pcm->setup.format.sfmt);
164         }
165         share->hw_ptr = *slave->pcm->hw_ptr;
166         pcm->hw_ptr = &share->hw_ptr;
167 }
168
169 /* Warning: take the mutex before to call this */
170 static void snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
171 {
172         struct list_head *i;
173         size_t buffer_size, boundary;
174         size_t slave_appl_ptr;
175         ssize_t frames, safety_frames;
176         size_t min_frames, max_frames;
177         ssize_t avail;
178         int err;
179         avail = snd_pcm_avail_update(slave->pcm);
180         if (avail == 0)
181                 return;
182         assert(avail > 0);
183         boundary = slave->pcm->setup.boundary;
184         buffer_size = slave->pcm->setup.buffer_size;
185         min_frames = buffer_size;
186         max_frames = 0;
187         slave_appl_ptr = *slave->pcm->appl_ptr;
188         for (i = slave->clients.next; i != &slave->clients; i = i->next) {
189                 snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
190                 snd_pcm_t *pcm = share->pcm;
191                 switch (share->state) {
192                 case SND_PCM_STATE_RUNNING:
193                         break;
194                 case SND_PCM_STATE_DRAINING:
195                 {
196                         size_t a, offset;
197                         if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
198                                 continue;
199                         a = snd_pcm_mmap_avail(pcm);
200                         frames = a - share->draining_silence;
201                         offset = snd_pcm_mmap_offset(pcm);
202                         offset += share->draining_silence;
203                         if (offset >= buffer_size)
204                                 offset -= buffer_size;
205                         while (frames > 0) {
206                                 size_t f = buffer_size - offset;
207                                 if (f > (size_t) frames)
208                                         f = frames;
209                                 snd_pcm_areas_silence(pcm->running_areas, offset,
210                                                       pcm->setup.format.channels, 
211                                                       f, pcm->setup.format.sfmt);
212                                 offset += f;
213                                 if (offset == buffer_size)
214                                         offset = 0;
215                                 frames -= f;
216                         }
217                         share->draining_silence = a;
218                         if (a == buffer_size)
219                                 snd_pcm_share_stop(pcm, SND_PCM_STATE_SETUP);
220                         break;
221                 }
222                 default:
223                         continue;
224                 }
225                 frames = share->appl_ptr - slave_appl_ptr;
226                 if (frames > (ssize_t)buffer_size)
227                         frames -= pcm->setup.boundary;
228                 else if (frames < -(ssize_t)pcm->setup.buffer_size)
229                         frames += pcm->setup.boundary;
230                 if (frames < 0) {
231                         if (snd_pcm_mmap_hw_avail(pcm) <= 0 &&
232                             pcm->setup.xrun_mode != SND_PCM_XRUN_NONE)
233                                 snd_pcm_share_stop(pcm, SND_PCM_STATE_XRUN);
234                         continue;
235                 }
236                 if ((size_t)frames < min_frames)
237                         min_frames = frames;
238                 if ((size_t)frames > max_frames)
239                         max_frames = frames;
240         }
241         if (max_frames == 0)
242                 return;
243         frames = min_frames;
244         if (frames > avail)
245                 frames = avail;
246         /* Slave xrun prevention */
247         safety_frames = slave->safety_threshold - snd_pcm_mmap_hw_avail(slave->pcm);
248         if (safety_frames > 0 &&
249             frames < (ssize_t)safety_frames) {
250                 /* Avoid to pass over the last */
251                 if (max_frames < (size_t)safety_frames)
252                         frames = max_frames;
253                 else
254                         frames = safety_frames;
255         }
256         if (frames > 0) {
257                 err = snd_pcm_mmap_forward(slave->pcm, frames);
258                 assert(err == frames);
259         }
260 }
261
262 static int snd_pcm_share_close(snd_pcm_t *pcm)
263 {
264         snd_pcm_share_t *share = pcm->private;
265         snd_pcm_share_slave_t *slave = share->slave;
266         int err = 0;
267         if (share->state == SND_PCM_STATE_RUNNING) {
268                 if (pcm->mode & SND_PCM_NONBLOCK)
269                         snd_pcm_drop(pcm);
270                 else
271                         snd_pcm_drain(pcm);
272         }
273         pthread_mutex_lock(&slave->mutex);
274         if (pcm->valid_setup)
275                 slave->setup_count--;
276         slave->open_count--;
277         if (slave->open_count == 0) {
278                 pthread_kill(slave->thread, SIGTERM);
279                 err = snd_pcm_close(slave->pcm);
280                 list_del(&slave->list);
281                 pthread_mutex_unlock(&slave->mutex);
282                 pthread_mutex_destroy(&slave->mutex);
283                 free(slave);
284                 list_del(&share->list);
285         } else {
286                 list_del(&share->list);
287                 pthread_mutex_unlock(&slave->mutex);
288         }
289         close(share->client_socket);
290         close(share->slave_socket);
291         free(share->slave_channels);
292         free(share);
293         return err;
294 }
295
296 static int snd_pcm_share_nonblock(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int nonblock ATTRIBUTE_UNUSED)
297 {
298         return 0;
299 }
300
301 static int snd_pcm_share_async(snd_pcm_t *pcm, int sig, pid_t pid)
302 {
303         snd_pcm_share_t *share = pcm->private;
304         if (sig)
305                 share->async_sig = sig;
306         else
307                 share->async_sig = SIGIO;
308         if (pid)
309                 share->async_pid = pid;
310         else
311                 share->async_pid = getpid();
312         return -ENOSYS;
313 }
314
315 static int snd_pcm_share_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
316 {
317         snd_pcm_share_t *share = pcm->private;
318         return snd_pcm_info(share->slave->pcm, info);
319 }
320
321 static int snd_pcm_share_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t *info)
322 {
323         snd_pcm_share_t *share = pcm->private;
324         snd_pcm_share_slave_t *slave = share->slave;
325         int err = 0;
326         unsigned int req_mask = info->req_mask;
327         unsigned int channels = info->req.format.channels;
328         if ((req_mask & SND_PCM_PARAMS_CHANNELS) &&
329             channels != share->channels_count) {
330                 info->req.fail_mask |= SND_PCM_PARAMS_CHANNELS;
331                 info->req.fail_reason = SND_PCM_PARAMS_FAIL_INVAL;
332                 return -EINVAL;
333         }
334         info->req_mask |= SND_PCM_PARAMS_CHANNELS;
335         info->req.format.channels = slave->channels_count;
336         err = snd_pcm_params_info(slave->pcm, info);
337         info->req.format.channels = channels;
338         info->req_mask = req_mask;
339         if (slave->setup_count > 1 || 
340             (slave->setup_count == 1 && !pcm->valid_setup)) {
341                 snd_pcm_setup_t *s = &slave->pcm->setup;
342                 if ((req_mask & SND_PCM_PARAMS_SFMT) &&
343                     info->req.format.sfmt != s->format.sfmt) {
344                         info->req.fail_mask |= SND_PCM_PARAMS_SFMT;
345                         info->req.fail_reason = SND_PCM_PARAMS_FAIL_INVAL;
346                         return -EINVAL;
347                 }
348                 info->formats = 1 << s->format.sfmt;
349                 info->rates = SND_PCM_RATE_CONTINUOUS;
350                 info->min_rate = info->max_rate = s->format.rate;
351                 info->buffer_size = s->buffer_size;
352                 info->min_fragment_size = info->max_fragment_size = s->frag_size;
353                 info->min_fragments = info->max_fragments = s->frags;
354                 info->fragment_align = s->frag_size;
355                 info->req.fail_mask = 0;
356         }
357
358         info->min_channels = info->max_channels = share->channels_count;
359         if (info->flags & SND_PCM_INFO_INTERLEAVED) {
360                 info->flags &= ~SND_PCM_INFO_INTERLEAVED;
361                 info->flags |= SND_PCM_INFO_COMPLEX;
362         }
363         return err;
364 }
365
366 static int snd_pcm_share_mmap(snd_pcm_t *pcm)
367 {
368         snd_pcm_share_t *share = pcm->private;
369         snd_pcm_share_slave_t *slave = share->slave;
370         snd_pcm_mmap_info_t *i;
371         int err;
372         pthread_mutex_lock(&slave->mutex);
373         if (slave->mmap_count == 0) {
374                 err = snd_pcm_mmap(slave->pcm);
375                 if (err < 0) {
376                         pthread_mutex_unlock(&slave->mutex);
377                         return err;
378                 }
379                 if (slave->pcm->stream == SND_PCM_STREAM_PLAYBACK)
380                         snd_pcm_areas_silence(slave->pcm->running_areas, 0, slave->pcm->setup.format.channels, slave->pcm->setup.buffer_size, slave->pcm->setup.format.sfmt);
381                 slave->mmap_count++;
382         }
383         pthread_mutex_unlock(&slave->mutex);
384         pcm->mmap_info_count = slave->pcm->mmap_info_count + 1;
385         pcm->mmap_info = malloc(pcm->mmap_info_count * sizeof(*pcm->mmap_info));
386         if (!pcm->mmap_info)
387                 return -ENOMEM;
388         memcpy(pcm->mmap_info, slave->pcm->mmap_info, slave->pcm->mmap_info_count * sizeof(*pcm->mmap_info));
389         i = &pcm->mmap_info[slave->pcm->mmap_info_count];
390         i->type = SND_PCM_MMAP_USER;
391         i->size = snd_pcm_frames_to_bytes(pcm, pcm->setup.buffer_size);
392         share->stopped_data = malloc(i->size);
393         if (share->stopped_data == 0) {
394                 free(pcm->mmap_info);
395                 pcm->mmap_info = 0;
396                 return -ENOMEM;
397         }
398         i->addr = share->stopped_data;
399         return 0;
400 }
401
402 static int snd_pcm_share_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
403 {
404         snd_pcm_share_t *share = pcm->private;
405         snd_pcm_share_slave_t *slave = share->slave;
406         int err;
407         pthread_mutex_lock(&slave->mutex);
408         slave->mmap_count--;
409         if (slave->mmap_count == 0) {
410                 err = snd_pcm_munmap(slave->pcm);
411                 if (err < 0) {
412                         pthread_mutex_unlock(&slave->mutex);
413                         return err;
414                 }
415         }
416         pthread_mutex_unlock(&slave->mutex);
417         free(pcm->mmap_info);
418         pcm->mmap_info_count = 0;
419         pcm->mmap_info = 0;
420         free(share->stopped_data);
421         return 0;
422 }
423                 
424 static int snd_pcm_share_params(snd_pcm_t *pcm, snd_pcm_params_t *params)
425 {
426         snd_pcm_share_t *share = pcm->private;
427         snd_pcm_share_slave_t *slave = share->slave;
428         unsigned int channels = params->format.channels;
429         int err = 0;
430         if (channels != share->channels_count) {
431                 params->fail_mask = SND_PCM_PARAMS_CHANNELS;
432                 params->fail_reason = SND_PCM_PARAMS_FAIL_INVAL;
433                 ERR("channels requested (%d) differs from configuration (%ld)", channels, (long)share->channels_count);
434                 return -EINVAL;
435         }
436         share->xfer_mode = params->xfer_mode;
437         share->xrun_mode = params->xrun_mode;
438         pthread_mutex_lock(&slave->mutex);
439         if (slave->setup_count > 1 || 
440             (slave->setup_count == 1 && !pcm->valid_setup)) {
441                 snd_pcm_setup_t *s = &slave->pcm->setup;
442                 if (params->format.sfmt != s->format.sfmt) {
443                         ERR("slave is already running with different format");
444                         params->fail_mask |= SND_PCM_PARAMS_SFMT;
445                 }
446                 if (params->fail_mask) {
447                         params->fail_reason = SND_PCM_PARAMS_FAIL_INVAL;
448                         err = -EINVAL;
449                         goto _end;
450                 }
451         } else {
452                 snd_pcm_params_t sp = *params;
453                 sp.xfer_mode = SND_PCM_XFER_UNSPECIFIED;
454                 sp.xrun_mode = SND_PCM_XRUN_NONE;
455                 sp.format.channels = slave->channels_count;
456                 err = snd_pcm_params(slave->pcm, &sp);
457                 if (err < 0)
458                         goto _end;
459         }
460         share->state = SND_PCM_STATE_SETUP;
461         slave->setup_count++;
462  _end:
463         pthread_mutex_unlock(&slave->mutex);
464         return err;
465 }
466
467 static int snd_pcm_share_setup(snd_pcm_t *pcm, snd_pcm_setup_t *setup)
468 {
469         snd_pcm_share_t *share = pcm->private;
470         snd_pcm_share_slave_t *slave = share->slave;
471         int err;
472         err = snd_pcm_setup(slave->pcm, setup);
473         if (err < 0)
474                 return err;
475         setup->xrun_mode = share->xrun_mode;
476         setup->format.channels = share->channels_count;
477         if (share->xfer_mode == SND_PCM_XFER_UNSPECIFIED)
478                 setup->xfer_mode = SND_PCM_XFER_NONINTERLEAVED;
479         else
480                 setup->xfer_mode = share->xfer_mode;
481         if (setup->mmap_shape != SND_PCM_MMAP_INTERLEAVED)
482                 setup->mmap_shape = SND_PCM_MMAP_COMPLEX;
483         return 0;
484 }
485
486 static int snd_pcm_share_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
487 {
488         snd_pcm_share_t *share = pcm->private;
489         snd_pcm_share_slave_t *slave = share->slave;
490         int err = 0;
491         ssize_t sd = 0, d = 0;
492         pthread_mutex_lock(&slave->mutex);
493         if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
494                 status->avail = snd_pcm_mmap_playback_avail(pcm);
495                 if (share->state != SND_PCM_STATE_RUNNING &&
496                     share->state != SND_PCM_STATE_DRAINING)
497                         goto _notrunning;
498                 d = pcm->setup.buffer_size - status->avail;
499         } else {
500                 status->avail = snd_pcm_mmap_capture_avail(pcm);
501                 if (share->state != SND_PCM_STATE_RUNNING)
502                         goto _notrunning;
503                 d = status->avail;
504         }
505         err = snd_pcm_delay(slave->pcm, &sd);
506         if (err < 0)
507                 goto _end;
508  _notrunning:
509         status->delay = sd + d;
510         status->state = share->state;
511         status->trigger_time = share->trigger_time;
512  _end:
513         pthread_mutex_unlock(&slave->mutex);
514         return err;
515 }
516
517 static int snd_pcm_share_state(snd_pcm_t *pcm)
518 {
519         snd_pcm_share_t *share = pcm->private;
520         return share->state;
521 }
522
523 static int snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
524 {
525         snd_pcm_share_t *share = pcm->private;
526         snd_pcm_share_slave_t *slave = share->slave;
527         int err = 0;
528         ssize_t sd;
529         pthread_mutex_lock(&slave->mutex);
530         switch (share->state) {
531         case SND_PCM_STATE_XRUN:
532                 err = -EPIPE;
533                 goto _end;
534         case SND_PCM_STATE_RUNNING:
535                 break;
536         case SND_PCM_STATE_DRAINING:
537                 if (pcm->stream == SND_PCM_STREAM_PLAYBACK)
538                         break;
539                 /* Fall through */
540         default:
541                 err = -EBADFD;
542                 goto _end;
543         }
544         err = snd_pcm_delay(slave->pcm, &sd);
545         if (err < 0)
546                 goto _end;
547         *delayp = sd + snd_pcm_mmap_delay(pcm);
548  _end:
549         pthread_mutex_unlock(&slave->mutex);
550         return 0;
551 }
552
553 static ssize_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
554 {
555         snd_pcm_share_t *share = pcm->private;
556         snd_pcm_share_slave_t *slave = share->slave;
557         ssize_t ret = 0;
558         pthread_mutex_lock(&slave->mutex);
559         ret = snd_pcm_avail_update(slave->pcm);
560         if (ret == -EPIPE) {
561                 struct list_head *i;
562                 for (i = slave->clients.next; i != &slave->clients; i = i->next) {
563                         snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
564                         snd_pcm_t *pcm = share->pcm;
565                         if (share->state == SND_PCM_STATE_RUNNING &&
566                             pcm->setup.xrun_mode != SND_PCM_XRUN_NONE)
567                                 snd_pcm_share_stop(pcm, SND_PCM_STATE_XRUN);
568                 }
569         }
570         pthread_mutex_unlock(&slave->mutex);
571         if (ret >= 0) {
572                 ret = snd_pcm_mmap_avail(pcm);
573                 if ((size_t)ret > pcm->setup.buffer_size)
574                         return -EPIPE;
575         }
576         return ret;
577 }
578
579 /* Call it with mutex held */
580 static ssize_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
581 {
582         snd_pcm_share_t *share = pcm->private;
583         snd_pcm_share_slave_t *slave = share->slave;
584         ssize_t ret = 0;
585         ssize_t frames;
586         if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
587             share->state == SND_PCM_STATE_RUNNING) {
588                 frames = *slave->pcm->appl_ptr - share->appl_ptr;
589                 if (frames > (ssize_t)pcm->setup.buffer_size)
590                         frames -= pcm->setup.boundary;
591                 else if (frames < -(ssize_t)pcm->setup.buffer_size)
592                         frames += pcm->setup.boundary;
593                 if (frames > 0) {
594                         /* Latecomer PCM */
595                         ret = snd_pcm_rewind(slave->pcm, frames);
596                         if (ret < 0)
597                                 return ret;
598                         size += ret;
599                 }
600         }
601         snd_pcm_mmap_appl_forward(pcm, size);
602         snd_pcm_share_slave_forward(share->slave);
603         return size;
604 }
605
606 static ssize_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
607 {
608         snd_pcm_share_t *share = pcm->private;
609         snd_pcm_share_slave_t *slave = share->slave;
610         ssize_t ret;
611         pthread_mutex_lock(&slave->mutex);
612         ret = _snd_pcm_share_mmap_forward(pcm, size);
613         pthread_mutex_unlock(&slave->mutex);
614         return ret;
615 }
616
617 static int snd_pcm_share_prepare(snd_pcm_t *pcm)
618 {
619         snd_pcm_share_t *share = pcm->private;
620         snd_pcm_share_slave_t *slave = share->slave;
621         int err = 0;
622         pthread_mutex_lock(&slave->mutex);
623         if (slave->prepared_count == 0) {
624                 err = snd_pcm_prepare(slave->pcm);
625                 if (err < 0)
626                         goto _end;
627         }
628         slave->prepared_count++;
629         share->hw_ptr = 0;
630         share->appl_ptr = 0;
631         share->state = SND_PCM_STATE_PREPARED;
632  _end:
633         pthread_mutex_unlock(&slave->mutex);
634         return err;
635 }
636
637 static int snd_pcm_share_start(snd_pcm_t *pcm)
638 {
639         snd_pcm_share_t *share = pcm->private;
640         snd_pcm_share_slave_t *slave = share->slave;
641         int err = 0;
642         if (share->state != SND_PCM_STATE_PREPARED)
643                 return -EBADFD;
644         pthread_mutex_lock(&slave->mutex);
645         share->state = SND_PCM_STATE_RUNNING;
646         if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
647                 size_t hw_avail = snd_pcm_mmap_playback_hw_avail(pcm);
648                 if (hw_avail == 0) {
649                         err = -EPIPE;
650                         goto _end;
651                 }
652                 if (slave->running_count) {
653                         ssize_t sd;
654                         err = snd_pcm_delay(slave->pcm, &sd);
655                         if (err < 0)
656                                 goto _end;
657                         err = snd_pcm_rewind(slave->pcm, sd);
658                         if (err < 0)
659                                 goto _end;
660                 }
661                 assert(share->hw_ptr == 0);
662                 /* Share the same hw_ptr of slave */
663                 pcm->hw_ptr = slave->pcm->hw_ptr;
664                 share->appl_ptr = *slave->pcm->appl_ptr;
665                 snd_pcm_areas_copy(pcm->stopped_areas, 0,
666                                    pcm->running_areas, snd_pcm_mmap_offset(pcm),
667                                    pcm->setup.format.channels, hw_avail,
668                                    pcm->setup.format.sfmt);
669                 _snd_pcm_share_mmap_forward(pcm, pcm->setup.buffer_size);
670         }
671         if (slave->running_count == 0) {
672                 err = snd_pcm_start(slave->pcm);
673                 if (err < 0)
674                         goto _end;
675         }
676         slave->running_count++;
677         gettimeofday(&share->trigger_time, 0);
678  _end:
679         pthread_mutex_unlock(&slave->mutex);
680         return err;
681 }
682
683 static int snd_pcm_share_drop(snd_pcm_t *pcm)
684 {
685         snd_pcm_share_t *share = pcm->private;
686         snd_pcm_share_slave_t *slave = share->slave;
687         int err = 0;
688         pthread_mutex_lock(&slave->mutex);
689         switch (share->state) {
690         case SND_PCM_STATE_OPEN:
691                 err = -EBADFD;
692                 goto _end;
693         case SND_PCM_STATE_SETUP:
694                 goto _end;
695         case SND_PCM_STATE_DRAINING:
696                 if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
697                         share->state = SND_PCM_STATE_SETUP;
698                         break;
699                 }
700                 /* Fall through */
701         case SND_PCM_STATE_RUNNING:
702                 snd_pcm_share_stop(pcm, SND_PCM_STATE_SETUP);
703                 break;
704         case SND_PCM_STATE_PREPARED:
705         case SND_PCM_STATE_XRUN:
706                 share->state = SND_PCM_STATE_SETUP;
707                 break;
708         }
709         
710         if (slave->running_count > 0 &&
711             pcm->stream == SND_PCM_STREAM_PLAYBACK) {
712                 ssize_t delay;
713                 err = snd_pcm_delay(pcm, &delay);
714                 if (err < 0)
715                         goto _end;
716                 if (delay > 0) {
717                         err = snd_pcm_rewind(pcm, delay);
718                         if (err < 0)
719                                 goto _end;
720                 }
721                 snd_pcm_areas_silence(pcm->running_areas, 0, pcm->setup.format.channels,
722                                       pcm->setup.buffer_size, pcm->setup.format.sfmt);
723                 snd_pcm_mmap_forward(pcm, pcm->setup.buffer_size);
724         }
725         share->appl_ptr = share->hw_ptr = 0;
726  _end:
727         pthread_mutex_unlock(&slave->mutex);
728         return err;
729 }
730
731 static int snd_pcm_share_drain(snd_pcm_t *pcm)
732 {
733         snd_pcm_share_t *share = pcm->private;
734         snd_pcm_share_slave_t *slave = share->slave;
735         int err = 0;
736         pthread_mutex_lock(&slave->mutex);
737         switch (share->state) {
738         case SND_PCM_STATE_OPEN:
739                 err = -EBADFD;
740                 goto _end;
741         case SND_PCM_STATE_PREPARED:
742                 share->state = SND_PCM_STATE_SETUP;
743                 break;
744         case SND_PCM_STATE_SETUP:
745         case SND_PCM_STATE_DRAINING:
746                 goto _end;
747         case SND_PCM_STATE_XRUN:
748                 if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
749                         share->state = SND_PCM_STATE_SETUP;
750                         break;
751                 }
752                 /* Fall through */
753         case SND_PCM_STATE_RUNNING:
754                 if (snd_pcm_mmap_avail(pcm) <= 0) {
755                         share->state = SND_PCM_STATE_SETUP;
756                         break;
757                 }
758                 share->draining_silence = 0;
759                 share->state = SND_PCM_STATE_DRAINING;
760                 break;
761         }
762  _end:
763         pthread_mutex_unlock(&slave->mutex);
764         return err;
765 }
766
767 static int snd_pcm_share_pause(snd_pcm_t *pcm ATTRIBUTE_UNUSED, int enable ATTRIBUTE_UNUSED)
768 {
769         return -ENOSYS;
770 }
771
772 static int snd_pcm_share_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
773 {
774         snd_pcm_share_t *share = pcm->private;
775         snd_pcm_share_slave_t *slave = share->slave;
776         unsigned int channel = info->channel;
777         int c = share->slave_channels[channel];
778         int err;
779         info->channel = c;
780         err = snd_pcm_channel_info(slave->pcm, info);
781         info->channel = channel;
782         return err;
783 }
784
785 static int snd_pcm_share_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t *params)
786 {
787         snd_pcm_share_t *share = pcm->private;
788         snd_pcm_share_slave_t *slave = share->slave;
789         unsigned int channel = params->channel;
790         int c = share->slave_channels[channel];
791         int err;
792         params->channel = c;
793         err = snd_pcm_channel_params(slave->pcm, params);
794         params->channel = channel;
795         return err;
796 }
797
798 static int snd_pcm_share_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t *setup)
799 {
800         snd_pcm_share_t *share = pcm->private;
801         snd_pcm_share_slave_t *slave = share->slave;
802         unsigned int channel = setup->channel;
803         int c = share->slave_channels[channel];
804         int err;
805         setup->channel = c;
806         err = snd_pcm_channel_setup(slave->pcm, setup);
807         setup->channel = channel;
808         if (err < 0)
809                 return err;
810         if (!pcm->mmap_info)
811                 return 0;
812         switch (pcm->setup.mmap_shape) {
813         case SND_PCM_MMAP_INTERLEAVED:
814         case SND_PCM_MMAP_COMPLEX:
815                 setup->stopped_area.addr = share->stopped_data;
816                 setup->stopped_area.first = channel * pcm->bits_per_sample;
817                 setup->stopped_area.step = pcm->bits_per_frame;
818                 break;
819         case SND_PCM_MMAP_NONINTERLEAVED:
820                 setup->stopped_area.addr = share->stopped_data + c * pcm->setup.buffer_size * pcm->bits_per_sample / 8;
821                 setup->stopped_area.first = 0;
822                 setup->stopped_area.step = pcm->bits_per_sample;
823                 break;
824         default:
825                 assert(0);
826         }
827         return 0;
828 }
829
830 static ssize_t snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
831 {
832         snd_pcm_share_t *share = pcm->private;
833         snd_pcm_share_slave_t *slave = share->slave;
834         int ret = -EBADFD;
835         ssize_t n;
836         switch (share->state) {
837         case SND_PCM_STATE_RUNNING:
838                 break;
839         case SND_PCM_STATE_PREPARED:
840                 if (pcm->stream != SND_PCM_STREAM_PLAYBACK)
841                         return -EBADFD;
842                 break;
843         case SND_PCM_STATE_DRAINING:
844                 if (pcm->stream != SND_PCM_STREAM_CAPTURE)
845                         return -EBADFD;
846                 break;
847         case SND_PCM_STATE_XRUN:
848                 return -EPIPE;
849         default:
850                 goto _err;
851         }
852         n = snd_pcm_mmap_hw_avail(pcm);
853         assert(n >= 0);
854         if (n > 0) {
855                 if ((size_t)n > frames)
856                         n = frames;
857                 frames -= n;
858         }
859         if (share->state == SND_PCM_STATE_RUNNING &&
860             frames > 0) {
861                 pthread_mutex_lock(&slave->mutex);
862                 ret = snd_pcm_rewind(slave->pcm, frames);
863                 pthread_mutex_unlock(&slave->mutex);
864                 if (ret < 0) {
865                         if (n <= 0)
866                                 return ret;
867                         goto _end;
868                 }
869                 n += ret;
870         }
871  _end:
872         snd_pcm_mmap_appl_backward(pcm, n);
873         ret = n;
874  _err:
875         return ret;
876 }
877
878 static int snd_pcm_share_channels_mask(snd_pcm_t *pcm, bitset_t *cmask)
879 {
880         snd_pcm_share_t *share = pcm->private;
881         snd_pcm_share_slave_t *slave = share->slave;
882         unsigned int i;
883         bitset_t m[bitset_size(slave->channels_count)];
884         int err = snd_pcm_channels_mask(slave->pcm, m);
885         if (err < 0)
886                 return err;
887         for (i = 0; i < share->channels_count; ++i) {
888                 if (!bitset_get(m, share->slave_channels[i]))
889                         bitset_reset(cmask, i);
890         }
891         return 0;
892 }
893                 
894 int snd_pcm_share_poll_descriptor(snd_pcm_t *pcm)
895 {
896         snd_pcm_share_t *share = pcm->private;
897         return share->client_socket;
898 }
899
900 static void snd_pcm_share_dump(snd_pcm_t *pcm, FILE *fp)
901 {
902         snd_pcm_share_t *share = pcm->private;
903         snd_pcm_share_slave_t *slave = share->slave;
904         unsigned int k;
905         fprintf(fp, "Share PCM\n");
906         fprintf(fp, "\nChannel bindings:\n");
907         for (k = 0; k < share->channels_count; ++k)
908                 fprintf(fp, "%d: %d\n", k, share->slave_channels[k]);
909         if (pcm->valid_setup) {
910                 fprintf(fp, "\nIts setup is:\n");
911                 snd_pcm_dump_setup(pcm, fp);
912         }
913         fprintf(fp, "Slave: ");
914         snd_pcm_dump(slave->pcm, fp);
915 }
916
917 snd_pcm_ops_t snd_pcm_share_ops = {
918         close: snd_pcm_share_close,
919         info: snd_pcm_share_info,
920         params_info: snd_pcm_share_params_info,
921         params: snd_pcm_share_params,
922         setup: snd_pcm_share_setup,
923         channel_info: snd_pcm_share_channel_info,
924         channel_params: snd_pcm_share_channel_params,
925         channel_setup: snd_pcm_share_channel_setup,
926         dump: snd_pcm_share_dump,
927         nonblock: snd_pcm_share_nonblock,
928         async: snd_pcm_share_async,
929         mmap: snd_pcm_share_mmap,
930         munmap: snd_pcm_share_munmap,
931 };
932
933 snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
934         status: snd_pcm_share_status,
935         state: snd_pcm_share_state,
936         delay: snd_pcm_share_delay,
937         prepare: snd_pcm_share_prepare,
938         start: snd_pcm_share_start,
939         drop: snd_pcm_share_drop,
940         drain: snd_pcm_share_drain,
941         pause: snd_pcm_share_pause,
942         writei: snd_pcm_mmap_writei,
943         writen: snd_pcm_mmap_writen,
944         readi: snd_pcm_mmap_readi,
945         readn: snd_pcm_mmap_readn,
946         rewind: snd_pcm_share_rewind,
947         channels_mask: snd_pcm_share_channels_mask,
948         avail_update: snd_pcm_share_avail_update,
949         mmap_forward: snd_pcm_share_mmap_forward,
950 };
951
952 int snd_pcm_share_open(snd_pcm_t **pcmp, char *name, char *sname,
953                        size_t schannels_count,
954                        size_t channels_count, int *channels_map,
955                        int stream, int mode)
956 {
957         snd_pcm_t *pcm;
958         snd_pcm_share_t *share;
959         int err;
960         struct list_head *i;
961         char slave_map[32] = { 0 };
962         unsigned int k;
963         snd_pcm_share_slave_t *slave = NULL;
964         int sd[2];
965
966         assert(pcmp);
967         assert(channels_count > 0 && sname && channels_map);
968
969         for (k = 0; k < channels_count; ++k) {
970                 if (channels_map[k] < 0 || channels_map[k] > 31) {
971                         ERR("Invalid slave channel (%d) in binding", channels_map[k]);
972                         return -EINVAL;
973                 }
974                 if (slave_map[channels_map[k]]) {
975                         ERR("Repeated slave channel (%d) in binding", channels_map[k]);
976                         return -EINVAL;
977                 }
978                 slave_map[channels_map[k]] = 1;
979                 assert((unsigned)channels_map[k] < schannels_count);
980         }
981
982         share = calloc(1, sizeof(snd_pcm_share_t));
983         if (!share)
984                 return -ENOMEM;
985
986         share->channels_count = channels_count;
987         share->slave_channels = calloc(channels_count, sizeof(*share->slave_channels));
988         if (!share->slave_channels) {
989                 free(share);
990                 return -ENOMEM;
991         }
992         memcpy(share->slave_channels, channels_map, channels_count * sizeof(*share->slave_channels));
993
994         pcm = calloc(1, sizeof(snd_pcm_t));
995         if (!pcm) {
996                 free(share->slave_channels);
997                 free(share);
998                 return -ENOMEM;
999         }
1000         err = socketpair(AF_LOCAL, SOCK_STREAM, 0, sd);
1001         if (err >= 0 && stream == SND_PCM_STREAM_PLAYBACK) {
1002                 int bufsize = 1;
1003                 err = setsockopt(sd[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
1004                 if (err >= 0) {
1005                         struct pollfd pfd;
1006                         pfd.fd = sd[0];
1007                         pfd.events = POLLOUT;
1008                         while ((err = poll(&pfd, 1, 0)) == 1) {
1009                                 char buf[1];
1010                                 err = write(sd[0], buf, 1);
1011                                 assert(err != 0);
1012                                 if (err != 1)
1013                                         break;
1014                         }
1015                 }
1016         }
1017         if (err < 0) {
1018                 err = -errno;
1019                 free(pcm);
1020                 free(share->slave_channels);
1021                 free(share);
1022                 return err;
1023         }
1024
1025         pthread_mutex_lock(&slaves_mutex);
1026         for (i = slaves.next; i != &slaves; i = i->next) {
1027                 snd_pcm_share_slave_t *s = list_entry(i, snd_pcm_share_slave_t, list);
1028                 if (s->pcm->name && strcmp(s->pcm->name, sname)) {
1029                         slave = s;
1030                         break;
1031                 }
1032         }
1033         if (!slave) {
1034                 snd_pcm_t *spcm;
1035                 err = snd_pcm_open(&spcm, sname, stream, mode);
1036                 if (err < 0) {
1037                         pthread_mutex_unlock(&slaves_mutex);
1038                         close(sd[0]);
1039                         close(sd[1]);
1040                         free(pcm);
1041                         free(share->slave_channels);
1042                         free(share);
1043                         return err;
1044                 }
1045                 slave = calloc(1, sizeof(*slave));
1046                 if (!slave) {
1047                         pthread_mutex_unlock(&slaves_mutex);
1048                         snd_pcm_close(spcm);
1049                         close(sd[0]);
1050                         close(sd[1]);
1051                         free(pcm);
1052                         free(share->slave_channels);
1053                         free(share);
1054                         return err;
1055                 }
1056                 INIT_LIST_HEAD(&slave->clients);
1057                 slave->pcm = spcm;
1058                 slave->channels_count = schannels_count;
1059                 pthread_mutex_init(&slave->mutex, NULL);
1060                 list_add_tail(&slave->list, &slaves);
1061         }
1062         pthread_mutex_unlock(&slaves_mutex);
1063
1064         pthread_mutex_lock(&slave->mutex);
1065         if (slave->open_count == 0) {
1066                 err = pthread_create(&slave->thread, NULL, snd_pcm_share_slave_thread, slave);
1067                 assert(err == 0);
1068         }
1069         slave->open_count++;
1070         list_add_tail(&share->list, &slave->clients);
1071         pthread_mutex_unlock(&slave->mutex);
1072
1073         share->slave = slave;
1074         share->pcm = pcm;
1075         share->client_socket = sd[0];
1076         share->slave_socket = sd[1];
1077         share->async_sig = SIGIO;
1078         share->async_pid = getpid();
1079         
1080         if (name)
1081                 pcm->name = strdup(name);
1082         pcm->type = SND_PCM_TYPE_SHARE;
1083         pcm->stream = stream;
1084         pcm->mode = mode;
1085         pcm->mmap_auto = 1;
1086         pcm->ops = &snd_pcm_share_ops;
1087         pcm->op_arg = pcm;
1088         pcm->fast_ops = &snd_pcm_share_fast_ops;
1089         pcm->fast_op_arg = pcm;
1090         pcm->private = share;
1091         pcm->poll_fd = share->client_socket;
1092         pcm->hw_ptr = &share->hw_ptr;
1093         pcm->appl_ptr = &share->appl_ptr;
1094         *pcmp = pcm;
1095         return 0;
1096 }
1097
1098 int _snd_pcm_share_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf,
1099                         int stream, int mode)
1100 {
1101         snd_config_iterator_t i;
1102         char *sname = NULL;
1103         snd_config_t *binding = NULL;
1104         int err;
1105         unsigned int idx;
1106         int *channels_map;
1107         size_t channels_count = 0;
1108         long schannels_count = -1;
1109         size_t schannel_max = 0;
1110         snd_config_foreach(i, conf) {
1111                 snd_config_t *n = snd_config_entry(i);
1112                 if (strcmp(n->id, "comment") == 0)
1113                         continue;
1114                 if (strcmp(n->id, "type") == 0)
1115                         continue;
1116                 if (strcmp(n->id, "stream") == 0)
1117                         continue;
1118                 if (strcmp(n->id, "sname") == 0) {
1119                         err = snd_config_string_get(n, &sname);
1120                         if (err < 0) {
1121                                 ERR("Invalid type for sname");
1122                                 return -EINVAL;
1123                         }
1124                         continue;
1125                 }
1126                 if (strcmp(n->id, "schannels") == 0) {
1127                         err = snd_config_integer_get(n, &schannels_count);
1128                         if (err < 0) {
1129                                 ERR("Invalid type for schannels");
1130                                 return -EINVAL;
1131                         }
1132                         continue;
1133                 }
1134                 if (strcmp(n->id, "binding") == 0) {
1135                         if (snd_config_type(n) != SND_CONFIG_TYPE_COMPOUND) {
1136                                 ERR("Invalid type for binding");
1137                                 return -EINVAL;
1138                         }
1139                         binding = n;
1140                         continue;
1141                 }
1142                 ERR("Unknown field: %s", n->id);
1143                 return -EINVAL;
1144         }
1145         if (!sname) {
1146                 ERR("sname is not defined");
1147                 return -EINVAL;
1148         }
1149         if (!binding) {
1150                 ERR("binding is not defined");
1151                 return -EINVAL;
1152         }
1153         snd_config_foreach(i, binding) {
1154                 int cchannel = -1;
1155                 char *p;
1156                 snd_config_t *n = snd_config_entry(i);
1157                 errno = 0;
1158                 cchannel = strtol(n->id, &p, 10);
1159                 if (errno || *p || cchannel < 0) {
1160                         ERR("Invalid client channel in binding: %s", n->id);
1161                         return -EINVAL;
1162                 }
1163                 if ((unsigned)cchannel > channels_count)
1164                         channels_count = cchannel + 1;
1165         }
1166         if (channels_count == 0) {
1167                 ERR("No bindings defined");
1168                 return -EINVAL;
1169         }
1170         channels_map = calloc(channels_count, sizeof(*channels_map));
1171         for (idx = 0; idx < channels_count; ++idx)
1172                 channels_map[idx] = -1;
1173
1174         snd_config_foreach(i, binding) {
1175                 snd_config_t *n = snd_config_entry(i);
1176                 long cchannel;
1177                 long schannel = -1;
1178                 cchannel = strtol(n->id, 0, 10);
1179                 err = snd_config_integer_get(n, &schannel);
1180                 if (err < 0)
1181                         goto _free;
1182                 assert(schannels_count <= 0 || schannel < schannels_count);
1183                 channels_map[cchannel] = schannel;
1184                 if ((unsigned)schannel > schannel_max)
1185                         schannel_max = schannel;
1186         }
1187         if (schannels_count <= 0)
1188                 schannels_count = schannel_max + 1;
1189             err = snd_pcm_share_open(pcmp, name, sname, schannels_count,
1190                                  channels_count, channels_map, stream, mode);
1191 _free:
1192         free(channels_map);
1193         return err;
1194 }