#!/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
# I18N'ed by Masaki Shinomiya <shino@pos.to>
# specify the directory i18n data file exists
ALSACONF_DIR=/usr/lib/alsaconf

#  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\
 @128 128 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\
 @128 128 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\
 @128 128 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-es1938 ESS_Solo-1_ES1938/ES1946\
 @\
 @\
 @"
export CARD_0x15="snd-card-es18xx 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-opti93x 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-trident 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-trident 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\
 @128 256"
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\
 @128 128 256 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\
 @128 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\
 @128 128 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\
 @64 64 128 1 2 0"
export CARD_0x34="snd-card-x ESS_ES1978\
 @\
 @\
 @"
export CARD_0x35="snd-card-x DIGI96\
 @\
 @\
 @"
export CARD_0x36="snd-card-via686a VIA_VT82C686A\
 @mpu_port pbk_frame_size cap_frame_size fm_frame_size\
 @0x300,0x310,0x320,0x330 4-128 4-128 4-128\
 @0x300 128 128 128"
export CARD_0x40="snd-card-cmipci C-Media_CMI8x38\
 @dac_frame_size adc_frame_size\
 @4-128 4-128 \
 @128 128"
export CARD_0x41="snd-card-ymfpci YAMAHA_YMF7xx\
 @dac_frame_size adc_frame_size ac97_frame_size\
 @4-128 4-128 4-128\
 @128 128 128"
export CARD_0x42="snd-card-als4000 Advance_Logic_ALS4000\
 @sb_port mpu_port fm_port game_port dac_frame_size adc_frame_size\
 @0x220,0x240 0x330 0x388 0x200 1-32 1-32\
 @'' 32 32"
export CARD_0x43="snd-card-maestro3 ESS_Maestro3/Allegro\
 @playback_bufsize capture_bufsize global_dsp_speed external_amp\
 @4-128 4-128 33,36,49 0-1\
 @128 128 '' ''"
export CARD_0x44="snd-card-cs4281 Cirrus_Logic_CS4281\
 @playback_bufsize capture_bufsize\
 @4-128 4-128\
 @128 128"
export CARD_0x45="snd-card-nm256 NeoMagic_256AV/256ZX\
 @playback_bufsize capture_bufsize\
 @4-128 4-128\
 @128 128 "
export CARD_0x46="snd-card-via8233 VIA_VT8233\
 @pbk_frame_size cap_frame_size\
 @4-128 4-128\
 @128 128 "
export CARDS_0x47="snd-card-ali5451 ALI_M5451\
 @dac_frame_size adc_frame_size pcm_channels\
 @4-128 4-64 1-32\
 @128 64 32"
export CARDS_0x48="snd-card-awacs PowerMac_AWACS\
 @dac_frame_size adc_frame_size\
 @4-128 4-128\
 @128 128"

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\
 0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0x48"

# 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

# for Vine
if [ -e /sbin/snddevices ]; then
  export mksnddevices=/sbin/snddevices
else
  export mksnddevices=/bin/true
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

