PyOctaveBand 1.0.2__tar.gz → 1.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyoctaveband-1.0.2/src/PyOctaveBand.egg-info → pyoctaveband-1.0.4}/PKG-INFO +22 -23
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/README.md +21 -22
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/pyproject.toml +1 -1
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4/src/PyOctaveBand.egg-info}/PKG-INFO +22 -23
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/LICENSE +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/setup.cfg +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/PyOctaveBand.egg-info/SOURCES.txt +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/PyOctaveBand.egg-info/dependency_links.txt +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/PyOctaveBand.egg-info/requires.txt +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/PyOctaveBand.egg-info/top_level.txt +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/pyoctaveband/__init__.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/pyoctaveband/calibration.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/pyoctaveband/core.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/pyoctaveband/filter_design.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/pyoctaveband/frequencies.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/pyoctaveband/parametric_filters.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/src/pyoctaveband/utils.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/tests/test_advanced.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/tests/test_audio_processing.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/tests/test_basic.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/tests/test_coverage_gap.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/tests/test_errors_and_edge_cases.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/tests/test_multichannel.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/tests/test_parametric.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/tests/test_parametric_filters.py +0 -0
- {pyoctaveband-1.0.2 → pyoctaveband-1.0.4}/tests/test_performance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyOctaveBand
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Octave-Band and Fractional Octave-Band filter for signals in time domain.
|
|
5
5
|
Author-email: Jose Manuel Requena Plens <jmrplens@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/jmrplens/PyOctaveBand
|
|
@@ -66,23 +66,22 @@ Now available on [PyPI](https://pypi.org/project/PyOctaveBand/).
|
|
|
66
66
|
|
|
67
67
|
### Installation
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
**Option 1: From PyPI (Recommended)**
|
|
70
|
+
Install `PyOctaveBand` directly using pip:
|
|
71
71
|
```bash
|
|
72
72
|
pip install PyOctaveBand
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
**Option 1: Cloning and Installing**
|
|
75
|
+
**Option 2: Cloning and Installing**
|
|
76
|
+
Clone the repository and install it manually:
|
|
78
77
|
```bash
|
|
79
78
|
git clone https://github.com/jmrplens/PyOctaveBand.git
|
|
80
79
|
cd PyOctaveBand
|
|
81
80
|
pip install .
|
|
82
81
|
```
|
|
83
82
|
|
|
84
|
-
**Option
|
|
85
|
-
Add PyOctaveBand as a dependency within your own git repository:
|
|
83
|
+
**Option 3: Git Submodule**
|
|
84
|
+
Add `PyOctaveBand` as a dependency within your own git repository:
|
|
86
85
|
```bash
|
|
87
86
|
git submodule add https://github.com/jmrplens/PyOctaveBand.git
|
|
88
87
|
# Then install in editable mode to use it from your project
|
|
@@ -117,7 +116,7 @@ PyOctaveBand supports several filter types, each with its own transfer function
|
|
|
117
116
|
### Filter Comparison and Zoom
|
|
118
117
|
We use Second-Order Sections (SOS) for all filters to ensure numerical stability. The following plot compares the architectures focusing on the -3 dB crossover point.
|
|
119
118
|
|
|
120
|
-
<img src=".github/images/filter_type_comparison.png" width="80%"></img>
|
|
119
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_type_comparison.png" width="80%"></img>
|
|
121
120
|
|
|
122
121
|
| Type | Name | Usage Example | Best For |
|
|
123
122
|
| :--- | :--- | :--- | :--- |
|
|
@@ -132,11 +131,11 @@ Full spectral view of the filter banks for Octave (1/1) and 1/3-Octave fractions
|
|
|
132
131
|
|
|
133
132
|
| Architecture | 1/1 Octave (Fraction=1) | 1/3 Octave (Fraction=3) |
|
|
134
133
|
| :--- | :--- | :--- |
|
|
135
|
-
| **Butterworth** | <img src=".github/images/filter_butter_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_butter_fraction_3_order_6.png" width="100%"> |
|
|
136
|
-
| **Chebyshev I** | <img src=".github/images/filter_cheby1_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_cheby1_fraction_3_order_6.png" width="100%"> |
|
|
137
|
-
| **Chebyshev II** | <img src=".github/images/filter_cheby2_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_cheby2_fraction_3_order_6.png" width="100%"> |
|
|
138
|
-
| **Elliptic** | <img src=".github/images/filter_ellip_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_ellip_fraction_3_order_6.png" width="100%"> |
|
|
139
|
-
| **Bessel** | <img src=".github/images/filter_bessel_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_bessel_fraction_3_order_6.png" width="100%"> |
|
|
134
|
+
| **Butterworth** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_butter_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_butter_fraction_3_order_6.png" width="100%"> |
|
|
135
|
+
| **Chebyshev I** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby1_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby1_fraction_3_order_6.png" width="100%"> |
|
|
136
|
+
| **Chebyshev II** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby2_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby2_fraction_3_order_6.png" width="100%"> |
|
|
137
|
+
| **Elliptic** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_ellip_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_ellip_fraction_3_order_6.png" width="100%"> |
|
|
138
|
+
| **Bessel** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_bessel_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_bessel_fraction_3_order_6.png" width="100%"> |
|
|
140
139
|
|
|
141
140
|
---
|
|
142
141
|
|
|
@@ -144,7 +143,7 @@ Full spectral view of the filter banks for Octave (1/1) and 1/3-Octave fractions
|
|
|
144
143
|
|
|
145
144
|
Frequency weighting curves simulate the human ear\'s sensitivity.
|
|
146
145
|
|
|
147
|
-
<img src=".github/images/weighting_responses.png" width="80%"></img>
|
|
146
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/weighting_responses.png" width="80%"></img>
|
|
148
147
|
|
|
149
148
|
* **A-Weighting (`A`):** Standard for environmental noise (IEC 61672-1).
|
|
150
149
|
* **C-Weighting (`C`):** Used for peak sound pressure and high-level noise.
|
|
@@ -166,7 +165,7 @@ c_weighted_signal = weighting_filter(signal, fs, curve='C')
|
|
|
166
165
|
|
|
167
166
|
Accurate SPL measurement requires capturing energy over specific time windows.
|
|
168
167
|
|
|
169
|
-
<img src=".github/images/time_weighting_analysis.png" width="80%"></img>
|
|
168
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/time_weighting_analysis.png" width="80%"></img>
|
|
170
169
|
|
|
171
170
|
* **Fast (`fast`):** $\tau = 125$ ms. Standard for noise fluctuations.
|
|
172
171
|
* **Slow (`slow`):** $\tau = 1000$ ms. Standard for steady noise.
|
|
@@ -211,7 +210,7 @@ from pyoctaveband import octavefilter
|
|
|
211
210
|
# Default standard measurement
|
|
212
211
|
spl, freq = octavefilter(x, fs, filter_type='butter')
|
|
213
212
|
```
|
|
214
|
-
<img src=".github/images/filter_butter_fraction_3_order_6.png" width="60%"></img>
|
|
213
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_butter_fraction_3_order_6.png" width="60%"></img>
|
|
215
214
|
|
|
216
215
|
### 2. Chebyshev I (`cheby1`)
|
|
217
216
|
Chebyshev Type I filters provide a **steeper roll-off** than Butterworth at the expense of ripples in the passband. Useful when high selectivity is needed near the cut-off frequencies.
|
|
@@ -220,7 +219,7 @@ Chebyshev Type I filters provide a **steeper roll-off** than Butterworth at the
|
|
|
220
219
|
# Selectivity with 0.1 dB passband ripple
|
|
221
220
|
spl, freq = octavefilter(x, fs, filter_type='cheby1', ripple=0.1)
|
|
222
221
|
```
|
|
223
|
-
<img src=".github/images/filter_cheby1_fraction_3_order_6.png" width="60%"></img>
|
|
222
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby1_fraction_3_order_6.png" width="60%"></img>
|
|
224
223
|
|
|
225
224
|
### 3. Chebyshev II (`cheby2`)
|
|
226
225
|
Also known as Inverse Chebyshev, it has a **flat passband** and ripples in the stopband. It provides faster roll-off than Butterworth without affecting the signal in the passband.
|
|
@@ -229,7 +228,7 @@ Also known as Inverse Chebyshev, it has a **flat passband** and ripples in the s
|
|
|
229
228
|
# Flat passband with 60 dB stopband attenuation
|
|
230
229
|
spl, freq = octavefilter(x, fs, filter_type='cheby2', attenuation=60)
|
|
231
230
|
```
|
|
232
|
-
<img src=".github/images/filter_cheby2_fraction_3_order_6.png" width="60%"></img>
|
|
231
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby2_fraction_3_order_6.png" width="60%"></img>
|
|
233
232
|
|
|
234
233
|
### 4. Elliptic (`ellip`)
|
|
235
234
|
Elliptic (Cauer) filters have the **shortest transition width** (steepest roll-off) for a given order. They feature ripples in both the passband and stopband.
|
|
@@ -238,7 +237,7 @@ Elliptic (Cauer) filters have the **shortest transition width** (steepest roll-o
|
|
|
238
237
|
# Maximum selectivity for extreme band isolation
|
|
239
238
|
spl, freq = octavefilter(x, fs, filter_type='ellip', ripple=0.1, attenuation=60)
|
|
240
239
|
```
|
|
241
|
-
<img src=".github/images/filter_ellip_fraction_3_order_6.png" width="60%"></img>
|
|
240
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_ellip_fraction_3_order_6.png" width="60%"></img>
|
|
242
241
|
|
|
243
242
|
### 5. Bessel (`bessel`)
|
|
244
243
|
Bessel filters are optimized for **linear phase response** and minimal group delay. They preserve the shape of filtered waveforms (transients) better than any other type, but have the slowest roll-off.
|
|
@@ -247,7 +246,7 @@ Bessel filters are optimized for **linear phase response** and minimal group del
|
|
|
247
246
|
# Best for pulse analysis and transient preservation
|
|
248
247
|
spl, freq = octavefilter(x, fs, filter_type='bessel')
|
|
249
248
|
```
|
|
250
|
-
<img src=".github/images/filter_bessel_fraction_3_order_6.png" width="60%"></img>
|
|
249
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_bessel_fraction_3_order_6.png" width="60%"></img>
|
|
251
250
|
|
|
252
251
|
### 6. Linkwitz-Riley (`lr`)
|
|
253
252
|
Specifically designed for **audio crossovers**. Linkwitz-Riley filters (typically 4th order) allow splitting a signal into bands that, when summed, result in a perfectly flat magnitude response and zero phase difference between bands at the crossover.
|
|
@@ -258,7 +257,7 @@ from pyoctaveband import linkwitz_riley
|
|
|
258
257
|
low, high = linkwitz_riley(signal, fs, freq=1000, order=4)
|
|
259
258
|
# Reconstruction: low + high == signal (flat response)
|
|
260
259
|
```
|
|
261
|
-
<img src=".github/images/crossover_lr4.png" width="60%"></img>
|
|
260
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/crossover_lr4.png" width="60%"></img>
|
|
262
261
|
|
|
263
262
|
---
|
|
264
263
|
|
|
@@ -317,7 +316,7 @@ spl, freq, xb = octavefilter(y, fs=fs, fraction=1, sigbands=True)
|
|
|
317
316
|
# Each band in 'xb' has the same length as the original input 'y'.
|
|
318
317
|
```
|
|
319
318
|
|
|
320
|
-
<img src=".github/images/signal_decomposition.png" width="80%"></img>
|
|
319
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/signal_decomposition.png" width="80%"></img>
|
|
321
320
|
|
|
322
321
|
*The bottom plot shows the **Impulse Response** of a band, demonstrating the stability and decay characteristics of the filter.*
|
|
323
322
|
|
|
@@ -48,23 +48,22 @@ Now available on [PyPI](https://pypi.org/project/PyOctaveBand/).
|
|
|
48
48
|
|
|
49
49
|
### Installation
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
**Option 1: From PyPI (Recommended)**
|
|
52
|
+
Install `PyOctaveBand` directly using pip:
|
|
53
53
|
```bash
|
|
54
54
|
pip install PyOctaveBand
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
**Option 1: Cloning and Installing**
|
|
57
|
+
**Option 2: Cloning and Installing**
|
|
58
|
+
Clone the repository and install it manually:
|
|
60
59
|
```bash
|
|
61
60
|
git clone https://github.com/jmrplens/PyOctaveBand.git
|
|
62
61
|
cd PyOctaveBand
|
|
63
62
|
pip install .
|
|
64
63
|
```
|
|
65
64
|
|
|
66
|
-
**Option
|
|
67
|
-
Add PyOctaveBand as a dependency within your own git repository:
|
|
65
|
+
**Option 3: Git Submodule**
|
|
66
|
+
Add `PyOctaveBand` as a dependency within your own git repository:
|
|
68
67
|
```bash
|
|
69
68
|
git submodule add https://github.com/jmrplens/PyOctaveBand.git
|
|
70
69
|
# Then install in editable mode to use it from your project
|
|
@@ -99,7 +98,7 @@ PyOctaveBand supports several filter types, each with its own transfer function
|
|
|
99
98
|
### Filter Comparison and Zoom
|
|
100
99
|
We use Second-Order Sections (SOS) for all filters to ensure numerical stability. The following plot compares the architectures focusing on the -3 dB crossover point.
|
|
101
100
|
|
|
102
|
-
<img src=".github/images/filter_type_comparison.png" width="80%"></img>
|
|
101
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_type_comparison.png" width="80%"></img>
|
|
103
102
|
|
|
104
103
|
| Type | Name | Usage Example | Best For |
|
|
105
104
|
| :--- | :--- | :--- | :--- |
|
|
@@ -114,11 +113,11 @@ Full spectral view of the filter banks for Octave (1/1) and 1/3-Octave fractions
|
|
|
114
113
|
|
|
115
114
|
| Architecture | 1/1 Octave (Fraction=1) | 1/3 Octave (Fraction=3) |
|
|
116
115
|
| :--- | :--- | :--- |
|
|
117
|
-
| **Butterworth** | <img src=".github/images/filter_butter_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_butter_fraction_3_order_6.png" width="100%"> |
|
|
118
|
-
| **Chebyshev I** | <img src=".github/images/filter_cheby1_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_cheby1_fraction_3_order_6.png" width="100%"> |
|
|
119
|
-
| **Chebyshev II** | <img src=".github/images/filter_cheby2_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_cheby2_fraction_3_order_6.png" width="100%"> |
|
|
120
|
-
| **Elliptic** | <img src=".github/images/filter_ellip_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_ellip_fraction_3_order_6.png" width="100%"> |
|
|
121
|
-
| **Bessel** | <img src=".github/images/filter_bessel_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_bessel_fraction_3_order_6.png" width="100%"> |
|
|
116
|
+
| **Butterworth** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_butter_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_butter_fraction_3_order_6.png" width="100%"> |
|
|
117
|
+
| **Chebyshev I** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby1_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby1_fraction_3_order_6.png" width="100%"> |
|
|
118
|
+
| **Chebyshev II** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby2_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby2_fraction_3_order_6.png" width="100%"> |
|
|
119
|
+
| **Elliptic** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_ellip_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_ellip_fraction_3_order_6.png" width="100%"> |
|
|
120
|
+
| **Bessel** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_bessel_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_bessel_fraction_3_order_6.png" width="100%"> |
|
|
122
121
|
|
|
123
122
|
---
|
|
124
123
|
|
|
@@ -126,7 +125,7 @@ Full spectral view of the filter banks for Octave (1/1) and 1/3-Octave fractions
|
|
|
126
125
|
|
|
127
126
|
Frequency weighting curves simulate the human ear\'s sensitivity.
|
|
128
127
|
|
|
129
|
-
<img src=".github/images/weighting_responses.png" width="80%"></img>
|
|
128
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/weighting_responses.png" width="80%"></img>
|
|
130
129
|
|
|
131
130
|
* **A-Weighting (`A`):** Standard for environmental noise (IEC 61672-1).
|
|
132
131
|
* **C-Weighting (`C`):** Used for peak sound pressure and high-level noise.
|
|
@@ -148,7 +147,7 @@ c_weighted_signal = weighting_filter(signal, fs, curve='C')
|
|
|
148
147
|
|
|
149
148
|
Accurate SPL measurement requires capturing energy over specific time windows.
|
|
150
149
|
|
|
151
|
-
<img src=".github/images/time_weighting_analysis.png" width="80%"></img>
|
|
150
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/time_weighting_analysis.png" width="80%"></img>
|
|
152
151
|
|
|
153
152
|
* **Fast (`fast`):** $\tau = 125$ ms. Standard for noise fluctuations.
|
|
154
153
|
* **Slow (`slow`):** $\tau = 1000$ ms. Standard for steady noise.
|
|
@@ -193,7 +192,7 @@ from pyoctaveband import octavefilter
|
|
|
193
192
|
# Default standard measurement
|
|
194
193
|
spl, freq = octavefilter(x, fs, filter_type='butter')
|
|
195
194
|
```
|
|
196
|
-
<img src=".github/images/filter_butter_fraction_3_order_6.png" width="60%"></img>
|
|
195
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_butter_fraction_3_order_6.png" width="60%"></img>
|
|
197
196
|
|
|
198
197
|
### 2. Chebyshev I (`cheby1`)
|
|
199
198
|
Chebyshev Type I filters provide a **steeper roll-off** than Butterworth at the expense of ripples in the passband. Useful when high selectivity is needed near the cut-off frequencies.
|
|
@@ -202,7 +201,7 @@ Chebyshev Type I filters provide a **steeper roll-off** than Butterworth at the
|
|
|
202
201
|
# Selectivity with 0.1 dB passband ripple
|
|
203
202
|
spl, freq = octavefilter(x, fs, filter_type='cheby1', ripple=0.1)
|
|
204
203
|
```
|
|
205
|
-
<img src=".github/images/filter_cheby1_fraction_3_order_6.png" width="60%"></img>
|
|
204
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby1_fraction_3_order_6.png" width="60%"></img>
|
|
206
205
|
|
|
207
206
|
### 3. Chebyshev II (`cheby2`)
|
|
208
207
|
Also known as Inverse Chebyshev, it has a **flat passband** and ripples in the stopband. It provides faster roll-off than Butterworth without affecting the signal in the passband.
|
|
@@ -211,7 +210,7 @@ Also known as Inverse Chebyshev, it has a **flat passband** and ripples in the s
|
|
|
211
210
|
# Flat passband with 60 dB stopband attenuation
|
|
212
211
|
spl, freq = octavefilter(x, fs, filter_type='cheby2', attenuation=60)
|
|
213
212
|
```
|
|
214
|
-
<img src=".github/images/filter_cheby2_fraction_3_order_6.png" width="60%"></img>
|
|
213
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby2_fraction_3_order_6.png" width="60%"></img>
|
|
215
214
|
|
|
216
215
|
### 4. Elliptic (`ellip`)
|
|
217
216
|
Elliptic (Cauer) filters have the **shortest transition width** (steepest roll-off) for a given order. They feature ripples in both the passband and stopband.
|
|
@@ -220,7 +219,7 @@ Elliptic (Cauer) filters have the **shortest transition width** (steepest roll-o
|
|
|
220
219
|
# Maximum selectivity for extreme band isolation
|
|
221
220
|
spl, freq = octavefilter(x, fs, filter_type='ellip', ripple=0.1, attenuation=60)
|
|
222
221
|
```
|
|
223
|
-
<img src=".github/images/filter_ellip_fraction_3_order_6.png" width="60%"></img>
|
|
222
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_ellip_fraction_3_order_6.png" width="60%"></img>
|
|
224
223
|
|
|
225
224
|
### 5. Bessel (`bessel`)
|
|
226
225
|
Bessel filters are optimized for **linear phase response** and minimal group delay. They preserve the shape of filtered waveforms (transients) better than any other type, but have the slowest roll-off.
|
|
@@ -229,7 +228,7 @@ Bessel filters are optimized for **linear phase response** and minimal group del
|
|
|
229
228
|
# Best for pulse analysis and transient preservation
|
|
230
229
|
spl, freq = octavefilter(x, fs, filter_type='bessel')
|
|
231
230
|
```
|
|
232
|
-
<img src=".github/images/filter_bessel_fraction_3_order_6.png" width="60%"></img>
|
|
231
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_bessel_fraction_3_order_6.png" width="60%"></img>
|
|
233
232
|
|
|
234
233
|
### 6. Linkwitz-Riley (`lr`)
|
|
235
234
|
Specifically designed for **audio crossovers**. Linkwitz-Riley filters (typically 4th order) allow splitting a signal into bands that, when summed, result in a perfectly flat magnitude response and zero phase difference between bands at the crossover.
|
|
@@ -240,7 +239,7 @@ from pyoctaveband import linkwitz_riley
|
|
|
240
239
|
low, high = linkwitz_riley(signal, fs, freq=1000, order=4)
|
|
241
240
|
# Reconstruction: low + high == signal (flat response)
|
|
242
241
|
```
|
|
243
|
-
<img src=".github/images/crossover_lr4.png" width="60%"></img>
|
|
242
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/crossover_lr4.png" width="60%"></img>
|
|
244
243
|
|
|
245
244
|
---
|
|
246
245
|
|
|
@@ -299,7 +298,7 @@ spl, freq, xb = octavefilter(y, fs=fs, fraction=1, sigbands=True)
|
|
|
299
298
|
# Each band in 'xb' has the same length as the original input 'y'.
|
|
300
299
|
```
|
|
301
300
|
|
|
302
|
-
<img src=".github/images/signal_decomposition.png" width="80%"></img>
|
|
301
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/signal_decomposition.png" width="80%"></img>
|
|
303
302
|
|
|
304
303
|
*The bottom plot shows the **Impulse Response** of a band, demonstrating the stability and decay characteristics of the filter.*
|
|
305
304
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyOctaveBand
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: Octave-Band and Fractional Octave-Band filter for signals in time domain.
|
|
5
5
|
Author-email: Jose Manuel Requena Plens <jmrplens@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/jmrplens/PyOctaveBand
|
|
@@ -66,23 +66,22 @@ Now available on [PyPI](https://pypi.org/project/PyOctaveBand/).
|
|
|
66
66
|
|
|
67
67
|
### Installation
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
**Option 1: From PyPI (Recommended)**
|
|
70
|
+
Install `PyOctaveBand` directly using pip:
|
|
71
71
|
```bash
|
|
72
72
|
pip install PyOctaveBand
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
**Option 1: Cloning and Installing**
|
|
75
|
+
**Option 2: Cloning and Installing**
|
|
76
|
+
Clone the repository and install it manually:
|
|
78
77
|
```bash
|
|
79
78
|
git clone https://github.com/jmrplens/PyOctaveBand.git
|
|
80
79
|
cd PyOctaveBand
|
|
81
80
|
pip install .
|
|
82
81
|
```
|
|
83
82
|
|
|
84
|
-
**Option
|
|
85
|
-
Add PyOctaveBand as a dependency within your own git repository:
|
|
83
|
+
**Option 3: Git Submodule**
|
|
84
|
+
Add `PyOctaveBand` as a dependency within your own git repository:
|
|
86
85
|
```bash
|
|
87
86
|
git submodule add https://github.com/jmrplens/PyOctaveBand.git
|
|
88
87
|
# Then install in editable mode to use it from your project
|
|
@@ -117,7 +116,7 @@ PyOctaveBand supports several filter types, each with its own transfer function
|
|
|
117
116
|
### Filter Comparison and Zoom
|
|
118
117
|
We use Second-Order Sections (SOS) for all filters to ensure numerical stability. The following plot compares the architectures focusing on the -3 dB crossover point.
|
|
119
118
|
|
|
120
|
-
<img src=".github/images/filter_type_comparison.png" width="80%"></img>
|
|
119
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_type_comparison.png" width="80%"></img>
|
|
121
120
|
|
|
122
121
|
| Type | Name | Usage Example | Best For |
|
|
123
122
|
| :--- | :--- | :--- | :--- |
|
|
@@ -132,11 +131,11 @@ Full spectral view of the filter banks for Octave (1/1) and 1/3-Octave fractions
|
|
|
132
131
|
|
|
133
132
|
| Architecture | 1/1 Octave (Fraction=1) | 1/3 Octave (Fraction=3) |
|
|
134
133
|
| :--- | :--- | :--- |
|
|
135
|
-
| **Butterworth** | <img src=".github/images/filter_butter_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_butter_fraction_3_order_6.png" width="100%"> |
|
|
136
|
-
| **Chebyshev I** | <img src=".github/images/filter_cheby1_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_cheby1_fraction_3_order_6.png" width="100%"> |
|
|
137
|
-
| **Chebyshev II** | <img src=".github/images/filter_cheby2_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_cheby2_fraction_3_order_6.png" width="100%"> |
|
|
138
|
-
| **Elliptic** | <img src=".github/images/filter_ellip_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_ellip_fraction_3_order_6.png" width="100%"> |
|
|
139
|
-
| **Bessel** | <img src=".github/images/filter_bessel_fraction_1_order_6.png" width="100%"> | <img src=".github/images/filter_bessel_fraction_3_order_6.png" width="100%"> |
|
|
134
|
+
| **Butterworth** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_butter_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_butter_fraction_3_order_6.png" width="100%"> |
|
|
135
|
+
| **Chebyshev I** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby1_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby1_fraction_3_order_6.png" width="100%"> |
|
|
136
|
+
| **Chebyshev II** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby2_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby2_fraction_3_order_6.png" width="100%"> |
|
|
137
|
+
| **Elliptic** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_ellip_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_ellip_fraction_3_order_6.png" width="100%"> |
|
|
138
|
+
| **Bessel** | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_bessel_fraction_1_order_6.png" width="100%"> | <img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_bessel_fraction_3_order_6.png" width="100%"> |
|
|
140
139
|
|
|
141
140
|
---
|
|
142
141
|
|
|
@@ -144,7 +143,7 @@ Full spectral view of the filter banks for Octave (1/1) and 1/3-Octave fractions
|
|
|
144
143
|
|
|
145
144
|
Frequency weighting curves simulate the human ear\'s sensitivity.
|
|
146
145
|
|
|
147
|
-
<img src=".github/images/weighting_responses.png" width="80%"></img>
|
|
146
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/weighting_responses.png" width="80%"></img>
|
|
148
147
|
|
|
149
148
|
* **A-Weighting (`A`):** Standard for environmental noise (IEC 61672-1).
|
|
150
149
|
* **C-Weighting (`C`):** Used for peak sound pressure and high-level noise.
|
|
@@ -166,7 +165,7 @@ c_weighted_signal = weighting_filter(signal, fs, curve='C')
|
|
|
166
165
|
|
|
167
166
|
Accurate SPL measurement requires capturing energy over specific time windows.
|
|
168
167
|
|
|
169
|
-
<img src=".github/images/time_weighting_analysis.png" width="80%"></img>
|
|
168
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/time_weighting_analysis.png" width="80%"></img>
|
|
170
169
|
|
|
171
170
|
* **Fast (`fast`):** $\tau = 125$ ms. Standard for noise fluctuations.
|
|
172
171
|
* **Slow (`slow`):** $\tau = 1000$ ms. Standard for steady noise.
|
|
@@ -211,7 +210,7 @@ from pyoctaveband import octavefilter
|
|
|
211
210
|
# Default standard measurement
|
|
212
211
|
spl, freq = octavefilter(x, fs, filter_type='butter')
|
|
213
212
|
```
|
|
214
|
-
<img src=".github/images/filter_butter_fraction_3_order_6.png" width="60%"></img>
|
|
213
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_butter_fraction_3_order_6.png" width="60%"></img>
|
|
215
214
|
|
|
216
215
|
### 2. Chebyshev I (`cheby1`)
|
|
217
216
|
Chebyshev Type I filters provide a **steeper roll-off** than Butterworth at the expense of ripples in the passband. Useful when high selectivity is needed near the cut-off frequencies.
|
|
@@ -220,7 +219,7 @@ Chebyshev Type I filters provide a **steeper roll-off** than Butterworth at the
|
|
|
220
219
|
# Selectivity with 0.1 dB passband ripple
|
|
221
220
|
spl, freq = octavefilter(x, fs, filter_type='cheby1', ripple=0.1)
|
|
222
221
|
```
|
|
223
|
-
<img src=".github/images/filter_cheby1_fraction_3_order_6.png" width="60%"></img>
|
|
222
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby1_fraction_3_order_6.png" width="60%"></img>
|
|
224
223
|
|
|
225
224
|
### 3. Chebyshev II (`cheby2`)
|
|
226
225
|
Also known as Inverse Chebyshev, it has a **flat passband** and ripples in the stopband. It provides faster roll-off than Butterworth without affecting the signal in the passband.
|
|
@@ -229,7 +228,7 @@ Also known as Inverse Chebyshev, it has a **flat passband** and ripples in the s
|
|
|
229
228
|
# Flat passband with 60 dB stopband attenuation
|
|
230
229
|
spl, freq = octavefilter(x, fs, filter_type='cheby2', attenuation=60)
|
|
231
230
|
```
|
|
232
|
-
<img src=".github/images/filter_cheby2_fraction_3_order_6.png" width="60%"></img>
|
|
231
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_cheby2_fraction_3_order_6.png" width="60%"></img>
|
|
233
232
|
|
|
234
233
|
### 4. Elliptic (`ellip`)
|
|
235
234
|
Elliptic (Cauer) filters have the **shortest transition width** (steepest roll-off) for a given order. They feature ripples in both the passband and stopband.
|
|
@@ -238,7 +237,7 @@ Elliptic (Cauer) filters have the **shortest transition width** (steepest roll-o
|
|
|
238
237
|
# Maximum selectivity for extreme band isolation
|
|
239
238
|
spl, freq = octavefilter(x, fs, filter_type='ellip', ripple=0.1, attenuation=60)
|
|
240
239
|
```
|
|
241
|
-
<img src=".github/images/filter_ellip_fraction_3_order_6.png" width="60%"></img>
|
|
240
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_ellip_fraction_3_order_6.png" width="60%"></img>
|
|
242
241
|
|
|
243
242
|
### 5. Bessel (`bessel`)
|
|
244
243
|
Bessel filters are optimized for **linear phase response** and minimal group delay. They preserve the shape of filtered waveforms (transients) better than any other type, but have the slowest roll-off.
|
|
@@ -247,7 +246,7 @@ Bessel filters are optimized for **linear phase response** and minimal group del
|
|
|
247
246
|
# Best for pulse analysis and transient preservation
|
|
248
247
|
spl, freq = octavefilter(x, fs, filter_type='bessel')
|
|
249
248
|
```
|
|
250
|
-
<img src=".github/images/filter_bessel_fraction_3_order_6.png" width="60%"></img>
|
|
249
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/filter_bessel_fraction_3_order_6.png" width="60%"></img>
|
|
251
250
|
|
|
252
251
|
### 6. Linkwitz-Riley (`lr`)
|
|
253
252
|
Specifically designed for **audio crossovers**. Linkwitz-Riley filters (typically 4th order) allow splitting a signal into bands that, when summed, result in a perfectly flat magnitude response and zero phase difference between bands at the crossover.
|
|
@@ -258,7 +257,7 @@ from pyoctaveband import linkwitz_riley
|
|
|
258
257
|
low, high = linkwitz_riley(signal, fs, freq=1000, order=4)
|
|
259
258
|
# Reconstruction: low + high == signal (flat response)
|
|
260
259
|
```
|
|
261
|
-
<img src=".github/images/crossover_lr4.png" width="60%"></img>
|
|
260
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/crossover_lr4.png" width="60%"></img>
|
|
262
261
|
|
|
263
262
|
---
|
|
264
263
|
|
|
@@ -317,7 +316,7 @@ spl, freq, xb = octavefilter(y, fs=fs, fraction=1, sigbands=True)
|
|
|
317
316
|
# Each band in 'xb' has the same length as the original input 'y'.
|
|
318
317
|
```
|
|
319
318
|
|
|
320
|
-
<img src=".github/images/signal_decomposition.png" width="80%"></img>
|
|
319
|
+
<img src="https://raw.githubusercontent.com/jmrplens/PyOctaveBand/main/.github/images/signal_decomposition.png" width="80%"></img>
|
|
321
320
|
|
|
322
321
|
*The bottom plot shows the **Impulse Response** of a band, demonstrating the stability and decay characteristics of the filter.*
|
|
323
322
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|