#!/bin/sh

# ALSA configurator
# in 1998,1999,2000 by SALSOFT, Jan ONDREJ <ondrejj@salstar.shadow.sk>
# Many fixes and improvements by Bernd Kaindl, SuSE

version=0.4.3b

#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

# Example:
# export CARD_0x#="snd-module_name Nicnames_of_cards [...]\
#  @IOs IRQs DMAs ...\
#  @available_IOs avail_IRQs ...\
#  default_IO default_IRQ ..."
# Don't forget add to CARDS!

export CARD_0="nocard No_more_cards\
 @io_names\
 @available\
 @default"
export CARD_0x1="snd-card-gusclassic Gravis_UltraSound_Classic\
 @port irq dma1 dma1_size dma2 dma2_size joystick_dac\
 @0x220,0x230,0x240,0x250,0x260 3,5,9,11,12,15 1,3,5,6,7 4-128 1,3,5,6,7 4-128 0-31\
 @0x220 5 6 '' 6 '' ''"
export CARD_0x2="snd-card-gusextreme Gravis_UltraSound_Extreme\
 @port mpu_port irq mpu_irq irq1 dma8 dma8_size dma1 dma1_size joystick_dac\
 @0x220,0x230,0x240,0x250,0x260 0x300,0x310,0x320,0x330,-1 5,7,9,10 5,7,9,10 3,5,9,11,12,15 0,1,3 4-64 1,3,5,6,7 4-128 0-31\
 @0x220 0x300 5 7 11 1 '' 6 '' ''"
export CARD_0x3="snd-card-gusclassic Gravis_UltraSound_ACE\
 @port irq dma1 dma1_size dma2 dma2_size joystick_dac\
 @0x220,0x230,0x240,0x250,0x260 3,5,9,11,12,15 1,3,5,6,7 4-128 1,3,5,6,7 4-128 0-31\
 @0x220 5 6 '' 6 '' ''"
export CARD_0x4="snd-card-gusmax Gravis_UltraSound_MAX\
 @port irq dma1 dma1_size dma2 dma2_size joystick_dac\
 @0x220,0x230,0x240,0x250,0x260 3,5,9,11,12,15 1,3,5,6,7 4-128 1,3,5,6,7 4-128 0-31\
 @0x220 11 5 '' 6 '' ''"
export CARD_0x5="snd-card-interwave Gravis_UltraSound_PnP Dynasonic_3-D/Pro\
 @port irq dma1 dma1_size dma2 dma2_size joystick_dac midi\
 @0x210,0x220,0x230,0x240,0x250,0x260 3,5,9,11,12,15 0,1,3,5,6,7 4-128 0,1,3,5,6,7 4-128 0-31 0,1\
 @0x220 11 5 '' 6 '' '' 0"
export CARD_0x6="snd-card-sb8 SoundBlaster_1.0\
 @port irq dma8 dma8_size\
 @0x220,0x240,0x260 5,7,9,10 1,3 4-64\
 @0x220 5 1 ''"
export CARD_0x7="snd-card-sb8 SoundBlaster_2.0\
 @port irq dma8 dma8_size\
 @0x220,0x240,0x260 5,7,9,10 1,3 4-64\
 @0x220 5 1 ''"
export CARD_0x8="snd-card-sb8 SoundBlaster_Pro\
 @port irq dma8 dma8_size\
 @0x220,0x240,0x260 5,7,9,10 1,3 4-64\
 @0x220 5 1 ''"
export CARD_0x9="snd-card-sb16 SoundBlaster_16_(PnP)\
 @port mpu_port irq dma8 dma8_size dma16 dma16_size mic_agc\
 @0x220,0x240,0x260 0x300,0x330,-1 5,7,9,10 0,1,3 4-64 5,6,7 4-128 0,1\
 @0x220 0x300 5 1 '' 5 '' 0"
export CARD_0xa="snd-card-sbawe SoundBlaster_AWE_32_(PnP) SoundBlaster_AWE_64_PnP\
 @port mpu_port awe_port irq dma8 dma8_size dma16 dma16_size mic_agc\
 @0x220,0x240,0x260 0x300,0x330,-1 0x620,0x630,0x640,0x670,0x680,-1 5,7,9,10 0,1,3 4-64 5,6,7 4-128 0,1\
 @0x220 0x300 0x620 5 1 '' 5 '' 0"
export CARD_0xb="snd-card-es1688 ESS_AudioDrive_ESx688\
 @port mpu_port irq mpu_irq dma8 dma8_size\
 @0x220,0x240,0x260 0x300,0x310,0x320,0x330,-1 5,7,9,10 5,7,9,10 0,1,3 4-64\
 @0x220 -1 5 7 1 ''"
export CARD_0xc="snd-card-opl3sa2 Yamaha_OPL3-SA2/SA3\
 @port sb_port wss_port midi_port fm_port irq dma1 dma1_size dma2 dma2_size\
 @0x??? 0x220 0x530,0xe80,0xf40,0x604 0x300,0x330,-1 0x388,-1 5,7,9,10 0,1,3 4-64 0,1,3,-1 4-64\
 @0x370 0x220 0x530 0x300 0x388 5 1 '' 3 ''"
