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)