comparison libao2/ao_alsa1x.c @ 7077:a24f91c247cd

iec958-init completly rewritten some debug printfs cleaned
author joyping
date Fri, 23 Aug 2002 13:03:00 +0000
parents a5b2b377ab50
children dda97c5190d7
comparison
equal deleted inserted replaced
7076:3275af5787e0 7077:a24f91c247cd
1 /* 1 /*
2 ao_alsa9 - ALSA-0.9.x output plugin for MPlayer 2 ao_alsa9 - ALSA-0.9.x output plugin for MPlayer
3 3
4 (C) Alex Beregszaszi <alex@naxine.org> 4 (C) Alex Beregszaszi <alex@naxine.org>
5 5
6 modified for better alsa-0.9.0beta12(rc1)-support by Joy Winter <joy@pingfm.org> 6 modified for real alsa-0.9.0-support by Joy Winter <joy@pingfm.org>
7 additional AC3 passthrough support by Andy Lo A Foe <andy@alsaplayer.org> 7 additional AC3 passthrough support by Andy Lo A Foe <andy@alsaplayer.org>
8 08/22/2002 iec958-init rewritten and merged with common init, joy
8 9
9 Any bugreports regarding to this driver are welcome either to the mplayer-user-mailinglist or directly to the authors. 10 Any bugreports regarding to this driver are welcome.
10 */ 11 */
11 12
12 #include <errno.h> 13 #include <errno.h>
13 #include <sys/time.h> 14 #include <sys/time.h>
14 #include <stdlib.h> 15 #include <stdlib.h>
45 46
46 static snd_pcm_t *alsa_handler; 47 static snd_pcm_t *alsa_handler;
47 static snd_pcm_format_t alsa_format; 48 static snd_pcm_format_t alsa_format;
48 static snd_pcm_hw_params_t *alsa_hwparams; 49 static snd_pcm_hw_params_t *alsa_hwparams;
49 static snd_pcm_sw_params_t *alsa_swparams; 50 static snd_pcm_sw_params_t *alsa_swparams;
50 static char *alsa_device; 51 const char *alsa_device;
51 52
52 /* possible 4096, original 8192 53 /* possible 4096, original 8192
53 * was only needed for calculating chunksize? */ 54 * was only needed for calculating chunksize? */
54 static int alsa_fragsize = 4096; 55 static int alsa_fragsize = 4096;
55 /* 16 sets buffersize to 16 * chunksize is as default 1024 56 /* 16 sets buffersize to 16 * chunksize is as default 1024
71 #define ALSA_DEVICE_SIZE 48 72 #define ALSA_DEVICE_SIZE 48
72 73
73 #undef BUFFERTIME 74 #undef BUFFERTIME
74 #define SET_CHUNKSIZE 75 #define SET_CHUNKSIZE
75 #undef USE_POLL 76 #undef USE_POLL
76
77 snd_pcm_t *spdif_init(char *pcm_name)
78 {
79 //char *pcm_name = "hw:0,2"; /* first card second device */
80 static snd_aes_iec958_t spdif;
81 static snd_aes_iec958_t spdif_test;
82 snd_pcm_info_t *info;
83 snd_pcm_t *handler;
84 snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
85 unsigned int channels = 2;
86 unsigned int rate = 48000;
87 int err, c;
88
89 if ((err = snd_pcm_open(&handler, pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
90 {
91 fprintf(stderr, "open: %s\n", snd_strerror(err));
92 return NULL;
93 }
94
95 snd_pcm_info_alloca(&info);
96
97 if ((err = snd_pcm_info(handler, info)) < 0) {
98 fprintf(stderr, "info: %s\n", snd_strerror(err));
99 snd_pcm_close(handler);
100 return NULL;
101 }
102 printf("device: %d, subdevice: %d\n", snd_pcm_info_get_device(info),
103 snd_pcm_info_get_subdevice(info));
104 {
105
106 snd_ctl_elem_value_t *ctl;
107 snd_ctl_t *ctl_handler;
108 snd_ctl_elem_id_t *elem_id;
109 unsigned int elem_device;
110 const char *elem_name;
111 char ctl_name[12];
112 int ctl_card;
113 //elem_id = 36;
114
115 spdif.status[0] = IEC958_AES0_NONAUDIO |
116 IEC958_AES0_CON_EMPHASIS_NONE;
117 spdif.status[1] = IEC958_AES1_CON_ORIGINAL |
118 IEC958_AES1_CON_PCM_CODER;
119 spdif.status[2] = 0;
120 spdif.status[3] = IEC958_AES3_CON_FS_48000;
121
122 snd_ctl_elem_value_alloca(&ctl);
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
125 snd_ctl_elem_value_set_device(ctl, snd_pcm_info_get_device(info));
126 snd_ctl_elem_value_set_subdevice(ctl, snd_pcm_info_get_subdevice(info));
127 snd_ctl_elem_value_set_name(ctl,SND_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM)); //SWITCH
128 snd_ctl_elem_value_set_iec958(ctl, &spdif);
129 ctl_card = snd_pcm_info_get_card(info);
130 if (ctl_card < 0) {
131 fprintf(stderr, "Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card");
132 goto __diga_end;
133 }
134
135 sprintf(ctl_name, "hw:%d", ctl_card);
136 printf("hw:%d\n", ctl_card);
137 if ((err = snd_ctl_open(&ctl_handler, ctl_name, 0)) < 0) {
138 fprintf(stderr, "Unable to open the control interface '%s': %s\n", ctl_name, snd_strerror(err));
139 goto __diga_end;
140 }
141 if ((err = snd_ctl_elem_write(ctl_handler, ctl)) < 0) {
142 //fprintf(stderr, "Unable to update the IEC958 control: %s\n", snd_strerror(err));
143 printf("alsa-spdif-init: cant set spdif-through automatically\n");
144 goto __diga_end;
145 }
146
147 snd_ctl_close(ctl_handler);
148 __diga_end:
149
150 }
151
152 {
153 snd_pcm_hw_params_t *params;
154 snd_pcm_sw_params_t *swparams;
155
156 snd_pcm_hw_params_alloca(&params);
157 snd_pcm_sw_params_alloca(&swparams);
158
159 err = snd_pcm_hw_params_any(handler, params);
160 if (err < 0) {
161 fprintf(stderr, "Broken configuration for this PCM: no configurations available");
162 return NULL;
163 }
164
165 err = snd_pcm_hw_params_set_access(handler, params,SND_PCM_ACCESS_RW_INTERLEAVED);
166 if (err < 0) {
167 fprintf(stderr, "Access tyep not available");
168 return NULL;
169 }
170 err = snd_pcm_hw_params_set_format(handler, params, format);
171
172 if (err < 0) {
173 fprintf(stderr, "Sample format non available");
174 return NULL;
175 }
176
177 err = snd_pcm_hw_params_set_channels(handler, params, channels);
178
179 if (err < 0) {
180 fprintf(stderr, "Channels count non avaible");
181 return NULL;
182 }
183
184 err = snd_pcm_hw_params_set_rate_near(handler, params, rate, 0); assert(err >= 0);
185
186 err = snd_pcm_hw_params(handler, params);
187
188 if (err < 0) {
189 fprintf(stderr, "Cannot set buffer size\n");
190 return NULL;
191 }
192 snd_pcm_sw_params_current(handler, swparams);
193 }
194 return handler;
195 }
196 77
197 78
198 /* to set/get/query special features/parameters */ 79 /* to set/get/query special features/parameters */
199 static int control(int cmd, int arg) 80 static int control(int cmd, int arg)
200 { 81 {
411 char *sub_str; 292 char *sub_str;
412 293
413 char *token_str[3]; 294 char *token_str[3];
414 char* test_str = strdup(ao_subdevice); 295 char* test_str = strdup(ao_subdevice);
415 296
416 //printf("subd=%s, test=%s\n", ao_subdevice,test_str);
417 297
418 if ((strcspn(ao_subdevice, ":")) > 0) { 298 if ((strcspn(ao_subdevice, ":")) > 0) {
419 299
420 sub_str = strtok(test_str, ":"); 300 sub_str = strtok(test_str, ":");
421 *(token_str) = sub_str; 301 *(token_str) = sub_str;
422 302
423 while (((sub_str = strtok(NULL, ":")) != NULL) && (i2 <= 3)) { 303 while (((sub_str = strtok(NULL, ":")) != NULL) && (i2 <= 3)) {
424 *(token_str+i2) = sub_str; 304 *(token_str+i2) = sub_str;
425 //printf("token %i: %s\n", i2, *(token_str+i2));
426 i2 += 1; 305 i2 += 1;
427 } 306 }
428 307
429 for (i3=0; i3 <= i2-1; i3++) { 308 for (i3=0; i3 <= i2-1; i3++) {
430 //printf("test %i, %s\n", i3, *(token_str+i3));
431 if (strcmp(*(token_str + i3), "mmap") == 0) { 309 if (strcmp(*(token_str + i3), "mmap") == 0) {
432 ao_mmap = 1; 310 ao_mmap = 1;
433 } 311 }
434 else if (strcmp(*(token_str+i3), "noblock") == 0) { 312 else if (strcmp(*(token_str+i3), "noblock") == 0) {
435 ao_noblock = 1; 313 ao_noblock = 1;
436 } 314 }
437 else if (strcmp(*(token_str+i3), "hw") == 0) { 315 else if (strcmp(*(token_str+i3), "hw") == 0) {
438 if ((i3 < i2-1) && (strcmp(*(token_str+i3+1), "noblock") != 0) && (strcmp(*(token_str+i3+1), "mmap") != 0)) { 316 if ((i3 < i2-1) && (strcmp(*(token_str+i3+1), "noblock") != 0) && (strcmp(*(token_str+i3+1), "mmap") != 0)) {
439 //printf("next tok = %s\n", *(token_str+(i3+1)));
440 alsa_device = alloca(ALSA_DEVICE_SIZE); 317 alsa_device = alloca(ALSA_DEVICE_SIZE);
441 snprintf(alsa_device, ALSA_DEVICE_SIZE, "hw:%s", *(token_str+(i3+1))); 318 snprintf(alsa_device, ALSA_DEVICE_SIZE, "hw:%s", *(token_str+(i3+1)));
442 device_set = 1; 319 device_set = 1;
443 } 320 }
444 else { 321 else {
445 //printf("setting hw\n");
446 alsa_device = *(token_str+i3); 322 alsa_device = *(token_str+i3);
447 device_set = 1; 323 device_set = 1;
448 } 324 }
449 } 325 }
450 else if (device_set == 0 && (!ao_mmap || !ao_noblock)) { 326 else if (device_set == 0 && (!ao_mmap || !ao_noblock)) {
451 //printf("setting common, %s\n", *(token_str+i3));
452 alsa_device = *(token_str+i3); 327 alsa_device = *(token_str+i3);
453 device_set = 1; 328 device_set = 1;
454 } 329 }
455 } 330 }
456 } 331 }
457 } //end parsing ao_subdevice 332 } //end parsing ao_subdevice
333
334 /* switch for spdif
335 * sets opening sequence for SPDIF
336 * sets also the playback and other switches 'on the fly'
337 * while opening the abstract alias for the spdif subdevice
338 * 'iec958'
339 */
340 if (format == AFMT_AC3) {
341 char devstr[128];
342 unsigned char s[4];
343 int err, c;
344
345 switch (channels) {
346 case 1:
347 case 2:
348
349 s[0] = IEC958_AES0_NONAUDIO |
350 IEC958_AES0_CON_EMPHASIS_NONE;
351 s[1] = IEC958_AES1_CON_ORIGINAL |
352 IEC958_AES1_CON_PCM_CODER;
353 s[2] = 0;
354 s[3] = IEC958_AES3_CON_FS_48000;
355
356 sprintf(devstr, "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x",
357 s[0], s[1], s[2], s[3]);
358
359 if (verbose)
360 printf("alsa-spdif-init: playing AC3, %i channels\n", channels);
361 break;
362 case 4:
363 strcpy(devstr, "surround40");
364 break;
365
366 case 6:
367 strcpy(devstr, "surround51");
368 break;
369
370 default:
371 fprintf(stderr, "%d channels are not supported\n", channels);
372 exit (0);
373 }
374
375 alsa_device = devstr;
376 }
458 377
459 if (alsa_device == NULL) 378 if (alsa_device == NULL)
460 { 379 {
461 int tmp_device, tmp_subdevice, err; 380 int tmp_device, tmp_subdevice, err;
462 381
504 printf(" mmap-mode and the device-name as first card third device\n"); 423 printf(" mmap-mode and the device-name as first card third device\n");
505 return(0); 424 return(0);
506 } else { 425 } else {
507 printf("alsa-init: soundcard set to %s\n", alsa_device); 426 printf("alsa-init: soundcard set to %s\n", alsa_device);
508 } 427 }
509
510 // switch for spdif
511 // Try to initialize the SPDIF interface
512 if (format == AFMT_AC3) {
513 if (device_set)
514 alsa_handler = spdif_init(alsa_device);
515 else
516 alsa_handler = spdif_init("iec958");
517 }
518 428
519 //setting modes for block or nonblock-mode 429 //setting modes for block or nonblock-mode
520 if (ao_noblock) { 430 if (ao_noblock) {
521 open_mode = SND_PCM_NONBLOCK; 431 open_mode = SND_PCM_NONBLOCK;
522 set_block_mode = 1; 432 set_block_mode = 1;