pax_global_header00006660000000000000000000000064146537646660014541gustar00rootroot0000000000000052 comment=7f415a8a591473653679a005581638cd3f203b3e audioop-0.2.1/000077500000000000000000000000001465376466600132015ustar00rootroot00000000000000audioop-0.2.1/.devcontainer/000077500000000000000000000000001465376466600157405ustar00rootroot00000000000000audioop-0.2.1/.devcontainer/devcontainer.json000066400000000000000000000005161465376466600213160ustar00rootroot00000000000000{ "image": "python:3.13-rc-bookworm", "customizations": { "vscode": { "extensions": [ "ms-python.python", "ms-python.vscode-pylance", "ms-vscode.cpptools", "twxs.cmake", "ms-vscode.cmake-tools" ] } } } audioop-0.2.1/.github/000077500000000000000000000000001465376466600145415ustar00rootroot00000000000000audioop-0.2.1/.github/dependabot.yaml000066400000000000000000000001661465376466600175350ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" audioop-0.2.1/.github/workflows/000077500000000000000000000000001465376466600165765ustar00rootroot00000000000000audioop-0.2.1/.github/workflows/build-ci.yaml000066400000000000000000000045721465376466600211620ustar00rootroot00000000000000name: Build on: push: branches: - main tags: - "*.*.*" pull_request: branches: - main types: [opened, reopened, synchronize] jobs: build_wheels: name: Build wheels on ${{ matrix.os }} [${{ matrix.archs }}] runs-on: ${{ matrix.os }} strategy: matrix: include: # macOS Intel & ARM - os: macos-latest archs: all # Windows x86 32-bit and 64-bit - os: windows-latest archs: auto # Windows ARM - os: windows-latest archs: ARM64 # Linux x86 32-bit and 64-bit - os: ubuntu-latest archs: auto # Linux aarch64 - os: ubuntu-latest archs: aarch64 # Linux ppc64le - os: ubuntu-latest archs: ppc64le # Linux s390x - os: ubuntu-latest archs: s390x steps: - uses: actions/checkout@v4 - name: Set up QEMU if: runner.os == 'Linux' uses: docker/setup-qemu-action@v3 with: platforms: all - name: Build wheels uses: pypa/cibuildwheel@v2.20.0 env: CIBW_BUILD: "cp313-* cp3*t-*" CIBW_ARCHS: ${{ matrix.archs }} CIBW_FREE_THREADED_SUPPORT: true - uses: actions/upload-artifact@v4 with: name: artifact-cibw-wheels-${{ matrix.os }}-${{ matrix.archs }}-${{ strategy.job-index }} path: ./wheelhouse/*.whl make-sdist: name: Make source distribution runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: pipx run build --sdist - uses: actions/upload-artifact@v4 with: name: artifact-source-dist path: "./**/dist/*.tar.gz" upload_pypi: if: github.event_name == 'push' && github.ref_type == 'tag' name: Publish built wheels to Pypi runs-on: ubuntu-latest environment: release needs: [make-sdist, build_wheels] permissions: id-token: write steps: - uses: actions/download-artifact@v4 - name: Copy artifacts to dist/ folder run: | find . -name 'artifact-*' -exec unzip '{}' \; mkdir -p dist/ find . -name '*.tar.gz' -exec mv '{}' dist/ \; find . -name '*.whl' -exec mv '{}' dist/ \; - uses: pypa/gh-action-pypi-publish@release/v1 name: Publish to PyPI audioop-0.2.1/.gitignore000066400000000000000000000000771465376466600151750ustar00rootroot00000000000000.venv/ .12-venv/ .py[cod] build/ dist/ *.egg-info/ __pycache__/audioop-0.2.1/.vscode/000077500000000000000000000000001465376466600145425ustar00rootroot00000000000000audioop-0.2.1/.vscode/c_cpp_properties.json000066400000000000000000000007211465376466600207750ustar00rootroot00000000000000{ "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**", "/usr/local/include/python3.13", "/usr/include/python3.13" ], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "c17", "cppStandard": "gnu++17", "intelliSenseMode": "linux-gcc-x64" } ], "version": 4 }audioop-0.2.1/LICENSE000066400000000000000000000331601465376466600142110ustar00rootroot00000000000000A. HISTORY OF THE SOFTWARE ========================== Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI, see https://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others. In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see https://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software. In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations, which became Zope Corporation. In 2001, the Python Software Foundation (PSF, see https://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation was a sponsoring member of the PSF. All Python releases are Open Source (see https://opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. Release Derived Year Owner GPL- from compatible? (1) 0.9.0 thru 1.2 1991-1995 CWI yes 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes 1.6 1.5.2 2000 CNRI no 2.0 1.6 2000 BeOpen.com no 1.6.1 1.6 2001 CNRI yes (2) 2.1 2.0+1.6.1 2001 PSF no 2.0.1 2.0+1.6.1 2001 PSF yes 2.1.1 2.1+2.0.1 2001 PSF yes 2.1.2 2.1.1 2002 PSF yes 2.1.3 2.1.2 2002 PSF yes 2.2 and above 2.1.1 2001-now PSF yes Footnotes: (1) GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't. (2) According to Richard Stallman, 1.6.1 is not GPL-compatible, because its license has a choice of law clause. According to CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 is "not incompatible" with the GPL. Thanks to the many outside volunteers who have worked under Guido's direction to make these releases possible. B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON =============================================================== Python software and documentation are licensed under the Python Software Foundation License Version 2. Starting with Python 3.8.6, examples, recipes, and other code in the documentation are dual licensed under the PSF License Version 2 and the Zero-Clause BSD license. Some software incorporated into Python is under different licenses. The licenses are listed with code falling under that license. PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -------------------------------------------- 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python. 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement. BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 ------------------------------------------- BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization ("Licensee") accessing and otherwise using this software in source or binary form and its associated documentation ("the Software"). 2. Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee. 3. BeOpen is making the Software available to Licensee on an "AS IS" basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 5. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 6. This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conflict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the "BeOpen Python" logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page. 7. By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement. CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 --------------------------------------- 1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) 1995-2001 Corporation for National Research Initiatives; All Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the internet using the following URL: http://hdl.handle.net/1895.22/1013". 3. In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1. 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. This License Agreement shall be governed by the federal intellectual property law of the United States, including without limitation the federal copyright law, and, to the extent such U.S. federal law does not apply, by the law of the Commonwealth of Virginia, excluding Virginia's conflict of law provisions. Notwithstanding the foregoing, with regard to derivative works based on Python 1.6.1 that incorporate non-separable material that was previously distributed under the GNU General Public License (GPL), the law of the Commonwealth of Virginia shall govern this License Agreement only as to issues arising under or with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By clicking on the "ACCEPT" button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. ACCEPT CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 -------------------------------------------------- Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION ---------------------------------------------------------------------- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. audioop-0.2.1/README.md000066400000000000000000000020121465376466600144530ustar00rootroot00000000000000# audioop An LTS port of the Python builtin module `audioop` which was deprecated since version 3.11 and removed in 3.13. This project exists to maintain this module for future versions. ## Using this project As this only becomes mandatory at Python versions of 3.13 or greater, you can conditionally add this project to your dependencies: ### pip-requirements ``` audioop-lts; python_version>='3.13' ``` ### Poetry-pyproject ```toml [tool.poetry.dependencies] audioop-lts = { version = "...", python = "^3.13" } ``` Relevant documtation is [here](https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies), or alternatively use [`markers`](https://python-poetry.org/docs/dependency-specification/#using-environment-markers) ### Pipenv-pipfile ```toml [packages] audioop-lts = { version = "...", markers = "python_version >= 3.13" } ``` ### Hatch-pyproject ```toml [project] dependencies = [ "audioop-lts; python_version >= '3.13'" # or "audioop-lts==...; python_version >= '3.13'" ] audioop-0.2.1/audioop/000077500000000000000000000000001465376466600146415ustar00rootroot00000000000000audioop-0.2.1/audioop/__init__.py000066400000000000000000000013671465376466600167610ustar00rootroot00000000000000from ._audioop import ( error, add, adpcm2lin, alaw2lin, avg, avgpp, bias, byteswap, cross, findfactor, findfit, findmax, getsample, lin2adpcm, lin2alaw, lin2lin, lin2ulaw, max, maxpp, minmax, mul, ratecv, reverse, rms, tomono, tostereo, ulaw2lin, ) __all__ = ( "error", "add", "adpcm2lin", "alaw2lin", "avg", "avgpp", "bias", "byteswap", "cross", "findfactor", "findfit", "findmax", "getsample", "lin2adpcm", "lin2alaw", "lin2lin", "lin2ulaw", "max", "maxpp", "minmax", "mul", "ratecv", "reverse", "rms", "tomono", "tostereo", "ulaw2lin", ) audioop-0.2.1/audioop/__init__.pyi000066400000000000000000000041321465376466600171230ustar00rootroot00000000000000from collections.abc import Buffer from typing import TypeAlias _AdpcmState: TypeAlias = tuple[int, int] _RatecvState: TypeAlias = tuple[int, tuple[tuple[int, int], ...]] class error(Exception): ... def add(fragment1: Buffer, fragment2: Buffer, width: int, /) -> bytes: ... def adpcm2lin(fragment: Buffer, width: int, state: _AdpcmState | None, /) -> tuple[bytes, _AdpcmState]: ... def alaw2lin(fragment: Buffer, width: int, /) -> bytes: ... def avg(fragment: Buffer, width: int, /) -> int: ... def avgpp(fragment: Buffer, width: int, /) -> int: ... def bias(fragment: Buffer, width: int, bias: int, /) -> bytes: ... def byteswap(fragment: Buffer, width: int, /) -> bytes: ... def cross(fragment: Buffer, width: int, /) -> int: ... def findfactor(fragment: Buffer, reference: Buffer, /) -> float: ... def findfit(fragment: Buffer, reference: Buffer, /) -> tuple[int, float]: ... def findmax(fragment: Buffer, length: int, /) -> int: ... def getsample(fragment: Buffer, width: int, index: int, /) -> int: ... def lin2adpcm(fragment: Buffer, width: int, state: _AdpcmState | None, /) -> tuple[bytes, _AdpcmState]: ... def lin2alaw(fragment: Buffer, width: int, /) -> bytes: ... def lin2lin(fragment: Buffer, width: int, newwidth: int, /) -> bytes: ... def lin2ulaw(fragment: Buffer, width: int, /) -> bytes: ... def max(fragment: Buffer, width: int, /) -> int: ... def maxpp(fragment: Buffer, width: int, /) -> int: ... def minmax(fragment: Buffer, width: int, /) -> tuple[int, int]: ... def mul(fragment: Buffer, width: int, factor: float, /) -> bytes: ... def ratecv( fragment: Buffer, width: int, nchannels: int, inrate: int, outrate: int, state: _RatecvState | None, weightA: int = 1, weightB: int = 0, /, ) -> tuple[bytes, _RatecvState]: ... def reverse(fragment: Buffer, width: int, /) -> bytes: ... def rms(fragment: Buffer, width: int, /) -> int: ... def tomono(fragment: Buffer, width: int, lfactor: float, rfactor: float, /) -> bytes: ... def tostereo(fragment: Buffer, width: int, lfactor: float, rfactor: float, /) -> bytes: ... def ulaw2lin(fragment: Buffer, width: int, /) -> bytes: ... audioop-0.2.1/audioop/_audioop.c000066400000000000000000001703251465376466600166140ustar00rootroot00000000000000/* The audioop module uses the code base in g777.c file of the Sox project. Source: https://sourceforge.net/projects/sox/files/sox/12.17.7/sox-12.17.7.tar.gz Copyright of g771.c: * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* audioopmodule - Module to detect peak values in arrays */ #define PY_SSIZE_T_CLEAN #include "Python.h" #define _LTS_Py_SETREF(op, op2) \ do { \ PyObject *_py_tmp = (PyObject *)(op); \ (op) = (op2); \ Py_DECREF(_py_tmp); \ } while (0) static const int maxvals[] = {0, 0x7F, 0x7FFF, 0x7FFFFF, 0x7FFFFFFF}; /* -1 trick is needed on Windows to support -0x80000000 without a warning */ static const int minvals[] = {0, -0x80, -0x8000, -0x800000, -0x7FFFFFFF-1}; static const unsigned int masks[] = {0, 0xFF, 0xFFFF, 0xFFFFFF, 0xFFFFFFFF}; static int fbound(double val, double minval, double maxval) { if (val > maxval) { val = maxval; } else if (val < minval + 1.0) { val = minval; } /* Round towards minus infinity (-inf) */ val = floor(val); /* Cast double to integer: round towards zero */ return (int)val; } #define BIAS 0x84 /* define the add-in bias for 16 bit samples */ #define CLIP 32635 #define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */ static const int16_t seg_aend[8] = { 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF }; static const int16_t seg_uend[8] = { 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF }; static int16_t search(int16_t val, const int16_t *table, int size) { assert(0 <= size); assert(size < INT16_MAX); int i; for (i = 0; i < size; i++) { if (val <= *table++) return (i); } return (size); } #define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc]) #define st_alaw2linear16(uc) (_st_alaw2linear16[uc]) static const int16_t _st_ulaw2linear16[256] = { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, -876, -844, -812, -780, -748, -716, -684, -652, -620, -588, -556, -524, -492, -460, -428, -396, -372, -356, -340, -324, -308, -292, -276, -260, -244, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0, 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 876, 844, 812, 780, 748, 716, 684, 652, 620, 588, 556, 524, 492, 460, 428, 396, 372, 356, 340, 324, 308, 292, 276, 260, 244, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 }; /* * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 14-bits. * * In order to simplify the encoding process, the original linear magnitude * is biased by adding 33 which shifts the encoding range from (0 - 8158) to * (33 - 8191). The result can be seen in the following encoding table: * * Biased Linear Input Code Compressed Code * ------------------------ --------------- * 00000001wxyza 000wxyz * 0000001wxyzab 001wxyz * 000001wxyzabc 010wxyz * 00001wxyzabcd 011wxyz * 0001wxyzabcde 100wxyz * 001wxyzabcdef 101wxyz * 01wxyzabcdefg 110wxyz * 1wxyzabcdefgh 111wxyz * * Each biased linear code has a leading 1 which identifies the segment * number. The value of the segment number is equal to 7 minus the number * of leading 0's. The quantization interval is directly available as the * four bits wxyz. * The trailing bits (a - h) are ignored. * * Ordinarily the complement of the resulting code word is used for * transmission, and so the code word is complemented before it is returned. * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */ static unsigned char st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */ { int16_t mask; int16_t seg; unsigned char uval; /* u-law inverts all bits */ /* Get the sign and the magnitude of the value. */ if (pcm_val < 0) { pcm_val = -pcm_val; mask = 0x7F; } else { mask = 0xFF; } if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */ pcm_val += (BIAS >> 2); /* Convert the scaled magnitude to segment number. */ seg = search(pcm_val, seg_uend, 8); /* * Combine the sign, segment, quantization bits; * and complement the code word. */ if (seg >= 8) /* out of range, return maximum value. */ return (unsigned char) (0x7F ^ mask); else { assert(seg >= 0); uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); return (uval ^ mask); } } static const int16_t _st_alaw2linear16[256] = { -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848 }; /* * linear2alaw() accepts a 13-bit signed integer and encodes it as A-law data * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 13-bits. * * Linear Input Code Compressed Code * ------------------------ --------------- * 0000000wxyza 000wxyz * 0000001wxyza 001wxyz * 000001wxyzab 010wxyz * 00001wxyzabc 011wxyz * 0001wxyzabcd 100wxyz * 001wxyzabcde 101wxyz * 01wxyzabcdef 110wxyz * 1wxyzabcdefg 111wxyz * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */ static unsigned char st_linear2alaw(int16_t pcm_val) /* 2's complement (13-bit range) */ { int16_t mask; int16_t seg; unsigned char aval; /* A-law using even bit inversion */ if (pcm_val >= 0) { mask = 0xD5; /* sign (7th) bit = 1 */ } else { mask = 0x55; /* sign bit = 0 */ pcm_val = -pcm_val - 1; } /* Convert the scaled magnitude to segment number. */ seg = search(pcm_val, seg_aend, 8); /* Combine the sign, segment, and quantization bits. */ if (seg >= 8) /* out of range, return maximum value. */ return (unsigned char) (0x7F ^ mask); else { aval = (unsigned char) seg << SEG_SHIFT; if (seg < 2) aval |= (pcm_val >> 1) & QUANT_MASK; else aval |= (pcm_val >> seg) & QUANT_MASK; return (aval ^ mask); } } /* End of code taken from sox */ /* Intel ADPCM step variation table */ static const int indexTable[16] = { -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8, }; static const int stepsizeTable[89] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 }; #define GETINTX(T, cp, i) (*(T *)((unsigned char *)(cp) + (i))) #define SETINTX(T, cp, i, val) do { \ *(T *)((unsigned char *)(cp) + (i)) = (T)(val); \ } while (0) #define GETINT8(cp, i) GETINTX(signed char, (cp), (i)) #define GETINT16(cp, i) GETINTX(int16_t, (cp), (i)) #define GETINT32(cp, i) GETINTX(int32_t, (cp), (i)) #ifdef WORDS_BIGENDIAN #define GETINT24(cp, i) ( \ ((unsigned char *)(cp) + (i))[2] + \ (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ (((signed char *)(cp) + (i))[0] * (1 << 16)) ) #else #define GETINT24(cp, i) ( \ ((unsigned char *)(cp) + (i))[0] + \ (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ (((signed char *)(cp) + (i))[2] * (1 << 16)) ) #endif #define SETINT8(cp, i, val) SETINTX(signed char, (cp), (i), (val)) #define SETINT16(cp, i, val) SETINTX(int16_t, (cp), (i), (val)) #define SETINT32(cp, i, val) SETINTX(int32_t, (cp), (i), (val)) #ifdef WORDS_BIGENDIAN #define SETINT24(cp, i, val) do { \ ((unsigned char *)(cp) + (i))[2] = (int)(val); \ ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \ ((signed char *)(cp) + (i))[0] = (int)(val) >> 16; \ } while (0) #else #define SETINT24(cp, i, val) do { \ ((unsigned char *)(cp) + (i))[0] = (int)(val); \ ((unsigned char *)(cp) + (i))[1] = (int)(val) >> 8; \ ((signed char *)(cp) + (i))[2] = (int)(val) >> 16; \ } while (0) #endif #define GETRAWSAMPLE(size, cp, i) ( \ (size == 1) ? (int)GETINT8((cp), (i)) : \ (size == 2) ? (int)GETINT16((cp), (i)) : \ (size == 3) ? (int)GETINT24((cp), (i)) : \ (int)GETINT32((cp), (i))) #define SETRAWSAMPLE(size, cp, i, val) do { \ if (size == 1) \ SETINT8((cp), (i), (val)); \ else if (size == 2) \ SETINT16((cp), (i), (val)); \ else if (size == 3) \ SETINT24((cp), (i), (val)); \ else \ SETINT32((cp), (i), (val)); \ } while(0) #define GETSAMPLE32(size, cp, i) ( \ (size == 1) ? (int)GETINT8((cp), (i)) * (1 << 24) : \ (size == 2) ? (int)GETINT16((cp), (i)) * (1 << 16) : \ (size == 3) ? (int)GETINT24((cp), (i)) * (1 << 8) : \ (int)GETINT32((cp), (i))) #define SETSAMPLE32(size, cp, i, val) do { \ if (size == 1) \ SETINT8((cp), (i), (val) >> 24); \ else if (size == 2) \ SETINT16((cp), (i), (val) >> 16); \ else if (size == 3) \ SETINT24((cp), (i), (val) >> 8); \ else \ SETINT32((cp), (i), (val)); \ } while(0) static PyModuleDef audioopmodule; typedef struct { PyObject *AudioopError; } audioop_state; static inline audioop_state * get_audioop_state(PyObject *module) { void *state = PyModule_GetState(module); assert(state != NULL); return (audioop_state *)state; } static int audioop_check_size(PyObject *module, int size) { if (size < 1 || size > 4) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Size should be 1, 2, 3 or 4"); return 0; } else return 1; } static int audioop_check_parameters(PyObject *module, Py_ssize_t len, int size) { if (!audioop_check_size(module, size)) return 0; if (len % size != 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, "not a whole number of frames"); return 0; } return 1; } /*[clinic input] module audioop [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fa8f6611be3591a]*/ /*[clinic input] audioop.getsample fragment: Py_buffer width: int index: Py_ssize_t / Return the value of sample index from the fragment. [clinic start generated code]*/ static PyObject * audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width, Py_ssize_t index) /*[clinic end generated code: output=8fe1b1775134f39a input=88edbe2871393549]*/ { int val; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; if (index < 0 || index >= fragment->len/width) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Index out of range"); return NULL; } val = GETRAWSAMPLE(width, fragment->buf, index*width); return PyLong_FromLong(val); } /*[clinic input] audioop.max fragment: Py_buffer width: int / Return the maximum of the absolute value of all samples in a fragment. [clinic start generated code]*/ static PyObject * audioop_max_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=e6c5952714f1c3f0 input=32bea5ea0ac8c223]*/ { Py_ssize_t i; unsigned int absval, max = 0; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; for (i = 0; i < fragment->len; i += width) { int val = GETRAWSAMPLE(width, fragment->buf, i); /* Cast to unsigned before negating. Unsigned overflow is well- defined, but signed overflow is not. */ if (val < 0) absval = (unsigned int)-(int64_t)val; else absval = val; if (absval > max) max = absval; } return PyLong_FromUnsignedLong(max); } /*[clinic input] audioop.minmax fragment: Py_buffer width: int / Return the minimum and maximum values of all samples in the sound fragment. [clinic start generated code]*/ static PyObject * audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=473fda66b15c836e input=89848e9b927a0696]*/ { Py_ssize_t i; /* -1 trick below is needed on Windows to support -0x80000000 without a warning */ int min = 0x7fffffff, max = -0x7FFFFFFF-1; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; for (i = 0; i < fragment->len; i += width) { int val = GETRAWSAMPLE(width, fragment->buf, i); if (val > max) max = val; if (val < min) min = val; } return Py_BuildValue("(ii)", min, max); } /*[clinic input] audioop.avg fragment: Py_buffer width: int / Return the average over all samples in the fragment. [clinic start generated code]*/ static PyObject * audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=4410a4c12c3586e6 input=1114493c7611334d]*/ { Py_ssize_t i; int avg; double sum = 0.0; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; for (i = 0; i < fragment->len; i += width) sum += GETRAWSAMPLE(width, fragment->buf, i); if (fragment->len == 0) avg = 0; else avg = (int)floor(sum / (double)(fragment->len/width)); return PyLong_FromLong(avg); } /*[clinic input] audioop.rms fragment: Py_buffer width: int / Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n). [clinic start generated code]*/ static PyObject * audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=1e7871c826445698 input=4cc57c6c94219d78]*/ { Py_ssize_t i; unsigned int res; double sum_squares = 0.0; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; for (i = 0; i < fragment->len; i += width) { double val = GETRAWSAMPLE(width, fragment->buf, i); sum_squares += val*val; } if (fragment->len == 0) res = 0; else res = (unsigned int)sqrt(sum_squares / (double)(fragment->len/width)); return PyLong_FromUnsignedLong(res); } static double _sum2(const int16_t *a, const int16_t *b, Py_ssize_t len) { Py_ssize_t i; double sum = 0.0; for( i=0; i n, and let all sums be over i from 0 to n-1. ** ** Now, for each j in {0..N-n} we compute a factor fj so that -fj*R matches A ** as good as possible, i.e. sum( (A[j+i]+fj*R[i])^2 ) is minimal. This ** equation gives fj = sum( A[j+i]R[i] ) / sum(R[i]^2). ** ** Next, we compute the relative distance between the original signal and ** the modified signal and minimize that over j: ** vj = sum( (A[j+i]-fj*R[i])^2 ) / sum( A[j+i]^2 ) => ** vj = ( sum(A[j+i]^2)*sum(R[i]^2) - sum(A[j+i]R[i])^2 ) / sum( A[j+i]^2 ) ** ** In the code variables correspond as follows: ** cp1 A ** cp2 R ** len1 N ** len2 n ** aj_m1 A[j-1] ** aj_lm1 A[j+n-1] ** sum_ri_2 sum(R[i]^2) ** sum_aij_2 sum(A[i+j]^2) ** sum_aij_ri sum(A[i+j]R[i]) ** ** sum_ri is calculated once, sum_aij_2 is updated each step and sum_aij_ri ** is completely recalculated each step. */ /*[clinic input] audioop.findfit fragment: Py_buffer reference: Py_buffer / Try to match reference as well as possible to a portion of fragment. [clinic start generated code]*/ static PyObject * audioop_findfit_impl(PyObject *module, Py_buffer *fragment, Py_buffer *reference) /*[clinic end generated code: output=5752306d83cbbada input=62c305605e183c9a]*/ { const int16_t *cp1, *cp2; Py_ssize_t len1, len2; Py_ssize_t j, best_j; double aj_m1, aj_lm1; double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor; if (fragment->len & 1 || reference->len & 1) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Strings should be even-sized"); return NULL; } cp1 = (const int16_t *)fragment->buf; len1 = fragment->len >> 1; cp2 = (const int16_t *)reference->buf; len2 = reference->len >> 1; if (len1 < len2) { PyErr_SetString(get_audioop_state(module)->AudioopError, "First sample should be longer"); return NULL; } sum_ri_2 = _sum2(cp2, cp2, len2); sum_aij_2 = _sum2(cp1, cp1, len2); sum_aij_ri = _sum2(cp1, cp2, len2); result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2; best_result = result; best_j = 0; for ( j=1; j<=len1-len2; j++) { aj_m1 = (double)cp1[j-1]; aj_lm1 = (double)cp1[j+len2-1]; sum_aij_2 = sum_aij_2 + aj_lm1*aj_lm1 - aj_m1*aj_m1; sum_aij_ri = _sum2(cp1+j, cp2, len2); result = (sum_ri_2*sum_aij_2 - sum_aij_ri*sum_aij_ri) / sum_aij_2; if ( result < best_result ) { best_result = result; best_j = j; } } factor = _sum2(cp1+best_j, cp2, len2) / sum_ri_2; return Py_BuildValue("(nf)", best_j, factor); } /* ** findfactor finds a factor f so that the energy in A-fB is minimal. ** See the comment for findfit for details. */ /*[clinic input] audioop.findfactor fragment: Py_buffer reference: Py_buffer / Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal. [clinic start generated code]*/ static PyObject * audioop_findfactor_impl(PyObject *module, Py_buffer *fragment, Py_buffer *reference) /*[clinic end generated code: output=14ea95652c1afcf8 input=816680301d012b21]*/ { const int16_t *cp1, *cp2; Py_ssize_t len; double sum_ri_2, sum_aij_ri, result; if (fragment->len & 1 || reference->len & 1) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Strings should be even-sized"); return NULL; } if (fragment->len != reference->len) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Samples should be same size"); return NULL; } cp1 = (const int16_t *)fragment->buf; cp2 = (const int16_t *)reference->buf; len = fragment->len >> 1; sum_ri_2 = _sum2(cp2, cp2, len); sum_aij_ri = _sum2(cp1, cp2, len); result = sum_aij_ri / sum_ri_2; return PyFloat_FromDouble(result); } /* ** findmax returns the index of the n-sized segment of the input sample ** that contains the most energy. */ /*[clinic input] audioop.findmax fragment: Py_buffer length: Py_ssize_t / Search fragment for a slice of specified number of samples with maximum energy. [clinic start generated code]*/ static PyObject * audioop_findmax_impl(PyObject *module, Py_buffer *fragment, Py_ssize_t length) /*[clinic end generated code: output=f008128233523040 input=2f304801ed42383c]*/ { const int16_t *cp1; Py_ssize_t len1; Py_ssize_t j, best_j; double aj_m1, aj_lm1; double result, best_result; if (fragment->len & 1) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Strings should be even-sized"); return NULL; } cp1 = (const int16_t *)fragment->buf; len1 = fragment->len >> 1; if (length < 0 || len1 < length) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Input sample should be longer"); return NULL; } result = _sum2(cp1, cp1, length); best_result = result; best_j = 0; for ( j=1; j<=len1-length; j++) { aj_m1 = (double)cp1[j-1]; aj_lm1 = (double)cp1[j+length-1]; result = result + aj_lm1*aj_lm1 - aj_m1*aj_m1; if ( result > best_result ) { best_result = result; best_j = j; } } return PyLong_FromSsize_t(best_j); } /*[clinic input] audioop.avgpp fragment: Py_buffer width: int / Return the average peak-peak value over all samples in the fragment. [clinic start generated code]*/ static PyObject * audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=269596b0d5ae0b2b input=0b3cceeae420a7d9]*/ { Py_ssize_t i; int prevval, prevextremevalid = 0, prevextreme = 0; double sum = 0.0; unsigned int avg; int diff, prevdiff, nextreme = 0; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; if (fragment->len <= width) return PyLong_FromLong(0); prevval = GETRAWSAMPLE(width, fragment->buf, 0); prevdiff = 17; /* Anything != 0, 1 */ for (i = width; i < fragment->len; i += width) { int val = GETRAWSAMPLE(width, fragment->buf, i); if (val != prevval) { diff = val < prevval; if (prevdiff == !diff) { /* Derivative changed sign. Compute difference to last ** extreme value and remember. */ if (prevextremevalid) { if (prevval < prevextreme) sum += (double)((unsigned int)prevextreme - (unsigned int)prevval); else sum += (double)((unsigned int)prevval - (unsigned int)prevextreme); nextreme++; } prevextremevalid = 1; prevextreme = prevval; } prevval = val; prevdiff = diff; } } if ( nextreme == 0 ) avg = 0; else avg = (unsigned int)(sum / (double)nextreme); return PyLong_FromUnsignedLong(avg); } /*[clinic input] audioop.maxpp fragment: Py_buffer width: int / Return the maximum peak-peak value in the sound fragment. [clinic start generated code]*/ static PyObject * audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=5b918ed5dbbdb978 input=671a13e1518f80a1]*/ { Py_ssize_t i; int prevval, prevextremevalid = 0, prevextreme = 0; unsigned int max = 0, extremediff; int diff, prevdiff; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; if (fragment->len <= width) return PyLong_FromLong(0); prevval = GETRAWSAMPLE(width, fragment->buf, 0); prevdiff = 17; /* Anything != 0, 1 */ for (i = width; i < fragment->len; i += width) { int val = GETRAWSAMPLE(width, fragment->buf, i); if (val != prevval) { diff = val < prevval; if (prevdiff == !diff) { /* Derivative changed sign. Compute difference to ** last extreme value and remember. */ if (prevextremevalid) { if (prevval < prevextreme) extremediff = (unsigned int)prevextreme - (unsigned int)prevval; else extremediff = (unsigned int)prevval - (unsigned int)prevextreme; if ( extremediff > max ) max = extremediff; } prevextremevalid = 1; prevextreme = prevval; } prevval = val; prevdiff = diff; } } return PyLong_FromUnsignedLong(max); } /*[clinic input] audioop.cross fragment: Py_buffer width: int / Return the number of zero crossings in the fragment passed as an argument. [clinic start generated code]*/ static PyObject * audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=5938dcdd74a1f431 input=b1b3f15b83f6b41a]*/ { Py_ssize_t i; int prevval; Py_ssize_t ncross; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; ncross = -1; prevval = 17; /* Anything <> 0,1 */ for (i = 0; i < fragment->len; i += width) { int val = GETRAWSAMPLE(width, fragment->buf, i) < 0; if (val != prevval) ncross++; prevval = val; } return PyLong_FromSsize_t(ncross); } /*[clinic input] audioop.mul fragment: Py_buffer width: int factor: double / Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor. [clinic start generated code]*/ static PyObject * audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width, double factor) /*[clinic end generated code: output=6cd48fe796da0ea4 input=c726667baa157d3c]*/ { signed char *ncp; Py_ssize_t i; double maxval, minval; PyObject *rv; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; maxval = (double) maxvals[width]; minval = (double) minvals[width]; rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) return NULL; ncp = (signed char *)PyBytes_AsString(rv); for (i = 0; i < fragment->len; i += width) { double val = GETRAWSAMPLE(width, fragment->buf, i); int ival = fbound(val * factor, minval, maxval); SETRAWSAMPLE(width, ncp, i, ival); } return rv; } /*[clinic input] audioop.tomono fragment: Py_buffer width: int lfactor: double rfactor: double / Convert a stereo fragment to a mono fragment. [clinic start generated code]*/ static PyObject * audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width, double lfactor, double rfactor) /*[clinic end generated code: output=235c8277216d4e4e input=c4ec949b3f4dddfa]*/ { signed char *cp, *ncp; Py_ssize_t len, i; double maxval, minval; PyObject *rv; cp = fragment->buf; len = fragment->len; if (!audioop_check_parameters(module, len, width)) return NULL; if (((len / width) & 1) != 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, "not a whole number of frames"); return NULL; } maxval = (double) maxvals[width]; minval = (double) minvals[width]; rv = PyBytes_FromStringAndSize(NULL, len/2); if (rv == NULL) return NULL; ncp = (signed char *)PyBytes_AsString(rv); for (i = 0; i < len; i += width*2) { double val1 = GETRAWSAMPLE(width, cp, i); double val2 = GETRAWSAMPLE(width, cp, i + width); double val = val1 * lfactor + val2 * rfactor; int ival = fbound(val, minval, maxval); SETRAWSAMPLE(width, ncp, i/2, ival); } return rv; } /*[clinic input] audioop.tostereo fragment: Py_buffer width: int lfactor: double rfactor: double / Generate a stereo fragment from a mono fragment. [clinic start generated code]*/ static PyObject * audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width, double lfactor, double rfactor) /*[clinic end generated code: output=046f13defa5f1595 input=27b6395ebfdff37a]*/ { signed char *ncp; Py_ssize_t i; double maxval, minval; PyObject *rv; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; maxval = (double) maxvals[width]; minval = (double) minvals[width]; if (fragment->len > PY_SSIZE_T_MAX/2) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return NULL; } rv = PyBytes_FromStringAndSize(NULL, fragment->len*2); if (rv == NULL) return NULL; ncp = (signed char *)PyBytes_AsString(rv); for (i = 0; i < fragment->len; i += width) { double val = GETRAWSAMPLE(width, fragment->buf, i); int val1 = fbound(val * lfactor, minval, maxval); int val2 = fbound(val * rfactor, minval, maxval); SETRAWSAMPLE(width, ncp, i*2, val1); SETRAWSAMPLE(width, ncp, i*2 + width, val2); } return rv; } /*[clinic input] audioop.add fragment1: Py_buffer fragment2: Py_buffer width: int / Return a fragment which is the addition of the two samples passed as parameters. [clinic start generated code]*/ static PyObject * audioop_add_impl(PyObject *module, Py_buffer *fragment1, Py_buffer *fragment2, int width) /*[clinic end generated code: output=60140af4d1aab6f2 input=4a8d4bae4c1605c7]*/ { signed char *ncp; Py_ssize_t i; int minval, maxval, newval; PyObject *rv; if (!audioop_check_parameters(module, fragment1->len, width)) return NULL; if (fragment1->len != fragment2->len) { PyErr_SetString(get_audioop_state(module)->AudioopError, "Lengths should be the same"); return NULL; } maxval = maxvals[width]; minval = minvals[width]; rv = PyBytes_FromStringAndSize(NULL, fragment1->len); if (rv == NULL) return NULL; ncp = (signed char *)PyBytes_AsString(rv); for (i = 0; i < fragment1->len; i += width) { int val1 = GETRAWSAMPLE(width, fragment1->buf, i); int val2 = GETRAWSAMPLE(width, fragment2->buf, i); if (width < 4) { newval = val1 + val2; /* truncate in case of overflow */ if (newval > maxval) newval = maxval; else if (newval < minval) newval = minval; } else { double fval = (double)val1 + (double)val2; /* truncate in case of overflow */ newval = fbound(fval, minval, maxval); } SETRAWSAMPLE(width, ncp, i, newval); } return rv; } /*[clinic input] audioop.bias fragment: Py_buffer width: int bias: int / Return a fragment that is the original fragment with a bias added to each sample. [clinic start generated code]*/ static PyObject * audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias) /*[clinic end generated code: output=6e0aa8f68f045093 input=2b5cce5c3bb4838c]*/ { signed char *ncp; Py_ssize_t i; unsigned int val = 0, mask; PyObject *rv; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) return NULL; ncp = (signed char *)PyBytes_AsString(rv); mask = masks[width]; for (i = 0; i < fragment->len; i += width) { if (width == 1) val = GETINTX(unsigned char, fragment->buf, i); else if (width == 2) val = GETINTX(uint16_t, fragment->buf, i); else if (width == 3) val = ((unsigned int)GETINT24(fragment->buf, i)) & 0xffffffu; else { assert(width == 4); val = GETINTX(uint32_t, fragment->buf, i); } val += (unsigned int)bias; /* wrap around in case of overflow */ val &= mask; if (width == 1) SETINTX(unsigned char, ncp, i, val); else if (width == 2) SETINTX(uint16_t, ncp, i, val); else if (width == 3) SETINT24(ncp, i, (int)val); else { assert(width == 4); SETINTX(uint32_t, ncp, i, val); } } return rv; } /*[clinic input] audioop.reverse fragment: Py_buffer width: int / Reverse the samples in a fragment and returns the modified fragment. [clinic start generated code]*/ static PyObject * audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=b44135698418da14 input=668f890cf9f9d225]*/ { unsigned char *ncp; Py_ssize_t i; PyObject *rv; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); for (i = 0; i < fragment->len; i += width) { int val = GETRAWSAMPLE(width, fragment->buf, i); SETRAWSAMPLE(width, ncp, fragment->len - i - width, val); } return rv; } /*[clinic input] audioop.byteswap fragment: Py_buffer width: int / Convert big-endian samples to little-endian and vice versa. [clinic start generated code]*/ static PyObject * audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=50838a9e4b87cd4d input=fae7611ceffa5c82]*/ { unsigned char *ncp; Py_ssize_t i; PyObject *rv; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; rv = PyBytes_FromStringAndSize(NULL, fragment->len); if (rv == NULL) return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); for (i = 0; i < fragment->len; i += width) { int j; for (j = 0; j < width; j++) ncp[i + width - 1 - j] = ((unsigned char *)fragment->buf)[i + j]; } return rv; } /*[clinic input] audioop.lin2lin fragment: Py_buffer width: int newwidth: int / Convert samples between 1-, 2-, 3- and 4-byte formats. [clinic start generated code]*/ static PyObject * audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width, int newwidth) /*[clinic end generated code: output=17b14109248f1d99 input=5ce08c8aa2f24d96]*/ { unsigned char *ncp; Py_ssize_t i, j; PyObject *rv; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; if (!audioop_check_size(module, newwidth)) return NULL; if (fragment->len/width > PY_SSIZE_T_MAX/newwidth) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return NULL; } rv = PyBytes_FromStringAndSize(NULL, (fragment->len/width)*newwidth); if (rv == NULL) return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); for (i = j = 0; i < fragment->len; i += width, j += newwidth) { int val = GETSAMPLE32(width, fragment->buf, i); SETSAMPLE32(newwidth, ncp, j, val); } return rv; } static int gcd(int a, int b) { while (b > 0) { int tmp = a % b; a = b; b = tmp; } return a; } /*[clinic input] audioop.ratecv fragment: Py_buffer width: int nchannels: int inrate: int outrate: int state: object weightA: int = 1 weightB: int = 0 / Convert the frame rate of the input fragment. [clinic start generated code]*/ static PyObject * audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, int nchannels, int inrate, int outrate, PyObject *state, int weightA, int weightB) /*[clinic end generated code: output=624038e843243139 input=aff3acdc94476191]*/ { char *cp, *ncp; Py_ssize_t len; int chan, d, *prev_i, *cur_i, cur_o; PyObject *samps, *str, *rv = NULL, *channel; int bytes_per_frame; if (!audioop_check_size(module, width)) return NULL; if (nchannels < 1) { PyErr_SetString(get_audioop_state(module)->AudioopError, "# of channels should be >= 1"); return NULL; } if (width > INT_MAX / nchannels) { /* This overflow test is rigorously correct because both multiplicands are >= 1. Use the argument names from the docs for the error msg. */ PyErr_SetString(PyExc_OverflowError, "width * nchannels too big for a C int"); return NULL; } bytes_per_frame = width * nchannels; if (weightA < 1 || weightB < 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, "weightA should be >= 1, weightB should be >= 0"); return NULL; } assert(fragment->len >= 0); if (fragment->len % bytes_per_frame != 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, "not a whole number of frames"); return NULL; } if (inrate <= 0 || outrate <= 0) { PyErr_SetString(get_audioop_state(module)->AudioopError, "sampling rate not > 0"); return NULL; } /* divide inrate and outrate by their greatest common divisor */ d = gcd(inrate, outrate); inrate /= d; outrate /= d; /* divide weightA and weightB by their greatest common divisor */ d = gcd(weightA, weightB); weightA /= d; weightB /= d; if ((size_t)nchannels > SIZE_MAX/sizeof(int)) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return NULL; } prev_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); cur_i = (int *) PyMem_Malloc(nchannels * sizeof(int)); if (prev_i == NULL || cur_i == NULL) { (void) PyErr_NoMemory(); goto exit; } len = fragment->len / bytes_per_frame; /* # of frames */ if (state == Py_None) { d = -outrate; for (chan = 0; chan < nchannels; chan++) prev_i[chan] = cur_i[chan] = 0; } else { if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); goto exit; } if (!PyArg_ParseTuple(state, "iO!;ratecv(): illegal state argument", &d, &PyTuple_Type, &samps)) goto exit; if (PyTuple_Size(samps) != nchannels) { PyErr_SetString(get_audioop_state(module)->AudioopError, "illegal state argument"); goto exit; } for (chan = 0; chan < nchannels; chan++) { channel = PyTuple_GetItem(samps, chan); if (!PyTuple_Check(channel)) { PyErr_SetString(PyExc_TypeError, "ratecv(): illegal state argument"); goto exit; } if (!PyArg_ParseTuple(channel, "ii;ratecv(): illegal state argument", &prev_i[chan], &cur_i[chan])) { goto exit; } } } /* str <- Space for the output buffer. */ if (len == 0) str = PyBytes_FromStringAndSize(NULL, 0); else { /* There are len input frames, so we need (mathematically) ceiling(len*outrate/inrate) output frames, and each frame requires bytes_per_frame bytes. Computing this without spurious overflow is the challenge; we can settle for a reasonable upper bound, though, in this case ceiling(len/inrate) * outrate. */ /* compute ceiling(len/inrate) without overflow */ Py_ssize_t q = 1 + (len - 1) / inrate; if (outrate > PY_SSIZE_T_MAX / q / bytes_per_frame) str = NULL; else str = PyBytes_FromStringAndSize(NULL, q * outrate * bytes_per_frame); } if (str == NULL) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); goto exit; } ncp = PyBytes_AsString(str); cp = fragment->buf; for (;;) { while (d < 0) { if (len == 0) { samps = PyTuple_New(nchannels); if (samps == NULL) goto exit; for (chan = 0; chan < nchannels; chan++) PyTuple_SetItem(samps, chan, Py_BuildValue("(ii)", prev_i[chan], cur_i[chan])); if (PyErr_Occurred()) goto exit; /* We have checked before that the length * of the string fits into int. */ len = (Py_ssize_t)(ncp - PyBytes_AsString(str)); rv = PyBytes_FromStringAndSize (PyBytes_AsString(str), len); _LTS_Py_SETREF(str, rv); if (str == NULL) goto exit; rv = Py_BuildValue("(O(iO))", str, d, samps); Py_DECREF(samps); Py_DECREF(str); goto exit; /* return rv */ } for (chan = 0; chan < nchannels; chan++) { prev_i[chan] = cur_i[chan]; cur_i[chan] = GETSAMPLE32(width, cp, 0); cp += width; /* implements a simple digital filter */ cur_i[chan] = (int)( ((double)weightA * (double)cur_i[chan] + (double)weightB * (double)prev_i[chan]) / ((double)weightA + (double)weightB)); } len--; d += outrate; } while (d >= 0) { for (chan = 0; chan < nchannels; chan++) { cur_o = (int)(((double)prev_i[chan] * (double)d + (double)cur_i[chan] * (double)(outrate - d)) / (double)outrate); SETSAMPLE32(width, ncp, 0, cur_o); ncp += width; } d -= inrate; } } exit: PyMem_Free(prev_i); PyMem_Free(cur_i); return rv; } /*[clinic input] audioop.lin2ulaw fragment: Py_buffer width: int / Convert samples in the audio fragment to u-LAW encoding. [clinic start generated code]*/ static PyObject * audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=14fb62b16fe8ea8e input=2450d1b870b6bac2]*/ { unsigned char *ncp; Py_ssize_t i; PyObject *rv; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); if (rv == NULL) return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); for (i = 0; i < fragment->len; i += width) { int val = GETSAMPLE32(width, fragment->buf, i); *ncp++ = st_14linear2ulaw(val >> 18); } return rv; } /*[clinic input] audioop.ulaw2lin fragment: Py_buffer width: int / Convert sound fragments in u-LAW encoding to linearly encoded sound fragments. [clinic start generated code]*/ static PyObject * audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=378356b047521ba2 input=45d53ddce5be7d06]*/ { unsigned char *cp; signed char *ncp; Py_ssize_t i; PyObject *rv; if (!audioop_check_size(module, width)) return NULL; if (fragment->len > PY_SSIZE_T_MAX/width) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return NULL; } rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); if (rv == NULL) return NULL; ncp = (signed char *)PyBytes_AsString(rv); cp = fragment->buf; for (i = 0; i < fragment->len*width; i += width) { int val = st_ulaw2linear16(*cp++) * (1 << 16); SETSAMPLE32(width, ncp, i, val); } return rv; } /*[clinic input] audioop.lin2alaw fragment: Py_buffer width: int / Convert samples in the audio fragment to a-LAW encoding. [clinic start generated code]*/ static PyObject * audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=d076f130121a82f0 input=ffb1ef8bb39da945]*/ { unsigned char *ncp; Py_ssize_t i; PyObject *rv; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; rv = PyBytes_FromStringAndSize(NULL, fragment->len/width); if (rv == NULL) return NULL; ncp = (unsigned char *)PyBytes_AsString(rv); for (i = 0; i < fragment->len; i += width) { int val = GETSAMPLE32(width, fragment->buf, i); *ncp++ = st_linear2alaw(val >> 19); } return rv; } /*[clinic input] audioop.alaw2lin fragment: Py_buffer width: int / Convert sound fragments in a-LAW encoding to linearly encoded sound fragments. [clinic start generated code]*/ static PyObject * audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) /*[clinic end generated code: output=85c365ec559df647 input=4140626046cd1772]*/ { unsigned char *cp; signed char *ncp; Py_ssize_t i; int val; PyObject *rv; if (!audioop_check_size(module, width)) return NULL; if (fragment->len > PY_SSIZE_T_MAX/width) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return NULL; } rv = PyBytes_FromStringAndSize(NULL, fragment->len*width); if (rv == NULL) return NULL; ncp = (signed char *)PyBytes_AsString(rv); cp = fragment->buf; for (i = 0; i < fragment->len*width; i += width) { val = st_alaw2linear16(*cp++) * (1 << 16); SETSAMPLE32(width, ncp, i, val); } return rv; } /*[clinic input] audioop.lin2adpcm fragment: Py_buffer width: int state: object / Convert samples to 4 bit Intel/DVI ADPCM encoding. [clinic start generated code]*/ static PyObject * audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, PyObject *state) /*[clinic end generated code: output=cc19f159f16c6793 input=12919d549b90c90a]*/ { signed char *ncp; Py_ssize_t i; int step, valpred, delta, index, sign, vpdiff, diff; PyObject *rv = NULL, *str; int outputbuffer = 0, bufferstep; if (!audioop_check_parameters(module, fragment->len, width)) return NULL; /* Decode state, should have (value, step) */ if ( state == Py_None ) { /* First time, it seems. Set defaults */ valpred = 0; index = 0; } else if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); return NULL; } else if (!PyArg_ParseTuple(state, "ii;lin2adpcm(): illegal state argument", &valpred, &index)) { return NULL; } else if (valpred >= 0x8000 || valpred < -0x8000 || (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) { PyErr_SetString(PyExc_ValueError, "bad state"); return NULL; } str = PyBytes_FromStringAndSize(NULL, fragment->len/(width*2)); if (str == NULL) return NULL; ncp = (signed char *)PyBytes_AsString(str); step = stepsizeTable[index]; bufferstep = 1; for (i = 0; i < fragment->len; i += width) { int val = GETSAMPLE32(width, fragment->buf, i) >> 16; /* Step 1 - compute difference with previous value */ if (val < valpred) { diff = valpred - val; sign = 8; } else { diff = val - valpred; sign = 0; } /* Step 2 - Divide and clamp */ /* Note: ** This code *approximately* computes: ** delta = diff*4/step; ** vpdiff = (delta+0.5)*step/4; ** but in shift step bits are dropped. The net result of this ** is that even if you have fast mul/div hardware you cannot ** put it to good use since the fixup would be too expensive. */ delta = 0; vpdiff = (step >> 3); if ( diff >= step ) { delta = 4; diff -= step; vpdiff += step; } step >>= 1; if ( diff >= step ) { delta |= 2; diff -= step; vpdiff += step; } step >>= 1; if ( diff >= step ) { delta |= 1; vpdiff += step; } /* Step 3 - Update previous value */ if ( sign ) valpred -= vpdiff; else valpred += vpdiff; /* Step 4 - Clamp previous value to 16 bits */ if ( valpred > 32767 ) valpred = 32767; else if ( valpred < -32768 ) valpred = -32768; /* Step 5 - Assemble value, update index and step values */ delta |= sign; index += indexTable[delta]; if ( index < 0 ) index = 0; if ( index > 88 ) index = 88; step = stepsizeTable[index]; /* Step 6 - Output value */ if ( bufferstep ) { outputbuffer = (delta * (1 << 4)) & 0xf0; } else { *ncp++ = (delta & 0x0f) | outputbuffer; } bufferstep = !bufferstep; } rv = Py_BuildValue("(O(ii))", str, valpred, index); Py_DECREF(str); return rv; } /*[clinic input] audioop.adpcm2lin fragment: Py_buffer width: int state: object / Decode an Intel/DVI ADPCM coded fragment to a linear fragment. [clinic start generated code]*/ static PyObject * audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, PyObject *state) /*[clinic end generated code: output=3440ea105acb3456 input=f5221144f5ca9ef0]*/ { signed char *cp; signed char *ncp; Py_ssize_t i, outlen; int valpred, step, delta, index, sign, vpdiff; PyObject *rv, *str; int inputbuffer = 0, bufferstep; if (!audioop_check_size(module, width)) return NULL; /* Decode state, should have (value, step) */ if ( state == Py_None ) { /* First time, it seems. Set defaults */ valpred = 0; index = 0; } else if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, "state must be a tuple or None"); return NULL; } else if (!PyArg_ParseTuple(state, "ii;adpcm2lin(): illegal state argument", &valpred, &index)) { return NULL; } else if (valpred >= 0x8000 || valpred < -0x8000 || (size_t)index >= Py_ARRAY_LENGTH(stepsizeTable)) { PyErr_SetString(PyExc_ValueError, "bad state"); return NULL; } if (fragment->len > (PY_SSIZE_T_MAX/2)/width) { PyErr_SetString(PyExc_MemoryError, "not enough memory for output buffer"); return NULL; } outlen = fragment->len*width*2; str = PyBytes_FromStringAndSize(NULL, outlen); if (str == NULL) return NULL; ncp = (signed char *)PyBytes_AsString(str); cp = fragment->buf; step = stepsizeTable[index]; bufferstep = 0; for (i = 0; i < outlen; i += width) { /* Step 1 - get the delta value and compute next index */ if ( bufferstep ) { delta = inputbuffer & 0xf; } else { inputbuffer = *cp++; delta = (inputbuffer >> 4) & 0xf; } bufferstep = !bufferstep; /* Step 2 - Find new index value (for later) */ index += indexTable[delta]; if ( index < 0 ) index = 0; if ( index > 88 ) index = 88; /* Step 3 - Separate sign and magnitude */ sign = delta & 8; delta = delta & 7; /* Step 4 - Compute difference and new predicted value */ /* ** Computes 'vpdiff = (delta+0.5)*step/4', but see comment ** in adpcm_coder. */ vpdiff = step >> 3; if ( delta & 4 ) vpdiff += step; if ( delta & 2 ) vpdiff += step>>1; if ( delta & 1 ) vpdiff += step>>2; if ( sign ) valpred -= vpdiff; else valpred += vpdiff; /* Step 5 - clamp output value */ if ( valpred > 32767 ) valpred = 32767; else if ( valpred < -32768 ) valpred = -32768; /* Step 6 - Update step value */ step = stepsizeTable[index]; /* Step 6 - Output value */ SETSAMPLE32(width, ncp, i, valpred * (1 << 16)); } rv = Py_BuildValue("(O(ii))", str, valpred, index); Py_DECREF(str); return rv; } #include "_audioop.c.h" static PyMethodDef audioop_methods[] = { AUDIOOP_MAX_METHODDEF AUDIOOP_MINMAX_METHODDEF AUDIOOP_AVG_METHODDEF AUDIOOP_MAXPP_METHODDEF AUDIOOP_AVGPP_METHODDEF AUDIOOP_RMS_METHODDEF AUDIOOP_FINDFIT_METHODDEF AUDIOOP_FINDMAX_METHODDEF AUDIOOP_FINDFACTOR_METHODDEF AUDIOOP_CROSS_METHODDEF AUDIOOP_MUL_METHODDEF AUDIOOP_ADD_METHODDEF AUDIOOP_BIAS_METHODDEF AUDIOOP_ULAW2LIN_METHODDEF AUDIOOP_LIN2ULAW_METHODDEF AUDIOOP_ALAW2LIN_METHODDEF AUDIOOP_LIN2ALAW_METHODDEF AUDIOOP_LIN2LIN_METHODDEF AUDIOOP_ADPCM2LIN_METHODDEF AUDIOOP_LIN2ADPCM_METHODDEF AUDIOOP_TOMONO_METHODDEF AUDIOOP_TOSTEREO_METHODDEF AUDIOOP_GETSAMPLE_METHODDEF AUDIOOP_REVERSE_METHODDEF AUDIOOP_BYTESWAP_METHODDEF AUDIOOP_RATECV_METHODDEF { 0, 0 } }; static int audioop_traverse(PyObject *module, visitproc visit, void *arg) { audioop_state *state = get_audioop_state(module); Py_VISIT(state->AudioopError); return 0; } static int audioop_clear(PyObject *module) { audioop_state *state = get_audioop_state(module); Py_CLEAR(state->AudioopError); return 0; } static void audioop_free(void *module) { audioop_clear((PyObject *)module); } static int audioop_exec(PyObject* module) { audioop_state *state = get_audioop_state(module); state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL); if (state->AudioopError == NULL) { return -1; } Py_INCREF(state->AudioopError); if (PyModule_AddObject(module, "error", state->AudioopError) < 0) { Py_DECREF(state->AudioopError); return -1; } return 0; } static PyModuleDef_Slot audioop_slots[] = { {Py_mod_exec, audioop_exec}, {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {Py_mod_gil, Py_MOD_GIL_NOT_USED}, {0, NULL} }; static struct PyModuleDef audioopmodule = { PyModuleDef_HEAD_INIT, "audioop", NULL, sizeof(audioop_state), audioop_methods, audioop_slots, audioop_traverse, audioop_clear, audioop_free }; PyMODINIT_FUNC PyInit__audioop(void) { return PyModuleDef_Init(&audioopmodule); } audioop-0.2.1/audioop/_audioop.c.h000066400000000000000000001146141465376466600170410ustar00rootroot00000000000000/*[clinic input] preserve [clinic start generated code]*/ #include "Python.h" #include "assert.h" int _LTS_PyArg_CheckPositional(const char *name, Py_ssize_t nargs, Py_ssize_t min, Py_ssize_t max) { assert(min >= 0); assert(min <= max); if (nargs < min) { if (name != NULL) PyErr_Format( PyExc_TypeError, "%.200s expected %s%zd argument%s, got %zd", name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs); else PyErr_Format( PyExc_TypeError, "unpacked tuple should have %s%zd element%s," " but has %zd", (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs); return 0; } if (nargs == 0) { return 1; } if (nargs > max) { if (name != NULL) PyErr_Format( PyExc_TypeError, "%.200s expected %s%zd argument%s, got %zd", name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs); else PyErr_Format( PyExc_TypeError, "unpacked tuple should have %s%zd element%s," " but has %zd", (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs); return 0; } return 1; } void _LTS_PyArg_BadArgument(const char *fname, const char *displayname, const char *expected, PyObject *arg) { PyTypeObject *arg_type = (PyTypeObject *)PyObject_Type(arg); if (arg_type == NULL) return; PyObject *arg_type_name = PyType_GetName(arg_type); if (arg_type_name == NULL) { Py_DECREF(arg_type); return; } const char *arg_type_name_chars = PyUnicode_AsUTF8AndSize(arg_type_name, NULL); if (arg_type_name_chars == NULL) { Py_DECREF(arg_type_name); Py_DECREF(arg_type); return; } PyErr_Format(PyExc_TypeError, "%.200s() %.200s must be %.50s, not %.50s", fname, displayname, expected, arg == Py_None ? "None" : arg_type_name_chars); Py_DECREF(arg_type); Py_DECREF(arg_type_name); } /* Get a C int from an int object or any object that has an __index__ method. Return -1 and set an error if overflow occurs. */ int _LTS_PyLong_AsInt(PyObject *obj) { int overflow; long result = PyLong_AsLongAndOverflow(obj, &overflow); if (overflow || result > INT_MAX || result < INT_MIN) { /* XXX: could be cute and give a different message for overflow == -1 */ PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C int"); return -1; } return (int)result; } PyDoc_STRVAR(audioop_getsample__doc__, "getsample($module, fragment, width, index, /)\n" "--\n" "\n" "Return the value of sample index from the fragment."); #define AUDIOOP_GETSAMPLE_METHODDEF \ {"getsample", _PyCFunction_CAST(audioop_getsample), METH_FASTCALL, audioop_getsample__doc__}, static PyObject * audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width, Py_ssize_t index); static PyObject * audioop_getsample(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; Py_ssize_t index; if (!_LTS_PyArg_CheckPositional("getsample", nargs, 3, 3)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("getsample", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } { Py_ssize_t ival = -1; PyObject *iobj = PyNumber_Index(args[2]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); } if (ival == -1 && PyErr_Occurred()) { goto exit; } index = ival; } return_value = audioop_getsample_impl(module, &fragment, width, index); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_max__doc__, "max($module, fragment, width, /)\n" "--\n" "\n" "Return the maximum of the absolute value of all samples in a fragment."); #define AUDIOOP_MAX_METHODDEF \ {"max", _PyCFunction_CAST(audioop_max), METH_FASTCALL, audioop_max__doc__}, static PyObject * audioop_max_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("max", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("max", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_max_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_minmax__doc__, "minmax($module, fragment, width, /)\n" "--\n" "\n" "Return the minimum and maximum values of all samples in the sound fragment."); #define AUDIOOP_MINMAX_METHODDEF \ {"minmax", _PyCFunction_CAST(audioop_minmax), METH_FASTCALL, audioop_minmax__doc__}, static PyObject * audioop_minmax_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_minmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("minmax", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("minmax", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_minmax_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_avg__doc__, "avg($module, fragment, width, /)\n" "--\n" "\n" "Return the average over all samples in the fragment."); #define AUDIOOP_AVG_METHODDEF \ {"avg", _PyCFunction_CAST(audioop_avg), METH_FASTCALL, audioop_avg__doc__}, static PyObject * audioop_avg_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_avg(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("avg", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("avg", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_avg_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_rms__doc__, "rms($module, fragment, width, /)\n" "--\n" "\n" "Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n)."); #define AUDIOOP_RMS_METHODDEF \ {"rms", _PyCFunction_CAST(audioop_rms), METH_FASTCALL, audioop_rms__doc__}, static PyObject * audioop_rms_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_rms(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("rms", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("rms", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_rms_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_findfit__doc__, "findfit($module, fragment, reference, /)\n" "--\n" "\n" "Try to match reference as well as possible to a portion of fragment."); #define AUDIOOP_FINDFIT_METHODDEF \ {"findfit", _PyCFunction_CAST(audioop_findfit), METH_FASTCALL, audioop_findfit__doc__}, static PyObject * audioop_findfit_impl(PyObject *module, Py_buffer *fragment, Py_buffer *reference); static PyObject * audioop_findfit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; Py_buffer reference = {NULL, NULL}; if (!_LTS_PyArg_CheckPositional("findfit", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("findfit", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &reference, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&reference, 'C')) { _LTS_PyArg_BadArgument("findfit", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = audioop_findfit_impl(module, &fragment, &reference); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } /* Cleanup for reference */ if (reference.obj) { PyBuffer_Release(&reference); } return return_value; } PyDoc_STRVAR(audioop_findfactor__doc__, "findfactor($module, fragment, reference, /)\n" "--\n" "\n" "Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal."); #define AUDIOOP_FINDFACTOR_METHODDEF \ {"findfactor", _PyCFunction_CAST(audioop_findfactor), METH_FASTCALL, audioop_findfactor__doc__}, static PyObject * audioop_findfactor_impl(PyObject *module, Py_buffer *fragment, Py_buffer *reference); static PyObject * audioop_findfactor(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; Py_buffer reference = {NULL, NULL}; if (!_LTS_PyArg_CheckPositional("findfactor", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("findfactor", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &reference, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&reference, 'C')) { _LTS_PyArg_BadArgument("findfactor", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = audioop_findfactor_impl(module, &fragment, &reference); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } /* Cleanup for reference */ if (reference.obj) { PyBuffer_Release(&reference); } return return_value; } PyDoc_STRVAR(audioop_findmax__doc__, "findmax($module, fragment, length, /)\n" "--\n" "\n" "Search fragment for a slice of specified number of samples with maximum energy."); #define AUDIOOP_FINDMAX_METHODDEF \ {"findmax", _PyCFunction_CAST(audioop_findmax), METH_FASTCALL, audioop_findmax__doc__}, static PyObject * audioop_findmax_impl(PyObject *module, Py_buffer *fragment, Py_ssize_t length); static PyObject * audioop_findmax(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; Py_ssize_t length; if (!_LTS_PyArg_CheckPositional("findmax", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("findmax", "argument 1", "contiguous buffer", args[0]); goto exit; } { Py_ssize_t ival = -1; PyObject *iobj = PyNumber_Index(args[1]); if (iobj != NULL) { ival = PyLong_AsSsize_t(iobj); Py_DECREF(iobj); } if (ival == -1 && PyErr_Occurred()) { goto exit; } length = ival; } return_value = audioop_findmax_impl(module, &fragment, length); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_avgpp__doc__, "avgpp($module, fragment, width, /)\n" "--\n" "\n" "Return the average peak-peak value over all samples in the fragment."); #define AUDIOOP_AVGPP_METHODDEF \ {"avgpp", _PyCFunction_CAST(audioop_avgpp), METH_FASTCALL, audioop_avgpp__doc__}, static PyObject * audioop_avgpp_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_avgpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("avgpp", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("avgpp", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_avgpp_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_maxpp__doc__, "maxpp($module, fragment, width, /)\n" "--\n" "\n" "Return the maximum peak-peak value in the sound fragment."); #define AUDIOOP_MAXPP_METHODDEF \ {"maxpp", _PyCFunction_CAST(audioop_maxpp), METH_FASTCALL, audioop_maxpp__doc__}, static PyObject * audioop_maxpp_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_maxpp(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("maxpp", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("maxpp", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_maxpp_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_cross__doc__, "cross($module, fragment, width, /)\n" "--\n" "\n" "Return the number of zero crossings in the fragment passed as an argument."); #define AUDIOOP_CROSS_METHODDEF \ {"cross", _PyCFunction_CAST(audioop_cross), METH_FASTCALL, audioop_cross__doc__}, static PyObject * audioop_cross_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_cross(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("cross", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("cross", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_cross_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_mul__doc__, "mul($module, fragment, width, factor, /)\n" "--\n" "\n" "Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor."); #define AUDIOOP_MUL_METHODDEF \ {"mul", _PyCFunction_CAST(audioop_mul), METH_FASTCALL, audioop_mul__doc__}, static PyObject * audioop_mul_impl(PyObject *module, Py_buffer *fragment, int width, double factor); static PyObject * audioop_mul(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; double factor; if (!_LTS_PyArg_CheckPositional("mul", nargs, 3, 3)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("mul", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } if (PyFloat_CheckExact(args[2])) { factor = PyFloat_AsDouble(args[2]); } else { factor = PyFloat_AsDouble(args[2]); if (factor == -1.0 && PyErr_Occurred()) { goto exit; } } return_value = audioop_mul_impl(module, &fragment, width, factor); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_tomono__doc__, "tomono($module, fragment, width, lfactor, rfactor, /)\n" "--\n" "\n" "Convert a stereo fragment to a mono fragment."); #define AUDIOOP_TOMONO_METHODDEF \ {"tomono", _PyCFunction_CAST(audioop_tomono), METH_FASTCALL, audioop_tomono__doc__}, static PyObject * audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width, double lfactor, double rfactor); static PyObject * audioop_tomono(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; double lfactor; double rfactor; if (!_LTS_PyArg_CheckPositional("tomono", nargs, 4, 4)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("tomono", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } if (PyFloat_CheckExact(args[2])) { lfactor = PyFloat_AsDouble(args[2]); } else { lfactor = PyFloat_AsDouble(args[2]); if (lfactor == -1.0 && PyErr_Occurred()) { goto exit; } } if (PyFloat_CheckExact(args[3])) { rfactor = PyFloat_AsDouble(args[3]); } else { rfactor = PyFloat_AsDouble(args[3]); if (rfactor == -1.0 && PyErr_Occurred()) { goto exit; } } return_value = audioop_tomono_impl(module, &fragment, width, lfactor, rfactor); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_tostereo__doc__, "tostereo($module, fragment, width, lfactor, rfactor, /)\n" "--\n" "\n" "Generate a stereo fragment from a mono fragment."); #define AUDIOOP_TOSTEREO_METHODDEF \ {"tostereo", _PyCFunction_CAST(audioop_tostereo), METH_FASTCALL, audioop_tostereo__doc__}, static PyObject * audioop_tostereo_impl(PyObject *module, Py_buffer *fragment, int width, double lfactor, double rfactor); static PyObject * audioop_tostereo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; double lfactor; double rfactor; if (!_LTS_PyArg_CheckPositional("tostereo", nargs, 4, 4)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("tostereo", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } if (PyFloat_CheckExact(args[2])) { lfactor = PyFloat_AsDouble(args[2]); } else { lfactor = PyFloat_AsDouble(args[2]); if (lfactor == -1.0 && PyErr_Occurred()) { goto exit; } } if (PyFloat_CheckExact(args[3])) { rfactor = PyFloat_AsDouble(args[3]); } else { rfactor = PyFloat_AsDouble(args[3]); if (rfactor == -1.0 && PyErr_Occurred()) { goto exit; } } return_value = audioop_tostereo_impl(module, &fragment, width, lfactor, rfactor); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_add__doc__, "add($module, fragment1, fragment2, width, /)\n" "--\n" "\n" "Return a fragment which is the addition of the two samples passed as parameters."); #define AUDIOOP_ADD_METHODDEF \ {"add", _PyCFunction_CAST(audioop_add), METH_FASTCALL, audioop_add__doc__}, static PyObject * audioop_add_impl(PyObject *module, Py_buffer *fragment1, Py_buffer *fragment2, int width); static PyObject * audioop_add(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment1 = {NULL, NULL}; Py_buffer fragment2 = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("add", nargs, 3, 3)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment1, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment1, 'C')) { _LTS_PyArg_BadArgument("add", "argument 1", "contiguous buffer", args[0]); goto exit; } if (PyObject_GetBuffer(args[1], &fragment2, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment2, 'C')) { _LTS_PyArg_BadArgument("add", "argument 2", "contiguous buffer", args[1]); goto exit; } width = _LTS_PyLong_AsInt(args[2]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_add_impl(module, &fragment1, &fragment2, width); exit: /* Cleanup for fragment1 */ if (fragment1.obj) { PyBuffer_Release(&fragment1); } /* Cleanup for fragment2 */ if (fragment2.obj) { PyBuffer_Release(&fragment2); } return return_value; } PyDoc_STRVAR(audioop_bias__doc__, "bias($module, fragment, width, bias, /)\n" "--\n" "\n" "Return a fragment that is the original fragment with a bias added to each sample."); #define AUDIOOP_BIAS_METHODDEF \ {"bias", _PyCFunction_CAST(audioop_bias), METH_FASTCALL, audioop_bias__doc__}, static PyObject * audioop_bias_impl(PyObject *module, Py_buffer *fragment, int width, int bias); static PyObject * audioop_bias(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; int bias; if (!_LTS_PyArg_CheckPositional("bias", nargs, 3, 3)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("bias", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } bias = _LTS_PyLong_AsInt(args[2]); if (bias == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_bias_impl(module, &fragment, width, bias); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_reverse__doc__, "reverse($module, fragment, width, /)\n" "--\n" "\n" "Reverse the samples in a fragment and returns the modified fragment."); #define AUDIOOP_REVERSE_METHODDEF \ {"reverse", _PyCFunction_CAST(audioop_reverse), METH_FASTCALL, audioop_reverse__doc__}, static PyObject * audioop_reverse_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_reverse(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("reverse", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("reverse", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_reverse_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_byteswap__doc__, "byteswap($module, fragment, width, /)\n" "--\n" "\n" "Convert big-endian samples to little-endian and vice versa."); #define AUDIOOP_BYTESWAP_METHODDEF \ {"byteswap", _PyCFunction_CAST(audioop_byteswap), METH_FASTCALL, audioop_byteswap__doc__}, static PyObject * audioop_byteswap_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_byteswap(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("byteswap", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("byteswap", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_byteswap_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_lin2lin__doc__, "lin2lin($module, fragment, width, newwidth, /)\n" "--\n" "\n" "Convert samples between 1-, 2-, 3- and 4-byte formats."); #define AUDIOOP_LIN2LIN_METHODDEF \ {"lin2lin", _PyCFunction_CAST(audioop_lin2lin), METH_FASTCALL, audioop_lin2lin__doc__}, static PyObject * audioop_lin2lin_impl(PyObject *module, Py_buffer *fragment, int width, int newwidth); static PyObject * audioop_lin2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; int newwidth; if (!_LTS_PyArg_CheckPositional("lin2lin", nargs, 3, 3)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("lin2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } newwidth = _LTS_PyLong_AsInt(args[2]); if (newwidth == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_lin2lin_impl(module, &fragment, width, newwidth); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_ratecv__doc__, "ratecv($module, fragment, width, nchannels, inrate, outrate, state,\n" " weightA=1, weightB=0, /)\n" "--\n" "\n" "Convert the frame rate of the input fragment."); #define AUDIOOP_RATECV_METHODDEF \ {"ratecv", _PyCFunction_CAST(audioop_ratecv), METH_FASTCALL, audioop_ratecv__doc__}, static PyObject * audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, int nchannels, int inrate, int outrate, PyObject *state, int weightA, int weightB); static PyObject * audioop_ratecv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; int nchannels; int inrate; int outrate; PyObject *state; int weightA = 1; int weightB = 0; if (!_LTS_PyArg_CheckPositional("ratecv", nargs, 6, 8)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("ratecv", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } nchannels = _LTS_PyLong_AsInt(args[2]); if (nchannels == -1 && PyErr_Occurred()) { goto exit; } inrate = _LTS_PyLong_AsInt(args[3]); if (inrate == -1 && PyErr_Occurred()) { goto exit; } outrate = _LTS_PyLong_AsInt(args[4]); if (outrate == -1 && PyErr_Occurred()) { goto exit; } state = args[5]; if (nargs < 7) { goto skip_optional; } weightA = _LTS_PyLong_AsInt(args[6]); if (weightA == -1 && PyErr_Occurred()) { goto exit; } if (nargs < 8) { goto skip_optional; } weightB = _LTS_PyLong_AsInt(args[7]); if (weightB == -1 && PyErr_Occurred()) { goto exit; } skip_optional: return_value = audioop_ratecv_impl(module, &fragment, width, nchannels, inrate, outrate, state, weightA, weightB); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_lin2ulaw__doc__, "lin2ulaw($module, fragment, width, /)\n" "--\n" "\n" "Convert samples in the audio fragment to u-LAW encoding."); #define AUDIOOP_LIN2ULAW_METHODDEF \ {"lin2ulaw", _PyCFunction_CAST(audioop_lin2ulaw), METH_FASTCALL, audioop_lin2ulaw__doc__}, static PyObject * audioop_lin2ulaw_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_lin2ulaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("lin2ulaw", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("lin2ulaw", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_lin2ulaw_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_ulaw2lin__doc__, "ulaw2lin($module, fragment, width, /)\n" "--\n" "\n" "Convert sound fragments in u-LAW encoding to linearly encoded sound fragments."); #define AUDIOOP_ULAW2LIN_METHODDEF \ {"ulaw2lin", _PyCFunction_CAST(audioop_ulaw2lin), METH_FASTCALL, audioop_ulaw2lin__doc__}, static PyObject * audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_ulaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("ulaw2lin", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("ulaw2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_ulaw2lin_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_lin2alaw__doc__, "lin2alaw($module, fragment, width, /)\n" "--\n" "\n" "Convert samples in the audio fragment to a-LAW encoding."); #define AUDIOOP_LIN2ALAW_METHODDEF \ {"lin2alaw", _PyCFunction_CAST(audioop_lin2alaw), METH_FASTCALL, audioop_lin2alaw__doc__}, static PyObject * audioop_lin2alaw_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_lin2alaw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("lin2alaw", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("lin2alaw", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_lin2alaw_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_alaw2lin__doc__, "alaw2lin($module, fragment, width, /)\n" "--\n" "\n" "Convert sound fragments in a-LAW encoding to linearly encoded sound fragments."); #define AUDIOOP_ALAW2LIN_METHODDEF \ {"alaw2lin", _PyCFunction_CAST(audioop_alaw2lin), METH_FASTCALL, audioop_alaw2lin__doc__}, static PyObject * audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width); static PyObject * audioop_alaw2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; if (!_LTS_PyArg_CheckPositional("alaw2lin", nargs, 2, 2)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("alaw2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } return_value = audioop_alaw2lin_impl(module, &fragment, width); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_lin2adpcm__doc__, "lin2adpcm($module, fragment, width, state, /)\n" "--\n" "\n" "Convert samples to 4 bit Intel/DVI ADPCM encoding."); #define AUDIOOP_LIN2ADPCM_METHODDEF \ {"lin2adpcm", _PyCFunction_CAST(audioop_lin2adpcm), METH_FASTCALL, audioop_lin2adpcm__doc__}, static PyObject * audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, PyObject *state); static PyObject * audioop_lin2adpcm(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; PyObject *state; if (!_LTS_PyArg_CheckPositional("lin2adpcm", nargs, 3, 3)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("lin2adpcm", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } state = args[2]; return_value = audioop_lin2adpcm_impl(module, &fragment, width, state); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } PyDoc_STRVAR(audioop_adpcm2lin__doc__, "adpcm2lin($module, fragment, width, state, /)\n" "--\n" "\n" "Decode an Intel/DVI ADPCM coded fragment to a linear fragment."); #define AUDIOOP_ADPCM2LIN_METHODDEF \ {"adpcm2lin", _PyCFunction_CAST(audioop_adpcm2lin), METH_FASTCALL, audioop_adpcm2lin__doc__}, static PyObject * audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, PyObject *state); static PyObject * audioop_adpcm2lin(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; Py_buffer fragment = {NULL, NULL}; int width; PyObject *state; if (!_LTS_PyArg_CheckPositional("adpcm2lin", nargs, 3, 3)) { goto exit; } if (PyObject_GetBuffer(args[0], &fragment, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&fragment, 'C')) { _LTS_PyArg_BadArgument("adpcm2lin", "argument 1", "contiguous buffer", args[0]); goto exit; } width = _LTS_PyLong_AsInt(args[1]); if (width == -1 && PyErr_Occurred()) { goto exit; } state = args[2]; return_value = audioop_adpcm2lin_impl(module, &fragment, width, state); exit: /* Cleanup for fragment */ if (fragment.obj) { PyBuffer_Release(&fragment); } return return_value; } /*[clinic end generated code: output=9a7e36f1179f0223 input=a9049054013a1b77]*/ audioop-0.2.1/audioop/py.typed000066400000000000000000000000001465376466600163260ustar00rootroot00000000000000audioop-0.2.1/pyproject.toml000066400000000000000000000024201465376466600161130ustar00rootroot00000000000000[build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" [project] name = "audioop-lts" description = "LTS Port of Python audioop" requires-python = ">=3.13" version = "0.2.1" readme = "README.md" license = { text = "PSF-2.0" } maintainers = [{ name = "AbstractUmbra", email = "umbra@abstractumbra.dev" }] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", ] [project.urls] Homepage = "https://github.com/AbstractUmbra/audioop" [tool.setuptools] packages = ["audioop"] [tool.setuptools.exclude-package-data] # Keep just the shared object when packing a wheel, not the C source code. audioop = ["*.c", "*.h"] [tool.pyright] pythonVersion = "3.13" typeCheckingMode = "strict" include = ["audioop"] ignore = [ "audioop/__init__.py", # Pyright can't see the shared object being imported from. ] reportPrivateUsage = "none" reportUnnecessaryTypeIgnoreComment = "warning" # configuration common between all platforms, rest is defined in the GH Actions workflow [tool.cibuildwheel] test-command = "python {project}/tests/test_audioop.py" audioop-0.2.1/setup.py000066400000000000000000000010541465376466600147130ustar00rootroot00000000000000import sysconfig from setuptools import Extension, setup Py_GIL_DISABLED = sysconfig.get_config_var("Py_GIL_DISABLED") macros = [] options = {} if not Py_GIL_DISABLED: macros.append(("Py_LIMITED_API", "0x030D0000")) options["bdist_wheel"] = {"py_limited_api": "cp313"} extensions = [ Extension( name="audioop._audioop", sources=["audioop/_audioop.c"], depends=["audioop/_audioop.c.h"], define_macros=macros, py_limited_api=not Py_GIL_DISABLED, ) ] setup(ext_modules=extensions, options=options) audioop-0.2.1/tests/000077500000000000000000000000001465376466600143435ustar00rootroot00000000000000audioop-0.2.1/tests/test_audioop.py000066400000000000000000000706601465376466600174250ustar00rootroot00000000000000import sys import unittest import audioop # pyright: ignore[reportShadowedImports] from collections.abc import Callable def pack(width: int, data: tuple[int, ...]) -> bytes: return b''.join(v.to_bytes(width, sys.byteorder, signed=True) for v in data) def unpack(width: int, data: bytes) -> list[int]: return [int.from_bytes(data[i: i + width], sys.byteorder, signed=True) for i in range(0, len(data), width)] packs: dict[int, Callable[[*tuple[int, ...]], bytes]] = { w: (lambda *data, width=w: pack(width, data)) for w in (1, 2, 3, 4) } maxvalues = {w: (1 << (8 * w - 1)) - 1 for w in (1, 2, 3, 4)} minvalues = {w: -1 << (8 * w - 1) for w in (1, 2, 3, 4)} datas = { 1: b'\x00\x12\x45\xbb\x7f\x80\xff', 2: packs[2](0, 0x1234, 0x4567, -0x4567, 0x7fff, -0x8000, -1), 3: packs[3](0, 0x123456, 0x456789, -0x456789, 0x7fffff, -0x800000, -1), 4: packs[4](0, 0x12345678, 0x456789ab, -0x456789ab, 0x7fffffff, -0x80000000, -1), } INVALID_DATA = [ (b'abc', 0), (b'abc', 2), (b'ab', 3), (b'abc', 4), ] class TestAudioop(unittest.TestCase): def test_max(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.max(b'', w), 0) self.assertEqual(audioop.max(bytearray(), w), 0) self.assertEqual(audioop.max(memoryview(b''), w), 0) p = packs[w] self.assertEqual(audioop.max(p(5), w), 5) self.assertEqual(audioop.max(p(5, -8, -1), w), 8) self.assertEqual(audioop.max(p(maxvalues[w]), w), maxvalues[w]) self.assertEqual(audioop.max(p(minvalues[w]), w), -minvalues[w]) self.assertEqual(audioop.max(datas[w], w), -minvalues[w]) def test_minmax(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.minmax(b'', w), (0x7fffffff, -0x80000000)) self.assertEqual(audioop.minmax(bytearray(), w), (0x7fffffff, -0x80000000)) self.assertEqual(audioop.minmax(memoryview(b''), w), (0x7fffffff, -0x80000000)) p = packs[w] self.assertEqual(audioop.minmax(p(5), w), (5, 5)) self.assertEqual(audioop.minmax(p(5, -8, -1), w), (-8, 5)) self.assertEqual(audioop.minmax(p(maxvalues[w]), w), (maxvalues[w], maxvalues[w])) self.assertEqual(audioop.minmax(p(minvalues[w]), w), (minvalues[w], minvalues[w])) self.assertEqual(audioop.minmax(datas[w], w), (minvalues[w], maxvalues[w])) def test_maxpp(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.maxpp(b'', w), 0) self.assertEqual(audioop.maxpp(bytearray(), w), 0) self.assertEqual(audioop.maxpp(memoryview(b''), w), 0) self.assertEqual(audioop.maxpp(packs[w](*range(100)), w), 0) self.assertEqual(audioop.maxpp(packs[w](9, 10, 5, 5, 0, 1), w), 10) self.assertEqual(audioop.maxpp(datas[w], w), maxvalues[w] - minvalues[w]) def test_avg(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.avg(b'', w), 0) self.assertEqual(audioop.avg(bytearray(), w), 0) self.assertEqual(audioop.avg(memoryview(b''), w), 0) p = packs[w] self.assertEqual(audioop.avg(p(5), w), 5) self .assertEqual(audioop.avg(p(5, 8), w), 6) self.assertEqual(audioop.avg(p(5, -8), w), -2) self.assertEqual(audioop.avg(p(maxvalues[w], maxvalues[w]), w), maxvalues[w]) self.assertEqual(audioop.avg(p(minvalues[w], minvalues[w]), w), minvalues[w]) self.assertEqual(audioop.avg(packs[4](0x50000000, 0x70000000), 4), 0x60000000) self.assertEqual(audioop.avg(packs[4](-0x50000000, -0x70000000), 4), -0x60000000) def test_avgpp(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.avgpp(b'', w), 0) self.assertEqual(audioop.avgpp(bytearray(), w), 0) self.assertEqual(audioop.avgpp(memoryview(b''), w), 0) self.assertEqual(audioop.avgpp(packs[w](*range(100)), w), 0) self.assertEqual(audioop.avgpp(packs[w](9, 10, 5, 5, 0, 1), w), 10) self.assertEqual(audioop.avgpp(datas[1], 1), 196) self.assertEqual(audioop.avgpp(datas[2], 2), 50534) self.assertEqual(audioop.avgpp(datas[3], 3), 12937096) self.assertEqual(audioop.avgpp(datas[4], 4), 3311897002) def test_rms(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.rms(b'', w), 0) self.assertEqual(audioop.rms(bytearray(), w), 0) self.assertEqual(audioop.rms(memoryview(b''), w), 0) p = packs[w] self.assertEqual(audioop.rms(p(*range(100)), w), 57) self.assertAlmostEqual(audioop.rms(p(maxvalues[w]) * 5, w), maxvalues[w], delta=1) self.assertAlmostEqual(audioop.rms(p(minvalues[w]) * 5, w), -minvalues[w], delta=1) self.assertEqual(audioop.rms(datas[1], 1), 77) self.assertEqual(audioop.rms(datas[2], 2), 20001) self.assertEqual(audioop.rms(datas[3], 3), 5120523) self.assertEqual(audioop.rms(datas[4], 4), 1310854152) def test_cross(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.cross(b'', w), -1) self.assertEqual(audioop.cross(bytearray(), w), -1) self.assertEqual(audioop.cross(memoryview(b''), w), -1) p = packs[w] self.assertEqual(audioop.cross(p(0, 1, 2), w), 0) self.assertEqual(audioop.cross(p(1, 2, -3, -4), w), 1) self.assertEqual(audioop.cross(p(-1, -2, 3, 4), w), 1) self.assertEqual(audioop.cross(p(0, minvalues[w]), w), 1) self.assertEqual(audioop.cross(p(minvalues[w], maxvalues[w]), w), 1) def test_add(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.add(b'', b'', w), b'') self.assertEqual(audioop.add(bytearray(), bytearray(), w), b'') self.assertEqual(audioop.add(memoryview(b''), memoryview(b''), w), b'') self.assertEqual(audioop.add(datas[w], b'\0' * len(datas[w]), w), datas[w]) self.assertEqual(audioop.add(datas[1], datas[1], 1), b'\x00\x24\x7f\x80\x7f\x80\xfe') self.assertEqual(audioop.add(datas[2], datas[2], 2), packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2)) self.assertEqual(audioop.add(datas[3], datas[3], 3), packs[3](0, 0x2468ac, 0x7fffff, -0x800000, 0x7fffff, -0x800000, -2)) self.assertEqual(audioop.add(datas[4], datas[4], 4), packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000, 0x7fffffff, -0x80000000, -2)) def test_bias(self): for w in 1, 2, 3, 4: for bias in 0, 1, -1, 127, -128, 0x7fffffff, -0x80000000: self.assertEqual(audioop.bias(b'', w, bias), b'') self.assertEqual(audioop.bias(bytearray(), w, bias), b'') self.assertEqual(audioop.bias(memoryview(b''), w, bias), b'') self.assertEqual(audioop.bias(datas[1], 1, 1), b'\x01\x13\x46\xbc\x80\x81\x00') self.assertEqual(audioop.bias(datas[1], 1, -1), b'\xff\x11\x44\xba\x7e\x7f\xfe') self.assertEqual(audioop.bias(datas[1], 1, 0x7fffffff), b'\xff\x11\x44\xba\x7e\x7f\xfe') self.assertEqual(audioop.bias(datas[1], 1, -0x80000000), datas[1]) self.assertEqual(audioop.bias(datas[2], 2, 1), packs[2](1, 0x1235, 0x4568, -0x4566, -0x8000, -0x7fff, 0)) self.assertEqual(audioop.bias(datas[2], 2, -1), packs[2](-1, 0x1233, 0x4566, -0x4568, 0x7ffe, 0x7fff, -2)) self.assertEqual(audioop.bias(datas[2], 2, 0x7fffffff), packs[2](-1, 0x1233, 0x4566, -0x4568, 0x7ffe, 0x7fff, -2)) self.assertEqual(audioop.bias(datas[2], 2, -0x80000000), datas[2]) self.assertEqual(audioop.bias(datas[3], 3, 1), packs[3](1, 0x123457, 0x45678a, -0x456788, -0x800000, -0x7fffff, 0)) self.assertEqual(audioop.bias(datas[3], 3, -1), packs[3](-1, 0x123455, 0x456788, -0x45678a, 0x7ffffe, 0x7fffff, -2)) self.assertEqual(audioop.bias(datas[3], 3, 0x7fffffff), packs[3](-1, 0x123455, 0x456788, -0x45678a, 0x7ffffe, 0x7fffff, -2)) self.assertEqual(audioop.bias(datas[3], 3, -0x80000000), datas[3]) self.assertEqual(audioop.bias(datas[4], 4, 1), packs[4](1, 0x12345679, 0x456789ac, -0x456789aa, -0x80000000, -0x7fffffff, 0)) self.assertEqual(audioop.bias(datas[4], 4, -1), packs[4](-1, 0x12345677, 0x456789aa, -0x456789ac, 0x7ffffffe, 0x7fffffff, -2)) self.assertEqual(audioop.bias(datas[4], 4, 0x7fffffff), packs[4](0x7fffffff, -0x6dcba989, -0x3a987656, 0x3a987654, -2, -1, 0x7ffffffe)) self.assertEqual(audioop.bias(datas[4], 4, -0x80000000), packs[4](-0x80000000, -0x6dcba988, -0x3a987655, 0x3a987655, -1, 0, 0x7fffffff)) def test_lin2lin(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.lin2lin(datas[w], w, w), datas[w]) self.assertEqual(audioop.lin2lin(bytearray(datas[w]), w, w), datas[w]) self.assertEqual(audioop.lin2lin(memoryview(datas[w]), w, w), datas[w]) self.assertEqual(audioop.lin2lin(datas[1], 1, 2), packs[2](0, 0x1200, 0x4500, -0x4500, 0x7f00, -0x8000, -0x100)) self.assertEqual(audioop.lin2lin(datas[1], 1, 3), packs[3](0, 0x120000, 0x450000, -0x450000, 0x7f0000, -0x800000, -0x10000)) self.assertEqual(audioop.lin2lin(datas[1], 1, 4), packs[4](0, 0x12000000, 0x45000000, -0x45000000, 0x7f000000, -0x80000000, -0x1000000)) self.assertEqual(audioop.lin2lin(datas[2], 2, 1), b'\x00\x12\x45\xba\x7f\x80\xff') self.assertEqual(audioop.lin2lin(datas[2], 2, 3), packs[3](0, 0x123400, 0x456700, -0x456700, 0x7fff00, -0x800000, -0x100)) self.assertEqual(audioop.lin2lin(datas[2], 2, 4), packs[4](0, 0x12340000, 0x45670000, -0x45670000, 0x7fff0000, -0x80000000, -0x10000)) self.assertEqual(audioop.lin2lin(datas[3], 3, 1), b'\x00\x12\x45\xba\x7f\x80\xff') self.assertEqual(audioop.lin2lin(datas[3], 3, 2), packs[2](0, 0x1234, 0x4567, -0x4568, 0x7fff, -0x8000, -1)) self.assertEqual(audioop.lin2lin(datas[3], 3, 4), packs[4](0, 0x12345600, 0x45678900, -0x45678900, 0x7fffff00, -0x80000000, -0x100)) self.assertEqual(audioop.lin2lin(datas[4], 4, 1), b'\x00\x12\x45\xba\x7f\x80\xff') self.assertEqual(audioop.lin2lin(datas[4], 4, 2), packs[2](0, 0x1234, 0x4567, -0x4568, 0x7fff, -0x8000, -1)) self.assertEqual(audioop.lin2lin(datas[4], 4, 3), packs[3](0, 0x123456, 0x456789, -0x45678a, 0x7fffff, -0x800000, -1)) def test_adpcm2lin(self): self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 1, None), (b'\x00\x00\x00\xff\x00\xff', (-179, 40))) self.assertEqual(audioop.adpcm2lin(bytearray(b'\x07\x7f\x7f'), 1, None), (b'\x00\x00\x00\xff\x00\xff', (-179, 40))) self.assertEqual(audioop.adpcm2lin(memoryview(b'\x07\x7f\x7f'), 1, None), (b'\x00\x00\x00\xff\x00\xff', (-179, 40))) self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 2, None), (packs[2](0, 0xb, 0x29, -0x16, 0x72, -0xb3), (-179, 40))) self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 3, None), (packs[3](0, 0xb00, 0x2900, -0x1600, 0x7200, -0xb300), (-179, 40))) self.assertEqual(audioop.adpcm2lin(b'\x07\x7f\x7f', 4, None), (packs[4](0, 0xb0000, 0x290000, -0x160000, 0x720000, -0xb30000), (-179, 40))) # Very cursory test for w in 1, 2, 3, 4: self.assertEqual(audioop.adpcm2lin(b'\0' * 5, w, None), (b'\0' * w * 10, (0, 0))) def test_lin2adpcm(self): self.assertEqual(audioop.lin2adpcm(datas[1], 1, None), (b'\x07\x7f\x7f', (-221, 39))) self.assertEqual(audioop.lin2adpcm(bytearray(datas[1]), 1, None), (b'\x07\x7f\x7f', (-221, 39))) self.assertEqual(audioop.lin2adpcm(memoryview(datas[1]), 1, None), (b'\x07\x7f\x7f', (-221, 39))) for w in 2, 3, 4: self.assertEqual(audioop.lin2adpcm(datas[w], w, None), (b'\x07\x7f\x7f', (31, 39))) # Very cursory test for w in 1, 2, 3, 4: self.assertEqual(audioop.lin2adpcm(b'\0' * w * 10, w, None), (b'\0' * 5, (0, 0))) def test_invalid_adpcm_state(self): # state must be a tuple or None, not an integer self.assertRaises(TypeError, audioop.adpcm2lin, b'\0', 1, 555) self.assertRaises(TypeError, audioop.lin2adpcm, b'\0', 1, 555) # Issues #24456, #24457: index out of range self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, -1)) self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0, 89)) self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, -1)) self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0, 89)) # value out of range self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (-0x8001, 0)) self.assertRaises(ValueError, audioop.adpcm2lin, b'\0', 1, (0x8000, 0)) self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (-0x8001, 0)) self.assertRaises(ValueError, audioop.lin2adpcm, b'\0', 1, (0x8000, 0)) def test_lin2alaw(self): self.assertEqual(audioop.lin2alaw(datas[1], 1), b'\xd5\x87\xa4\x24\xaa\x2a\x5a') self.assertEqual(audioop.lin2alaw(bytearray(datas[1]), 1), b'\xd5\x87\xa4\x24\xaa\x2a\x5a') self.assertEqual(audioop.lin2alaw(memoryview(datas[1]), 1), b'\xd5\x87\xa4\x24\xaa\x2a\x5a') for w in 2, 3, 4: self.assertEqual(audioop.lin2alaw(datas[w], w), b'\xd5\x87\xa4\x24\xaa\x2a\x55') def test_alaw2lin(self): encoded = b'\x00\x03\x24\x2a\x51\x54\x55\x58\x6b\x71\x7f'\ b'\x80\x83\xa4\xaa\xd1\xd4\xd5\xd8\xeb\xf1\xff' src = [-688, -720, -2240, -4032, -9, -3, -1, -27, -244, -82, -106, 688, 720, 2240, 4032, 9, 3, 1, 27, 244, 82, 106] for w in 1, 2, 3, 4: decoded = packs[w](*(x << (w * 8) >> 13 for x in src)) self.assertEqual(audioop.alaw2lin(encoded, w), decoded) self.assertEqual(audioop.alaw2lin(bytearray(encoded), w), decoded) self.assertEqual(audioop.alaw2lin(memoryview(encoded), w), decoded) encoded = bytes(range(256)) for w in 2, 3, 4: decoded = audioop.alaw2lin(encoded, w) self.assertEqual(audioop.lin2alaw(decoded, w), encoded) def test_lin2ulaw(self): self.assertEqual(audioop.lin2ulaw(datas[1], 1), b'\xff\xad\x8e\x0e\x80\x00\x67') self.assertEqual(audioop.lin2ulaw(bytearray(datas[1]), 1), b'\xff\xad\x8e\x0e\x80\x00\x67') self.assertEqual(audioop.lin2ulaw(memoryview(datas[1]), 1), b'\xff\xad\x8e\x0e\x80\x00\x67') for w in 2, 3, 4: self.assertEqual(audioop.lin2ulaw(datas[w], w), b'\xff\xad\x8e\x0e\x80\x00\x7e') def test_ulaw2lin(self): encoded = b'\x00\x0e\x28\x3f\x57\x6a\x76\x7c\x7e\x7f'\ b'\x80\x8e\xa8\xbf\xd7\xea\xf6\xfc\xfe\xff' src = [-8031, -4447, -1471, -495, -163, -53, -18, -6, -2, 0, 8031, 4447, 1471, 495, 163, 53, 18, 6, 2, 0] for w in 1, 2, 3, 4: decoded = packs[w](*(x << (w * 8) >> 14 for x in src)) self.assertEqual(audioop.ulaw2lin(encoded, w), decoded) self.assertEqual(audioop.ulaw2lin(bytearray(encoded), w), decoded) self.assertEqual(audioop.ulaw2lin(memoryview(encoded), w), decoded) # Current u-law implementation has two codes fo 0: 0x7f and 0xff. encoded = bytes(range(127)) + bytes(range(128, 256)) for w in 2, 3, 4: decoded = audioop.ulaw2lin(encoded, w) self.assertEqual(audioop.lin2ulaw(decoded, w), encoded) def test_mul(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.mul(b'', w, 2), b'') self.assertEqual(audioop.mul(bytearray(), w, 2), b'') self.assertEqual(audioop.mul(memoryview(b''), w, 2), b'') self.assertEqual(audioop.mul(datas[w], w, 0), b'\0' * len(datas[w])) self.assertEqual(audioop.mul(datas[w], w, 1), datas[w]) self.assertEqual(audioop.mul(datas[1], 1, 2), b'\x00\x24\x7f\x80\x7f\x80\xfe') self.assertEqual(audioop.mul(datas[2], 2, 2), packs[2](0, 0x2468, 0x7fff, -0x8000, 0x7fff, -0x8000, -2)) self.assertEqual(audioop.mul(datas[3], 3, 2), packs[3](0, 0x2468ac, 0x7fffff, -0x800000, 0x7fffff, -0x800000, -2)) self.assertEqual(audioop.mul(datas[4], 4, 2), packs[4](0, 0x2468acf0, 0x7fffffff, -0x80000000, 0x7fffffff, -0x80000000, -2)) def test_ratecv(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 8000, None), (b'', (-1, ((0, 0),)))) self.assertEqual(audioop.ratecv(bytearray(), w, 1, 8000, 8000, None), (b'', (-1, ((0, 0),)))) self.assertEqual(audioop.ratecv(memoryview(b''), w, 1, 8000, 8000, None), (b'', (-1, ((0, 0),)))) self.assertEqual(audioop.ratecv(b'', w, 5, 8000, 8000, None), (b'', (-1, ((0, 0),) * 5))) self.assertEqual(audioop.ratecv(b'', w, 1, 8000, 16000, None), (b'', (-2, ((0, 0),)))) self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None)[0], datas[w]) self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 1, 0)[0], datas[w]) state = None d1, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) d2, state = audioop.ratecv(b'\x00\x01\x02', 1, 1, 8000, 16000, state) self.assertEqual(d1 + d2, b'\000\000\001\001\002\001\000\000\001\001\002') for w in 1, 2, 3, 4: d0, state0 = audioop.ratecv(datas[w], w, 1, 8000, 16000, None) d, state = b'', None for i in range(0, len(datas[w]), w): d1, state = audioop.ratecv(datas[w][i:i + w], w, 1, 8000, 16000, state) d += d1 self.assertEqual(d, d0) self.assertEqual(state, state0) expected = { 1: packs[1](0, 0x0d, 0x37, -0x26, 0x55, -0x4b, -0x14), 2: packs[2](0, 0x0da7, 0x3777, -0x2630, 0x5673, -0x4a64, -0x129a), 3: packs[3](0, 0x0da740, 0x377776, -0x262fca, 0x56740c, -0x4a62fd, -0x1298c0), 4: packs[4](0, 0x0da740da, 0x37777776, -0x262fc962, 0x56740da6, -0x4a62fc96, -0x1298bf26), } for w in 1, 2, 3, 4: self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 3, 1)[0], expected[w]) self.assertEqual(audioop.ratecv(datas[w], w, 1, 8000, 8000, None, 30, 10)[0], expected[w]) self.assertRaises(TypeError, audioop.ratecv, b'', 1, 1, 8000, 8000, 42) self.assertRaises(TypeError, audioop.ratecv, b'', 1, 1, 8000, 8000, (1, (42,))) def test_reverse(self): for w in 1, 2, 3, 4: self.assertEqual(audioop.reverse(b'', w), b'') self.assertEqual(audioop.reverse(bytearray(), w), b'') self.assertEqual(audioop.reverse(memoryview(b''), w), b'') self.assertEqual(audioop.reverse(packs[w](0, 1, 2), w), packs[w](2, 1, 0)) def test_tomono(self): for w in 1, 2, 3, 4: data1 = datas[w] data2 = bytearray(2 * len(data1)) for k in range(w): data2[k::2*w] = data1[k::w] self.assertEqual(audioop.tomono(data2, w, 1, 0), data1) self.assertEqual(audioop.tomono(data2, w, 0, 1), b'\0' * len(data1)) for k in range(w): data2[k+w::2*w] = data1[k::w] self.assertEqual(audioop.tomono(data2, w, 0.5, 0.5), data1) self.assertEqual(audioop.tomono(bytearray(data2), w, 0.5, 0.5), data1) self.assertEqual(audioop.tomono(memoryview(data2), w, 0.5, 0.5), data1) def test_tostereo(self): for w in 1, 2, 3, 4: data1 = datas[w] data2 = bytearray(2 * len(data1)) for k in range(w): data2[k::2*w] = data1[k::w] self.assertEqual(audioop.tostereo(data1, w, 1, 0), data2) self.assertEqual(audioop.tostereo(data1, w, 0, 0), b'\0' * len(data2)) for k in range(w): data2[k+w::2*w] = data1[k::w] self.assertEqual(audioop.tostereo(data1, w, 1, 1), data2) self.assertEqual(audioop.tostereo(bytearray(data1), w, 1, 1), data2) self.assertEqual(audioop.tostereo(memoryview(data1), w, 1, 1), data2) def test_findfactor(self): self.assertEqual(audioop.findfactor(datas[2], datas[2]), 1.0) self.assertEqual(audioop.findfactor(bytearray(datas[2]), bytearray(datas[2])), 1.0) self.assertEqual(audioop.findfactor(memoryview(datas[2]), memoryview(datas[2])), 1.0) self.assertEqual(audioop.findfactor(b'\0' * len(datas[2]), datas[2]), 0.0) def test_findfit(self): self.assertEqual(audioop.findfit(datas[2], datas[2]), (0, 1.0)) self.assertEqual(audioop.findfit(bytearray(datas[2]), bytearray(datas[2])), (0, 1.0)) self.assertEqual(audioop.findfit(memoryview(datas[2]), memoryview(datas[2])), (0, 1.0)) self.assertEqual(audioop.findfit(datas[2], packs[2](1, 2, 0)), (1, 8038.8)) self.assertEqual(audioop.findfit(datas[2][:-2] * 5 + datas[2], datas[2]), (30, 1.0)) def test_findmax(self): self.assertEqual(audioop.findmax(datas[2], 1), 5) self.assertEqual(audioop.findmax(bytearray(datas[2]), 1), 5) self.assertEqual(audioop.findmax(memoryview(datas[2]), 1), 5) def test_getsample(self): for w in 1, 2, 3, 4: data = packs[w](0, 1, -1, maxvalues[w], minvalues[w]) self.assertEqual(audioop.getsample(data, w, 0), 0) self.assertEqual(audioop.getsample(bytearray(data), w, 0), 0) self.assertEqual(audioop.getsample(memoryview(data), w, 0), 0) self.assertEqual(audioop.getsample(data, w, 1), 1) self.assertEqual(audioop.getsample(data, w, 2), -1) self.assertEqual(audioop.getsample(data, w, 3), maxvalues[w]) self.assertEqual(audioop.getsample(data, w, 4), minvalues[w]) def test_byteswap(self): swapped_datas = { 1: datas[1], 2: packs[2](0, 0x3412, 0x6745, -0x6646, -0x81, 0x80, -1), 3: packs[3](0, 0x563412, -0x7698bb, 0x7798ba, -0x81, 0x80, -1), 4: packs[4](0, 0x78563412, -0x547698bb, 0x557698ba, -0x81, 0x80, -1), } for w in 1, 2, 3, 4: self.assertEqual(audioop.byteswap(b'', w), b'') self.assertEqual(audioop.byteswap(datas[w], w), swapped_datas[w]) self.assertEqual(audioop.byteswap(swapped_datas[w], w), datas[w]) self.assertEqual(audioop.byteswap(bytearray(datas[w]), w), swapped_datas[w]) self.assertEqual(audioop.byteswap(memoryview(datas[w]), w), swapped_datas[w]) def test_negativelen(self): # from issue 3306, previously it segfaulted self.assertRaises(audioop.error, audioop.findmax, bytes(range(256)), -2392392) def test_issue7673(self): state = None for data, size in INVALID_DATA: size2 = size self.assertRaises(audioop.error, audioop.getsample, data, size, 0) self.assertRaises(audioop.error, audioop.max, data, size) self.assertRaises(audioop.error, audioop.minmax, data, size) self.assertRaises(audioop.error, audioop.avg, data, size) self.assertRaises(audioop.error, audioop.rms, data, size) self.assertRaises(audioop.error, audioop.avgpp, data, size) self.assertRaises(audioop.error, audioop.maxpp, data, size) self.assertRaises(audioop.error, audioop.cross, data, size) self.assertRaises(audioop.error, audioop.mul, data, size, 1.0) self.assertRaises(audioop.error, audioop.tomono, data, size, 0.5, 0.5) self.assertRaises(audioop.error, audioop.tostereo, data, size, 0.5, 0.5) self.assertRaises(audioop.error, audioop.add, data, data, size) self.assertRaises(audioop.error, audioop.bias, data, size, 0) self.assertRaises(audioop.error, audioop.reverse, data, size) self.assertRaises(audioop.error, audioop.lin2lin, data, size, size2) self.assertRaises(audioop.error, audioop.ratecv, data, size, 1, 1, 1, state) self.assertRaises(audioop.error, audioop.lin2ulaw, data, size) self.assertRaises(audioop.error, audioop.lin2alaw, data, size) self.assertRaises(audioop.error, audioop.lin2adpcm, data, size, state) def test_string(self): data = 'abcd' size = 2 self.assertRaises(TypeError, audioop.getsample, data, size, 0) self.assertRaises(TypeError, audioop.max, data, size) self.assertRaises(TypeError, audioop.minmax, data, size) self.assertRaises(TypeError, audioop.avg, data, size) self.assertRaises(TypeError, audioop.rms, data, size) self.assertRaises(TypeError, audioop.avgpp, data, size) self.assertRaises(TypeError, audioop.maxpp, data, size) self.assertRaises(TypeError, audioop.cross, data, size) self.assertRaises(TypeError, audioop.mul, data, size, 1.0) self.assertRaises(TypeError, audioop.tomono, data, size, 0.5, 0.5) self.assertRaises(TypeError, audioop.tostereo, data, size, 0.5, 0.5) self.assertRaises(TypeError, audioop.add, data, data, size) self.assertRaises(TypeError, audioop.bias, data, size, 0) self.assertRaises(TypeError, audioop.reverse, data, size) self.assertRaises(TypeError, audioop.lin2lin, data, size, size) self.assertRaises(TypeError, audioop.ratecv, data, size, 1, 1, 1, None) self.assertRaises(TypeError, audioop.lin2ulaw, data, size) self.assertRaises(TypeError, audioop.lin2alaw, data, size) self.assertRaises(TypeError, audioop.lin2adpcm, data, size, None) def test_wrongsize(self): data = b'abcdefgh' state = None for size in (-1, 0, 5, 1024): self.assertRaises(audioop.error, audioop.ulaw2lin, data, size) self.assertRaises(audioop.error, audioop.alaw2lin, data, size) self.assertRaises(audioop.error, audioop.adpcm2lin, data, size, state) if __name__ == '__main__': unittest.main()