in reply to Re^4: Measuring the sound level (dB(A)) with PERL
in thread Measuring the sound level (dB(A)) with PERL

Can you show me the output of the following code? It's a slightly modified version of your original code. According to you the else-branch should trigger if there's nothing to be read from /dev/dsp1.

#!/usr/bin/perl use strict; use warnings; # input device my $input = "/dev/dsp1"; # open filehandler open(my $fh, '<', $input) or die("ERROR open $input ($!)\n"); binmode($fh); while(1) { my $buffer; # read one byte read($fh, $buffer, 1); if(defined($buffer)) { # ignore } else { print "nothing to collect\n"; } } close($fh);

If the else-branch does indeed trigger then I wonder what's going on. From my understanding of Perl the if-condition is always true, even if there's nothing to be read.

#!/usr/bin/perl use strict; use warnings; open my $fh, '<', '/dev/null'; binmode($fh); my $buffer; # read one byte read($fh, $buffer, 1); if(defined $buffer) { print "read something\n"; } else { print "nothing to collect\n"; }

returns

read something

Which is a lie. According to read you're supposed to check the return value, modifiying the code accordingly

#!/usr/bin/perl use strict; use warnings; open my $fh, '<', '/dev/null'; binmode($fh); my $buffer; # read one byte my $r = read($fh, $buffer, 1); if($r > 0) { print "read something\n"; } else { print "nothing to collect\n"; } close($fh);

yields:

nothing to collect

Replies are listed 'Best First'.
Re^6: Measuring the sound level (dB(A)) with PERL
by John-Robie (Novice) on Nov 10, 2016 at 13:19 UTC

    your code included:

    [...] # read one byte read($fh, $buffer, 1); if(defined($buffer)) { # get an unsigned char my $v = unpack("C", $buffer); # sum the squared distance from the theoretical mean $sse += ($v-127.5)**2; $cnt++; } else { print "No byte here\n"; } [...]

    The ELSE condition does not show up a single time:

    OUTPUT: root@node:/srv/perl# ./dba2.pl dbFSrms: -20.9475641203622, dba: 89.0524358796378 dbFSrms: -21.662467195052, dba: 88.337532804948 dbFSrms: -21.5176778028847, dba: 88.4823221971153 dbFSrms: -24.4135001203418, dba: 85.5864998796582 dbFSrms: -23.0140885363105, dba: 86.9859114636895 dbFSrms: -18.5448040737999, dba: 91.4551959262001 dbFSrms: -21.636493545482, dba: 88.363506454518 dbFSrms: -20.3636900956917, dba: 89.6363099043083 dbFSrms: -21.3307953726968, dba: 88.6692046273032 dbFSrms: -22.1928440805489, dba: 87.8071559194511 [...]

    If there is nothing to read, the read command seems to for something to read.... this seems to be a special behavior of the read command on devices (at least on /dev/dsp1). If there is something to read it will do the calculation as 8000 values were reached (which is 8000 values per second == 8KHz...

      Ah. So the read() simply blocks until there actually is something to read and then continues.

      Which indicates you can either remove the if-condition completely (since it does nothing) -or- replace it with something that acts on the return value (in case there is an actual i/o error).

        That's correct!