[SCRIPT] Select Default Sound Card (set device order)

New features which should be implemented in Porteus; suggestions are welcome. All questions or problems with testing releases (alpha, beta, or rc) should go in their relevant thread here, rather than the Bug Reports section.
User avatar
Ahau
King of Docs
King of Docs
Posts: 1331
Joined: 28 Dec 2010, 15:18
Distribution: LXDE & Xfce 32/64-bit
Location: USA

[SCRIPT] Select Default Sound Card (set device order)

Post#1 by Ahau » 15 Nov 2012, 20:26

Some users with more than one sound card have been experiencing issues with the wrong card being set as the default card, or with their cards jumping back and forth from default after reboots. There have been a couple of threads about this, particularly in regards to the Xfce edition, and I believe this can be attributed to the fact that:
1) the mixer I put in (retrovol) doesn't effectively allow users to select soundcards and have that selection survive a reboot
2) even if we reconfigure ALSA to use a card other than the default, flashplayer seems to have a mind of its own and sound stops working there (my assumption is that flashplayer only sends output to the default card, card0).

To remedy this, I'm working on a gtk-dialog script that will allow users to define their desired sound card as card0 (hw:0, however you want to refer to it).

At this point (11/15/2012) this is a very preliminary version, but please try it out and let me know your experience.

Copy and save the following text into a new file, e.g. /tmp/soundconfig-script, make it executable with "chmod +x /tmp/soundconfig-script", and then run it as "/tmp/soundconfig-script" (or cd /tmp; ./soundconfig-script):

Code: Select all

#!/bin/bash
## This script will create a gtkdialog window
## that will allow users to select a sound card
## to use as their default.

## script by Ahau, this is free software under the terms of GPL3 license.

. /usr/lib/librokenman

## Switch to root -- uncomment this if we want this application to only run as root.

if [ `whoami` != "root" ]; then
  ktsuss "$0"
  exit
fi

#exec 2>/dev/null
set -x

## Variables
export SNDSET="/tmp/sndset_$$"
[ -d $SNDSET ] && rm -r $SNDSET
mkdir -p $SNDSET
unset viruns
	
## Is user using changes= ?
change_loc=`grep -i -A1 "changes are stored" /var/log/porteus-livedbg |tail -n1`
[[ "$change_loc" != "memory" && "$change_loc" != "none" ]] && using_changes=1 || unset using_changes	
	
## Can we see modules folder?
modf=`ls -l /mnt/live/porteus/modules|awk '{print$NF}'`
[ -w $modf ] && mods=${modf} || unset mods modf

#this is here mostly so I can test alternative configs
cardsfile=/proc/asound/cards
modsfile=/proc/asound/modules

#since this will be used primarily for xfce users, we'll accomodate 
#shutdown/restart of the volumeicon tray applet
restart_volumeicon()
{
unset vipid
if [ "$viruns" = "true" ]; then
  vipid=`ps ax|grep -v grep|grep volumeicon|awk '{print$1}'`
  [[ ! $vipid ]] && volumeicon&
fi
}; export -f restart_volumeicon

#give us a simple way to exit cleanly
clean_exit()
{
rm -rf $SNDSET
rm /tmp/.snd_config*
restart_volumeicon
exit
}; export -f clean_exit
	
## generate soundcard/driver list
grep -e '^ [0-9]' $cardsfile |sed -e 's/^ //g' > $SNDSET/proclist

cat $modsfile|sed 's/^ //g'  > $SNDSET/modlist
 
#find number of cards listed
numlines=`wc $SNDSET/proclist |awk '{print$1}'`

#if a user only has one sound card, they don't need to run this utility.

#***************UNCOMMENT FOR PRODUCTION MODE!!!************************
#[ "$numlines" -le "1" ] && gtk_message "One or fewer sound cards were detected on your system, so this utility is not needed.  If your sound is not working, please post a report on our forum at http://porteus.org/forum." 550 gtk-yes && clean_exit

curline=1

