Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/isa Add support for Spatializer, 3D audio effects em...



details:   https://anonhg.NetBSD.org/src/rev/a2ef08bf49b3
branches:  trunk
changeset: 331610:a2ef08bf49b3
user:      nakayama <nakayama%NetBSD.org@localhost>
date:      Sat Aug 16 13:01:33 2014 +0000

description:
Add support for Spatializer, 3D audio effects embedded in ES1869
and ES1879 to ess(4).

Tested on my old laptop, mobio NX.

diffstat:

 sys/dev/isa/ess.c    |  138 ++++++++++++++++++++++++++++++++++++++++++++++----
 sys/dev/isa/essreg.h |   19 ++++++-
 sys/dev/isa/essvar.h |   11 +++-
 3 files changed, 152 insertions(+), 16 deletions(-)

diffs (truncated from 342 to 300 lines):

diff -r bdf8151bc5a7 -r a2ef08bf49b3 sys/dev/isa/ess.c
--- a/sys/dev/isa/ess.c Sat Aug 16 12:30:12 2014 +0000
+++ b/sys/dev/isa/ess.c Sat Aug 16 13:01:33 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ess.c,v 1.81 2014/08/15 19:55:23 nakayama Exp $        */
+/*     $NetBSD: ess.c,v 1.82 2014/08/16 13:01:33 nakayama Exp $        */
 
 /*
  * Copyright 1997
@@ -66,7 +66,7 @@
 */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ess.c,v 1.81 2014/08/15 19:55:23 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ess.c,v 1.82 2014/08/16 13:01:33 nakayama Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -170,7 +170,7 @@
 void   ess_set_gain(struct ess_softc *, int, int);
 int    ess_set_in_port(struct ess_softc *, int);
 int    ess_set_in_ports(struct ess_softc *, int);
-u_int  ess_srtotc(u_int);
+u_int  ess_srtotc(struct ess_softc *, u_int);
 u_int  ess_srtofc(u_int);
 u_char ess_get_dsp_status(struct ess_softc *);
 u_char ess_dsp_read_ready(struct ess_softc *);
@@ -994,7 +994,17 @@
        if (ESS_USE_AUDIO1(sc->sc_model)) {
                ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIC);
                sc->in_port = ESS_SOURCE_MIC;
-               sc->ndevs = ESS_1788_NDEVS;
+               if (ESS_IS_ES18X9(sc->sc_model)) {
+                       sc->ndevs = ESS_18X9_NDEVS;
+                       sc->sc_spatializer = 0;
+                       ess_set_mreg_bits(sc, ESS_MREG_MODE,
+                           ESS_MODE_ASYNC_MODE | ESS_MODE_NEWREG);
+                       ess_set_mreg_bits(sc, ESS_MREG_SPATIAL_CTRL,
+                           ESS_SPATIAL_CTRL_RESET);
+                       ess_clear_mreg_bits(sc, ESS_MREG_SPATIAL_CTRL,
+                           ESS_SPATIAL_CTRL_ENABLE | ESS_SPATIAL_CTRL_MONO);
+               } else
+                       sc->ndevs = ESS_1788_NDEVS;
        } else {
                /*
                 * Set hardware record source to use output of the record
@@ -1015,6 +1025,14 @@
         * are set to 50% volume.
         */
        for (i = 0; i < sc->ndevs; i++) {
+               if (ESS_IS_ES18X9(sc->sc_model)) {
+                       switch (i) {
+                       case ESS_SPATIALIZER:
+                       case ESS_SPATIALIZER_ENABLE:
+                               v = 0;
+                               goto skip;
+                       }
+               }
                switch (i) {
                case ESS_MIC_PLAY_VOL:
                case ESS_LINE_PLAY_VOL:
@@ -1031,6 +1049,7 @@
                        v = ESS_4BIT_GAIN(AUDIO_MAX_GAIN / 2);
                        break;
                }
+skip:
                sc->gain[i][ESS_LEFT] = sc->gain[i][ESS_RIGHT] = v;
                ess_set_gain(sc, i, 1);
        }
@@ -1262,11 +1281,12 @@
        else
                rate = play->sample_rate;
 
-       ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(rate));
+       ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(sc, rate));
        ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
 
        if (!ESS_USE_AUDIO1(sc->sc_model)) {
-               ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, ess_srtotc(rate));
+               ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE,
+                   ess_srtotc(sc, rate));
                ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
        }
 
@@ -1781,6 +1801,35 @@
                return 0;
        }
 
