Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-SoundCard for 
openSUSE:Factory checked in at 2022-08-30 14:49:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-SoundCard (Old)
 and      /work/SRC/openSUSE:Factory/.python-SoundCard.new.2083 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-SoundCard"

Tue Aug 30 14:49:03 2022 rev:9 rq:999912 version:0.4.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-SoundCard/python-SoundCard.changes        
2021-08-29 21:34:13.594699269 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-SoundCard.new.2083/python-SoundCard.changes  
    2022-08-30 14:49:32.320129406 +0200
@@ -1,0 +2,8 @@
+Mon Aug 29 03:52:21 UTC 2022 - Yogalakshmi Arunachalam <[email protected]>
+
+- Update to 0.4.2: 
+  * adds compatibility with NixOS library naming (Thank you, shithead!)
+  * fixes deprecation for Python 3.10 (Thank you, Nekyo!)
+  * fixes deprecation in recent Numpy
+
+-------------------------------------------------------------------

Old:
----
  SoundCard-0.4.1.tar.gz

New:
----
  SoundCard-0.4.2.tar.gz

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

Other differences:
------------------
++++++ python-SoundCard.spec ++++++
--- /var/tmp/diff_new_pack.w7r3nN/_old  2022-08-30 14:49:34.344134569 +0200
+++ /var/tmp/diff_new_pack.w7r3nN/_new  2022-08-30 14:49:34.352134590 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-SoundCard
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -22,7 +22,7 @@
 %define         skip_python36 1
 %endif
 Name:           python-SoundCard
-Version:        0.4.1
+Version:        0.4.2
 Release:        0
 Summary:        Python package to play and record audio
 License:        BSD-3-Clause

++++++ SoundCard-0.4.1.tar.gz -> SoundCard-0.4.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/.gitignore 
new/SoundCard-0.4.2/.gitignore
--- old/SoundCard-0.4.1/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.2/.gitignore      2022-05-09 15:57:27.000000000 +0200
@@ -0,0 +1,7 @@
+*.DS_Store
+*.pyc
+
+temp/
+build/
+dist/
+SoundCard.egg-info/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/LICENSE new/SoundCard-0.4.2/LICENSE
--- old/SoundCard-0.4.1/LICENSE 1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.2/LICENSE 2022-05-09 15:57:27.000000000 +0200
@@ -0,0 +1,30 @@
+Copyright (c) 2016 Bastian Bechtold
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the
+   distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+   contributors may be used to endorse or promote products derived
+   from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/PKG-INFO new/SoundCard-0.4.2/PKG-INFO
--- old/SoundCard-0.4.1/PKG-INFO        2021-03-14 13:40:59.074842700 +0100
+++ new/SoundCard-0.4.2/PKG-INFO        2022-05-09 16:02:36.808252000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: SoundCard
-Version: 0.4.1
+Version: 0.4.2
 Summary: Play and record audio without resorting to CPython extensions
 Home-page: https://github.com/bastibe/SoundCard
 Author: Bastian Bechtold
@@ -215,14 +215,11 @@
           (Thank you, Bob Thomas!)
         - 2020-05-19 adds compatibility with Windows 7
           (Thank you, demberto!)
