[−][src]Struct flac_bound::FlacEncoder
The stream encoder can encode to native FLAC, and optionally Ogg FLAC (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files.
The basic usage of this encoder is as follows:
- The program creates an instance of an encoder using
FlacEncoder::new()
. - The program overrides the default settings using functions in
FlacEncoderConfig
. At a minimum, the following functions should be called: - If the application wants to control the compression level or set its own metadata, then the following should also be called:
- The rest of the set functions should only be called if the client needs exact control over how the audio is compressed; thorough understanding of the FLAC format is necessary to achieve good results.
- The program initializes the instance to validate the settings and
prepare for encoding using
FlacEncoderConfig::init_write()
, orFlacEncoderConfig::init_file()
, orFlacEncoderConfig::init_stdout()
for native FLACFlacEncoderConfig::init_write_ogg()
, orFlacEncoderConfig::init_file_ogg()
, orFlacEncoderConfig::init_stdout_ogg()
for Ogg FLAC
- The program calls
FlacEncoder::process()
orFlacEncoder::process_interleaved()
to encode data, which subsequently calls the callbacks when there is encoder data ready to be written. - The program finishes the encoding with
FlacEncoder::finish()
, which causes the encoder to encode any data still in its input pipe, update the metadata with the final encoding statistics if output seeking is possible, and finally reset the encoder to the uninitialized state. Note: the stream isfinish()
ed when it's dropped, and any potential error is ignored. - The instance may be used again or deleted with
FlacEncoder::delete()
. Note: the stream isdelete()
ed when it's dropped.
In more detail, the stream encoder functions similarly to the
stream decoder, but has fewer
callbacks and more options. Typically the client will create a new
instance by calling FlacEncoder::new()
, then set the necessary
parameters with functions on FlacEncoderConfig
, and initialize it by
calling one of the FlacEncoderConfig::init_*()
functions.
Unlike the decoders, the stream encoder has many options that can
affect the speed and compression ratio. When setting these parameters
you should have some basic knowledge of the format (see the
user-level documentation or the formal description). The functions on
FlacEncoderConfig
themselves do not validate the
values as many are interdependent. The FlacEncoderConfig::init_*()
functions will do this, so make sure to pay attention to the result
returned by FlacEncoderConfig::init_*()
to make sure that it is
Ok()
. Any parameters that are not set
before FlacEncoderConfig::init_*()
will take on the defaults from
the constructor.
There are three initialization functions for native FLAC, one for
setting up the encoder to encode FLAC data to the client via
a Write
stream, and two for encoding directly to a file.
For encoding via a Write
stream, use FlacEncoderConfig::init_write()
.
You must also supply a std::io::Write
stream which will be called anytime
there is raw encoded data to write. The client cannot seek the output due to
RFC 2035, so the
encoder cannot go back after encoding is finished to write back
information that was collected while encoding, like seek point offsets,
frame sizes, etc.
For encoding directly to a file, use FlacEncoderConfig::init_file()
.
Then you must only supply a UTF-8 filename; the encoder will handle all the callbacks
internally. You may also supply a progress callback for periodic
notification of the encoding progress.
There are three similarly-named init functions for encoding to Ogg FLAC streams.
The call to FlacEncoderConfig::init_*()
currently will also immediately
call write to the sink several times, once with the fLaC
signature,
and once for each encoded metadata block. Note that for Ogg FLAC
encoding you will usually get at least twice the number of callbacks than
with native FLAC, one for the Ogg page header and one for the page body.
After initializing the instance, the client may feed audio data to the encoder in one of two ways:
- Channel separate, through
FlacEncoder::process()
- The client will pass an slice of buffer slices, one for each channel, to the encoder, each of the same length. The samples need not be block-aligned, but each channel should have the same number of samples. This function will allocate if the user supplies more than 8 channels. - Channel interleaved, through
FlacEncoder::process_interleaved()
- The client will pass a single slice to data that is channel-interleaved (i.e.channel0_sample0
,channel1_sample0
, ... ,channelN_sample0
,channel0_sample1
, ...). Again, the samples need not be block-aligned but they must be sample-aligned, i.e. the first value should bechannel0_sample0
and the last valuechannelN_sampleM
.
Note that for either process call, each sample in the buffers should be a
signed integer, right-justified to the resolution set by
FlacEncoderConfig::bits_per_sample()
.
For example, if the resolution is 16 bits per sample, the samples should all be in the range [-32768,32767].
When the client is finished encoding data, it calls
FlacEncoder::finish()
, either explicitly or by dropping the encoder,
which causes the encoder to encode any
data still in its input pipe, and call the metadata callback with the
final encoding statistics. Then the instance may be deleted with
FlacEncoder::delete()
by dropping the encoder, or initialized again to encode another
stream.
For programs that write their own metadata, but that do not know the actual metadata until after encoding, it is advantageous to instruct the encoder to write a PADDING block of the correct size, so that instead of rewriting the whole stream after encoding, the program can just overwrite the PADDING block. If only the maximum size of the metadata is known, the program can write a slightly larger padding block, then split it after encoding.
Make sure you understand how lengths are calculated. All FLAC metadata blocks have a 4 byte header which contains the type and length. This length does not include the 4 bytes of the header. See the format page for the specification of metadata blocks and their lengths.
Note:
If you are writing the FLAC data to a file via callbacks, make sure it
is open for update (e.g. mode "w+" for stdio streams). This is because
after the first encoding pass, the encoder will try to seek back to the
beginning of the stream, to the STREAMINFO block, to write some data
there. (If using FlacEncoderConfig::init_file()
, the file is managed internally.)
Note:
FlacEncoder::finish()
resets all settings to the constructor defaults.
Implementations
impl<'out> FlacEncoder<'out>
[src]
pub fn new() -> Option<FlacEncoderConfig>
[src]
Create a new stream encoder, in a configuration wrapper, or None
if one couldn't be allocated.
pub fn state(&self) -> FlacEncoderState
[src]
Get the current encoder state.
pub fn verify_decoder_state(&self) -> FlacEncoderState
[src]
Get the state of the verify stream decoder.
Useful when the stream encoder state is
VerifyDecoderError
.
pub fn process(&mut self, buffers: &[&[i32]]) -> Result<(), ()>
[src]
Submit data for encoding.
This version allows you to supply the input data via a slice of
slices, each slice consisting of the same amount of samples as the first one,
representing one channel. The samples need not be block-aligned,
but each channel should have the same number of samples. Each sample
should be a signed integer, right-justified to the resolution set by
FlacEncoderConfig::bits_per_sample()
. For example, if the
resolution is 16 bits per sample, the samples should all be in the
range [-32768,32767].
For applications where channel order is important, channels must follow the order as described in the frame header.
Requires encoder instance to be in OK state.
pub fn process_interleaved(
&mut self,
buffer: &[i32],
samples_per_channel: u32
) -> Result<(), ()>
[src]
&mut self,
buffer: &[i32],
samples_per_channel: u32
) -> Result<(), ()>
Submit data for encoding.
This version allows you to supply the input data where the channels
are interleaved into a single array (i.e. channel0_sample0
,
channel1_sample0
, ... , channelN_sample0
, channel0_sample1
, ...).
The samples need not be block-aligned but they must be
sample-aligned, i.e. the first value should be channel0_sample0
and the last value channelN_sampleM
. Each sample should be a signed
integer, right-justified to the resolution set by
FlacEncoderConfig::bits_per_sample()
.
For example, if the resolution is 16 bits per sample, the samples should all be in the
range [-32768,32767].
For applications where channel order is important, channels must follow the order as described in the frame header.
Requires encoder instance to be in OK state.
pub fn finish(self) -> Result<FlacEncoderConfig, FlacEncoder<'out>>
[src]
Finish the encoding process.
Flushes the encoding buffer, releases resources, resets the encoder
settings to their defaults, and returns the encoder state to
FLAC__STREAM_ENCODER_UNINITIALIZED
. Note that this can generate
one or more write callbacks before returning, and will generate
a metadata callback.
Note that in the course of processing the last frame, errors can occur, so the caller should be sure to check the return value to ensure the file was encoded properly.
In the event of a prematurely-terminated encode, it is not strictly
necessary to call this immediately before FlacEncoder::delete()
but it is good practice to match every FlacEncoderConfig::init_*()
with a FlacEncoder::finish()
.
This is also called by drop()
.
Returns Err(self)
if an error occurred processing the last frame, or, if verify
mode is set (see FlacEncoderConfig::verify()
), there was a
verify mismatch; else the config wrapper.
If Err()
, caller should check the state with state()
for more information about the error.
Trait Implementations
impl<'out> Debug for FlacEncoder<'out>
[src]
impl<'out> Drop for FlacEncoder<'out>
[src]
impl<'out> Eq for FlacEncoder<'out>
[src]
impl<'out> Hash for FlacEncoder<'out>
[src]
fn hash<__H: Hasher>(&self, state: &mut __H)
[src]
fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
impl<'out> Ord for FlacEncoder<'out>
[src]
fn cmp(&self, other: &FlacEncoder<'out>) -> Ordering
[src]
#[must_use]fn max(self, other: Self) -> Self
1.21.0[src]
#[must_use]fn min(self, other: Self) -> Self
1.21.0[src]
#[must_use]fn clamp(self, min: Self, max: Self) -> Self
[src]
impl<'out> PartialEq<FlacEncoder<'out>> for FlacEncoder<'out>
[src]
fn eq(&self, other: &FlacEncoder<'out>) -> bool
[src]
fn ne(&self, other: &FlacEncoder<'out>) -> bool
[src]
impl<'out> PartialOrd<FlacEncoder<'out>> for FlacEncoder<'out>
[src]
fn partial_cmp(&self, other: &FlacEncoder<'out>) -> Option<Ordering>
[src]
fn lt(&self, other: &FlacEncoder<'out>) -> bool
[src]
fn le(&self, other: &FlacEncoder<'out>) -> bool
[src]
fn gt(&self, other: &FlacEncoder<'out>) -> bool
[src]
fn ge(&self, other: &FlacEncoder<'out>) -> bool
[src]
impl<'out> StructuralEq for FlacEncoder<'out>
[src]
impl<'out> StructuralPartialEq for FlacEncoder<'out>
[src]
Auto Trait Implementations
impl<'out> RefUnwindSafe for FlacEncoder<'out>
impl<'out> !Send for FlacEncoder<'out>
impl<'out> !Sync for FlacEncoder<'out>
impl<'out> Unpin for FlacEncoder<'out>
impl<'out> !UnwindSafe for FlacEncoder<'out>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,