while [ "$curline" -le "$numlines" ]; do
  procline=`head -n$curline $SNDSET/proclist|tail -n1`
  cardnum=`echo $procline|awk '{print$1}'`
  cardname=`echo $procline|awk -F: '{print$2}'`
  [[ $cardname ]] && cardmod=`grep -e "^$cardnum" $SNDSET/modlist|awk '{print$2}'`&& echo $cardname >> $SNDSET/cardlist && echo $cardname~$cardmod >> $SNDSET/cardmodlist;
  (( curline++ ))
done

#FOR TESTING ONLY -- REMOVE FOR PRODUCTION
#ADD A CHECK AT BEGINNING TO QUIT PROGRAM IF ONLY ONE CARD EXISTS
#echo "Big fat liar" >> $SNDSET/cardlist

apply_settings()
{
defaultcard=`cat $SNDSET/dump|grep "default card is"|tail -n 1|sed 's/default card is //g'`

#kill volumeicon
unset viruns
unset vipid
vipid=`ps ax|grep -v grep|grep volumeicon|awk '{print$1}'`
[[ $vipid ]] && viruns=true && kill $vipid

#drop drivers for all sound cards
unset rmfailed
for a in `cat $SNDSET/cardmodlist|awk -F~ '{print$2}'`; do
  rmmod $a
  unset ismodactive
  ismodactive=`lsmod|grep -w $a`
  [[ "$ismodactive" ]] && rmfailed=true;
done
[ "$rmfailed" = "true" ] && gtk_message "Sound drivers failed to unload, please close all applications that support sound and retry." 450 gtk-yes && clean_exit

#bring them back
#gtk_message "Please wait a moment for the sound system to reinitialize." 350 gtk-yes &
#can we convert this to a red line of text inside the gui box?

defaultdriver=`grep "$defaultcard" $SNDSET/cardmodlist|awk -F~ '{print$2}'`
sleep 1
modprobe $defaultdriver
sleep 1
unset other_list
for a in `cat $SNDSET/cardmodlist|awk -F~ '{print$2}'|grep -v "$defaultdriver"`; do
  modprobe $a
  other_list=`echo "$other_list,$a"`
  sleep 1;
done

restart_volumeicon

export defaultdriver
export other_list

}; export -f apply_settings
	
export SNDCONFIG='
<window window_position="1" title="Default Sound Card Selector" icon-name="preferences-sound" allow-shrink="false" width-request="500" height-request="300">
<vbox margin="10">
  <hbox>
    <pixmap><height>48</height><width>48</width><input file>/usr/share/icons/Humanity-LXDE/devices/48/input-keyboard.svg</input></pixmap>
    '`txtcolor 400 darkred x-large normal "            Porteus Sound Card Selector"`'
  </hbox>
    '`hsep`'
    <frame Choose your default sound card>
      <hbox>
      <text xalign="0" wrap="true" width-request="450"><label>"
Please select your desired default sound card from the list below.
      
Once you press the OK button, your selection will be applied.

Please close all programs that use sound, such as browsers, media players and mixers (other than volumeicon).
"</label>        
      </text>
      </hbox>
      <hseparator></hseparator>
<hbox>
<vbox>
<hbox>
  <text use-markup="true" xalign="0" wrap="true"><label>"Default card:"</label></text>
<comboboxtext focus-on-click="false" width-request="250">
	<variable>PICKDEFBOX</variable>
	<input file>'$SNDSET'/cardlist</input>
	<action signal="changed">echo default card is $PICKDEFBOX >> $SNDSET/dump</action>
	<action signal="changed">enable:APPLY</action>
	<action signal="changed">enable:OKBUT</action>
</comboboxtext>
</hbox>

</vbox>
<vbox>
<text width-request="20"><label>""</label></text>
</vbox>
</hbox>   
<hseparator></hseparator>
    </frame>
  <hbox>
    <button ok>
        <variable>OKBUT</variable>
    </button>
    <button cancel>
    </button>
  </hbox>
</vbox>
<action signal="hide">exit:Cancel</action>
</window>
'
gtkdialog -p SNDCONFIG > /tmp/.snd_config

## Did user cancel ?
[ `egrep -o "Cancel|abort" /tmp/.snd_config` ] && clean_exit

apply_settings

#write the config
echo "options snd slots=$defaultdriver$other_list" > /etc/modprobe.d/alsa_order.conf

