On Tuesday 07 June 2011 19:01:52 Alexander Motin wrote:
> Author: mav
> Date: Tue Jun  7 17:01:52 2011
> New Revision: 222826
> URL: http://svn.freebsd.org/changeset/base/222826
> 
> Log:
>   Make automatic hw.snd.default_unit choice a bit more intelligent. Instead
>   of just setting it to the first registered device, reevaluate it for each
>   device registered, trying to choose best candidate, unless one was
> forced. For now use such preference order: play&rec, play, rec.
> 
>   As side effect, this should workaround the situation when HDMI audio
> output of the video card, usually not connected to anything, becomes
> default, that requires manual user intervention to make sound working. If
> at some point this won't be enough, we can try to fetch some additional
> priority flags from the device driver.
> 
> Modified:
>   head/sys/dev/sound/pcm/sound.c
> 
> Modified: head/sys/dev/sound/pcm/sound.c
> ===========================================================================
> === --- head/sys/dev/sound/pcm/sound.c        Tue Jun  7 16:23:27 2011        
> (r222825)
> +++ head/sys/dev/sound/pcm/sound.c    Tue Jun  7 17:01:52 2011        
> (r222826) @@
> -51,7 +51,7 @@ int pcm_veto_load = 1;
>  int snd_unit = -1;
>  TUNABLE_INT("hw.snd.default_unit", &snd_unit);
> 
> -static int snd_unit_auto = 0;
> +static int snd_unit_auto = -1;
>  TUNABLE_INT("hw.snd.default_auto", &snd_unit_auto);
>  SYSCTL_INT(_hw_snd, OID_AUTO, default_auto, CTLFLAG_RW,
>      &snd_unit_auto, 0, "assign default unit to a newly attached device");
> @@ -443,6 +443,7 @@ sysctl_hw_snd_default_unit(SYSCTL_HANDLE
>               if (!PCM_REGISTERED(d) || CHN_EMPTY(d, channels.pcm))
>                       return EINVAL;
>               snd_unit = unit;
> +             snd_unit_auto = 0;
>       }
>       return (error);
>  }
> @@ -737,6 +738,32 @@ pcm_killchan(device_t dev)
>       return (pcm_chn_destroy(ch));
>  }
> 
> +static int
> +pcm_best_unit(int old)
> +{
> +     struct snddev_info *d;
> +     int i, best, bestprio, prio;
> +
> +     best = -1;
> +     bestprio = -100;
> +     for (i = 0; pcm_devclass != NULL &&
> +         i < devclass_get_maxunit(pcm_devclass); i++) {
> +             d = devclass_get_softc(pcm_devclass, i);
> +             if (!PCM_REGISTERED(d))
> +                     continue;
> +             prio = 0;
> +             if (d->playcount == 0)
> +                     prio -= 10;
> +             if (d->reccount == 0)
> +                     prio -= 2;
> +             if (prio > bestprio || (prio == bestprio && i == old)) {
> +                     best = i;
> +                     bestprio = prio;
> +             }
> +     }
> +     return (best);
> +}
> +
>  int
>  pcm_setstatus(device_t dev, char *str)
>  {
> @@ -770,8 +797,12 @@ pcm_setstatus(device_t dev, char *str)
> 
>       PCM_UNLOCK(d);
> 
> -     if (snd_unit < 0 || snd_unit_auto != 0)
> +     if (snd_unit_auto < 0)
> +             snd_unit_auto = (snd_unit < 0) ? 1 : 0;
> +     if (snd_unit < 0 || snd_unit_auto > 1)
>               snd_unit = device_get_unit(dev);
> +     else if (snd_unit_auto == 1)
> +             snd_unit = pcm_best_unit(snd_unit);
> 
>       return (0);
>  }
> @@ -1113,7 +1144,6 @@ pcm_unregister(device_t dev)
>       struct snddev_info *d;
>       struct pcm_channel *ch;
>       struct thread *td;
> -     int i;
> 
>       td = curthread;
>       d = device_get_softc(dev);
> @@ -1216,21 +1246,9 @@ pcm_unregister(device_t dev)
>       sndstat_release(td);
> 
>       if (snd_unit == device_get_unit(dev)) {
> -             /*
> -              * Reassign default unit to the next available dev, but
> -              * first, reset snd_unit to something ridiculous.
> -              */
> -             snd_unit = -1;
> -             for (i = 0; pcm_devclass != NULL &&
> -                 i < devclass_get_maxunit(pcm_devclass); i++) {
> -                     if (device_get_unit(dev) == i)
> -                             continue;
> -                     d = devclass_get_softc(pcm_devclass, i);
> -                     if (PCM_REGISTERED(d)) {
> -                             snd_unit = i;
> -                             break;
> -                     }
> -             }
> +             snd_unit = pcm_best_unit(-1);
> +             if (snd_unit_auto == 0)
> +                     snd_unit_auto = 1;
>       }
> 
>       return (0);

Idea: I would be cool if some GTK mixer apps can set this value.

--HPS
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to