#!/bin/sh
#
# Copyright (c) 2004-2005 Mikael Magnusson <mikma@users.sourceforge.net>
#

bindir=@bindir@
LO10K1=${bindir}/lo10k1

## Default configuration
#
DECODER=SIMPLE51
#DECODER=PROLOGIC
#DECODER=BOTH

# Inputs
FXIN_PCM_89=1
EXTIN_AC97=1
EXTIN_SPDIF_CD=1
#EXTIN_ZOOM=1
#EXTIN_TOSLINK=1
#EXTIN_LINE1=1
#EXTIN_COAX_SPDIF=1
#EXTIN_LINE2=1

# Outputs
EXTOUT_ANALOG_FRONT=1
EXTOUT_ANALOG_REAR=1
EXTOUT_ANALOG_CENTER=1
EXTOUT_ANALOG_LFE=1
#EXTOUT_IEC958=1
#EXTOUT_REAR=1
#EXTOUT_CENTER=1
#EXTOUT_LFE=1
EXTOUT_HEADPHONE=1

if [ -r /etc/default/ld10k1 ]; then
    . /etc/default/ld10k1
fi

#LO10K1="valgrind --num-callers=6 ../lo10k1"

DEBUG=0

std_playback=playback
#std_playback=playback_noswitch
std_capture=capture
#std_capture=capture_noswitch

function log
{
    local level=$1

    shift

    if [ $DEBUG -gt $level ]; then
	echo "$@"
    fi
}

function runlo10k1
{
    log 2 $LO10K1 "$@"

    $LO10K1 "$@"

    res=$?

    if [ $res -ne 0 ]; then
	echo Failed $LO10K1 "$@"
	exit 1
    fi
}

function rename
{
    port=$1
    name=$2

    log 1 "rename  $port = $name"

    runlo10k1 --renam "$port=$name"
}

function connect
{
    from=$1
    op=$2
    to=$3

    log 1 "connect  $from $op $to"

    runlo10k1 --conadd "$from$op$to"
}

function copy
{
    local name=$1
    local port=$2

    log 0 "copy              \"$name\" $port"

    # Copy
    runlo10k1 -n --patch_name "$name Copy" -a copy_2.emu10k1
    # Input
    connect "PIN($name Copy)" '=' "$port"
}

function volume
{
    local name=$1
    local port=$2
    local default=$3
    local index=${4:-0}

    log 1 "volume            \"$name\" $port default=$default"

    # Volume
    runlo10k1 -n --ctrl "c-Left,Right:$name Volume,t-$name Volume:1,s-$name Volume:$default,i-$name Volume:${index}" --patch_name "$name Volume" -a vol_2.emu10k1
    # Input
    connect "PIN($name Volume)" '=' "$port"
}

function master_volume
{
    local name=$1
    local port=$2
    local default=$3
    local index=$4

    log 1 "master volume \"$name\" $port default=$default"

    # Master
    runlo10k1 -n --ctrl "c-VolM:$name Volume,t-$name Volume:1,s-$name Volume:$default,i-$name Volume:$index" --patch_name "$name Volume" -a vol_master.emu10k1
    # Input
    connect "$port" '=' "PIN($name Volume)"
}

function switch
{
    local name=$1
    local port=$2
    local default=$3

    log 1 "switch            \"$name\" $port default=$default"

    # Switch
    #runlo10k1 -n --ctrl "c-switchL,switchR:$name Switch,t-$name Switch:4,s-$name Switch:$default" --patch_name "$name Switch" -a switch_2.emu10k1
    runlo10k1 -n --ctrl "c-switch:$name Switch,t-$name Switch:4,s-$name Switch:$default" --patch_name "$name Switch" -a mono_switch_2.emu10k1
    # Input
    connect "PIN($name Switch)" '>' "$port"
}

function switch_2x2
{
    local name=$1
    local port1=$2
    local port2=$3
    local default=$4

    log 1 "switch 2x2        \"$name\" $port1 $port2 default=$default"

    # Switch
    runlo10k1 -n --ctrl "c-switchL,switchR:$name Switch,t-$name Switch:4,s-$name Switch:$default" --patch_name "$name Switch" -a switch_2x2.emu10k1
    # Input
    connect "PIN($name Switch,0,1)" '>' "$port1"
    connect "PIN($name Switch,2,3)" '>' "$port2"
}

function switch_5x2
{
    local name=$1
    local port1=$2
    local port2=$3
    local default=$4

    log 1 "switch 5x2        \"$name\" $port1 $port2 default=$default"

    # Switch
    runlo10k1 -n --ctrl "c-switch:$name Switch,t-$name Switch:4,s-$name Switch:$default" --patch_name "$name Switch" -a switch_5x2.emu10k1
    # Input
    connect "PIN($name Switch,0,1,2,3,4)" '>' "$port1"
    connect "PIN($name Switch,5,6,7,8,9)" '>' "$port2"
}

