• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/iserver/alsa-lib-1.0.26/src/pcm/

Lines Matching defs:dmix

4  * \brief PCM Direct Stream Mixing (dmix) Plugin Interface
62 static int shm_sum_discard(snd_pcm_direct_t *dmix);
67 static int shm_sum_create_or_connect(snd_pcm_direct_t *dmix)
73 size = dmix->shmptr->s.channels *
74 dmix->shmptr->s.buffer_size *
77 dmix->u.dmix.shmid_sum = shmget(dmix->ipc_key + 1, size,
78 IPC_CREAT | dmix->ipc_perm);
80 if (dmix->u.dmix.shmid_sum < 0) {
82 if ((tmpid = shmget(dmix->ipc_key + 1, 0, dmix->ipc_perm)) != -1)
90 if (shmctl(dmix->u.dmix.shmid_sum, IPC_STAT, &buf) < 0) {
92 shm_sum_discard(dmix);
95 if (dmix->ipc_gid >= 0) {
96 buf.shm_perm.gid = dmix->ipc_gid;
97 shmctl(dmix->u.dmix.shmid_sum, IPC_SET, &buf);
99 dmix->u.dmix.sum_buffer = shmat(dmix->u.dmix.shmid_sum, 0, 0);
100 if (dmix->u.dmix.sum_buffer == (void *) -1) {
102 shm_sum_discard(dmix);
105 mlock(dmix->u.dmix.sum_buffer, size);
109 static int shm_sum_discard(snd_pcm_direct_t *dmix)
114 if (dmix->u.dmix.shmid_sum < 0)
116 if (dmix->u.dmix.sum_buffer != (void *) -1 && shmdt(dmix->u.dmix.sum_buffer) < 0)
118 dmix->u.dmix.sum_buffer = (void *) -1;
119 if (shmctl(dmix->u.dmix.shmid_sum, IPC_STAT, &buf) < 0)
122 if (shmctl(dmix->u.dmix.shmid_sum, IPC_RMID, NULL) < 0)
126 dmix->u.dmix.shmid_sum = -1;
130 static void dmix_server_free(snd_pcm_direct_t *dmix)
133 shm_sum_create_or_connect(dmix);
134 shm_sum_discard(dmix);
154 static void mix_areas(snd_pcm_direct_t *dmix,
165 channels = dmix->channels;
166 switch (dmix->shmptr->s.format) {
170 do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_16;
175 do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_32;
179 do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_24;
183 do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_24;
187 do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_u8;
192 if (dmix->interleaved) {
200 dmix->u.dmix.sum_buffer + dst_ofs * channels,
207 dchn = dmix->bindings ? dmix->bindings[chn] : chn;
208 if (dchn >= dmix->shmptr->s.channels)
215 dmix->u.dmix.sum_buffer + channels * dst_ofs + chn,
222 static void remix_areas(snd_pcm_direct_t *dmix,
233 channels = dmix->channels;
234 switch (dmix->shmptr->s.format) {
238 do_remix_areas = (mix_areas_t *)dmix->u.dmix.remix_areas_16;
243 do_remix_areas = (mix_areas_t *)dmix->u.dmix.remix_areas_32;
247 do_remix_areas = (mix_areas_t *)dmix->u.dmix.remix_areas_24;
251 do_remix_areas = (mix_areas_t *)dmix->u.dmix.remix_areas_24;
255 do_remix_areas = (mix_areas_t *)dmix->u.dmix.remix_areas_u8;
260 if (dmix->interleaved) {
268 dmix->u.dmix.sum_buffer + dst_ofs * channels,
275 dchn = dmix->bindings ? dmix->bindings[chn] : chn;
276 if (dchn >= dmix->shmptr->s.channels)
283 dmix->u.dmix.sum_buffer + channels * dst_ofs + chn,
296 #define dmix_down_sem(dmix) snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT)
297 #define dmix_up_sem(dmix) snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT)
299 #define dmix_down_sem(dmix)
300 #define dmix_up_sem(dmix)
309 snd_pcm_direct_t *dmix = pcm->private_data;
318 size = dmix->appl_ptr - dmix->last_appl_ptr;
326 if (dmix->slave_hw_ptr <= dmix->slave_appl_ptr)
327 slave_size = dmix->slave_appl_ptr - dmix->slave_hw_ptr;
329 slave_size = dmix->slave_appl_ptr + (dmix->slave_boundary - dmix->slave_hw_ptr);
330 if (slave_size > dmix->slave_buffer_size) {
331 transfer = dmix->slave_buffer_size - slave_size;
334 dmix->last_appl_ptr += transfer;
335 dmix->last_appl_ptr %= pcm->boundary;
336 dmix->slave_appl_ptr += transfer;
337 dmix->slave_appl_ptr %= dmix->slave_boundary;
338 size = dmix->appl_ptr - dmix->last_appl_ptr;
346 slave_hw_ptr = dmix->slave_hw_ptr;
350 slave_hw_ptr -= slave_hw_ptr % dmix->slave_period_size;
351 slave_hw_ptr += dmix->slave_buffer_size;
352 if (slave_hw_ptr >= dmix->slave_boundary)
353 slave_hw_ptr -= dmix->slave_boundary;
354 if (slave_hw_ptr < dmix->slave_appl_ptr)
355 slave_size = slave_hw_ptr + (dmix->slave_boundary - dmix->slave_appl_ptr);
357 slave_size = slave_hw_ptr - dmix->slave_appl_ptr;
365 dst_areas = snd_pcm_mmap_areas(dmix->spcm);
366 appl_ptr = dmix->last_appl_ptr % pcm->buffer_size;
367 dmix->last_appl_ptr += size;
368 dmix->last_appl_ptr %= pcm->boundary;
369 slave_appl_ptr = dmix->slave_appl_ptr % dmix->slave_buffer_size;
370 dmix->slave_appl_ptr += size;
371 dmix->slave_appl_ptr %= dmix->slave_boundary;
372 dmix_down_sem(dmix);
377 if (slave_appl_ptr + transfer > dmix->slave_buffer_size)
378 transfer = dmix->slave_buffer_size - slave_appl_ptr;
379 mix_areas(dmix, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
384 slave_appl_ptr %= dmix->slave_buffer_size;
388 dmix_up_sem(dmix);
396 snd_pcm_direct_t *dmix = pcm->private_data;
400 switch (snd_pcm_state(dmix->spcm)) {
402 dmix->state = SND_PCM_STATE_DISCONNECTED;
407 if (dmix->slowptr)
408 snd_pcm_hwsync(dmix->spcm);
409 old_slave_hw_ptr = dmix->slave_hw_ptr;
410 slave_hw_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
414 if (dmix->state != SND_PCM_STATE_RUNNING &&
415 dmix->state != SND_PCM_STATE_DRAINING)
419 slave_hw_ptr += dmix->slave_boundary;
422 dmix->hw_ptr += diff;
423 dmix->hw_ptr %= pcm->boundary;
427 if (avail > dmix->avail_max)
428 dmix->avail_max = avail;
430 snd_timer_stop(dmix->timer);
431 gettimestamp(&dmix->trigger_tstamp, pcm->monotonic);
432 if (dmix->state == SND_PCM_STATE_RUNNING) {
433 dmix->state = SND_PCM_STATE_XRUN;
436 dmix->state = SND_PCM_STATE_SETUP;
438 snd_pcm_direct_clear_timer_queue(dmix);
449 snd_pcm_direct_t *dmix = pcm->private_data;
451 state = snd_pcm_state(dmix->spcm);
460 if (dmix->state == STATE_RUN_PENDING)
462 return dmix->state;
467 snd_pcm_direct_t *dmix = pcm->private_data;
469 switch (dmix->state) {
479 status->trigger_tstamp = dmix->trigger_tstamp;
482 status->avail_max = status->avail > dmix->avail_max ? status->avail : dmix->avail_max;
483 dmix->avail_max = 0;
489 snd_pcm_direct_t *dmix = pcm->private_data;
492 switch(dmix->state) {
515 snd_pcm_direct_t *dmix = pcm->private_data;
517 switch(dmix->state) {
537 snd_pcm_direct_t *dmix = pcm->private_data;
539 snd_pcm_direct_check_interleave(dmix, pcm);
540 dmix->state = SND_PCM_STATE_PREPARED;
541 dmix->appl_ptr = dmix->last_appl_ptr = 0;
542 dmix->hw_ptr = 0;
543 return snd_pcm_direct_set_timer_params(dmix);
546 static void reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
548 dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr;
555 dmix->slave_appl_ptr = ((dmix->slave_appl_ptr + dmix->slave_period_size - 1)
556 / dmix->slave_period_size) * dmix->slave_period_size;
561 snd_pcm_direct_t *dmix = pcm->private_data;
562 dmix->hw_ptr %= pcm->period_size;
563 dmix->appl_ptr = dmix->last_appl_ptr = dmix->hw_ptr;
564 reset_slave_ptr(pcm, dmix);
568 static int snd_pcm_dmix_start_timer(snd_pcm_t *pcm, snd_pcm_direct_t *dmix)
572 snd_pcm_hwsync(dmix->spcm);
573 reset_slave_ptr(pcm, dmix);
574 err = snd_timer_start(dmix->timer);
577 dmix->state = SND_PCM_STATE_RUNNING;
583 snd_pcm_direct_t *dmix = pcm->private_data;
587 if (dmix->state != SND_PCM_STATE_PREPARED)
591 dmix->state = STATE_RUN_PENDING;
595 if ((err = snd_pcm_dmix_start_timer(pcm, dmix)) < 0)
599 gettimestamp(&dmix->trigger_tstamp, pcm->monotonic);
605 snd_pcm_direct_t *dmix = pcm->private_data;
606 if (dmix->state == SND_PCM_STATE_OPEN)
608 dmix->state = SND_PCM_STATE_SETUP;
609 snd_pcm_direct_timer_stop(dmix);
615 snd_pcm_direct_t *dmix = pcm->private_data;
619 if (dmix->state == SND_PCM_STATE_OPEN)
623 if (dmix->state == SND_PCM_STATE_PREPARED) {
632 if (dmix->state == SND_PCM_STATE_XRUN) {
640 dmix->state = SND_PCM_STATE_DRAINING;
647 if (dmix->state == SND_PCM_STATE_DRAINING) {
650 snd_pcm_direct_clear_timer_queue(dmix); /* force poll to wait */
652 } while (dmix->state == SND_PCM_STATE_DRAINING);
669 snd_pcm_direct_t *dmix = pcm->private_data;
674 if (dmix->state == SND_PCM_STATE_RUNNING ||
675 dmix->state == SND_PCM_STATE_DRAINING)
678 if (dmix->last_appl_ptr < dmix->appl_ptr)
679 size = dmix->appl_ptr - dmix->last_appl_ptr;
681 size = dmix->appl_ptr + (pcm->boundary - dmix->last_appl_ptr);
690 if (dmix->hw_ptr < dmix->appl_ptr)
691 size = dmix->appl_ptr - dmix->hw_ptr;
693 size = dmix->appl_ptr + (pcm->boundary - dmix->hw_ptr);
696 if (dmix->slave_hw_ptr < dmix->slave_appl_ptr)
697 slave_size = dmix->slave_appl_ptr - dmix->slave_hw_ptr;
699 slave_size = dmix->slave_appl_ptr + (pcm->boundary - dmix->slave_hw_ptr);
707 dst_areas = snd_pcm_mmap_areas(dmix->spcm);
708 dmix->last_appl_ptr -= size;
709 dmix->last_appl_ptr %= pcm->boundary;
710 appl_ptr = dmix->last_appl_ptr % pcm->buffer_size;
711 dmix->slave_appl_ptr -= size;
712 dmix->slave_appl_ptr %= dmix->slave_boundary;
713 slave_appl_ptr = dmix->slave_appl_ptr % dmix->slave_buffer_size;
714 dmix_down_sem(dmix);
719 if (slave_appl_ptr + transfer > dmix->slave_buffer_size)
720 transfer = dmix->slave_buffer_size - slave_appl_ptr;
721 remix_areas(dmix, src_areas, dst_areas, appl_ptr, slave_appl_ptr, transfer);
726 slave_appl_ptr %= dmix->slave_buffer_size;
730 dmix->last_appl_ptr -= frames;
731 dmix->last_appl_ptr %= pcm->boundary;
732 dmix->slave_appl_ptr -= frames;
733 dmix->slave_appl_ptr %= dmix->slave_boundary;
734 dmix_up_sem(dmix);
771 snd_pcm_direct_t *dmix = pcm->private_data;
773 if (dmix->timer)
774 snd_timer_close(dmix->timer);
775 snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
776 snd_pcm_close(dmix->spcm);
777 if (dmix->server)
778 snd_pcm_direct_server_discard(dmix);
779 if (dmix->client)
780 snd_pcm_direct_client_discard(dmix);
781 shm_sum_discard(dmix);
782 if (snd_pcm_direct_shm_discard(dmix)) {
783 if (snd_pcm_direct_semaphore_discard(dmix))
784 snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
786 snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
787 free(dmix->bindings);
789 free(dmix);
797 snd_pcm_direct_t *dmix = pcm->private_data;
800 switch (snd_pcm_state(dmix->spcm)) {
811 if (dmix->state == STATE_RUN_PENDING) {
812 if ((err = snd_pcm_dmix_start_timer(pcm, dmix)) < 0)
814 } else if (dmix->state == SND_PCM_STATE_RUNNING ||
815 dmix->state == SND_PCM_STATE_DRAINING)
817 if (dmix->state == SND_PCM_STATE_RUNNING ||
818 dmix->state == SND_PCM_STATE_DRAINING) {
824 snd_pcm_direct_clear_timer_queue(dmix);
831 snd_pcm_direct_t *dmix = pcm->private_data;
833 if (dmix->state == SND_PCM_STATE_RUNNING ||
834 dmix->state == SND_PCM_STATE_DRAINING)
843 snd_pcm_direct_t *dmix = pcm->private_data;
848 if (dmix->state == SND_PCM_STATE_RUNNING ||
849 dmix->state == SND_PCM_STATE_DRAINING)
855 *tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm);
862 snd_pcm_direct_t *dmix = pcm->private_data;
863 if (dmix->state == SND_PCM_STATE_RUNNING)
871 snd_pcm_direct_t *dmix = pcm->private_data;
878 if (dmix->spcm)
879 snd_pcm_dump(dmix->spcm, out);
929 * \brief Creates a new dmix PCM
950 snd_pcm_direct_t *dmix = NULL;
957 SNDERR("The dmix plugin supports only playback stream");
961 dmix = calloc(1, sizeof(snd_pcm_direct_t));
962 if (!dmix) {
967 ret = snd_pcm_direct_parse_bindings(dmix, params, opts->bindings);
971 dmix->ipc_key = opts->ipc_key;
972 dmix->ipc_perm = opts->ipc_perm;
973 dmix->ipc_gid = opts->ipc_gid;
974 dmix->semid = -1;
975 dmix->shmid = -1;
977 ret = snd_pcm_new(&pcm, dmix->type = SND_PCM_TYPE_DMIX, name, stream, mode);
983 ret = snd_pcm_direct_semaphore_create_or_connect(dmix);
988 ret = snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
990 snd_pcm_direct_semaphore_discard(dmix);
998 first_instance = ret = snd_pcm_direct_shm_create_or_connect(dmix);
1006 pcm->private_data = dmix;
1007 dmix->state = SND_PCM_STATE_OPEN;
1008 dmix->slowptr = opts->slowptr;
1009 dmix->max_periods = opts->max_periods;
1010 dmix->sync_ptr = snd_pcm_dmix_sync_ptr;
1023 SNDERR("dmix plugin can be only connected to hw plugin");
1028 ret = snd_pcm_direct_initialize_slave(dmix, spcm, params);
1034 dmix->spcm = spcm;
1036 if (dmix->shmptr->use_server) {
1037 dmix->server_free = dmix_server_free;
1039 ret = snd_pcm_direct_server_create(dmix);
1046 dmix->shmptr->type = spcm->type;
1048 if (dmix->shmptr->use_server) {
1050 snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
1051 ret = snd_pcm_direct_client_connect(dmix);
1057 snd_pcm_direct_semaphore_down(dmix, DIRECT_IPC_SEM_CLIENT);
1058 ret = snd_pcm_direct_open_secondary_client(&spcm, dmix, "dmix_client");
1072 SNDERR("dmix plugin can be only connected to hw plugin");
1077 ret = snd_pcm_direct_initialize_secondary_slave(dmix, spcm, params);
1084 dmix->spcm = spcm;
1087 ret = shm_sum_create_or_connect(dmix);
1093 ret = snd_pcm_direct_initialize_poll_fd(dmix);
1099 mix_select_callbacks(dmix);
1101 pcm->poll_fd = dmix->poll_fd;
1105 snd_pcm_set_hw_ptr(pcm, &dmix->hw_ptr, -1, 0);
1106 snd_pcm_set_appl_ptr(pcm, &dmix->appl_ptr, -1, 0);
1108 if (dmix->channels == UINT_MAX)
1109 dmix->channels = dmix->shmptr->s.channels;
1111 snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
1117 if (dmix->timer)
1118 snd_timer_close(dmix->timer);
1119 if (dmix->server)
1120 snd_pcm_direct_server_discard(dmix);
1121 if (dmix->client)
1122 snd_pcm_direct_client_discard(dmix);
1125 if (dmix->u.dmix.shmid_sum >= 0)
1126 shm_sum_discard(dmix);
1127 if (dmix->shmid >= 0)
1128 snd_pcm_direct_shm_discard(dmix);
1129 if (snd_pcm_direct_semaphore_discard(dmix) < 0)
1130 snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
1132 if (dmix) {
1133 free(dmix->bindings);
1134 free(dmix);
1143 \section pcm_plugins_dmix Plugin: dmix
1151 type dmix # Direct mix
1180 This number must be unique for each different dmix definition,
1187 Note that the dmix plugin itself supports only a single configuration.
1199 type dmix
1209 You can hear 48000 Hz samples still using this dmix pcm via plug plugin
1215 For using the dmix plugin for OSS emulation device, you have to set
1219 type dmix
1242 so that only the first two channels are used by dmix.
1257 * \brief Creates a new dmix PCM
1261 * \param conf Configuration node with dmix PCM description