Hello community,

here is the log from the commit of package python-SoundCard for 
openSUSE:Factory checked in at 2020-07-21 15:48:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-SoundCard (Old)
 and      /work/SRC/openSUSE:Factory/.python-SoundCard.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-SoundCard"

Tue Jul 21 15:48:42 2020 rev:6 rq:821996 version:0.4.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-SoundCard/python-SoundCard.changes        
2019-12-03 15:21:43.858524714 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-SoundCard.new.3592/python-SoundCard.changes  
    2020-07-21 15:50:20.708292311 +0200
@@ -1,0 +2,10 @@
+Tue Jul 21 05:39:41 UTC 2020 - Steve Kowalik <[email protected]>
+
+- Update to 0.4.0:
+  * fixes silent recordings on Windows
+  * get and set the pulseaudio program name on Linux
+  * fixes error with unicode soundcard names on Windows
+  * adds support for pyinstaller (v4)
+  * adds compatibility with Windows 7
+
+-------------------------------------------------------------------

Old:
----
  SoundCard-0.3.3.tar.gz

New:
----
  SoundCard-0.4.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-SoundCard.spec ++++++
--- /var/tmp/diff_new_pack.wpbUlV/_old  2020-07-21 15:50:22.172294121 +0200
+++ /var/tmp/diff_new_pack.wpbUlV/_new  2020-07-21 15:50:22.176294126 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-SoundCard
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,11 +19,10 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define         skip_python2 1
 Name:           python-SoundCard
-Version:        0.3.3
+Version:        0.4.0
 Release:        0
 Summary:        Python package to play and record audio
 License:        BSD-3-Clause
-Group:          Development/Languages/Python
 URL:            https://github.com/bastibe/SoundCard
 Source0:        
https://files.pythonhosted.org/packages/source/S/SoundCard/SoundCard-%{version}.tar.gz
 Source1:        
https://raw.githubusercontent.com/bastibe/SoundCard/master/LICENSE

++++++ SoundCard-0.3.3.tar.gz -> SoundCard-0.4.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/PKG-INFO new/SoundCard-0.4.0/PKG-INFO
--- old/SoundCard-0.3.3/PKG-INFO        2019-10-08 10:29:17.000000000 +0200
+++ new/SoundCard-0.4.0/PKG-INFO        2020-05-26 08:39:19.095513000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: SoundCard
-Version: 0.3.3
+Version: 0.4.0
 Summary: Play and record audio without resorting to CPython extensions
 Home-page: https://github.com/bastibe/SoundCard
 Author: Bastian Bechtold
@@ -130,6 +130,19 @@
         how these buffers are handled by the operating system, though, and 
might be
         significantly higher.
         
+        Additionally, it might help to experiment with advice from here: 
https://askubuntu.com/questions/707171/how-can-i-fix-choppy-audio and edit your 
/etc/pulse/default.pa file to replace the line saying ::
+        
+            load-module module-udev-detect
+        
+        with ::
+        
+            load-module module-udev-detect tsched=0
+        
+        and then do not forget to restart pulseaudio with ::
+        
+            pulseaudio -k
+        
+        
         Channel Maps
         ------------
         
@@ -178,8 +191,17 @@
           (Thank you, Inti Pelupessy!)
         - 2019-06-18 fixes crash when opening many streams on Linux
         - 2019-08-23 fixes attribute error when accessing stream state on Linux
-          (Thank you, Davíð Sindri Pétursson)
+          (Thank you, Davíð Sindri Pétursson!)
         - 2019-10-08 fixes inconsistent dtypes when recording on Linux
+        - 2020-01-06 fixes silent recordings on Windows
+        - 2020-04-28 get and set the pulseaudio program name on Linux
+          (Thank you, Philipp A.!)
+        - 2020-05-14 fixes error with unicode soundcard names on Windows
+          (Thank you, BAKEZQ!)
+        - 2020-05-18 adds support for pyinstaller (v4)
+          (Thank you, Bob Thomas!)
+        - 2020-05-19 adds compatibility with Windows 7
+          (Thank you, demberto!)
         
 Platform: UNKNOWN
 Classifier: Development Status :: 4 - Beta
