[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
sending data to an asynchronous process
From: |
Nicolas Graner |
Subject: |
sending data to an asynchronous process |
Date: |
Fri, 02 Apr 2021 12:20:26 +0200 |
I am writing a program that creates audio samples in an emacs
buffer, then sends them to an external program (sox) to play in
the background while I continue working with emacs. Part of the
code is roughly as follows:
(setq process
(let ((process-connection-type nil))
(start-process "my-process" nil
"sox" "-r" rate "-c" channels "-b" bits "-e" encoding
"-q" "-d")))
(process-send-region process start end)
(process-send-eof process)
The sound plays as expected, but process-send-region does not
return until about half a second before the sound finishes
playing. This means that if I send several minutes of audio,
emacs is stuck during all that time, which completely defeats the
purpose of an asynchronous process. Using process-send-string
instead of process-send-region makes no difference.
I suppose it has to do with buffering on the pipe, bit I don't
know if I have any control over this. I tried to use stdbuf, as in:
(start-process "my-process" nil "stdbuf" "-i10M" "-o10M" "sox" ...
which makes no difference.
One possible approach would be to send the data in small chunks,
arranging for some sort of sentinel to be called when a chunk has
been consumed, to send the nex one. Is there any way to do this?
I could also write the data into a temporary file and let sox
read from it but that seems pretty inefficient and would require
careful cleanup to not clutter the disk.
The solution I found is to use a synchronous process:
(call-process-region start end "sox" nil 0 nil ...
where the fifth argument 0 means to discard process output and
not wait for completion. This works and does essentially what I
want, except that I don't know the PID of the spawned process so
I cannot communicate with it, e.g. to stop it before the end or
determine whether it's still runnin or not.
I'd appreciate any insights and/or solutions?
FYI, running emacs 28.0.50 on debian 5.5.
Thanks,
Nicolas