flac_bound/encoder/
config.rs

1#[cfg(feature = "flac")]
2use flac_sys::{FLAC__StreamEncoderInitStatus, FLAC__bool, FLAC__stream_encoder_set_ogg_serial_number, FLAC__stream_encoder_set_verify,
3               FLAC__stream_encoder_set_streamable_subset, FLAC__stream_encoder_set_channels, FLAC__stream_encoder_set_bits_per_sample,
4               FLAC__stream_encoder_set_sample_rate, FLAC__stream_encoder_set_compression_level, FLAC__stream_encoder_set_blocksize,
5               FLAC__stream_encoder_set_do_mid_side_stereo, FLAC__stream_encoder_set_loose_mid_side_stereo, FLAC__stream_encoder_set_apodization,
6               FLAC__stream_encoder_set_max_lpc_order, FLAC__stream_encoder_set_qlp_coeff_precision, FLAC__stream_encoder_set_do_qlp_coeff_prec_search,
7               FLAC__stream_encoder_set_do_escape_coding, FLAC__stream_encoder_set_do_exhaustive_model_search,
8               FLAC__stream_encoder_set_min_residual_partition_order, FLAC__stream_encoder_set_max_residual_partition_order,
9               FLAC__stream_encoder_set_rice_parameter_search_dist,
10               FLAC__stream_encoder_set_total_samples_estimate /* , FLAC__stream_encoder_set_metadata */, FLAC__stream_encoder_init_stream,
11               FLAC__stream_encoder_init_ogg_stream, FLAC__stream_encoder_init_file, FLAC__stream_encoder_init_ogg_file,
12               FLAC__StreamEncoderInitStatus_FLAC__STREAM_ENCODER_INIT_STATUS_OK};
13
14#[cfg(feature = "libflac-nobuild")]
15use libflac_sys::{FLAC__StreamEncoderInitStatus, FLAC__bool, FLAC__stream_encoder_set_ogg_serial_number, FLAC__stream_encoder_set_verify,
16                  FLAC__stream_encoder_set_streamable_subset, FLAC__stream_encoder_set_channels, FLAC__stream_encoder_set_bits_per_sample,
17                  FLAC__stream_encoder_set_sample_rate, FLAC__stream_encoder_set_compression_level, FLAC__stream_encoder_set_blocksize,
18                  FLAC__stream_encoder_set_do_mid_side_stereo, FLAC__stream_encoder_set_loose_mid_side_stereo, FLAC__stream_encoder_set_apodization,
19                  FLAC__stream_encoder_set_max_lpc_order, FLAC__stream_encoder_set_qlp_coeff_precision, FLAC__stream_encoder_set_do_qlp_coeff_prec_search,
20                  FLAC__stream_encoder_set_do_escape_coding, FLAC__stream_encoder_set_do_exhaustive_model_search,
21                  FLAC__stream_encoder_set_min_residual_partition_order, FLAC__stream_encoder_set_max_residual_partition_order,
22                  FLAC__stream_encoder_set_limit_min_bitrate, FLAC__stream_encoder_set_rice_parameter_search_dist,
23                  FLAC__stream_encoder_set_total_samples_estimate /* , FLAC__stream_encoder_set_metadata */, FLAC__stream_encoder_init_stream,
24                  FLAC__stream_encoder_init_ogg_stream, FLAC__stream_encoder_init_file, FLAC__stream_encoder_init_ogg_file,
25                  FLAC__STREAM_ENCODER_INIT_STATUS_OK as FLAC__StreamEncoderInitStatus_FLAC__STREAM_ENCODER_INIT_STATUS_OK};
26
27
28use super::{StreamEncoderContainer, FlacEncoderInitError, WriteWrapper, FlacEncoder, flac_encoder_write_write_callback};
29use std::os::raw::{c_long, c_void};
30use std::ffi::{CString, CStr};
31use std::marker::PhantomData;
32use std::convert::TryFrom;
33use std::path::Path;
34use std::ptr;
35
36
37/// Wrapper around a FLAC encoder for configuring the output settings.
38///
39/// `FILE*` constructors unsupported, Write+Seek constructors unsupportable due to <https://github.com/rust-lang/rfcs/issues/2035>
40#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
41#[repr(transparent)]
42pub struct FlacEncoderConfig(pub(super) StreamEncoderContainer);
43
44impl FlacEncoderConfig {
45    /// Initialize the encoder instance to encode native FLAC streams.
46    ///
47    /// This flavor of initialization sets up the encoder to encode to a
48    /// native FLAC stream. I/O is performed into the specified stream.
49    ///
50    /// The call to `init_write()` currently will also
51    /// immediately write several times, once with the `fLaC`
52    /// signature, and once for each encoded metadata block.
53    pub fn init_write<'out>(self, out: &'out mut WriteWrapper<'out>) -> Result<FlacEncoder<'out>, FlacEncoderInitError> {
54        let result = unsafe {
55            FLAC__stream_encoder_init_stream((self.0).0,
56                                             Some(flac_encoder_write_write_callback),
57                                             None,
58                                             None,
59                                             None,
60                                             out as *mut WriteWrapper as *mut c_void)
61        };
62        self.do_init(result)
63    }
64
65    /// Initialize the encoder instance to encode Ogg FLAC streams.
66    ///
67    /// This flavor of initialization sets up the encoder to encode to a FLAC
68    /// stream in an Ogg container. I/O is performed into the specified stream.
69    ///
70    /// The call to `init_write_ogg()` currently will also
71    /// immediately write several times, once for the Ogg container,
72    /// `fLaC` signature, and encoded metadata block.
73    pub fn init_write_ogg<'out>(self, out: &'out mut WriteWrapper<'out>) -> Result<FlacEncoder<'out>, FlacEncoderInitError> {
74        let result = unsafe {
75            FLAC__stream_encoder_init_ogg_stream((self.0).0,
76                                                 None,
77                                                 Some(flac_encoder_write_write_callback),
78                                                 None,
79                                                 None,
80                                                 None,
81                                                 out as *mut WriteWrapper as *mut c_void)
82        };
83        self.do_init(result)
84    }
85
86    /// Initialize the encoder instance to encode native FLAC files.
87    ///
88    /// This flavor of initialization sets up the encoder to encode to a plain
89    /// FLAC file. If POSIX fopen() semantics are not sufficient (for example,
90    /// with Unicode filenames), you must use `init_write()`
91    /// and provide the output stream.
92    ///
93    /// The file will be opened with `fopen()`.
94    pub fn init_file<P: AsRef<Path>>(self, filename: &P /* FLAC__StreamEncoderProgressCallback progress_callback, void *client_data */)
95                                     -> Result<FlacEncoder<'static>, FlacEncoderInitError> {
96        self.init_file_impl(filename.as_ref())
97    }
98
99    fn init_file_impl(self, filename: &Path /* FLAC__StreamEncoderProgressCallback progress_callback, void *client_data */)
100                      -> Result<FlacEncoder<'static>, FlacEncoderInitError> {
101        let result = unsafe { FLAC__stream_encoder_init_file((self.0).0, FlacEncoderConfig::convert_path(filename).as_ptr(), None, ptr::null_mut()) };
102        self.do_init(result)
103    }
104
105    /// Initialize the encoder instance to encode Ogg FLAC files.
106    ///
107    /// This flavor of initialization sets up the encoder to encode to a plain
108    /// FLAC file. If POSIX fopen() semantics are not sufficient (for example,
109    /// with Unicode filenames), you must use `init_write_ogg()`
110    /// and provide the output stream.
111    ///
112    /// The file will be opened with `fopen()`.
113    pub fn init_file_ogg<P: AsRef<Path>>(self, filename: &P /* FLAC__StreamEncoderProgressCallback progress_callback, void *client_data */)
114                                         -> Result<FlacEncoder<'static>, FlacEncoderInitError> {
115        self.init_file_ogg_impl(filename.as_ref())
116    }
117
118    fn init_file_ogg_impl(self, filename: &Path /* FLAC__StreamEncoderProgressCallback progress_callback, void *client_data */)
119                          -> Result<FlacEncoder<'static>, FlacEncoderInitError> {
120        let result = unsafe { FLAC__stream_encoder_init_ogg_file((self.0).0, FlacEncoderConfig::convert_path(filename).as_ptr(), None, ptr::null_mut()) };
121        self.do_init(result)
122    }
123
124    /// Initialize the encoder instance to encode native FLAC files.
125    ///
126    /// This flavor of initialization sets up the encoder to encode a plain
127    /// FLAC file to stdout.
128    ///
129    /// **Note**: a proper SEEKTABLE cannot be created when encoding to `stdout` since it is not seekable.
130    pub fn init_stdout(self) -> Result<FlacEncoder<'static>, FlacEncoderInitError> {
131        let result = unsafe { FLAC__stream_encoder_init_file((self.0).0, ptr::null(), None, ptr::null_mut()) };
132        self.do_init(result)
133    }
134
135    /// Initialize the encoder instance to encode Ogg FLAC files.
136    ///
137    /// This flavor of initialization sets up the encoder to encode a plain
138    /// OGG FLAC file to stdout.
139    ///
140    /// **Note**: a proper SEEKTABLE cannot be created when encoding to `stdout` since it is not seekable.
141    pub fn init_stdout_ogg(self) -> Result<FlacEncoder<'static>, FlacEncoderInitError> {
142        let result = unsafe { FLAC__stream_encoder_init_ogg_file((self.0).0, ptr::null(), None, ptr::null_mut()) };
143        self.do_init(result)
144    }
145
146    fn convert_path(path: &Path) -> CString {
147        CString::new(path.to_str().expect("non-UTF-8 filename")).expect("filename has internal NULs")
148    }
149
150    fn do_init<'out>(self, init_result: FLAC__StreamEncoderInitStatus) -> Result<FlacEncoder<'out>, FlacEncoderInitError> {
151        if init_result == FLAC__StreamEncoderInitStatus_FLAC__STREAM_ENCODER_INIT_STATUS_OK {
152            Ok(FlacEncoder(self.0, PhantomData))
153        } else {
154            Err(FlacEncoderInitError::try_from(init_result).unwrap())
155        }
156    }
157}
158
159
160impl FlacEncoderConfig {
161    /// Set the serial number for the FLAC stream to use in the Ogg container.
162    ///
163    /// **Note**:<br />
164    /// This does not need to be set for native FLAC encoding.
165    ///
166    /// It is recommended to set a serial number explicitly as the default of '0'
167    /// may collide with other streams.
168    ///
169    /// **Default**: `0`
170    pub fn ogg_serial_number(self, serial_number: c_long) -> FlacEncoderConfig {
171        unsafe { FLAC__stream_encoder_set_ogg_serial_number((self.0).0, serial_number) };
172        self
173    }
174
175    /// Set the "verify" flag.
176    ///
177    /// If `true`, the encoder will verify its own
178    /// encoded output by feeding it through an internal decoder and comparing
179    /// the original signal against the decoded signal. If a mismatch occurs,
180    /// the process call will return `false`. Note that this will slow the
181    /// encoding process by the extra time required for decoding and comparison.
182    ///
183    /// **Default**: `false`
184    pub fn verify(self, value: bool) -> FlacEncoderConfig {
185        unsafe { FLAC__stream_encoder_set_verify((self.0).0, value as FLAC__bool) };
186        self
187    }
188
189    /// Set the Subset flag.
190    ///
191    /// If `true`, the encoder will comply with the Subset and will check the
192    /// settings during [`init_*()`](#method.init_write) to see if all settings
193    /// comply. If `false`, the settings may take advantage of the full
194    /// range that the format allows.
195    ///
196    /// Make sure you know what it entails before setting this to `false`.
197    ///
198    /// **Default**: `true`
199    pub fn streamable_subset(self, value: bool) -> FlacEncoderConfig {
200        unsafe { FLAC__stream_encoder_set_streamable_subset((self.0).0, value as FLAC__bool) };
201        self
202    }
203
204    /// Set the number of channels to be encoded.
205    ///
206    /// **Default**: `2`
207    pub fn channels(self, value: u32) -> FlacEncoderConfig {
208        unsafe { FLAC__stream_encoder_set_channels((self.0).0, value) };
209        self
210    }
211
212    /// Set the sample resolution of the input to be encoded.
213    ///
214    /// **Warning**:<br />
215    /// Do not feed the encoder data that is wider than the value you
216    /// set here or you will generate an invalid stream.
217    ///
218    /// **Default**: `16`
219    pub fn bits_per_sample(self, value: u32) -> FlacEncoderConfig {
220        unsafe { FLAC__stream_encoder_set_bits_per_sample((self.0).0, value) };
221        self
222    }
223
224    /// Set the sample rate (in Hz) of the input to be encoded.
225    ///
226    /// **Default**: `44100`
227    pub fn sample_rate(self, value: u32) -> FlacEncoderConfig {
228        unsafe { FLAC__stream_encoder_set_sample_rate((self.0).0, value) };
229        self
230    }
231
232    /// Set the compression level
233    ///
234    /// The compression level is roughly proportional to the amount of effort
235    /// the encoder expends to compress the file. A higher level usually
236    /// means more computation but higher compression. The default level is
237    /// suitable for most applications.
238    ///
239    /// Currently the levels range from `0` (fastest, least compression) to
240    /// `8` (slowest, most compression). A value larger than `8` will be
241    /// treated as `8`.
242    ///
243    /// This function automatically calls the following other *`set`*
244    /// functions with appropriate values, so the client does not need to
245    /// unless it specifically wants to override them:
246    ///   * [`do_mid_side_stereo()`](#method.do_mid_side_stereo)
247    ///   * [`loose_mid_side_stereo()`](#method.loose_mid_side_stereo)
248    ///   * [`apodization()`](#method.apodization)
249    ///   * [`max_lpc_order()`](#method.max_lpc_order)
250    ///   * [`qlp_coeff_precision()`](#method.qlp_coeff_precision)
251    ///   * [`do_qlp_coeff_prec_search()`](#method.do_qlp_coeff_prec_search)
252    ///   * [`do_escape_coding()`](#method.do_escape_coding)
253    ///   * [`do_exhaustive_model_search()`](#method.do_exhaustive_model_search)
254    ///   * [`min_residual_partition_order()`](#method.min_residual_partition_order)
255    ///   * [`max_residual_partition_order()`](#method.max_residual_partition_order)
256    ///   * [`rice_parameter_search_dist()`](#method.rice_parameter_search_dist)
257    ///
258    /// The actual values set for each level are:
259    /// <table>
260    /// <tr>
261    ///  <td><b>level</b></td>
262    ///  <td>do mid-side stereo</td>
263    ///  <td>loose mid-side stereo</td>
264    ///  <td>apodization</td>
265    ///  <td>max lpc order</td>
266    ///  <td>qlp coeff precision</td>
267    ///  <td>qlp coeff prec search</td>
268    ///  <td>escape coding</td>
269    ///  <td>exhaustive model search</td>
270    ///  <td>min residual partition order</td>
271    ///  <td>max residual partition order</td>
272    ///  <td>rice parameter search dist</td>
273    /// </tr>
274    /// <tr><td><b>0</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)</td>
275    ///     <td>0</td>        <td>0</td>     <td>false</td> <td>false</td>
276    ///     <td>false</td>    <td>0</td>     <td>3</td>     <td>0</td></tr>
277    /// <tr><td><b>1</b></td> <td>true</td>  <td>true</td>  <td>tukey(0.5)</td>
278    ///     <td>0</td>        <td>0</td>     <td>false</td> <td>false</td>
279    ///     <td>false</td>    <td>0</td>     <td>3</td>     <td>0</td></tr>
280    /// <tr><td><b>2</b></td> <td>true</td>  <td>false</td> <td>tukey(0.5)</td>
281    ///     <td>0</td>        <td>0</td>     <td>false</td> <td>false</td>
282    ///     <td>false</td>    <td>0</td>     <td>3</td>     <td>0</td></tr>
283    /// <tr><td><b>3</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)</td>
284    ///     <td>6</td>        <td>0</td>     <td>false</td> <td>false</td>
285    ///     <td>false</td>    <td>0</td>     <td>4</td>     <td>0</td></tr>
286    /// <tr><td><b>4</b></td> <td>true</td>  <td>true</td>  <td>tukey(0.5)</td>
287    ///     <td>8</td>        <td>0</td>     <td>false</td> <td>false</td>
288    ///     <td>false</td>    <td>0</td>     <td>4</td>     <td>0</td></tr>
289    /// <tr><td><b>5</b></td> <td>true</td>  <td>false</td> <td>tukey(0.5)</td>
290    ///     <td>8</td>        <td>0</td>     <td>false</td> <td>false</td>
291    ///     <td>false</td>    <td>0</td>     <td>5</td>     <td>0</td></tr>
292    /// <tr><td><b>6</b></td> <td>true</td>  <td>false</td> <td>tukey(0.5);partial_tukey(2)</td>
293    ///     <td>8</td>        <td>0</td>     <td>false</td> <td>false</td>
294    ///     <td>false</td>    <td>0</td>     <td>6</td>     <td>0</td></tr>
295    /// <tr><td><b>7</b></td> <td>true</td>  <td>false</td> <td>tukey(0.5);partial_tukey(2)</td>
296    ///     <td>12</td>       <td>0</td>     <td>false</td> <td>false</td>
297    ///     <td>false</td>    <td>0</td>     <td>6</td>     <td>0</td></tr>
298    /// <tr><td><b>8</b></td> <td>true</td>  <td>false</td> <td>tukey(0.5);partial_tukey(2);punchout_tukey(3)</td>
299    ///     <td>12</td>       <td>0</td>     <td>false</td> <td>false</td>
300    ///     <td>false</td>    <td>0</td>     <td>6</td>     <td>0</td></tr>
301    /// </table>
302    ///
303    /// **Default**: `5`
304    pub fn compression_level(self, value: u32) -> FlacEncoderConfig {
305        unsafe { FLAC__stream_encoder_set_compression_level((self.0).0, value) };
306        self
307    }
308
309    /// Set the blocksize to use while encoding.
310    ///
311    /// The number of samples to use per frame. Use `0` to let the encoder
312    /// estimate a blocksize; this is usually best.
313    ///
314    /// **Default**: `0`
315    pub fn blocksize(self, value: u32) -> FlacEncoderConfig {
316        unsafe { FLAC__stream_encoder_set_blocksize((self.0).0, value) };
317        self
318    }
319
320    /// Set to `true` to enable mid-side encoding on stereo input.
321    ///
322    /// The number of channels must be 2 for this to have any effect.
323    /// Set to `false` to use only independent channel coding.
324    ///
325    /// **Default**: `true`
326    pub fn do_mid_side_stereo(self, value: bool) -> FlacEncoderConfig {
327        unsafe { FLAC__stream_encoder_set_do_mid_side_stereo((self.0).0, value as FLAC__bool) };
328        self
329    }
330
331    /// Set to `true` to enable adaptive switching between mid-side and left-right encoding on stereo input.
332    ///
333    /// Set to `false` to use exhaustive searching. Setting this to `true` requires
334    /// `do_mid_side_stereo()` to also be set to `true` in order to have any effect.
335    ///
336    /// **Default**: `false`
337    pub fn loose_mid_side_stereo(self, value: bool) -> FlacEncoderConfig {
338        unsafe { FLAC__stream_encoder_set_loose_mid_side_stereo((self.0).0, value as FLAC__bool) };
339        self
340    }
341
342    /// Sets the apodization function(s) the encoder will use when windowing audio data for LPC analysis.
343    ///
344    /// The *specification* is a plain ASCII string which specifies exactly
345    /// which functions to use. There may be more than one (up to 32),
346    /// separated by `';'` characters. Some functions take one or more
347    /// comma-separated arguments in parentheses.
348    ///
349    /// The available functions are `bartlett`, `bartlett_hann`,
350    /// `blackman`, `blackman_harris_4term_92db`, `connes`, `flattop`,
351    /// `gauss`(STDDEV), `hamming`, `hann`, `kaiser_bessel`, `nuttall`,
352    /// `rectangle`, `triangle`, `tukey`(P), `partial_tukey(n[/ov[/P]])`,
353    /// `punchout_tukey(n[/ov[/P]])`, `welch`.
354    ///
355    /// For `gauss(STDDEV)`, STDDEV specifies the standard deviation
356    /// (0<STDDEV<=0.5).
357    ///
358    /// For `tukey(P)`, P specifies the fraction of the window that is
359    /// tapered (0<=P<=1). P=0 corresponds to `rectangle` and P=1
360    /// corresponds to `hann`.
361    ///
362    /// Specifying `partial_tukey` or `punchout_tukey` works a little
363    /// different. These do not specify a single apodization function, but
364    /// a series of them with some overlap. partial_tukey specifies a series
365    /// of small windows (all treated separately) while punchout_tukey
366    /// specifies a series of windows that have a hole in them. In this way,
367    /// the predictor is constructed with only a part of the block, which
368    /// helps in case a block consists of dissimilar parts.
369    ///
370    /// The three parameters that can be specified for the functions are
371    /// n, ov and P. n is the number of functions to add, ov is the overlap
372    /// of the windows in case of partial_tukey and the overlap in the gaps
373    /// in case of punchout_tukey. P is the fraction of the window that is
374    /// tapered, like with a regular tukey window. The function can be
375    /// specified with only a number, a number and an overlap, or a number
376    /// an overlap and a P, for example, partial_tukey(3), partial_tukey(3/0.3)
377    /// and partial_tukey(3/0.3/0.5) are all valid. ov should be smaller than 1
378    /// and can be negative.
379    ///
380    /// Example specifications are `"blackman"` or
381    /// `"hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)"`
382    ///
383    /// Any function that is specified erroneously is silently dropped. Up
384    /// to 32 functions are kept, the rest are dropped. If the specification
385    /// is empty the encoder defaults to `"tukey(0.5)"`.
386    ///
387    /// When more than one function is specified, then for every subframe the
388    /// encoder will try each of them separately and choose the window that
389    /// results in the smallest compressed subframe.
390    ///
391    /// Note that each function specified causes the encoder to occupy a
392    /// floating point array in which to store the window. Also note that the
393    /// values of P, STDDEV and ov are locale-specific, so if the comma
394    /// separator specified by the locale is a comma, a comma should be used.
395    ///
396    /// **Default**: `"tukey(0.5)"`
397    pub fn apodization(self, specification: &CStr) -> FlacEncoderConfig {
398        unsafe { FLAC__stream_encoder_set_apodization((self.0).0, specification.as_ptr()) };
399        self
400    }
401
402    /// Set the maximum LPC order, or `0` to use only the fixed predictors.
403    ///
404    /// **Default**: `8`
405    pub fn max_lpc_order(self, value: u32) -> FlacEncoderConfig {
406        unsafe { FLAC__stream_encoder_set_max_lpc_order((self.0).0, value) };
407        self
408    }
409
410    /// Set the precision, in bits, of the quantized linear predictor
411    /// coefficients, or `0` to let the encoder select it based on the
412    /// blocksize.
413    ///
414    /// **Note**:<br />
415    /// In the current implementation, `qlp_coeff_precision + bits_per_sample` must
416    /// be less than 32.
417    ///
418    /// **Default**: `0`
419    pub fn qlp_coeff_precision(self, value: u32) -> FlacEncoderConfig {
420        unsafe { FLAC__stream_encoder_set_qlp_coeff_precision((self.0).0, value) };
421        self
422    }
423
424    /// Set to `false` to use only the specified quantized linear predictor
425    /// coefficient precision, or `true` to search neighboring precision
426    /// values and use the best one.
427    ///
428    /// **Default**: `false`
429    pub fn do_qlp_coeff_prec_search(self, value: bool) -> FlacEncoderConfig {
430        unsafe { FLAC__stream_encoder_set_do_qlp_coeff_prec_search((self.0).0, value as FLAC__bool) };
431        self
432    }
433
434    /// Deprecated. Setting this value has no effect.
435    ///
436    /// **Default**: `false`
437    pub fn do_escape_coding(self, value: bool) -> FlacEncoderConfig {
438        unsafe { FLAC__stream_encoder_set_do_escape_coding((self.0).0, value as FLAC__bool) };
439        self
440    }
441
442    /// Set to `false` to let the encoder estimate the best model order
443    /// based on the residual signal energy, or `true` to force the
444    /// encoder to evaluate all order models and select the best.
445    ///
446    /// **Default**: `false`
447    pub fn do_exhaustive_model_search(self, value: bool) -> FlacEncoderConfig {
448        unsafe { FLAC__stream_encoder_set_do_exhaustive_model_search((self.0).0, value as FLAC__bool) };
449        self
450    }
451
452    /// Set the minimum partition order to search when coding the residual.
453    ///
454    /// This is used in tandem with [`max_residual_partition_order()`](method.max_residual_partition_order).
455    ///
456    /// The partition order determines the context size in the residual.
457    ///
458    /// The context size will be approximately `blocksize / (2 ^ order)`.
459    ///
460    /// Set both min and max values to `0` to force a single context,
461    /// whose Rice parameter is based on the residual signal variance.
462    /// Otherwise, set a min and max order, and the encoder will search
463    /// all orders, using the mean of each context for its Rice parameter,
464    /// and use the best.
465    ///
466    /// **Default**: `0`
467    pub fn min_residual_partition_order(self, value: u32) -> FlacEncoderConfig {
468        unsafe { FLAC__stream_encoder_set_min_residual_partition_order((self.0).0, value) };
469        self
470    }
471
472    /// Set the maximum partition order to search when coding the residual.
473    ///
474    /// This is used in tandem with [`min_residual_partition_order()`](method.min_residual_partition_order).
475    ///
476    /// The partition order determines the context size in the residual.
477    /// The context size will be approximately `blocksize / (2 ^ order)`.
478    ///
479    /// Set both min and max values to `0` to force a single context,
480    /// whose Rice parameter is based on the residual signal variance.
481    /// Otherwise, set a min and max order, and the encoder will search
482    /// all orders, using the mean of each context for its Rice parameter,
483    /// and use the best.
484    ///
485    /// **Default**: `5`
486    pub fn max_residual_partition_order(self, value: u32) -> FlacEncoderConfig {
487        unsafe { FLAC__stream_encoder_set_max_residual_partition_order((self.0).0, value) };
488        self
489    }
490
491    /// Limit the compression of digital silence to prevent streaming connection loss
492    ///
493    /// See <https://github.com/xiph/flac/pull/264>.
494    ///
495    /// **Default**: `false`
496    #[cfg(feature = "libflac-nobuild")]
497    pub fn set_limit_min_bitrate(self, value: bool) -> FlacEncoderConfig {
498        unsafe { FLAC__stream_encoder_set_limit_min_bitrate((self.0).0, value as FLAC__bool) };
499        self
500    }
501
502    /// Deprecated. Setting this value has no effect.
503    ///
504    /// **Default**: `0`
505    pub fn rice_parameter_search_dist(self, value: u32) -> FlacEncoderConfig {
506        unsafe { FLAC__stream_encoder_set_rice_parameter_search_dist((self.0).0, value) };
507        self
508    }
509
510    /// Set an estimate of the total samples that will be encoded.
511    ///
512    /// This is merely an estimate and may be set to `0` if unknown.
513    /// This value will be written to the STREAMINFO block before encoding,
514    /// and can remove the need for the caller to rewrite the value later
515    /// if the value is known before encoding.
516    ///
517    /// **Default**: `0`
518    pub fn total_samples_estimate(self, value: u64) -> FlacEncoderConfig {
519        unsafe { FLAC__stream_encoder_set_total_samples_estimate((self.0).0, value) };
520        self
521    }
522}