@@ -191,6 +213,7 @@
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
 Classifier: Topic :: Multimedia :: Sound/Audio :: Capture/Recording
 Classifier: Topic :: Multimedia :: Sound/Audio :: Players
 Requires-Python: >=3.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/README.rst 
new/SoundCard-0.4.0/README.rst
--- old/SoundCard-0.3.3/README.rst      2019-10-08 10:16:13.000000000 +0200
+++ new/SoundCard-0.4.0/README.rst      2020-05-26 08:37:41.000000000 +0200
@@ -123,6 +123,19 @@
 how these buffers are handled by the operating system, though, and might be
 significantly higher.
 
+Additionally, it might help to experiment with advice from here: 
https://askubuntu.com/questions/707171/how-can-i-fix-choppy-audio and edit your 
/etc/pulse/default.pa file to replace the line saying ::
+
+    load-module module-udev-detect
+
+with ::
+
+    load-module module-udev-detect tsched=0
+
+and then do not forget to restart pulseaudio with ::
+
+    pulseaudio -k
+
+
 Channel Maps
 ------------
 
@@ -171,5 +184,14 @@
   (Thank you, Inti Pelupessy!)
 - 2019-06-18 fixes crash when opening many streams on Linux
 - 2019-08-23 fixes attribute error when accessing stream state on Linux
-  (Thank you, Davíð Sindri Pétursson)
+  (Thank you, Davíð Sindri Pétursson!)
 - 2019-10-08 fixes inconsistent dtypes when recording on Linux
+- 2020-01-06 fixes silent recordings on Windows
+- 2020-04-28 get and set the pulseaudio program name on Linux
+  (Thank you, Philipp A.!)
+- 2020-05-14 fixes error with unicode soundcard names on Windows
+  (Thank you, BAKEZQ!)
+- 2020-05-18 adds support for pyinstaller (v4)
+  (Thank you, Bob Thomas!)
+- 2020-05-19 adds compatibility with Windows 7
+  (Thank you, demberto!)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/SoundCard.egg-info/PKG-INFO 
new/SoundCard-0.4.0/SoundCard.egg-info/PKG-INFO
--- old/SoundCard-0.3.3/SoundCard.egg-info/PKG-INFO     2019-10-08 
10:29:17.000000000 +0200
+++ new/SoundCard-0.4.0/SoundCard.egg-info/PKG-INFO     2020-05-26 
08:39:18.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: SoundCard
-Version: 0.3.3
+Version: 0.4.0
 Summary: Play and record audio without resorting to CPython extensions
 Home-page: https://github.com/bastibe/SoundCard
 Author: Bastian Bechtold
@@ -130,6 +130,19 @@
         how these buffers are handled by the operating system, though, and 
might be
         significantly higher.
         
+        Additionally, it might help to experiment with advice from here: 
https://askubuntu.com/questions/707171/how-can-i-fix-choppy-audio and edit your 
/etc/pulse/default.pa file to replace the line saying ::
+        
+            load-module module-udev-detect
+        
+        with ::
+        
+            load-module module-udev-detect tsched=0
+        
+        and then do not forget to restart pulseaudio with ::
+        
+            pulseaudio -k
+        
+        
         Channel Maps
         ------------
         
@@ -178,8 +191,17 @@
           (Thank you, Inti Pelupessy!)
         - 2019-06-18 fixes crash when opening many streams on Linux
         - 2019-08-23 fixes attribute error when accessing stream state on Linux
-          (Thank you, Davíð Sindri Pétursson)
+          (Thank you, Davíð Sindri Pétursson!)
         - 2019-10-08 fixes inconsistent dtypes when recording on Linux
