77
88
99class ConverterType (Enum ):
10+ """Samplerate converter types."""
1011 sinc_best = 0
1112 sinc_medium = 1
1213 sinc_fastest = 2
@@ -24,6 +25,32 @@ def _get_converter_type(identifier):
2425
2526
2627def resample (input_data , ratio , converter_type = 'sinc_best' , verbose = False ):
28+ """Resample the signal in `input_data` at once.
29+
30+ Parameters
31+ ----------
32+ input_data : ndarray
33+ Input data. A single channel is provided as a 1D array of `num_frames`
34+ length. Several channels are represented as a 2D array of shape
35+ (`num_frames`, `num_channels`). For use with `libsamplerate`, `input_data`
36+ is converted to 32-bit float and C (row-major) memory order.
37+ ratio : float
38+ Conversion ratio = output sample rate / input sample rate.
39+ converter_type : ConverterType, str, or int
40+ Sample rate converter.
41+ verbose : bool
42+ If `True`, print additional information about the conversion.
43+
44+ Returns
45+ -------
46+ output_data : ndarray
47+ Resampled input data.
48+
49+
50+ .. note::
51+ If samples are to be processed in chunks, `Resampler` and `CallbackResampler`
52+ will provide better results and allow for variable conversion ratios.
53+ """
2754 from samplerate .lowlevel import src_simple
2855 from samplerate .exceptions import ResamplingError
2956
@@ -59,6 +86,15 @@ def resample(input_data, ratio, converter_type='sinc_best', verbose=False):
5986
6087
6188class Resampler (object ):
89+ """Resampler.
90+
91+ Parameters
92+ ----------
93+ converter_type : ConverterType, str, or int
94+ Sample rate converter.
95+ num_channels : int
96+ Number of channels.
97+ """
6298 def __init__ (self , converter_type = 'sinc_fastest' , channels = 1 ):
6399 from samplerate .lowlevel import ffi , src_new , src_delete
64100 from samplerate .exceptions import ResamplingError
@@ -73,21 +109,46 @@ def __init__(self, converter_type='sinc_fastest', channels=1):
73109
74110 @property
75111 def converter_type (self ):
112+ """Converter type."""
76113 return self ._converter_type
77114
78115 @property
79116 def channels (self ):
117+ """Number of channels."""
80118 return self ._channels
81119
82120 def reset (self ):
121+ """Reset internal state."""
83122 from samplerate .lowlevel import src_reset
84123 return src_reset (self ._state )
85124
86125 def set_ratio (self , new_ratio ):
126+ """Set a new conversion ratio immediately."""
87127 from samplerate .lowlevel import src_set_ratio
88128 return src_set_ratio (self ._state , new_ratio )
89129
90- def process (self , input_data , ratio , end_of_input = 0 , verbose = False ):
130+ def process (self , input_data , ratio , end_of_input = False , verbose = False ):
131+ """Resample the signal in `input_data`.
132+
133+ Parameters
134+ ----------
135+ input_data : ndarray
136+ Input data. A single channel is provided as a 1D array of `num_frames`
137+ length. Several channels are represented as a 2D array of shape
138+ (`num_frames`, `num_channels`). For use with `libsamplerate`, `input_data`
139+ is converted to 32-bit float and C (row-major) memory order.
140+ ratio : float
141+ Conversion ratio = output sample rate / input sample rate.
142+ end_of_input : int
143+ Set to `True` if no more data is available, or to `False` otherwise.
144+ verbose : bool
145+ If `True`, print additional information about the conversion.
146+
147+ Returns
148+ -------
149+ output_data : ndarray
150+ Resampled input data.
151+ """
91152 from samplerate .lowlevel import src_process
92153 from samplerate .exceptions import ResamplingError
93154
@@ -124,6 +185,24 @@ def process(self, input_data, ratio, end_of_input=0, verbose=False):
124185
125186
126187class CallbackResampler (object ):
188+ """CallbackResampler.
189+
190+ Parameters
191+ ----------
192+ callback : function
193+ Function that returns new frames on each call, or `None` otherwise.
194+ A single channel is provided as a 1D array of `num_frames` length.
195+ Several channels are represented as a 2D array of shape
196+ (`num_frames`, `num_channels`). For use with `libsamplerate`,
197+ the returned data is converted to 32-bit float and C (row-major)
198+ memory order.
199+ ratio : float
200+ Conversion ratio = output sample rate / input sample rate.
201+ converter_type : ConverterType, str, or int
202+ Sample rate converter.
203+ channels : int
204+ Number of channels.
205+ """
127206 def __init__ (self , callback , ratio , converter_type = 'sinc_fastest' ,
128207 channels = 1 ):
129208 if channels < 1 :
@@ -134,9 +213,10 @@ def __init__(self, callback, ratio, converter_type='sinc_fastest',
134213 self ._channels = channels
135214 self ._state = None
136215 self ._handle = None
137- self .create ()
216+ self ._create ()
138217
139- def create (self ):
218+ def _create (self ):
219+ """Create new callback resampler."""
140220 from samplerate .lowlevel import ffi , src_callback_new , src_delete
141221 from samplerate .exceptions import ResamplingError
142222
@@ -147,7 +227,8 @@ def create(self):
147227 self ._state = ffi .gc (state , src_delete )
148228 self ._handle = handle
149229
150- def destroy (self ):
230+ def _destroy (self ):
231+ """Destroy resampler state."""
151232 if self ._state :
152233 self ._state = None
153234 self ._handle = None
@@ -156,32 +237,53 @@ def __enter__(self):
156237 return self
157238
158239 def __exit__ (self , * args ):
159- self .destroy ()
240+ self ._destroy ()
160241
161242 def set_starting_ratio (self , ratio ):
162243 """ Set the starting conversion ratio for the next `read` call. """
163244 from samplerate .lowlevel import src_set_ratio
245+ if self ._state is None :
246+ self ._create ()
164247 src_set_ratio (self ._state , ratio )
165248 self .ratio = ratio
166249
167250 def reset (self ):
251+ """Reset state."""
168252 from samplerate .lowlevel import src_reset
253+ if self ._state is None :
254+ self ._create ()
169255 src_reset (self ._state )
170256
171257 @property
172258 def ratio (self ):
259+ """Conversion ratio = output sample rate / input sample rate."""
173260 return self ._ratio
174261
175262 @ratio .setter
176263 def ratio (self , ratio ):
177264 self ._ratio = ratio
178265
179266 def read (self , num_frames ):
267+ """Read a number of frames from the resampler.
268+
269+ Parameters
270+ ----------
271+ num_frames : int
272+ Number of frames to read.
273+
274+ Returns
275+ -------
276+ output_data : ndarray
277+ Resampled frames as a (`num_output_frames`, `num_channels`) or
278+ (`num_output_frames`,) array. Note that `num_output_frames` may
279+ be lower than `num_frames`, for example when no more input is
280+ available.
281+ """
180282 from samplerate .lowlevel import src_callback_read , src_error
181283 from samplerate .exceptions import ResamplingError
182284
183285 if self ._state is None :
184- self .create ()
286+ self ._create ()
185287 if self ._channels > 1 :
186288 output_shape = (num_frames , self ._channels )
187289 elif self ._channels == 1 :
0 commit comments