Notes on audio capture trials using a BT878
Last modified Tuesday, 22-Jul-2008 18:00:53 UTC
I'm just jotting these notes down as I go along, so refresh from time to
time to get the latest progress...
Hardware
[root@sb ~]# cat /proc/cpuinfo
...
processor : 3
vendor_id : GenuineIntel
cpu family : 15
model : 4
model name : Intel(R) Xeon(TM) CPU 3.20GHz
stepping : 1
cpu MHz : 3193.937
cache size : 1024 KB
...
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge \
mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 \
ss ht tm pbe nx lm pni monitor ds_cpl cid xtpr
bogomips : 6373.37
Linux version
[root@sb ~]# cat /proc/version
Linux version 2.6.9-1.667smp (bhcompile@tweety.build.redhat.com) \
(gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)) \
#1 SMP Tue Nov 2 14:59:52 EST 2004
Card installed, unmodified
[root@sb rh]# lspci
...
06:00.0 Multimedia video controller: Brooktree Corporation Bt878 \
Video Capture (rev 02)
06:00.1 Multimedia controller: Brooktree Corporation Bt878 \
Audio Capture (rev 02)
[root@sb ~]# cd /proc/asound
[root@sb asound]# cat cards
0 [Bt878 ]: Bt87x - Brooktree Bt878
Brooktree Bt878 at 0xd0001000, irq 209
[root@sb asound]# ls card0
id oss_mixer pcm0c pcm1c
[root@sb asound]# cat card0/pcm0c/info
card: 0
device: 0
subdevice: 0
stream: CAPTURE
id: Bt87x Digital
name: Bt87x Digital
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 1
[root@sb asound]# cat card0/pcm1c/info
card: 0
device: 1
subdevice: 0
stream: CAPTURE
id: Bt87x Analog
name: Bt87x Analog
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 1
Modules - Linux has kindly figured out which modules to load - phew!
[root@sb ~]# lsmod | grep snd
snd_bt87x 16649 0
snd_pcm_oss 50809 0
snd_mixer_oss 20929 1 snd_pcm_oss
snd_pcm 89669 2 snd_bt87x,snd_pcm_oss
snd_timer 27077 1 snd_pcm
snd 54821 5 snd_bt87x,snd_pcm_oss,snd_mixer_oss,\
snd_pcm,snd_timer
soundcore 12961 1 snd
snd_page_alloc 13641 2 snd_bt87x,snd_pcm
Default mixer settings,
[root@sb ~]# amixer -c 0
Simple mixer control 'FM',0
Capabilities: cswitch cswitch-joined cswitch-exclusive
Capture exclusive group: 0
Capture channels: Mono
Mono: Capture [off]
Simple mixer control 'Mic/Line',0
Capabilities: cswitch cswitch-joined cswitch-exclusive
Capture exclusive group: 0
Capture channels: Mono
Mono: Capture [off]
Simple mixer control 'Capture',0
Capabilities: cvolume
Capture channels: Mono
Limits: Capture 0 - 15
Mono: Capture 0 [0%]
Simple mixer control 'Capture Boost',0
Capabilities: pswitch pswitch-joined
Playback channels: Mono
Mono: Playback [off]
Simple mixer control 'TV Tuner',0
Capabilities: cswitch cswitch-joined cswitch-exclusive
Capture exclusive group: 0
Capture channels: Mono
Mono: Capture [on]
Use amixer to turn the line input on, and bring up line and
capture gains:-
[root@sb ~]# amixer -c 0 sset 'Mic/Line',0 60% unmute cap
Simple mixer control 'Mic/Line',0
Capabilities: cswitch cswitch-joined cswitch-exclusive
Capture exclusive group: 0
Capture channels: Mono
Mono: Capture [on]
[root@sb ~]# amixer -c 0 sset 'Capture',0 15
Simple mixer control 'Capture',0
Capabilities: cvolume
Capture channels: Mono
Limits: Capture 0 - 15
Mono: Capture 15 [100%]
Quick trial using my rxr program
http://abelian.org/vlf/README.txt
Will use the 2nd device of the card, 'hw:0,1', which is the analogue
device.
[root@sb rh]# rxr -d 'hw:0,1' -r 32000 -rd 1
starting device hw:0,1
requested sample rate: 32000
rate min 119466 max 448000
BAILOUT: cannot set channel count (Invalid argument)
The sample rates are there! But rxr always tries to read the card
in stereo mode even when running just one channel - will have to alter that
to deal with this 'mono only' device.
Quick alteration to rxr, added a -cm 1 option to specify mono operation
of the soundcard, try again...
starting device hw:0,1
requested sample rate: 32000
rate min 119466 max 448000
actual sample rate: 119466
rawfile 20080722-075301_119466
rms 0.1392 0.0000 max 0.2356 0.0000
rms 0.1428 0.0000 max 0.2368 0.0000
rms 0.1427 0.0000 max 0.2283 0.0000
rms 0.1427 0.0000 max 0.2355 0.0000
rms 0.1427 0.0000 max 0.2349 0.0000
rms 0.1427 0.0000 max 0.2359 0.0000
rms 0.1428 0.0000 max 0.2378 0.0000
The above is with a 1.4kHz tone at 35mV RMS into the line
input. The driver has overriden my request for 32k sample
rate and applied its min rate of 119466. The 50mV peak signal
shows 0.238 of full scale, so the input will clip (with gain
set at 60%) at about 200mV peak.
Now with line input shorted,
rms 0.0098 0.0000 max 0.0320 0.0000
rms 0.0097 0.0000 max 0.0312 0.0000
rms 0.0095 0.0000 max 0.0194 0.0000
rms 0.0098 0.0000 max 0.0310 0.0000
S/N ratio of the 35mV 1.4kHz tone is therefore 20 * log10( 0.143/0.01)
which is about 23dB, not bad considering the RMS is taken over the
full bandwidth.
Sig gen reconnected, now at 55kHz, 35mV RMS,
rms 0.1173 0.0000 max 0.1992 0.0000
rms 0.1174 0.0000 max 0.2033 0.0000
rms 0.1174 0.0000 max 0.1976 0.0000
rms 0.1174 0.0000 max 0.1973 0.0000
rms 0.1174 0.0000 max 0.1932 0.0000
rms 0.1175 0.0000 max 0.2079 0.0000
Nice, only 20 * log10( 0.117/0.143) = -1.7dB at 55kHz compared
with 1.4kHz.
[root@sb ~]# top
top - 09:25:42 up 2:14, 3 users, load average: 0.05, 0.04, 0.00
Tasks: 79 total, 1 running, 78 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.3% us, 0.7% sy, 0.0% ni, 98.9% id, 0.1% wa, 0.0% hi, 0.0% si
Mem: 1033444k total, 1029652k used, 3792k free, 227604k buffers
Swap: 0k total, 0k used, 0k free, 511576k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2796 root 15 0 8556 5072 2628 S 2.0 0.5 0:45.87 rxr
4099 root 16 0 2388 944 1664 R 0.3 0.1 0:01.21 top
Fine, only 2% of a 3.2GHz cpu is occupied by rxr running at 119k/sec.
Now restarting rxr at the max soundcard rate, sig gen still at 55kHz, 35mV RMS:
[root@sb raw]# rxr -d 'hw:0,1' -cm 1 -r 448000 -rd 1
soundcard mode: mono
starting device hw:0,1
requested sample rate: 448000
rate min 119466 max 448000
actual sample rate: 448000
rawfile 20080722-082856_448000
rms 0.1385 0.0000 max 0.2200 0.0000
rms 0.1389 0.0000 max 0.2310 0.0000
rms 0.1389 0.0000 max 0.2279 0.0000
rms 0.1389 0.0000 max 0.2290 0.0000
And the CPU load at this sample rate is
[root@sb ~]# top
top - 09:33:46 up 2:22, 3 users, load average: 0.14, 0.13, 0.04
Tasks: 79 total, 1 running, 78 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2% us, 2.1% sy, 0.0% ni, 96.9% id, 0.8% wa, 0.0% hi, 0.0% si
Mem: 1033444k total, 551876k used, 481568k free, 196304k buffers
Swap: 0k total, 0k used, 0k free, 280796k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4869 root 16 0 7796 5068 2628 S 8.6 0.5 0:25.34 rxr
5141 root 16 0 1884 944 1664 R 0.7 0.1 0:00.02 top
Oh boy this thing eats disk space when recording raw,
[root@sb ~]# ls -l /raw
total 1020948
drwxr-xr-x 2 root root 4096 Jul 22 09:28 .
drwxr-xr-x 34 root root 4096 Jul 22 07:11 ..
-rw-r--r-- 1 root root 510550016 Jul 22 09:28 20080722-075301_119466.1
-rw-r--r-- 1 root root 533823488 Jul 22 09:38 20080722-082856_448000.1
-rw-r--r-- 1 root root 25853 Jul 22 09:38 20080722.log
Yikes, I've clocked up a Gbyte in about 30 mins of operation! Here's
a spectrum,
Wonder how many of those spikes are coming from the signal generator. I'll
add a second trace with the input terminated in a 50 ohm dummy load:-
Well, disconnecting the Thurlby Thandar has lowered the noise floor a
few dB. Nice and flat up to 200kHz by the looks of it.
rxr's log file reports two soundcard overruns in 1400 seconds of operation
at 448k/sec. Maybe the driver's buffer sizes need a bit of a tweak but I'll
live with it for now.
Okay let's connect a VLF receiver, bypassing the isolating transformer in
the shack,
rms 0.6589 0.0000 max 1.0000 0.0000
rms 0.8040 0.0000 max 1.0000 0.0000
rms 0.8025 0.0000 max 1.0000 0.0000
rms 0.7414 0.0000 max 1.0000 0.0000
rms 0.7856 0.0000 max 1.0000 0.0000
Hmm, clipping! Will have to tweak the line input gain ... had to put in
an attenuator and set the capture gain to 20%.
rms 0.1957 0.0000 max 0.8816 0.0000
rms 0.1979 0.0000 max 0.8444 0.0000
rms 0.1952 0.0000 max 0.8296 0.0000
rms 0.1929 0.0000 max 0.8276 0.0000
rms 0.1927 0.0000 max 0.8292 0.0000
rms 0.1923 0.0000 max 0.8280 0.0000
And here's the spectrum!
Obviously there's not much coming down the cable from the VLF receiver
above about 25kHz or so, the aggressive high-frequency roll-off built into
the receiver is doing its job - unfortunately! But we can see what looks
like the BBC at around 198kHz.
Is that MSF that we can see at 60kHz? Here's a close look at around 60kHz,
Either we're not getting anything from the antenna at 60kHz, or the BT878
sample rate is way off. Here are the alpha signals,
at 11910, 12650, and 14880. They seem pretty close.
Will adjourn and set up a suitable antenna to feed the BT878 directly.
We should at least get a good signal at 60kHz from MSF.
Why can't I see MSF? Mystery solved,
http://www.npl.co.uk/server.php?show=ConWebDoc.1001
"The annual 48 hour shutdown of the MSF service will take place over
the period 08:00 BST 22nd July 2008 to 08:00 BST 24th July"
So there, no MSF, what good timing!
I dragged an old loop antenna out of the shed and set that up in
the garden,
Coil is a couple of hundred metres of cheap speaker wire, frame is 1 metre
per side, 53mH, 30 ohms, and the coax back to the BT878 is 1.67nF. There
is no resonance because of the low (I guess 600 ohms?) input Z of the
line input. It's held up by tent pegs and string.
Here's the spectrum
Let's try DCF at 77.5 kHz
which reads 77.6kHz on this BT787, so +0.13% sample rate error.
How about HBG at 75kHz? Nothing shows when I plot that part of
the spectrum.
The BBC transmitter on 198kHz shows up very well,
The peak shows at 198.248 on the BT878, an error of +0.125%.
Here's the lower part of the band,
An immense spectrum of hum harmonics, worse than I expected, even though the
antenna is right next to the house. I wonder just how linear this card is.
From the signal generator test earlier, the 2nd and 3rd harmonics were about
30dB down, but TTI generator isn't any cleaner than that.
Here are the overall signal levels reported by rxr,
rms 0.0116 0.0000 max 0.0557 0.0000
rms 0.0118 0.0000 max 0.0650 0.0000
rms 0.0117 0.0000 max 0.0509 0.0000
rms 0.0120 0.0000 max 0.0594 0.0000
As you can see, we need about another 20dB of gain in order to make use
of the card's full dynamic range. This antenna needs to go down into
the field on a long coax, and a 30dB preamp will just do nicely to drive
a long cable.
There's a bunch of strong signals between 60khz and 70kHz, can anyone help
ID them?
A quick look at the source for the BT878 driver reveals that my version
doesn't have the CONFIG_SND_BT87X_OVERCLOCK option mentioned in
http://www.linuxhq.com/kernel/v2.6/11/Documentation/sound/alsa/Bt87x.txt
But no worries, inspecting the code, it is easy to see how the sample
rates are fiddled to go higher, ... from bt87x.c,
static ratnum_t analog_clock = {
.num = 1792000,
.den_min = 4,
.den_max = 15,
.den_step = 1
};
Obviously the thing uses a master clock at 1792 kHz and allowable divisors
are from 4 to 15, giving 448k to 119.466k. We just need to alter the '4' to
a '1' :)
But first I must download the entire kernel source - just so I can recompile
bt87x ... there we go:
[root@sb ~]# ls -l linux*
-rw-r--r-- 1 root root 45930201 Jul 22 15:48 linux-2.6.9.tar.gz
There we go, the entire linux kernel source in 46Mbytes - beat that M$ :)
Now, just unpack, copy in my current kernel config, and recompile just
the modules...
[root@sb ~]# tar xzf linux-2.6.9.tar.gz
[root@sb ~]# cd linux*
[root@sb linux-2.6.9]# cp /boot/config-2.6.9-1.667smp .config
[root@sb linux-2.6.9]# make modules
Well, that didn't work, there's a complaint when I insmod the freshly
built snd-bt87x, I guess I'll have to go get the *exact* kernel revision,
my fault for being lazy and trying shortcuts!
Ah, here we are, kernel-2.6.9-1.667.src.rpm from Red Hat...
[root@sb ~]# rpm -i ./kernel-2.6.9-1.667.src.rpm
[root@sb ~]# cd /usr/src/redhat/SPECS
[root@sb SPECS]# rpmbuild -bp --target=i686 kernel-2.6.spec
[root@sb SPECS]# cd /usr/src/redhat/BUILD/kernel-2.6.9
[root@sb kernel-2.6.9]# cp -rf linux-2.6.9 /root
[root@sb kernel-2.6.9]# cd /root/linux-2.6.9
[root@sb linux-2.6.9]# cp /boot/config-2.6.9-1.667smp .config
[root@sb linux-2.6.9]# make modules
[root@sb linux-2.6.9]# rmmod snd-bt87x
[root@sb linux-2.6.9]# insmod sound/pci/snd-bt87x.ko
Okay, the freshly built bt878 driver module is loaded, and after
re-issuing the 'amixer' commands, a quick check to make sure it
is working...
[root@sb ~]# rxr -d 'hw:0,1' -cm 1 -r 448000 -rd 1
soundcard mode: mono
starting device hw:0,1
requested sample rate: 448000
rate min 119466 max 448000
actual sample rate: 448000
rawfile 20080722-164643_448000
rms 0.0108 0.0000 max 0.0440 0.0000
rms 0.0110 0.0000 max 0.0483 0.0000
rms 0.0109 0.0000 max 0.0508 0.0000
Looks good. Now to change a 4 to a 2 in bt87x.c,
[root@sb ~]# cd linux-2.6.9
[root@sb linux-2.6.9]# vi sound/pci/bt87x.c
[root@sb linux-2.6.9]# make modules
[root@sb linux-2.6.9]# rmmod snd-bt87x
[root@sb linux-2.6.9]# insmod sound/pci/snd-bt87x.ko
And now the moment of truth, rxr should report now the
extended range of sample rates...
[root@sb ~]# rxr -d 'hw:0,1' -cm 1 -r 448000 -rd 1
soundcard mode: mono
starting device hw:0,1
requested sample rate: 448000
rate min 119466 max 448000
actual sample rate: 448000
rawfile 20080722-165332_448000
Darn, it doesn't. Hmm, better take a closer look at the
driver source ... ah, there's another line that needs altering:-
static snd_pcm_hardware_t snd_bt87x_analog_hw = {
.info = SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID,
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8,
.rates = SNDRV_PCM_RATE_KNOT,
.rate_min = 119466,
.rate_max = 448000,
.channels_min = 1,
.channels_max = 1,
.buffer_bytes_max = 255 * 4092,
.period_bytes_min = 32,
.period_bytes_max = 4092,
.periods_min = 2,
.periods_max = 255,
};
A quick edit of .rate_max to 896000 and another make modules... and a
reload of the driver...
[root@sb ~]# rxr -d 'hw:0,1' -cm 1 -r 448000 -rd 1
soundcard mode: mono
starting device hw:0,1
requested sample rate: 448000
rate min 119466 max 896000
actual sample rate: 448000
rawfile 20080722-165758_448000
rms 0.0226 0.0000 max 0.0425 0.0000
rms 0.0112 0.0000 max 0.0594 0.0000
rms 0.0113 0.0000 max 0.0613 0.0000
That's better, it's showing the new high rate. Now we'll get rxr to
try it...
[root@sb ~]# rxr -d 'hw:0,1' -cm 1 -r 896000 -rd 1
soundcard mode: mono
starting device hw:0,1
requested sample rate: 896000
rate min 119466 max 896000
actual sample rate: 896000
rawfile 20080722-165941_896000
rms 0.0024 0.0000 max 0.0208 0.0000
rms 0.0008 0.0000 max 0.0031 0.0000
rms 0.0008 0.0000 max 0.0040 0.0000
rms 0.0008 0.0000 max 0.0669 0.0000
rms 0.0008 0.0000 max 0.0075 0.0000
rms 0.0008 0.0000 max 0.0036 0.0000
Well, it took the command, but what's happened to the signal? The RMS
has dropped to a background level. I don't think we'll get a spectrum
out of that. Oh,....
Well, we got something, but we've lost about 20dB or thereabouts overall.
Let's try the divisor 3,
[root@sb ~]# rxr -d 'hw:0,1' -cm 1 -r 597333 -rd 1
soundcard mode: mono
starting device hw:0,1
requested sample rate: 597333
rate min 119466 max 896000
actual sample rate: 597333
rawfile 20080722-170532_597333
rms 0.0026 0.0000 max 0.0107 0.0000
rms 0.0041 0.0000 max 0.0172 0.0000
rms 0.0041 0.0000 max 0.0332 0.0000
rms 0.0041 0.0000 max 0.0169 0.0000
rms 0.0042 0.0000 max 0.4163 0.0000
rms 0.0040 0.0000 max 0.0465 0.0000
rms 0.0040 0.0000 max 0.0208 0.0000
Well we've got a bit more signal now, and the spectrum is
Well, it's running, but the RMS is down about a factor of 3 or more
below the level when clocking at 448k. I guess the sound card's input
filter is not designed for it. Still, there may be a useful S/N ratio
up above 224k. Have to break off this now and contemplate making
a preamp/line driver so we can get a decent VLF level into the card.
Then we'll see how it looks.
Wait, I'll just do one more run with the dummy load attached, at the
full rate...
[root@sb ~]# rxr -d 'hw:0,1' -cm 1 -r 896000 -rd 1
soundcard mode: mono
starting device hw:0,1
requested sample rate: 896000
rate min 119466 max 896000
actual sample rate: 896000
rawfile 20080722-172158_896000
rms 0.0014 0.0000 max 0.0067 0.0000
rms 0.0007 0.0000 max 0.0025 0.0000
rms 0.0007 0.0000 max 0.0025 0.0000
rms 0.0007 0.0000 max 0.0020 0.0000
rms 0.0007 0.0000 max 0.0022 0.0000
which gives the graph, combined with the earlier run at 896k,
Some funny little resonances at 275kHz and 377kHz, sharper with
a 50 ohm load than with the antenna connected. Crikey do we have
to worry about getting an impedance match into the line input in
order to get a flat response above 224kHz?
Hey - and I didn't crash or have to reboot the PC at all :)