comparison libao2/ao_alsa1x.c @ 6749:7f619a5d6eb8

added real mmap support support for -abs opt, 4 different modes
author joyping
date Thu, 18 Jul 2002 16:09:54 +0000
parents df3bf0f971d1
children a5b2b377ab50
comparison
equal deleted inserted replaced
6748:c0e8034d47e4 6749:7f619a5d6eb8
12 #include <errno.h> 12 #include <errno.h>
13 #include <sys/time.h> 13 #include <sys/time.h>
14 #include <stdlib.h> 14 #include <stdlib.h>
15 #include <math.h> 15 #include <math.h>
16 #include <string.h> 16 #include <string.h>
17 #include <sys/poll.h>
17 18
18 #include "../config.h" 19 #include "../config.h"
19 20
20 #if HAVE_SYS_ASOUNDLIB_H 21 #if HAVE_SYS_ASOUNDLIB_H
21 #include <sys/asoundlib.h> 22 #include <sys/asoundlib.h>
46 static snd_pcm_format_t alsa_format; 47 static snd_pcm_format_t alsa_format;
47 static snd_pcm_hw_params_t *alsa_hwparams; 48 static snd_pcm_hw_params_t *alsa_hwparams;
48 static snd_pcm_sw_params_t *alsa_swparams; 49 static snd_pcm_sw_params_t *alsa_swparams;
49 static char *alsa_device; 50 static char *alsa_device;
50 51
51 /* possible 4096, original 8192, OUTBURST is set statically to 512 in config.h */ 52 /* possible 4096, original 8192
52 static int alsa_fragsize = 4096; //OUTBURST 53 * was only needed for calculating chunksize? */
53 static int alsa_fragcount = 8; 54 static int alsa_fragsize = 4096;
54 55 /* 16 sets buffersize to 16 * chunksize is as default 1024
55 static int chunk_size = -1; 56 * which seems to be good avarge for most situations
57 * so buffersize is 16384 frames by default */
58 static int alsa_fragcount = 16;
59 static int chunk_size = 1024; //is alsa_fragsize / 4
60
56 static size_t bits_per_sample, bits_per_frame; 61 static size_t bits_per_sample, bits_per_frame;
57 static size_t chunk_bytes; 62 static size_t chunk_bytes;
58 63
59 int ao_mmap = 0; 64 int ao_mmap = 0;
60 int ao_noblock = 0; 65 int ao_noblock = 0;
66 int first = 1;
61 67
62 static int open_mode; 68 static int open_mode;
63 static int set_block_mode; 69 static int set_block_mode;
64 70
65 #define ALSA_DEVICE_SIZE 48 71 #define ALSA_DEVICE_SIZE 48
66 72
67 #undef BUFFERTIME 73 #undef BUFFERTIME
68 #define SET_CHUNKSIZE 74 #define SET_CHUNKSIZE
69 75 #undef USE_POLL
70 snd_pcm_t * 76
71 77 snd_pcm_t *spdif_init(char *pcm_name)
72 spdif_init(char *pcm_name)
73 { 78 {
74 //char *pcm_name = "hw:0,2"; /* first card second device */ 79 //char *pcm_name = "hw:0,2"; /* first card second device */
75 static snd_aes_iec958_t spdif; 80 static snd_aes_iec958_t spdif;
81 static snd_aes_iec958_t spdif_test;
76 snd_pcm_info_t *info; 82 snd_pcm_info_t *info;
77 snd_pcm_t *handler; 83 snd_pcm_t *handler;
78 snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE; 84 snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
79 unsigned int channels = 2; 85 unsigned int channels = 2;
80 unsigned int rate = 48000; 86 unsigned int rate = 48000;
94 return NULL; 100 return NULL;
95 } 101 }
96 printf("device: %d, subdevice: %d\n", snd_pcm_info_get_device(info), 102 printf("device: %d, subdevice: %d\n", snd_pcm_info_get_device(info),
97 snd_pcm_info_get_subdevice(info)); 103 snd_pcm_info_get_subdevice(info));
98 { 104 {
105
99 snd_ctl_elem_value_t *ctl; 106 snd_ctl_elem_value_t *ctl;
100 snd_ctl_t *ctl_handler; 107 snd_ctl_t *ctl_handler;
108 snd_ctl_elem_id_t *elem_id;
109 unsigned int elem_device;
110 const char *elem_name;
101 char ctl_name[12]; 111 char ctl_name[12];
102 int ctl_card; 112 int ctl_card;
113 //elem_id = 36;
103 114
104 spdif.status[0] = IEC958_AES0_NONAUDIO | 115 spdif.status[0] = IEC958_AES0_NONAUDIO |
105 IEC958_AES0_CON_EMPHASIS_NONE; 116 IEC958_AES0_CON_EMPHASIS_NONE;
106 spdif.status[1] = IEC958_AES1_CON_ORIGINAL | 117 spdif.status[1] = IEC958_AES1_CON_ORIGINAL |
107 IEC958_AES1_CON_PCM_CODER; 118 IEC958_AES1_CON_PCM_CODER;
108 spdif.status[2] = 0; 119 spdif.status[2] = 0;
109 spdif.status[3] = IEC958_AES3_CON_FS_48000; 120 spdif.status[3] = IEC958_AES3_CON_FS_48000;
110 121
111 snd_ctl_elem_value_alloca(&ctl); 122 snd_ctl_elem_value_alloca(&ctl);
112 snd_ctl_elem_value_set_interface(ctl, SND_CTL_ELEM_IFACE_PCM); 123 snd_ctl_elem_id_alloca(&elem_id);
124 snd_ctl_elem_value_set_interface(ctl, SND_CTL_ELEM_IFACE_PCM); //SND_CTL_ELEM_IFACE_MIXER
113 snd_ctl_elem_value_set_device(ctl, snd_pcm_info_get_device(info)); 125 snd_ctl_elem_value_set_device(ctl, snd_pcm_info_get_device(info));
114 snd_ctl_elem_value_set_subdevice(ctl, snd_pcm_info_get_subdevice(info)); 126 snd_ctl_elem_value_set_subdevice(ctl, snd_pcm_info_get_subdevice(info));
115 snd_ctl_elem_value_set_name(ctl, SND_CTL_NAME_IEC958("", PLAYBACK,PCM_STREAM)); 127 snd_ctl_elem_value_set_name(ctl,SND_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM)); //SWITCH
116 snd_ctl_elem_value_set_iec958(ctl, &spdif); 128 snd_ctl_elem_value_set_iec958(ctl, &spdif);
117 ctl_card = snd_pcm_info_get_card(info); 129 ctl_card = snd_pcm_info_get_card(info);
118 if (ctl_card < 0) { 130 if (ctl_card < 0) {
119 fprintf(stderr, "Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card"); 131 fprintf(stderr, "Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card");
120 goto __diga_end; 132 goto __diga_end;
121 } 133 }
134
122 sprintf(ctl_name, "hw:%d", ctl_card); 135 sprintf(ctl_name, "hw:%d", ctl_card);
123 printf("hw:%d\n", ctl_card); 136 printf("hw:%d\n", ctl_card);
124 if ((err = snd_ctl_open(&ctl_handler, ctl_name, 0)) < 0) { 137 if ((err = snd_ctl_open(&ctl_handler, ctl_name, 0)) < 0) {
125 fprintf(stderr, "Unable to open the control interface '%s': %s\n", ctl_name, snd_strerror(err)); 138 fprintf(stderr, "Unable to open the control interface '%s': %s\n", ctl_name, snd_strerror(err));
126 goto __diga_end; 139 goto __diga_end;
127 } 140 }
128 if ((err = snd_ctl_elem_write(ctl_handler, ctl)) < 0) { 141 if ((err = snd_ctl_elem_write(ctl_handler, ctl)) < 0) {
129 fprintf(stderr, "Unable to update the IEC958 control: %s\n", snd_strerror(err)); 142 //fprintf(stderr, "Unable to update the IEC958 control: %s\n", snd_strerror(err));
143 printf("alsa-spdif-init: cant set spdif-trough automatically\n");
130 goto __diga_end; 144 goto __diga_end;
131 } 145 }
146 //test area
147 /* elem_device = snd_ctl_elem_id_get_device(elem_id); */
148 /* elem_name = snd_ctl_elem_value_get_name(ctl); */
149 /* snd_ctl_elem_value_get_iec958(ctl, &spdif); */
150 /* printf("spdif = %i, device = %i\n", &spdif, elem_device); */
151 /* printf("name = %s\n", elem_name); */
152 //end test area
153
154
132 snd_ctl_close(ctl_handler); 155 snd_ctl_close(ctl_handler);
133 __diga_end: 156 __diga_end:
134 157
135 } 158 }
136 159
316 ao_data.samplerate = rate_hz; 339 ao_data.samplerate = rate_hz;
317 ao_data.bps = channels; /* really this is bytes per frame so bad varname */ 340 ao_data.bps = channels; /* really this is bytes per frame so bad varname */
318 ao_data.format = format; 341 ao_data.format = format;
319 ao_data.channels = channels; 342 ao_data.channels = channels;
320 ao_data.outburst = OUTBURST; 343 ao_data.outburst = OUTBURST;
321 ao_data.buffersize = MAX_OUTBURST; // was 16384 344 //ao_data.buffersize = MAX_OUTBURST; // was 16384
322 345
323 switch (format) 346 switch (format)
324 { 347 {
325 case AFMT_S8: 348 case AFMT_S8:
326 alsa_format = SND_PCM_FORMAT_S8; 349 alsa_format = SND_PCM_FORMAT_S8;
487 else { 510 else {
488 open_mode = 0; 511 open_mode = 0;
489 set_block_mode = 0; 512 set_block_mode = 0;
490 str_block_mode = "block-mode"; 513 str_block_mode = "block-mode";
491 } 514 }
492 515 //cvs cosmetics fix
516 //sets buff/chunksize if its set manually
517 if (ao_data.buffersize) {
518 switch (ao_data.buffersize)
519 {
520 case 1:
521 alsa_fragcount = 16;
522 chunk_size = 512;
523 if (verbose) {
524 printf("alsa-init: buffersize set manually to 8192\n");
525 printf("alsa-init: chunksize set manually to 512\n");
526 }
527 break;
528 case 2:
529 alsa_fragcount = 8;
530 chunk_size = 1024;
531 if (verbose) {
532 printf("alsa-init: buffersize set manually to 8192\n");
533 printf("alsa-init: chunksize set manually to 1024\n");
534 }
535 break;
536 case 3:
537 alsa_fragcount = 32;
538 chunk_size = 512;
539 if (verbose) {
540 printf("alsa-init: buffersize set manually to 16384\n");
541 printf("alsa-init: chunksize set manually to 512\n");
542 }
543 break;
544 case 4:
545 alsa_fragcount = 16;
546 chunk_size = 1024;
547 if (verbose) {
548 printf("alsa-init: buffersize set manually to 16384\n");
549 printf("alsa-init: chunksize set manually to 1024\n");
550 }
551 break;
552 default:
553 alsa_fragcount = 16;
554 if (ao_mmap)
555 chunk_size = 512;
556 else
557 chunk_size = 1024;
558 break;
559 }
560 }
561
493 if (!alsa_handler) { 562 if (!alsa_handler) {
494 //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC 563 //modes = 0, SND_PCM_NONBLOCK, SND_PCM_ASYNC
495 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, open_mode)) < 0) 564 if ((err = snd_pcm_open(&alsa_handler, alsa_device, SND_PCM_STREAM_PLAYBACK, open_mode)) < 0)
496 { 565 {
497 if (ao_noblock) { 566 if (ao_noblock) {
535 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX); 604 snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX);
536 err = snd_pcm_hw_params_set_access_mask(alsa_handler, alsa_hwparams, mask); 605 err = snd_pcm_hw_params_set_access_mask(alsa_handler, alsa_hwparams, mask);
537 printf("alsa-init: mmap set\n"); 606 printf("alsa-init: mmap set\n");
538 } else { 607 } else {
539 err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams,SND_PCM_ACCESS_RW_INTERLEAVED); 608 err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams,SND_PCM_ACCESS_RW_INTERLEAVED);
540 printf("alsa-init: interleave set\n");
541 } 609 }
542 if (err < 0) { 610 if (err < 0) {
543 printf("alsa-init: unable to set access type: %s\n", snd_strerror(err)); 611 printf("alsa-init: unable to set access type: %s\n", snd_strerror(err));
544 return (0); 612 return (0);
545 } 613 }
592 #endif 660 #endif
593 661
594 #ifdef SET_CHUNKSIZE 662 #ifdef SET_CHUNKSIZE
595 { 663 {
596 //set chunksize 664 //set chunksize
597 chunk_size = alsa_fragsize / 4;
598
599 if ((err = snd_pcm_hw_params_set_period_size(alsa_handler, alsa_hwparams, chunk_size, 0)) < 0) 665 if ((err = snd_pcm_hw_params_set_period_size(alsa_handler, alsa_hwparams, chunk_size, 0)) < 0)
600 { 666 {
601 printf("alsa-init: unable to set periodsize: %s\n", snd_strerror(err)); 667 printf("alsa-init: unable to set periodsize: %s\n", snd_strerror(err));
602 return(0); 668 return(0);
603 } 669 }
651 return(0); 717 return(0);
652 } 718 }
653 719
654 //set min available frames to consider pcm ready (4) 720 //set min available frames to consider pcm ready (4)
655 //increased for nonblock-mode should be set dynamically later 721 //increased for nonblock-mode should be set dynamically later
656 if ((err = snd_pcm_sw_params_set_avail_min(alsa_handler, alsa_swparams, chunk_size)) < 0) 722 if ((err = snd_pcm_sw_params_set_avail_min(alsa_handler, alsa_swparams, 4)) < 0)
657 { 723 {
658 printf("alsa-init: unable to set avail_min %s\n",snd_strerror(err)); 724 printf("alsa-init: unable to set avail_min %s\n",snd_strerror(err));
659 return(0); 725 return(0);
660 } 726 }
661 727
773 if (verbose) 839 if (verbose)
774 printf("alsa-reset: reset nonblocked"); 840 printf("alsa-reset: reset nonblocked");
775 return; 841 return;
776 } 842 }
777 } 843 }
844
845 #ifdef USE_POLL
846 static int wait_for_poll(snd_pcm_t *handle, struct pollfd *ufds, unsigned int count)
847 {
848 unsigned short revents;
849
850 while (1) {
851 poll(ufds, count, -1);
852 snd_pcm_poll_descriptors_revents(handle, ufds, count, &revents);
853 if (revents & POLLERR)
854 return -EIO;
855 if (revents & POLLOUT)
856 return 0;
857 }
858 }
859 #endif
778 860
779 #ifndef timersub 861 #ifndef timersub
780 #define timersub(a, b, result) \ 862 #define timersub(a, b, result) \
781 do { \ 863 do { \
782 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ 864 (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
817 } 899 }
818 900
819 return(1); /* ok, data should be accepted again */ 901 return(1); /* ok, data should be accepted again */
820 } 902 }
821 903
904 static int play(void* data, int len, int flags)
905 {
906 int result;
907 if (ao_mmap)
908 result = play_mmap(data, len);
909 else
910 result = play_normal(data, len);
911
912 return result;
913 }
914
822 /* 915 /*
823 plays 'len' bytes of 'data' 916 plays 'len' bytes of 'data'
824 returns: number of bytes played 917 returns: number of bytes played
825 modified last at 29.06.02 by jp 918 modified last at 29.06.02 by jp
826 thanxs for marius <marius@rospot.com> for giving us the light ;) 919 thanxs for marius <marius@rospot.com> for giving us the light ;)
827 */ 920 */
828 921
829 static int play(void* data, int len, int flags) 922 static int play_normal(void* data, int len)
830 { 923 {
831 924
832 //ao_data.bps is always 4 cause its set to channels * 2 by alsa_format?? 925 //ao_data.bps is always 4 for 2 chn S16_LE
833 int num_frames = len / ao_data.bps; 926 int num_frames = len / ao_data.bps;
834 signed short *output_samples=data; 927 signed short *output_samples=data;
835 snd_pcm_sframes_t res = 0; 928 snd_pcm_sframes_t res = 0;
836 929
837 //printf("alsa-play: frames=%i, len=%i",num_frames,len); 930 //printf("alsa-play: frames=%i, len=%i",num_frames,len);
841 return 0; 934 return 0;
842 } 935 }
843 936
844 while (num_frames > 0) { 937 while (num_frames > 0) {
845 938
846 if (ao_mmap) { 939 res = snd_pcm_writei(alsa_handler, (void *)output_samples, num_frames);
847 res = snd_pcm_mmap_writei(alsa_handler, (void *)output_samples, num_frames);
848 } else {
849 res = snd_pcm_writei(alsa_handler, (void *)output_samples, num_frames);
850 }
851 940
852 if (res == -EAGAIN) { 941 if (res == -EAGAIN) {
853 snd_pcm_wait(alsa_handler, 1000); 942 snd_pcm_wait(alsa_handler, 1000);
854 } 943 }
855 else if (res == -EPIPE) { /* underrun */ 944 else if (res == -EPIPE) { /* underrun */
884 return 0; 973 return 0;
885 } 974 }
886 return res < 0 ? (int)res : len; 975 return res < 0 ? (int)res : len;
887 } 976 }
888 977
978 /* mmap-mode mainly based on descriptions by Joshua Haberman <joshua@haberman.com>
979 * 'An overview of the ALSA API' http://people.debian.org/~joshua/x66.html
980 * and some help by Paul Davis <pbd@op.net> */
981
982 static int play_mmap(void* data, int len)
983 {
984 snd_pcm_sframes_t commitres, frames_available;
985 snd_pcm_uframes_t frames_transmit, size, offset;
986 const snd_pcm_channel_area_t *area;
987 void *outbuffer;
988 int err, result;
989
990 #ifdef USE_POLL //seems not really be needed
991 struct pollfd *ufds;
992 int count;
993
994 count = snd_pcm_poll_descriptors_count (alsa_handler);
995 ufds = malloc(sizeof(struct pollfd) * count);
996 snd_pcm_poll_descriptors(alsa_handler, ufds, count);
997
998 //first wait_for_poll
999 if (err = (wait_for_poll(alsa_handler, ufds, count) < 0)) {
1000 if (snd_pcm_state(alsa_handler) == SND_PCM_STATE_XRUN ||
1001 snd_pcm_state(alsa_handler) == SND_PCM_STATE_SUSPENDED) {
1002 xrun("play");
1003 }
1004 }
1005 #endif
1006
1007 outbuffer = alloca(ao_data.buffersize);
1008
1009 //don't trust get_space() ;)
1010 frames_available = snd_pcm_avail_update(alsa_handler) * ao_data.bps;
1011 if (frames_available < 0)
1012 xrun("play");
1013
1014 if (frames_available < 4) {
1015 if (first) {
1016 first = 0;
1017 snd_pcm_start(alsa_handler);
1018 }
1019 else { //FIXME should break and return 0?
1020 snd_pcm_wait(alsa_handler, -1);
1021 first = 1;
1022 }
1023 }
1024
1025 /* len is simply the available bufferspace got by get_space()
1026 * but real avail_buffer in frames is ab/ao_data.bps */
1027 size = len / ao_data.bps;
1028
1029 //if (verbose)
1030 //printf("len: %i size %i, f_avail %i, bps %i ...\n", len, size, frames_available, ao_data.bps);
1031
1032 frames_transmit = size;
1033
1034 /* prepare areas and set sw-pointers
1035 * frames_transmit returns the real available buffer-size
1036 * sometimes != frames_available cause of ringbuffer 'emulation' */
1037 snd_pcm_mmap_begin(alsa_handler, &area, &offset, &frames_transmit);
1038
1039 /* this is specific to interleaved streams (or non-interleaved
1040 * streams with only one channel) */
1041 outbuffer = ((char *) area->addr + (area->first + area->step * offset) / 8); //8
1042
1043 //write data
1044 memcpy(outbuffer, data, (frames_transmit * ao_data.bps));
1045
1046 commitres = snd_pcm_mmap_commit(alsa_handler, offset, frames_transmit);
1047
1048 if (commitres < 0 || commitres != frames_transmit) {
1049 if (snd_pcm_state(alsa_handler) == SND_PCM_STATE_XRUN ||
1050 snd_pcm_state(alsa_handler) == SND_PCM_STATE_SUSPENDED) {
1051 xrun("play");
1052 }
1053 }
1054
1055 //if (verbose)
1056 //printf("mmap ft: %i, cres: %i\n", frames_transmit, commitres);
1057
1058 /* err = snd_pcm_area_copy(&area, offset, &data, offset, len, alsa_format); */
1059 /* if (err < 0) { */
1060 /* printf("area-copy-error\n"); */
1061 /* return 0; */
1062 /* } */
1063
1064
1065 //calculate written frames!
1066 result = commitres * ao_data.bps;
1067
1068
1069 /* if (verbose) { */
1070 /* if (len == result) */
1071 /* printf("result: %i, frames written: %i ...\n", result, frames_transmit); */
1072 /* else */
1073 /* printf("result: %i, frames written: %i, result != len ...\n", result, frames_transmit); */
1074 /* } */
1075
1076 //mplayer doesn't like -result
1077 if (result < 0)
1078 result = 0;
1079
1080 #ifdef USE_POLL
1081 free(ufds);
1082 #endif
1083
1084 return result;
1085 }
1086
889 /* how many byes are free in the buffer */ 1087 /* how many byes are free in the buffer */
890 static int get_space() 1088 static int get_space()
891 { 1089 {
892 snd_pcm_status_t *status; 1090 snd_pcm_status_t *status;
893 int ret; 1091 int ret;
910 switch(snd_pcm_status_get_state(status)) 1108 switch(snd_pcm_status_get_state(status))
911 { 1109 {
912 case SND_PCM_STATE_OPEN: 1110 case SND_PCM_STATE_OPEN:
913 str_status = "open"; 1111 str_status = "open";
914 case SND_PCM_STATE_PREPARED: 1112 case SND_PCM_STATE_PREPARED:
915 if (str_status != "open") 1113 if (str_status != "open") {
916 str_status = "prepared"; 1114 str_status = "prepared";
1115 first = 1;
1116 ret = snd_pcm_status_get_avail(status) * ao_data.bps;
1117 if (ret == 0) //ugly workaround for hang in mmap-mode
1118 ret = 10;
1119 break;
1120 }
917 case SND_PCM_STATE_RUNNING: 1121 case SND_PCM_STATE_RUNNING:
918 ret = snd_pcm_status_get_avail(status) * ao_data.bps; 1122 ret = snd_pcm_status_get_avail(status) * ao_data.bps;
919 //avail_frames = snd_pcm_avail_update(alsa_handler) * ao_data.bps; 1123 //avail_frames = snd_pcm_avail_update(alsa_handler) * ao_data.bps;
920 if (str_status != "open" && str_status != "prepared") 1124 if (str_status != "open" && str_status != "prepared")
921 str_status = "running"; 1125 str_status = "running";
926 ret = 0; 1130 ret = 0;
927 break; 1131 break;
928 case SND_PCM_STATE_XRUN: 1132 case SND_PCM_STATE_XRUN:
929 xrun("space"); 1133 xrun("space");
930 str_status = "xrun"; 1134 str_status = "xrun";
1135 first = 1;
931 ret = 0; 1136 ret = 0;
932 break; 1137 break;
933 default: 1138 default:
934 str_status = "undefined"; 1139 str_status = "undefined";
935 ret = 0; 1140 ret = snd_pcm_status_get_avail(status) * ao_data.bps;
1141 if (ret <= 0) {
1142 xrun("space");
1143 }
936 } 1144 }
937 1145
938 if (verbose && str_status != "running") 1146 if (verbose && str_status != "running")
939 printf("alsa-space: free space = %i, status=%i, %s --\n", ret, status, str_status); 1147 printf("alsa-space: free space = %i, status=%i, %s --\n", ret, status, str_status);
940 snd_pcm_status_free(status); 1148 snd_pcm_status_free(status);