# Messages
#export Mustberoot="You must be root to use this script."
#export Initializing="Initializing ... please wait ..."
export Aborted="Aborted."
export Selectcard="Select card"
export Disable="Disable"
export Enable="Enable"
export Detected="I have detected"
export Configure="Do you want to configure it?"
export Modify="Do you want to modify"
export Loading="Loading driver:"
export Setting="Setting the PCM volume and the Master output volume to 70%"
export Couldnotinitialize="Could not initialize the mixer, the card was probably\n\
not detected correctly."
export Saving="Saving the mixer setup used for this in /etc/asound.conf.\n\
It will be restored when you load alsa with \"$rcalsasound start\".\n\
If you save your own mixer settings to this file, run \"alsactl store\"."
export Couldnotbesaved="could not be saved."
export ConfiguredALSA="Configured ALSA is in $TMP"
export Intro="\n\
  This script is a configurator for Advanced Linux Sound\n\
  Architecture driver.\n\
  If alsa is running, you should close all sound apps\n\
  now and run \"$rcalsasound stop\"\n\
  to remove the drivers. alsaconf will try to do this,\n\
  but it cannot kill your apps.\n\
  You need ALSA 0.5.0 or higher now.\n\
"
export Farewell="\n\
           will prepare the card for playing now.\n\
\n\
 Now I'll run '$rcalsasound start',\n\
 then use I'll use amixer to raise the 'Master' and 'PCM'\n\
 volumes. If you want to use the commandline-based mixer\n\
 amixer also, read the man page: 'man amixer'.\n\
"
export Alsamixer="\n\
alsamixer is a interactive program to set volume bars\n\
on your sound card. Left & right arrow keys are used to\n\
select the channel (or device, depending on your preferred\n\
terminology). You can also use n (next) and p (previous).\n\
\n\
Up/down arrows control the volume for the currently selected\n\
device. Both the left & right signals are controlled.\n\
You can also use "+" or "-" to turn volumes up or down.\n\
\n\
"M" toggles muting for the current channel (both left and right).\n\
You can mute left and right independently by using , and . resp.\n\
\n\
You can exit with ALT + Q, or by hitting ESC.\n\
\n\
Do you need to set your miexer settings with alsamixer?\n\
"
export Sample="\n\
 PCM and Master channels should now be open for playing.\n\
      Shall I try to play a sound sample now?\n\
\n\
                           NOTE:\n\
If you have a big amplifier, lower your volumes or say no.\n\
    Otherwise check that your speaker volume is open,\n\
           and look if you can hear Linus.\n\
"
export Ending="\n\
===============================================================================\n\
\n\
 You can use aplay to play audio files with ALSA, and almost\n\
 any OSS Sound tool and Games out there should also work.\n\
\n\
 When you run '$rcalsasound stop' your mixer settings will\n\
 be saved to /etc/asound.conf.\n\
 They will be restored on the next '$rcalsasound start'\n\
 which is used to load ALSA.\n\
\n\
 To use the alsa mixers, start X and call "xamixer2" or "gamix",\n\
 press the Buttons below the 'Master' and 'PCM' bars if they\n\
 are not already pressed to unmute the channels and raise the\n\
 volumes of these settings if not done yet.\n\
"
# read I18N message file
[ "$ALSACONF_DIR" = "" ] && ALSACONF_DIR=.
L=$(echo $LANG | sed 's/_.*$//')
i18n=$ALSACONF_DIR/alsaconf_$L
[ -f $i18n ] && . $i18n

# 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
$Intro
               (Detected ALSA version: $ALSAVER)
" 21 67 || acex 0 "$Aborted."
}

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

                $*

                   ALSA  CONFIGURATOR
                     version $version
$Farewell
" 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 "$Selectcard" 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"
        ;;
      ac97_frame_size)
        enter_data "Mac. ac97 frame sieze 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"
        ;;
      game_port)
        enter_data "Game port." "$MAINOPT"
        ;;
      playback_bufsize)
        enter_data "Max. dac frame size in kB." "$MAINOPT"
        ;;
      capture_bufsize)
        enter_data "Max. adc frame size in kB." "$MAINOPT"
        ;;
      global_dsp_speed)
        enter_data "DSP rate." "$MAINOPT"
        ;;
      external_amp)
        enter_data "Enable external amp." "$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 "$Detected $DET_B card named\n\n$DET_C
      \n$Configure"`" 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 "$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 ""

  # 10 Jan 2002 Masaki Shinomiya <shino@os.to>
  $mksnddevices   # Making sound devices
  /sbin/depmod -a

  echo "$Loading"
  $rcalsasound start
  echo "$Setting"
# because some drivers do not accept 100%
  if amixer set Master 70% unmute
  then
    :
  else
    echo "$Couldnotinitialize"
    exit
  fi
  amixer set PCM 70% unmute
  # ESS 1969 chipset has 2 PCM channels
  amixer set PCM,1 70% unmute                                  2>/dev/null
  # Trident chipsets have also Wave group on digital path:
  amixer set Wave 70% unmute					2>/dev/null
  # CS4237B chipset:
  amixer set 'Master Digital' 70% unmute			2>/dev/null
  # for some GUS soundcards
  amixer set Synth 70% unmute					2>/dev/null
  # ymfpci
  GROUP='Wave Playback Volume'
  amixer | grep -q "$GROUP" && amixer set "$GROUP" 100%

  # Start alsamixer dialog
  if $DIALOG --yesno "$Alsamixer" 21 70
  then
        clear
        alsamixer
  fi

  # Play sample dialog
  if $DIALOG --yesno "$Sample" 13 65
  then
	clear
	aplay /usr/share/sndconfig/sample.au
  fi
  if [ ! -r /etc/asound.conf ]; then
     echo "$Saving"
     /usr/sbin/alsactl store
  fi
echo -e $Ending
else
  echo "ERROR! $cfgfile $Couldnotbesaved"
  echo "$ConfiguredALSA"
fi
