{"id":13618642,"url":"https://github.com/danilobellini/audiolazy","last_synced_at":"2025-12-25T00:56:48.779Z","repository":{"id":5002730,"uuid":"6160997","full_name":"danilobellini/audiolazy","owner":"danilobellini","description":"Expressive Digital Signal Processing (DSP) package for Python","archived":false,"fork":false,"pushed_at":"2022-04-30T15:01:28.000Z","size":1439,"stargazers_count":691,"open_issues_count":12,"forks_count":74,"subscribers_count":57,"default_branch":"master","last_synced_at":"2024-11-07T00:06:36.251Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"miketheman/nginx","license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danilobellini.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":null,"funding":null,"license":"COPYING.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-10-10T17:09:35.000Z","updated_at":"2024-10-13T13:06:20.000Z","dependencies_parsed_at":"2022-08-31T23:13:03.931Z","dependency_job_id":null,"html_url":"https://github.com/danilobellini/audiolazy","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danilobellini%2Faudiolazy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danilobellini%2Faudiolazy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danilobellini%2Faudiolazy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danilobellini%2Faudiolazy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danilobellini","download_url":"https://codeload.github.com/danilobellini/audiolazy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223633393,"owners_count":17176803,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:00:28.016Z","updated_at":"2025-12-25T00:56:48.739Z","avatar_url":"https://github.com/danilobellini.png","language":"Python","funding_links":[],"categories":["Audio","资源列表","Analysis and Visualization","Python","Audio Related Packages","Awesome Python"],"sub_categories":["音频","Audio"],"readme":"..\r\n  This file is part of AudioLazy, the signal processing Python package.\r\n  Copyright (C) 2012-2016 Danilo de Jesus da Silva Bellini\r\n\r\n  AudioLazy is free software: you can redistribute it and/or modify\r\n  it under the terms of the GNU General Public License as published by\r\n  the Free Software Foundation, version 3 of the License.\r\n\r\n  This program is distributed in the hope that it will be useful,\r\n  but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n  GNU General Public License for more details.\r\n\r\n  You should have received a copy of the GNU General Public License\r\n  along with this program. If not, see \u003chttp://www.gnu.org/licenses/\u003e.\r\n\r\nAudioLazy\r\n=========\r\n\r\n.. list-table::\r\n  :stub-columns: 1\r\n\r\n  * - Development\r\n    - |travis| |coveralls|\r\n  * - Last release\r\n    - |v| |pyversions| |implementation|\r\n  * - PyPI status\r\n    - |format| |status| |l|\r\n\r\n.. |travis| image::\r\n  https://img.shields.io/travis/danilobellini/audiolazy/master.svg\r\n  :target: https://travis-ci.org/danilobellini/audiolazy\r\n  :alt: Travis CI builds\r\n\r\n.. |coveralls| image::\r\n  https://img.shields.io/coveralls/danilobellini/audiolazy/master.svg\r\n  :target: https://coveralls.io/r/danilobellini/audiolazy\r\n  :alt: Coveralls coverage report\r\n\r\n.. |v| image::\r\n  https://img.shields.io/pypi/v/audiolazy.svg\r\n  :target: https://pypi.python.org/pypi/audiolazy\r\n  :alt: Last stable version (PyPI)\r\n\r\n.. |pyversions| image::\r\n  https://img.shields.io/pypi/pyversions/audiolazy.svg\r\n  :target: https://pypi.python.org/pypi/audiolazy\r\n  :alt: Python versions (PyPI)\r\n\r\n.. |implementation| image::\r\n  https://img.shields.io/pypi/implementation/audiolazy.svg\r\n  :target: https://pypi.python.org/pypi/audiolazy\r\n  :alt: Python implementations (PyPI)\r\n\r\n.. |format| image::\r\n  https://img.shields.io/pypi/format/audiolazy.svg\r\n  :target: https://pypi.python.org/pypi/audiolazy\r\n  :alt: Distribution format (PyPI)\r\n\r\n.. |status| image::\r\n  https://img.shields.io/pypi/status/audiolazy.svg\r\n  :target: https://pypi.python.org/pypi/audiolazy\r\n  :alt: Project status (PyPI)\r\n\r\n.. |l| image::\r\n  https://img.shields.io/pypi/l/audiolazy.svg\r\n  :target: https://pypi.python.org/pypi/audiolazy\r\n  :alt: License (PyPI)\r\n\r\nReal-Time Expressive Digital Signal Processing (DSP) Package for Python!\r\n\r\nLaziness and object representation\r\n----------------------------------\r\n\r\nThere are several tools and packages that let the Python use and\r\nexpressiveness look like languages such as MatLab and Octave. However, the\r\neager evaluation done by most of these tools make it difficult, perhaps\r\nimpossible, to use them for real time audio processing. To avoid such\r\neagerness, one can make the calculations only when data is requested, not\r\nwhen the path to the data is given. This is the core idea in laziness that\r\nallows:\r\n\r\n- Real-time application (you don't need to wait until all data is\r\n  processed to have a result);\r\n- Endless data sequence representation;\r\n- Data-flow representation;\r\n- Task elimination when a reverse task is done: instead of doing something\r\n  to then undo, nothing needs to be done, and no conscious optimization\r\n  need to be done for that.\r\n\r\nAnother difficulty concerns expressive code creation for audio processing in\r\nblocks through indexes and vectors. Sometimes, that's unavoidable, or at\r\nleast such avoidance would limit the power of the system that works with\r\nsequence data.\r\n\r\nBlock sequences can be found from sample sequences being both objects, where\r\nthe latter can be the result of a method or function over the former. The\r\ninformation needed for such is the block size and where would start the next\r\nblock. Although one can think about the last block and the exact index where\r\nit would start, most of the time spent in steps like this one happens to be\r\nan implementation issue that just keep the focus away from the problem being\r\nworked on. To allow a thing like an endless data sequence, there should be\r\nno need to know when something stops.\r\n\r\nProbably an engineer would find the use of equations and structures from\r\nelectrical engineering theory much cleaner to understand than storing\r\neverything into data arrays, mainly when common operations are done to these\r\nrepresentations. What is the product of the filter with numerator\r\n``[1, 7, 2]`` and denominator ``[1, 0.5, 0.2]`` as its system equation with\r\nthe one that has the arrays reversed like ``[2, 7, 1]``? That might be simple,\r\nand the reversed would avoid questions like \"what comes first, the zero or the\r\n[minus] two exponent?\", but maybe we could get more efficient ourselves if we\r\nhad something easier: multiplication could be written once and for all and\r\nwith a representation programmers are used to see. This would be even more\r\nexpressive if we could get rid from the asymmetry of a method call like\r\n``filt1.multiply_by(filt2)``, since multiplication in this case should be\r\ncommutative. The use of natural operators is possible in a language that\r\nallows operator overloading, but for such we need to describe\r\nthose equations and structures as objects and object relationships.\r\n\r\nThe name ``Hz`` can be a number that would allow conversion to a default DSP\r\ninternal rad/samples unit, so one can write things like ``freq = 440 * Hz``.\r\nThis isn't difficult in probably any language, but can help in expressiveness,\r\nalready. If (almost) everything would need data in \"samples\" or \"rad/sample\"\r\nunits, constants for converting these from \"second\" and \"hertz\" would help\r\nwith the code expressiveness. A comb filter ``comb.tau(delay=30*s, tau=40*s)``\r\ncan represent a comb filter with the given delay and time constant, both in\r\nsamples, but with a more clear meaning for the reader than it would have with\r\nan expression like ``[1] + [0] * 239999 + [alpha]``. Would it be needed to\r\nstore all those zeros while just using the filter to get a frequency response\r\nplot?\r\n\r\nIt's possible to avoid some of these problems with well-chosen constants,\r\nduck typing, overloaded operators, functions as first-class citizens, object\r\noriented together with functional style programming, etc.., resources\r\nthat the Python language gives us for free.\r\n\r\nWhat does it do?\r\n----------------\r\n\r\nPrioritizing code expressiveness, clarity and simplicity, without precluding\r\nthe lazy evaluation, and aiming to be used together with Numpy, Scipy and\r\nMatplotlib as well as default Python structures like lists and generators,\r\nAudioLazy is a package written in pure Python proposing digital audio signal\r\nprocessing (DSP), featuring:\r\n\r\n- A ``Stream`` class for finite and endless signals representation with\r\n  elementwise operators (auto-broadcast with non-iterables) in a common\r\n  Python iterable container accepting heterogeneous data;\r\n- Strongly sample-based representation (Stream class) with easy conversion\r\n  to block representation using the ``Stream.blocks(size, hop)`` method;\r\n- Sample-based interactive processing with ``ControlStream``;\r\n- ``Streamix`` mixer for iterables given their starting time deltas;\r\n- Multi-thread audio I/O integration with PyAudio;\r\n- Linear filtering with Z-transform filters directly as equations (e.g.\r\n  ``filt = 1 / (1 - .3 * z ** -1)``), including linear time variant filters\r\n  (i.e., the ``a`` in ``a * z ** k`` can be a Stream instance), cascade\r\n  filters (behaves as a list of filters), resonators, etc.. Each\r\n  ``LinearFilter`` instance is compiled just in time when called;\r\n- Zeros and poles plots and frequency response plotting integration with\r\n  MatPlotLib;\r\n- Linear Predictive Coding (LPC) directly to ``ZFilter`` instances, from\r\n  which you can find PARCOR coeffs and LSFs;\r\n- Both sample-based (e.g., zero-cross rate, envelope, moving average,\r\n  clipping, unwrapping) and block-based (e.g., window functions, DFT,\r\n  autocorrelation, lag matrix) analysis and processing tools;\r\n- A simple synthesizer (Table lookup, Karplus-Strong) with processing tools\r\n  (Linear ADSR envelope, fade in/out, fixed duration line stream) and basic\r\n  wave data generation (sinusoid, white noise, impulse);\r\n- Biological auditory periphery modeling (ERB and gammatone filter models);\r\n- Multiple implementation organization as ``StrategyDict`` instances:\r\n  callable dictionaries that allows the same name to have several different\r\n  implementations (e.g. ``erb``, ``gammatone``, ``lowpass``, ``resonator``,\r\n  ``lpc``, ``window``);\r\n- Converters among MIDI pitch numbers, strings like \"F#4\" and frequencies;\r\n- Polynomials, Stream-based functions from itertools, math, cmath, and more!\r\n  Go try yourself! =)\r\n\r\nInstalling\r\n----------\r\n\r\nThe package works both on Linux and on Windows. You can find the last stable\r\nversion at `PyPI \u003chttp://pypi.python.org/pypi/audiolazy\u003e`_ and install it with\r\nthe usual Python installing mechanism::\r\n\r\n  python setup.py install\r\n\r\nIf you have pip, you can go directly (use ``-U`` for update or reinstall)::\r\n\r\n  pip install audiolazy\r\n\r\nfor downloading (from PyPI) and installing the package for you, or::\r\n\r\n  pip install -U .\r\n\r\nTo install from a path that has the ``setup.py`` file and the package data\r\nuncompressed previously.\r\n\r\nFor the *bleeding-edge* version, you can install directly from the github\r\nrepository (requires ``git`` for cloning)::\r\n\r\n  pip install -U git+git://github.com/danilobellini/audiolazy.git\r\n\r\nFor older versions, you can install from the PyPI link or directly from the\r\ngithub repository, based on the repository tags. For example, to install the\r\nversion 0.04 (requires ``git`` for cloning)::\r\n\r\n  pip install -U git+git://github.com/danilobellini/audiolazy.git@v0.04\r\n\r\nThe package doesn't have any strong dependency for its core besides the Python\r\nitself (versions 2.7, 3.2 or newer) as well as its standard library, but you\r\nmight need:\r\n\r\n- PyAudio: needed for playing and recording audio (``AudioIO`` class);\r\n- NumPy: needed for doing some maths, such as finding the LSFs from a filter\r\n  or roots from a polynomial;\r\n- MatPlotLib: needed for all default plotting, like in ``LinearFilter.plot``\r\n  method and several examples;\r\n- SciPy (testing and examples only): used as an oracle for LTI filter testing\r\n  and for the Butterworth filter example;\r\n- Sympy (testing only): used for testing linear filters with time-varying\r\n  matrices of symbolic coeffs where the Stream samples are these matrices;\r\n- tox for testing all at once, or pytest, pytest-cov and pytest-timeout for\r\n  testing in a single environment (testing only): runs test suite and\r\n  shows code coverage status;\r\n- wxPython (example only): used by one example with FM synthesis in an\r\n  interactive GUI;\r\n- Tkinter (example only): needed for the pitch follower based on the\r\n  zero-crossing rate example GUI;\r\n- Music21 (example only): there's one example that gets the Bach chorals from\r\n  that package corpora for synthesizing and playing;\r\n- Sphinx (documentation only): it can create the software documentation in\r\n  several different file formats.\r\n\r\nBeside examples and tests, only the filter plotting with ``plot`` and\r\n``zplot`` methods needs MatPlotLib. Also, the routines that needs NumPy up to\r\nnow are:\r\n\r\n- Root finding with ``zeros`` and ``poles`` properties (filter classes) or\r\n  with ``roots`` property (Poly class);\r\n- Some Linear Predictive Coding (``lpc``) strategies: ``nautocor``,\r\n  ``autocor`` and ``covar``;\r\n- Line Spectral Frequencies ``lsf`` and ``lsf_stable`` functions.\r\n\r\nGetting started\r\n---------------\r\n\r\nBefore all examples below, it's easier to get everything from audiolazy\r\nnamespace:\r\n\r\n.. code-block:: python\r\n\r\n  from audiolazy import *\r\n\r\nAll modules starts with \"lazy\\_\", but their data is already loaded in the main\r\nnamespace. These two lines of code do the same thing:\r\n\r\n.. code-block:: python\r\n\r\n  from audiolazy.lazy_stream import Stream\r\n  from audiolazy import Stream\r\n\r\nEndless iterables with operators (be careful with loops through an endless\r\niterator!):\r\n\r\n.. code-block:: python\r\n\r\n  \u003e\u003e\u003e a = Stream(2, -2, -1) # Periodic\r\n  \u003e\u003e\u003e b = Stream(3, 7, 5, 4) # Periodic\r\n  \u003e\u003e\u003e c = a + b # Elementwise sum, periodic\r\n  \u003e\u003e\u003e c.take(15) # First 15 elements from the Stream object\r\n  [5, 5, 4, 6, 1, 6, 7, 2, 2, 9, 3, 3, 5, 5, 4]\r\n\r\nAnd also finite iterators (you can think on any Stream as a generator with\r\nelementwise operators):\r\n\r\n.. code-block:: python\r\n\r\n  \u003e\u003e\u003e a = Stream([1, 2, 3, 2, 1]) # Finite, since it's a cast from an iterable\r\n  \u003e\u003e\u003e b = Stream(3, 7, 5, 4) # Periodic\r\n  \u003e\u003e\u003e c = a + b # Elementwise sum, finite\r\n  \u003e\u003e\u003e list(c)\r\n  [4, 9, 8, 6, 4]\r\n\r\nLTI Filtering from system equations (Z-transform). After this, try summing,\r\ncomposing, multiplying ZFilter objects:\r\n\r\n.. code-block:: python\r\n\r\n  \u003e\u003e\u003e filt = 1 - z ** -1 # Diff between a sample and the previous one\r\n  \u003e\u003e\u003e filt\r\n  1 - z^-1\r\n  \u003e\u003e\u003e data = filt([.1, .2, .4, .3, .2, -.1, -.3, -.2]) # Past memory has 0.0\r\n  \u003e\u003e\u003e data # This should have internally [.1, .1, .2, -.1, -.1, -.3, -.2, .1]\r\n  \u003caudiolazy.lazy_stream.Stream object at ...\u003e\r\n  \u003e\u003e\u003e data *= 10 # Elementwise gain\r\n  \u003e\u003e\u003e [int(round(x)) for x in data] # Streams are iterables\r\n  [1, 1, 2, -1, -1, -3, -2, 1]\r\n  \u003e\u003e\u003e data_int = filt([1, 2, 4, 3, 2, -1, -3, -2], zero=0) # Now zero is int\r\n  \u003e\u003e\u003e list(data_int)\r\n  [1, 1, 2, -1, -1, -3, -2, 1]\r\n\r\nLTI Filter frequency response plot (needs MatPlotLib):\r\n\r\n.. code-block:: python\r\n\r\n  (1 + z ** -2).plot().show()\r\n\r\n.. image:: images/filt_plot.png\r\n\r\nThe ``matplotlib.figure.Figure.show`` method won't work unless you're\r\nusing a newer version of MatPlotLib (works on MatPlotLib 1.2.0), but you still\r\ncan save the above plot directly to a PDF, PNG, etc. with older versions\r\n(e.g. MatPlotLib 1.0.1):\r\n\r\n.. code-block:: python\r\n\r\n  (1 + z ** -2).plot().savefig(\"my_plot.pdf\")\r\n\r\nOn the other hand, you can always show the figure using MatPlotLib directly:\r\n\r\n.. code-block:: python\r\n\r\n  from matplotlib import pyplot as plt # Or \"import pylab as plt\"\r\n  filt = 1 + z ** -2\r\n  fig1 = filt.plot(plt.figure()) # Argument not needed on the first figure\r\n  fig2 = filt.zplot(plt.figure()) # The argument ensures a new figure\r\n  plt.show()\r\n\r\nCascadeFilter instances and ParallelFilter instances are lists of filters with\r\nthe same operator behavior as a list, and also works for plotting linear\r\nfilters. Constructors accepts both a filter and an iterable with filters.\r\nFor example, a zeros and poles plot (needs MatPlotLib):\r\n\r\n.. code-block:: python\r\n\r\n  filt1 = CascadeFilter(0.2 - z ** -3) # 3 zeros\r\n  filt2 = CascadeFilter(1 / (1 -.8 * z ** -1 + .6 * z ** -2)) # 2 poles\r\n  # Here __add__ concatenates and __mul__ by an integer make reference copies\r\n  filt = (filt1 * 5 + filt2 * 10) # 15 zeros and 20 poles\r\n  filt.zplot().show()\r\n\r\n.. image:: images/cascade_plot.png\r\n\r\nLinear Predictive Coding (LPC) autocorrelation method analysis filter\r\nfrequency response plot (needs MatPlotLib):\r\n\r\n.. code-block:: python\r\n\r\n  lpc([1, -2, 3, -4, -3, 2, -3, 2, 1], order=3).plot().show()\r\n\r\n.. image:: images/lpc_plot.png\r\n\r\nLinear Predictive Coding covariance method analysis and synthesis filter,\r\nfollowed by the frequency response plot together with block data DFT\r\n(MatPlotLib):\r\n\r\n.. code-block:: python\r\n\r\n  \u003e\u003e\u003e data = Stream(-1., 0., 1., 0.) # Periodic\r\n  \u003e\u003e\u003e blk = data.take(200)\r\n  \u003e\u003e\u003e analysis_filt = lpc.covar(blk, 4)\r\n  \u003e\u003e\u003e analysis_filt\r\n  1 + 0.5 * z^-2 - 0.5 * z^-4\r\n  \u003e\u003e\u003e residual = list(analysis_filt(blk))\r\n  \u003e\u003e\u003e residual[:10]\r\n  [-1.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]\r\n  \u003e\u003e\u003e synth_filt = 1 / analysis_filt\r\n  \u003e\u003e\u003e synth_filt(residual).take(10)\r\n  [-1.0, 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0, 0.0]\r\n  \u003e\u003e\u003e amplified_blk = list(Stream(blk) * -200) # For alignment w/ DFT\r\n  \u003e\u003e\u003e synth_filt.plot(blk=amplified_blk).show()\r\n\r\n.. image:: images/dft_lpc_plot.png\r\n\r\nAudioLazy doesn't need any audio card to process audio, but needs PyAudio to\r\nplay some sound:\r\n\r\n.. code-block:: python\r\n\r\n  rate = 44100 # Sampling rate, in samples/second\r\n  s, Hz = sHz(rate) # Seconds and hertz\r\n  ms = 1e-3 * s\r\n  note1 = karplus_strong(440 * Hz) # Pluck \"digitar\" synth\r\n  note2 = zeros(300 * ms).append(karplus_strong(880 * Hz))\r\n  notes = (note1 + note2) * .5\r\n  sound = notes.take(int(2 * s)) # 2 seconds of a Karplus-Strong note\r\n  with AudioIO(True) as player: # True means \"wait for all sounds to stop\"\r\n    player.play(sound, rate=rate)\r\n\r\nSee also the docstrings and the \"examples\" directory at the github repository\r\nfor more help. Also, the huge test suite might help you understanding how the\r\npackage works and how to use it.\r\n\r\nProject files\r\n-------------\r\n\r\nThere are several files and directories in the AudioLazy repository (as well\r\nas in the source distribution):\r\n\r\n================ =============================================================\r\nFile/Directory   Description\r\n================ =============================================================\r\naudiolazy/       AudioLazy package modules source code\r\naudiolazy/tests/ Testing subpackage\r\ndocs/            Documentation generation scripts\r\nexamples/        Examples for some AudioLazy use cases\r\nimages/          Images referenced by some reStructuredText documentation file\r\nmath/            Proof for some formula used by AudioLazy using Sympy CAS\r\nCHANGES.rst      AudioLazy History, a.k.a. change log\r\nconftest.py      Configuration for py.test, to work properly with doctests on\r\n                 StrategyDict strategies and on an environment missing Numpy\r\nCOPYING.txt      License file\r\nMANIFEST.in      List of extra distributed files to be included in the tarball\r\n                 that doesn't need to be installed together with the package\r\nREADME.rst       Some general information about the AudioLazy project\r\nsetup.py         General Python setup script for installation, testing, etc.\r\ntox.ini          Configuration for tox, py.test and pytest-cov\r\n.travis.yml      Travis-CI configuration (not in PyPI tarball/\"egg\" source\r\n                 distribution)\r\n================ =============================================================\r\n\r\nThe ``examples`` and the ``math`` directories might be useful for an AudioLazy\r\nuser. All Python files in these two directories are scripts intended to run on\r\nboth Python 2 and 3 unless they need something not yet available for Python 3\r\n(e.g. wxPython), most of them have some external dependency.\r\n\r\n----\r\n\r\nCopyright (C) 2012-2016 Danilo de Jesus da Silva Bellini\r\n\r\nLicense is GPLv3. See COPYING.txt for more details.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanilobellini%2Faudiolazy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanilobellini%2Faudiolazy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanilobellini%2Faudiolazy/lists"}