{"id":15114255,"url":"https://github.com/jmrplens/PyOctaveBand","last_synced_at":"2025-09-27T18:30:32.964Z","repository":{"id":152919635,"uuid":"275682981","full_name":"jmrplens/PyOctaveBand","owner":"jmrplens","description":"[Python3] Octave-Band and Fractional Octave-Band filter. For signal in time domain. ","archived":false,"fork":false,"pushed_at":"2023-07-06T23:33:18.000Z","size":1181,"stargazers_count":79,"open_issues_count":6,"forks_count":18,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-01-11T18:23:15.541Z","etag":null,"topics":["acoustics","audio","filter","frequency","frequency-analysis","frequency-domain","octave","python3","signal","time-domain"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jmrplens.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"jmrplens","patreon":null,"open_collective":null,"ko_fi":"jmrplens","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":"https://www.paypal.com/donate?hosted_button_id=BLP3R6VGYJB4Q"}},"created_at":"2020-06-28T23:01:25.000Z","updated_at":"2025-01-06T16:55:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"b5ae8afb-2458-41dd-8c28-2278ba05f9a6","html_url":"https://github.com/jmrplens/PyOctaveBand","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmrplens%2FPyOctaveBand","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmrplens%2FPyOctaveBand/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmrplens%2FPyOctaveBand/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmrplens%2FPyOctaveBand/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jmrplens","download_url":"https://codeload.github.com/jmrplens/PyOctaveBand/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234450832,"owners_count":18834583,"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":["acoustics","audio","filter","frequency","frequency-analysis","frequency-domain","octave","python3","signal","time-domain"],"created_at":"2024-09-26T01:41:07.170Z","updated_at":"2025-09-27T18:30:32.599Z","avatar_url":"https://github.com/jmrplens.png","language":"Python","funding_links":["https://github.com/sponsors/jmrplens","https://ko-fi.com/jmrplens","https://www.paypal.com/donate?hosted_button_id=BLP3R6VGYJB4Q"],"categories":["Signal Processing"],"sub_categories":[],"readme":"[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate?hosted_button_id=BLP3R6VGYJB4Q)\n[![Donate](https://img.shields.io/badge/Donate-Ko--fi-brightgreen?color=ff5f5f)](https://ko-fi.com/jmrplens) \n\n# PyOctaveBand\nOctave-Band and Fractional Octave-Band filter. For signal in time domain.\n\n### Public Methods\n\n##### octavefilter\nThe function that filters the input signal according to the selected parameters.\n```python\nx # signal\nfs # sample rate\nfraction # Bandwidth 'b'. Examples: 1/3-octave b=3, 1-octave b=1, 2/3-octave b = 3/2. [Optional] Default: 1\norder # Order of Butterworth filter. [Optional] Default: 6.\nlimits # Minimum and maximum limit frequencies. [Optional] Default [12,20000]\nshow # Boolean for plot o not the filter response.\nsigbands # Boolean to also return the signal in the time domain divided into bands. A list with as many arrays as there are frequency bands\n\n# Only octave spectra\nspl, freq = octavefilter(x, fs, fraction=1, order=6, limits=None, show=0, sigbands=0)\n\n# Octave spectra and bands in time domain\nspl, freq, xb = octavefilter(x, fs, fraction=1, order=6, limits=None, show=0, sigbands=1)\n```\n\n##### getansifrequencies\nReturns the frequency vector according to ANSI s1.11-2004 and IEC 61260-1-2014 standards.\n\n```python\nfraction # Bandwidth 'b'. Examples: 1/3-octave b=3, 1-octave b=1, 2/3-octave b = 3/2.\nlimits # Minimum and maximum limit frequencies. [Optional] Default [12,20000]\nfreq = getansifrequencies(fraction, limits=None)\n```\n\n##### normalizedfreq\nReturns the normalized frequency vector according to ANSI s1.11-2004 and IEC 61260-1-2014. Only for octave and third octave bands.\n```python\nfraction # Bandwidth 'b'. For 1/3-octave b=3 and b=1 for one-octave.\nfreq = normalizedfreq(fraction)\n```\n\n### The filter\nThe filter used to design the octave filter bank is a Butterworth with SOS coefficients. You can find more information about the filter here: [scipy.signal.butter](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.butter.html).\n\n### Frequency values\nThe values of the center frequencies and the upper and lower edges are obtained with the calculation defined in the ANSI s1.11-2004 and IEC 61260-1-2014 standards.\n\n### Automatic downsampling\nTo obtain the best filter coefficients, especially at low frequency, it is necessary to downsampling, this is done automatically by calculating the necessary downsampling factor for each frequency band.\n\n```python\nfs # sample rate\nfreq # frequency\nfactor = ((fs / 2) / freq)\n```\nThe resampling is done with the resample function of the [SciPy library](https://www.scipy.org/scipylib/index.html) (Thanks to [@ashley-b](https://github.com/ashley-b) - [ISSUE](https://github.com/jmrplens/PyOctaveBand/issues/2)) :\n\n```python\nx # signal\nxdown = signal.resample(x, round(len(x) / factor))\n```\n\n### Anti-aliasing\nThe frequency bands of the filters that are above the Nyquist's frequency (`sample_rate/2`) are automatically removed because the values will not be correct.\n\n\n### Examples of filter responses\n| Fraction | Butterworth order: 6       | Butterworth order: 16      | \n|:-------------:|:-------------:|:-------------:|\n| 1-octave | \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/one.png\" width=\"100%\"\u003e\u003c/img\u003e      | \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/one16.png\" width=\"100%\"\u003e\u003c/img\u003e  |\n| 1/3-octave | \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/third.png\" width=\"100%\"\u003e\u003c/img\u003e      | \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/third16.png\" width=\"100%\"\u003e\u003c/img\u003e  |\n| 2/3-octave | \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/twothird.png\" width=\"100%\"\u003e\u003c/img\u003e      | \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/twothird16.png\" width=\"100%\"\u003e\u003c/img\u003e  |\n\n### Usage example\n\nThis example is included in the file test.py.\n\n```python\nimport PyOctaveBand\nimport numpy as np\nimport scipy.io.wavfile\n\n# Sample rate and duration\nfs = 48000\nduration = 5  # In seconds\n\n# Time array\nx = np.arange(np.round(fs * duration)) / fs\n\n# Signal with 6 frequencies\nf1, f2, f3, f4, f5, f6 = 20, 100, 500, 2000, 4000, 15000\n# Multi Sine wave signal\ny = 100 \\\n    * (np.sin(2 * np.pi * f1 * x)\n       + np.sin(2 * np.pi * f2 * x)\n       + np.sin(2 * np.pi * f3 * x)\n       + np.sin(2 * np.pi * f4 * x)\n       + np.sin(2 * np.pi * f5 * x)\n       + np.sin(2 * np.pi * f6 * x))\n\n# Filter (only octave spectra)\nspl, freq = PyOctaveBand.octavefilter(y, fs=fs, fraction=3, order=6, limits=[12, 20000], show=1)\n\n# Filter (get spectra and signal in bands)\nsplb, freqb, xb = PyOctaveBand.octavefilter(y, fs=fs, fraction=3, order=6, limits=[12, 20000], show=0, sigbands=1)\n\n# Store signal in bands in separated wav files\nfor idx in range(len(freq)):\n    scipy.io.wavfile.write(\n            \"test_\"+str(round(freq[idx]))+\"_Hz.wav\",\n            fs,\n            xb[idx]/np.max(xb[idx]))\n```\n\nThe result is as follows:\n\n| One Octave filter       | One-Third Octave filter      | \n|:-------------:|:-------------:|\n| \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/response1.png\" width=\"100%\"\u003e\u003c/img\u003e      | \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/response.png\" width=\"100%\"\u003e\u003c/img\u003e  |\n\n| 1/12 Octave filter       | 1/24 Octave filter      | \n|:-------------:|:-------------:|\n| \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/12.png\" width=\"100%\"\u003e\u003c/img\u003e      | \u003cimg src=\"https://github.com/jmrplens/PyOctaveBand/blob/1670365c01c70383e1c142c24fa91563cb9342b9/.github/images/24.png\" width=\"100%\"\u003e\u003c/img\u003e  |\n\n# Roadmap\n\n- Add multichannel support\n\nIf you have any suggestions or you found an error please, make a [Pull Request](https://github.com/jmrplens/PyOctave/pulls) or [contact me](mailto:info@jmrplens.com).\n\n# Author\nJose M. Requena Plens, 2020.\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/donate?hosted_button_id=BLP3R6VGYJB4Q)\n[![Donate](https://img.shields.io/badge/Donate-Ko--fi-brightgreen?color=ff5f5f)](https://ko-fi.com/jmrplens) \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmrplens%2FPyOctaveBand","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjmrplens%2FPyOctaveBand","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmrplens%2FPyOctaveBand/lists"}