export CARD_0xd="snd-card-mozart OAK_Mozart\
 @port irq dma1 dma1_size\
 @0x530,0xe80,0xf40,0x604 7,9,10,11 0,1,3 4-64\
 @0x530 7 1 ''"
export CARD_0xe="snd-card-sonicvibes S3_SonicVibes_PCI\
 @dmaa_size dmac_size reverb mge\
 @4-128 4-128 0,1 0,1\
 @'' '' 0 0"
export CARD_0xf="snd-card-ens1370 Ensoniq_AudioPCI_ES1370\
 @dac1_frame_size dac2_frame_size adc_frame_size\
 @4-128 4-128 4-128\
 @'' '' ''"
export CARD_0x10="snd-card-ens1371 Ensoniq_AudioPCI_ES1371 Sound_Blaster_PCI_64 Sound_Blaster_PCI_128 Sound_Blaster_Vibra_PCI\
 @dac1_frame_size dac2_frame_size adc_frame_size\
 @4-128 4-128 4-128\
 @'' '' ''"
export CARD_0x11="snd-card-cs4232 CS4232/CS4232A\
 @port cport mpu_port fm_port jport irq mpu_irq dma1 dma1_size dma2 dma2_size\
 @PnP_setup=0x534 PnP_setup=0x120 PnP_setup=0x300,-1 PnP_setup=0x388,-1 PnP_setup=0x200,-1 5,7,9,11,12,15 9,11,12,15 0,1,3 4-64 0,1,3,-1 4-64\
 @0x534 0x120 0x300 0x388 0x200 11 7 1 '' 3 ''"
export CARD_0x12="snd-card-cs4236 CS4235/CS4236B/CS4237B/CS4238B/CS4239\
 @port cport mpu_port fm_port irq mpu_irq dma1 dma1_size dma2 dma2_size\
 @PnP_setup=0x534 PnP_setup=0x120 PnP_setup=0x300,-1 PnP_setup=0x388,-1 5,7,9,11,12,15 9,11,12,15 0,1,3 4-64 0,1,3,-1 4-64\
 @0x534 0x120 0x300 0x388 11 7 1 '' 3 ''"
export CARD_0x13="snd-card-interwave-stb UltraSound_32-Pro\
 @port port_tc irq dma1 dma1_size dma2 dma2_size joystick_dac midi\
 @0x210,0x220,0x230,0x240,0x250,0x260 0x350,0x360,0x370,0x380 3,5,9,11,12,15 0,1,3,5,6,7 4-128 0,1,3,5,6,7 4-128 0-31 0,1\
 @0x220 0x350 11 5 '' 6 '' '' 0"
export CARD_0x14="snd-card-ess1938 ESS_Solo-1_ES1938/ES1946\
 @\
 @\
 @"
export CARD_0x15="snd-card-audiodrive18xx ESS_AudioDrive_ES18XX\
 @port mpu_port fm_port irq dma1 dma1_size dma2 dma2_size snd_isapnp\
 @0x220,0x240,0x260 0x300,0x310,0x320,0x330,-1 ??? 5,7,9,10 0,1,3 4-64 0,1,3 4-64 0,1\
 @0x220 0x300 -1 5 0 '' 1 '' 1"
export CARD_0x16="snd-card-cs4231 Soundcards_based_on_CS4231_chips\
 @port mpu_port jport irq mpu_irq dma1 dma1_size dma2 dma2_size\
 @??? ???,-1 ???,-1 ??? ??? ??? 4-128 ??? 4-128\
 @'' -1 -1 '' '' '' '' '' ''"
export CARD_0x17="snd-card-opti9xx OPTi_82C9xx_chips\
 @port mpu_port opl_port irq mpu_irq dma1 dma1_size dma2 dma2_size cd_if cd_port cd_irq cd_drq game\
 @0x530,0xe80,0xf40,0x604 0x300,0x310,0x320,0x330 0x388 5,7,9,10,11 5,7,9,10 0,1,3 4-64 0,1 4-64 disabled,ide1,ide2,mitsumi,panasonic,sony 0x320,0x330,0x340,0x360 5,7,9,10,11,-1 0,1,3,-1 enabled,disabled\
 @0x530 0x300 0x388 7 9 0 '' 1 '' disabled 0x320 -1 -1 disabled"
export CARD_0x18="snd-card-serial Serial_MIDI_driver\
 @\
 @\
 @"
export CARD_0x19="snd-card-card-ad1848 Soundcards_based_on_AD1848/AD1847/CS4248_chips\
 @port irq dma1 dma1_size\
 @??? ??? 0,1,3 4-64\
 @'' '' 1 ''"
