-
Notifications
You must be signed in to change notification settings - Fork 1
/
live_noise_filter.sh
executable file
·152 lines (129 loc) · 4.12 KB
/
live_noise_filter.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/bin/bash
which sox > /dev/null 2>&1 || (echo "SoX not found. Please install Sound eXchange to proceed." && exit)
time=5
workDir=$(mktemp -d)
noiseFile="noise.wav"
#record noise sample
record()
{
read -p "Recording background noise. Keep quiet for $time seconds. Press Enter to start."
sleep 0.5
parecord -d $input $noiseFile &
PID=$!
sleep $time
kill $PID
echo "Playing back noise sample"
paplay $noiseFile
}
quit()
{
cd -
rm -rf "$workdir"
sudo modprobe -r snd_aloop
exit
}
cd $workDir
trap quit SIGINT
#detect if aloop module is loaded
#allow the user to load the module here
if [ $(lsmod | grep -c snd_aloop) -eq 0 ]; then
echo "ALOOP module is not loaded."
read -p "Attempt to load the module?[y/n]" yn
case $yn in
[Yy]* ) sudo modprobe snd_aloop;;
[Nn]* ) exit;;
* ) echo "Please answer yes or no.";;
esac
fi
#get list of input and output devices (with details)
inputs=$(pactl list short sources | grep -E -v '(monitor|aloop)')
outputs=$(pactl list short sinks | grep aloop)
#abort if devices aren't available
if [ $(echo "$inputs" | wc -l) -lt 1 ]; then
echo "No input devices detected. Aborting"
exit
fi
if [ $(echo "$outputs" | wc -l) -lt 1 ]; then
echo "No output devices detected. Aborting"
exit
fi
inputIndex=0
#allow user selection when multiple devices are available
if [ $(echo "$inputs" | wc -l) -gt 1 ]; then
echo "Multiple input devices detected. Select from this list:"
echo "$inputs" | awk -F '\\s' '{print NR-1," ",$2}'
read -p "Enter an index:" inputIndex
exit
fi
inputs=$(echo "$inputs" | awk -v idx=$inputIndex '{if (NR-1 == idx) print}')
outputIndex=0
#allow user selection when multiple devices are available
if [ $(echo "$outputs" | wc -l) -gt 1 ]; then
echo "Multiple output devices detected. Select from this list:"
echo "$outputs" | awk -F '\\s' '{print NR-1," ",$2}'
read -p "Enter an index:" outputIndex
exit
fi
outputs=$(echo "$outputs" | awk -v idx=$outputIndex '{if (NR-1 == idx) print}')
#load device names
input=$(echo "$inputs" | awk -F '\\s' '{print $2}')
output=$(echo "$outputs" | awk -F '\\s' '{print $2}')
#get input device specs
format=$(echo "$inputs" | awk -F '\\s' '{print $4}')
#number type
tmp=$(echo $format | grep -o "^[fus]")
case $tmp in
f ) inputEncoding="floating-point";;
s ) inputEncoding="signed-integer";;
u ) inputEncoding="unsigned-integer";;
esac
#bit count
inputBits=$(echo $format | grep -o "[0-9]*")
#endianness
tmp=$(echo $format | grep -o "[bl]e$")
case $tmp in
be ) inputEndian="-B";;
le ) inputEndian="-L";;
esac
#channels
inputChannels=$(echo "$inputs" | awk -F '\\s' '{print $5}' | grep -o "[0-9]*")
#bitrate
inputBitrate=$(echo "$inputs" | awk -F '\\s' '{print $6}' | grep -o "[0-9]*")
#get output device specs
format=$(echo "$outputs" | awk -F '\\s' '{print $4}')
#number type
tmp=$(echo $format | grep -o "^[fus]")
case $tmp in
f ) outputEncoding="floating-point";;
s ) outputEncoding="signed-integer";;
u ) outputEncoding="unsigned-integer";;
esac
#bit count
outputBits=$(echo $format | grep -o "[0-9]*")
#endianness
tmp=$(echo $format | grep -o "[bl]e$")
case $tmp in
be ) outputEndian="-B";;
le ) outputEndian="-L";;
esac
#channels
outputChannels=$(echo "$outputs" | awk -F '\\s' '{print $5}' | grep -o "[0-9]*")
#bitrate
outputBitrate=$(echo "$outputs" | awk -F '\\s' '{print $6}' | grep -o "[0-9]*")
#record noise sample
record
while true; do
read -p "Do you wish to re-record the noise sample?[y/n]" yn
case $yn in
[Yy]* ) record;;
[Nn]* ) break;;
* ) echo "Please answer yes or no.";;
esac
done
#create noise profile
sox $noiseFile -n noiseprof noise.prof
echo "Sending output to loopback device."
echo "Change recording port to <Loopback Analog Stereo Monitor> in PulseAudio to apply."
echo "Ctrl+C to terminate."
#filter audio from $input to $output
pacat -r -d $input --latency=1msec | sox -b $inputBits -e $inputEncoding -c $inputChannels -r $inputBitrate $inputEndian -t raw - -b $outputBits -e $outputEncoding -c $outputChannels -r $outputBitrate $outputEndian -t raw - noisered noise.prof 0.2 | pacat -p -d $output --latency=1msec