[MPlayer-users] Re: Problems w/ AC3 pass-through on SB Live!

Simo Salam vholma at pp.htv.fi
Wed Aug 21 21:57:01 CEST 2002


Beautiful! It did take approximately 3 hours to get fixed ;-). Where
else can you find these kind of response times...

What I'm trying to say is your patch works flawlessly at least for me.
Using a command:

mplayer -ao alsa9 -ac hwac3 ...
 .
 .
 .

AO: [alsa9] 48000Hz 2ch AC3
alsa-init: testing and bugreports are welcome.
alsa-init: requested format: 48000 Hz, 2 channels, AC3
alsa-spdif-init: playing AC3, 2 channels
alsa-init: soundcard set to iec958:AES0=0x2,AES1=0x82,AES2=0x0,AES3=0x2
alsa9: 48000 Hz/2 channels/4 bpf/16384 bytes buffer/Signed 16 bit Little
Endian
Start playing...

and everything just works[tm]. Both the sound and the blue lights I
mentioned earlier. Great work, Thank You very much. You have my vote on
commiting the patch to cvs!!

--s



On Wed, 2002-08-21 at 23:01, joy ping wrote:
> ok, i did a fast hack and did completly rewrote the iec958
> initialization for alsa. its a striped down version from ac3dec
> without support for professional mode.
> the patch should aply against current mplayer_0.9pre6. it will *not*
> aply against current cvs, but it will aply against the cvs-version
> three days ago. so if you have a really brand new mplayer-cvs-version
> downgrade ao_alsa9.c to a version at least three days ago. sorry for
> the inconveniennce but its another branch in my local cvs.
> note: you don't need to pass any subopts to this version anymore
> 'iec958' is the only selectable device and should work with all iec958
> capable devices. also spdif-playback and other switches will be set on
> the fly.
> please check the patch, and report success/failure.
> 
> the patch should be aplyed directly against ao_alsa9.c in libao2 like:
> cp ao_alsa9_spdif_rewrite.patch mplayer/libao2
> patch ao_alsa9.c ao_alsa9_spdif_rewrite.patch
> 
> 
> On Wed, Aug 21, 2002 at 06:03:35PM +0300, Simo Salam wrote:
> > [Automatic answer: RTFM (read DOCS, FAQ), also read DOCS/bugreports.html]
> > Actually I too have a problem similar to this one. My soundcard is a SB
> > Live! 5.1 and I'm using alsa09 rc1. This is what my lspci output looks
> > like:
> > 
> > 00:07.5 Multimedia audio controller: VIA Technologies, Inc. AC97 Audio
> > Controller (rev 50)
> > 00:0c.0 Multimedia audio controller: Creative Labs SB Live! EMU10000
> > (rev 07)
> > 00:0c.1 Input device controller: Creative Labs SB Live! (rev 07)
> > 
> > I'm also using kernel 2.4.18 and mplayer from cvs (currently maybe a
> > week old). My external receiver is a Sony.
> > 
> > The problem is strange and it goes like this. If I try to get ac3
> > passthrough either from dvd or a divx movie using a command similar to:
> > 
> > amixer sset "IEC958 Optical Raw" on
> > mplayer -ao alsa9:hw:0,3 -ac hwac3
> >  .
> >  .
> >  .
> > alsa-init: testing and bugreports are welcome.
> > alsa-init: requested format: 48000 Hz, 2 channels, AC3
> > alsa-init: soundcard set to hw:0,3
> > device: 3, subdevice: 0
> > hw:0
> > alsa-spdif-init: cant set spdif-trough automatically
> > Start playing...
> > 
> > it either starts playing sound in all 5+1 speakers for a while, but does
> > not 'light up' the blue light on the receiver which usually indicates
> > that the sony has detected an ac3 stream. But after a while, and usually
> > immediately after doing some seeking in the movie, the blue lights on
> > the receiver light up, and the receiver informs what kind of stream it
> > has detected, but at the same time mutes the sound on all the speakers.
> > So it's either no sound and proper lights or vice versa for me. xine, on
> > the other hand, works properly for me also regarding the ac3 passthrough
> > but otherwise sucks badly compared to mplayer so i'm using mplayer (btw.
> > thanks to all the developers of mplayer, its an awesome player).
> > 
> > I've connected my card to the receiver with a coaxial cable and I've
> > compiled mplayer with gcc-3.1. Can't think of anything else that might
> > have an influence on this. 
> > 
> > Anyhow, hope this information is of some use
> > 
> > --s
> > 
> > > 
> > > i will take a look at it. but i will be in holidays (without notebook;)
> > > for a few weeks, so don't expect fast solutions. maybe i get it to
> > > place some docs somewhere about how far i get till now with my
> > > rewriting ideas, so somebody could fix this.
> > > i thought that it would be really easy but currently i have no idea
> > > where the fscking bug could be that it doesn't work for you. basically the
> > > mechanism is the same as in ac3dec or lovely xine without setting the
> > > spdif-playback-switch automagically. most confusing is that the
> > > current routine seems to work for others also with a *'SBlive'*, 
> > > so if we start to make a new init it may work for you but the 
> > > other half will start to cry 'my digital out don't work'. 
> > > but we will see...
> > > 
> > > 
> > > -- 
> > > regards
> > > 
> > > ____-
> > > joy
> > > 
> > > ________/\---------%%%___________-----------
> > > webcast every sunday 2000 cest at pingfm.org
> > > 
> > > pgp key at: x-hkp://wwwkeys.de.pgp.net
> > > 
> > > _______________________________________________
> > > RTFM!!!  http://www.MPlayerHQ.hu/DOCS
> > > Search:  http://www.MPlayerHQ.hu/cgi-bin/htsearch
> > > http://mplayerhq.hu/mailman/listinfo/mplayer-users
> > 
> > 
> > 
> > _______________________________________________
> > RTFM!!!  http://www.MPlayerHQ.hu/DOCS
> > Search:  http://www.MPlayerHQ.hu/cgi-bin/htsearch
> > http://mplayerhq.hu/mailman/listinfo/mplayer-users
> 
> -- 
> regards
> 
> ____-
> joy
> 
> ________/\---------%%%___________-----------
> webcast every sunday 2000 cest at pingfm.org
> 
> pgp key at: x-hkp://wwwkeys.de.pgp.net
> ----
> 