export CARD_0x1a="snd-card-trid4dwave Trident_4DWave_DX\
 @dac_frame_size_dx adc_frame_size_dx dac_frame_size_nx adc_frame_size_nx pcm_channels wavetable_size\
 @4-64 4-64 4-64 4-64 ??? 4-?\
 @'' '' '' '' '' ''"
export CARD_0x1b="snd-card-trid4dwave Trident_4DWave_NX\
 @dac_frame_size_dx adc_frame_size_dx dac_frame_size_nx adc_frame_size_nx pcm_channels wavetable_size\
 @4-64 4-64 4-64 4-64 ??? 4-?\
 @'' '' '' '' '' ''"
export CARD_0x1c="snd-card-sgalaxy Aztech_Sound_Galaxy\
 @sbport wssport irq dma1 dma1_size\
 @0x220,0x240 0x530,0xe80,0xf40,0x604 7,9,10,11 0,1,3 8,16,32,64\
 @0x220 0x530 9 1 ''"
export CARD_0x1d="snd-card-cs461x Soundcards_based_on_CS4610/CS4612/CS4614/CS4615/CS4280 Turtle_Beach_WaveFront_series\
 @dac_frame_size adc_frame_size\
 @4-64 4-64\
 @'' ''"
export CARD_0x1e="snd-card-x TB_WaveFront_generic\
 @\
 @\
 @"
export CARD_0x1f="snd-card-x TB_Tropez\
 @\
 @\
 @"
export CARD_0x20="snd-card-x TB_Tropez+\
 @\
 @\
 @"
export CARD_0x21="snd-card-x TB_Maui\
 @\
 @\
 @"
export CARD_0x22="snd-card-cmi8330 Soundcards_based_on_C-Media_CMI8330_chips\
 @wssport wssirq wssdma wssdma_size sbport sbirq sbdma8 sbdma8_size sbdma16 sbdma16_size\
 @??? ??? ??? ??? ??? ??? ??? ??? ??? ???\
 @'' '' '' '' '' '' '' '' '' ''"
export CARD_0x23="snd-card-dummy Dummy_soundcard\
 @\
 @\
 @"
export CARD_0x24="snd-card-als100 Advance_Logic_ALS100\
 @\
 @\
 @"
export CARD_0x25="snd-card-share Sahred_card\
 @\
 @\
 @"
export CARD_0x26="snd-card-x SiS_7018\
 @\
 @\
 @"
export CARD_0x27="snd-card-opti93x OPTi_93x_chipset\
 @port mpu_port opl_port irq mpu_irq dma1 dma1_size dma2 dma2_size\
 @0x530,0xe80,0xf40,0x604 0x300,0x310,0x320,0x330 0x388 5,7,9,10,11 5,7,9,10 0,1,3 4-64 0,1,3 4-64kB\
 @0x530 0x330 0x388 5 7 0 '' 1 ''"
export CARD_0x28="snd-card-x MOTU_MidiTimePiece_AV_multiport_MIDI\
 @\
 @\
 @"
export CARD_0x29="snd-card-x Virtual_MIDI\
 @\
 @\
 @"
export CARD_0x2a="snd-card-emu10k1 Sound_Blaster_Live! Sound_Blaster_PCI_512\
 @dac_frame_size adc_frame_size\
 @4-128 4-64\
 @'' ''"
export CARD_0x2b="snd-card-x RME_Digi9652\
 @\
 @\
 @"
export CARD_0x2c="snd-card-x RME_Digi9652,_but_no_expansion_card\
 @\
 @\
 @"
export CARD_0x2d="snd-card-ice1712 MidiMan_M_Audio_Delta_1010 MidiMan_M_Audio_Delta_DiO_2496 MidiMan_M_Audio_Delta_66 MidiMan_M_Audio_Delta_44\
 @conp_frame_size prop_frame_size conc_frame_size proc_frame_size\
 @4-128 4-128 4-256 4-256\
 @'' '' '' ''"
export CARD_0x2e="snd-card-x C-Media_CMI8338\
 @\
 @\
 @"
export CARD_0x2f="snd-card-x C-Media_CMI8738\
 @\
 @\
 @"
export CARD_0x30="snd-card-ad1816a Chips_on_Analog_Devices_AD1816A/AD1815\
 @dma1_size dma2_size\
 @4-128 4-128\
 @'' ''"
export CARD_0x31="snd-card-intel8x0 Intel_i810/810E,i820,i830,i840,MX440\
 @pbk_frame_size cap_frame_size mic_frame_size\
 @4-128 4-128 4-128\
 @'' '' ''"
export CARD_0x32="snd-card-x ESS_ESOLDM1\
 @\
 @\
 @"
export CARD_0x33="snd-card-es1968 ESS_Maestro-1/2/2E_(ES1968/ES1978)_chips\
 @dac_frame_size adc_frame_size gesbuf midi_enable pcm_channels_p pcm_channels_c\
 @4-64 4-64 1-4096 0,1 1-8 1-8\
 @'' '' '' 1 2 0"
export CARD_0x34="snd-card-x ESS_ES1978\
 @\
 @\
 @"