gtk_message "Your settings have been applied." 350 gtk-yes

## prompt user to create a module
if [ "using_changes" != "1" ]; then

export ASK_ME='
'`start_window "Yes or no" cdr 450`'
  <frame>
    <hbox>
      '`pixmapstock gtk-dialog-question`'
      <text use-markup="true" width-request="375" selectable="true" can-focus="no">
      <label>"You do not appear to be saving your Porteus changes. You should create a module for your changes which will be loaded every time you boot.  Would you like to create the module now?"</label></text>
  </hbox>
  </frame>
  <hbox>
    '`butyes`'
    '`butno`'
  </hbox>
'`end_window`'
'
for a in `gtkdialog -p ASK_ME`; do
  if [ `egrep -o "abort|No|no" <<<$a` ]; then
    clean_exit
  fi
  if [ `egrep -o "Yes|yes" <<<$a` ]; then
    answ=yes
      else
    unset answ
  fi
done

  if [ "$answ" == "yes" ]; then
    unset answ
    mkdir -p $SNDSET/fakeroot/etc/modprobe.d/
	cp -a /etc/modprobe.d/alsa_order.conf $SNDSET/fakeroot/etc/modprobe.d/
    
    if [ "$mods" ]; then
      dir2xzm $SNDSET/fakeroot/ $mods/soundcard_config.xzm
      gtk_message "Your soundcard_config.xzm module will now be activated when you boot Porteus." 450 gtk-yes
        else
        ## The modules folder is not available
        dir2xzm $SNDSET/fakeroot/ /tmp/soundcard_config.xzm
        gtk_message "Your porteus/modules folder was not found or is unwritable. Please copy the file /tmp/soundcard_config.xzm into the modules folder or base folder." 500 gtk-no
    fi
  fi
fi


clean_exit

Note that you will need to close any applications that interact with ALSA/sound -- this includes any mixers in your panel (retrovol in xfce, and "volume control" in the lxde panel -- I haven't figured out yet what needs to be closed in kde4 or trinity, so standard edition users may want to do this in lxde).

Please report your experience on this thread, and I'll work to resolve bugs.

ToDo:
-fix broken icon
-add button to test configuration before writing config file
*done*add a prompt to tell users if they only have one recognized card, that they don't need to run this script

If this fails to work for you but you still want to test my methodology, please simply create a file at /etc/modprobe.d/alsa_order.conf with one line of text such as:

Code: Select all

options snd slots=snd_hda_intel,snd_emu10k1
but replace "snd_hda_intel" with the driver of your desired default card and "snd_emu10k1" with the driver of your other card. You can find the driver names by issuing "lspci -kk".

Many thanks for your help in testing!
Please take a look at our online documentation, here. Suggestions are welcome!

mailmegx
White ninja
White ninja
Posts: 29
Joined: 23 Mar 2012, 18:44
Distribution: Porteus 1.2 XFCE 64bit
Location: Cyprus

Re: [SCRIPT] Select Default Sound Card (set device order)

Post#2 by mailmegx » 16 Nov 2012, 02:36

Hi Ahau

I tried the script, it showed my 3 cards, when I selected the default it said it failed to set it, after that there were no soundcards. I will email you the output of the script.

GX

User avatar
Ahau
King of Docs
King of Docs
Posts: 1331
Joined: 28 Dec 2010, 15:18
Distribution: LXDE & Xfce 32/64-bit
Location: USA

Re: [SCRIPT] Select Default Sound Card (set device order)

Post#3 by Ahau » 16 Nov 2012, 07:00

GX,

Thank you so much for testing and for the emailing the output. With that, I was able to find out what went wrong, and I think I have the issues addressed. I've updated the script in the first post above, please give that a shot :)

NOTE -- you have to change the selection in the box in order for this to work. if your card is listed first when it opens, open the drop down, pick another card, then switch it back to the first. I'll fix this tomorrow.

if you run into any issues that persist beyond a reboot, please remove any modules created by this script and delete the file at /etc/modprobe.d/alsa_order.conf

thanks again!
Please take a look at our online documentation, here. Suggestions are welcome!

Post Reply