Hi,

please find attached a sndio backend for FreeRDP which implements

- Audio Output Virtual Channel
  (= sound on remote desktop is redirected to local sndiod) and

- Audio Input Redirection Virtual Channel
  (= local microphone is redirected to remote desktop).

This allows me to use MS Teams on a remote desktop via FreeRDP. The audio
quality is very good in my test setup; sometimes Windows chimes crackle a bit;
the same behavior is observed with a recent FreeRDP on a Linux machine
(with a pulseaudio/alsa backend).

The backend is based on the oss backend with inspiration from alsa und
pulseaudio. Neither of those three work on OpenBSD. At the moment I do not
plan to submit this upstream as the implementation uses a slightly outdated
API. I am willing to do this once (whether?) our FreeRDP ports gets updated
(which is blocked to due missing timer_create()) as I cannot test
against newer versions easily at the moment.

If a developer thinks this is a useful contribution (and gives an OK) we can
add it to our FreeRDP port locally for the moment.

I attached a .tar.gz to make it easier to review as I did not dare to
cvs add a new "files" directory (as CVS won't forget?). The following diff
shows everything besides the "files" directory.

You need to add /sound:sys:sndio /microphone:sys:sndio to activate the
new features. (x11/remmina cannot handle it; I did not investigate in
depth as we have an outdated version in ports). E.g.:

xfreerdp /d:yourdomain /u:yourusername /v:yourservername.com /sound:sys:sndio 
/microphone:sys:sndio

OK?

Best regards,
Ingo

Index: Makefile
===================================================================
RCS file: /cvs/ports/x11/freerdp/Makefile,v
retrieving revision 1.39
diff -u -p -r1.39 Makefile
--- Makefile    4 Nov 2019 10:30:20 -0000       1.39
+++ Makefile    10 Sep 2020 14:17:31 -0000
@@ -6,7 +6,7 @@ BROKEN-hppa =           undefined reference to __
 COMMENT =              client for Microsoft RDP (remote desktop protocol)
 DISTNAME =             freerdp-2.0.0-rc1
 PKGNAME =              freerdp-2.0.0rc1
-REVISION =             4
+REVISION =             5
 CATEGORIES =           x11 net
 
 # XXX This version has known security issues.
@@ -26,7 +26,7 @@ MASTER_SITES =                https://pub.freerdp.com/
 PERMIT_PACKAGE =       Yes
 
 WANTLIB += X11 Xcursor Xext Xfixes Xi Xinerama Xrender Xv avcodec
-WANTLIB += avutil c crypto cups execinfo m pthread ssl xkbfile
+WANTLIB += avutil c crypto cups execinfo m pthread sndio ssl xkbfile
 
 # thread-local storage
 COMPILER =             base-clang ports-gcc
@@ -50,9 +50,15 @@ CONFIGURE_ARGS +=    -DBUILD_TESTING=ON \
                        -DWITH_OPENSLES=OFF \
                        -DWITH_PCSC=ON \
                        -DWITH_LIBSYSTEMD=OFF \
-                       -DWITH_OSS=OFF
+                       -DWITH_OSS=OFF \
+                       -DWITH_SNDIO=ON
 
 pre-configure:
+       mkdir ${WRKSRC}/channels/{audin,rdpsnd}/client/sndio
+       cp ${FILESDIR}/audin/{CMakeLists.txt,audin_sndio.c} \
+               ${WRKSRC}/channels/audin/client/sndio
+       cp ${FILESDIR}/rdpsnd/{CMakeLists.txt,rdpsnd_sndio.c} \
+               ${WRKSRC}/channels/rdpsnd/client/sndio
        ${SUBST_CMD}    ${WRKSRC}/winpr/libwinpr/CMakeLists.txt
        ${SUBST_CMD}    ${WRKSRC}/CMakeLists.txt
 
Index: patches/patch-channels_audin_client_CMakeLists_txt
===================================================================
RCS file: patches/patch-channels_audin_client_CMakeLists_txt
diff -N patches/patch-channels_audin_client_CMakeLists_txt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-channels_audin_client_CMakeLists_txt  10 Sep 2020 14:17:31 
-0000
@@ -0,0 +1,13 @@
+$OpenBSD$
+
+Index: channels/audin/client/CMakeLists.txt
+--- channels/audin/client/CMakeLists.txt.orig
++++ channels/audin/client/CMakeLists.txt
+@@ -56,3 +56,7 @@ endif()
+ if(WITH_MACAUDIO)
+       add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "mac" "")
+ endif()
++
++if(WITH_SNDIO)
++      add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "sndio" 
"")
++endif()
Index: patches/patch-channels_audin_client_audin_main_c
===================================================================
RCS file: patches/patch-channels_audin_client_audin_main_c
diff -N patches/patch-channels_audin_client_audin_main_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-channels_audin_client_audin_main_c    10 Sep 2020 14:17:31 
-0000
@@ -0,0 +1,27 @@
+$OpenBSD$
+
+Index: channels/audin/client/audin_main.c
+--- channels/audin/client/audin_main.c.orig
++++ channels/audin/client/audin_main.c
+@@ -670,8 +670,11 @@ static UINT audin_load_device_plugin(IWTSPlugin* pPlug
+       AUDIN_PLUGIN* audin = (AUDIN_PLUGIN*)pPlugin;
+       UINT error;
+ 
++      /*
++       * Causes invalid memory access. Ignore as we do not have arguments.
+       if (!audin_process_addin_args(audin, args))
+               return CHANNEL_RC_INITIALIZATION_ERROR;
++      */
+ 
+       entry = (PFREERDP_AUDIN_DEVICE_ENTRY) 
freerdp_load_channel_addin_entry("audin", (LPSTR) name, NULL,
+               0);
+@@ -863,6 +866,9 @@ UINT DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoint
+ #endif
+ #if defined(WITH_MACAUDIO)
+               {"mac", "default"},
++#endif
++#if defined(WITH_SNDIO)
++              {"sndio", "default"},
+ #endif
+               {NULL, NULL}
+       };
Index: patches/patch-channels_rdpsnd_client_CMakeLists_txt
===================================================================
RCS file: patches/patch-channels_rdpsnd_client_CMakeLists_txt
diff -N patches/patch-channels_rdpsnd_client_CMakeLists_txt
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-channels_rdpsnd_client_CMakeLists_txt 10 Sep 2020 14:17:31 
-0000
@@ -0,0 +1,13 @@
+$OpenBSD$
+
+Index: channels/rdpsnd/client/CMakeLists.txt
+--- channels/rdpsnd/client/CMakeLists.txt.orig
++++ channels/rdpsnd/client/CMakeLists.txt
+@@ -57,3 +57,7 @@ endif()
+ if(WITH_OPENSLES)
+       add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} 
"opensles" "")
+ endif()
++
++if(WITH_SNDIO)
++      add_channel_client_subsystem(${MODULE_PREFIX} ${CHANNEL_NAME} "sndio" 
"")
++endif()
Index: patches/patch-channels_rdpsnd_client_rdpsnd_main_c
===================================================================
RCS file: patches/patch-channels_rdpsnd_client_rdpsnd_main_c
diff -N patches/patch-channels_rdpsnd_client_rdpsnd_main_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-channels_rdpsnd_client_rdpsnd_main_c  10 Sep 2020 14:17:31 
-0000
@@ -0,0 +1,25 @@
+$OpenBSD$
+
+Index: channels/rdpsnd/client/rdpsnd_main.c
+--- channels/rdpsnd/client/rdpsnd_main.c.orig
++++ channels/rdpsnd/client/rdpsnd_main.c
+@@ -1086,6 +1086,19 @@ static UINT rdpsnd_process_connect(rdpsndPlugin* rdpsn
+               }
+ 
+ #endif
++#if defined(WITH_SNDIO)
++
++              if (!rdpsnd->device)
++              {
++                      subsystem_name = "sndio";
++                      device_name = "";
++
++                      if ((status = rdpsnd_load_device_plugin(rdpsnd, 
subsystem_name, args)))
++                              WLog_ERR(TAG, "unable to load the %s subsystem 
plugin because of error %"PRIu32"",
++                                       subsystem_name, status);
++              }
++
++#endif
+ 
+               if (status)
+                       return status;
Index: patches/patch-client_common_CMakeLists_txt
===================================================================
RCS file: /cvs/ports/x11/freerdp/patches/patch-client_common_CMakeLists_txt,v
retrieving revision 1.1
diff -u -p -r1.1 patch-client_common_CMakeLists_txt
--- patches/patch-client_common_CMakeLists_txt  28 Apr 2018 19:20:17 -0000      
1.1
+++ patches/patch-client_common_CMakeLists_txt  10 Sep 2020 14:17:31 -0000
@@ -1,5 +1,5 @@
 $OpenBSD: patch-client_common_CMakeLists_txt,v 1.1 2018/04/28 19:20:17 landry 
Exp $
-Doesn't use ossaudio for OpenBSD
+Use sndio audio backend
 Index: client/common/CMakeLists.txt
 --- client/common/CMakeLists.txt.orig
 +++ client/common/CMakeLists.txt
@@ -12,7 +12,7 @@ Index: client/common/CMakeLists.txt
 -else()
 -      target_link_libraries(${MODULE_NAME} ${PUBLIC_KEYWORD} 
${${MODULE_PREFIX}_LIBS})
 -endif()
-+target_link_libraries(${MODULE_NAME} ${PUBLIC_KEYWORD} 
${${MODULE_PREFIX}_LIBS})
++target_link_libraries(${MODULE_NAME} ${PUBLIC_KEYWORD} 
${${MODULE_PREFIX}_LIBS} sndio)
  
  
  install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT 
libraries EXPORT FreeRDP-ClientTargets)

Attachment: freerdp.tar.gz
Description: application/tar-gz

Reply via email to