+        - 2020-01-06 fixes silent recordings on Windows
+        - 2020-04-28 get and set the pulseaudio program name on Linux
+          (Thank you, Philipp A.!)
+        - 2020-05-14 fixes error with unicode soundcard names on Windows
+          (Thank you, BAKEZQ!)
+        - 2020-05-18 adds support for pyinstaller (v4)
+          (Thank you, Bob Thomas!)
+        - 2020-05-19 adds compatibility with Windows 7
+          (Thank you, demberto!)
         
 Platform: UNKNOWN
 Classifier: Development Status :: 4 - Beta
@@ -191,6 +213,7 @@
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
 Classifier: Topic :: Multimedia :: Sound/Audio :: Capture/Recording
 Classifier: Topic :: Multimedia :: Sound/Audio :: Players
 Requires-Python: >=3.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/SoundCard.egg-info/SOURCES.txt 
new/SoundCard-0.4.0/SoundCard.egg-info/SOURCES.txt
--- old/SoundCard-0.3.3/SoundCard.egg-info/SOURCES.txt  2019-10-08 
10:29:17.000000000 +0200
+++ new/SoundCard-0.4.0/SoundCard.egg-info/SOURCES.txt  2020-05-26 
08:39:18.000000000 +0200
@@ -3,6 +3,7 @@
 SoundCard.egg-info/PKG-INFO
 SoundCard.egg-info/SOURCES.txt
 SoundCard.egg-info/dependency_links.txt
+SoundCard.egg-info/entry_points.txt
 SoundCard.egg-info/requires.txt
 SoundCard.egg-info/top_level.txt
 soundcard/__init__.py
@@ -12,4 +13,8 @@
 soundcard/mediafoundation.py
 soundcard/mediafoundation.py.h
 soundcard/pulseaudio.py
-soundcard/pulseaudio.py.h
\ No newline at end of file
+soundcard/pulseaudio.py.h
+soundcard/__pyinstaller/__init__.py
+soundcard/__pyinstaller/conftest.py
+soundcard/__pyinstaller/hook-soundcard.py
+soundcard/__pyinstaller/test_soundcard.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/SoundCard.egg-info/entry_points.txt 
new/SoundCard-0.4.0/SoundCard.egg-info/entry_points.txt
--- old/SoundCard-0.3.3/SoundCard.egg-info/entry_points.txt     1970-01-01 
01:00:00.000000000 +0100
+++ new/SoundCard-0.4.0/SoundCard.egg-info/entry_points.txt     2020-05-26 
08:39:18.000000000 +0200
@@ -0,0 +1,4 @@
+[pyinstaller40]
+hook-dirs = soundcard.__pyinstaller:get_hook_dirs
+tests = soundcard.__pyinstaller:get_test_dirs
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/SoundCard.egg-info/requires.txt 
new/SoundCard-0.4.0/SoundCard.egg-info/requires.txt
--- old/SoundCard-0.3.3/SoundCard.egg-info/requires.txt 2019-10-08 
10:29:17.000000000 +0200
+++ new/SoundCard-0.4.0/SoundCard.egg-info/requires.txt 2020-05-26 
08:39:18.000000000 +0200
@@ -1,2 +1,2 @@
-numpy
 cffi
+numpy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/setup.py new/SoundCard-0.4.0/setup.py
--- old/SoundCard-0.3.3/setup.py        2019-10-08 10:10:49.000000000 +0200
+++ new/SoundCard-0.4.0/setup.py        2020-05-26 08:37:56.000000000 +0200
@@ -2,12 +2,12 @@
 
 setup(
     name='SoundCard',
-    version='0.3.3',
+    version='0.4.0',
     description='Play and record audio without resorting to CPython 
extensions',
     author='Bastian Bechtold',
     url='https://github.com/bastibe/SoundCard',
     license='BSD 3-clause',
-    packages=['soundcard'],
+    packages=['soundcard', 'soundcard.__pyinstaller'],
     package_data={'soundcard': ['*.py.h']},
     install_requires=['numpy', 'cffi'],
     python_requires='>=3.5',
@@ -21,8 +21,15 @@
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: 3.8',
         'Topic :: Multimedia :: Sound/Audio :: Capture/Recording',
         'Topic :: Multimedia :: Sound/Audio :: Players',
     ],
     long_description=open('README.rst').read(),
