Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all - I'm trying to read a wav file into a buffer but for some reason I could only read a specific wav file size. For example, I have a wav (no.wav) that's 16K that can get read but any other file that I have that's greater then 16K won't get read. Here is my code:
#!/usr/bin/perl use IO::Socket; use FileHandle; use IPC::Open2; $file = $ARGV[0]; open (FH, $file) || return undef; $fh = *FH; $file =~ /(gsm|wav)$/; my $type = $1; if ($type !~ /gsm|wav/) { warn "Unknown file type ($file)"; return undef; } print "FTYPE: $type\n"; #sox yellowaudio.wav -r 16000 -c 1 -s -w yellowaudio16k.raw $pid = open2(*SOXIN, *SOXOUT, "sox -t $type - -s -r 8000 -w -t wav - 2 +>/dev/null") || warn ("Could not open2.\n"); binmode $fh; binmode SOXIN; binmode SOXOUT; binmode $remote; print "hello\n"; while (defined(my $b = read $fh, my($buf), 4096)) { print "b = $b\n"; last if $b == 0; $count += $b; print SOXOUT $buf; print "count = $count\n"; } close SOXOUT;
I don't know why it can't read any wav file size greater then 16K. I think it might have to do with my cpu buffer size but when I run top this is what I have:
top - 17:43:41 up 2:31, 4 users, load average: 0.00, 0.02, 0.06 Tasks: 71 total, 1 running, 70 sleeping, 0 stopped, 0 zombie Cpu(s): 3.5% us, 2.1% sy, 3.3% ni, 86.1% id, 5.0% wa, 0.0% hi, 0 +.0% si Mem: 515584k total, 399400k used, 116184k free, 27072k buffe +rs Swap: 779144k total, 148k used, 778996k free, 298108k cache +d
The buffer looks fine, so I don't know what can be wrong. Any help will be greatly appreciated. Thanks.

Replies are listed 'Best First'.
Re: I need some help with open2
by Joost (Canon) on Dec 21, 2007 at 23:32 UTC
    Why and what are you printing to SOXOUT? IOW why are you printing anything to SOXOUT and extrapolating from that why are you using open2 at all?

    Removing the print SOXOUT $buf; line seems to fix the issue as far as I'm able to reproduce it.

    As far as I can see it looks like you're misunderstanding the sox interface.

    ..

      This is just an example code. This is part of a bigger project. I just wanted to make things a little more simple so I just took out the problem area and posted it here. When i run this code it does not work with any file greater then 16K, I don't know why. I think it may have to do something with buffers but I tried using syswrite and sysread but it doesn't help.

        If sox is sending you data and you're not reading it, the pipe will fill up and sox will block trying to print to the pipe.

        One bug: You never call waitpid to cleanup the zombie child process.

        Another bug: You pass user-provided text the shell without (usefully) validating it and without escaping it.
        "sox -t $type - -s -r 8000 -w -t wav - 2>/dev/null"
        should be
        "sox -t \Q$type\E - -s -r 8000 -w -t wav - 2>/dev/null"

        You should probably flush your pipe after writing to it (or turn on autoflushing on it).

        Update: I had the sox and the parent program mixed up. Fixed.

Re: I need some help with open2
by Joost (Canon) on Dec 22, 2007 at 01:16 UTC