Lisp HUG Maillist Archive

Reading Binary Data from Pipe Streams

Hi guys,

it appears to me that it is not possible to read binary data from pipes in  
LIspworks on Windows, but maybe I am wrong. The way I am trying to do it  
at the moment is this:

(defun test (command)
   (with-open-stream (s (sys:open-pipe command
                        :direction :input :element-type '(signed-byte 32)))
     (let ((out (make-array 44100 :element-type '(signed-byte 32))))
       (loop for pos from 0
             for byte = (read-byte s nil #\Null)
             while byte do (setf (aref out pos) byte))
       out)))

What is happening there is very simple: I am trying to request one second  
of audio data from a console application in 32 signed format and write it  
to an array for further manipulation. Of course it is possible to do it by  
requesting the utility to write an intermediate file but I think that a  
pipe approach is a bit cleaner.

What  is happening at the moment, I get an error "Error:  
STREAM:STREAM-READ-BYTE is not implemented for this stream type:  
#<WIN32::PROCESS-PIPE-STREAM 21F424E3>" Now, I am using a random  
termination character #\Null for read-byte because I do not know better at  
the moment.

read-sequence does not seem to work either.

Any input would be greatly appreciated,

		Yuri

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: Reading Binary Data from Pipe Streams

"Yuri Davidovsky" <yury.davidouski2@mail.dcu.ie> writes:

> Hi guys,
>
> it appears to me that it is not possible to read binary data from
> pipes in LIspworks on Windows, but maybe I am wrong. The way I am
> trying to do it at the moment is this:
>
> (defun test (command)
>   (with-open-stream (s (sys:open-pipe command
>                        :direction :input :element-type '(signed-byte 32)))
>     (let ((out (make-array 44100 :element-type '(signed-byte 32))))
>       (loop for pos from 0
>             for byte = (read-byte s nil #\Null)
>             while byte do (setf (aref out pos) byte))
>       out)))
>
> What is happening there is very simple: I am trying to request one
> second of audio data from a console application in 32 signed format
> and write it to an array for further manipulation. Of course it is
> possible to do it by requesting the utility to write an intermediate
> file but I think that a pipe approach is a bit cleaner.
>
> What  is happening at the moment, I get an error "Error:
> STREAM:STREAM-READ-BYTE is not implemented for this stream type:
> #<WIN32::PROCESS-PIPE-STREAM 21F424E3>" Now, I am using a random
> termination character #\Null for read-byte because I do not know
> better at the moment.
>
> read-sequence does not seem to work either.
>
> Any input would be greatly appreciated,


Using anything but (unsigned-byte 8) may require a file format including
a descriptive header.  It would be difficult to establish a file header
on a pipe.

So you should rather use (unsigned-byte 8) as element-type and decompose
and combine bytes for transmission. (cf. ldb and dpb, with byte).

Notice by the way that you've not specified an :external-format to
open-pipe, therefore you didn't specify any bytesex for your 32-bit
values.   Do you know what byte-sex would be used when reading (from
files) (signed-byet 32)?   I'm not saying that it's possible to give an
:external-format  specifying the byte-sex (check the documentation).
But this is something that you should explicitely manage one way or
another.  Reading (unsigned-byte 8) bytes, you will explicitely
recompose big-endian or little-endian words to make your (signed-byte
32) values.



Now, the object to be returned by read-byte (or read) upon end-of-file
can by of any type, so you can indeed give a character such as #\Null
(and get it back into byte) when end-of-file occurs, but #\Null is true,
so it won't stop the loop, and it will break while trying to store this
character into the output vector of (signed-byte 32).  You seem to be
wanting to get nil instead, so pass that instead of #\Null to read-byte.





-- 
__Pascal Bourguignon__
http://www.informatimago.com/

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Updated at: 2020-12-10 08:35 UTC