export CARD_0x35="snd-card-x DIGI96\
 @\
 @\
 @"
export CARD_0x36="snd-card-x VIA82C686A\
 @mpu_port joystick pbk_frame_size cap_frame_size\
 @0x300,0x310,0x320,0x330 0,1 1-128 1-128\
 @0x300 1 '' ''"
export CARDS="0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf\
 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c\
 0x1d 0x22 0x23 0x24 0x25 0x2a 0x2d 0x30 0x31 0x33 0x36"

# Check for root privileges
if [ `id -u` -ne 0 ]; then
  echo "You must be root to use this script."
  exit 1
fi

echo "Initializing ... please wait ..."

# Exit function
acex() {
  test -n $TMP && test -f $TMP && rm -f $TMP
  clear
  echo "$2"
  exit $1
}

# Find module configuration (and make it if none)
if [ -f /etc/modules.conf ]; then
  export cfgfile="/etc/modules.conf"
elif [ -d /etc/modutils ]; then
  export cfgfile="/etc/modutils/alsa"
elif [ -f /etc/conf.modules ]; then
  export cfgfile="/etc/conf.modules"
else
  export cfgfile="/etc/modules.conf"
fi
test -f $cfgfile || touch $cfgfile

# Check for alsasound rc script
if [ -f /etc/rc.d/init.d/alsasound ]; then
  # RedHat
  export rcalsasound=/etc/rc.d/init.d/alsasound
elif [ -f /sbin/init.d/alsasound ]; then
  # SuSe
  export rcalsasound=/sbin/init.d/alsasound
elif [ -f /etc/init.d/alsa ]; then
  # Debian
  export rcalsasound=/etc/init.d/alsa
fi

# Check for dialog, whiptail, gdialog, awk, ... ?
if which dialog > /dev/null; then
  DIALOG=dialog
else
  if which whiptail > /dev/null; then
    whiptail_wrapper() {
      X1="$1"
      X2="$2"
      if [ $1 = --yesno ]; then
        X3=`expr $3 + 3`
      elif [ $1 = --menu ]; then
        X3=`expr $3 + 1`
      else
        X3=$3
      fi
      shift 3
      whiptail "$X1" "$X2" $X3 "$@"
    }
    DIALOG=whiptail_wrapper
  else
    acex 1 "Error, dialog or whiptail not found."
  fi
fi
if which awk > /dev/null; then :
else
  acex 1 "Error, awk not found. Can't continue."
fi

# Check for existence of group "audio".
if grep -q ^audio: /etc/group; then
  SND_MODE=0660
  SND_GID=`grep ^audio: /etc/group | cut -d: -f3`
  SND_UID=0
else
  SND_MODE=0666
  SND_GID=0
  SND_UID=0
fi

# Read mode, gid, uid from conf.modules
eval `grep "^options snd " $cfgfile | cut -d " " -f3-`
if [ "$snd_device_mode" ]; then
  SND_MODE="$snd_device_mode"
fi
if [ "$snd_device_gid" ]; then
  SND_GID="$snd_device_gid"
fi
if [ "$snd_device_uid" ]; then
  SND_UID="$snd_device_uid"
fi

# Get the ALSA version
/sbin/modprobe snd
ALSAVER=`cat /proc/asound/version | awk '/Advanced Linux Sound Architecture/ {print $7}'`
AV_MAJOR=`echo $ALSAVER | cut -d. -f1`
AV_MINOR=`echo $ALSAVER | cut -d. -f2`
AV_FULL=`expr $AV_MAJOR \* 1000 + $AV_MINOR`

# Stripnum
stripnum() {
  SEQ=":`seq -s : $1 $2`:"
  shift 2
  for i in $@; do
    SEQ=`echo $SEQ | sed s/:$i:/:/`
  done
  echo $SEQ
}

# Set variables
TMP=/tmp/alsaconf.$$
USED_IRQS=`grep "^ *[0-9]*:" /proc/interrupts | cut -d: -f1 | tr -d " "`
FREE_IRQS=`stripnum 0 15 $USED_IRQS`
USED_DMAS=`grep "^ *[0-9]*:" /proc/dma | cut -d: -f1 | tr -d " "`
FREE_DMAS=`stripnum 0 7 $USED_DMAS`
DETECTFILE=/proc/asound/detect

# INTRO
intro() {
$DIALOG --msgbox "
                    ALSA  CONFIGURATOR
                      version $version

                    (c) 1998,1999,2000
        Jan ONDREJ (SAL), <ondrejj@salstar.shadow.sk>
      Many fixes and improvements by Bernd Kaindl, SuSE

  This script is a configurator for Advanced Linux Sound
  Architecture driver.
  If alsa is running, you should close all sound apps
  now and run \"$rcalsasound stop\"
  to remove the drivers. alsaconf will try to do this,
  but it cannot kill your apps.
  You need ALSA 0.5.0 or higher now.

               (Detected ALSA version: $ALSAVER)
" 21 67 || acex 0 "Aborted."
}