+    entry_points={
+        "pyinstaller40": [
+            "hook-dirs = soundcard.__pyinstaller:get_hook_dirs",
+            "tests = soundcard.__pyinstaller:get_test_dirs",
+        ],
+    },
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/soundcard/__pyinstaller/__init__.py 
new/SoundCard-0.4.0/soundcard/__pyinstaller/__init__.py
--- old/SoundCard-0.3.3/soundcard/__pyinstaller/__init__.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/SoundCard-0.4.0/soundcard/__pyinstaller/__init__.py     2020-05-26 
08:29:37.000000000 +0200
@@ -0,0 +1,12 @@
+from os.path import dirname
+
+
+HERE = dirname(__file__)
+
+
+def get_hook_dirs():
+    return [HERE]
+
+
+def get_test_dirs():
+    return [HERE]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/soundcard/__pyinstaller/conftest.py 
new/SoundCard-0.4.0/soundcard/__pyinstaller/conftest.py
--- old/SoundCard-0.3.3/soundcard/__pyinstaller/conftest.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/SoundCard-0.4.0/soundcard/__pyinstaller/conftest.py     2020-05-26 
08:29:37.000000000 +0200
@@ -0,0 +1 @@
+from PyInstaller.utils.conftest import *  # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/SoundCard-0.3.3/soundcard/__pyinstaller/hook-soundcard.py 
new/SoundCard-0.4.0/soundcard/__pyinstaller/hook-soundcard.py
--- old/SoundCard-0.3.3/soundcard/__pyinstaller/hook-soundcard.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.0/soundcard/__pyinstaller/hook-soundcard.py       
2020-05-26 08:29:37.000000000 +0200
@@ -0,0 +1,7 @@
+"""
+Hook for https://pypi.org/project/SoundCard/
+"""
+
+from PyInstaller.utils.hooks import collect_data_files
+
+datas = collect_data_files('soundcard')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/SoundCard-0.3.3/soundcard/__pyinstaller/test_soundcard.py 
new/SoundCard-0.4.0/soundcard/__pyinstaller/test_soundcard.py
--- old/SoundCard-0.3.3/soundcard/__pyinstaller/test_soundcard.py       
1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.0/soundcard/__pyinstaller/test_soundcard.py       
2020-05-26 08:29:37.000000000 +0200
@@ -0,0 +1,6 @@
+def test_pyi_soundcard(pyi_builder):
+    pyi_builder.test_source(
+        """
+        import soundcard
+    """
+    )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/soundcard/coreaudio.py 
new/SoundCard-0.4.0/soundcard/coreaudio.py
--- old/SoundCard-0.3.3/soundcard/coreaudio.py  2019-10-08 10:01:45.000000000 
+0200
+++ new/SoundCard-0.4.0/soundcard/coreaudio.py  2020-04-28 16:14:27.000000000 
+0200
@@ -105,6 +105,14 @@
     raise IndexError('no device with id {}'.format(id))
 
 
