Lines Matching defs:pcm

185 static int oops(struct pcm *pcm, int e, const char *fmt, ...);
329 int param_set_hw_refine(struct pcm *pcm, struct snd_pcm_hw_params *params)
331 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_REFINE, params)) {
338 int param_set_hw_params(struct pcm *pcm, struct snd_pcm_hw_params *params)
340 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_PARAMS, params)) {
343 pcm->hw_p = params;
347 int param_set_sw_params(struct pcm *pcm, struct snd_pcm_sw_params *sparams)
349 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, sparams)) {
352 pcm->sw_p = sparams;
376 const char* pcm_error(struct pcm *pcm)
378 return pcm->error;
381 static int oops(struct pcm *pcm, int e, const char *fmt, ...)
387 vsnprintf(pcm->error, PCM_ERROR_MAX, fmt, ap);
389 sz = strnlen(pcm->error, PCM_ERROR_MAX);
392 snprintf(pcm->error + sz, PCM_ERROR_MAX - sz,
397 long pcm_avail(struct pcm *pcm)
399 struct snd_pcm_sync_ptr *sync_ptr = pcm->sync_ptr;
400 if (pcm->flags & DEBUG_ON) {
403 pcm->buffer_size,
406 if (pcm->flags & PCM_IN) {
409 avail += pcm->sw_p->boundary;
412 long avail = sync_ptr->s.status.hw_ptr - sync_ptr->c.control.appl_ptr + ((pcm->flags & PCM_MONO) ? pcm->buffer_size/2 : pcm->buffer_size/4);
414 avail += pcm->sw_p->boundary;
415 else if ((unsigned long) avail >= pcm->sw_p->boundary)
416 avail -= pcm->sw_p->boundary;
421 int sync_ptr(struct pcm *pcm)
424 err = ioctl(pcm->fd, SNDRV_PCM_IOCTL_SYNC_PTR, pcm->sync_ptr);
434 int mmap_buffer(struct pcm *pcm)
440 int channels = (pcm->flags & PCM_MONO) ? 1 : 2;
442 size = pcm->buffer_size;
443 if (pcm->flags & DEBUG_ON)
445 pcm->addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
446 pcm->fd, 0);
447 if (pcm->addr)
456 * Hence destination address would be base address(pcm->addr) +
459 u_int8_t *dst_address(struct pcm *pcm)
462 struct snd_pcm_sync_ptr *sync_ptr = pcm->sync_ptr;
465 appl_ptr = (pcm->flags & PCM_MONO) ? sync_ptr->c.control.appl_ptr*2 : sync_ptr->c.control.appl_ptr*4;
466 pcm_offset = (appl_ptr % (unsigned long)pcm->buffer_size);
467 return pcm->addr + pcm_offset;
471 int mmap_transfer(struct pcm *pcm, void *data, unsigned offset,
474 struct snd_pcm_sync_ptr *sync_ptr = pcm->sync_ptr;
478 int channels = (pcm->flags & PCM_MONO) ? 1 : 2;
480 dst_addr = dst_address(pcm);
492 int mmap_transfer_capture(struct pcm *pcm, void *data, unsigned offset,
495 struct snd_pcm_sync_ptr *sync_ptr = pcm->sync_ptr;
500 int channels = (pcm->flags & PCM_MONO) ? 1 : 2;
501 unsigned int tmp = (pcm->flags & PCM_MONO) ? sync_ptr->c.control.appl_ptr*2 : sync_ptr->c.control.appl_ptr*4;
503 pcm_offset = (tmp % (unsigned long)pcm->buffer_size);
505 src_addr = pcm->addr + pcm_offset;
516 int pcm_prepare(struct pcm *pcm)
518 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE)) {
522 pcm->running = 1;
526 static int pcm_write_mmap(struct pcm *pcm, void *data, unsigned count)
532 frames = (pcm->flags & PCM_MONO) ? (count / 2) : (count / 4);
534 pcm->sync_ptr->flags = SNDRV_PCM_SYNC_PTR_APPL | SNDRV_PCM_SYNC_PTR_AVAIL_MIN;
535 err = sync_ptr(pcm);
539 pcm->underruns++;
540 pcm->running = 0;
541 pcm_prepare(pcm);
543 pcm->sync_ptr->c.control.appl_ptr += frames;
544 pcm->sync_ptr->flags = 0;
546 err = sync_ptr(pcm);
550 pcm->underruns++;
551 pcm->running = 0;
552 pcm_prepare(pcm);
554 bytes_written = pcm->sync_ptr->c.control.appl_ptr - pcm->sync_ptr->s.status.hw_ptr;
555 if ((bytes_written >= pcm->sw_p->start_threshold) && (!pcm->start)) {
556 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
561 pcm->underruns++;
562 pcm->running = 0;
563 pcm_prepare(pcm);
570 pcm->start = 1;
576 static int pcm_write_nmmap(struct pcm *pcm, void *data, unsigned count)
579 int channels = (pcm->flags & PCM_MONO) ? 1 : ((pcm->flags & PCM_5POINT1)? 6 : 2 );
581 if (pcm->flags & PCM_IN)
587 if (!pcm->running) {
588 if (pcm_prepare(pcm))
591 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {
595 pcm->underruns++;
596 pcm->running = 0;
601 if (pcm->flags & DEBUG_ON)
607 int pcm_write(struct pcm *pcm, void *data, unsigned count)
609 if (pcm->flags & PCM_MMAP)
610 return pcm_write_mmap(pcm, data, count);
612 return pcm_write_nmmap(pcm, data, count);
615 int pcm_read(struct pcm *pcm, void *data, unsigned count)
619 if (!(pcm->flags & PCM_IN))
623 if (pcm->flags & PCM_MONO) {
625 } else if (pcm->flags & PCM_QUAD) {
627 } else if (pcm->flags & PCM_5POINT1) {
634 if (!pcm->running) {
635 if (pcm_prepare(pcm))
637 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START)) {
641 pcm->running = 1;
643 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
647 pcm->underruns++;
648 pcm->running = 0;
658 static struct pcm bad_pcm = {
662 static int enable_timer(struct pcm *pcm) {
664 pcm->timer_fd = open("/dev/snd/timer", O_RDWR | O_NONBLOCK);
665 if (pcm->timer_fd < 0) {
666 close(pcm->fd);
673 if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_TREAD, &arg) < 0) {
679 sel.id.card = pcm->card_no;
680 sel.id.device = pcm->device_no;
681 if (pcm->flags & PCM_IN)
686 if (pcm->flags & DEBUG_ON) {
693 if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_SELECT, &sel) < 0) {
695 close(pcm->timer_fd);
696 close(pcm->fd);
704 if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_PARAMS, &timer_param)< 0) {
707 if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_START) < 0) {
708 close(pcm->timer_fd);
714 static int disable_timer(struct pcm *pcm) {
715 if (pcm == &bad_pcm)
717 if (ioctl(pcm->timer_fd, SNDRV_TIMER_IOCTL_STOP) < 0)
719 return close(pcm->timer_fd);
722 int pcm_close(struct pcm *pcm)
724 if (pcm == &bad_pcm)
727 if (pcm->flags & PCM_MMAP) {
728 disable_timer(pcm);
729 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_DROP) < 0) {
733 if (munmap(pcm->addr, pcm->buffer_size))
736 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) {
741 if (pcm->fd >= 0)
742 close(pcm->fd);
743 pcm->running = 0;
744 pcm->buffer_size = 0;
745 pcm->fd = -1;
746 if (pcm->sw_p)
747 free(pcm->sw_p);
748 if (pcm->hw_p)
749 free(pcm->hw_p);
750 if (pcm->sync_ptr)
751 free(pcm->sync_ptr);
752 free(pcm);
756 struct pcm *pcm_open(unsigned flags, char *device)
759 struct pcm *pcm;
772 pcm = calloc(1, sizeof(struct pcm));
773 if (!pcm)
779 free(pcm);
787 pcm->card_no = atoi(tmp);
790 pcm->device_no = atoi(tmp);
791 /* should be safe to assume pcm dev ID never exceed 99 */
792 if (pcm->device_no > 9)
801 pcm->card_no = atoi(tmp);
804 pcm->device_no = atoi(tmp);
805 /* should be safe to assume pcm dev ID never exceed 99 */
806 if (pcm->device_no > 9)
812 if (pcm->flags & DEBUG_ON)
815 pcm->sync_ptr = calloc(1, sizeof(struct snd_pcm_sync_ptr));
816 if (!pcm->sync_ptr) {
817 free(pcm);
820 pcm->flags = flags;
822 pcm->fd = open(dname, O_RDWR|O_NONBLOCK);
823 if (pcm->fd < 0) {
824 free(pcm->sync_ptr);
825 free(pcm);
830 if (fcntl(pcm->fd, F_SETFL, fcntl(pcm->fd, F_GETFL) &
832 close(pcm->fd);
833 free(pcm->sync_ptr);
834 free(pcm);
839 if (pcm->flags & PCM_MMAP)
840 enable_timer(pcm);
842 if (pcm->flags & DEBUG_ON)
844 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_INFO, &info)) {
847 if (pcm->flags & DEBUG_ON)
850 return pcm;
853 int pcm_ready(struct pcm *pcm)
855 return pcm->fd >= 0;