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

Hi, I've tried for a few hours, and I am at a roadblock. What I am trying to do, is pipe raw pcm sound from /dev/dsp to oggenc, and save it to a scalar. In the code below, I can create an ogg file, or dump the binary data to stdout. But I can't seem to capture the stdout from oggenc. I tried IO::Tee and a few other things, but I can't seem to capture the data I see flying by on the screen.

Does anyone know if this type of capture is possible?

#!/usr/bin/perl use warnings; use strict; use Audio::DSP; $|++; my ($buf, $chan, $fmt, $rate) = (4096, 1, 16, 22050); my $dsp = new Audio::DSP(buffer => $buf, channels => $chan, format => $fmt, rate => $rate); $dsp->init() || die $dsp->errstr(); #this method dosn't work #close STDOUT; #my $ogg_out = ''; #open STDOUT, '>', \$ogg_out, or die "Couldn't redirect STDOUT to $ogg +_out: $!"; #this will dump the encoded ogg to STDOUT my $pid = open(OGGIN, "| oggenc -Q -r -R 22050 --resample 8000 -C 1 -q + 2 - ") or warn "No oggenc $!\n"; #this will dump it to a file #my $pid = open(OGGIN, "| oggenc -Q -r -R 22050 --resample #8000 -C 1 +-q 2 - | cat > $0.ogg ") # or warn "No oggenc $!\n"; while (my $buffer = $dsp->dread(4096) ) { syswrite( OGGIN, $buffer, length($buffer) ); } # of course, cntrl-c out of the while loop never lets this print # but I include it to show what I'm after #print $ogg_out;

I'm not really a human, but I play one on earth. flash japh

Replies are listed 'Best First'.
Re: capturing stdout from a piped open
by davidrw (Prior) on Aug 29, 2005 at 19:45 UTC
    From perldoc -f open:
    You are not allowed to "open" to a command that pipes both in and out, but see the IPC::Open2 man- page, the IPC::Open3 manpage, and the Bidirec- tional Communication with Another Process entry in the perlipc manpage for alternatives.
    Take a look at perldoc perlipc, IPC::Open2 and IPC::Open3 ..
Re: capturing stdout from a piped open
by Joost (Canon) on Aug 29, 2005 at 20:22 UTC
Re: capturing stdout from a piped open
by izut (Chaplain) on Aug 30, 2005 at 11:35 UTC
    This works:
    open *STDOUT, ">", $ogg_out or die $!; ... close *STDOUT;


    Igor S. Lopes - izut
    surrender to perl. your code, your rules.
      I get errors when I try it. When I do
      close STDOUT; my $ogg_out; open *STDOUT, ">", \$ogg_out or die $!;
      It starts to run, but quickly fails with
      Failed writing data to output stream Broken pipe

      I'm not really a human, but I play one on earth. flash japh
Re: capturing stdout from a piped open
by zentara (Cardinal) on Aug 30, 2005 at 10:27 UTC
    Thanks for the replies. I should have mentioned that oggenc will not work with IPC::Open3, and the piped open is the only thing that has given any output.

    My plan was to capture the encoded chunks and send it to a socket......to make a VOIP type of program. The temp file would work, but would introduce a delay in sending the audio. I need to send as it is being spoken, at least in 4k chunks.

    Maybe I need to capture the stdout file-descriptor of the piped-open?


    I'm not really a human, but I play one on earth. flash japh