# FAREWELL
farewell() {
$DIALOG --msgbox "

                $*

                   ALSA  CONFIGURATOR
                     version $version

           will prepare the card for playing now.

 Now I'll run '$rcalsasound start',
 then use I'll use amixer to raise the 'Master' and 'PCM'
 volumes. If you want to use the commandline-based mixer
 amixer also, read the man page: 'man amixer'.

" 18 62 || acex 0 "Aborted."
}

# Set card variables from CARD_#.
set_card_vars() {
  eval CARD_INFO=\$CARD_$1
  CARD_DRIVER=`echo $CARD_INFO | cut -d" " -f1`
  CARD_NAMES=`echo $CARD_INFO | cut -d"@" -f1 | cut -d" " -f2-`
  if [ "$2" ]; then
    CARD_GETOPT="id "`echo $CARD_INFO | cut -d"@" -f2`
    CARD_MAINOPT="_ "`echo $CARD_INFO | cut -d"@" -f3`
    CARD_DEFOPT="CARD_$2 "`echo $CARD_INFO | cut -d"@" -f4`
  fi
}

# Test card informations in CARD_# variables
test_card_info() {
  for C in $CARDS; do
    set_card_vars $C X
    echo "-----------------------------------------------------------------"
    echo "DRIVER:  $CARD_DRIVER"
    echo "NAMES:   $CARD_NAMES"
    echo "-----------------------------------------------------------------"
    echo "Parameter      Default   Options"
    OPTNUM=0
    for OPT in $CARD_GETOPT; do
      OPTNUM=`expr $OPTNUM + 1`
      MAINOPT="(`echo \"$CARD_MAINOPT\" | cut -d" " -f$OPTNUM`)"
      DEFOPT=`echo "$CARD_DEFOPT" | cut -d" " -f$OPTNUM | tr -d "'"`
      echo "$OPT@$DEFOPT@$MAINOPT" \
        | awk -F@ '{ printf "%-15s%-10s%s\n",$1,$2,$3 }'
    done
  done
  exit 0
}

# Select card
select_card() {
  $DIALOG --menu "Select card" 20 70 13 $MENU_CARDS 2> $TMP || acex 0 "Aborted."
  SEL_CARD=`cat $TMP`
}

# Enter a number or text.
enter_data() {
  $DIALOG --inputbox "$1\n$2" 9 50 "$DEFOPT" 2> $TMP || acex 0 "Aborted."
  RETURN=`cat $TMP`
}

# Disabled or Enabled ?
enter_dis_ena() {
  $DIALOG --menu "$1" 9 50 2 "0" "Disable" "1" "Enable" 2> $TMP || acex 0 "Aborted."
  RETURN=`cat $TMP`
}

# Add option
add_option() {
  if [ "$2" ]; then
    CARD_OPT="$CARD_OPT $1=$2"
  fi
}

# Get card options from conf.modules
get_card_options() {
  # Clear all ALSACONF_snd_ variables
  ALSACONF_snd_temp=0
  `set | grep "^ALSACONF_snd_" | cut -d"=" -f1 \
    | sed -e 's/^/export /g' -e 's/$/=/g'`

  # Read conf.modules
  O=`grep "options * $1 * snd_index=$2 " $cfgfile`
  if [ "$O" ]; then
    # single card conf. detected
    `echo $O | cut -d" " -f3- | tr " " "\n" | sed 's/^/export ALSACONF_/g'`
  else
    O=`grep "options * $1 * snd_index=$2," $cfgfile`
    if [ -z "$O" ]; then
      O=`grep "options * $1 * snd_index=[0-9,]*,$2[, ]" $cfgfile`
    fi
    if [ "$O" ]; then
      # now is multicard conf. detected. Try, what card is it.
      X=`echo $O | cut -d" " -f3 | cut -d"=" -f2 | tr "," " "`
      I=2
      for x in $X; do
        [ $x -eq $2 ] && break
        I=`expr $I + 1`
      done
      export I
      # now $I-1 is number of card on options line, $O is options line
      `echo $O | cut -d" " -f3- | tr " " "\n" | sed 's/=/=,/g' \
         | awk 'BEGIN -F, {I=ENVIRON["I"]} {print $1$(I)}' \
         | sed 's/^/export ALSACONF_/g'`
    fi
  fi
}

