unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Nicolas Graner <nicolas@graner.name>
To: help-gnu-emacs@gnu.org
Subject: sending data to an asynchronous process
Date: Fri, 02 Apr 2021 12:20:26 +0200	[thread overview]
Message-ID: <86v995t2c5.fsf@graner.name> (raw)

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



             reply	other threads:[~2021-04-02 10:20 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-02 10:20 Nicolas Graner [this message]
2021-04-02 16:13 ` sending data to an asynchronous process Jean Louis
2021-04-02 17:18 ` Jean Louis
2021-04-02 18:35   ` Nicolas Graner
2021-04-02 18:54     ` Jean Louis
2021-04-02 19:10       ` Jean Louis
2021-04-02 19:15 ` Eli Zaretskii
2021-04-02 23:03   ` Nicolas Graner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=86v995t2c5.fsf@graner.name \
    --to=nicolas@graner.name \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).