-        - 2020-07-22 fixes freezing bug on Linux during startup
-          (Thank you, zhujisheng!)
-        - 2020-08-01 improves error reporting on Linux
-          (Thank you, Rik van Riel!)
-        - 2020-08-13 fixes crash due to use-after-free on Linux
-          (Thank you, Rik van Riel!)
-        - 2021-01-13 fixes unicode error on Windows
-          (Thank you, paulzzh!)
+        - 2021-11-24 adds compatibility with NixOS library naming
+          (Thank you, shithead!)
+        - 2021-12-23 fixes deprecation for Python 3.10
+          (Thank you, Nekyo!)
+        - 2022-04-29 fixes deprecation in recent Numpy
         
 Platform: UNKNOWN
 Classifier: Development Status :: 4 - Beta
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/Pipfile new/SoundCard-0.4.2/Pipfile
--- old/SoundCard-0.4.1/Pipfile 1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.2/Pipfile 2022-05-09 15:57:27.000000000 +0200
@@ -0,0 +1,13 @@
+[[source]]
+url = "https://pypi.org/simple";
+verify_ssl = true
+name = "pypi"
+
+[packages]
+cffi = "*"
+numpy = "*"
+
+[dev-packages]
+
+[requires]
+python_version = "3.6"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/README.rst 
new/SoundCard-0.4.2/README.rst
--- old/SoundCard-0.4.1/README.rst      2021-03-14 13:37:19.000000000 +0100
+++ new/SoundCard-0.4.2/README.rst      2022-05-09 16:01:07.000000000 +0200
@@ -208,11 +208,8 @@
   (Thank you, Bob Thomas!)
 - 2020-05-19 adds compatibility with Windows 7
   (Thank you, demberto!)
-- 2020-07-22 fixes freezing bug on Linux during startup
-  (Thank you, zhujisheng!)
-- 2020-08-01 improves error reporting on Linux
-  (Thank you, Rik van Riel!)
-- 2020-08-13 fixes crash due to use-after-free on Linux
-  (Thank you, Rik van Riel!)
-- 2021-01-13 fixes unicode error on Windows
-  (Thank you, paulzzh!)
+- 2021-11-24 adds compatibility with NixOS library naming
+  (Thank you, shithead!)
+- 2021-12-23 fixes deprecation for Python 3.10
+  (Thank you, Nekyo!)
+- 2022-04-29 fixes deprecation in recent Numpy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/SoundCard.egg-info/PKG-INFO 
new/SoundCard-0.4.2/SoundCard.egg-info/PKG-INFO
--- old/SoundCard-0.4.1/SoundCard.egg-info/PKG-INFO     2021-03-14 
13:40:57.000000000 +0100
+++ new/SoundCard-0.4.2/SoundCard.egg-info/PKG-INFO     2022-05-09 
16:02:36.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.2
 Name: SoundCard
-Version: 0.4.1
+Version: 0.4.2
 Summary: Play and record audio without resorting to CPython extensions
 Home-page: https://github.com/bastibe/SoundCard
 Author: Bastian Bechtold
@@ -215,14 +215,11 @@
           (Thank you, Bob Thomas!)
         - 2020-05-19 adds compatibility with Windows 7
           (Thank you, demberto!)
-        - 2020-07-22 fixes freezing bug on Linux during startup
-          (Thank you, zhujisheng!)
-        - 2020-08-01 improves error reporting on Linux
-          (Thank you, Rik van Riel!)
-        - 2020-08-13 fixes crash due to use-after-free on Linux
-          (Thank you, Rik van Riel!)
-        - 2021-01-13 fixes unicode error on Windows
-          (Thank you, paulzzh!)
+        - 2021-11-24 adds compatibility with NixOS library naming
+          (Thank you, shithead!)
+        - 2021-12-23 fixes deprecation for Python 3.10
+          (Thank you, Nekyo!)
+        - 2022-04-29 fixes deprecation in recent Numpy
         
 Platform: UNKNOWN
 Classifier: Development Status :: 4 - Beta
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/SoundCard.egg-info/SOURCES.txt 
new/SoundCard-0.4.2/SoundCard.egg-info/SOURCES.txt
--- old/SoundCard-0.4.1/SoundCard.egg-info/SOURCES.txt  2021-03-14 
13:40:57.000000000 +0100
+++ new/SoundCard-0.4.2/SoundCard.egg-info/SOURCES.txt  2022-05-09 
16:02:36.000000000 +0200
@@ -1,11 +1,21 @@
+.gitignore
+LICENSE
+Pipfile
 README.rst
+readthedocs.yml
 setup.py
+test_soundcard.py
 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
