plover icon indicating copy to clipboard operation
plover copied to clipboard

Add a specific dictionary syntax to play a wav audiofile

Open Sillabix opened this issue 2 years ago • 25 comments

DESCRIPTION: Some professional cat softwares (Eclipse) have a specific syntax to associate a definition when playing an audio file, for example: {w: filename.wav}.

This function can be used, for example, to ask the witness to repeat a word that is not well understood, or to slow down the speech to allow it to be better written.

In the case of Plover, in addition to these uses, this function could be applied both for educational purposes and in the case of devices designed for people with disabilities. For example, in the didactic field, by associating the main keyboard combinations to specific audio files that reproduce their sound, the apprentice can have an immediate confirmation of the correctness of the keys pressed without looking at the screen but concentrating only on the keyboard. In the field of disabilities it is possible to create specific dictionaries of syllables associated with their respective phonemes. In this way, for example, a person with speech disabilities could use the steno machine to "speak" at normal speed just writing each syllable of the words, so without the need to learn any abbreviation, or a blind person could use the shorthand machine while also receiving a syllabic feedback.

ALTERNATIVE SOLUTIONS CONSIDERED: It is possible to obtain a similar result by associating the Plover output to a speech to text software. However, this solution is less flexible because most of these software are structured to work on words and not with syllables or single letters, so with the latter they can produce not correct audio results. Furthermore to write words with Plover it is necessary to learn to shorthand using all its abbreviations and this would prevent its use for the didactic purposes or to aid the disabilities described above.

Sillabix avatar Aug 18 '22 17:08 Sillabix

If anything, I have user202729/plover_run_shell: Run a shell command from Plover..

Works, but is unportable and maybe lengthy translation format.

user202729 avatar Aug 18 '22 18:08 user202729

Thanks, I'll give it a try

Sillabix avatar Aug 18 '22 23:08 Sillabix

If anything, I have user202729/plover_run_shell: Run a shell command from Plover..

Works, but is unportable and maybe lengthy translation format.

Hi, I found the correct powershell command to play an audio file directly without running a media player. The problem now is that I don't know how to install in Plover your plugin (I use Windows 10)

Sillabix avatar Aug 20 '22 17:08 Sillabix

It's in the plugins registry, so you should be able to install it through the plugins manager.

benoit-pierre avatar Aug 20 '22 18:08 benoit-pierre

It's in the plugins registry, so you should be able to install it through the plugins manager.

Oh my bad! I must be blind...

Sillabix avatar Aug 20 '22 21:08 Sillabix

Ok, tried to use the shell plugin with this command to play a wav.file of a phoneme sound:

powershell -c (New-Object Media.SoundPlayer "C:\Users\Compadmin_Asus\Music\phoneme.wav").PlaySync();

It works but it still opens the dos command window for the time the sound is played. Moreover is a bit slow: the sound comes out about one second after the stroke.

Sillabix avatar Aug 20 '22 21:08 Sillabix

@Sillabix have you tried https://superuser.com/questions/101974/play-a-sound-maybe-wav-from-windows-line-command#comment2093832_528490 already?

sol avatar Sep 01 '22 18:09 sol

@Sillabix have you tried https://superuser.com/questions/101974/play-a-sound-maybe-wav-from-windows-line-command#comment2093832_528490 already?

Still not entirely. I have to make a few more attempts with VLC and other mediaplayer

Sillabix avatar Sep 01 '22 23:09 Sillabix

So I tested VLC and is kinda slow and it runs in foreground so it opens briefly a window. Then, following the other suggestions in the thread, I tried with fmedia player. This is faster and can run in background. The problem is that the dos prompt window still open and close for a few milliseconds when you stroke the steno with the shell command and this is a bit annoying. With fmedia I used this command:

{PLOVER:SHELL:C:\fmedia\fmedia.exe --background sound.wav}

Sillabix avatar Sep 02 '22 18:09 Sillabix

At this point I’m puzzled if os.system Is responsible for that ”dos prompt “ you see.

  1. When you tried vlc, did you see a command prompt window, too?

  2. You can try the following:

Locate the file plover_run_shell.py on your system and replace the last line

	os.system(command)

with

	subprocess.Popen(command.split())

Make sure to keep the exact same indentation. I think @user202729 used tabs, so you want to indent that line by exactly one tab.

In addition add

import subprocess

just below that line containing import os.

Notes:

  • The above code should work, but I haven’t tested it.
  • This is not a proper solution, as it breaks other shell commands and does not work with paths that contain spaces for example. So use this for testing only and report back.

sol avatar Sep 03 '22 03:09 sol

When you play a file with VLC using the shell plugin it opens two windows: the dos command prompt and a VLC minimized window; with fmedia instead it opens only the dos command prompt window and for a shorter time.

I tried to introduce the suggested changes to the py file but all remains quite the same: with fmedia there is still the dos prompt windows flickering for some milliseconds; with VLC two windows open (DOS command prompt and VLC) but there is also the following addiitional error which comes up after the audio file has been played:

"Python ERROR: engine_on stroke failed FileNotFound error: {WInError 2} Impossible to find the specified path"

I don't know If I interpreted correctly the suggested changes to the py file so I attach it below for checking purposes

''' Execute shell command in Plover using strokes. '''

import os import subprocess

def shell_cmd(_: 'plover.engine.StenoEngine', command: str): ''' Command to execute a shell command. :param _: The Plover engine that is executing the command. :param command: The command to execute. ''' os.system(command) subprocess.Popen(command.split())