# Read options for card
read_card_options() {
  # Input options for this driver
  CARD_OPT="$CARD_DRIVER snd_index=$CARD_NUM"
  OPTNUM="0"
  for OPT in $CARD_GETOPT; do
    OPTNUM=`expr $OPTNUM + 1`
    MAINOPT="(`echo \"$CARD_MAINOPT\" | cut -d" " -f$OPTNUM`)"
    eval DEFOPT="\$ALSACONF_snd_$OPT"
    if [ -z "$DEFOPT" ]; then
      DEFOPT=`echo "$CARD_DEFOPT" | cut -d" " -f$OPTNUM | tr -d "'"`
    fi
    case $OPT in
      id)
        enter_data "Card identifier." ""
        ;;
      port|sbport)
        enter_data "IO port." "$MAINOPT"
        ;;
      mpu_port)
        enter_data "MPU IO port." "$MAINOPT"
        ;;
      awe_port)
        enter_data "EMU8000 synthesizer port." "$MAINOPT"
        ;;
      wss_port|wssport)
        enter_data "WSS IO port." "$MAINOPT"
        ;;
      midi_port)
        enter_data "MIDI (MPU-401 UART) port." "$MAINOPT"
        ;;
      fm_port)
        enter_data "FM port (-1 for disable)." "$MAINOPT"
        ;;
      cport)
        enter_data "Control port." "$MAINOPT"
        ;;
      jport)
        enter_data "Game port." "$MAINOPT"
        ;;
      irq|sbirq|wssirq)
        enter_data "IRQ." "$MAINOPT"
        ;;
      mpu_irq)
        enter_data "MPU IRQ." "$MAINOPT"
        ;;
      dma1|wssdma)
        enter_data "First DMA." "$MAINOPT"
        ;;
      dma1_size|waadma_size)
        enter_data "Max. first DMA size in kB." "$MAINOPT"
        ;;
      dma2)
        enter_data "Second DMA." "$MAINOPT"
        ;;
      dma2_size)
        enter_data "Max. second DMA size in kB." "$MAINOPT"
        ;;
      dma8|sbdma8)
        enter_data "8-bit DMA." "$MAINOPT"
        ;;
      dma8_size|sbdma8_size)
        enter_data "Max. 8-bit DMA size in kB." "$MAINOPT"
        ;;
      dma16|sbdma16)
        enter_data "16-bit DMA." "$MAINOPT"
        ;;
      dma16_size|sbdma16_size)
        enter_data "Max. 16-bit DMA size in kB." "$MAINOPT"
        ;;
      joystick_dac)
        enter_data "Joystick DAC." "$MAINOPT"
        ;;
      midi)
        enter_dis_ena "MIDI UART"
        ;;
      midi_enable)
        enter_dis_ena "MIDI support."
        ;;
      port_tc)
        enter_data "Tone control port." "$MAINOPT"
        ;;
      mic_agc)
        enter_dis_ena "Mic. Auto-Gain-Control"
        ;;
      dmaa_size)
        enter_data "Max. DDMA-A (playback) size in kB." "$MAINOPT"
        ;;
      dmac_size)
        enter_data "Max. DDMA-C (record) size in kB." "$MAINOPT"
        ;;
      dac1_frame_size)
	enter_data "Max. dac1 (playback1) frame size in kB." "$MAINOPT"
	;;
      dac2_frame_size)
        enter_data "Max. dac2 (playback2) frame size in kB." "$MAINOPT"
	;;
      dac_frame_size)
        enter_data "Max. dac (playback) frame size in kB." "$MAINOPT"
        ;;
      adc_frame_size)
        enter_data "Max. adc (record) frame size in kB." "$MAINOPT"
	;;
      conp_frame_size)
        enter_data "Max. consumer dac (playback) frame size in kB" "$MAINOPT"
        ;;
      prop_frame_size)
        enter_data "Max. professional dac (playback) frame size in kB" "$MAINOPT"
        ;;
      conc_frame_size)
        enter_data "Max. consumer adc (record) frame size in kB" "$MAINOPT"
        ;;
      proc_frame_size)
        enter_data "Max. professional adc (record) frame size in kB" "$MAINOPT"
        ;;
      pbk_frame_size)
        enter_data "Max. playback frame size in kB" "$MAINOPT"
        ;;
      cap_frame_size)
        enter_data "Max. capture frame size in kB" "$MAINOPT"
        ;;
      mic_frame_size)
        enter_data "Max. microphone frame size in kB" "$MAINOPT"
        ;;
      reverb)
        enter_dis_ena "Reverb"
        ;;
      mge)
        enter_dis_ena "Microphone Gain"
        ;;
      dac_frame_size_dx)
	enter_data "Max. dac (playback) frame size in kB (DX)." "$MAINOPT"
	;;
      adc_frame_size_dx)
        enter_data "Max. adc (record) frame size in kB (DX)." "$MAINOPT"
	;;
      dac_frame_size_nx)
	enter_data "Max. dac (playback) frame size in kB (NX)." "$MAINOPT"
	;;
      adc_frame_size_nx)
        enter_data "Max. adc (record) frame size in kB (NX)." "$MAINOPT"
	;;
      gesbuf)
        enter_data "Total buffer size in kB." "$MAINOPT"
        ;;
      pcm_channels_p)
        enter_data "Playback channels." "$MAINOPT"
        ;;
      pcm_channels_c)
        enter_data "Capture channels." "$MAINOPT"
        ;;
    esac
    add_option snd_$OPT $RETURN
  done
}