function master_switch
{
    local name=$1
    local port=$2
    local default=$3
    local index=$4

    log 1 "master_switch \"$name\" $port default=$default"

    # Master switch
    runlo10k1 -n --ctrl "c-switch:$name Switch,t-$name Switch:4,s-$name Switch:$default,i-$name Switch:$index" --patch_name "$name Switch" -a switch_6.emu10k1
    # Input
    connect "PIN($name Switch)" '=' "$port"
}

function playback
{
    name=$1
    port=$2

    log 0 "playback          \"$name\" $port"

    # Switch
    switch "$name Playback" "$port" "1#1"
    volume "$name Playback" "POUT($name Playback Switch)" "0#0"
    # Output
    add_output "POUT($name Playback Volume)"
}

function playback_noswitch
{
    name=$1
    port=$2

    log 0 "playback_noswitch \"$name\" $port"

    # Switch
    volume "$name Playback" "$port" "0#0"
    # Output
    add_output "POUT($name Playback Volume)"
}

function capture
{
    name=$1
    port=$2

    log 0 "capture           \"$name\" $port"

    # Capture switch
    switch "$name Capture" "$port" "0#0"
    volume "$name Capture" "POUT($name Capture Switch)" "100#100"
    # Output
    connect "POUT($name Capture Volume)" '>' "OUT(OUT_PCM_Capture_Left,OUT_PCM_Capture_Right)"
}

function capture_noswitch
{
    name=$1
    port=$2

    log 0 "capture_noswitch  \"$name\" $port"

    # Capture switch
    volume "$name Capture" "$port" "100#100"
    # Output
    connect "POUT($name Capture Volume)" '>' "OUT(OUT_PCM_Capture_Left,OUT_PCM_Capture_Right)"
}

function master
{
    local name=$1
    local port=$2
    local index=$3

    log 0 "master            \"$name\" $port"

    # Switch
    master_volume "$name Playback" "$port" 100 $index
    master_switch "$name Playback" "POUT($name Playback Volume)" 1 $index
}

function dump_patches
{
    num=$1

    for (( i=0; $i < $num; i=$i+1 )); do
	p=$(( $i + 100))
	runlo10k1 --debug $p
    done


    exit
}

function add_output
{
    local port=$1

    $add_output_func "$port"
}

function add_output_tone_2
{
    local port=$1

    connect "$port" '>' "PIN(Tone Control,0,1)"
}

function add_output_simple_2
{
    local port=$1

    connect "$port" '>' "PIN(Wave Simple Stereo To 51,0,1)"
}

function add_output_prologic_2
{
    local port=$1

    connect "$port" '>' "PIN(Wave Prologic,0,1)"
}

function add_output_switched_2
{
    local port=$1

    add_output_simple_2 "$port"
    add_output_prologic_2 "$port"
}


function simple_stereo_to_51
{
    local name=$1
    local control=$2
    local port=$3

    log 0 "simple_stereo_to_51 \"$name\" $port"

# Simple Stereo to 5.1
    runlo10k1 -n --ctrl "c-Left,Right:${control}Front Playback Volume,t-${control}Front Playback Volume:1,s-${control}Front Playback Volume:100#100,c-LeftSurr,RightSurr:${control}Surround Playback Volume,t-${control}Surround Playback Volume:1,c-Center:${control}Center Playback Volume,t-${control}Center Playback Volume:1,c-LFE:${control}LFE Playback Volume,t-${control}LFE Playback Volume:1" --patch_name "$name Simple Stereo To 51" -a sto51.emu10k1
# Input
    if [ "$port" != "" ]; then
	connect "$port" '>' "PIN($name Simple Stereo To 51,0,1)"
    fi
}

function prologic
{
    local name=$1
    local control=$2
    local port=$3

    log 0 "prologic          \"$name\" $port"

# Stereo to 5.1
    runlo10k1 -n --ctrl "" --patch_name "$name Prologic" -a prologic.emu10k1
# Input
    if [ "$port" != "" ]; then
	connect "PIN($name Prologic,0,1)" '>' "$port"
    fi

# PCM Multi
    runlo10k1 -n --ctrl "c-Left,Right:${control}Front Playback Volume,t-${control}Front Playback Volume:1,c-LeftSurr,RightSurr:${control}Surround Playback Volume,t-${control}Surround Playback Volume:1,c-Center:${control}Center Playback Volume,t-${control}Center Playback Volume:1,c-LFE:${control}LFE Playback Volume,t-${control}LFE Playback Volume:1" --patch_name "$name Multi Volume" -a simple.emu10k1
# Input
    connect "POUT($name Prologic)" '=' "PIN($name Multi Volume,0,1,2,3,4,5)"
}

