openvortex-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Openvortex-dev] spdif init


From: Manuel Jander
Subject: Re: [Openvortex-dev] spdif init
Date: Fri, 14 Nov 2003 20:25:28 -0400

Hi Gordon

On Fri, 2003-11-14 at 18:46, J. Gordon Wolfe wrote:
> Hi all,
> 
> I spent the afternoon hacking on the spdif trying to get AC3 passthru to
> work.  The bad news is I haven't made it work yet.  The good news is I
> spent some time messing with vortex_spdif_init() and I fixed a bug,
> among other discoveries.
> 
> Anyway, without further adieu:
> 
> --- alsa/pci/au88x0/au88x0_core.c       2003-10-30 11:01:40.000000000 -0500
> +++ alsa-work/pci/au88x0/au88x0_core.c  2003-11-14 16:33:58.444307910 -0500
> @@ -2140,7 +2140,7 @@
>  /* SPDIF support  */
>  void vortex_spdif_init(vortex_t *vortex, int spdif_sr, int spdif_mode) {
>         int i, this_38 = 0, this_04=0, this_08=0, this_0c=0;
> -
> +
>         /* CAsp4Spdif::InitializeSpdifHardware(void) */
>         hwwrite(vortex->mmio, VORTEX_SPDIF_FLAGS, hwread(vortex->mmio, 
> VORTEX_SPDIF_FLAGS) & 0xfff3fffd);
>         //for (i=0x291D4; i<0x29200; i+=4)
> @@ -2174,7 +2174,7 @@
>                         this_38 &= 0xFFFFFFFE;
>                         this_38 &= 0xFFFFFFFD;
>                         this_38 &= 0xF3FFFFFF;
> -                       this_38 |= 0x03000000;
> +                       this_38 |= 0x03000000;  /* set 32khz samplerate */
>                         this_38 &= 0xFFFFFF3F;
>                         spdif_sr &= 0xFFFFFFFD;
>                         spdif_sr |= 1;
> @@ -2183,7 +2183,7 @@
>                         this_38 &= 0xFFFFFFFE;
>                         this_38 &= 0xFFFFFFFD;
>                         this_38 &= 0xF0FFFFFF;
> -                       this_38 |= 0x03000000;
> +                       this_38 |= 0x00000000;  /* set 44.1khz samplerate */
>                         this_38 &= 0xFFFFFF3F;
>                         spdif_sr &= 0xFFFFFFFC;
>                         break;
> @@ -2192,9 +2192,10 @@
>                                 this_38 &= 0xFFFFFFFE;
>                                 this_38 &= 0xFFFFFFFD;
>                                 this_38 &= 0xF2FFFFFF;
> -                               this_38 |= 0x02000000;
> +                               this_38 |= 0x02000000;  /* set 48khz 
> samplerate */
>                                 this_38 &= 0xFFFFFF3F;
>                         } else {
> +                               /* I think this stuff is for AC3 */
>                                 this_38 |= 0x00000003;
>                                 this_38 &= 0xFFFFFFBF;
>                                 this_38 |= 0x80;
> @@ -2204,9 +2205,11 @@
>                         break;
>   
>         }
> -       hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
> -       hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x10);
> -       hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);
> +       /* looks like the next 2 lines transfer a 16-bit value into 2 8-bit 
> registers.
> +          seems to be for the standard IEC/SPDIF initialization stuff */
> +       hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
> +       hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x0f);
> +       hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);  /* for a 
> samplerate converter I think */
>  }
>   
>  /* Initialization */
> 
> 
> Theres a lot of stuff there, but the important change is the 0x10
> becoming an 0x0f on the second hwwrite line.  I'm convinced thats just
> somebodys off-by-one error, and with that change my receiver *finally*
> initializes correctly.  Also, in the switch statement where I changed
> 0x03000000 to 0x00000000, that was necessary to get sound from the spdif
> when its set to 44.1khz once I'd made the hwwrite change.  

The 0xf -> 0x10 change is a great bug discovery. Will be submitted ASAP.
The support for 44.1KHz seems to be somewhat "strange", since the MX25
add on card seems to provide a external oscillator for the SPDIF clock.
I don't own one, so i can't  proof that. So i guess we should be careful
changing stuf, since this code is a mere translation of the Original
Aureal driver.

> Looking at the way emu10k1 uses their spdif, I'm convinced its the
> correct way to do things.  And now my spdif will play mostly correct
> sound when its set to either 44.1khz or 48khz, regardless of the
> frequency of the source.  Theres a touch of distortion playing 44.1k
> sounds at 48k, but nowheres near what I used to get.  For some reason,
> 32khz still doesn't work at all for me.  I think it must have to do with
> spdif_sr being set incorrectly for that frequency, but that variable's
> pretty cryptic and I don't know what to do other than trial and error to
> fix it.

Well, as i told before i think there is something weird with 44.1 KHz.
What kind of SPDIF adapter are you using ? You may want to try Jeff's
Win2k driver snooper. It logs any IO made by the Aureal driver. I'm
using it with great success for the WT and A3D stuff. That way you could
see what the Win2k driver writes into each register when changing the
SPDIF setup.

> For the interested, I also walked through all the setting of this_38 and
> spdif_sr, and as best I can tell, most of the code in that function is
> unnecessary.  You can reduce that part of the function to this, and it
> will work:
> 
>       i = spdif_sr;
>       switch (i) {
>               case 32000:
>                       this_38 = 0x03000000;
>                       spdif_sr = 0x7D8D;
>                       break;
>               case 44100:
>                       this_38 = 0x00000000;
>                       spdif_sr = 0xACCC;
>                       break;
>               case 48000:
>                       if (spdif_mode == 1) {
>                               this_38 = 0x02000000;
>                       } else {
>                               this_38 = 0x83;
>                       }
>                       spdif_sr = 0xBB8E;
>                       break;
>               
>       }
>       hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
>       hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x0f);
>       hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);
> 
> I'm not sure if thats because we're arbitrarily setting this_38=0 at the
> beginning.  If we set it to something different to start, all those &=
> might be good for something, so maybe we don't want to take them out
> just yet.  Same goes for spdif_sr, since I don't know why its written
> the way it is.  Just thought it was interesting that all that code
> wasn't doing anything.

The initial value for this_38 is my invention. Since its a member if the
SPDIF class, i don't know which value it may have. I think that the
source code shouldn't be simplified before we know that we aren't
deleting some lines that could give us a clue about currently unknown
things. The separate "and" and "or" operations, expose the individual
bit fields of the hardware registers. Thats why i didn't put them all
together into one single "and" and "or".

> Now about getting AC3 working... I think setting spdif_mode=0 will setup
> the hardware correctly, though this_38 might need to be 0x02000083
> instead of just 0x83, I'm really not sure.  For that matter, the 0x80
> might be wrong, all I'm really sure of is that the 0x03 sets some flags
> that are required for AC3.  Anyhow, the problem I'm running into right
> now is that I can't get xine to open up the spdif device so I can test. 
> It keeps giving me "Invalid type" errors.  Not being an ALSA expert, I
> don't know how to fix this.  Any ideas?
> 

Well, i would like to thank you very much. I'm very glad someone is
actually coding instead of just complaining :D

Best Regards,

Manuel






reply via email to

[Prev in Thread] Current Thread [Next in Thread]