+def get_name():
+    raise NotImplementedError()
+
+
+def set_name(name):
+    raise NotImplementedError()
+
+
 class _Soundcard:
     """A soundcard. This is meant to be subclassed.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/soundcard/mediafoundation.py 
new/SoundCard-0.4.0/soundcard/mediafoundation.py
--- old/SoundCard-0.3.3/soundcard/mediafoundation.py    2019-10-08 
10:01:45.000000000 +0200
+++ new/SoundCard-0.4.0/soundcard/mediafoundation.py    2020-05-26 
08:29:37.000000000 +0200
@@ -6,13 +6,13 @@
 import time
 import re
 import collections
+import platform
 
 _ffi = cffi.FFI()
 _package_dir, _ = os.path.split(__file__)
 with open(os.path.join(_package_dir, 'mediafoundation.py.h'), 'rt') as f:
     _ffi.cdef(f.read())
 
-_combase = _ffi.dlopen('combase')
 _ole32 = _ffi.dlopen('ole32')
 
 class _COMLibrary:
@@ -27,7 +27,15 @@
 
     def __init__(self):
         COINIT_MULTITHREADED = 0x0
-        hr = _combase.CoInitializeEx(_ffi.NULL, COINIT_MULTITHREADED)
+        if platform.win32_ver()[0] == '8':
+            # On Windows 8, according to Microsoft, the first use of 
+            # IAudioClient should be from the STA thread. Calls from 
+            # an MTA thread may result in undefined behavior.
+            
+            # CoInitialize initialises calling thread to STA.
+            hr = _ole32.CoInitialize(_ffi.NULL)
+        else:
+            hr = _ole32.CoInitializeEx(_ffi.NULL, COINIT_MULTITHREADED)
 
         try:
             self.check_error(hr)
@@ -53,7 +61,7 @@
         # Don't un-initialize COM if COM was not initialized directly
         # by this class:
         if self.com_loaded:
-            _combase.CoUninitialize()
+            _ole32.CoUninitialize()
 
     @staticmethod
     def check_error(hresult):
@@ -174,10 +182,19 @@
     IID = _ffi.new('LPIID')
     # convert to zero terminated wide string
     uuid = _str2wstr(uuid_str)
-    hr = _combase.IIDFromString(_ffi.cast("char*", uuid), IID)
+    hr = _ole32.IIDFromString(_ffi.cast("char*", uuid), IID)
     _com.check_error(hr)
     return IID
 
+
+def get_name():
+    raise NotImplementedError()
+
+
+def set_name(name):
+    raise NotImplementedError()
+
+
 class _DeviceEnumerator:
     """Wrapper class for an IMMDeviceEnumerator**.
 
@@ -192,7 +209,7 @@
         IID_IMMDeviceEnumerator = 
_guidof("{A95664D2-9614-4F35-A746-DE8DB63617E6}")
         # see shared/WTypesbase.h and um/combaseapi.h:
         CLSCTX_ALL = 23