+doc/Makefile
+doc/conf.py
+doc/index.rst
+doc/make.bat
+doc/requirements.txt
 soundcard/__init__.py
 soundcard/coreaudio.py
 soundcard/coreaudio.py.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/SoundCard.egg-info/requires.txt 
new/SoundCard-0.4.2/SoundCard.egg-info/requires.txt
--- old/SoundCard-0.4.1/SoundCard.egg-info/requires.txt 2021-03-14 
13:40:57.000000000 +0100
+++ new/SoundCard-0.4.2/SoundCard.egg-info/requires.txt 2022-05-09 
16:02:36.000000000 +0200
@@ -1,2 +1,2 @@
-numpy
 cffi
+numpy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/doc/Makefile 
new/SoundCard-0.4.2/doc/Makefile
--- old/SoundCard-0.4.1/doc/Makefile    1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.2/doc/Makefile    2022-05-09 15:57:27.000000000 +0200
@@ -0,0 +1,19 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+SOURCEDIR     = .
+BUILDDIR      = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+       @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+       @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/doc/conf.py 
new/SoundCard-0.4.2/doc/conf.py
--- old/SoundCard-0.4.1/doc/conf.py     1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.2/doc/conf.py     2022-05-09 15:57:27.000000000 +0200
@@ -0,0 +1,193 @@
+# -*- coding: utf-8 -*-
+#
+# Configuration file for the Sphinx documentation builder.
+#
+# This file does only contain a selection of the most common options. For a
+# full list see the documentation:
+# http://www.sphinx-doc.org/en/master/config
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import os
+import sys
+sys.path.insert(0, os.path.abspath('..'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'SoundCard'
+copyright = '2018, Bastian Bechtold'
+author = 'Bastian Bechtold'
+
+# The short X.Y version
+version = ''
+# The full version, including alpha/beta/rc tags
+release = '0.2.0'
+
+
+# -- General configuration ---------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.imgmath',
+    'sphinx.ext.viewcode',
+    'sphinx.ext.napoleon',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = None
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'alabaster'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# The default sidebars (for documents that don't match any pattern) are
+# defined by theme itself.  Builtin themes are using these templates by
+# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
+# 'searchbox.html']``.
+#
+# html_sidebars = {}
+
+
+# -- Options for HTMLHelp output ---------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'SoundCarddoc'
+
+
+# -- Options for LaTeX output ------------------------------------------------
+
+latex_elements = {
+    # The paper size ('letterpaper' or 'a4paper').
+    #
+    # 'papersize': 'letterpaper',
+
+    # The font size ('10pt', '11pt' or '12pt').
+    #
+    # 'pointsize': '10pt',
+
+    # Additional stuff for the LaTeX preamble.
+    #
+    # 'preamble': '',
+
+    # Latex figure (float) alignment
+    #
+    # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+    (master_doc, 'SoundCard.tex', 'SoundCard Documentation',
+     'Bastian Bechtold', 'manual'),
+]
+
+
+# -- Options for manual page output ------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    (master_doc, 'soundcard', 'SoundCard Documentation',
+     [author], 1)
+]
+
+
+# -- Options for Texinfo output ----------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+    (master_doc, 'SoundCard', 'SoundCard Documentation',
+     author, 'SoundCard', 'One line description of project.',
+     'Miscellaneous'),
+]
+
+
+# -- Options for Epub output -------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = project
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#
+# epub_identifier = ''
+
+# A unique identification for the text.
+#
+# epub_uid = ''
+
+# A list of files that should not be packed into the epub file.
+epub_exclude_files = ['search.html']
+
+
+# -- Extension configuration -------------------------------------------------
+
+from mock import Mock as MagicMock
+
+class Mock(MagicMock):
+    @classmethod
+    def __getattr__(cls, name):
+        return Mock()
+
+    def __eq__(self, other):
+        # so _pa_context_get_state() == PA_CONTEXT_READY
+        return isinstance(other, Mock)
+
+sys.modules.update({'cffi': Mock()})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/doc/index.rst 
new/SoundCard-0.4.2/doc/index.rst
--- old/SoundCard-0.4.1/doc/index.rst   1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.2/doc/index.rst   2022-05-09 15:57:27.000000000 +0200
@@ -0,0 +1,76 @@
+.. SoundCard documentation master file, created by
+   sphinx-quickstart on Tue Nov 27 16:22:51 2018.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+.. include:: ../README.rst
+
+.. default-role::
+
+API Documentation
+=================
+
+The following functions are your entry point to the SoundCard library.
+All of them return instances of :class:`soundcard._Speaker` or
+:class:`soundcard._Microphone`. These are lightweight objects that
+reference a sound card, but don't do any actual work.
+
+Since audio hardware can change frequently when new audio devices are
+plugged in or out, it is a good idea to always retrieve new instances
+of :class:`soundcard._Speaker` and :class:`soundcard._Microphone`
+instead of keeping old references around for a long time.
+
+.. automodule:: soundcard
+   :imported-members:
+   :members:
+   :undoc-members:
+
+Sound Card Handles
+------------------
+
+The following classes are lightweight references to sound cards. They
+are not meant to be constructed by hand, but are returned by
+:func:`default_speaker`, :func:`get_speaker`, :func:`all_speakers`,
+:func:`default_microphone`, :func:`get_microphone`,
+:func:`all_microphones`.
+
+The real work of interfacing with the hardware and playing or
+recording audio is delegated to the :class:`_Player` and
+:class:`_Recorder` objects, which are created by
+:func:`_Speaker.play`, :func:`_Speaker.player`,
+:func:`_Microphone.record`, and :func:`_Microphone.recorder`.
+
+.. autoclass:: soundcard._Speaker
+   :members:
+   :inherited-members:
+   :undoc-members:
+
+.. autoclass:: soundcard._Microphone
+   :members:
+   :inherited-members:
+   :undoc-members:
+
+Sound Streams
+-------------
+
+The following classes are the context managers that do the heavy
+lifting of interacting with the backend drivers and sound cards. They
+are not meant to be constructed by hand, but are returned by
+:func:`_Speaker.player`, and :func:`_Microphone.recorder`.
+
+.. autoclass:: soundcard._Player
+   :members:
+   :inherited-members:
+   :undoc-members:
+
+.. autoclass:: soundcard._Recorder
+   :members:
+   :inherited-members:
+   :undoc-members:
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/doc/make.bat 
new/SoundCard-0.4.2/doc/make.bat
--- old/SoundCard-0.4.1/doc/make.bat    1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.2/doc/make.bat    2022-05-09 15:57:27.000000000 +0200
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+       set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+       echo.
+       echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+       echo.installed, then set the SPHINXBUILD environment variable to point
+       echo.to the full path of the 'sphinx-build' executable. Alternatively 
you
+       echo.may add the Sphinx directory to PATH.
+       echo.
+       echo.If you don't have Sphinx installed, grab it from
+       echo.http://sphinx-doc.org/
+       exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+
+:end
+popd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/doc/requirements.txt 
new/SoundCard-0.4.2/doc/requirements.txt
--- old/SoundCard-0.4.1/doc/requirements.txt    1970-01-01 01:00:00.000000000 
+0100
+++ new/SoundCard-0.4.2/doc/requirements.txt    2022-05-09 15:57:27.000000000 
+0200
@@ -0,0 +1,2 @@
+cffi
+numpy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/readthedocs.yml 
new/SoundCard-0.4.2/readthedocs.yml
--- old/SoundCard-0.4.1/readthedocs.yml 1970-01-01 01:00:00.000000000 +0100
+++ new/SoundCard-0.4.2/readthedocs.yml 2022-05-09 15:57:27.000000000 +0200
@@ -0,0 +1,11 @@
+build:
+  image: latest
+
+python:
+  version: 3.6
+
+requirements_file: doc/requirements.txt
+
+formats:
+  - epub
+  - pdf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/setup.py new/SoundCard-0.4.2/setup.py
--- old/SoundCard-0.4.1/setup.py        2021-03-14 13:32:12.000000000 +0100
+++ new/SoundCard-0.4.2/setup.py        2022-05-09 16:02:03.000000000 +0200
@@ -2,7 +2,7 @@
 
 setup(
     name='SoundCard',
-    version='0.4.1',
+    version='0.4.2',
     description='Play and record audio without resorting to CPython 
extensions',
     author='Bastian Bechtold',
     url='https://github.com/bastibe/SoundCard',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/soundcard/coreaudio.py 
new/SoundCard-0.4.2/soundcard/coreaudio.py
--- old/SoundCard-0.4.1/soundcard/coreaudio.py  2021-03-14 13:30:27.000000000 
+0100
+++ new/SoundCard-0.4.2/soundcard/coreaudio.py  2022-05-09 15:57:27.000000000 
+0200
@@ -465,7 +465,7 @@
                             .format(self.blocksizerange[0],
                                     maxblocksize))
 
