diff --git a/include/FLAC/Makefile.am b/include/FLAC/Makefile.am index 49a899b3..d97a1dca 100644 --- a/include/FLAC/Makefile.am +++ b/include/FLAC/Makefile.am @@ -21,10 +21,12 @@ includedir = ${prefix}/include/FLAC include_HEADERS = \ all.h \ assert.h \ + file_encoder.h \ file_decoder.h \ format.h \ metadata.h \ ordinals.h \ seekable_stream_decoder.h \ + seekable_stream_encoder.h \ stream_decoder.h \ stream_encoder.h diff --git a/include/FLAC/all.h b/include/FLAC/all.h index f86416e1..76fe78c7 100644 --- a/include/FLAC/all.h +++ b/include/FLAC/all.h @@ -22,10 +22,12 @@ #include "assert.h" #include "file_decoder.h" +#include "file_encoder.h" #include "format.h" #include "metadata.h" #include "ordinals.h" #include "seekable_stream_decoder.h" +#include "seekable_stream_encoder.h" #include "stream_decoder.h" #include "stream_encoder.h" @@ -94,6 +96,28 @@ * From there you can go on to look at the documentation of * individual functions. You can see different views of the individual * functions through the links in top bar across this page. + * + * \section embedded_developers Embedded Developers + * + * libFLAC has grown larger over time as more functionality has been + * included, but much of it may be unnecessary for a particular embedded + * implementation. Unused parts may be pruned by some simple editing of + * src/libFLAC/Makefile.am. In general, the decoders, encoders, and + * metadata interface are all independent from each other. + * + * It is easiest to just describe the dependencies: + * + * - All modules depend on the \link flac_format Format \endlink module. + * - The decoders and encoders are independent of each other. + * - The metadata interface requires the file decoder. + * - The decoder and encoder layers depend on the layers below them, but + * not above them; e.g. the seekable stream decoder depends on the stream + * decoder but not the file decoder + * + * For example, if your application only requires the stream decoder, no + * encoders, and no metadata interface, you can remove the seekable stream + * decoder, file decoder, all encoders, and the metadata interface, which + * will greatly reduce the size of the library. */ /** \defgroup flac FLAC C API diff --git a/include/FLAC/file_encoder.h b/include/FLAC/file_encoder.h new file mode 100644 index 00000000..fb6f4bed --- /dev/null +++ b/include/FLAC/file_encoder.h @@ -0,0 +1,711 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2002 Josh Coalson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__FILE_ENCODER_H +#define FLAC__FILE_ENCODER_H + +#include "seekable_stream_encoder.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \file include/FLAC/file_encoder.h + * + * \brief + * This module contains the functions which implement the file + * encoder. + * + * See the detailed documentation in the + * \link flac_file_encoder file encoder \endlink module. + */ + +/** \defgroup flac_file_encoder FLAC/file_encoder.h: file encoder interface + * \ingroup flac_encoder + * + * \brief + * This module contains the functions which implement the file + * encoder. + * + * The basic usage of this encoder is as follows: + * - The program creates an instance of an encoder using + * FLAC__file_encoder_new(). + * - The program overrides the default settings using + * FLAC__file_encoder_set_*() functions. + * - The program initializes the instance to validate the settings and + * prepare for encoding using FLAC__file_encoder_init(). + * - The program calls FLAC__file_encoder_process() or + * FLAC__file_encoder_process_interleaved() to encode data, which + * subsequently writes data to the output file. + * - The program finishes the encoding with FLAC__file_encoder_finish(), + * which causes the encoder to encode any data still in its input pipe, + * rewind and write the STREAMINFO metadata to file, and finally reset + * the encoder to the uninitialized state. + * - The instance may be used again or deleted with + * FLAC__file_encoder_delete(). + * + * The file encoder is a wrapper around the + * \link flac_seekable_stream_encoder seekable stream encoder \endlink which supplies all + * callbacks internally; the user need specify only the filename. + * + * Make sure to read the detailed description of the + * \link flac_seekable_stream_encoder seekable stream encoder module \endlink since the + * \link flac_stream_encoder stream encoder module \endlink since the + * file encoder inherits much of its behavior from them. + * + * \note + * The "set" functions may only be called when the encoder is in the + * state FLAC__FILE_ENCODER_UNINITIALIZED, i.e. after + * FLAC__file_encoder_new() or FLAC__file_encoder_finish(), but + * before FLAC__file_encoder_init(). If this is the case they will + * return \c true, otherwise \c false. + * + * \note + * FLAC__file_encoder_finish() resets all settings to the constructor + * defaults. + * + * \{ + */ + + +/** State values for a FLAC__FileEncoder + * + * The encoder's state can be obtained by calling FLAC__file_encoder_get_state(). + */ +typedef enum { + + FLAC__FILE_ENCODER_OK = 0, + /**< The encoder is in the normal OK state. */ + + FLAC__FILE_ENCODER_NO_FILENAME, + /**< FLAC__file_encoder_init() was called without first calling + * FLAC__file_encoder_set_filename(). + */ + + FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR, + /**< An error occurred in the underlying seekable stream encoder; + * check FLAC__file_encoder_get_seekable_stream_encoder_state(). + */ + + FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING, + /**< A fatal error occurred while writing to the encoded file. */ + + FLAC__FILE_ENCODER_ERROR_OPENING_FILE, + /**< An error occurred opening the output file for writing. */ + + FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed. */ + + FLAC__FILE_ENCODER_ALREADY_INITIALIZED, + /**< FLAC__file_encoder_init() was called when the encoder was + * already initialized, usually because + * FLAC__file_encoder_finish() was not called. + */ + + FLAC__FILE_ENCODER_UNINITIALIZED + /**< The encoder is in the uninitialized state. */ + +} FLAC__FileEncoderState; + +/** Maps a FLAC__FileEncoderState to a C string. + * + * Using a FLAC__FileEncoderState as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +/* @@@@ double-check mapping */ +extern const char * const FLAC__FileEncoderStateString[]; + + +/*********************************************************************** + * + * class FLAC__FileEncoder + * + ***********************************************************************/ + +struct FLAC__FileEncoderProtected; +struct FLAC__FileEncoderPrivate; +/** The opaque structure definition for the file encoder type. + * See the \link flac_file_encoder file encoder module \endlink + * for a detailed description. + */ +typedef struct { + struct FLAC__FileEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__FileEncoderPrivate *private_; /* avoid the C++ keyword 'private' */ +} FLAC__FileEncoder; + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +/** Create a new file encoder instance. The instance is created with + * default settings; see the individual FLAC__file_encoder_set_*() + * functions for each setting's default. + * + * \retval FLAC__FileEncoder* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC__FileEncoder *FLAC__file_encoder_new(); + +/** Free an encoder instance. Deletes the object pointed to by \a encoder. + * + * \param encoder A pointer to an existing encoder. + * \assert + * \code encoder != NULL \endcode + */ +void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder); + +/*********************************************************************** + * + * Public class method prototypes + * + ***********************************************************************/ + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_streamable_subset(). + * + * \default \c true + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_do_mid_side_stereo(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_channels(). + * + * \default \c 2 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_bits_per_sample(). + * + * \warning + * Do not feed the encoder data that is wider than the value you + * set here or you will generate an invalid stream. + * + * \default \c 16 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_sample_rate(). + * + * \default \c 44100 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_blocksize(). + * + * \default \c 1152 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_max_lpc_order(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_qlp_coeff_precision(). + * + * \note + * In the current implementation, qlp_coeff_precision + bits_per_sample must + * be less than 32. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_do_escape_coding(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_min_residual_partition_order(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_max_residual_partition_order(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_total_samples_estimate(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value); + +/** This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_set_metadata(). + * + * \default \c NULL, 0 + * \param encoder An encoder instance to set. + * \param metadata See above. + * \param num_blocks See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__FileMetadata **metadata, unsigned num_blocks); + +/** Set the output file name encode to. + * + * \note + * The filename is mandatory and must be set before initialization. + * + * \note + * Unlike the FLAC__FileDecoder, the filename does not interpret "-" for + * \c stdout; writing to \c stdout is not relevant in the file encoder. + * + * \default \c NULL + * \param encoder A encoder instance to set. + * \param value The output file name. + * \assert + * \code encoder != NULL \endcode + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, or there was a memory + * allocation error, else \c true. + */ +FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value); + +/** Get the current encoder state. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__FileEncoderState + * The current encoder state. + */ +FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder); + +/** Get the state of the underlying seekable stream encoder. + * Useful when the file encoder state is + * \c FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__SeekableStreamEncoderState + * The seekable stream encoder state. + */ +FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder); + +/** Get the "streamable subset" flag. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_streamable_subset(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_streamable_subset(). + */ +FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder); + +/** Get the "mid/side stereo coding" flag. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_do_mid_side_stereo(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_get_do_mid_side_stereo(). + */ +FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder); + +/** Get the "adaptive mid/side switching" flag. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_loose_mid_side_stereo(). + */ +FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder); + +/** Get the number of input channels being processed. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_channels(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_channels(). + */ +unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder); + +/** Get the input sample resolution setting. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_bits_per_sample(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_bits_per_sample(). + */ +unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder); + +/** Get the input sample rate setting. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_sample_rate(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_sample_rate(). + */ +unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder); + +/** Get the blocksize setting. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_blocksize(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_blocksize(). + */ +unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder); + +/** Get the maximum LPC order setting. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_max_lpc_order(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_max_lpc_order(). + */ +unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder); + +/** Get the quantized linear predictor coefficient precision setting. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_qlp_coeff_precision(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_qlp_coeff_precision(). + */ +unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder); + +/** Get the qlp coefficient precision search flag. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_do_qlp_coeff_prec_search(). + */ +FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder); + +/** Get the "escape coding" flag. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_do_escape_coding(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_do_escape_coding(). + */ +FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder); + +/** Get the exhaustive model search flag. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_do_exhaustive_model_search(). + */ +FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder); + +/** Get the minimum residual partition order setting. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_min_residual_partition_order(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_min_residual_partition_order(). + */ +unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder); + +/** Get maximum residual partition order setting. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_max_residual_partition_order(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_max_residual_partition_order(). + */ +unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder); + +/** Get the Rice parameter search distance setting. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__file_encoder_set_rice_parameter_search_dist(). + */ +unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder); + +/** Initialize the encoder instance. + * Should be called after FLAC__file_encoder_new() and + * FLAC__file_encoder_set_*() but before FLAC__file_encoder_process() + * or FLAC__file_encoder_process_interleaved(). Will set and return + * the encoder state, which will be FLAC__FILE_ENCODER_OK if + * initialization succeeded. + * + * \param encoder An uninitialized encoder instance. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__FileEncoderState + * \c FLAC__FILE_ENCODER_OK if initialization was successful; see + * FLAC__FileEncoderState for the meanings of other return values. + */ +FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder); + +/** Finish the encoding process. + * Flushes the encoding buffer, releases resources, resets the encoder + * settings to their defaults, and returns the encoder state to + * FLAC__FILE_ENCODER_UNINITIALIZED. + * + * In the event of a prematurely-terminated encode, it is not strictly + * necessary to call this immediately before FLAC__file_encoder_delete() + * but it is good practice to match every FLAC__file_encoder_init() + * with a FLAC__file_encoder_finish(). + * + * \param encoder An uninitialized encoder instance. + * \assert + * \code encoder != NULL \endcode + */ +void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder); + +/** Submit data for encoding. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_process(). + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of pointers to each channel's signal. + * \param samples The number of samples in one channel. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__file_encoder_get_state(encoder) == FLAC__FILE_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__file_encoder_get_state() to see what + * went wrong. + */ +FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); + +/** Submit data for encoding. + * This is inherited from FLAC__SeekableStreamEncoder; see + * FLAC__seekable_stream_encoder_process_interleaved(). + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of channel-interleaved data (see above). + * \param samples The number of samples in one channel, the same as for + * FLAC__file_encoder_process(). For example, if + * encoding two channels, \c 1000 \a samples corresponds + * to a \a buffer of 2000 values. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__file_encoder_get_state(encoder) == FLAC__FILE_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__file_encoder_get_state() to see what + * went wrong. + */ +FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/FLAC/seekable_stream_encoder.h b/include/FLAC/seekable_stream_encoder.h new file mode 100644 index 00000000..6d393310 --- /dev/null +++ b/include/FLAC/seekable_stream_encoder.h @@ -0,0 +1,728 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2002 Josh Coalson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__SEEKABLE_STREAM_ENCODER_H +#define FLAC__SEEKABLE_STREAM_ENCODER_H + +#include "stream_encoder.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** \file include/FLAC/seekable_stream_encoder.h + * + * \brief + * This module contains the functions which implement the seekable stream + * encoder. + * + * See the detailed documentation in the + * \link flac_seekable_stream_encoder seekable stream encoder \endlink module. + */ + +/** \defgroup flac_seekable_stream_encoder FLAC/seekable_stream_encoder.h: seekable stream encoder interface + * \ingroup flac_encoder + * + * \brief + * This module contains the functions which implement the seekable stream + * encoder. + * + * XXX (import) + * + * The seekable stream encoder is a wrapper around the + * \link flac_stream_encoder stream encoder \endlink which (XXXimport) + * + * Make sure to read the detailed description of the + * \link flac_stream_encoder stream encoder module \endlink since the + * seekable stream encoder inherits much of its behavior. + * + * \note + * The "set" functions may only be called when the encoder is in the + * state FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED, i.e. after + * FLAC__seekable_stream_encoder_new() or FLAC__seekable_stream_encoder_finish(), but + * before FLAC__seekable_stream_encoder_init(). If this is the case they will + * return \c true, otherwise \c false. + * + * \note + * FLAC__seekable_stream_encoder_finish() resets all settings to the constructor + * defaults, including the callbacks. + * + * \{ + */ + + +/** State values for a FLAC__SeekableStreamEncoder + * + * The encoder's state can be obtained by calling FLAC__seekable_stream_encoder_get_state(). + */ +typedef enum { + + FLAC__SEEKABLE_STREAM_ENCODER_OK = 0, + /**< The encoder is in the normal OK state. */ + + FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR, + /**< An error occurred in the underlying stream encoder; + * check FLAC__seekable_stream_encoder_get_stream_encoder_state(). + */ + + FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR, + /**< Memory allocation failed. */ + + FLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR, + /**< The read callback returned an error. */ + + FLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR, + /**< The seek callback returned an error. */ + + FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED, + /**< FLAC__seekable_stream_encoder_init() was called when the encoder was + * already initialized, usually because + * FLAC__seekable_stream_encoder_finish() was not called. + */ + + FLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK, + /**< FLAC__seekable_stream_encoder_init() was called without all + * callbacks being set. + */ + + FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED + /**< The encoder is in the uninitialized state. */ + +} FLAC__SeekableStreamEncoderState; + +/** Maps a FLAC__SeekableStreamEncoderState to a C string. + * + * Using a FLAC__SeekableStreamEncoderState as the index to this array + * will give the string equivalent. The contents should not be modified. + */ +/* @@@@ double-check mapping */ +extern const char * const FLAC__SeekableStreamEncoderStateString[]; + + +/*********************************************************************** + * + * class FLAC__SeekableStreamEncoder + * + ***********************************************************************/ + +struct FLAC__SeekableStreamEncoderProtected; +struct FLAC__SeekableStreamEncoderPrivate; +/** The opaque structure definition for the seekable stream encoder type. + * See the \link flac_seekable_stream_encoder seekable stream encoder module \endlink + * for a detailed description. + */ +typedef struct { + struct FLAC__SeekableStreamEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */ + struct FLAC__SeekableStreamEncoderPrivate *private_; /* avoid the C++ keyword 'private' */ +} FLAC__SeekableStreamEncoder; + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ + +/** Create a new seekable stream encoder instance. The instance is created with + * default settings; see the individual FLAC__seekable_stream_encoder_set_*() + * functions for each setting's default. + * + * \retval FLAC__SeekableStreamEncoder* + * \c NULL if there was an error allocating memory, else the new instance. + */ +FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new(); + +/** Free an encoder instance. Deletes the object pointed to by \a encoder. + * + * \param encoder A pointer to an existing encoder. + * \assert + * \code encoder != NULL \endcode + */ +void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder); + +/*********************************************************************** + * + * Public class method prototypes + * + ***********************************************************************/ + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_streamable_subset(). + * + * \default \c true + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_do_mid_side_stereo(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_loose_mid_side_stereo(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_channels(). + * + * \default \c 2 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_bits_per_sample(). + * + * \warning + * Do not feed the encoder data that is wider than the value you + * set here or you will generate an invalid stream. + * + * \default \c 16 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_sample_rate(). + * + * \default \c 44100 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_blocksize(). + * + * \default \c 1152 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_max_lpc_order(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_qlp_coeff_precision(). + * + * \note + * In the current implementation, qlp_coeff_precision + bits_per_sample must + * be less than 32. + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_do_qlp_coeff_prec_search(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_do_escape_coding(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_do_exhaustive_model_search(). + * + * \default \c false + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_min_residual_partition_order(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_max_residual_partition_order(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_rice_parameter_search_dist(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_total_samples_estimate(). + * + * \default \c 0 + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value); + +/** This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_metadata(). + * + * \default \c NULL, 0 + * \param encoder An encoder instance to set. + * \param metadata See above. + * \param num_blocks See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__FileMetadata **metadata, unsigned num_blocks); + +/** Set the seek callback. + * The supplied function will be called when the encoder needs to seek + * the output stream. The encoder will pass the absolute byte offset + * to seek to, 0 meaning the beginning of the stream. + * + * \note + * The callback is mandatory and must be set before initialization. + * + * \default \c NULL + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekStatus (*value)(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)); + +/** Set the write callback. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_set_write_callback(). + * + * \note + * The callback is mandatory and must be set before initialization. + * + * \default \c NULL + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \code value != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__stream_encoder_set_write_callback(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteStatus (*value)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)); + +/** Set the client data to be passed back to callbacks. + * This value will be supplied to callbacks in their \a client_data + * argument. + * + * \default \c NULL + * \param encoder An encoder instance to set. + * \param value See above. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * \c false if the encoder is already initialized, else \c true. + */ +FLAC__bool FLAC__stream_encoder_set_client_data(FLAC__StreamEncoder *encoder, void *value); + +/** Get the current encoder state. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__SeekableStreamEncoderState + * The current encoder state. + */ +FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the state of the underlying stream encoder. + * Useful when the seekable stream encoder state is + * \c FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR. + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__StreamEncoderState + * The stream encoder state. + */ +FLAC__StreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the "streamable subset" flag. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_streamable_subset(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_streamable_subset(). + */ +FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the "mid/side stereo coding" flag. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_do_mid_side_stereo(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_get_do_mid_side_stereo(). + */ +FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the "adaptive mid/side switching" flag. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_loose_mid_side_stereo(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(). + */ +FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the number of input channels being processed. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_channels(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_channels(). + */ +unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the input sample resolution setting. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_bits_per_sample(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_bits_per_sample(). + */ +unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the input sample rate setting. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_sample_rate(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_sample_rate(). + */ +unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the blocksize setting. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_blocksize(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_blocksize(). + */ +unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the maximum LPC order setting. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_max_lpc_order(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_max_lpc_order(). + */ +unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the quantized linear predictor coefficient precision setting. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_qlp_coeff_precision(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_qlp_coeff_precision(). + */ +unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the qlp coefficient precision search flag. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_do_qlp_coeff_prec_search(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(). + */ +FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the "escape coding" flag. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_do_escape_coding(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_do_escape_coding(). + */ +FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the exhaustive model search flag. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_do_exhaustive_model_search(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(). + */ +FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the minimum residual partition order setting. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_min_residual_partition_order(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_min_residual_partition_order(). + */ +unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder); + +/** Get maximum residual partition order setting. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_max_residual_partition_order(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_max_residual_partition_order(). + */ +unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder); + +/** Get the Rice parameter search distance setting. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_get_rice_parameter_search_dist(). + * + * \param encoder An encoder instance to query. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__bool + * See FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(). + */ +unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder); + +/** Initialize the encoder instance. + * Should be called after FLAC__seekable_stream_encoder_new() and + * FLAC__seekable_stream_encoder_set_*() but before FLAC__seekable_stream_encoder_process() + * or FLAC__seekable_stream_encoder_process_interleaved(). Will set and return + * the encoder state, which will be FLAC__SEEKABLE_STREAM_ENCODER_OK if + * initialization succeeded. + * + * The call to FLAC__seekable_stream_encoder_init() currently will also immediately + * call the write callback with the \c fLaC signature and all the encoded + * metadata. + * + * \param encoder An uninitialized encoder instance. + * \assert + * \code encoder != NULL \endcode + * \retval FLAC__SeekableStreamEncoderState + * \c FLAC__SEEKABLE_STREAM_ENCODER_OK if initialization was successful; see + * FLAC__SeekableStreamEncoderState for the meanings of other return values. + */ +FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder); + +/** Finish the encoding process. + * Flushes the encoding buffer, releases resources, resets the encoder + * settings to their defaults, and returns the encoder state to + * FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED. + * + * In the event of a prematurely-terminated encode, it is not strictly + * necessary to call this immediately before FLAC__seekable_stream_encoder_delete() + * but it is good practice to match every FLAC__seekable_stream_encoder_init() + * with a FLAC__seekable_stream_encoder_finish(). + * + * \param encoder An uninitialized encoder instance. + * \assert + * \code encoder != NULL \endcode + */ +void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder); + +/** Submit data for encoding. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_process(). + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of pointers to each channel's signal. + * \param samples The number of samples in one channel. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__seekable_stream_encoder_get_state(encoder) == FLAC__SEEKABLE_STREAM_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__seekable_stream_encoder_get_state() to see what + * went wrong. + */ +FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); + +/** Submit data for encoding. + * This is inherited from FLAC__StreamEncoder; see + * FLAC__stream_encoder_process_interleaved(). + * + * \param encoder An initialized encoder instance in the OK state. + * \param buffer An array of channel-interleaved data (see above). + * \param samples The number of samples in one channel, the same as for + * FLAC__seekable_stream_encoder_process(). For example, if + * encoding two channels, \c 1000 \a samples corresponds + * to a \a buffer of 2000 values. + * \assert + * \code encoder != NULL \endcode + * \code FLAC__seekable_stream_encoder_get_state(encoder) == FLAC__SEEKABLE_STREAM_ENCODER_OK \endcode + * \retval FLAC__bool + * \c true if successful, else \c false; in this case, check the + * encoder state with FLAC__seekable_stream_encoder_get_state() to see what + * went wrong. + */ +FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); + +/* \} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/FLAC/stream_encoder.h b/include/FLAC/stream_encoder.h index 8c2fa7ad..7ef95749 100644 --- a/include/FLAC/stream_encoder.h +++ b/include/FLAC/stream_encoder.h @@ -41,11 +41,18 @@ extern "C" { * \ingroup flac * * \brief - * This module describes the single encoder layer provided by libFLAC. + * This module describes the two encoder layers provided by libFLAC. * - * Currently there is only one level of encoder implementation which is at - * the stream level. There is currently no file encoder because seeking - * within a file while encoding seemed like too obscure a feature. + * For encoding FLAC streams, libFLAC provides two layers of access. The + * lowest layer is stream-level encoding, and the highest is file-level + * encoding. The interfaces are described in the \link flac_stream_encoder + * stream encoder \endlink and \link flac_file_encoder file encoder \endlink + * modules respectively. Typically you will choose the highest layer that + * your output source will support. + * + * The stream encoder relies on callbacks for writing the data and + * metadata. The file encoder provides these callbacks internally and you + * need only supply the filename. */ /** \defgroup flac_stream_encoder FLAC/stream_encoder.h: stream encoder interface @@ -574,6 +581,13 @@ FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC_ * audio frames and the data is not guaranteed to be aligned on frame or * metadata block boundaries. * + * The only duty of the callback is to write out the \a bytes worth of data + * in \a buffer to the current position in the output stream. The arguments + * \a samples and \a current_frame are purely informational. If \a samples + * is greater than \c 0, then \a current_frame will hold the current frame + * number that is being written; otherwise, the write callback is being called + * to write metadata. + * * \note * The callback is mandatory and must be set before initialization. * @@ -848,7 +862,6 @@ FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC * sample-aligned, i.e. the first value should be channel0_sample0 * and the last value channelN_sampleM. * - * * \param encoder An initialized encoder instance in the OK state. * \param buffer An array of channel-interleaved data (see above). * \param samples The number of samples in one channel, the same as for diff --git a/src/libFLAC/Makefile.am b/src/libFLAC/Makefile.am index f57c71aa..a21a9a86 100644 --- a/src/libFLAC/Makefile.am +++ b/src/libFLAC/Makefile.am @@ -51,6 +51,7 @@ libFLAC_la_SOURCES = \ cpu.c \ crc.c \ file_decoder.c \ + file_encoder.c \ fixed.c \ format.c \ lpc.c \ @@ -59,6 +60,7 @@ libFLAC_la_SOURCES = \ metadata_iterators.c \ metadata_object.c \ seekable_stream_decoder.c \ + seekable_stream_encoder.c \ stream_decoder.c \ stream_encoder.c \ stream_encoder_framing.c diff --git a/src/libFLAC/Makefile.lite b/src/libFLAC/Makefile.lite index 775c268f..2a81e3d8 100644 --- a/src/libFLAC/Makefile.lite +++ b/src/libFLAC/Makefile.lite @@ -50,6 +50,7 @@ OBJS = $(ASM_OBJS) \ cpu.o \ crc.o \ file_decoder.o \ + file_encoder.o \ fixed.o \ format.o \ lpc.o \ @@ -58,6 +59,7 @@ OBJS = $(ASM_OBJS) \ metadata_iterators.o \ metadata_object.o \ seekable_stream_decoder.o \ + seekable_stream_encoder.o \ stream_decoder.o \ stream_encoder.o \ stream_encoder_framing.o diff --git a/src/libFLAC/Makefile.vc b/src/libFLAC/Makefile.vc index ea45f3af..53466017 100644 --- a/src/libFLAC/Makefile.vc +++ b/src/libFLAC/Makefile.vc @@ -34,6 +34,7 @@ C_FILES= \ cpu.c \ crc.c \ file_decoder.c \ + file_encoder.c \ fixed.c \ format.c \ lpc.c \ @@ -42,6 +43,7 @@ C_FILES= \ metadata_iterators.c \ metadata_object.c \ seekable_stream_decoder.c \ + seekable_stream_encoder.c \ stream_decoder.c \ stream_encoder.c \ stream_encoder_framing.c diff --git a/src/libFLAC/file_encoder.c b/src/libFLAC/file_encoder.c new file mode 100644 index 00000000..3e1e0505 --- /dev/null +++ b/src/libFLAC/file_encoder.c @@ -0,0 +1,740 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2002 Josh Coalson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include /* for malloc() */ +#include /* for memcpy() */ +#include "FLAC/assert.h" +#include "protected/file_encoder.h" +#include "protected/seekable_stream_encoder.h" + +/*********************************************************************** + * + * Private class method prototypes + * + ***********************************************************************/ + +static void set_defaults_(FLAC__FileEncoder *encoder); +static FLAC__StreamEncoderWriteStatus file_encoder_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); +static void file_encoder_metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); + +/*********************************************************************** + * + * Private class data + * + ***********************************************************************/ + +typedef struct FLAC__FileEncoderPrivate { + FILE *file; + char *filename; + FLAC__SeekableStreamEncoder *seekable_stream_encoder; +} FLAC__FileEncoderPrivate; + +/*********************************************************************** + * + * Public static class data + * + ***********************************************************************/ + +const char * const FLAC__FileEncoderStateString[] = { + "FLAC__FILE_ENCODER_OK", + "FLAC__FILE_ENCODER_NO_FILENAME", + "FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR", + "FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING", + "FLAC__FILE_ENCODER_ERROR_OPENING_FILE", + "FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR", + "FLAC__FILE_ENCODER_ALREADY_INITIALIZED", + "FLAC__FILE_ENCODER_UNINITIALIZED" +}; + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ +FLAC__FileEncoder *FLAC__file_encoder_new() +{ + FLAC__FileEncoder *encoder; + + FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ + + encoder = (FLAC__FileEncoder*)malloc(sizeof(FLAC__FileEncoder)); + if(encoder == 0) { + return 0; + } + encoder->protected_ = (FLAC__FileEncoderProtected*)malloc(sizeof(FLAC__FileEncoderProtected)); + if(encoder->protected_ == 0) { + free(encoder); + return 0; + } + encoder->private_ = (FLAC__FileEncoderPrivate*)malloc(sizeof(FLAC__FileEncoderPrivate)); + if(encoder->private_ == 0) { + free(encoder->protected_); + free(encoder); + return 0; + } + + encoder->private_->seekable_stream_encoder = FLAC__seekable_stream_encoder_new(); + + if(0 == encoder->private_->seekable_stream_encoder) { + free(encoder->private_); + free(encoder->protected_); + free(encoder); + return 0; + } + + encoder->private_->file = 0; + + set_defaults_(encoder); + + encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED; + + return encoder; +} + +void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + + (void)FLAC__file_encoder_finish(encoder); + + FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder); + + free(encoder->private_); + free(encoder->protected_); + free(encoder); +} + +/*********************************************************************** + * + * Public class methods + * + ***********************************************************************/ + +FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED; + + if(0 == encoder->private_->filename) + return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME; + + encoder->private_->file = fopen(encoder->private_->filename, "wb"); + + if(encoder->private_->file == 0) + return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE; + + FLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_); + FLAC__seekable_stream_encoder_set_metadata_callback(encoder->private_->seekable_stream_encoder, metadata_callback_); + FLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder); + + if(FLAC__seekable_seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != FLAC__SEEKABLE_STREAM_ENCODER_OK) + return encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR; + + return decoder->protected_->state = FLAC__FILE_ENCODER_OK; +} + +void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + + if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED) + return; + + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + + if(0 != encoder->private_->file) { + fclose(encoder->private_->file); + encoder->private_->file = 0; + } + + if(0 != encoder->private_->filename) { + free(encoder->private_->filename); + encoder->private_->filename = 0; + } + + set_defaults_(encoder); + + encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED; + + return FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder); +} + +FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + return FLAC__seekable_stream_encoder_set_metadata(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != value); + if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) + return false; + if(0 != encoder->private_->filename) { + free(encoder->private_->filename); + encoder->private_->filename = 0; + } + if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) { + encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR; + return false; + } + strcpy(encoder->private_->filename, value); + return true; +} + +FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->state; +} + +FLAC__FileEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder); +} + +FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder); +} + +FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder); +} + +FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder); +} + +unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder); +} + +unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder); +} + +unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder); +} + +unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder); +} + +unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder); +} + +unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder); +} + +FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder); +} + +FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder); +} + +FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder); +} + +unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder); +} + +unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder); +} + +unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder); +} + +FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples); +} + +/* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */ +FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples); +} + +/*********************************************************************** + * + * Private class methods + * + ***********************************************************************/ + +void set_defaults_(FLAC__FileEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + + encoder->protected_->filename = 0; +} + +FLAC__StreamEncoderWriteStatus file_encoder_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) +{ + FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data; + + /* mark the current seek point if hit (if stream_offset == 0 that means we're still writing metadata and haven't hit the first frame yet) */ + if(file_encoder->private_->stream_offset > 0 && file_encoder->private_->seek_table.num_points > 0) { + FLAC__uint64 current_sample = (FLAC__uint64)current_frame * (FLAC__uint64)FLAC__stream_encoder_get_blocksize(encoder), test_sample; + unsigned i; + for(i = file_encoder->private_->first_seek_point_to_check; i < file_encoder->private_->seek_table.num_points; i++) { + test_sample = file_encoder->private_->seek_table.points[i].sample_number; + if(test_sample > current_sample) { + break; + } + else if(test_sample == current_sample) { + file_encoder->private_->seek_table.points[i].stream_offset = file_encoder->private_->bytes_written - file_encoder->private_->stream_offset; + file_encoder->private_->seek_table.points[i].frame_samples = FLAC__stream_encoder_get_blocksize(encoder); + file_encoder->private_->first_seek_point_to_check++; + break; + } + else { + file_encoder->private_->first_seek_point_to_check++; + } + } + } + + file_encoder->private_->bytes_written += bytes; + file_encoder->private_->samples_written += samples; + file_encoder->private_->current_frame = current_frame; + + if(samples && file_encoder->private_->verbose && file_encoder->private_->total_samples_to_encode > 0 && !(current_frame & mask)) + print_stats(file_encoder->private_); + + if(file_encoder->private_->verify) { + file_encoder->private_->verify_fifo.encoded_signal = buffer; + file_encoder->private_->verify_fifo.encoded_bytes = bytes; + if(file_encoder->private_->verify_fifo.into_frames) { + if(!FLAC__stream_decoder_process_one_frame(file_encoder->private_->verify_fifo.decoder)) { + file_encoder->private_->verify_fifo.result = FLAC__VERIFY_FAILED_IN_FRAME; + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + } + } + else { + if(!FLAC__stream_decoder_process_metadata(file_encoder->private_->verify_fifo.decoder)) { + file_encoder->private_->verify_fifo.result = FLAC__VERIFY_FAILED_IN_METADATA; + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + } + } + } + +#ifdef FLAC__HAS_OGG + if(file_encoder->private_->use_ogg) { + ogg_packet op; + + memset(&op, 0, sizeof(op)); + op.packet = (unsigned char *)buffer; + op.granulepos = file_encoder->private_->samples_written - 1; + /*@@@ WATCHOUT: + * this depends on the behavior of libFLAC that we will get one + * write_callback first with all the metadata (and 'samples' + * will be 0), then one write_callback for each frame. + */ + op.packetno = (samples == 0? -1 : (int)file_encoder->private_->current_frame); + op.bytes = bytes; + + if (file_encoder->private_->bytes_written == bytes) + op.b_o_s = 1; + + if (file_encoder->private_->total_samples_to_encode == file_encoder->private_->samples_written) + op.e_o_s = 1; + + ogg_stream_packetin(&file_encoder->private_->ogg.os, &op); + + while(ogg_stream_pageout(&file_encoder->private_->ogg.os, &file_encoder->private_->ogg.og) != 0) { + int written; + written = fwrite(file_encoder->private_->ogg.og.header, 1, file_encoder->private_->ogg.og.header_len, file_encoder->private_->fout); + if (written != file_encoder->private_->ogg.og.header_len) + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + + written = fwrite(file_encoder->private_->ogg.og.body, 1, file_encoder->private_->ogg.og.body_len, file_encoder->private_->fout); + if (written != file_encoder->private_->ogg.og.body_len) + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + } + + return FLAC__STREAM_ENCODER_WRITE_OK; + } + else +#endif + { + if(fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->fout) == bytes) + return FLAC__STREAM_ENCODER_WRITE_OK; + else + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + } +} + +void file_encoder_metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data) +{ + file_encoder->private_ *file_encoder->private_ = (file_encoder->private_ *)client_data; + FLAC__byte b; + FILE *f = file_encoder->private_->fout; + const FLAC__uint64 samples = metadata->data.stream_info.total_samples; + const unsigned min_framesize = metadata->data.stream_info.min_framesize; + const unsigned max_framesize = metadata->data.stream_info.max_framesize; + + FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO); + + /* + * If we are writing to an ogg stream, there is no need to go back + * and update the STREAMINFO or SEEKTABLE blocks; the values we would + * update are not necessary with Ogg as the transport. We can't do + * it reliably anyway without knowing the Ogg structure. + */ +#ifdef FLAC__HAS_OGG + if(file_encoder->private_->use_ogg) + return; +#endif + + /* + * we get called by the encoder when the encoding process has + * finished so that we can update the STREAMINFO and SEEKTABLE + * blocks. + */ + + (void)encoder; /* silence compiler warning about unused parameter */ + + if(f != stdout) { + fclose(file_encoder->private_->fout); + if(0 == (f = fopen(file_encoder->private_->outfilename, "r+b"))) + return; + } + + /* all this is based on intimate knowledge of the stream header + * layout, but a change to the header format that would break this + * would also break all streams encoded in the previous format. + */ + + if(-1 == fseek(f, 26, SEEK_SET)) goto end_; + fwrite(metadata->data.stream_info.md5sum, 1, 16, f); + + /* if we get this far we know we can seek so no need to check the + * return value from fseek() + */ + fseek(f, 21, SEEK_SET); + if(fread(&b, 1, 1, f) != 1) goto framesize_; + fseek(f, 21, SEEK_SET); + b = (b & 0xf0) | (FLAC__byte)((samples >> 32) & 0x0F); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + b = (FLAC__byte)((samples >> 24) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + b = (FLAC__byte)((samples >> 16) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + b = (FLAC__byte)((samples >> 8) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + b = (FLAC__byte)(samples & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + +framesize_: + fseek(f, 12, SEEK_SET); + b = (FLAC__byte)((min_framesize >> 16) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)((min_framesize >> 8) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)(min_framesize & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)((max_framesize >> 16) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)((max_framesize >> 8) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)(max_framesize & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + +seektable_: + if(file_encoder->private_->seek_table.num_points > 0) { + long pos; + unsigned i; + + /* convert any unused seek points to placeholders */ + for(i = 0; i < file_encoder->private_->seek_table.num_points; i++) { + if(file_encoder->private_->seek_table.points[i].sample_number == FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) + break; + else if(file_encoder->private_->seek_table.points[i].frame_samples == 0) + file_encoder->private_->seek_table.points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + } + + /* the offset of the seek table data 'pos' should be after then stream sync and STREAMINFO block and SEEKTABLE header */ + pos = (FLAC__STREAM_SYNC_LEN + FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8; + pos += metadata->length; + pos += (FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8; + fseek(f, pos, SEEK_SET); + for(i = 0; i < file_encoder->private_->seek_table.num_points; i++) { + if(!write_big_endian_uint64(f, file_encoder->private_->seek_table.points[i].sample_number)) goto end_; + if(!write_big_endian_uint64(f, file_encoder->private_->seek_table.points[i].stream_offset)) goto end_; + if(!write_big_endian_uint16(f, (FLAC__uint16)file_encoder->private_->seek_table.points[i].frame_samples)) goto end_; + } + } + +end_: + fclose(f); + return; +} diff --git a/src/libFLAC/include/protected/Makefile.am b/src/libFLAC/include/protected/Makefile.am index 58ee9cf7..8920146c 100644 --- a/src/libFLAC/include/protected/Makefile.am +++ b/src/libFLAC/include/protected/Makefile.am @@ -19,6 +19,8 @@ noinst_HEADERS = \ all.h \ file_decoder.h \ + file_encoder.h \ seekable_stream_decoder.h \ + seekable_stream_encoder.h \ stream_decoder.h \ stream_encoder.h diff --git a/src/libFLAC/include/protected/all.h b/src/libFLAC/include/protected/all.h index 2d9b2af5..153fa48f 100644 --- a/src/libFLAC/include/protected/all.h +++ b/src/libFLAC/include/protected/all.h @@ -21,7 +21,9 @@ #define FLAC__PROTECTED__ALL_H #include "file_decoder.h" +#include "file_encoder.h" #include "seekable_stream_decoder.h" +#include "seekable_stream_encoder.h" #include "stream_decoder.h" #include "stream_encoder.h" diff --git a/src/libFLAC/include/protected/file_encoder.h b/src/libFLAC/include/protected/file_encoder.h new file mode 100644 index 00000000..d4dcee46 --- /dev/null +++ b/src/libFLAC/include/protected/file_encoder.h @@ -0,0 +1,29 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2001,2002 Josh Coalson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__PROTECTED__FILE_ENCODER_H +#define FLAC__PROTECTED__FILE_ENCODER_H + +#include "FLAC/file_encoder.h" + +typedef struct FLAC__FileEncoderProtected { + FLAC__FileEncoderState state; +} FLAC__FileEncoderProtected; + +#endif diff --git a/src/libFLAC/include/protected/seekable_stream_encoder.h b/src/libFLAC/include/protected/seekable_stream_encoder.h new file mode 100644 index 00000000..ccd51e54 --- /dev/null +++ b/src/libFLAC/include/protected/seekable_stream_encoder.h @@ -0,0 +1,29 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2002 Josh Coalson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef FLAC__PROTECTED__SEEKABLE_STREAM_ENCODER_H +#define FLAC__PROTECTED__SEEKABLE_STREAM_ENCODER_H + +#include "FLAC/seekable_stream_encoder.h" + +typedef struct FLAC__SeekableStreamEncoderProtected { + FLAC__SeekableStreamEncoderState state; +} FLAC__SeekableStreamEncoderProtected; + +#endif diff --git a/src/libFLAC/seekable_stream_encoder.c b/src/libFLAC/seekable_stream_encoder.c new file mode 100644 index 00000000..50205f4f --- /dev/null +++ b/src/libFLAC/seekable_stream_encoder.c @@ -0,0 +1,749 @@ +/* libFLAC - Free Lossless Audio Codec library + * Copyright (C) 2002 Josh Coalson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include /* for malloc() */ +#include /* for memcpy() */ +#include "FLAC/assert.h" +#include "protected/seekable_stream_encoder.h" +#include "protected/stream_encoder.h" + +/*********************************************************************** + * + * Private class method prototypes + * + ***********************************************************************/ + +static void set_defaults_(FLAC__SeekableStreamEncoder *encoder); +static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); +static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); + +/*********************************************************************** + * + * Private class data + * + ***********************************************************************/ + +typedef struct FLAC__SeekableStreamEncoderPrivate { + FILE *file; + char *filename; + FLAC__StreamEncoder *stream_encoder; +} FLAC__SeekableStreamEncoderPrivate; + +/*********************************************************************** + * + * Public static class data + * + ***********************************************************************/ + +const char * const FLAC__SeekableStreamEncoderStateString[] = { + "FLAC__SEEKABLE_STREAM_ENCODER_OK", + "FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR", + "FLAC__SEEKABLE_STREAM_ENCODER_ERROR_OPENING_FILE", + "FLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR", + "FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED", + "FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED" +}; + + +/*********************************************************************** + * + * Class constructor/destructor + * + ***********************************************************************/ +FLAC__SeekableStreamEncoder *FLAC__seekable_stream_encoder_new() +{ + FLAC__SeekableStreamEncoder *encoder; + + FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ + + encoder = (FLAC__SeekableStreamEncoder*)malloc(sizeof(FLAC__SeekableStreamEncoder)); + if(encoder == 0) { + return 0; + } + encoder->protected_ = (FLAC__SeekableStreamEncoderProtected*)malloc(sizeof(FLAC__SeekableStreamEncoderProtected)); + if(encoder->protected_ == 0) { + free(encoder); + return 0; + } + encoder->private_ = (FLAC__SeekableStreamEncoderPrivate*)malloc(sizeof(FLAC__SeekableStreamEncoderPrivate)); + if(encoder->private_ == 0) { + free(encoder->protected_); + free(encoder); + return 0; + } + + encoder->private_->stream_encoder = FLAC__stream_encoder_new(); + + if(0 == encoder->private_->stream_encoder) { + free(encoder->private_); + free(encoder->protected_); + free(encoder); + return 0; + } + + set_defaults_(encoder); + + encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED; + + return encoder; +} + +void FLAC__seekable_stream_encoder_delete(FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + + (void)FLAC__seekable_stream_encoder_finish(encoder); + + FLAC__stream_encoder_delete(encoder->private_->stream_encoder); + + free(encoder->private_); + free(encoder->protected_); + free(encoder); +} + +/*********************************************************************** + * + * Public class methods + * + ***********************************************************************/ + +FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_init(FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED; + + if(0 == encoder->private_->filename) + return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_NO_FILENAME; + + encoder->private_->file = fopen(encoder->private_->filename, "wb"); + + if(encoder->private_->file == 0) + return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_ERROR_OPENING_FILE; + + FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_); + FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_); + FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder); + + if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK) + return encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_STREAM_ENCODER_ERROR; + + return decoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_OK; +} + +void FLAC__seekable_stream_encoder_finish(FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + + if(encoder->protected_->state == FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return; + + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + + if(0 != encoder->private_->file) { + fclose(encoder->private_->file); + encoder->private_->file = 0; + } + + if(0 != encoder->private_->filename) { + free(encoder->private_->filename); + encoder->private_->filename = 0; + } + + set_defaults_(encoder); + + encoder->protected_->state = FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED; + + return FLAC__stream_encoder_finish(encoder->private_->stream_encoder); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_streamable_subset(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_do_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_channels(FLAC__SeekableStreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_bits_per_sample(FLAC__SeekableStreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__SeekableStreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_qlp_coeff_precision(FLAC__SeekableStreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_do_escape_coding(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_min_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_max_residual_partition_order(FLAC__SeekableStreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(FLAC__SeekableStreamEncoder *encoder, unsigned value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_total_samples_estimate(FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_metadata(FLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_->stream_encoder); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, value); +} + +FLAC__bool FLAC__seekable_stream_encoder_set_seek_callback(FLAC__SeekableStreamEncoder *encoder, FLAC__SeekableStreamEncoderSeekStatus (*value)(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->private_->seek_callback = value; + return true; +} + +FLAC__bool FLAC__stream_encoder_set_write_callback(FLAC__StreamEncoder *encoder, FLAC__StreamEncoderWriteStatus (*value)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->private_->write_callback = value; + return true; +} + +FLAC__bool FLAC__stream_encoder_set_client_data(FLAC__StreamEncoder *encoder, void *value) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + if(encoder->protected_->state != FLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED) + return false; + encoder->private_->client_data = value; + return true; +} + +FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_state(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->protected_); + return encoder->protected_->state; +} + +FLAC__SeekableStreamEncoderState FLAC__seekable_stream_encoder_get_stream_encoder_state(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_state(encoder->private_->stream_encoder); +} + +FLAC__bool FLAC__seekable_stream_encoder_get_streamable_subset(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_streamable_subset(encoder->private_->stream_encoder); +} + +FLAC__bool FLAC__seekable_stream_encoder_get_do_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->stream_encoder); +} + +FLAC__bool FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->stream_encoder); +} + +unsigned FLAC__seekable_stream_encoder_get_channels(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_channels(encoder->private_->stream_encoder); +} + +unsigned FLAC__seekable_stream_encoder_get_bits_per_sample(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->stream_encoder); +} + +unsigned FLAC__seekable_stream_encoder_get_sample_rate(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_sample_rate(encoder->private_->stream_encoder); +} + +unsigned FLAC__seekable_stream_encoder_get_blocksize(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_blocksize(encoder->private_->stream_encoder); +} + +unsigned FLAC__seekable_stream_encoder_get_max_lpc_order(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->stream_encoder); +} + +unsigned FLAC__seekable_stream_encoder_get_qlp_coeff_precision(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->stream_encoder); +} + +FLAC__bool FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->stream_encoder); +} + +FLAC__bool FLAC__seekable_stream_encoder_get_do_escape_coding(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->stream_encoder); +} + +FLAC__bool FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->stream_encoder); +} + +unsigned FLAC__seekable_stream_encoder_get_min_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->stream_encoder); +} + +unsigned FLAC__seekable_stream_encoder_get_max_residual_partition_order(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->stream_encoder); +} + +unsigned FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->stream_encoder); +} + +FLAC__bool FLAC__seekable_stream_encoder_process(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_process(encoder->private_->stream_encoder, buffer, samples); +} + +/* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */ +FLAC__bool FLAC__seekable_stream_encoder_process_interleaved(FLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + return FLAC__stream_encoder_process_interleaved(encoder->private_->stream_encoder, buffer, samples); +} + +/*********************************************************************** + * + * Private class methods + * + ***********************************************************************/ + +void set_defaults_(FLAC__SeekableStreamEncoder *encoder) +{ + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->protected_); + + encoder->protected_->filename = 0; +} + +FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) +{ + FLAC__SeekableStreamEncoder *seekable_stream_encoder = (FLAC__SeekableStreamEncoder*)client_data; + + /* mark the current seek point if hit (if stream_offset == 0 that means we're still writing metadata and haven't hit the first frame yet) */ + if(seekable_stream_encoder->private_->stream_offset > 0 && seekable_stream_encoder->private_->seek_table.num_points > 0) { + FLAC__uint64 current_sample = (FLAC__uint64)current_frame * (FLAC__uint64)FLAC__stream_encoder_get_blocksize(encoder), test_sample; + unsigned i; + for(i = seekable_stream_encoder->private_->first_seek_point_to_check; i < seekable_stream_encoder->private_->seek_table.num_points; i++) { + test_sample = seekable_stream_encoder->private_->seek_table.points[i].sample_number; + if(test_sample > current_sample) { + break; + } + else if(test_sample == current_sample) { + seekable_stream_encoder->private_->seek_table.points[i].stream_offset = seekable_stream_encoder->private_->bytes_written - seekable_stream_encoder->private_->stream_offset; + seekable_stream_encoder->private_->seek_table.points[i].frame_samples = FLAC__stream_encoder_get_blocksize(encoder); + seekable_stream_encoder->private_->first_seek_point_to_check++; + break; + } + else { + seekable_stream_encoder->private_->first_seek_point_to_check++; + } + } + } + + seekable_stream_encoder->private_->bytes_written += bytes; + seekable_stream_encoder->private_->samples_written += samples; + seekable_stream_encoder->private_->current_frame = current_frame; + + if(samples && seekable_stream_encoder->private_->verbose && seekable_stream_encoder->private_->total_samples_to_encode > 0 && !(current_frame & mask)) + print_stats(seekable_stream_encoder->private_); + + if(seekable_stream_encoder->private_->verify) { + seekable_stream_encoder->private_->verify_fifo.encoded_signal = buffer; + seekable_stream_encoder->private_->verify_fifo.encoded_bytes = bytes; + if(seekable_stream_encoder->private_->verify_fifo.into_frames) { + if(!FLAC__stream_decoder_process_one_frame(seekable_stream_encoder->private_->verify_fifo.decoder)) { + seekable_stream_encoder->private_->verify_fifo.result = FLAC__VERIFY_FAILED_IN_FRAME; + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + } + } + else { + if(!FLAC__stream_decoder_process_metadata(seekable_stream_encoder->private_->verify_fifo.decoder)) { + seekable_stream_encoder->private_->verify_fifo.result = FLAC__VERIFY_FAILED_IN_METADATA; + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + } + } + } + +#ifdef FLAC__HAS_OGG + if(seekable_stream_encoder->private_->use_ogg) { + ogg_packet op; + + memset(&op, 0, sizeof(op)); + op.packet = (unsigned char *)buffer; + op.granulepos = seekable_stream_encoder->private_->samples_written - 1; + /*@@@ WATCHOUT: + * this depends on the behavior of libFLAC that we will get one + * write_callback first with all the metadata (and 'samples' + * will be 0), then one write_callback for each frame. + */ + op.packetno = (samples == 0? -1 : (int)seekable_stream_encoder->private_->current_frame); + op.bytes = bytes; + + if (seekable_stream_encoder->private_->bytes_written == bytes) + op.b_o_s = 1; + + if (seekable_stream_encoder->private_->total_samples_to_encode == seekable_stream_encoder->private_->samples_written) + op.e_o_s = 1; + + ogg_stream_packetin(&seekable_stream_encoder->private_->ogg.os, &op); + + while(ogg_stream_pageout(&seekable_stream_encoder->private_->ogg.os, &seekable_stream_encoder->private_->ogg.og) != 0) { + int written; + written = fwrite(seekable_stream_encoder->private_->ogg.og.header, 1, seekable_stream_encoder->private_->ogg.og.header_len, seekable_stream_encoder->private_->fout); + if (written != seekable_stream_encoder->private_->ogg.og.header_len) + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + + written = fwrite(seekable_stream_encoder->private_->ogg.og.body, 1, seekable_stream_encoder->private_->ogg.og.body_len, seekable_stream_encoder->private_->fout); + if (written != seekable_stream_encoder->private_->ogg.og.body_len) + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + } + + return FLAC__STREAM_ENCODER_WRITE_OK; + } + else +#endif + { + if(fwrite(buffer, sizeof(FLAC__byte), bytes, seekable_stream_encoder->private_->fout) == bytes) + return FLAC__STREAM_ENCODER_WRITE_OK; + else + return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR; + } +} + +void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data) +{ + seekable_stream_encoder->private_ *seekable_stream_encoder->private_ = (seekable_stream_encoder->private_ *)client_data; + FLAC__byte b; + FILE *f = seekable_stream_encoder->private_->fout; + const FLAC__uint64 samples = metadata->data.stream_info.total_samples; + const unsigned min_framesize = metadata->data.stream_info.min_framesize; + const unsigned max_framesize = metadata->data.stream_info.max_framesize; + + FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO); + + /* + * If we are writing to an ogg stream, there is no need to go back + * and update the STREAMINFO or SEEKTABLE blocks; the values we would + * update are not necessary with Ogg as the transport. We can't do + * it reliably anyway without knowing the Ogg structure. + */ +#ifdef FLAC__HAS_OGG + if(seekable_stream_encoder->private_->use_ogg) + return; +#endif + + /* + * we get called by the encoder when the encoding process has + * finished so that we can update the STREAMINFO and SEEKTABLE + * blocks. + */ + + (void)encoder; /* silence compiler warning about unused parameter */ + + if(f != stdout) { + fclose(seekable_stream_encoder->private_->fout); + if(0 == (f = fopen(seekable_stream_encoder->private_->outfilename, "r+b"))) + return; + } + + /* all this is based on intimate knowledge of the stream header + * layout, but a change to the header format that would break this + * would also break all streams encoded in the previous format. + */ + + if(-1 == fseek(f, 26, SEEK_SET)) goto end_; + fwrite(metadata->data.stream_info.md5sum, 1, 16, f); + + /* if we get this far we know we can seek so no need to check the + * return value from fseek() + */ + fseek(f, 21, SEEK_SET); + if(fread(&b, 1, 1, f) != 1) goto framesize_; + fseek(f, 21, SEEK_SET); + b = (b & 0xf0) | (FLAC__byte)((samples >> 32) & 0x0F); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + b = (FLAC__byte)((samples >> 24) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + b = (FLAC__byte)((samples >> 16) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + b = (FLAC__byte)((samples >> 8) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + b = (FLAC__byte)(samples & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto framesize_; + +framesize_: + fseek(f, 12, SEEK_SET); + b = (FLAC__byte)((min_framesize >> 16) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)((min_framesize >> 8) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)(min_framesize & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)((max_framesize >> 16) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)((max_framesize >> 8) & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + b = (FLAC__byte)(max_framesize & 0xFF); + if(fwrite(&b, 1, 1, f) != 1) goto seektable_; + +seektable_: + if(seekable_stream_encoder->private_->seek_table.num_points > 0) { + long pos; + unsigned i; + + /* convert any unused seek points to placeholders */ + for(i = 0; i < seekable_stream_encoder->private_->seek_table.num_points; i++) { + if(seekable_stream_encoder->private_->seek_table.points[i].sample_number == FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) + break; + else if(seekable_stream_encoder->private_->seek_table.points[i].frame_samples == 0) + seekable_stream_encoder->private_->seek_table.points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; + } + + /* the offset of the seek table data 'pos' should be after then stream sync and STREAMINFO block and SEEKTABLE header */ + pos = (FLAC__STREAM_SYNC_LEN + FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8; + pos += metadata->length; + pos += (FLAC__STREAM_METADATA_IS_LAST_LEN + FLAC__STREAM_METADATA_TYPE_LEN + FLAC__STREAM_METADATA_LENGTH_LEN) / 8; + fseek(f, pos, SEEK_SET); + for(i = 0; i < seekable_stream_encoder->private_->seek_table.num_points; i++) { + if(!write_big_endian_uint64(f, seekable_stream_encoder->private_->seek_table.points[i].sample_number)) goto end_; + if(!write_big_endian_uint64(f, seekable_stream_encoder->private_->seek_table.points[i].stream_offset)) goto end_; + if(!write_big_endian_uint16(f, (FLAC__uint16)seekable_stream_encoder->private_->seek_table.points[i].frame_samples)) goto end_; + } + } + +end_: + fclose(f); + return; +} diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c index dcd2c923..44b05dda 100644 --- a/src/libFLAC/stream_encoder.c +++ b/src/libFLAC/stream_encoder.c @@ -48,28 +48,28 @@ * ***********************************************************************/ -static void stream_encoder_set_defaults_(FLAC__StreamEncoder *encoder); -static void stream_encoder_free_(FLAC__StreamEncoder *encoder); -static FLAC__bool stream_encoder_resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size); -static FLAC__bool stream_encoder_process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame); -static FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame); -static FLAC__bool stream_encoder_process_subframe_(FLAC__StreamEncoder *encoder, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool verbatim_only, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__int32 integer_signal[], const FLAC__real real_signal[], FLAC__Subframe *subframe[2], FLAC__int32 *residual[2], unsigned *best_subframe, unsigned *best_bits); -static FLAC__bool stream_encoder_add_subframe_(FLAC__StreamEncoder *encoder, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__Subframe *subframe, FLAC__BitBuffer *frame); -static unsigned stream_encoder_evaluate_constant_subframe_(const FLAC__int32 signal, unsigned subframe_bps, FLAC__Subframe *subframe); -static unsigned stream_encoder_evaluate_fixed_subframe_(FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe); -static unsigned stream_encoder_evaluate_lpc_subframe_(FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], const FLAC__real lp_coeff[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe); -static unsigned stream_encoder_evaluate_verbatim_subframe_(const FLAC__int32 signal[], unsigned blocksize, unsigned subframe_bps, FLAC__Subframe *subframe); -static unsigned stream_encoder_find_best_partition_order_(struct FLAC__StreamEncoderPrivate *private_, const FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, unsigned *best_partition_order, unsigned best_parameters[], unsigned best_raw_bits[]); -static void stream_encoder_precompute_partition_info_sums_(const FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order); -static void stream_encoder_precompute_partition_info_escapes_(const FLAC__int32 residual[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order); +static void set_defaults_(FLAC__StreamEncoder *encoder); +static void free_(FLAC__StreamEncoder *encoder); +static FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size); +static FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame); +static FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame); +static FLAC__bool process_subframe_(FLAC__StreamEncoder *encoder, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool verbatim_only, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__int32 integer_signal[], const FLAC__real real_signal[], FLAC__Subframe *subframe[2], FLAC__int32 *residual[2], unsigned *best_subframe, unsigned *best_bits); +static FLAC__bool add_subframe_(FLAC__StreamEncoder *encoder, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__Subframe *subframe, FLAC__BitBuffer *frame); +static unsigned evaluate_constant_subframe_(const FLAC__int32 signal, unsigned subframe_bps, FLAC__Subframe *subframe); +static unsigned evaluate_fixed_subframe_(FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe); +static unsigned evaluate_lpc_subframe_(FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], const FLAC__real lp_coeff[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe); +static unsigned evaluate_verbatim_subframe_(const FLAC__int32 signal[], unsigned blocksize, unsigned subframe_bps, FLAC__Subframe *subframe); +static unsigned find_best_partition_order_(struct FLAC__StreamEncoderPrivate *private_, const FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, unsigned *best_partition_order, unsigned best_parameters[], unsigned best_raw_bits[]); +static void precompute_partition_info_sums_(const FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order); +static void precompute_partition_info_escapes_(const FLAC__int32 residual[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order); #ifdef DONT_ESTIMATE_RICE_BITS -static FLAC__bool stream_encoder_set_partitioned_rice_(const FLAC__uint32 abs_residual[], const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, unsigned parameters[], unsigned *bits); -static FLAC__bool stream_encoder_set_partitioned_rice_with_precompute_(const FLAC__int32 residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, unsigned parameters[], unsigned raw_bits[], unsigned *bits); +static FLAC__bool set_partitioned_rice_(const FLAC__uint32 abs_residual[], const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, unsigned parameters[], unsigned *bits); +static FLAC__bool set_partitioned_rice_with_precompute_(const FLAC__int32 residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, unsigned parameters[], unsigned raw_bits[], unsigned *bits); #else -static FLAC__bool stream_encoder_set_partitioned_rice_(const FLAC__uint32 abs_residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, unsigned parameters[], unsigned *bits); -static FLAC__bool stream_encoder_set_partitioned_rice_with_precompute_(const FLAC__uint32 abs_residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, unsigned parameters[], unsigned raw_bits[], unsigned *bits); +static FLAC__bool set_partitioned_rice_(const FLAC__uint32 abs_residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, unsigned parameters[], unsigned *bits); +static FLAC__bool set_partitioned_rice_with_precompute_(const FLAC__uint32 abs_residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, unsigned parameters[], unsigned raw_bits[], unsigned *bits); #endif -static unsigned stream_encoder_get_wasted_bits_(FLAC__int32 signal[], unsigned samples); +static unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples); /*********************************************************************** * @@ -133,8 +133,8 @@ typedef struct FLAC__StreamEncoderPrivate { * These fields have been moved here from private function local * declarations merely to save stack space during encoding. */ - FLAC__real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER]; /* from stream_encoder_process_subframe_() */ - unsigned parameters[2][1 << FLAC__MAX_RICE_PARTITION_ORDER], raw_bits[2][1 << FLAC__MAX_RICE_PARTITION_ORDER]; /* from stream_encoder_find_best_partition_order_() */ + FLAC__real lp_coeff[FLAC__MAX_LPC_ORDER][FLAC__MAX_LPC_ORDER]; /* from process_subframe_() */ + unsigned parameters[2][1 << FLAC__MAX_RICE_PARTITION_ORDER], raw_bits[2][1 << FLAC__MAX_RICE_PARTITION_ORDER]; /* from find_best_partition_order_() */ } FLAC__StreamEncoderPrivate; /*********************************************************************** @@ -204,7 +204,7 @@ FLAC__StreamEncoder *FLAC__stream_encoder_new() return 0; } - stream_encoder_set_defaults_(encoder); + set_defaults_(encoder); encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; @@ -213,12 +213,12 @@ FLAC__StreamEncoder *FLAC__stream_encoder_new() void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder) { - FLAC__ASSERT(encoder != 0); - FLAC__ASSERT(encoder->protected_ != 0); - FLAC__ASSERT(encoder->private_ != 0); - FLAC__ASSERT(encoder->private_->frame != 0); + FLAC__ASSERT(0 != encoder); + FLAC__ASSERT(0 != encoder->protected_); + FLAC__ASSERT(0 != encoder->private_); + FLAC__ASSERT(0 != encoder->private_->frame); - stream_encoder_free_(encoder); + free_(encoder); FLAC__bitbuffer_delete(encoder->private_->frame); free(encoder->private_); free(encoder->protected_); @@ -235,7 +235,7 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder) { unsigned i; - FLAC__ASSERT(encoder != 0); + FLAC__ASSERT(0 != encoder); if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED) return encoder->protected_->state = FLAC__STREAM_ENCODER_ALREADY_INITIALIZED; @@ -416,7 +416,7 @@ FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder *encoder) /* we require precompute_partition_sums if do_escape_coding because of their intertwined nature */ encoder->private_->precompute_partition_sums = (encoder->protected_->max_residual_partition_order > encoder->protected_->min_residual_partition_order) || encoder->protected_->do_escape_coding; - if(!stream_encoder_resize_buffers_(encoder, encoder->protected_->blocksize)) { + if(!resize_buffers_(encoder, encoder->protected_->blocksize)) { /* the above function sets the state for us in case of an error */ return encoder->protected_->state; } @@ -477,18 +477,18 @@ void FLAC__stream_encoder_finish(FLAC__StreamEncoder *encoder) { unsigned i, channel; - FLAC__ASSERT(encoder != 0); + FLAC__ASSERT(0 != encoder); if(encoder->protected_->state == FLAC__STREAM_ENCODER_UNINITIALIZED) return; if(encoder->private_->current_sample_number != 0) { encoder->protected_->blocksize = encoder->private_->current_sample_number; - stream_encoder_process_frame_(encoder, true); /* true => is last frame */ + process_frame_(encoder, true); /* true => is last frame */ } MD5Final(encoder->private_->metadata.data.stream_info.md5sum, &encoder->private_->md5context); encoder->private_->metadata_callback(encoder, &encoder->private_->metadata, encoder->private_->client_data); - stream_encoder_free_(encoder); - stream_encoder_set_defaults_(encoder); + free_(encoder); + set_defaults_(encoder); encoder->protected_->state = FLAC__STREAM_ENCODER_UNINITIALIZED; } @@ -782,7 +782,7 @@ FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC FLAC__int32 x, mid, side; const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize; - FLAC__ASSERT(encoder != 0); + FLAC__ASSERT(0 != encoder); FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); j = 0; @@ -805,7 +805,7 @@ FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC encoder->private_->current_sample_number++; } if(i == blocksize) { - if(!stream_encoder_process_frame_(encoder, false)) /* false => not last frame */ + if(!process_frame_(encoder, false)) /* false => not last frame */ return false; } } while(j < samples); @@ -821,7 +821,7 @@ FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC encoder->private_->current_sample_number++; } if(i == blocksize) { - if(!stream_encoder_process_frame_(encoder, false)) /* false => not last frame */ + if(!process_frame_(encoder, false)) /* false => not last frame */ return false; } } while(j < samples); @@ -837,7 +837,7 @@ FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder FLAC__int32 x, mid, side; const unsigned channels = encoder->protected_->channels, blocksize = encoder->protected_->blocksize; - FLAC__ASSERT(encoder != 0); + FLAC__ASSERT(0 != encoder); FLAC__ASSERT(encoder->protected_->state == FLAC__STREAM_ENCODER_OK); j = k = 0; @@ -860,7 +860,7 @@ FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder encoder->private_->current_sample_number++; } if(i == blocksize) { - if(!stream_encoder_process_frame_(encoder, false)) /* false => not last frame */ + if(!process_frame_(encoder, false)) /* false => not last frame */ return false; } } while(j < samples); @@ -876,7 +876,7 @@ FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder encoder->private_->current_sample_number++; } if(i == blocksize) { - if(!stream_encoder_process_frame_(encoder, false)) /* false => not last frame */ + if(!process_frame_(encoder, false)) /* false => not last frame */ return false; } } while(j < samples); @@ -885,7 +885,13 @@ FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder return true; } -void stream_encoder_set_defaults_(FLAC__StreamEncoder *encoder) +/*********************************************************************** + * + * Private class methods + * + ***********************************************************************/ + +void set_defaults_(FLAC__StreamEncoder *encoder) { FLAC__ASSERT(0 != encoder); @@ -913,34 +919,34 @@ void stream_encoder_set_defaults_(FLAC__StreamEncoder *encoder) encoder->private_->client_data = 0; } -void stream_encoder_free_(FLAC__StreamEncoder *encoder) +void free_(FLAC__StreamEncoder *encoder) { unsigned i, channel; - FLAC__ASSERT(encoder != 0); + FLAC__ASSERT(0 != encoder); for(i = 0; i < encoder->protected_->channels; i++) { - if(encoder->private_->integer_signal_unaligned[i] != 0) { + if(0 != encoder->private_->integer_signal_unaligned[i]) { free(encoder->private_->integer_signal_unaligned[i]); encoder->private_->integer_signal_unaligned[i] = 0; } - if(encoder->private_->real_signal_unaligned[i] != 0) { + if(0 != encoder->private_->real_signal_unaligned[i]) { free(encoder->private_->real_signal_unaligned[i]); encoder->private_->real_signal_unaligned[i] = 0; } } for(i = 0; i < 2; i++) { - if(encoder->private_->integer_signal_mid_side_unaligned[i] != 0) { + if(0 != encoder->private_->integer_signal_mid_side_unaligned[i]) { free(encoder->private_->integer_signal_mid_side_unaligned[i]); encoder->private_->integer_signal_mid_side_unaligned[i] = 0; } - if(encoder->private_->real_signal_mid_side_unaligned[i] != 0) { + if(0 != encoder->private_->real_signal_mid_side_unaligned[i]) { free(encoder->private_->real_signal_mid_side_unaligned[i]); encoder->private_->real_signal_mid_side_unaligned[i] = 0; } } for(channel = 0; channel < encoder->protected_->channels; channel++) { for(i = 0; i < 2; i++) { - if(encoder->private_->residual_workspace_unaligned[channel][i] != 0) { + if(0 != encoder->private_->residual_workspace_unaligned[channel][i]) { free(encoder->private_->residual_workspace_unaligned[channel][i]); encoder->private_->residual_workspace_unaligned[channel][i] = 0; } @@ -948,28 +954,28 @@ void stream_encoder_free_(FLAC__StreamEncoder *encoder) } for(channel = 0; channel < 2; channel++) { for(i = 0; i < 2; i++) { - if(encoder->private_->residual_workspace_mid_side_unaligned[channel][i] != 0) { + if(0 != encoder->private_->residual_workspace_mid_side_unaligned[channel][i]) { free(encoder->private_->residual_workspace_mid_side_unaligned[channel][i]); encoder->private_->residual_workspace_mid_side_unaligned[channel][i] = 0; } } } - if(encoder->private_->abs_residual_unaligned != 0) { + if(0 != encoder->private_->abs_residual_unaligned) { free(encoder->private_->abs_residual_unaligned); encoder->private_->abs_residual_unaligned = 0; } - if(encoder->private_->abs_residual_partition_sums_unaligned != 0) { + if(0 != encoder->private_->abs_residual_partition_sums_unaligned) { free(encoder->private_->abs_residual_partition_sums_unaligned); encoder->private_->abs_residual_partition_sums_unaligned = 0; } - if(encoder->private_->raw_bits_per_partition_unaligned != 0) { + if(0 != encoder->private_->raw_bits_per_partition_unaligned) { free(encoder->private_->raw_bits_per_partition_unaligned); encoder->private_->raw_bits_per_partition_unaligned = 0; } FLAC__bitbuffer_free(encoder->private_->frame); } -FLAC__bool stream_encoder_resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size) +FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size) { FLAC__bool ok; unsigned i, channel; @@ -1022,13 +1028,7 @@ FLAC__bool stream_encoder_resize_buffers_(FLAC__StreamEncoder *encoder, unsigned return ok; } -/*********************************************************************** - * - * Private class methods - * - ***********************************************************************/ - -FLAC__bool stream_encoder_process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame) +FLAC__bool process_frame_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame) { const FLAC__byte *buffer; unsigned bytes; @@ -1046,7 +1046,7 @@ FLAC__bool stream_encoder_process_frame_(FLAC__StreamEncoder *encoder, FLAC__boo /* * Process the frame header and subframes into the frame bitbuffer */ - if(!stream_encoder_process_subframes_(encoder, is_last_frame)) { + if(!process_subframes_(encoder, is_last_frame)) { /* the above function sets the state for us in case of an error */ return false; } @@ -1087,7 +1087,7 @@ FLAC__bool stream_encoder_process_frame_(FLAC__StreamEncoder *encoder, FLAC__boo return true; } -FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame) +FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_frame) { FLAC__FrameHeader frame_header; unsigned channel, min_partition_order = encoder->protected_->min_residual_partition_order, max_partition_order; @@ -1158,7 +1158,7 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ if(do_independent) { unsigned w; for(channel = 0; channel < encoder->protected_->channels; channel++) { - w = stream_encoder_get_wasted_bits_(encoder->private_->integer_signal[channel], encoder->protected_->blocksize); + w = get_wasted_bits_(encoder->private_->integer_signal[channel], encoder->protected_->blocksize); encoder->private_->subframe_workspace[channel][0].wasted_bits = encoder->private_->subframe_workspace[channel][1].wasted_bits = w; encoder->private_->subframe_bps[channel] = encoder->protected_->bits_per_sample - w; } @@ -1167,7 +1167,7 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ unsigned w; FLAC__ASSERT(encoder->protected_->channels == 2); for(channel = 0; channel < 2; channel++) { - w = stream_encoder_get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize); + w = get_wasted_bits_(encoder->private_->integer_signal_mid_side[channel], encoder->protected_->blocksize); encoder->private_->subframe_workspace_mid_side[channel][0].wasted_bits = encoder->private_->subframe_workspace_mid_side[channel][1].wasted_bits = w; encoder->private_->subframe_bps_mid_side[channel] = encoder->protected_->bits_per_sample - w + (channel==0? 0:1); } @@ -1178,7 +1178,7 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ */ if(do_independent) { for(channel = 0; channel < encoder->protected_->channels; channel++) { - if(!stream_encoder_process_subframe_(encoder, min_partition_order, max_partition_order, precompute_partition_sums, false, &frame_header, encoder->private_->subframe_bps[channel], encoder->private_->integer_signal[channel], encoder->private_->real_signal[channel], encoder->private_->subframe_workspace_ptr[channel], encoder->private_->residual_workspace[channel], encoder->private_->best_subframe+channel, encoder->private_->best_subframe_bits+channel)) + if(!process_subframe_(encoder, min_partition_order, max_partition_order, precompute_partition_sums, false, &frame_header, encoder->private_->subframe_bps[channel], encoder->private_->integer_signal[channel], encoder->private_->real_signal[channel], encoder->private_->subframe_workspace_ptr[channel], encoder->private_->residual_workspace[channel], encoder->private_->best_subframe+channel, encoder->private_->best_subframe_bits+channel)) return false; } } @@ -1190,7 +1190,7 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ FLAC__ASSERT(encoder->protected_->channels == 2); for(channel = 0; channel < 2; channel++) { - if(!stream_encoder_process_subframe_(encoder, min_partition_order, max_partition_order, precompute_partition_sums, false, &frame_header, encoder->private_->subframe_bps_mid_side[channel], encoder->private_->integer_signal_mid_side[channel], encoder->private_->real_signal_mid_side[channel], encoder->private_->subframe_workspace_ptr_mid_side[channel], encoder->private_->residual_workspace_mid_side[channel], encoder->private_->best_subframe_mid_side+channel, encoder->private_->best_subframe_bits_mid_side+channel)) + if(!process_subframe_(encoder, min_partition_order, max_partition_order, precompute_partition_sums, false, &frame_header, encoder->private_->subframe_bps_mid_side[channel], encoder->private_->integer_signal_mid_side[channel], encoder->private_->real_signal_mid_side[channel], encoder->private_->subframe_workspace_ptr_mid_side[channel], encoder->private_->residual_workspace_mid_side[channel], encoder->private_->best_subframe_mid_side+channel, encoder->private_->best_subframe_bits_mid_side+channel)) return false; } } @@ -1279,9 +1279,9 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ } /* note that encoder_add_subframe_ sets the state for us in case of an error */ - if(!stream_encoder_add_subframe_(encoder, &frame_header, left_bps , left_subframe , encoder->private_->frame)) + if(!add_subframe_(encoder, &frame_header, left_bps , left_subframe , encoder->private_->frame)) return false; - if(!stream_encoder_add_subframe_(encoder, &frame_header, right_bps, right_subframe, encoder->private_->frame)) + if(!add_subframe_(encoder, &frame_header, right_bps, right_subframe, encoder->private_->frame)) return false; } else { @@ -1291,7 +1291,7 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ } for(channel = 0; channel < encoder->protected_->channels; channel++) { - if(!stream_encoder_add_subframe_(encoder, &frame_header, encoder->private_->subframe_bps[channel], &encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]], encoder->private_->frame)) { + if(!add_subframe_(encoder, &frame_header, encoder->private_->subframe_bps[channel], &encoder->private_->subframe_workspace[channel][encoder->private_->best_subframe[channel]], encoder->private_->frame)) { /* the above function sets the state for us in case of an error */ return false; } @@ -1309,7 +1309,7 @@ FLAC__bool stream_encoder_process_subframes_(FLAC__StreamEncoder *encoder, FLAC_ return true; } -FLAC__bool stream_encoder_process_subframe_(FLAC__StreamEncoder *encoder, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool verbatim_only, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__int32 integer_signal[], const FLAC__real real_signal[], FLAC__Subframe *subframe[2], FLAC__int32 *residual[2], unsigned *best_subframe, unsigned *best_bits) +FLAC__bool process_subframe_(FLAC__StreamEncoder *encoder, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool verbatim_only, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__int32 integer_signal[], const FLAC__real real_signal[], FLAC__Subframe *subframe[2], FLAC__int32 *residual[2], unsigned *best_subframe, unsigned *best_bits) { FLAC__real fixed_residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]; FLAC__real lpc_residual_bits_per_sample; @@ -1324,7 +1324,7 @@ FLAC__bool stream_encoder_process_subframe_(FLAC__StreamEncoder *encoder, unsign /* verbatim subframe is the baseline against which we measure other compressed subframes */ _best_subframe = 0; - _best_bits = stream_encoder_evaluate_verbatim_subframe_(integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); + _best_bits = evaluate_verbatim_subframe_(integer_signal, frame_header->blocksize, subframe_bps, subframe[_best_subframe]); if(!verbatim_only && frame_header->blocksize >= FLAC__MAX_FIXED_ORDER) { /* check for constant subframe */ @@ -1339,7 +1339,7 @@ FLAC__bool stream_encoder_process_subframe_(FLAC__StreamEncoder *encoder, unsign } } if(signal_is_constant) { - _candidate_bits = stream_encoder_evaluate_constant_subframe_(integer_signal[0], subframe_bps, subframe[!_best_subframe]); + _candidate_bits = evaluate_constant_subframe_(integer_signal[0], subframe_bps, subframe[!_best_subframe]); if(_candidate_bits < _best_bits) { _best_subframe = !_best_subframe; _best_bits = _candidate_bits; @@ -1368,7 +1368,7 @@ FLAC__bool stream_encoder_process_subframe_(FLAC__StreamEncoder *encoder, unsign #endif rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; } - _candidate_bits = stream_encoder_evaluate_fixed_subframe_(encoder, integer_signal, residual[!_best_subframe], encoder->private_->abs_residual, encoder->private_->abs_residual_partition_sums, encoder->private_->raw_bits_per_partition, frame_header->blocksize, subframe_bps, fixed_order, rice_parameter, min_partition_order, max_partition_order, precompute_partition_sums, encoder->protected_->do_escape_coding, encoder->protected_->rice_parameter_search_dist, subframe[!_best_subframe]); + _candidate_bits = evaluate_fixed_subframe_(encoder, integer_signal, residual[!_best_subframe], encoder->private_->abs_residual, encoder->private_->abs_residual_partition_sums, encoder->private_->raw_bits_per_partition, frame_header->blocksize, subframe_bps, fixed_order, rice_parameter, min_partition_order, max_partition_order, precompute_partition_sums, encoder->protected_->do_escape_coding, encoder->protected_->rice_parameter_search_dist, subframe[!_best_subframe]); if(_candidate_bits < _best_bits) { _best_subframe = !_best_subframe; _best_bits = _candidate_bits; @@ -1415,7 +1415,7 @@ FLAC__bool stream_encoder_process_subframe_(FLAC__StreamEncoder *encoder, unsign rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1; } for(qlp_coeff_precision = min_qlp_coeff_precision; qlp_coeff_precision <= max_qlp_coeff_precision; qlp_coeff_precision++) { - _candidate_bits = stream_encoder_evaluate_lpc_subframe_(encoder, integer_signal, residual[!_best_subframe], encoder->private_->abs_residual, encoder->private_->abs_residual_partition_sums, encoder->private_->raw_bits_per_partition, encoder->private_->lp_coeff[lpc_order-1], frame_header->blocksize, subframe_bps, lpc_order, qlp_coeff_precision, rice_parameter, min_partition_order, max_partition_order, precompute_partition_sums, encoder->protected_->do_escape_coding, encoder->protected_->rice_parameter_search_dist, subframe[!_best_subframe]); + _candidate_bits = evaluate_lpc_subframe_(encoder, integer_signal, residual[!_best_subframe], encoder->private_->abs_residual, encoder->private_->abs_residual_partition_sums, encoder->private_->raw_bits_per_partition, encoder->private_->lp_coeff[lpc_order-1], frame_header->blocksize, subframe_bps, lpc_order, qlp_coeff_precision, rice_parameter, min_partition_order, max_partition_order, precompute_partition_sums, encoder->protected_->do_escape_coding, encoder->protected_->rice_parameter_search_dist, subframe[!_best_subframe]); if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */ if(_candidate_bits < _best_bits) { _best_subframe = !_best_subframe; @@ -1436,7 +1436,7 @@ FLAC__bool stream_encoder_process_subframe_(FLAC__StreamEncoder *encoder, unsign return true; } -FLAC__bool stream_encoder_add_subframe_(FLAC__StreamEncoder *encoder, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__Subframe *subframe, FLAC__BitBuffer *frame) +FLAC__bool add_subframe_(FLAC__StreamEncoder *encoder, const FLAC__FrameHeader *frame_header, unsigned subframe_bps, const FLAC__Subframe *subframe, FLAC__BitBuffer *frame) { switch(subframe->type) { case FLAC__SUBFRAME_TYPE_CONSTANT: @@ -1470,7 +1470,7 @@ FLAC__bool stream_encoder_add_subframe_(FLAC__StreamEncoder *encoder, const FLAC return true; } -unsigned stream_encoder_evaluate_constant_subframe_(const FLAC__int32 signal, unsigned subframe_bps, FLAC__Subframe *subframe) +unsigned evaluate_constant_subframe_(const FLAC__int32 signal, unsigned subframe_bps, FLAC__Subframe *subframe) { subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT; subframe->data.constant.value = signal; @@ -1478,7 +1478,7 @@ unsigned stream_encoder_evaluate_constant_subframe_(const FLAC__int32 signal, un return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe_bps; } -unsigned stream_encoder_evaluate_fixed_subframe_(FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe) +unsigned evaluate_fixed_subframe_(FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe) { unsigned i, residual_bits; const unsigned residual_samples = blocksize - order; @@ -1490,7 +1490,7 @@ unsigned stream_encoder_evaluate_fixed_subframe_(FLAC__StreamEncoder *encoder, c subframe->data.fixed.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE; subframe->data.fixed.residual = residual; - residual_bits = stream_encoder_find_best_partition_order_(encoder->private_, residual, abs_residual, abs_residual_partition_sums, raw_bits_per_partition, residual_samples, order, rice_parameter, min_partition_order, max_partition_order, precompute_partition_sums, do_escape_coding, rice_parameter_search_dist, &subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.parameters, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.raw_bits); + residual_bits = find_best_partition_order_(encoder->private_, residual, abs_residual, abs_residual_partition_sums, raw_bits_per_partition, residual_samples, order, rice_parameter, min_partition_order, max_partition_order, precompute_partition_sums, do_escape_coding, rice_parameter_search_dist, &subframe->data.fixed.entropy_coding_method.data.partitioned_rice.order, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.parameters, subframe->data.fixed.entropy_coding_method.data.partitioned_rice.raw_bits); subframe->data.fixed.order = order; for(i = 0; i < order; i++) @@ -1499,7 +1499,7 @@ unsigned stream_encoder_evaluate_fixed_subframe_(FLAC__StreamEncoder *encoder, c return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + (order * subframe_bps) + residual_bits; } -unsigned stream_encoder_evaluate_lpc_subframe_(FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], const FLAC__real lp_coeff[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe) +unsigned evaluate_lpc_subframe_(FLAC__StreamEncoder *encoder, const FLAC__int32 signal[], FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], const FLAC__real lp_coeff[], unsigned blocksize, unsigned subframe_bps, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, FLAC__Subframe *subframe) { FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; unsigned i, residual_bits; @@ -1520,7 +1520,7 @@ unsigned stream_encoder_evaluate_lpc_subframe_(FLAC__StreamEncoder *encoder, con subframe->data.lpc.entropy_coding_method.type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE; subframe->data.lpc.residual = residual; - residual_bits = stream_encoder_find_best_partition_order_(encoder->private_, residual, abs_residual, abs_residual_partition_sums, raw_bits_per_partition, residual_samples, order, rice_parameter, min_partition_order, max_partition_order, precompute_partition_sums, do_escape_coding, rice_parameter_search_dist, &subframe->data.lpc.entropy_coding_method.data.partitioned_rice.order, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.parameters, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.raw_bits); + residual_bits = find_best_partition_order_(encoder->private_, residual, abs_residual, abs_residual_partition_sums, raw_bits_per_partition, residual_samples, order, rice_parameter, min_partition_order, max_partition_order, precompute_partition_sums, do_escape_coding, rice_parameter_search_dist, &subframe->data.lpc.entropy_coding_method.data.partitioned_rice.order, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.parameters, subframe->data.lpc.entropy_coding_method.data.partitioned_rice.raw_bits); subframe->data.lpc.order = order; subframe->data.lpc.qlp_coeff_precision = qlp_coeff_precision; @@ -1532,7 +1532,7 @@ unsigned stream_encoder_evaluate_lpc_subframe_(FLAC__StreamEncoder *encoder, con return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + subframe_bps)) + residual_bits; } -unsigned stream_encoder_evaluate_verbatim_subframe_(const FLAC__int32 signal[], unsigned blocksize, unsigned subframe_bps, FLAC__Subframe *subframe) +unsigned evaluate_verbatim_subframe_(const FLAC__int32 signal[], unsigned blocksize, unsigned subframe_bps, FLAC__Subframe *subframe) { subframe->type = FLAC__SUBFRAME_TYPE_VERBATIM; @@ -1541,7 +1541,7 @@ unsigned stream_encoder_evaluate_verbatim_subframe_(const FLAC__int32 signal[], return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + (blocksize * subframe_bps); } -unsigned stream_encoder_find_best_partition_order_(FLAC__StreamEncoderPrivate *private_, const FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, unsigned *best_partition_order, unsigned best_parameters[], unsigned best_raw_bits[]) +unsigned find_best_partition_order_(FLAC__StreamEncoderPrivate *private_, const FLAC__int32 residual[], FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned min_partition_order, unsigned max_partition_order, FLAC__bool precompute_partition_sums, FLAC__bool do_escape_coding, unsigned rice_parameter_search_dist, unsigned *best_partition_order, unsigned best_parameters[], unsigned best_raw_bits[]) { FLAC__int32 r; unsigned residual_bits, best_residual_bits = 0; @@ -1564,16 +1564,16 @@ unsigned stream_encoder_find_best_partition_order_(FLAC__StreamEncoderPrivate *p int partition_order; unsigned sum; - stream_encoder_precompute_partition_info_sums_(abs_residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order); + precompute_partition_info_sums_(abs_residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order); if(do_escape_coding) - stream_encoder_precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order); + precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order); for(partition_order = (int)max_partition_order, sum = 0; partition_order >= (int)min_partition_order; partition_order--) { #ifdef DONT_ESTIMATE_RICE_BITS - if(!stream_encoder_set_partitioned_rice_with_precompute_(residual, abs_residual_partition_sums+sum, raw_bits_per_partition+sum, residual_samples, predictor_order, rice_parameter, rice_parameter_search_dist, (unsigned)partition_order, do_escape_coding, private_->parameters[!best_parameters_index], private_->raw_bits[!best_parameters_index], &residual_bits)) + if(!set_partitioned_rice_with_precompute_(residual, abs_residual_partition_sums+sum, raw_bits_per_partition+sum, residual_samples, predictor_order, rice_parameter, rice_parameter_search_dist, (unsigned)partition_order, do_escape_coding, private_->parameters[!best_parameters_index], private_->raw_bits[!best_parameters_index], &residual_bits)) #else - if(!stream_encoder_set_partitioned_rice_with_precompute_(abs_residual, abs_residual_partition_sums+sum, raw_bits_per_partition+sum, residual_samples, predictor_order, rice_parameter, rice_parameter_search_dist, (unsigned)partition_order, do_escape_coding, private_->parameters[!best_parameters_index], private_->raw_bits[!best_parameters_index], &residual_bits)) + if(!set_partitioned_rice_with_precompute_(abs_residual, abs_residual_partition_sums+sum, raw_bits_per_partition+sum, residual_samples, predictor_order, rice_parameter, rice_parameter_search_dist, (unsigned)partition_order, do_escape_coding, private_->parameters[!best_parameters_index], private_->raw_bits[!best_parameters_index], &residual_bits)) #endif { FLAC__ASSERT(best_residual_bits != 0); @@ -1591,9 +1591,9 @@ unsigned stream_encoder_find_best_partition_order_(FLAC__StreamEncoderPrivate *p unsigned partition_order; for(partition_order = min_partition_order; partition_order <= max_partition_order; partition_order++) { #ifdef DONT_ESTIMATE_RICE_BITS - if(!stream_encoder_set_partitioned_rice_(abs_residual, residual, residual_samples, predictor_order, rice_parameter, rice_parameter_search_dist, partition_order, private_->parameters[!best_parameters_index], &residual_bits)) + if(!set_partitioned_rice_(abs_residual, residual, residual_samples, predictor_order, rice_parameter, rice_parameter_search_dist, partition_order, private_->parameters[!best_parameters_index], &residual_bits)) #else - if(!stream_encoder_set_partitioned_rice_(abs_residual, residual_samples, predictor_order, rice_parameter, rice_parameter_search_dist, partition_order, private_->parameters[!best_parameters_index], &residual_bits)) + if(!set_partitioned_rice_(abs_residual, residual_samples, predictor_order, rice_parameter, rice_parameter_search_dist, partition_order, private_->parameters[!best_parameters_index], &residual_bits)) #endif { FLAC__ASSERT(best_residual_bits != 0); @@ -1613,7 +1613,7 @@ unsigned stream_encoder_find_best_partition_order_(FLAC__StreamEncoderPrivate *p return best_residual_bits; } -void stream_encoder_precompute_partition_info_sums_(const FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order) +void precompute_partition_info_sums_(const FLAC__uint32 abs_residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order) { int partition_order; unsigned from_partition, to_partition = 0; @@ -1660,7 +1660,7 @@ void stream_encoder_precompute_partition_info_sums_(const FLAC__uint32 abs_resid } } -void stream_encoder_precompute_partition_info_escapes_(const FLAC__int32 residual[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order) +void precompute_partition_info_escapes_(const FLAC__int32 residual[], unsigned raw_bits_per_partition[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order) { int partition_order; unsigned from_partition, to_partition = 0; @@ -1720,9 +1720,9 @@ void stream_encoder_precompute_partition_info_escapes_(const FLAC__int32 residua #endif #ifdef DONT_ESTIMATE_RICE_BITS -FLAC__bool stream_encoder_set_partitioned_rice_(const FLAC__uint32 abs_residual[], const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, unsigned parameters[], unsigned *bits) +FLAC__bool set_partitioned_rice_(const FLAC__uint32 abs_residual[], const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, unsigned parameters[], unsigned *bits) #else -FLAC__bool stream_encoder_set_partitioned_rice_(const FLAC__uint32 abs_residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, unsigned parameters[], unsigned *bits) +FLAC__bool set_partitioned_rice_(const FLAC__uint32 abs_residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, unsigned parameters[], unsigned *bits) #endif { unsigned rice_parameter, partition_bits; @@ -1892,9 +1892,9 @@ FLAC__bool stream_encoder_set_partitioned_rice_(const FLAC__uint32 abs_residual[ } #ifdef DONT_ESTIMATE_RICE_BITS -FLAC__bool stream_encoder_set_partitioned_rice_with_precompute_(const FLAC__int32 residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, unsigned parameters[], unsigned raw_bits[], unsigned *bits) +FLAC__bool set_partitioned_rice_with_precompute_(const FLAC__int32 residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, unsigned parameters[], unsigned raw_bits[], unsigned *bits) #else -FLAC__bool stream_encoder_set_partitioned_rice_with_precompute_(const FLAC__uint32 abs_residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, unsigned parameters[], unsigned raw_bits[], unsigned *bits) +FLAC__bool set_partitioned_rice_with_precompute_(const FLAC__uint32 abs_residual[], const FLAC__uint64 abs_residual_partition_sums[], const unsigned raw_bits_per_partition[], const unsigned residual_samples, const unsigned predictor_order, const unsigned suggested_rice_parameter, const unsigned rice_parameter_search_dist, const unsigned partition_order, const FLAC__bool search_for_escapes, unsigned parameters[], unsigned raw_bits[], unsigned *bits) #endif { unsigned rice_parameter, partition_bits; @@ -2076,7 +2076,7 @@ FLAC__bool stream_encoder_set_partitioned_rice_with_precompute_(const FLAC__uint return true; } -unsigned stream_encoder_get_wasted_bits_(FLAC__int32 signal[], unsigned samples) +unsigned get_wasted_bits_(FLAC__int32 signal[], unsigned samples) { unsigned i, shift; FLAC__int32 x = 0; diff --git a/src/libFLAC/stream_encoder_framing.c b/src/libFLAC/stream_encoder_framing.c index 61127ba3..0abdde3a 100644 --- a/src/libFLAC/stream_encoder_framing.c +++ b/src/libFLAC/stream_encoder_framing.c @@ -27,8 +27,8 @@ #endif #define max(x,y) ((x)>(y)?(x):(y)) -static FLAC__bool subframe_add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__EntropyCodingMethod *method); -static FLAC__bool subframe_add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order); +static FLAC__bool add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__EntropyCodingMethod *method); +static FLAC__bool add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order); FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitBuffer *bb) { @@ -279,11 +279,11 @@ FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsign if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->warmup[i], subframe_bps)) return false; - if(!subframe_add_entropy_coding_method_(bb, &subframe->entropy_coding_method)) + if(!add_entropy_coding_method_(bb, &subframe->entropy_coding_method)) return false; switch(subframe->entropy_coding_method.type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - if(!subframe_add_residual_partitioned_rice_(bb, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.parameters, subframe->entropy_coding_method.data.partitioned_rice.raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) + if(!add_residual_partitioned_rice_(bb, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.parameters, subframe->entropy_coding_method.data.partitioned_rice.raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) return false; break; default: @@ -315,11 +315,11 @@ FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned r if(!FLAC__bitbuffer_write_raw_int32(bb, subframe->qlp_coeff[i], subframe->qlp_coeff_precision)) return false; - if(!subframe_add_entropy_coding_method_(bb, &subframe->entropy_coding_method)) + if(!add_entropy_coding_method_(bb, &subframe->entropy_coding_method)) return false; switch(subframe->entropy_coding_method.type) { case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: - if(!subframe_add_residual_partitioned_rice_(bb, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.parameters, subframe->entropy_coding_method.data.partitioned_rice.raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) + if(!add_residual_partitioned_rice_(bb, subframe->residual, residual_samples, subframe->order, subframe->entropy_coding_method.data.partitioned_rice.parameters, subframe->entropy_coding_method.data.partitioned_rice.raw_bits, subframe->entropy_coding_method.data.partitioned_rice.order)) return false; break; default: @@ -347,7 +347,7 @@ FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, return true; } -FLAC__bool subframe_add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__EntropyCodingMethod *method) +FLAC__bool add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__EntropyCodingMethod *method) { if(!FLAC__bitbuffer_write_raw_uint32(bb, method->type, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) return false; @@ -362,7 +362,7 @@ FLAC__bool subframe_add_entropy_coding_method_(FLAC__BitBuffer *bb, const FLAC__ return true; } -FLAC__bool subframe_add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order) +FLAC__bool add_residual_partitioned_rice_(FLAC__BitBuffer *bb, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order) { if(partition_order == 0) { unsigned i;