# Autodetection (if detect module is present)
autodetect() {
  AUTODET=false
  modprobe snd-detect > /dev/null 2> /dev/null
  [ -f $DETECTFILE ] || return
  DD=`grep -v ^Version $DETECTFILE | tr " " "_"`
  [ "$DD" ] && AUTODET=true
  for i in $DD; do
    DET_B=`echo $i | cut -d\# -f1`
    DET_N=`echo $i | cut -d\# -f2`
    DET_C=`echo $i | cut -d\# -f3`
    DET_1=`echo $i | cut -d\# -f4`
    CTC=no
    $DIALOG --yesno "`echo -e "I have detected $DET_B card named\n\n$DET_C
      \nDo you want to configure it?"`" 9 50 && CTC=yes
    if [ "$CTC" = "yes" ]; then
      SEL_CARD="$DET_N"
      CARD_NUM=`expr $CARD_NUM + 1`
      set_card_vars $SEL_CARD $CARD_NUM
      get_card_options $CARD_DRIVER $CARD_NUM
      if [ "$DET_B" = "ISA" ]; then
        ALSACONF_snd_port="$DET_1"
      fi
      read_card_options
      eval CARD_OPT_$CARD_NUM="\$CARD_OPT"
    fi
  done
  modprobe -r snd-detect 2> /dev/null
  modprobe -r snd 2> /dev/null
}

# MAIN
if [ "$1" = "-test" ]; then
  test_card_info
fi
MENU_CARDS=""
for N in $CARDS; do
  set_card_vars $N
  for CARD_NAME in $CARD_NAMES; do
    MENU_CARDS="$MENU_CARDS $N $CARD_NAME"
  done
done
intro
if [ -d /proc/asound ]; then
  $rcalsasound stop >/dev/null 2>&1
fi
CARD_NUM=0
autodetect
while true; do
  select_card
  if [ "$SEL_CARD" = "0" ]; then
    break
  fi
  set_card_vars $SEL_CARD $CARD_NUM
  get_card_options $CARD_DRIVER $CARD_NUM
  read_card_options

  eval CARD_OPT_$CARD_NUM="\$CARD_OPT"
  CARD_NUM=`expr $CARD_NUM + 1`
done

# If no cards configured, then exit
if [ "$CARD_NUM" = "0" ]; then
  acex 0 "No cards configured."
fi

# Configuration done
$DIALOG --yesno "Do you want to modify ${cfgfile}?" 5 50 || acex 0 "Aborted."
rm -f $TMP
clear

# Copy conf.modules and make changes.
export ACB="# --- BEGIN: Generated by ALSACONF, do not edit. ---"
export ACE="# --- END: Generated by ALSACONF, do not edit. ---"

add_to_conf_modules() {
  awk '
    BEGIN {
      ACB=ENVIRON["ACB"]
      ACE=ENVIRON["ACE"]
      WOAC=0
      do {
        EOF=getline CMF <ENVIRON["cfgfile"]
        if (EOF <= 0) {
          print ""
          print ACB
          WOAC=1
          break
        }
        print CMF
      } while (CMF != ACB);
    }
    // {
      print
    }
    END {
      if (WOAC == 1) {
        print ACE
      } else {
        do {
          EOF=getline CMF <ENVIRON["cfgfile"]
        } while ((CMF != ACE) && (EOF > 0));
        print CMF
        while (EOF > 0) {
          EOF=getline CMF <ENVIRON["cfgfile"]
          if (EOF>0)
            print CMF
        }
      }
    }
  '
}

join_cards() {
  # Join cards with same driver to one line.
  N1=0
  while [ $N1 -lt $CARD_NUM ]; do
    N1=`expr $N1 + 1`
    CO1=`eval echo \\$CARD_OPT_$N1 | cut -d" " -f1`
    N2=1
    while [ $N2 -lt $N1 ]; do
      CO2=`eval echo \\$CARD_OPT_$N2 | cut -d" " -f1`
      if [ "$CO1" = "$CO2" ]; then
        O1=`eval echo \\$CARD_OPT_$N1`
        O2=`eval echo \\$CARD_OPT_$N2`
        OO=`echo "$O2 $O1" | tr " " "\n" | awk -F= '
          BEGIN {
            x=0
          }
          /.*=.*/ {
            if (A[$1]=="") {
              N[x++]=$1
              A[$1]=$2
            } else {
              A[$1]=A[$1]","$2
            }
            next
          }
          {
            drv=$1
          }
          END {
            printf drv
            for(i=0;i<x;i++) {
              n=N[i]
              printf " %s=%s",n,A[n]
            }
          }
        '`
        eval CARD_OPT_$N2=\"$OO\"
        unset CARD_OPT_$N1
        break
      fi
      N2=`expr $N2 + 1`
    done
  done
}

# Detect 2.2.X kernel
KVER=`uname -r | tr ".-" "  "`
KVER1=`echo $KVER | cut -d" " -f1`
KVER2=`echo $KVER | cut -d" " -f2`
if [ $KVER1 -ge 2 ] && [ $KVER2 -ge 2 ]; then
  SOUND_CORE="soundcore"