+       if (ESS_IS_ES18X9(sc->sc_model)) {
+
+               switch (cp->dev) {
+               case ESS_SPATIALIZER:
+                       if (cp->type != AUDIO_MIXER_VALUE ||
+                           cp->un.value.num_channels != 1)
+                               return EINVAL;
+
+                       sc->gain[cp->dev][ESS_LEFT] =
+                               sc->gain[cp->dev][ESS_RIGHT] = ESS_6BIT_GAIN(
+                                   cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
+                       ess_set_gain(sc, cp->dev, 1);
+                       return 0;
+
+               case ESS_SPATIALIZER_ENABLE:
+                       if (cp->type != AUDIO_MIXER_ENUM)
+                               return EINVAL;
+
+                       sc->sc_spatializer = (cp->un.ord != 0);
+                       if (sc->sc_spatializer)
+                               ess_set_mreg_bits(sc, ESS_MREG_SPATIAL_CTRL,
+                                   ESS_SPATIAL_CTRL_ENABLE);
+                       else
+                               ess_clear_mreg_bits(sc, ESS_MREG_SPATIAL_CTRL,
+                                   ESS_SPATIAL_CTRL_ENABLE);
+                       return 0;
+               }
+       }
+
        if (ESS_USE_AUDIO1(sc->sc_model))
                return EINVAL;
 
@@ -1886,6 +1935,23 @@
                return 0;
        }
 
+       if (ESS_IS_ES18X9(sc->sc_model)) {
+
+               switch (cp->dev) {
+               case ESS_SPATIALIZER:
+                       if (cp->un.value.num_channels != 1)
+                               return EINVAL;
+
+                       cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
+                               sc->gain[cp->dev][ESS_LEFT];
+                       return 0;
+
+               case ESS_SPATIALIZER_ENABLE:
+                       cp->un.ord = sc->sc_spatializer;
+                       return 0;
+               }
+       }
+
        if (ESS_USE_AUDIO1(sc->sc_model))
                return EINVAL;
 
@@ -2108,6 +2174,34 @@
                return 0;
        }
 
+       if (ESS_IS_ES18X9(sc->sc_model)) {
+
+               switch (dip->index) {
+               case ESS_SPATIALIZER:
+                       dip->mixer_class = ESS_OUTPUT_CLASS;
+                       dip->prev = AUDIO_MIXER_LAST;
+                       dip->next = ESS_SPATIALIZER_ENABLE;
+                       strcpy(dip->label.name, AudioNspatial);
+                       dip->type = AUDIO_MIXER_VALUE;
+                       dip->un.v.num_channels = 1;
+                       strcpy(dip->un.v.units.name, "level");
+                       return 0;
+
+               case ESS_SPATIALIZER_ENABLE:
+                       dip->mixer_class = ESS_OUTPUT_CLASS;
+                       dip->prev = ESS_SPATIALIZER;
+                       dip->next = AUDIO_MIXER_LAST;
+                       strcpy(dip->label.name, "enable");
+                       dip->type = AUDIO_MIXER_ENUM;
+                       dip->un.e.num_mem = 2;
+                       strcpy(dip->un.e.member[0].label.name, AudioNoff);
+                       dip->un.e.member[0].ord = 0;
+                       strcpy(dip->un.e.member[1].label.name, AudioNon);
+                       dip->un.e.member[1].ord = 1;
+                       return 0;
+               }
+       }
+
        if (ESS_USE_AUDIO1(sc->sc_model))
                return ENXIO;
 
@@ -2301,6 +2395,16 @@
        mix = 1;
        stereo = 1;
 
+       if (ESS_IS_ES18X9(sc->sc_model)) {
+               switch (port) {
+               case ESS_SPATIALIZER:
+                       src = ESS_MREG_SPATIAL_LEVEL;
+                       stereo = -1;
+                       goto skip;
+               case ESS_SPATIALIZER_ENABLE:
+                       return;
+               }
+       }
        switch (port) {
        case ESS_MASTER_VOL:
                src = ESS_MREG_VOLUME_MASTER;
@@ -2355,6 +2459,7 @@
        default:
                return;
        }
+skip:
 
        /* 1788 doesn't have a separate recording mixer */
        if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62)
@@ -2367,7 +2472,9 @@
                left = right = 0;
        }
 
-       if (stereo)
+       if (stereo == -1)
+               gain = ESS_SPATIAL_GAIN(left);
+       else if (stereo)
                gain = ESS_STEREO_GAIN(left, right);
        else
                gain = ESS_MONO_GAIN(left);
