High quality, one-dimensional sample-rate conversion library for Python
npx @tessl/cli install tessl/pypi-soxr@0.5.00
# soxr
1
2
High quality, one-dimensional sample-rate conversion library for Python. Python-SoXR is a Python wrapper around libsoxr, providing both batch processing and streaming capabilities for audio resampling with exceptional quality and performance.
3
4
## Package Information
5
6
- **Package Name**: soxr
7
- **Language**: Python
8
- **Installation**: `pip install soxr`
9
10
## Core Imports
11
12
```python
13
import soxr
14
```
15
16
## Basic Usage
17
18
```python
19
import soxr
20
import numpy as np
21
22
# Create sample audio data (1 second at 44.1 kHz)
23
x = np.random.randn(44100).astype(np.float32)
24
25
# Batch resampling from 44.1 kHz to 16 kHz
26
y = soxr.resample(x, 44100, 16000)
27
28
# For streaming (real-time or very long signals)
29
resampler = soxr.ResampleStream(44100, 16000, 1, dtype='float32')
30
31
# Process chunks
32
chunk_size = 1024
33
for i in range(0, len(x), chunk_size):
34
chunk = x[i:i+chunk_size]
35
is_last = (i + chunk_size) >= len(x)
36
resampled_chunk = resampler.resample_chunk(chunk, last=is_last)
37
# Process resampled_chunk...
38
```
39
40
## Capabilities
41
42
### Batch Resampling
43
44
High-quality resampling for complete signals using the `resample()` function.
45
46
```python { .api }
47
def resample(x: ArrayLike, in_rate: float, out_rate: float, quality: Union[str, int] = 'HQ') -> np.ndarray:
48
"""
49
Resample signal using high-quality libsoxr algorithm.
50
51
Parameters:
52
- x: Input array (1D mono or 2D multi-channel [frame, channel])
53
- in_rate: Input sample rate in Hz
54
- out_rate: Output sample rate in Hz
55
- quality: Quality setting - 'QQ', 'LQ', 'MQ', 'HQ', 'VHQ' or constants (default: 'HQ')
56
57
Returns:
58
np.ndarray with same dtype and ndim as input
59
"""
60
```
61
62
#### Internal One-Shot Function
63
64
```python { .api }
65
def _resample_oneshot(x: np.ndarray, in_rate: float, out_rate: float, quality: Union[str, int] = 'HQ') -> np.ndarray:
66
"""
67
Internal one-shot resampling using libsoxr's soxr_oneshot().
68
69
Note: For testing purposes. Becomes slow with long inputs. Use resample() for general use.
70
71
Parameters:
72
- x: Input numpy array
73
- in_rate: Input sample rate in Hz
74
- out_rate: Output sample rate in Hz
75
- quality: Quality setting - 'QQ', 'LQ', 'MQ', 'HQ', 'VHQ' or constants
76
77
Returns:
78
np.ndarray with resampled data
79
"""
80
```
81
82
### Streaming Resampling
83
84
Real-time resampling using the `ResampleStream` class for processing long signals or real-time audio.
85
86
```python { .api }
87
class ResampleStream:
88
"""Streaming resampler for real-time processing or very long signals."""
89
90
def __init__(self, in_rate: float, out_rate: float, num_channels: int,
91
dtype: str = 'float32', quality: Union[str, int] = 'HQ'):
92
"""
93
Initialize streaming resampler.
94
95
Parameters:
96
- in_rate: Input sample rate in Hz
97
- out_rate: Output sample rate in Hz
98
- num_channels: Number of audio channels
99
- dtype: Data type - 'float32', 'float64', 'int16', 'int32'
100
- quality: Quality setting - 'QQ', 'LQ', 'MQ', 'HQ', 'VHQ' or constants
101
"""
102
103
def resample_chunk(self, x: np.ndarray, last: bool = False) -> np.ndarray:
104
"""
105
Resample audio chunk.
106
107
Parameters:
108
- x: Input chunk (1D mono or 2D multi-channel [frame, channel])
109
- last: True for final chunk to flush remaining output
110
111
Returns:
112
np.ndarray with resampled chunk
113
"""
114
115
def num_clips(self) -> int:
116
"""
117
Get clip counter for integer I/O.
118
119
Returns:
120
Count of clipped samples
121
"""
122
123
def delay(self) -> float:
124
"""
125
Get current algorithmic delay.
126
127
Returns:
128
Current delay in output samples
129
"""
130
131
def clear(self) -> None:
132
"""Reset resampler state for fresh signal with same configuration."""
133
134
def engine(self) -> str:
135
"""
136
Get the resampler engine name.
137
138
Returns:
139
Name of the resampling engine being used
140
"""
141
```
142
143
### Quality Constants
144
145
Pre-defined quality settings for different speed/quality trade-offs.
146
147
```python { .api }
148
QQ: int # Quick and dirty - lowest quality, fastest
149
LQ: int # Low quality
150
MQ: int # Medium quality
151
HQ: int # High quality (default)
152
VHQ: int # Very high quality - best quality, slowest
153
```
154
155
### Data Type Constants (Extension Module)
156
157
Low-level data type constants from the soxr_ext module.
158
159
```python { .api }
160
from soxr import soxr_ext
161
162
# Internal data type constants (advanced use)
163
soxr_ext.SOXR_FLOAT32_I: int # Float32 interleaved
164
soxr_ext.SOXR_FLOAT64_I: int # Float64 interleaved
165
soxr_ext.SOXR_INT32_I: int # Int32 interleaved
166
soxr_ext.SOXR_INT16_I: int # Int16 interleaved
167
```
168
169
### Version Information
170
171
Package and library version information.
172
173
```python { .api }
174
__version__: str # Package version
175
__libsoxr_version__: str # Underlying libsoxr version
176
```
177
178
## Types
179
180
```python { .api }
181
from typing import Union, Literal
182
from numpy.typing import ArrayLike
183
import numpy as np
184
185
# Supported data types for resampling
186
SupportedDType = Literal['float32', 'float64', 'int16', 'int32']
187
188
# Quality settings
189
QualitySetting = Union[Literal['QQ', 'LQ', 'MQ', 'HQ', 'VHQ'], int]
190
```
191
192
## Usage Examples
193
194
### High-Quality Audio Resampling
195
196
```python
197
import soxr
198
import numpy as np
199
200
# Load 48 kHz audio data
201
audio_48k = np.random.randn(480000).astype(np.float32)
202
203
# Convert to CD quality (44.1 kHz) with very high quality
204
audio_44k = soxr.resample(audio_48k, 48000, 44100, quality='VHQ')
205
206
print(f"Original: {len(audio_48k)} samples at 48 kHz")
207
print(f"Resampled: {len(audio_44k)} samples at 44.1 kHz")
208
```
209
210
### Multi-Channel Streaming
211
212
```python
213
import soxr
214
import numpy as np
215
216
# Setup for stereo streaming: 44.1 kHz -> 16 kHz
217
channels = 2
218
resampler = soxr.ResampleStream(44100, 16000, channels, dtype='float32', quality='HQ')
219
220
# Simulate streaming chunks
221
chunk_size = 4410 # 100ms at 44.1 kHz
222
total_samples = 44100 # 1 second
223
224
for i in range(0, total_samples, chunk_size):
225
# Create stereo chunk [frames, channels]
226
chunk = np.random.randn(min(chunk_size, total_samples - i), channels).astype(np.float32)
227
is_last = (i + chunk_size) >= total_samples
228
229
# Resample chunk
230
resampled = resampler.resample_chunk(chunk, last=is_last)
231
232
print(f"Chunk {i//chunk_size + 1}: {chunk.shape} -> {resampled.shape}")
233
234
# Process resampled audio...
235
if is_last:
236
break
237
238
# Check for any clipping (when using integer types)
239
print(f"Clipped samples: {resampler.num_clips()}")
240
```
241
242
### Different Data Types
243
244
```python
245
import soxr
246
import numpy as np
247
248
# Float32 (default, recommended for most uses)
249
x_f32 = np.random.randn(44100).astype(np.float32)
250
y_f32 = soxr.resample(x_f32, 44100, 22050)
251
252
# Float64 (higher precision)
253
x_f64 = np.random.randn(44100).astype(np.float64)
254
y_f64 = soxr.resample(x_f64, 44100, 22050)
255
256
# Int16 (16-bit integer, common in audio)
257
x_i16 = (np.random.randn(44100) * 32767).astype(np.int16)
258
y_i16 = soxr.resample(x_i16, 44100, 22050)
259
260
# Int32 (32-bit integer)
261
x_i32 = (np.random.randn(44100) * 2147483647).astype(np.int32)
262
y_i32 = soxr.resample(x_i32, 44100, 22050)
263
264
print("All data types preserve input dtype in output")
265
```
266
267
## Error Handling
268
269
Common errors and their causes:
270
271
- **ValueError**: Invalid sample rates (≤ 0), excessive channel counts (> 65536), or wrong array dimensions
272
- **TypeError**: Unsupported data types or dtype mismatches in streaming
273
- **RuntimeError**: Internal libsoxr processing errors
274
275
```python
276
import soxr
277
import numpy as np
278
279
try:
280
# This will raise ValueError for negative sample rate
281
soxr.resample(np.array([1, 2, 3]), -44100, 16000)
282
except ValueError as e:
283
print(f"Invalid parameters: {e}")
284
285
try:
286
# This will raise TypeError for unsupported dtype
287
soxr.resample(np.array([1, 2, 3], dtype=np.int8), 44100, 16000)
288
except TypeError as e:
289
print(f"Unsupported data type: {e}")
290
```