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}