-        if isinstance(channels, collections.Iterable):
+        if isinstance(channels, collections.abc.Iterable):
             if iotype == 'output':
                 # invert channel map and fill with -1 ([2, 0] -> [1, -1, 0]):
                 self.channels = len([c for c in channels if c >= 0])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/soundcard/mediafoundation.py 
new/SoundCard-0.4.2/soundcard/mediafoundation.py
--- old/SoundCard-0.4.1/soundcard/mediafoundation.py    2021-03-14 
13:30:27.000000000 +0100
+++ new/SoundCard-0.4.2/soundcard/mediafoundation.py    2022-05-09 
15:57:27.000000000 +0200
@@ -487,7 +487,7 @@
 
         if isinstance(channels, int):
             self.channelmap = list(range(channels))
-        elif isinstance(channels, collections.Iterable):
+        elif isinstance(channels, collections.abc.Iterable):
             self.channelmap = channels
         else:
             raise TypeError('channels must be iterable or integer')
@@ -772,7 +772,7 @@
                 recorded_data.append(chunk)
                 recorded_frames += len(chunk)
             if recorded_frames > required_frames:
-                to_split = -(recorded_frames-required_frames)
+                to_split = -int(recorded_frames-required_frames)
                 recorded_data[-1], self._pending_chunk = 