> --- /usr/local2/cvs_work/mplayer/mplayer_user/libao2/ao_alsa9.c	Fri Jul 19 19:17:24 2002
> +++ /home/joy/devel/cvs_work/mplayer/libao2/ao_alsa9.c	Wed Aug 21 19:23:53 2002
> @@ -47,7 +47,7 @@
>  static snd_pcm_format_t alsa_format;
>  static snd_pcm_hw_params_t *alsa_hwparams;
>  static snd_pcm_sw_params_t *alsa_swparams;
> -static char *alsa_device;
> +const char *alsa_device;
>  
>  /* possible 4096, original 8192 
>   * was only needed for calculating chunksize? */
> @@ -73,134 +73,7 @@
>  #undef BUFFERTIME
>  #define SET_CHUNKSIZE
>  #undef USE_POLL
> -
> -snd_pcm_t *spdif_init(char *pcm_name)
> -{
> -	//char *pcm_name = "hw:0,2"; /* first card second device */
> -	static snd_aes_iec958_t spdif;
> -	static snd_aes_iec958_t spdif_test;
> -	snd_pcm_info_t 	*info;
> -	snd_pcm_t *handler;
> -	snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
> -	unsigned int channels = 2;
> -	unsigned int rate = 48000;
> -	int err, c;
> -
> -	if ((err = snd_pcm_open(&handler, pcm_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
> -	{
> -		fprintf(stderr, "open: %s\n", snd_strerror(err));
> -		return NULL;
> -	}
> -
> -	snd_pcm_info_alloca(&info);
> -
> -	if ((err = snd_pcm_info(handler, info)) < 0) {
> -		fprintf(stderr, "info: %s\n", snd_strerror(err));
> -		snd_pcm_close(handler);
> -		return NULL;
> -	}
> -        printf("device: %d, subdevice: %d\n", snd_pcm_info_get_device(info),
> -                snd_pcm_info_get_subdevice(info));                              
> -	{
> -
> -        snd_ctl_elem_value_t *ctl;
> -        snd_ctl_t *ctl_handler;
> -	snd_ctl_elem_id_t *elem_id;
> -	unsigned int elem_device;
> -	const char *elem_name;
> -        char ctl_name[12];
> -        int ctl_card;
> -	//elem_id = 36;
> -
> -	spdif.status[0] = IEC958_AES0_NONAUDIO |
> -			  IEC958_AES0_CON_EMPHASIS_NONE;
> -	spdif.status[1] = IEC958_AES1_CON_ORIGINAL |
> -			  IEC958_AES1_CON_PCM_CODER;
> -	spdif.status[2] = 0;
> -	spdif.status[3] = IEC958_AES3_CON_FS_48000;
> -
> -        snd_ctl_elem_value_alloca(&ctl);
> -	snd_ctl_elem_id_alloca(&elem_id); 
> -	snd_ctl_elem_value_set_interface(ctl, SND_CTL_ELEM_IFACE_PCM); //SND_CTL_ELEM_IFACE_MIXER
> -        snd_ctl_elem_value_set_device(ctl, snd_pcm_info_get_device(info));
> -        snd_ctl_elem_value_set_subdevice(ctl, snd_pcm_info_get_subdevice(info));
> -        snd_ctl_elem_value_set_name(ctl,SND_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM)); //SWITCH
> -	snd_ctl_elem_value_set_iec958(ctl, &spdif);
> -        ctl_card = snd_pcm_info_get_card(info);
> -        if (ctl_card < 0) {
> -           fprintf(stderr, "Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card");
> -           goto __diga_end;
> -        }
> -
> -       sprintf(ctl_name, "hw:%d", ctl_card);
> -       printf("hw:%d\n", ctl_card);
> -       if ((err = snd_ctl_open(&ctl_handler, ctl_name, 0)) < 0) {
> -          fprintf(stderr, "Unable to open the control interface '%s': %s\n", ctl_name, snd_strerror(err));                                                    
> -          goto __diga_end;
> -       }
> -       if ((err = snd_ctl_elem_write(ctl_handler, ctl)) < 0) {
> -	 //fprintf(stderr, "Unable to update the IEC958 control: %s\n", snd_strerror(err));
> -	 printf("alsa-spdif-init: cant set spdif-trough automatically\n");
> -        goto __diga_end;
> -       }
> -       	//test area
> -       /* elem_device = snd_ctl_elem_id_get_device(elem_id); */
> -       /* elem_name = snd_ctl_elem_value_get_name(ctl);  */
> -       /* snd_ctl_elem_value_get_iec958(ctl, &spdif); */
> -       /* printf("spdif = %i, device = %i\n", &spdif, elem_device); */
> -       /* printf("name = %s\n", elem_name); */
> -	//end test area
> -
> -
> -      snd_ctl_close(ctl_handler);
> -      __diga_end:                                                       
> -
> -       }
> -
> -	{
> -	  snd_pcm_hw_params_t *params;
> -	  snd_pcm_sw_params_t *swparams;
> -	  
> -	  snd_pcm_hw_params_alloca(&params);
> -	  snd_pcm_sw_params_alloca(&swparams);
> -
> -          err = snd_pcm_hw_params_any(handler, params);
> -          if (err < 0) {
> -             fprintf(stderr, "Broken configuration for this PCM: no configurations available");                                                                        
> -	     return NULL;
> -	  }
> -
> -	  err = snd_pcm_hw_params_set_access(handler, params,SND_PCM_ACCESS_RW_INTERLEAVED);
> -	  if (err < 0) {
> -	    fprintf(stderr, "Access tyep not available");
> -	    return NULL;
> -	  }
> -	  err = snd_pcm_hw_params_set_format(handler, params, format);
> -
> -	  if (err < 0) {
> -	    fprintf(stderr, "Sample format non available");
> -	    return NULL;
> -	  }
> -
> -	  err = snd_pcm_hw_params_set_channels(handler, params, channels);
> -
> -	  if (err < 0) {
> -	    fprintf(stderr, "Channels count non avaible");
> -	    return NULL;
> -	  }
> -
> -          err = snd_pcm_hw_params_set_rate_near(handler, params, rate, 0);        assert(err >= 0);
> -
> -	  err = snd_pcm_hw_params(handler, params);
> -
> -	  if (err < 0) {
> -	    fprintf(stderr, "Cannot set buffer size\n");
> -	    return NULL;
> -	  }
> -	  snd_pcm_sw_params_current(handler, swparams);
> -	}  
> -	return handler;
> -}
> +#undef SEP_SPDIF_INIT
>  
>  
>  /* to set/get/query special features/parameters */
> @@ -211,6 +84,8 @@
>      return CONTROL_TRUE;
>    case AOCONTROL_GET_VOLUME:
>    case AOCONTROL_SET_VOLUME:
> +#ifndef WORDS_BIGENDIAN 
> +{ //seems to be a problem on macs?
>      {
>        ao_control_vol_t *vol = (ao_control_vol_t *)arg;
>  
> @@ -303,7 +178,17 @@
>        snd_mixer_close(handle);
>        return CONTROL_OK;
>      }
> +}// end big-endian
> +#endif
> +#ifdef WORDS_BIGENDIAN
> +{
> +  {
> +    return (CONTROL_UNKNOWN);
>    }
> +}
> +#endif
> +    
> +  } //end witch
>    return(CONTROL_UNKNOWN);
>  }
>  
> @@ -344,49 +229,60 @@
>      //ao_data.buffersize = MAX_OUTBURST; // was 16384
>  
>      switch (format)
> -    {
> -	case AFMT_S8:
> -	    alsa_format = SND_PCM_FORMAT_S8;
> -	    break;
> -	case AFMT_U8:
> -	    alsa_format = SND_PCM_FORMAT_U8;
> -	    break;
> -	case AFMT_U16_LE:
> -	    alsa_format = SND_PCM_FORMAT_U16_LE;
> -	    break;
> -	case AFMT_U16_BE:
> -	    alsa_format = SND_PCM_FORMAT_U16_BE;
> -	    break;
> +      {
> +      case AFMT_S8:
> +	alsa_format = SND_PCM_FORMAT_S8;
> +	break;
> +      case AFMT_U8:
> +	alsa_format = SND_PCM_FORMAT_U8;
> +	break;
> +      case AFMT_U16_LE:
> +	alsa_format = SND_PCM_FORMAT_U16_LE;
> +	break;
> +      case AFMT_U16_BE:
> +	alsa_format = SND_PCM_FORMAT_U16_BE;
> +	break;
>  #ifndef WORDS_BIGENDIAN
> -	case AFMT_AC3:
> +      case AFMT_AC3:
>  #endif
> -	case AFMT_S16_LE:
> -	    alsa_format = SND_PCM_FORMAT_S16_LE;
> -	    break;
> +      case AFMT_S16_LE:
> +	alsa_format = SND_PCM_FORMAT_S16_LE;
> +	break;
>  #ifdef WORDS_BIGENDIAN
> -	case AFMT_AC3:
> +      case AFMT_AC3:
>  #endif
> -	case AFMT_S16_BE:
> -	    alsa_format = SND_PCM_FORMAT_S16_BE;
> -	    break;
> -	default:
> -	    alsa_format = SND_PCM_FORMAT_MPEG;
> -	    break;
> -    }
> +      case AFMT_S16_BE:
> +	alsa_format = SND_PCM_FORMAT_S16_BE;
> +	break;
> +      case AFMT_S32_LE:
> +	alsa_format = SND_PCM_FORMAT_S32_LE;
> +	break;
> +      case AFMT_S32_BE:
> +	alsa_format = SND_PCM_FORMAT_S32_BE;
> +	break;
> +
> +      default:
> +	alsa_format = SND_PCM_FORMAT_MPEG;
> +	break;
> +      }
>      
>      switch(alsa_format)
> -    {
> -	case SND_PCM_FORMAT_S16_LE:
> -	case SND_PCM_FORMAT_U16_LE:
> -	    ao_data.bps *= 2;
> -	    break;
> -	case -1:
> -	    printf("alsa-init: invalid format (%s) requested - output disabled\n",
> -		audio_out_format_name(format));
> -	    return(0);
> -	default:
> -	    break;	    
> -    }
> +      {
> +      case SND_PCM_FORMAT_S16_LE:
> +      case SND_PCM_FORMAT_U16_LE:
> +	ao_data.bps *= 2;
> +	break;
> +      case SND_PCM_FORMAT_S32_LE:
> +      case SND_PCM_FORMAT_S32_BE:
> +	ao_data.bps *= 4;
> +	break;
> +      case -1:
> +	printf("alsa-init: invalid format (%s) requested - output disabled\n",
> +	       audio_out_format_name(format));
> +	return(0);
> +      default:
> +	break;	    
> +      }
>      
>      if (ao_subdevice) {
>        //start parsing ao_subdevice, ugly and not thread safe!
> @@ -441,6 +337,51 @@
>        }
>      } //end parsing ao_subdevice
>  
> +    /* switch for spdif
> +     * sets opening sequence for SPDIF
> +     * sets also the playback and other switches 'on the fly'
> +     * while opening the abstract alias for the spdif subdevice
> +     * 'iec958'
> +     */
> +    if (format == AFMT_AC3) {
> +      char devstr[128];
> +      unsigned char s[4];
> +      int err, c;
> +
> +      switch (channels) {
> +      case 1:
> +      case 2:
> +
> +	s[0] = IEC958_AES0_NONAUDIO | 
> +	  IEC958_AES0_CON_EMPHASIS_NONE;
> +	s[1] = IEC958_AES1_CON_ORIGINAL | 
> +	  IEC958_AES1_CON_PCM_CODER;
> +	s[2] = 0;
> +	s[3] = IEC958_AES3_CON_FS_48000;
> +
> +	sprintf(devstr, "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x", 
> +		s[0], s[1], s[2], s[3]);
> +	//snprintf(devstr, ALSA_DEVICE_SIZE, 
> +	//"default:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x", 
> +	//s[0], s[1], s[2], s[3]);
> +	printf("alsa-spdif-init: playing AC3, %i channels\n", channels);
> +	break;
> +      case 4:
> +	strcpy(devstr, "surround40");
> +	break;
> +    
> +      case 6:
> +	strcpy(devstr, "surround51");
> +	break;
> +
> +      default:
> +	fprintf(stderr, "%d channels are not supported\n", channels);
> +	exit (0);
> +      }
> +
> +      alsa_device = devstr;
> +    }
> +
>      if (alsa_device == NULL)
>        {
>  	int tmp_device, tmp_subdevice, err;
> @@ -492,15 +433,6 @@
>  		printf("alsa-init: soundcard set to %s\n", alsa_device);
>        }
>  
> -    // switch for spdif
> -    // Try to initialize the SPDIF interface
> -    if (format == AFMT_AC3) {
> -      if (device_set)
> -	alsa_handler = spdif_init(alsa_device);
> -      else
> -	alsa_handler = spdif_init("hw:0,2");
> -    }
> -
>      //setting modes for block or nonblock-mode
>      if (ao_noblock) {
>        open_mode = SND_PCM_NONBLOCK;
> @@ -512,7 +444,7 @@
>        set_block_mode = 0;
>        str_block_mode = "block-mode";
>      }
> -    //cvs cosmetics fix
> +
>      //sets buff/chunksize if its set manually
>      if (ao_data.buffersize) {
>        switch (ao_data.buffersize)






More information about the MPlayer-users mailing list