else
  SOUND_CORE="snd"
fi

if [ "$CARD_NUM" = "1" ]; then
# Single card.
echo "# --- ALSACONF verion $version ---
alias char-major-116 snd
alias snd-card-0 $CARD_DRIVER
alias char-major-14 $SOUND_CORE
alias sound-slot-0 snd-card-0
alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-oss
options snd snd_major=116 snd_cards_limit=1\
 snd_device_mode=$SND_MODE snd_device_gid=$SND_GID snd_device_uid=$SND_UID
options $CARD_OPT" | add_to_conf_modules > $TMP
else
# More cards.
(echo "# --- ALSACONF verion $version ---
alias char-major-116 snd
alias char-major-14 $SOUND_CORE"
N=0
while [ $N -lt $CARD_NUM ]; do
  N=`expr $N + 1`
  echo -n "alias snd-card-$N "
  eval echo \$CARD_OPT_$N | cut -d" " -f1
  echo "alias sound-slot-$N snd-card-$N"
  echo "alias sound-service-$N-0 snd-mixer-oss"
  echo "alias sound-service-$N-1 snd-seq-oss"
  echo "alias sound-service-$N-3 snd-pcm-oss"
  echo "alias sound-service-$N-8 snd-seq-oss"
  echo "alias sound-service-$N-12 snd-pcm-oss"
done
echo "options snd snd_major=116 snd_cards_limit=$CARD_NUM\
 snd_device_mode=$SND_MODE snd_device_gid=$SND_GID snd_device_uid=$SND_UID"
join_cards
N=0
while [ $N -lt $CARD_NUM ]; do
  N=`expr $N + 1`
  echo -n "options "
  eval echo \$CARD_OPT_$N
done
) | add_to_conf_modules > $TMP
fi

if cp -f $cfgfile $cfgfile.old; then
  mv -f $TMP $cfgfile
  # Update /etc/modules.conf on Debian systems newer than 2.2
  test -f /etc/debian_version -a ! -f /etc/conf.modules -a -x /sbin/update-modules \
    && /sbin/update-modules >/dev/null 2>&1
  depmod -a 2>/dev/null
  farewell "OK, $CARD_NUM card(s) configured."
  echo ""
  echo Loading driver:
  $rcalsasound start
  echo Setting the PCM volume to 100% and the Master output volume to 50%
  if amixer set PCM 100% unmute
  then
    :
  else
    echo "Could not initialize the mixer, the card was probably"
    echo "not detected correctly."
    exit
  fi
  amixer set Master 100% unmute
  # ESS 1969 chipset has 2 PCM channels
  amixer set PCM,1 100% unmute                                  2>/dev/null
  # Trident chipsets have also Wave group on digital path:
  amixer set Wave 100% unmute					2>/dev/null
  # CS4237B chipset:
  amixer set 'Master Digital' 80% unmute			2>/dev/null
  # for some GUS soundcards
  amixer set Synth 50% unmute					2>/dev/null

  # Start alsamixer dialog
  if $DIALOG --yesno "
alsamixer is a interactive program to set volume bars
on your sound card. Left & right arrow keys are used to
select the channel (or device, depending on your preferred
terminology). You can also use n (next) and p (previous).

Up/down arrows control the volume for the currently selected
device. Both the left & right signals are controlled.
You can also use "+" or "-" to turn volumes up or down.

"M" toggles muting for the current channel (both left and right).
You can mute left and right independently by using , and . resp.

You can exit with ALT + Q, or by hitting ESC.

Do you need to set your miexer settings with alsamixer?
" 21 70
  then
        clear
        alsamixer
  fi

  # Play sample dialog
  if $DIALOG --yesno "
 PCM and Master channels should now be open for playing.
      Shall I try to play a sound sample now?

                           NOTE:
If you have a big amplifier, lower your volumes or say no.
    Otherwise check that your speaker volume is open,
           and look if you can hear Linus.
" 13 65
  then
	clear
	aplay /usr/share/sndconfig/sample.au
  fi
  if [ ! -r /etc/asound.conf ]; then
     echo "Saving the mixer setup used for this in /etc/asound.conf."
     echo "It will be restored when you load alsa with \"$rcalsasound start\"."
     echo "If you save your own mixer settings to this file, run \"alsactl store\"."
     /usr/sbin/alsactl store
  fi
cat <<END
===============================================================================

 You can use aplay to play audio files with ALSA, and almost
 any OSS Sound tool and Games out there should also work.

 When you run '$rcalsasound stop' your mixer settings will
 be saved to /etc/asound.conf.
 They will be restored on the next '$rcalsasound start'
 which is used to load ALSA.

 To use the alsa mixers, start X and call "xamixer2" or "gamix",
 press the Buttons below the 'Master' and 'PCM' bars if they
 are not already pressed to unmute the channels and raise the
 volumes of these settings if not done yet.

END
else
  echo "ERROR! $cfgfile could not be saved."
  echo "Configured ALSA is in $TMP."
fi