Sillabix avatar Sep 03 '22 13:09 Sillabix

Please make two changes:

  1. Remove the line os.system(command)
  2. There is still something going wrong. Change your dictionary entry so that it uses an absolute path to the .wav file and try again. Not sure if that's the issue, but let's rule that out first.

sol avatar Sep 03 '22 14:09 sol

Actually, I'm wrong on (2). I think this error message is from Popen. It basically indicates that it can't find the fmedia.exe. I'll take a quick look.

sol avatar Sep 03 '22 15:09 sol

I've pushed an update to the VLC commands plugin that could help:

  • install the plugin
  • configure access, as per the instructions
  • launch VLC, add the files you want to play to the playlist
  • use the command: {PLOVER:VLC_play:sound.wav} to play the playlist entry named sound.wav

benoit-pierre avatar Sep 03 '22 15:09 benoit-pierre

Note: in VLC's preferences, select "All" to show all preferences, then search for "playlist", and in the "Playlist" tab, check "Play and pause", or upon finishing playing an item, VLC will automatically play the rest of the playlist.

benoit-pierre avatar Sep 03 '22 15:09 benoit-pierre

Alternatively, you could combine the new clear and add commands to achieve the same result (only play one file).

benoit-pierre avatar Sep 03 '22 15:09 benoit-pierre

The thing is that for the purposes described a playlist could not be used. In Eclipse I have about 20.000 wav files of each phoneme, each one associated to a dictionary entry: I suppose I couldn't set up 20.000 playlists in VLC

Sillabix avatar Sep 03 '22 17:09 Sillabix

I don't know what the limit is for a VLC playlist is, but the API is really stupid: you have to use an ID to specify the playlist item, and it's not the ID that is shown to the user, but an internal one, which mean my plugin command implementation has to fetch the whole playlist to look for the right ID...

With that many files, I'd create a dedicated plugin.

benoit-pierre avatar Sep 03 '22 18:09 benoit-pierre

Please make two changes:

  1. Remove the line os.system(command)
  2. There is still something going wrong. Change your dictionary entry so that it uses an absolute path to the .wav file and try again. Not sure if that's the issue, but let's rule that out first.

About 1. I removed the line os.system (command) but nothing changed, except that now VLC does not play any file anymore and it comes out just the message with the error:

"Python ERROR: engine_on stroke failed FileNotFound error: {WInError 2} Impossible to find the specified path"

Sillabix avatar Sep 03 '22 18:09 Sillabix

I don't know what the limit is for a VLC playlist is, but the API is really stupid: you have to use an ID to specify the playlist item, and it's not the ID that is shown to the user, but an internal one, which mean my plugin command implementation has to fetch the whole playlist to look for the right ID...

With that many files, I'd create a dedicated plugin.

Yes, a dedicated plugin would be the best solution but I really don't know how to create it. Anyway I can try with VLC and see if it has a limit in the playlist number

Sillabix avatar Sep 03 '22 19:09 Sillabix

Anyway the dos shell with fmedia works quite well in terms of responsiveness and speed. It would be perfect without the dos command prompt window coming out at every stroke but is already usable this way

Sillabix avatar Sep 03 '22 19:09 Sillabix

@Sillabix I just had the opportunity to try the solution using subprocess.Popen on a Windows box and this works perfectly for me.

It will not show the command prompt window. So from what I understand this could be turned into exactly what you want.

I'm not sure what went wrong on your computer. The error message indicates that it could not find the executable. Are you sure that there weren't any spaces in the path?

sol avatar Sep 05 '22 15:09 sol

@Sillabix I'm not sure how important this is to you, but this is a small thing. Here is a fully tested solution.

  1. Put this into plover_run_shell.py:
    import subprocess
    def shell_cmd(_, file):
        subprocess.Popen(["c:\\fmedia\\fmedia.exe", "--background", file])
    
  2. Restart Plover!
  3. Change your dictionary entry to something like {PLOVER:SHELL:c:\path\to\sound.wav}. Use an absolute path to your wave files, at least for a start.

If this works for you and you are gonna use this then you would want to package this up as a new plugin.

sol avatar Sep 05 '22 16:09 sol

@Sillabix I'm not sure how important this is to you, but this is a small thing. Here is a fully tested solution.

  1. Put this into plover_run_shell.py:
    import subprocess
    def shell_cmd(_, file):
        subprocess.Popen(["c:\\fmedia\\fmedia.exe", "--background", file])
    
  2. Restart Plover!
  3. Change your dictionary entry to something like {PLOVER:SHELL:c:\path\to\sound.wav}. Use an absolute path to your wave files, at least for a start.

If this works for you and you are gonna use this then you would want to package this up as a new plugin.

Thanks a lot! At the moment I'm traveling so I can't give it a try. I'll let you know ASAP

Sillabix avatar Sep 05 '22 20:09 Sillabix

Sorry for reopening this issue after so long time. I finally tried the last suggestion by sol and now the plover_run_shell.py appears the following

''' Execute shell command in Plover using strokes. '''

import os

import subprocess def shell_cmd(_, file): subprocess.Popen(["c:\fmedia\fmedia.exe", "--background", file])

When I try to play a file with the following steno definition:

{PLOVER:SHELL:C:\Users\Compadmin_Asus\Music\test.wav}

The file is not played and appears the message: Plover ERROR:engine on_stroked failed FileNotFoundError: [WinError 2] Impossible to find the specified file

Sillabix avatar Oct 30 '23 01:10 Sillabix