@@ -2468,15 +2575,22 @@
  * Calculate the time constant for the requested sampling rate.
  */
 u_int
-ess_srtotc(u_int rate)
+ess_srtotc(struct ess_softc *sc, u_int rate)
 {
        u_int tc;
 
        /* The following formulae are from the ESS data sheet. */
-       if (rate <= 22050)
-               tc = 128 - 397700L / rate;
-       else
-               tc = 256 - 795500L / rate;
+       if (ESS_IS_ES18X9(sc->sc_model)) {
+               if ((rate % 8000) != 0)
+                       tc = 128 - 793800L / rate;
+               else
+                       tc = 256 - 768000L / rate;
+       } else {
+               if (rate <= 22050)
+                       tc = 128 - 397700L / rate;
+               else
+                       tc = 256 - 795500L / rate;
+       }
 
        return tc;
 }
diff -r bdf8151bc5a7 -r a2ef08bf49b3 sys/dev/isa/essreg.h
--- a/sys/dev/isa/essreg.h      Sat Aug 16 12:30:12 2014 +0000
+++ b/sys/dev/isa/essreg.h      Sat Aug 16 13:01:33 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: essreg.h,v 1.16 2005/12/11 12:22:02 christos Exp $     */
+/*     $NetBSD: essreg.h,v 1.17 2014/08/16 13:01:33 nakayama Exp $     */
 /*
  * Copyright 1997
  * Digital Equipment Corporation. All rights reserved.
@@ -33,7 +33,7 @@
  */
 
 /*
-** @(#) $RCSfile: essreg.h,v $ $Revision: 1.16 $ (SHARK) $Date: 2005/12/11 12:22:02 $
+** @(#) $RCSfile: essreg.h,v $ $Revision: 1.17 $ (SHARK) $Date: 2014/08/16 13:01:33 $
 **
 **++
 **
@@ -176,14 +176,17 @@
 #define ESS_DRQ2_VALID(chan) ((chan) == 0 || (chan) == 1 || (chan) == 3 || (chan) == 5)
 
 #define ESS_USE_AUDIO1(model) ((model) <= ESS_1879)
+#define ESS_IS_ES18X9(model) (((model) == ESS_1869) || ((model) == ESS_1879))
 
 /*
  * Macros to manipulate gain values
  */
+#define ESS_6BIT_GAIN(x)       ((x) & 0xfc)
 #define ESS_4BIT_GAIN(x)       ((x) & 0xf0)
 #define ESS_3BIT_GAIN(x)       (((x) & 0xe0) >> 1)
 #define ESS_STEREO_GAIN(l, r)  ((l) | ((r) >> 4))
 #define ESS_MONO_GAIN(x)       ((x) >> 4)
+#define ESS_SPATIAL_GAIN(x)    ((x) >> 2)
 
 #ifdef ESS_AMODE_LOW
 /*
@@ -268,11 +271,23 @@
 #define ESS_MREG_VOLUME_AUXB   0x3A
 #define ESS_MREG_VOLUME_PCSPKR 0x3C
 #define ESS_MREG_VOLUME_LINE   0x3E
+#define ESS_MREG_SPATIAL_CTRL  0x50
+#define   ESS_SPATIAL_CTRL_MONO                0x02
+#define   ESS_SPATIAL_CTRL_RESET       0x04
+#define   ESS_SPATIAL_CTRL_ENABLE      0x08
+#define ESS_MREG_SPATIAL_LEVEL 0x52
 #define ESS_MREG_VOLUME_LEFT   0x60
 #define ESS_MREG_VOLUME_RIGHT  0x62
 #define   ESS_VOLUME_MUTE      0x40
 #define ESS_MREG_VOLUME_CTRL   0x64
 #define ESS_MREG_SAMPLE_RATE   0x70    /* sample rate for Audio2 channel */
+#define ESS_MREG_MODE          0x71    /* mode for Audio2 channel */
+#define   ESS_MODE_FM_MIX              0x01
+#define   ESS_MODE_ASYNC_MODE          0x02
+#define   ESS_MODE_SCF1_BYPASS         0x04
+#define   ESS_MODE_SCF2_BYPASS         0x08
+#define   ESS_MODE_4X_MODE             0x10
+#define   ESS_MODE_NEWREG              0x20



Home | Main Index | Thread Index | Old Index