numpy.split(recorded_data[-1], [to_split])
 
         data = numpy.reshape(numpy.concatenate(recorded_data), [-1, 
len(set(self.channelmap))])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/soundcard/pulseaudio.py 
new/SoundCard-0.4.2/soundcard/pulseaudio.py
--- old/SoundCard-0.4.1/soundcard/pulseaudio.py 2021-03-14 13:30:27.000000000 
+0100
+++ new/SoundCard-0.4.2/soundcard/pulseaudio.py 2022-05-09 15:57:27.000000000 
+0200
@@ -13,8 +13,12 @@
 with open(os.path.join(_package_dir, 'pulseaudio.py.h'), 'rt') as f:
     _ffi.cdef(f.read())
 
-_pa = _ffi.dlopen('pulse')
-
+try:
+    _pa = _ffi.dlopen('pulse')
+except OSError:
+    # Try explicit file name, if the general does not work (e.g. on nixos)
+    _pa = _ffi.dlopen('libpulse.so')
+    
 # First, we need to define a global _PulseAudio proxy for interacting
 # with the C API:
 
@@ -635,7 +639,7 @@
         samplespec = _ffi.new("pa_sample_spec*")
         samplespec.format = _pa.PA_SAMPLE_FLOAT32LE
         samplespec.rate = self._samplerate
-        if isinstance(self.channels, collections.Iterable):
+        if isinstance(self.channels, collections.abc.Iterable):
             samplespec.channels = len(self.channels)
         elif isinstance(self.channels, int):
             samplespec.channels = self.channels