-        hr = _combase.CoCreateInstance(IID_MMDeviceEnumerator, _ffi.NULL, 
CLSCTX_ALL,
+        hr = _ole32.CoCreateInstance(IID_MMDeviceEnumerator, _ffi.NULL, 
CLSCTX_ALL,
                                   IID_IMMDeviceEnumerator, _ffi.cast("void 
**", self._ptr))
         _com.check_error(hr)
 
@@ -303,7 +320,7 @@
 
     """
     def __init__(self):
-        self.ptr = _combase.CoTaskMemAlloc(_ffi.sizeof('PROPVARIANT'))
+        self.ptr = _ole32.CoTaskMemAlloc(_ffi.sizeof('PROPVARIANT'))
         self.ptr = _ffi.cast("PROPVARIANT *", self.ptr)
 
     def __del__(self):
@@ -511,9 +528,9 @@
         # ppMixFormat[0][0].dwChannelMask=channelmask
 
         if exclusive_mode:
-            sharemode = _combase.AUDCLNT_SHAREMODE_EXCLUSIVE
+            sharemode = _ole32.AUDCLNT_SHAREMODE_EXCLUSIVE
         else:
-            sharemode = _combase.AUDCLNT_SHAREMODE_SHARED
+            sharemode = _ole32.AUDCLNT_SHAREMODE_SHARED
         #             resample   | remix      | better-SRC | nopersist
         streamflags = 0x00100000 | 0x80000000 | 0x08000000 | 0x00080000
         if isloopback:
@@ -521,7 +538,7 @@
         bufferduration = int(blocksize/samplerate * 10000000) # in 
hecto-nanoseconds (1000_000_0)
         hr = self._ptr[0][0].lpVtbl.Initialize(self._ptr[0], sharemode, 
streamflags, bufferduration, 0, ppMixFormat[0], _ffi.NULL)
         _com.check_error(hr)
-        _combase.CoTaskMemFree(ppMixFormat[0])
+        _ole32.CoTaskMemFree(ppMixFormat[0])
 
     @property
     def buffersize(self):
@@ -698,7 +715,12 @@
 
         """
 
+        empty_frames = 0
         while not self._capture_available_frames():
+            empty_frames += 1
+            if empty_frames > 10:
+                # no data for 10 ms: give up.
+                return numpy.zeros([0], dtype='float32')
             time.sleep(0.001)
         data_ptr, nframes, flags = self._capture_buffer()
         if data_ptr != _ffi.NULL:
@@ -709,7 +731,7 @@
             self._capture_release(nframes)
             return chunk
         else:
-            return numpy.zeros([0])
+            return numpy.zeros([0], dtype='float32')
 
     def record(self, numframes=None):
         """Record a block of audio data.
@@ -741,6 +763,10 @@
             required_frames = numframes*len(set(self.channelmap))
             while recorded_frames < required_frames:
                 chunk = self._record_chunk()
+                if len(chunk) == 0:
+                    # no data forthcoming: return zeros
+                    chunk = numpy.zeros(required_frames-recorded_frames,
+                                        dtype='float32')
                 recorded_data.append(chunk)
                 recorded_frames += len(chunk)
             if recorded_frames > required_frames:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/soundcard/pulseaudio.py 
new/SoundCard-0.4.0/soundcard/pulseaudio.py
--- old/SoundCard-0.3.3/soundcard/pulseaudio.py 2019-10-08 10:07:30.000000000 
+0200
+++ new/SoundCard-0.4.0/soundcard/pulseaudio.py 2020-04-28 16:14:27.000000000 
+0200
@@ -63,13 +63,35 @@
         # don't need to hold the lock:
         self.mainloop = _pa.pa_threaded_mainloop_new()
         self.mainloop_api = _pa.pa_threaded_mainloop_get_api(self.mainloop)
-        self.context = _pa.pa_context_new(self.mainloop_api, b"audio")
+        self.context = _pa.pa_context_new(self.mainloop_api, 
self._infer_program_name().encode())
         _pa.pa_context_connect(self.context, _ffi.NULL, 
_pa.PA_CONTEXT_NOFLAGS, _ffi.NULL)
         _pa.pa_threaded_mainloop_start(self.mainloop)
 
         while self._pa_context_get_state(self.context) != _pa.PA_CONTEXT_READY:
             time.sleep(0.001)
 
+    @staticmethod
+    def _infer_program_name():
+        """Get current progam name.
+
+        Will handle `./script.py`, `python path/to/script.py`,
+        `python -m module.submodule` and `python -c 'code(x=y)'`.
+        See https://docs.python.org/3/using/cmdline.html#interface-options
+        """
+        import sys
+        prog_name = sys.argv[0]
+        if prog_name == "-c":
+            return sys.argv[1][:30] + "..."
+        if prog_name == "-m":
+            prog_name = sys.argv[1]
+        # Usually even with -m, sys.argv[0] will already be a path,
+        # so do the following outside the above check
+        main_str = "/__main__.py"
+        if prog_name.endswith(main_str):
+            prog_name = prog_name[:-len(main_str)]
+        # Not handled: sys.argv[0] == "-"
+        return os.path.basename(prog_name)
+
     def _shutdown(self):
         operation = self._pa_context_drain(self.context, _ffi.NULL, _ffi.NULL)
         self._block_operation(operation)
@@ -87,6 +109,34 @@
             time.sleep(0.001)
 
     @property
+    def name(self):
+        """Return application name stored in client proplist"""
+        idx = self._pa_context_get_index(self.context)
+        if idx < 0:  # PA_INVALID_INDEX == -1
+            raise RuntimeError("Could not get client index of PulseAudio 
context.")
+        name = None
+        @_ffi.callback("pa_client_info_cb_t")
+        def callback(context, client_info, eol, userdata):
+            nonlocal name
+            if not eol:
+                name = _ffi.string(client_info.name).decode('utf-8')
+        self._pa_context_get_client_info(self.context, idx, callback, 
_ffi.NULL)
+        assert name is not None
+        return name
+
+    @name.setter
+    def name(self, name):
+        rv = None
+        @_ffi.callback("pa_context_success_cb_t")
+        def callback(context, success, userdata):
+            nonlocal rv
+            rv = success
+        self._pa_context_set_name(self.context, name.encode(), callback, 
_ffi.NULL)
+        assert rv is not None
+        if rv == 0:
+            raise RuntimeError("Setting PulseAudio context name failed")
+
+    @property
     def source_list(self):
         """Return a list of dicts of information about available sources."""
         info = []
@@ -178,8 +228,11 @@
     _pa_context_get_source_info_by_name = 
_lock_and_block(_pa.pa_context_get_source_info_by_name)
     _pa_context_get_sink_info_list = 
_lock_and_block(_pa.pa_context_get_sink_info_list)
     _pa_context_get_sink_info_by_name = 
_lock_and_block(_pa.pa_context_get_sink_info_by_name)
+    _pa_context_get_client_info = 
_lock_and_block(_pa.pa_context_get_client_info)
     _pa_context_get_server_info = 
_lock_and_block(_pa.pa_context_get_server_info)
+    _pa_context_get_index = _lock(_pa.pa_context_get_index)
     _pa_context_get_state = _lock(_pa.pa_context_get_state)
+    _pa_context_set_name = _lock_and_block(_pa.pa_context_set_name)
     _pa_context_drain = _lock(_pa.pa_context_drain)
     _pa_context_disconnect = _lock(_pa.pa_context_disconnect)
     _pa_context_unref = _lock(_pa.pa_context_unref)
@@ -345,6 +398,34 @@
     raise IndexError('no soundcard with id {}'.format(id))
 
 
+def get_name():
+    """Get application name.
+
+    .. note::
+       Currently only works on Linux.
+
+    Returns
+    -------
+    name : str
+    """
+    return _pulse.name
+
+
+def set_name(name):
+    """Set application name.
+
+    .. note::
+       Currently only works on Linux.
+
+    Parameters
+    ----------
+    name :  str
+        The application using the soundcard
+        will be identified by the OS using this name.
+    """
+    _pulse.name = name
+
+
 class _SoundCard:
     def __init__(self, *, id):
         self._id = id
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.3.3/soundcard/pulseaudio.py.h 
new/SoundCard-0.4.0/soundcard/pulseaudio.py.h
--- old/SoundCard-0.3.3/soundcard/pulseaudio.py.h       2019-10-08 
10:01:45.000000000 +0200
+++ new/SoundCard-0.4.0/soundcard/pulseaudio.py.h       2020-04-28 
16:14:27.000000000 +0200
@@ -322,7 +322,20 @@
 pa_operation* pa_context_get_source_info_list(pa_context *c, 
pa_source_info_cb_t cb, void *userdata);
 pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char 
*name, pa_source_info_cb_t cb, void *userdata);
 typedef void (*pa_context_notify_cb)(pa_context *c, void *userdata);
-pa_operation *pa_context_drain(pa_context *c, pa_context_notify_cb cb, void 
*userdata);
+pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb cb, void 
*userdata);
+typedef void (*pa_context_success_cb_t)(pa_context *c, int success, void 
*userdata);
+pa_operation* pa_context_set_name(pa_context *c, const char *name, 
pa_context_success_cb_t cb, void *userdata);
+uint32_t pa_context_get_index(const pa_context *s);
+
+typedef struct pa_client_info {
+    uint32_t index;
+    const char *name;
+    uint32_t owner_module;
+    const char *driver;
+    pa_proplist *proplist;
+} pa_client_info;
+typedef void (*pa_client_info_cb_t) (pa_context *c, const pa_client_info*i, 
int eol, void *userdata);
+pa_operation* pa_context_get_client_info(pa_context *c, uint32_t idx, 
pa_client_info_cb_t cb, void *userdata);
 
 typedef struct pa_server_info {
     const char *user_name;


Reply via email to