Subject: kern/18901: Audio gain control of LR channel is contrary.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <sunakawa@hi-ho.ne.jp>
List: netbsd-bugs
Date: 11/04/2002 05:35:56
>Number:         18901
>Category:       kern
>Synopsis:       Audio gain control of LR channel is contrary.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Nov 03 03:37:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Hirokatsu Sunakawa
>Release:        NetBSD 1.6
>Organization:
individual
>Environment:
System: NetBSD alice 1.6 NetBSD 1.6 (ALICE) #4: Sun Nov 3 00:01:29 JST 2002 root@alice:/home/src/sys/arch/i386/compile/ALICE i386
Architecture: i386
Machine: i386

auvia0 at pci0 dev 17 function 5: VIA VT82C686A AC'97 Audio (rev 0x40)
auvia0: interrupting at irq 5
auvia0: unknown (0x83847650) codec; headphone, 20 bit DAC, 18 bit ADC, SigmaTel 3D
audio0 at auvia0: full duplex, mmap, independent

>Description:
	Audio gain control of LR channel is contrary.
>How-To-Repeat:
	Please try to change gain of L and R channels to different value, using some mixer program.
>Fix:

	According to the AC'97 specification, L ch's bit position is 8 and R ch's bit position is 0.
	So, I think, the following description of ac97.c (/usr/src/sys/dev/ic/ac97.c) is wrong.

    762                 newval = ((l & mask) << si->ofs);                <-----
    763                 if (value->num_channels == 2) {
    764                         newval |= ((r & mask) << (si->ofs + 8)); <-----
    765                         mask |= (mask << 8);
    766                 }


	These shold be as follows.

    762                 newval = ((r & mask) << si->ofs);
    763                 if (value->num_channels == 2) {
    764                         newval |= ((l & mask) << (si->ofs + 8));
    765                         mask |= (mask << 8);
    766                 }



	And also, the following description of ac97.c is wrong.

    837                 if (value->num_channels == 1) {
    838                         l = r = (val >> si->ofs) & mask;
    839                 } else {
    840                         if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) {
    841                                 l = (val >> si->ofs) & mask;              <----
    842                                 r = (val >> (si->ofs + 8)) & mask;        <----
    843                         } else {        /* host has reversed channels */
    844                                 r = (val >> si->ofs) & mask;		  <----
    845                                 l = (val >> (si->ofs + 8)) & mask;	  <----
    846                         }
    847                 }

	These shold be as follows.

    837                 if (value->num_channels == 1) {
    838                         l = r = (val >> si->ofs) & mask;
    839                 } else {
    840                         if (!(as->host_flags & AC97_HOST_SWAPPED_CHANNELS)) {
    841                                 r = (val >> si->ofs) & mask;
    842                                 l = (val >> (si->ofs + 8)) & mask;
    843                         } else {        /* host has reversed channels */
    844                                 l = (val >> si->ofs) & mask;
    845                                 r = (val >> (si->ofs + 8)) & mask;
    846                         }
    847                 }



	And also, according to the defines of Balance settings in audioio.h,
	the following description of audio.c (/usr/src/sys/dev/audio.c) is wrong.

   2397         if (balance == AUDIO_MID_BALANCE) {
   2398                 l = r = gain;
   2399         } else if (balance < AUDIO_MID_BALANCE) {
   2400                 r = gain;				     <----
   2401                 l = (balance * gain) / AUDIO_MID_BALANCE;    <----
   2402         } else {
   2403                 l = gain;				     <----
   2404                 r = ((AUDIO_RIGHT_BALANCE - balance) * gain) <----
   2405                     / AUDIO_MID_BALANCE;
   2406         }


	These shold be as follows.


   2397         if (balance == AUDIO_MID_BALANCE) {
   2398                 l = r = gain;
   2399         } else if (balance < AUDIO_MID_BALANCE) {
   2400           /* left > right */
   2401                 l = gain;
   2402                 r = (balance * gain) / AUDIO_MID_BALANCE;
   2403         } else {
   2404           /* left < right */
   2405                 r = gain;
   2406                 l = ((AUDIO_RIGHT_BALANCE - balance) * gain)
   2407                     / AUDIO_MID_BALANCE;
   2408         }



	That's all.
>Release-Note:
>Audit-Trail:
>Unformatted: