ideasman42 / nerd-dictation

Simple, hackable offline speech to text - using the VOSK-API.
GNU General Public License v3.0
1.3k stars 107 forks source link

Fix writing text immediately with --output STDOUT when --continuous is also enabled #53

Open tpoindex opened 2 years ago

tpoindex commented 2 years ago

Seems to me that --output STDOUT and --continuous should not defer writing text, this patch fixes that case.

This allows stdout text to go to a pipe or named pipe immediately. Backspaces are also passed, when the text is corrected by Vosk.

Here's a simple example of using a named pipe:

mkfifo /tmp/nerdpipe
nerd-dictation begin --output STDOUT --continuous >/tmp/nerdpipe

In another terminal:

while true; do 
    read -n 1000 -t 0.5 input </tmp/nerdpipe
    [[ -n "$input" ]] && echo "nerdpipe says: $input" 
done

Demo results:

nerdpipe says: hello
nerdpipe says: world
nerdpipe says: this
nerdpipe says: is a
nerdpipe says: longer sentence
nerdpipe says: goodbye

I included a flush() on the existing handler, but I also had another version that checked for this condition and only then use flush(). Flushing stdout on every write shouldn't cause much harm, since we can only speak so fast :-)

diff --git a/nerd-dictation b/nerd-dictation
index 1d6b626..77e51d4 100755
--- a/nerd-dictation
+++ b/nerd-dictation
@@ -1055,6 +1055,15 @@ def main_begin(
                 run_xdotool("key", ["BackSpace"] * delete_prev_chars)
             run_xdotool("type", ["--", text])

+    elif output == "STDOUT" and progressive:
+
+        def handle_fn(text: str, delete_prev_chars: int) -> None:
+            if delete_prev_chars:
+                sys.stdout.write("\x08" * delete_prev_chars)
+            sys.stdout.write(text)
+            sys.stdout.flush()
+
+  
     elif output == "STDOUT":

         def handle_fn(text: str, delete_prev_chars: int) -> None:
tpoindex commented 2 years ago

After playing a bit more, I'm thinking setting the variable 'progressive' should just be:

line 1353

progressive=not args.defer_output,

because the --continuous flag eliminates a space between words when a pause is detected. For my named pipe example, --continuous works, but if stdout is piped into another process, it might be better to have spaces left in.

vilhelmgray commented 2 years ago

@tpoindex Would you update this pull request to make the change you suggested to set progressive=not args.defer_output?