[Gajim-devel] Event sounds now broken on many platforms

Bruce Walzer bwalzer at 59.ca
Sat Nov 10 01:14:57 CET 2018

I am reasonably certain this was caused by the fix for this issue:


The result of this is that event sounds no longer work and can not be
made to work for any platforms other than Windows, Linux and MacOS. I
discovered this on an OpenBSD upgrade when the major version of gajim
went from 2 to 3. Setting the 'soundplayer' preference to "aucat -i"
as is normal no longer worked. That is because support for running
programs to play sound in "posix" was removed. This change can be
expected to break all the posix platforms but linux. The various BSDs
are the the most well known of these. After figuring out what was
going on I realized that I probably knew the various sound systems on
the more obscure systems better than most so I changed things around
to the way I thought they should be and have attached the results of
that work in the form of 2 patches added at the bottom of this report
(my git/github fu is very weak and attempts to attach the files
produced a "Invalid JSON response from server" error). I have only had
a chance to test my changes against OpenBSD (kind of a generic problem
with environment sensitive code like this).

*Comments on the patch against common/helpers.py:*

In general, if the user has put something in the 'soundplayer' pref
they probably want to use that program to play sounds. This is
something that someone on any platform might want to do, including
Windows and MacOS. For example, I play sounds to a house audio
system. A deaf user might want to run a program to flash a light. So
my patch allows this and fixes sound not just for posix but for any
platform that can run a program to play a sound. I removed the 'beep'
code because the same thing can be done with the 'soundplayer' pref
and I didn't see that a user could set 'path_to_soundfile' in the
first place. I got rid of the OSS support for linux section because it
is for all practical purposes (and has been for a while) dead code. In
the very unlikely event someone is running OSS on Linux the
initialization would set the 'soundplayer' pref when it saw the
'ossplay' program which is going to exist if OSS exists. In practice
people on Linux end up with the pulseaudio or alsa player in the
'soundplayer' pref these days.

*Comments on the patch against gui_interface.py:*

I disabled any possible auto-configuration of the 'soundplayer'
variable for the Windows and MacOS platforms because in most cases
that would be wrong and would create a really hard to find and
annoying problem. While I was there I added auto-configuration for
OpenBSD. I also corrected what seemed to be an 'if' that should of
been a 'elif' that was working by accident.

The following patches were generated against the version of Gajim in OpenBSD 6.4 (1.0.3p2).

--- helpers.py.dist     Wed Oct 31 19:05:36 2018
+++ helpers.py  Wed Nov  7 16:48:18 2018
@@ -83,12 +83,6 @@
         print('Gajim is not able to playback sound because'
               'pyobjc is missing', file=sys.stderr)

-    import wave     # posix-only fallback wav playback
-    import ossaudiodev as oss
-except Exception:
-    pass
 import logging
 log = logging.getLogger('gajim.c.helpers')

@@ -898,38 +892,25 @@
     return file_

 def play_sound_file(path_to_soundfile):
-    if path_to_soundfile == 'beep':
-        exec_command('beep')
-        return
     path_to_soundfile = check_soundfile_path(path_to_soundfile)
     if path_to_soundfile is None:
+    elif app.config.get('soundplayer') != '':
+        player = app.config.get('soundplayer')
+        command = build_command(player, path_to_soundfile)
+        exec_command(command)
+        return
     elif sys.platform == 'win32' and HAS_SOUND:
         except Exception:
             log.exception('Sound Playback Error')
-    elif sys.platform == 'linux':
-        if app.config.get('soundplayer') == '':
-            def _oss_play():
-                sndfile = wave.open(path_to_soundfile, 'rb')
-                (nc, sw, fr, nf, comptype, compname) = sndfile.getparams()
-                dev = oss.open('/dev/audio', 'w')
-                dev.setparameters(sw * 8, nc, fr)
-                dev.write(sndfile.readframes(nf))
-                sndfile.close()
-                dev.close()
-            app.thread_interface(_oss_play)
-            return
-        player = app.config.get('soundplayer')
-        command = build_command(player, path_to_soundfile)
-        exec_command(command)
     elif sys.platform == 'darwin' and HAS_SOUND:
         sound = NSSound.alloc()
         sound.initWithContentsOfFile_byReference_(path_to_soundfile, True)
 def get_global_show():
     maxi = 0
     for account in app.connections:

--- gui_interface.py.dist       Thu Nov  1 19:33:52 2018
+++ gui_interface.py    Thu Nov  1 19:06:36 2018
@@ -2953,17 +2953,20 @@
         # get transports type from DB
         app.transport_type = app.logger.get_transports_type()

-        if app.config.get('soundplayer') == '':
+        if app.config.get('soundplayer') == '' and sys.platform != 'win32' \
+        and sys.platform != 'darwin':
             # only on first time Gajim starts
-            commands = ('paplay', 'aplay', 'play', 'ossplay')
+            commands = ('aucat', 'paplay', 'aplay', 'play', 'ossplay')
             for command in commands:
                 if helpers.is_in_path(command):
                     if command == 'paplay':
                         command += ' -n gajim --property=media.role=event'
-                    if command in ('aplay', 'play'):
+                    elif command in ('aplay', 'play'):
                         command += ' -q'
                     elif command == 'ossplay':
                         command += ' -qq'
+                    elif command == 'aucat':
+                        command += ' -i'
                     app.config.set('soundplayer', command)

More information about the Gajim-devel mailing list