Unbuffered I/O problem

Discussion in 'Perl Misc' started by Dave Saville, Mar 23, 2014.

  1. Dave Saville

    Dave Saville Guest

    I am playing with sending audio to stereo speakers as part of a bigger
    project. At the moment I am just generating a sine wave that moves
    from left to right.

    I pipe the data to pacat a sample at a time.

    open my $PACAT, '|pacat ...................

    while(1)
    {
    # generate $stuff - This is the angle sample value
    print $PACAT $stuff; #
    }

    This works but is a little jerky. Wondering if it were a buffering
    problem I tried to make it unbuffered.

    open my $PACAT, '|pacat ...................
    my $old_fh = select $PACAT; $| = 1; select $old_fh;

    while (1)
    {
    # generate $stuff
    print $PACAT $stuff;
    }

    And it just sits there doing nothing - I assume something has blocked.

    --
    Regards
    Dave Saville
     
    Dave Saville, Mar 23, 2014
    #1
    1. Advertising

  2. "Dave Saville" <> writes:
    > I am playing with sending audio to stereo speakers as part of a bigger
    > project. At the moment I am just generating a sine wave that moves
    > from left to right.
    >
    > I pipe the data to pacat a sample at a time.
    >
    > open my $PACAT, '|pacat ...................
    >
    > while(1)
    > {
    > # generate $stuff - This is the angle sample value
    > print $PACAT $stuff; #
    > }
    >
    > This works but is a little jerky. Wondering if it were a buffering
    > problem I tried to make it unbuffered.
    >
    > open my $PACAT, '|pacat ...................
    > my $old_fh = select $PACAT; $| = 1; select $old_fh;


    This doesn't "make it unbuffered", it forces the buffer to be flushed
    after every output operation. Considering that you're dealing with a
    soft realtime problem, you shouldn't be using the implicit buffering
    layer to begin with, but syswrite.
     
    Rainer Weikusat, Mar 23, 2014
    #2
    1. Advertising

  3. Rainer Weikusat <> writes:
    > "Dave Saville" <> writes:
    >> I am playing with sending audio to stereo speakers as part of a bigger
    >> project. At the moment I am just generating a sine wave that moves
    >> from left to right.
    >>
    >> I pipe the data to pacat a sample at a time.
    >>
    >> open my $PACAT, '|pacat ...................
    >>
    >> while(1)
    >> {
    >> # generate $stuff - This is the angle sample value
    >> print $PACAT $stuff; #
    >> }
    >>
    >> This works but is a little jerky. Wondering if it were a buffering
    >> problem I tried to make it unbuffered.
    >>
    >> open my $PACAT, '|pacat ...................
    >> my $old_fh = select $PACAT; $| = 1; select $old_fh;

    >
    > This doesn't "make it unbuffered", it forces the buffer to be flushed
    > after every output operation. Considering that you're dealing with a
    > soft realtime problem, you shouldn't be using the implicit buffering
    > layer to begin with, but syswrite.


    Expanding a little on that (I'm ignoring the 'STREAMS for perl' features
    of PerlIO): The whole point of 'stdio-style, implicit buffering' is to
    delay actual output until a 'large' amount of output data has been
    accumulated in order to increase throughput/ decrease system resource
    usage by decreasing the number of system calls necessary to perform the
    actual output. This is already of somewhat dubious value in Perl because
    Perl-code usually doesn't do 'I/O processing' in 'really small chunks'
    aka 'char-by-char/ byte-by-byte' (I also suspect that the overhead of
    calling a Perl subroutine is higher than that of a system call) but it
    is (at best) totally useless for audio output: This implies that audio
    data has to become available at a fixed bit rate/ byte rate. When the
    next chunk of it is due, it must not be delayed and 'increasing
    throughput' is useless because sending data faster than required only
    means something else has to use an internal buffer in order to cope with
    that (this is somewhat simplified).

    Something similar is true for many other IPC scenarios which are not
    supposed to do batch processing of data. And trying to work around that
    by 'enabling autoflush' is just totally bizarre: It basically means "Oh
    well, the implicit buffering is really harmful in my case, so I'll
    always flush the buffer immediately after a totally redundant block
    memory copy of my input data was made" --- but if the buffering isn'y
    useful, why copy data from application buffer a to 'middleware buffer' b
    to begin with?
     
    Rainer Weikusat, Mar 23, 2014
    #3
  4. Dave Saville

    gamo Guest

    El 23/03/14 16:42, Dave Saville escribió:
    > open my $PACAT, '|pacat ...................
    > my $old_fh = select $PACAT; $| = 1; select $old_fh;
    >


    That could be wrong because, according to the documentation, $|=1
    affects to the currently selected I/O, and you do a select after that.

    $| If set to nonzero, forces a flush right away and after
    every write or print on the currently selected output channel.

    Check that, moving the $|=1 to after the relevant last select.

    Good luck.

    > while (1)
    > {
    > # generate $stuff
    > print $PACAT $stuff;
    > }
    >
    > And it just sits there doing nothing - I assume something has blocked.
    >



    --
    http://www.telecable.es/personales/gamo/
     
    gamo, Mar 26, 2014
    #4
  5. gamo <> writes:
    > El 23/03/14 16:42, Dave Saville escribió:
    >> open my $PACAT, '|pacat ...................
    >> my $old_fh = select $PACAT; $| = 1; select $old_fh;
    >>

    >
    > That could be wrong because, according to the documentation, $|=1
    > affects to the currently selected I/O, and you do a select after that.
    >
    > $| If set to nonzero, forces a flush right away and after
    > every write or print on the currently selected output channel.


    perldoc -f select contains this exact example:

    FILEHANDLE may be an expression whose value gives the name of
    the actual filehandle. Thus:

    $oldfh = select(STDERR); $| = 1; select($oldfh);

    See also select((select(s),$|=1)[0]),

    http://stackoverflow.com/questions/196754/what-does-selectselects-10-do-in-perl
     
    Rainer Weikusat, Mar 26, 2014
    #5
  6. On 03/23/14 08:42, Dave Saville wrote:
    > I am playing with sending audio to stereo speakers as part of a bigger
    > project. At the moment I am just generating a sine wave that moves
    > from left to right.
    >
    > I pipe the data to pacat a sample at a time.
    >
    > open my $PACAT, '|pacat ...................
    >
    > while(1)
    > {
    > # generate $stuff - This is the angle sample value
    > print $PACAT $stuff; #
    > }
    >
    > This works but is a little jerky. Wondering if it were a buffering
    > problem I tried to make it unbuffered.
    >
    > open my $PACAT, '|pacat ...................
    > my $old_fh = select $PACAT; $| = 1; select $old_fh;
    >
    > while (1)
    > {
    > # generate $stuff
    > print $PACAT $stuff;
    > }
    >
    > And it just sits there doing nothing - I assume something has blocked.
    >


    Please post code that compiles and does something.

    I'm willing you help you with perl, less willing to do extensive
    speculation about what the "...." and "# generate $stuff" might be
    concealing.

    In any case, it works for me if I remove the ..., balance the quotes,
    and just set my $stuff=random();

    Xho
     
    Xho Jingleheimerschmidt, Mar 27, 2014
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Starbase Commander

    Unbuffered keyboard input???

    Starbase Commander, Sep 10, 2004, in forum: Perl
    Replies:
    1
    Views:
    714
    Jürgen Exner
    Sep 11, 2004
  2. Rich

    unbuffered output file

    Rich, Apr 15, 2004, in forum: C++
    Replies:
    5
    Views:
    2,674
    David Harmon
    Apr 16, 2004
  3. Guest
    Replies:
    0
    Views:
    406
    Guest
    Aug 28, 2004
  4. Guest
    Replies:
    1
    Views:
    569
    Jonathan Turkanis
    Aug 29, 2004
  5. michael young

    unbuffered input

    michael young, Feb 5, 2004, in forum: Python
    Replies:
    1
    Views:
    409
    Diez B. Roggisch
    Feb 5, 2004
Loading...

Share This Page