树莓派上的麦阵列定位

最近又弄了个麦阵列玩定位……

1 安装ReSpeaker驱动

参考:ReSpeaker 6-Mic Circular Array kit for Raspberry Pi

手册上说换个源会快,那就换吧:

1
sudo vim /etc/apt/sources.list

手册上让用清华的镜像站:

1
2
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib

安装麦阵列驱动:

1
2
3
4
5
mkdir seeed
proxychains4 git clone https://github.com/respeaker/seeed-voicecard.git
cd seeed-voicecard
sudo proxychains4 ./install.sh
sudo reboot -h now

需要注意的是,在安装前不要运行sudo rpi-update升级固件,否则会因为固件版本问题导致无法安装。

2 录音及播放测试

查看声卡输入设备arecord -L,返回:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
null
Discard all samples (playback) or generate zero samples (capture)
default
ac108
dmixer
ac101
sysdefault:CARD=seeed8micvoicec
seeed-8mic-voicecard,
Default Audio Device
dmix:CARD=seeed8micvoicec,DEV=0
seeed-8mic-voicecard,
Direct sample mixing device
dsnoop:CARD=seeed8micvoicec,DEV=0
seeed-8mic-voicecard,
Direct sample snooping device
hw:CARD=seeed8micvoicec,DEV=0
seeed-8mic-voicecard,
Direct hardware device without any conversions
plughw:CARD=seeed8micvoicec,DEV=0
seeed-8mic-voicecard,
Hardware device with all software conversions

检查声卡输出设备aplay -L,返回:

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
null
Discard all samples (playback) or generate zero samples (capture)
default
ac108
dmixer
ac101
sysdefault:CARD=ALSA
bcm2835 ALSA, bcm2835 ALSA
Default Audio Device
dmix:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct sample mixing device
dmix:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct sample mixing device
dsnoop:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct sample snooping device
dsnoop:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct sample snooping device
hw:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Direct hardware device without any conversions
hw:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Direct hardware device without any conversions
plughw:CARD=ALSA,DEV=0
bcm2835 ALSA, bcm2835 ALSA
Hardware device with all software conversions
plughw:CARD=ALSA,DEV=1
bcm2835 ALSA, bcm2835 IEC958/HDMI
Hardware device with all software conversions
sysdefault:CARD=seeed8micvoicec
seeed-8mic-voicecard,
Default Audio Device
dmix:CARD=seeed8micvoicec,DEV=0
seeed-8mic-voicecard,
Direct sample mixing device
dsnoop:CARD=seeed8micvoicec,DEV=0
seeed-8mic-voicecard,
Direct sample snooping device
hw:CARD=seeed8micvoicec,DEV=0
seeed-8mic-voicecard,
Direct hardware device without any conversions
plughw:CARD=seeed8micvoicec,DEV=0
seeed-8mic-voicecard,
Hardware device with all software conversions

按照手册录制、播放音频文件,一切OK,还能边录边播~

1
2
3
4
5
6
7
8
9
10
11
12
#It will capture sound on AC108 and save as a.wav
arecord -Dac108 -f S32_LE -r 16000 -c 8 a.wav
#Take care of that the captured mic audio is on the first 6 channels

#It will play sound file a.wav on AC101
aplay -D ac101 a.wav
#Do not use -D plughw:1,0 directly except your wave file is single channel only.

#Doing capture && playback the same time
arecord -D hw:1,0 -f S32_LE -r 16000 -c 8 to_be_record.wav &
#mono_to_play.wav is a mono channel wave file to play
aplay -D plughw:1,0 -r 16000 to_be_record.wav

按照手册安装audacity,图形界面音频编辑软件,可以说是非常舒适了~

1
sudo apt-get install -y audacity

3 DOA定位测试

参考:ReSpeaker 6 Mic Array for Raspberry Pi

下载ODAS源码并编译:

1
2
3
4
5
6
sudo proxychains4 apt install -y libfftw3-dev libconfig-dev libasound2-dev cmake
proxychains4 git clone https://github.com/introlab/odas.git
mkdir odas/build
cd odas/build
cmake ..
make

安装完成后,编写麦阵列配置文件respeaker-6mic-odas.cfg

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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# Configuration file for ReSpeaker 6 Mic Array
# Circular shape, R = 0.0463m

version = "2.1";

# Raw
raw:
{
fS = 16000;
hopSize = 128;
nBits = 32;
nChannels = 8;

# Input with raw signal from microphones
interface: {
type = "soundcard";
card = 1;
device = 0;
}
}

# Mapping
mapping:
{
map: (1, 2, 3, 4, 5, 6);
}