function tone
{
    local name=$1
    local port=$2

    log 0 "tone              \"$name\" $port"

#
# Tone
#
    runlo10k1 -n --ctrl "c-bass0,bass1,bass2,bass3,bass4:$name - Bass,t-$name - Bass:2,v-$name - Bass:1,c-treble0,treble1,treble2,treble3,treble4:$name - Treble,t-$name - Treble:3,v-$name - Treble:1,c-toneonoff:$name - Switch,t-$name - Switch:4" --patch_name "${name}" -a tone.emu10k1
}

function multi_playback
{
    local name=$1
    local port=$2

    if [ "$name" != "" ]; then
	name="$name "
    fi

    log 0 "multi_playback    \"$name\" $port"

# PCM Multi
    runlo10k1 -n --ctrl "c-Left,Right:${name}Front Playback Volume,t-${name}Front Playback Volume:1,c-LeftSurr,RightSurr:${name}Surround Playback Volume,t-${name}Surround Playback Volume:1,c-Center:${name}Center Playback Volume,t-${name}Center Playback Volume:1,c-LFE:${name}LFE Playback Volume,t-${name}LFE Playback Volume:1" --patch_name "$name Multi Volume" -a simple.emu10k1
# Input
    connect "PIN($name Multi Volume)" '>' "$port"
# Output
    connect "POUT($name Multi Volume)" '>' "PIN(Tone Control)"
}

function fxbus
{
    local name=$1
    local enable_pcm_fx89=$2

    log 0 "fxbus             \"$name\"" $enable_pcm_fx89

    runlo10k1 --patch_name "$name" -a fxbus.emu10k1
    connect "PIN($name)" '=' "FX(FX_PCM_Left,FX_PCM_Right,FX_PCM_Surr_Left,FX_PCM_Surr_Right,FX_MIDI_Left,FX_MIDI_Right,FX_Center,FX_LFE,8,9)"


    if [ $enable_pcm_fx89 ]; then
	local front="8,9"
    else
	local front="0,1"
    fi

    fx_pcm="POUT($name,0,1)"
    fx_front="POUT($name,$front)"
    fx_rear="POUT($name,2,3)"
    fx_midi="POUT($name,4,5)"
    fx_multi="POUT($name,$front,2,3,6,7)"
}

#dump_patches 16

# Clear
runlo10k1 -s 

rename "FX(8)" "FX_PCM_Front_Left"
rename "FX(9)" "FX_PCM_Front_Right"

tone "Tone Control"

fxbus "FX Bus" $FXIN_PCM_89

if [ "$DECODER" = "PROLOGIC" ]; then
    prologic "Wave"
    connect "POUT(Wave Multi Volume,0,1,2,3,4,5)" '>' "PIN(Tone Control,0,1,2,3,4,5)"
    add_output_func=add_output_prologic_2
elif [ "$DECODER" = "BOTH" ]; then
    prologic "Wave"
    simple_stereo_to_51 "Wave"
    switch_5x2 "Wave Prologic" "POUT(Wave Prologic,0,1,2,3,4)" "POUT(Wave Simple Stereo To 51,0,1,2,3,4)" 0
    add_output_func=add_output_switched_2
else
    simple_stereo_to_51 "Wave"
#"$fx_pcm"
    connect "POUT(Wave Simple Stereo To 51,0,1,2,3,4,5)" '>' "PIN(Tone Control,0,1,2,3,4,5)"
    add_output_func=add_output_simple_2
fi

#
# FXBUS
#

$std_playback "Wave" "$fx_pcm"
$std_capture "Wave" "$fx_pcm"

multi_playback "PCM" "$fx_multi"
$std_capture "PCM Front" "$fx_front"
$std_capture "PCM Surround" "$fx_rear"

$std_playback "Music" "$fx_midi"
$std_capture "Music" "$fx_midi"


#
# INPUTS
#

if [ "$EXTIN_AC97" = "1" ]; then
    $std_playback "AC97" "IN(IN_AC97_Left,IN_AC97_Right)"
    capture_noswitch "AC97" "IN(IN_AC97_Left,IN_AC97_Right)"
fi

if [ "$EXTIN_SPDIF_CD" = "1" ]; then
    $std_playback "IEC958 TTL" "IN(IN_TTL_IEC958_Left,IN_TTL_IEC958_Right)"
    $std_capture "IEC958 TTL" "IN(IN_TTL_IEC958_Left,IN_TTL_IEC958_Right)"
fi

if [ "$EXTIN_ZOOM" = "1" ]; then
    $std_playback "Zoom Video" "IN(IN_Zoom_Video_Left,IN_Zoom_Video_Right)"
    $std_capture "Zoom Video" "IN(IN_Zoom_Video_Left,IN_Zoom_Video_Right)"
fi

