John-Robie has asked for the wisdom of the Perl Monks concerning the following question:
Hi, I’m trying to use a normal microphone connected to a Raspberry Pi in order the measure the sound level in dB(A). The idea is, to have simple PERL program measuring the loudness (e.g. Airplanes, Traffic…). I’m aware, that simple microphones do not have the quality to do this precisely, but for my goal the figures will be sufficient… so please no philosophic discussion about mics…
The code will just get some very small variation of decibel numbers, even if I scream into the microphone – so I think I am measuring something else than sound pressure or the conversion formula is wrong.
For this test, I bought a simple microphone from a local retailer and connected it to the USB Port of the Pi. The operating system is the “2016-09-23-raspbian-jessie” image, all PERL modules have been installed with cpanminus, and do not show any errors
The microphone shows up in the dmesg as follows:
[11249.256922] usb 1-1.4: new full-speed USB device number 10 using dw +c_otg [11249.365032] usb 1-1.4: New USB device found, idVendor=0d8c, idProdu +ct=0139 [11249.365094] usb 1-1.4: New USB device strings: Mfr=1, Product=2, Se +rialNumber=0 [11249.365113] usb 1-1.4: Product: USB PnP Sound Device [11249.365130] usb 1-1.4: Manufacturer: C-Media Electronics Inc. [11249.400778] input: C-Media Electronics Inc. USB PnP Sound Dev +ice as /devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.3/00 +03:0D8C:0139.0007/input/input6 [11249.457789] hid-generic 0003:0D8C:0139.0007: input,hidraw3: USB HID + v1.00 Device [C-Media Electronics Inc. USB PnP Sound Device] o +n usb-3f980000.usb-1.4/input3
As the microphone shows up at other Linux OS as well (e.g. CentOS), I do not expect any driver issues. The mic works for normal recording as well (
The module for the sound driver as been installed with
Linux OS CLI Command “modprobe snd_pcm_oss”, this installs a device /dev/dsp1 on the filesystem
This is the code I tried, there are some examples on the internet with this…
#!/usr/bin/perl use strict; use warnings; use POSIX qw(log10); # input device my $input="/dev/dsp1"; # open filehandler open(my $fh, '<', $input) or die("ERROR open $input ($!)\n"); binmode($fh); # 8 bit # 8000 hertz my $cnt = 0; my $value = 0; my $lastts = 0; while(1) { if ($cnt == 8000) { # the amplitude >= 0 <= 1 my $amplitude=$value / $cnt / 255; # calculate dba = 20 * log10(amplitude / 2 * 10**-5) my $dba = 20 * log10($amplitude / 0.00002); print "Calculated dB(A): $dba\n"; $cnt = 0; $value = 0; } my $buffer; # read one byte read($fh, $buffer, 1); if(defined($buffer)) { # get an unsigned char my $v = unpack("C", $buffer); # add the read byte to the values $value+=$v; # print "Byte read: $v\n"; $cnt++; } } close($fh);
The results shown yet show very similar values, even if I shout in the mic, The values show up every second as follows:
root@node:/srv/perl# ./dba.pl Calculated dB(A): 87.9548395267721 Calculated dB(A): 87.9599922725626 Calculated dB(A): 87.9595239674196 Calculated dB(A): 87.9586213444603 Calculated dB(A): 87.9595239674196
As byte values I can see 127 and 28 way to often – there should be more variance
I am stuck- can anyone help?
|
---|