This is my stupid and extremely hacky way to do it. Open for improvements.
It consists of two main parts:
- A script that correcly configures the microphone in amixer, that is triggered on udev start
- An autostarted script + program that resets the USB card, so that the udev-rule will actually be triggered on logon.
Create script to configure microphone
sudo nano /usr/local/bin/setmic.sh
#!/usr/bin/env bash
exec >> /tmp/setmic.log 2>&1
echo "Script started at $(date)"
cardNumber=$(aplay -l|grep 'Sound BlasterX G6'|cut -d' ' -f 2 |tr -d ':')
amixer -c "$cardNumber" -q set "PCM Capture Source" "External Mic"
if [ $? -eq 0 ]; then
echo "PCM Capture Source successfully changed to 'External Mic'"
else
echo "Failed to configure PCM Capture source for Sound BlasterX G6"
fi
amixer -c "$cardNumber" -q sset 'Input Gain Control' 3
if [ $? -eq 0 ]; then
echo "Input Gain Control set to 3"
else
echo "Failed to activate mic Boost for Sound BlasterX G6"
fi
Make it executable
sudo chmod +x /usr/local/bin/setmic.sh
Add udev rule to auto execute on usb connect
sudo nano /etc/udev/rules.d/99-sound-blaster.rules
SUBSYSTEM=="sound", ACTION=="add", ATTRS{idVendor}=="041e", ATTRS{idProduct}=="3256", RUN+="/bin/bash -c 'sleep 5; /usr/bin/setmic.sh", OPTIONS+="watch"
sudo udevadm control --reload
sudo udevadm trigger
Create program to reset USB-device
nano ~/usbreset.c
Add the following content:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
int main(int argc, char *argv)
{
const char filename;
int fd;
int rc;
if (argc != 2) {
fprintf(stderr, "Usage: usbreset device-filename\n");
return 1;
}
filename = argv[1];
fd = open(filename, O_WRONLY);
if (fd < 0) {
perror("Error opening output file");
return 1;
}
printf("Resetting USB device %s\n", filename);
rc = ioctl(fd, USBDEVFS_RESET, 0);
if (rc < 0) {
perror("Error in ioctl");
return 1;
}
printf("Reset successful\n");
close(fd);
return 0;
}
Compile the script and move it to the correct location
cc usbreset.c -o usbreset
mv usbreset /usr/local/bin
Secure the file to avoid exploits
sudo chown root:root /usr/local/bin/usbreset
sudo chmod 755 /usr/local/bin/usbreset
Add the script to sudoers
This is to avoid password prompts behind the scenes on autostart
sudo nano /etc/sudoers
# /etc/sudoers
your_username_here ALL=(root) NOPASSWD: /usr/local/bin/usbreset /dev/bus/usb/*/*
Create the reset script
This script will reset the USB device to make udev rules trigger (e.g. on logon)
sudo nano ~/bin/reset_soundcard.sh
#!/bin/bash
echo "$(date): Starting reset of Sound BlasterX G6" >> /tmp/reset_soundcard.log
DEVICE=$(lsusb | grep 'Sound BlasterX G6' | awk '{print "/dev/bus/usb/" $2 "/" substr($4, 1, length($4)-1)}')
if [ -n "$DEVICE" ]; then
echo "Found device: $DEVICE" >> /tmp/reset_soundcard.log
/usr/local/bin/usbreset "$DEVICE" >> /tmp/reset_soundcard.log 2>&1
else
echo "Sound BlasterX G6 not found" >> /tmp/reset_soundcard.log
fi
Make it executable
chmod +x ~/bin/reset_soundcard.sh
Create autostart for the reset script
So that you don't have to replug the device after boot
nano ~/.config/autostart/reset_soundcard.desktop
I assume you will have to modify this if you're not using Gnome.
[Desktop Entry]
Type=Application
Exec=~/bin/reset_soundcard.sh
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name=Reset Sound BlasterX G6
Comment=Reseter lydkortet ved innlogging
Reboot to verify that it's working
reboot
Troubleshooting
You can use the logs generated to troubleshoot where it went wrong
You can also manually run the scripts where necessary.