# General
general:
{
epsilon = 1E-20;
size:
{
hopSize = 128;
frameSize = 256;
};
samplerate:
{
mu = 16000;
sigma2 = 0.01;
};
speedofsound:
{
mu = 343.0;
sigma2 = 25.0;
};
mics = (
# Microphone 1
{
mu = ( -0.0232, +0.0401, +0.0000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 90.0 );
},
# Microphone 6
{
mu = ( +0.0232, +0.0401, +0.0000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 90.0 );
},
# Microphone 5
{
mu = ( +0.0463, +0.0000, +0.0000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 90.0 );
},
# Microphone 4
{
mu = ( +0.0232, -0.0401, +0.0000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 90.0 );
},
# Microphone 3
{
mu = ( -0.0232, -0.0401, +0.0000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 90.0 );
},
# Microphone 2
{
mu = ( -0.0463, +0.0000, +0.0000 );
sigma2 = ( +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000, +0.000 );
direction = ( +0.000, +0.000, +1.000 );
angle = ( 80.0, 90.0 );
}
);

# Spatial filters to include only a range of direction if required
# (may be useful to remove false detections from the floor, or
# limit the space search to a restricted region)
spatialfilters = (
{
direction = ( +0.000, +0.000, +1.000 );
angle = (80.0, 90.0);
}
);
nThetas = 181;
gainMin = 0.25;
}

# Stationnary noise estimation
sne:
{
b = 3;
alphaS = 0.1;
L = 150;
delta = 3.0;
alphaD = 0.1;
}

# Sound Source Localization
ssl:
{
nPots = 4;
nMatches = 10;
probMin = 0.5;
nRefinedLevels = 1;
interpRate = 4;

# Number of scans: level is the resolution of the sphere
# and delta is the size of the maximum sliding window
# (delta = -1 means the size is automatically computed)
scans = (
{ level = 2; delta = -1; },
{ level = 4; delta = -1; }
);

# Output to export potential sources
potential: {
format = "json";
interface: {
type = "socket"; ip = "192.168.1.100"; port = 9001;
};
#format = "undefined";
#interface: {
# type = "blackhole";
#}
};
}

# Sound Source Tracking
sst:
{
# Mode is either "kalman" or "particle"
mode = "kalman";

# Add is either "static" or "dynamic"
add = "dynamic";

# Parameters used by both the Kalman and particle filter
active = (
{ weight = 1.0; mu = 0.3; sigma2 = 0.0025 }
);

inactive = (
{ weight = 1.0; mu = 0.15; sigma2 = 0.0025 }
);

sigmaR2_prob = 0.0025;
sigmaR2_active = 0.0225;
sigmaR2_target = 0.0025;
Pfalse = 0.1;
Pnew = 0.1;
Ptrack = 0.8;

theta_new = 0.9;
N_prob = 5;
theta_prob = 0.8;
N_inactive = ( 150, 200, 250, 250 );
theta_inactive = 0.9;

# Parameters used by the Kalman filter only
kalman: {
sigmaQ = 0.001;
};

# Parameters used by the particle filter only
particle: {
nParticles = 1000;
st_alpha = 2.0;
st_beta = 0.04;
st_ratio = 0.5;
ve_alpha = 0.05;
ve_beta = 0.2;
ve_ratio = 0.3;
ac_alpha = 0.5;
ac_beta = 0.2;
ac_ratio = 0.2;
Nmin = 0.7;
};

target: ();

# Output to export tracked sources
tracked: {
format = "json";
interface: {
type = "socket"; ip = "192.168.1.100"; port = 9000;
};
#format = "undefined";
#interface: {
# type = "blackhole";
#}
};
}

sss:
{
# Mode is either "dds", "dgss" or "dmvdr"
mode_sep = "dds";
mode_pf = "ms";

gain_sep = 1.0;
gain_pf = 10.0;

dds: {

};

dgss: {
mu = 0.01;
lambda = 0.5;
};

dmvdr: {

};

ms: {
alphaPmin = 0.07;
eta = 0.5;
alphaZ = 0.8;
thetaWin = 0.3;
alphaWin = 0.3;
maxAbsenceProb = 0.9;
Gmin = 0.01;
winSizeLocal = 3;
winSizeGlobal = 23;
winSizeFrame = 256;
};

ss: {
Gmin = 0.01;
Gmid = 0.9;
Gslope = 10.0;
};

separated: {
fS = 44100;
hopSize = 512;
nBits = 16;

interface: {
type = "file";
path = "separated.raw";
};
};

postfiltered: {
fS = 44100;
hopSize = 512;
nBits = 16;

interface: {
type = "file";
path = "postfiltered.raw";
};
};
}

classify:
{
frameSize = 1024;
winSize = 3;
tauMin = 32;
tauMax = 200;
deltaTauMax = 7;
alpha = 0.3;
gamma = 0.05;
phiMin = 0.15;
r0 = 0.2;

category: {
format = "undefined";

interface: {
type = "blackhole";
}
}
}

波达方向定位服务odaslives位于odas/bin/目录下,使用配置文件启动定位服务:

1
2
ln -s ~/odas/3rd-lib/odas/bin/odaslive ~/.local/bin/odaslive
odaslive -c ~/respeaker-6mic-odas.cfg

在电脑上下载ODAS Studio源码并编译:

1
2
3
4
5
6
sudo npm install npm@latest -g
wget https://github.com/introlab/odas_web/archive/v0.2-alpha.zip
unzip -a v0.2-alpha.zip
git clone https://github.com/introlab/odas_web.git
cd odas_web-0.2-alpha
npm install

在电脑上安装npm,并从源码编译odas web v0.2-alpha:

1
2
3
sudo npm install npm@latest -g
cd odas_web
npm install

或者使用已编译好的程序:

1
proxychains4 wget https://github.com/introlab/odas_web/releases/download/v0.1-alpha/MacOS_x64.tar.gz

ODA Studio Test

分享到