@@ -648,7 +652,7 @@
         # names to avoid garbage collection trouble on the Python/C boundary
         pam = _ffi.new("pa_channel_map*")
         channelmap = _pa.pa_channel_map_init_auto(pam, samplespec.channels, 
_pa.PA_CHANNEL_MAP_DEFAULT)
-        if isinstance(self.channels, collections.Iterable):
+        if isinstance(self.channels, collections.abc.Iterable):
             for idx, ch in enumerate(self.channels):
                 channelmap.map[idx] = ch+1
         if not _pa.pa_channel_map_valid(channelmap):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SoundCard-0.4.1/test_soundcard.py 
new/SoundCard-0.4.2/test_soundcard.py
--- old/SoundCard-0.4.1/test_soundcard.py       1970-01-01 01:00:00.000000000 
+0100
+++ new/SoundCard-0.4.2/test_soundcard.py       2022-05-09 15:57:27.000000000 
+0200
@@ -0,0 +1,159 @@
+import sys
+import soundcard
+import numpy
+import pytest
+
+skip_if_not_linux = pytest.mark.skipif(sys.platform != 'linux', reason='Only 
implemented for PulseAudio so far')
+
+ones = numpy.ones(1024)
+signal = numpy.concatenate([[ones], [-ones]]).T
+
+def test_speakers():
+    for speaker in soundcard.all_speakers():
+        assert isinstance(speaker.name, str)
+        assert hasattr(speaker, 'id')
+        assert isinstance(speaker.channels, int)
+        assert speaker.channels > 0
+
+def test_microphones():
+    for microphone in soundcard.all_microphones():
+        assert isinstance(microphone.name, str)
+        assert hasattr(microphone, 'id')
+        assert isinstance(microphone.channels, int)
+        assert microphone.channels > 0
+
+def test_default_playback():
+    soundcard.default_speaker().play(signal, 44100, channels=2)
+
+def test_default_record():
+    recording = soundcard.default_microphone().record(1024, 44100)
+    assert len(recording == 1024)
+
+def test_default_blockless_record():
+    recording = soundcard.default_microphone().record(None, 44100)
+
+@skip_if_not_linux
+def test_name():
+    # The default is the application name, so when run from pytest,
+    # it???s ???pytest??? or ???_jb_pytest_runner.py??? or so.
+    assert 'pytest' in soundcard.get_name()
+    soundcard.set_name('testapp')
+    assert soundcard.get_name() == 'testapp'
+
+@skip_if_not_linux
[email protected]("argv,progname", [
+    (["./script.py"], "script.py"),  # chmod +x script.py; ./script.py
+    (["path/to/script.py"], "script.py"),  # python path/to/script.py or
+                                           # python -m path.to.script
+    (["module/__main__.py"], "module"),  # python -m module
+    (["-m", "module.submodule"], "module.submodule"),  # rare unresolved case
+    (["-c", "import soundcard; soundcard.foo()"], "import soundcard; 
soundcard.fo..."),
+])
+def test_infer_name(monkeypatch, argv, progname):
+    infer = soundcard.pulseaudio._PulseAudio._infer_program_name
+    monkeypatch.setattr(sys, "argv", argv)
+    assert infer() == progname
+
[email protected]
+def loopback_speaker():
+    import sys
+    if sys.platform == 'win32':
+        # must install https://www.vb-audio.com/Cable/index.htm
+        return soundcard.get_speaker('Cable')
+    elif sys.platform == 'darwin':
+        # must install soundflower
+        return soundcard.get_speaker('Soundflower64')
+    elif sys.platform == 'linux':
+        # pacmd load-module module-null-sink channels=6 rate=48000
+        return soundcard.get_speaker('Null')
+    else:
+        raise RuntimeError('Unknown platform {}'.format(sys.platform))
+
[email protected]
+def loopback_player(loopback_speaker):
+    with loopback_speaker.player(48000, channels=2, blocksize=512) as player:
+        yield player
+
[email protected]
+def loopback_microphone():
+    if sys.platform == 'win32':
+        # must install https://www.vb-audio.com/Cable/index.htm
+        return soundcard.get_microphone('Cable')
+    elif sys.platform == 'darwin':
+        # must install soundflower
+        return soundcard.get_microphone('Soundflower64')
+    elif sys.platform == 'linux':
+        return soundcard.get_microphone('Null', include_loopback=True)
+    else:
+        raise RuntimeError('Unknown platform {}'.format(sys.platform))
+
[email protected]
+def loopback_recorder(loopback_microphone):
+    with loopback_microphone.recorder(48000, channels=2, blocksize=512) as 
recorder:
+        yield recorder
+
+def test_loopback_playback(loopback_player, loopback_recorder):
+    loopback_player.play(signal)
+    recording = loopback_recorder.record(1024*10)
+    assert recording.shape[1] == 2
+    left, right = recording.T
+    assert left.mean() > 0
+    assert right.mean() < 0
+    assert (left > 0.5).sum() == len(signal)
+    assert (right < -0.5).sum() == len(signal)
+
+def test_loopback_reverse_recorder_channelmap(loopback_player, 
loopback_microphone):
+    with loopback_microphone.recorder(48000, channels=[1, 0], blocksize=512) 
as loopback_recorder:
+        loopback_player.play(signal)
+        recording = loopback_recorder.record(1024*12)
+    assert recording.shape[1] == 2
+    left, right = recording.T
+    assert right.mean() > 0
+    assert left.mean() < 0
+    assert (right > 0.5).sum() == len(signal)
+    assert (left < -0.5).sum() == len(signal)
+
+def test_loopback_reverse_player_channelmap(loopback_speaker, 
loopback_recorder):
+    with loopback_speaker.player(48000, channels=[1, 0], blocksize=512) as 
loopback_player:
+        loopback_player.play(signal)
+        recording = loopback_recorder.record(1024*12)
+    assert recording.shape[1] == 2
+    left, right = recording.T
+    assert right.mean() > 0
+    assert left.mean() < 0
+    assert (right > 0.5).sum() == len(signal)
+    assert (left < -0.5).sum() == len(signal)
+
+def test_loopback_mono_player_channelmap(loopback_speaker, loopback_recorder):
+    with loopback_speaker.player(48000, channels=[0], blocksize=512) as 
loopback_player:
+        loopback_player.play(signal[:,0])
+        recording = loopback_recorder.record(1024*12)
+    assert recording.shape[1] == 2
+    left, right = recording.T
+    assert left.mean() > 0
+    if sys.platform == 'linux':
+        # unmapped channels on linux are filled with the mean of other channels
+        assert right.mean() < left.mean()
+    else:
+        assert abs(right.mean()) < 0.01 # something like zero
+    assert (left > 0.5).sum() == len(signal)
+
+def test_loopback_mono_recorder_channelmap(loopback_player, 
loopback_microphone):
+    with loopback_microphone.recorder(48000, channels=[0], blocksize=512) as 
loopback_recorder:
+        loopback_player.play(signal)
+        recording = loopback_recorder.record(1024*12)
+    assert len(recording.shape) == 1 or recording.shape[1] == 1
+    assert recording.mean() > 0
+    assert (recording > 0.5).sum() == len(signal)
+
+def test_loopback_multichannel_channelmap(loopback_speaker, 
loopback_microphone):
+    with loopback_speaker.player(48000, channels=[2, 0], blocksize=512) as 
loopback_player:
+        with loopback_microphone.recorder(48000, channels=[2, 0], 
blocksize=512) as loopback_recorder:
+            loopback_player.play(signal)
+            recording = loopback_recorder.record(1024*12)
+    assert len(recording.shape) == 2
+    left, right = recording.T
+    assert left.mean() > 0
+    assert right.mean() < 0
+    assert (left > 0.5).sum() == len(signal)
+    assert (right < -0.5).sum() == len(signal)

Reply via email to