Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: Audio Stream Buffer

by Zaxo (Archbishop)
on Jul 01, 2004 at 01:36 UTC ( #370954=note: print w/ replies, xml ) Need Help??


in reply to Audio Stream Buffer

I think that you will get better results from four-arg select or the higher level IO::Select.

The select loop would allow several input packets to accumulate (with the .= operator) while a stalled write to *AUDIO_OUT is cooking. Once the delay in output is resolved, you'd have all the received data to pass along.

That will be most effective if you have an intermediate child process which can quickly read and buffer what you write to it and handle writes to the audio player in its own good time.

Update: Here's a fairly dumb example of a select loop. It reads from STDIN and writes to a child of open.

#!/usr/bin/perl open my $ofh, '-|', '/usr/bin/perl', 'lazyread.pl' or die $!; my ($inv, $ouv, $erv); $inv = $ouv = $erv = ''; vec($inv, fileno(*STDIN), 1) = 1; vec($ouv, fileno($fh), 1) = 1; $erv = $inv | $ouv; my $string = ''; { my $num = select my $in = $inv, my $out = $ouv, my $err = $erv, undef; sysread *STDIN, $string, -1, 10, length($string) or last if $in ne $inv; $string = substr($string, syswrite( $ofh, $string, length($string) +)) if $string && $out ne $ouv; redo; } __END__ #!/usr/bin/perl # lazyread.pl open my $fh, '>', 'lazy' or die $!; while (<>) { print $fh $_; sleep 5; }
Sorry I couldn't write closer to the problem, but my setup doesn't have alsasound installed.

reds, your fork example looks pretty good, but I think I see the problem. The child process will be unable to see changes the parent makes in its copy of $buffer. You'd need to set up IPC between the two, like a pipe or socket, to pass data.

After Compline,
Zaxo


Comment on Re: Audio Stream Buffer
Download Code
Re^2: Audio Stream Buffer
by tachyon (Chancellor) on Jul 01, 2004 at 02:17 UTC

    Could you show me your suggested select loop please? I am still trying to get my head properly around select.

    cheers

    tachyon

Re^2: Audio Stream Buffer
by reds (Novice) on Jul 01, 2004 at 03:57 UTC

    I, too, am a little fuzzy on how the select loop system works. Select just chooses the current FH, so how can I use that to buffer the input stream?

    Also, once I have my stream buffered, could you or someone please provide a small bit of sample code for how to set up a child process? To date, my strength has been processing text files - not fancy pants networking or multiple threads!

    I just tried the code below, but am beginning to understand that because the reading takes more time than it does to play 512 bytes worth of data, I get the interrupted playback. In fact, this code has also somehow corrupted the audio stream so that it plays a tone of some sort, rather like cartoon car horn sound. Learning how to set up a child process to smoothly feed aplay would really help me out!

    # build up a buffer sysread(CLIENT, $read_buffer, 2048); syswrite(AUDIO_OUT, $read_buffer); # with buffer established, stream as usual while ( sysread(CLIENT, $read_buffer, 512) ) { $buffer .= $read_buffer; syswrite( AUDIO_OUT, $buffer, 512);

    Thanks for your help so far. Cheers!

    --------------------------

    Some while later:

    I've been reading and learned that threads are different from child processes. It would seem as if a thread would serve me best, since I don't want copies of all the filehandles and stuff. Is this correct? The code I have doesn't seem to execute the child code...

    my $child_pid; if ( not defined($child_pid = fork()) ) { die "cannot fork: $!"; } elsif ($child_pid) { # I'm the parent # keep reading the stream while ( sysread(CLIENT, $read_buffer, 512) ) { $buffer .= $read_buffer; print "."; } } else { # I'm the child # with buffer established, stream as usual while ( $buffer ) { syswrite( AUDIO_OUT, $buffer, 512); print "-"; } exit; } waitpid($child_pid, 0);

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://370954]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2014-10-26 02:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (149 votes), past polls