if [ "$EXTIN_TOSLINK" = "1" ]; then
    $std_playback "IEC958 LiveDrive" "IN(IN_Optical_IEC958_Left,IN_Optical_IEC958_Right)"
    $std_capture "IEC958 LiveDrive" "IN(IN_Optical_IEC958_Left,IN_Optical_IEC958_Right)"
fi

if [ "$EXTIN_LINE1" = "1" ]; then
    $std_playback "Line LiveDrive" "IN(IN_Line_Mic_1_Left,IN_Line_Mic_1_Right)"
    $std_capture "Line LiveDrive" "IN(IN_Line_Mic_1_Left,IN_Line_Mic_1_Right)"
fi

if [ "$EXTIN_COAX_SPDIF" = "1" ]; then
    $std_playback "IEC958 Coaxial" "IN(IN_Coax_IEC958_Left,IN_Coax_IEC958_Right)"
    $std_capture "IEC958 Coaxial" "IN(IN_Coax_IEC958_Left,IN_Coax_IEC958_Right)"
fi

if [ "$EXTIN_LINE2" = "1" ]; then
    $std_playback "Line2 LiveDrive" "IN(IN_Line_Mic_2_Left,IN_Line_Mic_2_Right)"
    $std_capture "Line2 LiveDrive" "IN(IN_Line_Mic_2_Left,IN_Line_Mic_2_Right)"
fi

master_name="Master Digital"
master_volume="$master_name Playback Volume"
master_switch="$master_name Playback Switch"

master "$master_name" "POUT(Tone Control)" 0

if [ "$EXTOUT_ANALOG_FRONT" = "1" ]; then
    log 0 "out               Analog Front"
    connect "POUT($master_switch,0,1)" '>' "OUT(OUT_AC97_Left,OUT_AC97_Right)"
fi

if [ "$EXTOUT_REAR" = "1" ]; then
    log 0 "out               SB Live 5.1 (c) 2003 - Rear"
    connect "POUT($master_switch,2,3)" '>' "OUT(13,14)"
elif [ "$EXTOUT_ANALOG_REAR" = "1" ]; then
    log 0 "out               Analog Rear"
    connect "POUT($master_switch,2,3)" '>' "OUT(OUT_Analog_Surr_Left,OUT_Analog_Surr_Right)"
fi

if [ "$EXTOUT_CENTER" = "1" ]; then 
    log 0 "out               Center"
    connect "POUT($master_switch,4)" '>' "OUT(OUT_Center)"
elif [ "$EXTOUT_ANALOG_CENTER" = "1" ]; then 
    log 0 "out               Analog Center"
    connect "POUT($master_switch,4)" '>' "OUT(OUT_AC97_Center)"
fi

if [ "$EXTOUT_LFE" = "1" ]; then
    log 0 "out               LFE"
    connect "POUT($master_switch,5)" '>' "OUT(OUT_LFE)"
elif [ "$EXTOUT_ANALOG_LFE" = "1" ]; then
    log 0 "out               Analog LFE"
    connect "POUT($master_switch,5)" '>' "OUT(OUT_AC97_LFE)"
fi

# if [ $EXTOUT_MIC_CAP ]; then
#     log 0 "out               MIC Capture buffer"
#     connect "" '>' "OUT(OUT_MIC_Capture)"
# fi

if [ "$EXTOUT_HEADPHONE" = "1" ]; then
# Headphone
    log 0 "out               Headphone"

    runlo10k1 -n --ctrl "c-switchL:Headphone Center Playback Switch,c-switchR:Headphone LFE Playback Switch,t-Headphone Center Playback Switch:4,t-Headphone LFE Playback Switch:4,i-Headphone Center Playback Switch:1,i-Headphone LFE Playback Switch:1" --patch_name "Headphone Playback Switch" -a switch_2x2.emu10k1
#Input
    connect "PIN(Headphone Playback Switch,0,1)" '>' "POUT(Tone Control,0,1)"
    connect "PIN(Headphone Playback Switch,2,3)" '>' "POUT(Tone Control,4,5)"

    volume "Headphone Playback" "POUT(Headphone Playback Switch,0,1)" 100#100 1

#Output
    connect "POUT(Headphone Playback Volume)" '>' "OUT(OUT_Headphone_Left,OUT_Headphone_Right)"
fi

if [ "$EXTOUT_IEC958" = "1" ]; then
    log 0 "out               IEC958 Optical Raw"

    switch_2x2 "IEC958 Optical Raw Playback" "POUT(Tone Control,0,1)" "POUT(IEC958)"  1#1
    connect "POUT(IEC958 Optical Raw Playback Switch,0,1)" '>' "OUT(OUT_Opt_IEC958_Left,OUT_Opt_IEC958_Right)"
#    connect "POUT(IEC958 Optical Raw Playback Switch,0,1)" '>' "OUT(OUT_AC97_Left,OUT_AC97_Right)"
fi
