mirror of
https://github.com/claunia/flac.git
synced 2025-12-16 18:54:26 +00:00
add support for specifying which apodization functions to use to window data before lpc analysis
This commit is contained in:
@@ -127,6 +127,7 @@
|
|||||||
<li>
|
<li>
|
||||||
libFLAC:
|
libFLAC:
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><b>Added</b> FLAC__*_encoder_set_apodization()</li>
|
||||||
<li><b>Added</b> FLAC__metadata_object_cuesheet_calculate_cddb_id()</li>
|
<li><b>Added</b> FLAC__metadata_object_cuesheet_calculate_cddb_id()</li>
|
||||||
<li><b>Added</b> FLAC__metadata_get_cuesheet()</li>
|
<li><b>Added</b> FLAC__metadata_get_cuesheet()</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -134,6 +135,7 @@
|
|||||||
<li>
|
<li>
|
||||||
libFLAC++:
|
libFLAC++:
|
||||||
<ul>
|
<ul>
|
||||||
|
<li><b>Added</b> FLAC::*::Encoder::set_apodization()</li>
|
||||||
<li><b>Added</b> FLAC::Metadata::CueSheet::calculate_cddb_id()</li>
|
<li><b>Added</b> FLAC::Metadata::CueSheet::calculate_cddb_id()</li>
|
||||||
<li><b>Added</b> FLAC::Metadata::get_cuesheet()</li>
|
<li><b>Added</b> FLAC::Metadata::get_cuesheet()</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -314,6 +314,21 @@ FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encode
|
|||||||
*/
|
*/
|
||||||
FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value);
|
FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value);
|
||||||
|
|
||||||
|
/** This is inherited from FLAC__SeekableStreamEncoder; see
|
||||||
|
* FLAC__seekable_stream_encoder_set_apodization().
|
||||||
|
*
|
||||||
|
* \default \c 0
|
||||||
|
* \param encoder An encoder instance to set.
|
||||||
|
* \param specification See above.
|
||||||
|
* \assert
|
||||||
|
* \code encoder != NULL \endcode
|
||||||
|
* \code specification != NULL \endcode
|
||||||
|
* \retval FLAC__bool
|
||||||
|
* \c false if the encoder is already initialized, else \c true.
|
||||||
|
*/
|
||||||
|
/* @@@@add to unit tests*/
|
||||||
|
FLAC_API FLAC__bool FLAC__file_encoder_set_apodization(FLAC__FileEncoder *encoder, const char *specification);
|
||||||
|
|
||||||
/** This is inherited from FLAC__SeekableStreamEncoder; see
|
/** This is inherited from FLAC__SeekableStreamEncoder; see
|
||||||
* FLAC__seekable_stream_encoder_set_max_lpc_order().
|
* FLAC__seekable_stream_encoder_set_max_lpc_order().
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -315,6 +315,10 @@ typedef struct {
|
|||||||
|
|
||||||
const FLAC__int32 *residual;
|
const FLAC__int32 *residual;
|
||||||
/**< The residual signal, length == (blocksize minus order) samples. */
|
/**< The residual signal, length == (blocksize minus order) samples. */
|
||||||
|
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
char window_type[64]; //@@@@@@
|
||||||
|
#endif
|
||||||
} FLAC__Subframe_LPC;
|
} FLAC__Subframe_LPC;
|
||||||
|
|
||||||
extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */
|
extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */
|
||||||
|
|||||||
@@ -416,6 +416,21 @@ FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_sample_rate(FLAC__Seekable
|
|||||||
*/
|
*/
|
||||||
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value);
|
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableStreamEncoder *encoder, unsigned value);
|
||||||
|
|
||||||
|
/** This is inherited from FLAC__StreamEncoder; see
|
||||||
|
* FLAC__stream_encoder_set_apodization().
|
||||||
|
*
|
||||||
|
* \default \c 0
|
||||||
|
* \param encoder An encoder instance to set.
|
||||||
|
* \param specification See above.
|
||||||
|
* \assert
|
||||||
|
* \code encoder != NULL \endcode
|
||||||
|
* \code specification != NULL \endcode
|
||||||
|
* \retval FLAC__bool
|
||||||
|
* \c false if the encoder is already initialized, else \c true.
|
||||||
|
*/
|
||||||
|
/* @@@@add to unit tests*/
|
||||||
|
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_apodization(FLAC__SeekableStreamEncoder *encoder, const char *specification);
|
||||||
|
|
||||||
/** This is inherited from FLAC__StreamEncoder; see
|
/** This is inherited from FLAC__StreamEncoder; see
|
||||||
* FLAC__stream_encoder_set_max_lpc_order().
|
* FLAC__stream_encoder_set_max_lpc_order().
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -498,6 +498,52 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *en
|
|||||||
*/
|
*/
|
||||||
FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value);
|
FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value);
|
||||||
|
|
||||||
|
/** Sets the apodization function(s) the encoder will use when windowing
|
||||||
|
* audio data for LPC analysis.
|
||||||
|
*
|
||||||
|
* The \a specification is a plain ASCII string which specifies exactly
|
||||||
|
* which functions to use. There may be more than one (up to 32),
|
||||||
|
* separated by \c ';' characters. Some functions take one or more
|
||||||
|
* comma-separated arguments in parentheses.
|
||||||
|
*
|
||||||
|
* The available functions are \c bartlett, \c bartlett_hann,
|
||||||
|
* \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop,
|
||||||
|
* \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall,
|
||||||
|
* \c rectangle, \c triangle, \c tukey(P), \c welch.
|
||||||
|
*
|
||||||
|
* For \c gauss(STDDEV), STDDEV specifies the standard deviation
|
||||||
|
* (0<STDDEV<=0.5).
|
||||||
|
*
|
||||||
|
* For \c tukey(P), P specifies the fraction of the window that is
|
||||||
|
* tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1
|
||||||
|
* corresponds to \c hann.
|
||||||
|
*
|
||||||
|
* Example specifications are \c "blackman" or
|
||||||
|
* \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)"
|
||||||
|
*
|
||||||
|
* Any function that is specified erroneously is silently dropped. Up
|
||||||
|
* to 32 functions are kept, the rest are dropped. If the specification
|
||||||
|
* is empty the encoder defaults to \c "hann".
|
||||||
|
*
|
||||||
|
* When more than one function is specified, then for every subframe the
|
||||||
|
* encoder will try each of them separately and choose the window that
|
||||||
|
* results in the smallest compressed subframe.
|
||||||
|
*
|
||||||
|
* Note that each function specified causes the encoder to occupy a
|
||||||
|
* floating point array in which to store the window.
|
||||||
|
*
|
||||||
|
* \default \c "hann"
|
||||||
|
* \param encoder An encoder instance to set.
|
||||||
|
* \param specification See above.
|
||||||
|
* \assert
|
||||||
|
* \code encoder != NULL \endcode
|
||||||
|
* \code specification != NULL \endcode
|
||||||
|
* \retval FLAC__bool
|
||||||
|
* \c false if the encoder is already initialized, else \c true.
|
||||||
|
*/
|
||||||
|
/* @@@@add to unit tests*/
|
||||||
|
FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification);
|
||||||
|
|
||||||
/** Set the maximum LPC order, or \c 0 to use only the fixed predictors.
|
/** Set the maximum LPC order, or \c 0 to use only the fixed predictors.
|
||||||
*
|
*
|
||||||
* \default \c 0
|
* \default \c 0
|
||||||
|
|||||||
@@ -298,6 +298,20 @@ OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_sample_rate(OggFLAC__FileEncode
|
|||||||
*/
|
*/
|
||||||
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_blocksize(OggFLAC__FileEncoder *encoder, unsigned value);
|
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_blocksize(OggFLAC__FileEncoder *encoder, unsigned value);
|
||||||
|
|
||||||
|
/** This is inherited from OggFLAC__SeekableStreamEncoder; see
|
||||||
|
* OggFLAC__seekable_stream_encoder_set_apodization().
|
||||||
|
*
|
||||||
|
* \default \c 0
|
||||||
|
* \param encoder An encoder instance to set.
|
||||||
|
* \param specification See above.
|
||||||
|
* \assert
|
||||||
|
* \code encoder != NULL \endcode
|
||||||
|
* \code specification != NULL \endcode
|
||||||
|
* \retval FLAC__bool
|
||||||
|
* \c false if the encoder is already initialized, else \c true.
|
||||||
|
*/
|
||||||
|
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_apodization(OggFLAC__FileEncoder *encoder, const char *specification);
|
||||||
|
|
||||||
/** This is inherited from OggFLAC__SeekableStreamEncoder; see
|
/** This is inherited from OggFLAC__SeekableStreamEncoder; see
|
||||||
* OggFLAC__seekable_stream_encoder_set_max_lpc_order().
|
* OggFLAC__seekable_stream_encoder_set_max_lpc_order().
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -376,6 +376,19 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_sample_rate(OggFLAC_
|
|||||||
*/
|
*/
|
||||||
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_blocksize(OggFLAC__SeekableStreamEncoder *encoder, unsigned value);
|
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_blocksize(OggFLAC__SeekableStreamEncoder *encoder, unsigned value);
|
||||||
|
|
||||||
|
/** This is inherited from FLAC__StreamEncoder; see FLAC__stream_encoder_set_apodization()
|
||||||
|
*
|
||||||
|
* \default \c 0
|
||||||
|
* \param encoder An encoder instance to set.
|
||||||
|
* \param specification See above.
|
||||||
|
* \assert
|
||||||
|
* \code encoder != NULL \endcode
|
||||||
|
* \code specification != NULL \endcode
|
||||||
|
* \retval FLAC__bool
|
||||||
|
* \c false if the encoder is already initialized, else \c true.
|
||||||
|
*/
|
||||||
|
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_apodization(OggFLAC__SeekableStreamEncoder *encoder, const char *specification);
|
||||||
|
|
||||||
/** This is inherited from FLAC__StreamEncoder; see FLAC__stream_encoder_set_max_lpc_order()
|
/** This is inherited from FLAC__StreamEncoder; see FLAC__stream_encoder_set_max_lpc_order()
|
||||||
*
|
*
|
||||||
* \default \c 0
|
* \default \c 0
|
||||||
|
|||||||
@@ -312,6 +312,19 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_sample_rate(OggFLAC__StreamEn
|
|||||||
*/
|
*/
|
||||||
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_blocksize(OggFLAC__StreamEncoder *encoder, unsigned value);
|
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_blocksize(OggFLAC__StreamEncoder *encoder, unsigned value);
|
||||||
|
|
||||||
|
/** This is inherited from FLAC__StreamEncoder; see FLAC__stream_encoder_set_apodization()
|
||||||
|
*
|
||||||
|
* \default \c 0
|
||||||
|
* \param encoder An encoder instance to set.
|
||||||
|
* \param specification See above.
|
||||||
|
* \assert
|
||||||
|
* \code encoder != NULL \endcode
|
||||||
|
* \code specification != NULL \endcode
|
||||||
|
* \retval FLAC__bool
|
||||||
|
* \c false if the encoder is already initialized, else \c true.
|
||||||
|
*/
|
||||||
|
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_apodization(OggFLAC__StreamEncoder *encoder, const char *specification);
|
||||||
|
|
||||||
/** This is inherited from FLAC__StreamEncoder; see FLAC__stream_encoder_set_max_lpc_order()
|
/** This is inherited from FLAC__StreamEncoder; see FLAC__stream_encoder_set_max_lpc_order()
|
||||||
*
|
*
|
||||||
* \default \c 0
|
* \default \c 0
|
||||||
|
|||||||
@@ -1427,6 +1427,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
|
|||||||
OggFLAC__stream_encoder_set_bits_per_sample(e->encoder.ogg.stream, bps);
|
OggFLAC__stream_encoder_set_bits_per_sample(e->encoder.ogg.stream, bps);
|
||||||
OggFLAC__stream_encoder_set_sample_rate(e->encoder.ogg.stream, sample_rate);
|
OggFLAC__stream_encoder_set_sample_rate(e->encoder.ogg.stream, sample_rate);
|
||||||
OggFLAC__stream_encoder_set_blocksize(e->encoder.ogg.stream, options.blocksize);
|
OggFLAC__stream_encoder_set_blocksize(e->encoder.ogg.stream, options.blocksize);
|
||||||
|
OggFLAC__stream_encoder_set_apodization(e->encoder.ogg.stream, options.apodizations);
|
||||||
OggFLAC__stream_encoder_set_max_lpc_order(e->encoder.ogg.stream, options.max_lpc_order);
|
OggFLAC__stream_encoder_set_max_lpc_order(e->encoder.ogg.stream, options.max_lpc_order);
|
||||||
OggFLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.ogg.stream, options.qlp_coeff_precision);
|
OggFLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.ogg.stream, options.qlp_coeff_precision);
|
||||||
OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.stream, options.do_qlp_coeff_prec_search);
|
OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.stream, options.do_qlp_coeff_prec_search);
|
||||||
@@ -1463,6 +1464,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
|
|||||||
OggFLAC__file_encoder_set_bits_per_sample(e->encoder.ogg.file, bps);
|
OggFLAC__file_encoder_set_bits_per_sample(e->encoder.ogg.file, bps);
|
||||||
OggFLAC__file_encoder_set_sample_rate(e->encoder.ogg.file, sample_rate);
|
OggFLAC__file_encoder_set_sample_rate(e->encoder.ogg.file, sample_rate);
|
||||||
OggFLAC__file_encoder_set_blocksize(e->encoder.ogg.file, options.blocksize);
|
OggFLAC__file_encoder_set_blocksize(e->encoder.ogg.file, options.blocksize);
|
||||||
|
OggFLAC__file_encoder_set_apodization(e->encoder.ogg.file, options.apodizations);
|
||||||
OggFLAC__file_encoder_set_max_lpc_order(e->encoder.ogg.file, options.max_lpc_order);
|
OggFLAC__file_encoder_set_max_lpc_order(e->encoder.ogg.file, options.max_lpc_order);
|
||||||
OggFLAC__file_encoder_set_qlp_coeff_precision(e->encoder.ogg.file, options.qlp_coeff_precision);
|
OggFLAC__file_encoder_set_qlp_coeff_precision(e->encoder.ogg.file, options.qlp_coeff_precision);
|
||||||
OggFLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.file, options.do_qlp_coeff_prec_search);
|
OggFLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.ogg.file, options.do_qlp_coeff_prec_search);
|
||||||
@@ -1499,6 +1501,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
|
|||||||
FLAC__stream_encoder_set_bits_per_sample(e->encoder.flac.stream, bps);
|
FLAC__stream_encoder_set_bits_per_sample(e->encoder.flac.stream, bps);
|
||||||
FLAC__stream_encoder_set_sample_rate(e->encoder.flac.stream, sample_rate);
|
FLAC__stream_encoder_set_sample_rate(e->encoder.flac.stream, sample_rate);
|
||||||
FLAC__stream_encoder_set_blocksize(e->encoder.flac.stream, options.blocksize);
|
FLAC__stream_encoder_set_blocksize(e->encoder.flac.stream, options.blocksize);
|
||||||
|
FLAC__stream_encoder_set_apodization(e->encoder.flac.stream, options.apodizations);
|
||||||
FLAC__stream_encoder_set_max_lpc_order(e->encoder.flac.stream, options.max_lpc_order);
|
FLAC__stream_encoder_set_max_lpc_order(e->encoder.flac.stream, options.max_lpc_order);
|
||||||
FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.flac.stream, options.qlp_coeff_precision);
|
FLAC__stream_encoder_set_qlp_coeff_precision(e->encoder.flac.stream, options.qlp_coeff_precision);
|
||||||
FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.stream, options.do_qlp_coeff_prec_search);
|
FLAC__stream_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.stream, options.do_qlp_coeff_prec_search);
|
||||||
@@ -1534,6 +1537,7 @@ FLAC__bool EncoderSession_init_encoder(EncoderSession *e, encode_options_t optio
|
|||||||
FLAC__file_encoder_set_bits_per_sample(e->encoder.flac.file, bps);
|
FLAC__file_encoder_set_bits_per_sample(e->encoder.flac.file, bps);
|
||||||
FLAC__file_encoder_set_sample_rate(e->encoder.flac.file, sample_rate);
|
FLAC__file_encoder_set_sample_rate(e->encoder.flac.file, sample_rate);
|
||||||
FLAC__file_encoder_set_blocksize(e->encoder.flac.file, options.blocksize);
|
FLAC__file_encoder_set_blocksize(e->encoder.flac.file, options.blocksize);
|
||||||
|
FLAC__file_encoder_set_apodization(e->encoder.flac.file, options.apodizations);
|
||||||
FLAC__file_encoder_set_max_lpc_order(e->encoder.flac.file, options.max_lpc_order);
|
FLAC__file_encoder_set_max_lpc_order(e->encoder.flac.file, options.max_lpc_order);
|
||||||
FLAC__file_encoder_set_qlp_coeff_precision(e->encoder.flac.file, options.qlp_coeff_precision);
|
FLAC__file_encoder_set_qlp_coeff_precision(e->encoder.flac.file, options.qlp_coeff_precision);
|
||||||
FLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.file, options.do_qlp_coeff_prec_search);
|
FLAC__file_encoder_set_do_qlp_coeff_prec_search(e->encoder.flac.file, options.do_qlp_coeff_prec_search);
|
||||||
@@ -2141,7 +2145,7 @@ FLAC__bool fskip_ahead(FILE *f, FLAC__uint64 offset)
|
|||||||
long need = (long)min(offset, LONG_MAX);
|
long need = (long)min(offset, LONG_MAX);
|
||||||
if(fseek(f, need, SEEK_CUR) < 0) {
|
if(fseek(f, need, SEEK_CUR) < 0) {
|
||||||
need = (long)min(offset, sizeof(dump));
|
need = (long)min(offset, sizeof(dump));
|
||||||
if(fread(dump, 1, need, f) < need)
|
if((long)fread(dump, 1, need, f) < need)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
offset -= need;
|
offset -= need;
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ typedef struct {
|
|||||||
unsigned min_residual_partition_order;
|
unsigned min_residual_partition_order;
|
||||||
unsigned max_residual_partition_order;
|
unsigned max_residual_partition_order;
|
||||||
unsigned rice_parameter_search_dist;
|
unsigned rice_parameter_search_dist;
|
||||||
|
char *apodizations;
|
||||||
unsigned max_lpc_order;
|
unsigned max_lpc_order;
|
||||||
unsigned blocksize;
|
unsigned blocksize;
|
||||||
unsigned qlp_coeff_precision;
|
unsigned qlp_coeff_precision;
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ static struct share__option long_options_[] = {
|
|||||||
{ "blocksize" , share__required_argument, 0, 'b' },
|
{ "blocksize" , share__required_argument, 0, 'b' },
|
||||||
{ "exhaustive-model-search" , share__no_argument, 0, 'e' },
|
{ "exhaustive-model-search" , share__no_argument, 0, 'e' },
|
||||||
{ "max-lpc-order" , share__required_argument, 0, 'l' },
|
{ "max-lpc-order" , share__required_argument, 0, 'l' },
|
||||||
|
{ "apodization" , share__required_argument, 0, 'A' },
|
||||||
{ "mid-side" , share__no_argument, 0, 'm' },
|
{ "mid-side" , share__no_argument, 0, 'm' },
|
||||||
{ "adaptive-mid-side" , share__no_argument, 0, 'M' },
|
{ "adaptive-mid-side" , share__no_argument, 0, 'M' },
|
||||||
{ "qlp-coeff-precision-search", share__no_argument, 0, 'p' },
|
{ "qlp-coeff-precision-search", share__no_argument, 0, 'p' },
|
||||||
@@ -232,6 +233,7 @@ static struct {
|
|||||||
const char *output_prefix;
|
const char *output_prefix;
|
||||||
analysis_options aopts;
|
analysis_options aopts;
|
||||||
int padding;
|
int padding;
|
||||||
|
char apodizations[1000]; /* bad MAGIC NUMBER but buffer overflow is checked */
|
||||||
unsigned max_lpc_order;
|
unsigned max_lpc_order;
|
||||||
unsigned qlp_coeff_precision;
|
unsigned qlp_coeff_precision;
|
||||||
const char *skip_specification;
|
const char *skip_specification;
|
||||||
@@ -247,7 +249,7 @@ static struct {
|
|||||||
int min_residual_partition_order;
|
int min_residual_partition_order;
|
||||||
int max_residual_partition_order;
|
int max_residual_partition_order;
|
||||||
int rice_parameter_search_dist;
|
int rice_parameter_search_dist;
|
||||||
char requested_seek_points[50000]; /* bad MAGIC NUMBER but buffer overflow is checked */
|
char requested_seek_points[5000]; /* bad MAGIC NUMBER but buffer overflow is checked */
|
||||||
int num_requested_seek_points; /* -1 => no -S options were given, 0 => -S- was given */
|
int num_requested_seek_points; /* -1 => no -S options were given, 0 => -S- was given */
|
||||||
const char *cuesheet_filename;
|
const char *cuesheet_filename;
|
||||||
FLAC__bool cued_seekpoints;
|
FLAC__bool cued_seekpoints;
|
||||||
@@ -577,6 +579,7 @@ FLAC__bool init_options()
|
|||||||
option_values.aopts.do_residual_text = false;
|
option_values.aopts.do_residual_text = false;
|
||||||
option_values.aopts.do_residual_gnuplot = false;
|
option_values.aopts.do_residual_gnuplot = false;
|
||||||
option_values.padding = 4096;
|
option_values.padding = 4096;
|
||||||
|
option_values.apodizations[0] = '\0';
|
||||||
option_values.max_lpc_order = 8;
|
option_values.max_lpc_order = 8;
|
||||||
option_values.qlp_coeff_precision = 0;
|
option_values.qlp_coeff_precision = 0;
|
||||||
option_values.skip_specification = 0;
|
option_values.skip_specification = 0;
|
||||||
@@ -615,7 +618,7 @@ int parse_options(int argc, char *argv[])
|
|||||||
int short_option;
|
int short_option;
|
||||||
int option_index = 1;
|
int option_index = 1;
|
||||||
FLAC__bool had_error = false;
|
FLAC__bool had_error = false;
|
||||||
const char *short_opts = "0123456789ab:cdefFhHl:mMo:pP:q:r:sS:tT:vV";
|
const char *short_opts = "0123456789aA:b:cdefFhHl:mMo:pP:q:r:sS:tT:vV";
|
||||||
|
|
||||||
while ((short_option = share__getopt_long(argc, argv, short_opts, long_options_, &option_index)) != -1) {
|
while ((short_option = share__getopt_long(argc, argv, short_opts, long_options_, &option_index)) != -1) {
|
||||||
switch (short_option) {
|
switch (short_option) {
|
||||||
@@ -1030,6 +1033,16 @@ int parse_option(int short_option, const char *long_option, const char *option_a
|
|||||||
FLAC__ASSERT(0 != option_argument);
|
FLAC__ASSERT(0 != option_argument);
|
||||||
option_values.max_lpc_order = atoi(option_argument);
|
option_values.max_lpc_order = atoi(option_argument);
|
||||||
break;
|
break;
|
||||||
|
case 'A':
|
||||||
|
FLAC__ASSERT(0 != option_argument);
|
||||||
|
if(strlen(option_values.apodizations)+strlen(option_argument)+2 >= sizeof(option_values.apodizations)) {
|
||||||
|
return usage_error("ERROR: too many apodization functions requested\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strcat(option_values.apodizations, option_argument);
|
||||||
|
strcat(option_values.apodizations, ";");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
option_values.do_mid_side = true;
|
option_values.do_mid_side = true;
|
||||||
option_values.loose_mid_side = false;
|
option_values.loose_mid_side = false;
|
||||||
@@ -1210,6 +1223,7 @@ void show_help()
|
|||||||
printf(" -m, --mid-side Try mid-side coding for each frame\n");
|
printf(" -m, --mid-side Try mid-side coding for each frame\n");
|
||||||
printf(" -M, --adaptive-mid-side Adaptive mid-side coding for all frames\n");
|
printf(" -M, --adaptive-mid-side Adaptive mid-side coding for all frames\n");
|
||||||
printf(" -e, --exhaustive-model-search Do exhaustive model search (expensive!)\n");
|
printf(" -e, --exhaustive-model-search Do exhaustive model search (expensive!)\n");
|
||||||
|
printf(" -A, --apodization=\"function\" Window audio data with given the function\n");
|
||||||
printf(" -l, --max-lpc-order=# Max LPC order; 0 => only fixed predictors\n");
|
printf(" -l, --max-lpc-order=# Max LPC order; 0 => only fixed predictors\n");
|
||||||
printf(" -p, --qlp-coeff-precision-search Exhaustively search LP coeff quantization\n");
|
printf(" -p, --qlp-coeff-precision-search Exhaustively search LP coeff quantization\n");
|
||||||
printf(" -q, --qlp-coeff-precision=# Specify precision in bits\n");
|
printf(" -q, --qlp-coeff-precision=# Specify precision in bits\n");
|
||||||
@@ -1422,6 +1436,16 @@ void show_explain()
|
|||||||
printf(" -M, --adaptive-mid-side Adaptive mid-side coding for all frames\n");
|
printf(" -M, --adaptive-mid-side Adaptive mid-side coding for all frames\n");
|
||||||
printf(" (stereo only)\n");
|
printf(" (stereo only)\n");
|
||||||
printf(" -e, --exhaustive-model-search Do exhaustive model search (expensive!)\n");
|
printf(" -e, --exhaustive-model-search Do exhaustive model search (expensive!)\n");
|
||||||
|
printf(" -A, --apodization=\"function\" Window audio data with given the function.\n");
|
||||||
|
printf(" The functions are: bartlett, bartlett_hann,\n");
|
||||||
|
printf(" blackman, blackman_harris_4term_92db,\n");
|
||||||
|
printf(" connes, flattop, gauss(STDDEV), hamming,\n");
|
||||||
|
printf(" hann, kaiser_bessel, nuttall, rectangle,\n");
|
||||||
|
printf(" triangle, tukey(P), welch. More than one\n");
|
||||||
|
printf(" may be specified but encoding time is a\n");
|
||||||
|
printf(" multiple of the number of functions since\n");
|
||||||
|
printf(" they are each tried in turn. The default\n");
|
||||||
|
printf(" is \"hann\". \n");
|
||||||
printf(" -l, --max-lpc-order=# Max LPC order; 0 => only fixed predictors\n");
|
printf(" -l, --max-lpc-order=# Max LPC order; 0 => only fixed predictors\n");
|
||||||
printf(" -p, --qlp-coeff-precision-search Do exhaustive search of LP coefficient\n");
|
printf(" -p, --qlp-coeff-precision-search Do exhaustive search of LP coefficient\n");
|
||||||
printf(" quantization (expensive!); overrides -q;\n");
|
printf(" quantization (expensive!); overrides -q;\n");
|
||||||
@@ -1606,6 +1630,7 @@ int encode_file(const char *infilename, FLAC__bool is_first_file, FLAC__bool is_
|
|||||||
common_options.min_residual_partition_order = option_values.min_residual_partition_order;
|
common_options.min_residual_partition_order = option_values.min_residual_partition_order;
|
||||||
common_options.max_residual_partition_order = option_values.max_residual_partition_order;
|
common_options.max_residual_partition_order = option_values.max_residual_partition_order;
|
||||||
common_options.rice_parameter_search_dist = option_values.rice_parameter_search_dist;
|
common_options.rice_parameter_search_dist = option_values.rice_parameter_search_dist;
|
||||||
|
common_options.apodizations = option_values.apodizations;
|
||||||
common_options.max_lpc_order = option_values.max_lpc_order;
|
common_options.max_lpc_order = option_values.max_lpc_order;
|
||||||
common_options.blocksize = (unsigned)option_values.blocksize;
|
common_options.blocksize = (unsigned)option_values.blocksize;
|
||||||
common_options.qlp_coeff_precision = option_values.qlp_coeff_precision;
|
common_options.qlp_coeff_precision = option_values.qlp_coeff_precision;
|
||||||
|
|||||||
@@ -79,7 +79,8 @@ SRCS_C = \
|
|||||||
seekable_stream_encoder.c \
|
seekable_stream_encoder.c \
|
||||||
stream_decoder.c \
|
stream_decoder.c \
|
||||||
stream_encoder.c \
|
stream_encoder.c \
|
||||||
stream_encoder_framing.c
|
stream_encoder_framing.c \
|
||||||
|
window.c
|
||||||
|
|
||||||
include $(topdir)/build/lib.mk
|
include $(topdir)/build/lib.mk
|
||||||
|
|
||||||
|
|||||||
@@ -314,6 +314,17 @@ FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder,
|
|||||||
return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
|
return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLAC_API FLAC__bool FLAC__file_encoder_set_apodization(FLAC__FileEncoder *encoder, const char *specification)
|
||||||
|
{
|
||||||
|
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_apodization(encoder->private_->seekable_stream_encoder, specification);
|
||||||
|
}
|
||||||
|
|
||||||
FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value)
|
FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value)
|
||||||
{
|
{
|
||||||
FLAC__ASSERT(0 != encoder);
|
FLAC__ASSERT(0 != encoder);
|
||||||
|
|||||||
@@ -56,9 +56,10 @@ FLAC_API const char *FLAC__VERSION_STRING = VERSION;
|
|||||||
|
|
||||||
#if defined _MSC_VER || defined __MINW32__
|
#if defined _MSC_VER || defined __MINW32__
|
||||||
/* yet one more hack because of MSVC6: */
|
/* yet one more hack because of MSVC6: */
|
||||||
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.1.2 20050205";
|
/*@@@@@@WAS:FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.1.2 20050205";*/
|
||||||
|
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC CVS 20060425";
|
||||||
#else
|
#else
|
||||||
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20050205";
|
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20060425";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
|
FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
|
||||||
|
|||||||
@@ -41,6 +41,19 @@
|
|||||||
|
|
||||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FLAC__lpc_window_data()
|
||||||
|
* --------------------------------------------------------------------
|
||||||
|
* Applies the given window to the data.
|
||||||
|
* @@@@@@ asm optimize
|
||||||
|
*
|
||||||
|
* IN in[0,data_len-1]
|
||||||
|
* IN window[0,data_len-1]
|
||||||
|
* OUT out[0,lag-1]
|
||||||
|
* IN data_len
|
||||||
|
*/
|
||||||
|
void FLAC__lpc_window_data(const FLAC__real in[], const FLAC__real window[], FLAC__real out[], unsigned data_len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FLAC__lpc_compute_autocorrelation()
|
* FLAC__lpc_compute_autocorrelation()
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
|
|||||||
@@ -34,6 +34,44 @@
|
|||||||
|
|
||||||
#include "FLAC/stream_encoder.h"
|
#include "FLAC/stream_encoder.h"
|
||||||
|
|
||||||
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
|
||||||
|
#include "private/float.h"
|
||||||
|
|
||||||
|
#define FLAC__MAX_APODIZATION_FUNCTIONS 32
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FLAC__APODIZATION_BARTLETT,
|
||||||
|
FLAC__APODIZATION_BARTLETT_HANN,
|
||||||
|
FLAC__APODIZATION_BLACKMAN,
|
||||||
|
FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE,
|
||||||
|
FLAC__APODIZATION_CONNES,
|
||||||
|
FLAC__APODIZATION_FLATTOP,
|
||||||
|
FLAC__APODIZATION_GAUSS,
|
||||||
|
FLAC__APODIZATION_HAMMING,
|
||||||
|
FLAC__APODIZATION_HANN,
|
||||||
|
FLAC__APODIZATION_KAISER_BESSEL,
|
||||||
|
FLAC__APODIZATION_NUTTALL,
|
||||||
|
FLAC__APODIZATION_RECTANGLE,
|
||||||
|
FLAC__APODIZATION_TRIANGLE,
|
||||||
|
FLAC__APODIZATION_TUKEY,
|
||||||
|
FLAC__APODIZATION_WELCH
|
||||||
|
} FLAC__ApodizationFunction;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FLAC__ApodizationFunction type;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
FLAC__real stddev;
|
||||||
|
} gauss;
|
||||||
|
struct {
|
||||||
|
FLAC__real p;
|
||||||
|
} tukey;
|
||||||
|
} parameters;
|
||||||
|
} FLAC__ApodizationSpecification;
|
||||||
|
|
||||||
|
#endif // #ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
|
||||||
typedef struct FLAC__StreamEncoderProtected {
|
typedef struct FLAC__StreamEncoderProtected {
|
||||||
FLAC__StreamEncoderState state;
|
FLAC__StreamEncoderState state;
|
||||||
FLAC__bool verify;
|
FLAC__bool verify;
|
||||||
@@ -44,6 +82,10 @@ typedef struct FLAC__StreamEncoderProtected {
|
|||||||
unsigned bits_per_sample;
|
unsigned bits_per_sample;
|
||||||
unsigned sample_rate;
|
unsigned sample_rate;
|
||||||
unsigned blocksize;
|
unsigned blocksize;
|
||||||
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
unsigned num_apodizations;
|
||||||
|
FLAC__ApodizationSpecification apodizations[FLAC__MAX_APODIZATION_FUNCTIONS];
|
||||||
|
#endif
|
||||||
unsigned max_lpc_order;
|
unsigned max_lpc_order;
|
||||||
unsigned qlp_coeff_precision;
|
unsigned qlp_coeff_precision;
|
||||||
FLAC__bool do_qlp_coeff_prec_search;
|
FLAC__bool do_qlp_coeff_prec_search;
|
||||||
|
|||||||
@@ -45,6 +45,13 @@
|
|||||||
#define M_LN2 0.69314718055994530942
|
#define M_LN2 0.69314718055994530942
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void FLAC__lpc_window_data(const FLAC__real in[], const FLAC__real window[], FLAC__real out[], unsigned data_len)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
for(i = 0; i < data_len; i++)
|
||||||
|
out[i] = in[i] * window[i];
|
||||||
|
}
|
||||||
|
|
||||||
void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
|
||||||
{
|
{
|
||||||
/* a readable, but slower, version */
|
/* a readable, but slower, version */
|
||||||
|
|||||||
@@ -318,6 +318,17 @@ FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_blocksize(FLAC__SeekableSt
|
|||||||
return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
|
return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_apodization(FLAC__SeekableStreamEncoder *encoder, const char *specification)
|
||||||
|
{
|
||||||
|
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_apodization(encoder->private_->stream_encoder, specification);
|
||||||
|
}
|
||||||
|
|
||||||
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
|
FLAC_API FLAC__bool FLAC__seekable_stream_encoder_set_max_lpc_order(FLAC__SeekableStreamEncoder *encoder, unsigned value)
|
||||||
{
|
{
|
||||||
FLAC__ASSERT(0 != encoder);
|
FLAC__ASSERT(0 != encoder);
|
||||||
|
|||||||
@@ -29,6 +29,9 @@
|
|||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*@@@@@@*/
|
||||||
|
#define WINDOW_DEBUG_OUTPUT
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h> /* for malloc() */
|
#include <stdlib.h> /* for malloc() */
|
||||||
@@ -46,6 +49,7 @@
|
|||||||
#include "private/md5.h"
|
#include "private/md5.h"
|
||||||
#include "private/memory.h"
|
#include "private/memory.h"
|
||||||
#include "private/stream_encoder_framing.h"
|
#include "private/stream_encoder_framing.h"
|
||||||
|
#include "private/window.h"
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@@ -108,6 +112,9 @@ static FLAC__bool process_subframe_(
|
|||||||
FLAC__int32 *residual[2],
|
FLAC__int32 *residual[2],
|
||||||
unsigned *best_subframe,
|
unsigned *best_subframe,
|
||||||
unsigned *best_bits
|
unsigned *best_bits
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
,unsigned subframe_number
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
static FLAC__bool add_subframe_(
|
static FLAC__bool add_subframe_(
|
||||||
@@ -116,6 +123,9 @@ static FLAC__bool add_subframe_(
|
|||||||
unsigned subframe_bps,
|
unsigned subframe_bps,
|
||||||
const FLAC__Subframe *subframe,
|
const FLAC__Subframe *subframe,
|
||||||
FLAC__BitBuffer *frame
|
FLAC__BitBuffer *frame
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
,unsigned subframe_bits
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
|
|
||||||
static unsigned evaluate_constant_subframe_(
|
static unsigned evaluate_constant_subframe_(
|
||||||
@@ -165,6 +175,11 @@ static unsigned evaluate_lpc_subframe_(
|
|||||||
unsigned rice_parameter_search_dist,
|
unsigned rice_parameter_search_dist,
|
||||||
FLAC__Subframe *subframe,
|
FLAC__Subframe *subframe,
|
||||||
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
|
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
,unsigned frame_number
|
||||||
|
,unsigned subframe_number
|
||||||
|
,FLAC__ApodizationSpecification aspec
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -308,6 +323,25 @@ static void verify_error_callback_(
|
|||||||
void *client_data
|
void *client_data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
static const char * const winstr[] = {
|
||||||
|
"bartlett",
|
||||||
|
"bartlett_hann",
|
||||||
|
"blackman",
|
||||||
|
"blackman_harris_4term_92db_sidelobe",
|
||||||
|
"connes",
|
||||||
|
"flattop",
|
||||||
|
"gauss",
|
||||||
|
"hamming",
|
||||||
|
"hann",
|
||||||
|
"kaiser_bessel",
|
||||||
|
"nuttall",
|
||||||
|
"rectangular",
|
||||||
|
"triangle",
|
||||||
|
"tukey",
|
||||||
|
"welch"
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
@@ -322,6 +356,8 @@ typedef struct FLAC__StreamEncoderPrivate {
|
|||||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
FLAC__real *real_signal[FLAC__MAX_CHANNELS]; /* the floating-point version of the input signal */
|
FLAC__real *real_signal[FLAC__MAX_CHANNELS]; /* the floating-point version of the input signal */
|
||||||
FLAC__real *real_signal_mid_side[2]; /* the floating-point version of the mid-side input signal (stereo only) */
|
FLAC__real *real_signal_mid_side[2]; /* the floating-point version of the mid-side input signal (stereo only) */
|
||||||
|
FLAC__real *window[FLAC__MAX_APODIZATION_FUNCTIONS]; /* the pre-computed floating-point window for each apodization function */
|
||||||
|
FLAC__real *windowed_signal; /* the real_signal[] * current window[] */
|
||||||
#endif
|
#endif
|
||||||
unsigned subframe_bps[FLAC__MAX_CHANNELS]; /* the effective bits per sample of the input signal (stream bps - wasted bits) */
|
unsigned subframe_bps[FLAC__MAX_CHANNELS]; /* the effective bits per sample of the input signal (stream bps - wasted bits) */
|
||||||
unsigned subframe_bps_mid_side[2]; /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */
|
unsigned subframe_bps_mid_side[2]; /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */
|
||||||
@@ -378,6 +414,8 @@ typedef struct FLAC__StreamEncoderPrivate {
|
|||||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS];
|
FLAC__real *real_signal_unaligned[FLAC__MAX_CHANNELS];
|
||||||
FLAC__real *real_signal_mid_side_unaligned[2];
|
FLAC__real *real_signal_mid_side_unaligned[2];
|
||||||
|
FLAC__real *window_unaligned[FLAC__MAX_APODIZATION_FUNCTIONS];
|
||||||
|
FLAC__real *windowed_signal_unaligned;
|
||||||
#endif
|
#endif
|
||||||
FLAC__int32 *residual_workspace_unaligned[FLAC__MAX_CHANNELS][2];
|
FLAC__int32 *residual_workspace_unaligned[FLAC__MAX_CHANNELS][2];
|
||||||
FLAC__int32 *residual_workspace_mid_side_unaligned[2][2];
|
FLAC__int32 *residual_workspace_mid_side_unaligned[2][2];
|
||||||
@@ -723,6 +761,11 @@ FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_init(FLAC__StreamEncoder
|
|||||||
encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0;
|
encoder->private_->real_signal_mid_side_unaligned[i] = encoder->private_->real_signal_mid_side[i] = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
for(i = 0; i < encoder->protected_->num_apodizations; i++)
|
||||||
|
encoder->private_->window_unaligned[i] = encoder->private_->window[i] = 0;
|
||||||
|
encoder->private_->windowed_signal_unaligned = encoder->private_->windowed_signal = 0;
|
||||||
|
#endif
|
||||||
for(i = 0; i < encoder->protected_->channels; i++) {
|
for(i = 0; i < encoder->protected_->channels; i++) {
|
||||||
encoder->private_->residual_workspace_unaligned[i][0] = encoder->private_->residual_workspace[i][0] = 0;
|
encoder->private_->residual_workspace_unaligned[i][0] = encoder->private_->residual_workspace[i][0] = 0;
|
||||||
encoder->private_->residual_workspace_unaligned[i][1] = encoder->private_->residual_workspace[i][1] = 0;
|
encoder->private_->residual_workspace_unaligned[i][1] = encoder->private_->residual_workspace[i][1] = 0;
|
||||||
@@ -1063,6 +1106,77 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *enco
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *encoder, const char *specification)
|
||||||
|
{
|
||||||
|
FLAC__ASSERT(0 != encoder);
|
||||||
|
FLAC__ASSERT(0 != specification);
|
||||||
|
if(encoder->protected_->state != FLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||||
|
return false;
|
||||||
|
#ifdef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
(void)specification; /* silently ignore since we haven't integerized; will always use a rectangular window */
|
||||||
|
#else
|
||||||
|
encoder->protected_->num_apodizations = 0;
|
||||||
|
while(1) {
|
||||||
|
const char *s = strchr(specification, ';');
|
||||||
|
const size_t n = s? (size_t)(s - specification) : strlen(specification);
|
||||||
|
if (n==8 && 0 == strncmp("bartlett" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT;
|
||||||
|
else if(n==13 && 0 == strncmp("bartlett_hann", specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BARTLETT_HANN;
|
||||||
|
else if(n==8 && 0 == strncmp("blackman" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN;
|
||||||
|
else if(n==26 && 0 == strncmp("blackman_harris_4term_92db", specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE;
|
||||||
|
else if(n==6 && 0 == strncmp("connes" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_CONNES;
|
||||||
|
else if(n==7 && 0 == strncmp("flattop" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_FLATTOP;
|
||||||
|
else if(n>7 && 0 == strncmp("gauss(" , specification, 6)) {
|
||||||
|
FLAC__real stddev = (FLAC__real)strtod(specification+6, 0);
|
||||||
|
if (stddev > 0.0 && stddev <= 0.5) {
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.gauss.stddev = stddev;
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_GAUSS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(n==7 && 0 == strncmp("hamming" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HAMMING;
|
||||||
|
else if(n==4 && 0 == strncmp("hann" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_HANN;
|
||||||
|
else if(n==13 && 0 == strncmp("kaiser_bessel", specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_KAISER_BESSEL;
|
||||||
|
else if(n==7 && 0 == strncmp("nuttall" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_NUTTALL;
|
||||||
|
else if(n==9 && 0 == strncmp("rectangle" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_RECTANGLE;
|
||||||
|
else if(n==8 && 0 == strncmp("triangle" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TRIANGLE;
|
||||||
|
else if(n>7 && 0 == strncmp("tukey(" , specification, 6)) {
|
||||||
|
FLAC__real p = (FLAC__real)strtod(specification+6, 0);
|
||||||
|
if (p >= 0.0 && p <= 1.0) {
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = p;
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(n==5 && 0 == strncmp("welch" , specification, n))
|
||||||
|
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH;
|
||||||
|
if (encoder->protected_->num_apodizations == 32)
|
||||||
|
break;
|
||||||
|
if (s)
|
||||||
|
specification = s+1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(encoder->protected_->num_apodizations == 0) {
|
||||||
|
encoder->protected_->num_apodizations = 1;
|
||||||
|
encoder->protected_->apodizations[0].type = FLAC__APODIZATION_HANN;
|
||||||
|
}
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
{unsigned n;for(n=0;n<encoder->protected_->num_apodizations;n++)fprintf(stderr,"@@@@@@ parsed apodization[%zu]: %s\n",n,winstr[encoder->protected_->apodizations[n].type]);}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value)
|
FLAC_API FLAC__bool FLAC__stream_encoder_set_max_lpc_order(FLAC__StreamEncoder *encoder, unsigned value)
|
||||||
{
|
{
|
||||||
FLAC__ASSERT(0 != encoder);
|
FLAC__ASSERT(0 != encoder);
|
||||||
@@ -1648,6 +1762,10 @@ void set_defaults_(FLAC__StreamEncoder *encoder)
|
|||||||
encoder->protected_->bits_per_sample = 16;
|
encoder->protected_->bits_per_sample = 16;
|
||||||
encoder->protected_->sample_rate = 44100;
|
encoder->protected_->sample_rate = 44100;
|
||||||
encoder->protected_->blocksize = 1152;
|
encoder->protected_->blocksize = 1152;
|
||||||
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
encoder->protected_->num_apodizations = 1;
|
||||||
|
encoder->protected_->apodizations[0].type = FLAC__APODIZATION_HANN;
|
||||||
|
#endif
|
||||||
encoder->protected_->max_lpc_order = 0;
|
encoder->protected_->max_lpc_order = 0;
|
||||||
encoder->protected_->qlp_coeff_precision = 0;
|
encoder->protected_->qlp_coeff_precision = 0;
|
||||||
encoder->protected_->do_qlp_coeff_prec_search = false;
|
encoder->protected_->do_qlp_coeff_prec_search = false;
|
||||||
@@ -1697,6 +1815,18 @@ void free_(FLAC__StreamEncoder *encoder)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
for(i = 0; i < encoder->protected_->num_apodizations; i++) {
|
||||||
|
if(0 != encoder->private_->window_unaligned[i]) {
|
||||||
|
free(encoder->private_->window_unaligned[i]);
|
||||||
|
encoder->private_->window_unaligned[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(0 != encoder->private_->windowed_signal_unaligned) {
|
||||||
|
free(encoder->private_->windowed_signal_unaligned);
|
||||||
|
encoder->private_->windowed_signal_unaligned = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
for(channel = 0; channel < encoder->protected_->channels; channel++) {
|
for(channel = 0; channel < encoder->protected_->channels; channel++) {
|
||||||
for(i = 0; i < 2; i++) {
|
for(i = 0; i < 2; i++) {
|
||||||
if(0 != encoder->private_->residual_workspace_unaligned[channel][i]) {
|
if(0 != encoder->private_->residual_workspace_unaligned[channel][i]) {
|
||||||
@@ -1775,6 +1905,13 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size)
|
|||||||
memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4);
|
memset(encoder->private_->integer_signal_mid_side[i], 0, sizeof(FLAC__int32)*4);
|
||||||
encoder->private_->integer_signal_mid_side[i] += 4;
|
encoder->private_->integer_signal_mid_side[i] += 4;
|
||||||
}
|
}
|
||||||
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
if(ok && encoder->protected_->max_lpc_order > 0) {
|
||||||
|
for(i = 0; ok && i < encoder->protected_->num_apodizations; i++)
|
||||||
|
ok = ok && FLAC__memory_alloc_aligned_real_array(new_size, &encoder->private_->window_unaligned[i], &encoder->private_->window[i]);
|
||||||
|
ok = ok && FLAC__memory_alloc_aligned_real_array(new_size, &encoder->private_->windowed_signal_unaligned, &encoder->private_->windowed_signal);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
for(channel = 0; ok && channel < encoder->protected_->channels; channel++) {
|
for(channel = 0; ok && channel < encoder->protected_->channels; channel++) {
|
||||||
for(i = 0; ok && i < 2; i++) {
|
for(i = 0; ok && i < 2; i++) {
|
||||||
ok = ok && FLAC__memory_alloc_aligned_int32_array(new_size, &encoder->private_->residual_workspace_unaligned[channel][i], &encoder->private_->residual_workspace[channel][i]);
|
ok = ok && FLAC__memory_alloc_aligned_int32_array(new_size, &encoder->private_->residual_workspace_unaligned[channel][i], &encoder->private_->residual_workspace[channel][i]);
|
||||||
@@ -1796,6 +1933,65 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_size)
|
|||||||
else
|
else
|
||||||
encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
|
encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
|
||||||
|
|
||||||
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
|
if(ok && encoder->protected_->max_lpc_order > 0) {
|
||||||
|
for(i = 0; ok && i < encoder->protected_->num_apodizations; i++) {
|
||||||
|
switch(encoder->protected_->apodizations[i].type) {
|
||||||
|
case FLAC__APODIZATION_BARTLETT:
|
||||||
|
FLAC__window_bartlett(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_BARTLETT_HANN:
|
||||||
|
FLAC__window_bartlett_hann(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_BLACKMAN:
|
||||||
|
FLAC__window_blackman(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE:
|
||||||
|
FLAC__window_blackman_harris_4term_92db_sidelobe(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_CONNES:
|
||||||
|
FLAC__window_connes(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_FLATTOP:
|
||||||
|
FLAC__window_flattop(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_GAUSS:
|
||||||
|
FLAC__window_gauss(encoder->private_->window[i], new_size, encoder->protected_->apodizations[i].parameters.gauss.stddev);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_HAMMING:
|
||||||
|
FLAC__window_hamming(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_HANN:
|
||||||
|
FLAC__window_hann(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_KAISER_BESSEL:
|
||||||
|
FLAC__window_kaiser_bessel(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_NUTTALL:
|
||||||
|
FLAC__window_nuttall(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_RECTANGLE:
|
||||||
|
FLAC__window_rectangle(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_TRIANGLE:
|
||||||
|
FLAC__window_triangle(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_TUKEY:
|
||||||
|
FLAC__window_tukey(encoder->private_->window[i], new_size, encoder->protected_->apodizations[i].parameters.tukey.p);
|
||||||
|
break;
|
||||||
|
case FLAC__APODIZATION_WELCH:
|
||||||
|
FLAC__window_welch(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FLAC__ASSERT(0);
|
||||||
|
/* double protection */
|
||||||
|
FLAC__window_rectangle(encoder->private_->window[i], new_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1994,6 +2190,9 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f
|
|||||||
encoder->private_->residual_workspace[channel],
|
encoder->private_->residual_workspace[channel],
|
||||||
encoder->private_->best_subframe+channel,
|
encoder->private_->best_subframe+channel,
|
||||||
encoder->private_->best_subframe_bits+channel
|
encoder->private_->best_subframe_bits+channel
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
,channel
|
||||||
|
#endif
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return false;
|
return false;
|
||||||
@@ -2024,6 +2223,9 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f
|
|||||||
encoder->private_->residual_workspace_mid_side[channel],
|
encoder->private_->residual_workspace_mid_side[channel],
|
||||||
encoder->private_->best_subframe_mid_side+channel,
|
encoder->private_->best_subframe_mid_side+channel,
|
||||||
encoder->private_->best_subframe_bits_mid_side+channel
|
encoder->private_->best_subframe_bits_mid_side+channel
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
,channel
|
||||||
|
#endif
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return false;
|
return false;
|
||||||
@@ -2037,6 +2239,9 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f
|
|||||||
unsigned left_bps = 0, right_bps = 0; /* initialized only to prevent superfluous compiler warning */
|
unsigned left_bps = 0, right_bps = 0; /* initialized only to prevent superfluous compiler warning */
|
||||||
FLAC__Subframe *left_subframe = 0, *right_subframe = 0; /* initialized only to prevent superfluous compiler warning */
|
FLAC__Subframe *left_subframe = 0, *right_subframe = 0; /* initialized only to prevent superfluous compiler warning */
|
||||||
FLAC__ChannelAssignment channel_assignment;
|
FLAC__ChannelAssignment channel_assignment;
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
unsigned left_bits = 0, right_bits = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
FLAC__ASSERT(encoder->protected_->channels == 2);
|
FLAC__ASSERT(encoder->protected_->channels == 2);
|
||||||
|
|
||||||
@@ -2075,18 +2280,34 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f
|
|||||||
case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
|
case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
|
||||||
left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]];
|
left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]];
|
||||||
right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]];
|
right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]];
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
left_bits = encoder->private_->best_subframe_bits [0];
|
||||||
|
right_bits = encoder->private_->best_subframe_bits [1];
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
|
case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
|
||||||
left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]];
|
left_subframe = &encoder->private_->subframe_workspace [0][encoder->private_->best_subframe [0]];
|
||||||
right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
|
right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
left_bits = encoder->private_->best_subframe_bits [0];
|
||||||
|
right_bits = encoder->private_->best_subframe_bits_mid_side [1];
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
|
case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
|
||||||
left_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
|
left_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
|
||||||
right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]];
|
right_subframe = &encoder->private_->subframe_workspace [1][encoder->private_->best_subframe [1]];
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
left_bits = encoder->private_->best_subframe_bits_mid_side [1];
|
||||||
|
right_bits = encoder->private_->best_subframe_bits [1];
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
|
case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
|
||||||
left_subframe = &encoder->private_->subframe_workspace_mid_side[0][encoder->private_->best_subframe_mid_side[0]];
|
left_subframe = &encoder->private_->subframe_workspace_mid_side[0][encoder->private_->best_subframe_mid_side[0]];
|
||||||
right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
|
right_subframe = &encoder->private_->subframe_workspace_mid_side[1][encoder->private_->best_subframe_mid_side[1]];
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
left_bits = encoder->private_->best_subframe_bits_mid_side [0];
|
||||||
|
right_bits = encoder->private_->best_subframe_bits_mid_side [1];
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FLAC__ASSERT(0);
|
FLAC__ASSERT(0);
|
||||||
@@ -2114,10 +2335,17 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* note that encoder_add_subframe_ sets the state for us in case of an error */
|
/* note that encoder_add_subframe_ sets the state for us in case of an error */
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
if(!add_subframe_(encoder, &frame_header, left_bps , left_subframe , encoder->private_->frame, left_bits))
|
||||||
|
return false;
|
||||||
|
if(!add_subframe_(encoder, &frame_header, right_bps, right_subframe, encoder->private_->frame, right_bits))
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
if(!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;
|
return false;
|
||||||
if(!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;
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, encoder->private_->frame)) {
|
if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, encoder->private_->frame)) {
|
||||||
@@ -2126,7 +2354,7 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f
|
|||||||
}
|
}
|
||||||
|
|
||||||
for(channel = 0; channel < encoder->protected_->channels; channel++) {
|
for(channel = 0; channel < encoder->protected_->channels; channel++) {
|
||||||
if(!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, encoder->private_->best_subframe_bits[channel])) {
|
||||||
/* the above function sets the state for us in case of an error */
|
/* the above function sets the state for us in case of an error */
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2160,6 +2388,9 @@ FLAC__bool process_subframe_(
|
|||||||
FLAC__int32 *residual[2],
|
FLAC__int32 *residual[2],
|
||||||
unsigned *best_subframe,
|
unsigned *best_subframe,
|
||||||
unsigned *best_bits
|
unsigned *best_bits
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
,unsigned subframe_number
|
||||||
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
#ifndef FLAC__INTEGER_ONLY_LIBRARY
|
||||||
@@ -2277,7 +2508,10 @@ FLAC__bool process_subframe_(
|
|||||||
else
|
else
|
||||||
max_lpc_order = encoder->protected_->max_lpc_order;
|
max_lpc_order = encoder->protected_->max_lpc_order;
|
||||||
if(max_lpc_order > 0) {
|
if(max_lpc_order > 0) {
|
||||||
encoder->private_->local_lpc_compute_autocorrelation(real_signal, frame_header->blocksize, max_lpc_order+1, autoc);
|
unsigned a;
|
||||||
|
for (a = 0; a < encoder->protected_->num_apodizations; a++) {
|
||||||
|
FLAC__lpc_apply_apodization(real_signal, encoder->private_->window[a], encoder->private_->windowed_signal, frame_header->blocksize);
|
||||||
|
encoder->private_->local_lpc_compute_autocorrelation(encoder->private_->windowed_signal, frame_header->blocksize, max_lpc_order+1, autoc);
|
||||||
/* if autoc[0] == 0.0, the signal is constant and we usually won't get here, but it can happen */
|
/* if autoc[0] == 0.0, the signal is constant and we usually won't get here, but it can happen */
|
||||||
if(autoc[0] != 0.0) {
|
if(autoc[0] != 0.0) {
|
||||||
FLAC__lpc_compute_lp_coefficients(autoc, max_lpc_order, encoder->private_->lp_coeff, lpc_error);
|
FLAC__lpc_compute_lp_coefficients(autoc, max_lpc_order, encoder->private_->lp_coeff, lpc_error);
|
||||||
@@ -2295,9 +2529,9 @@ FLAC__bool process_subframe_(
|
|||||||
rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */
|
rice_parameter = (lpc_residual_bits_per_sample > 0.0)? (unsigned)(lpc_residual_bits_per_sample+0.5) : 0; /* 0.5 is for rounding */
|
||||||
rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */
|
rice_parameter++; /* to account for the signed->unsigned conversion during rice coding */
|
||||||
if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
|
if(rice_parameter >= FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER) {
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
|
fprintf(stderr, "clipping rice_parameter (%u -> %u) @1\n", rice_parameter, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1);
|
||||||
#endif
|
#endif
|
||||||
rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
|
rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1;
|
||||||
}
|
}
|
||||||
if(encoder->protected_->do_qlp_coeff_prec_search) {
|
if(encoder->protected_->do_qlp_coeff_prec_search) {
|
||||||
@@ -2333,6 +2567,11 @@ FLAC__bool process_subframe_(
|
|||||||
encoder->protected_->rice_parameter_search_dist,
|
encoder->protected_->rice_parameter_search_dist,
|
||||||
subframe[!_best_subframe],
|
subframe[!_best_subframe],
|
||||||
partitioned_rice_contents[!_best_subframe]
|
partitioned_rice_contents[!_best_subframe]
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
,frame_header->number.frame_number
|
||||||
|
,subframe_number
|
||||||
|
,encoder->protected_->apodizations[a]
|
||||||
|
#endif
|
||||||
);
|
);
|
||||||
if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */
|
if(_candidate_bits > 0) { /* if == 0, there was a problem quantizing the lpcoeffs */
|
||||||
if(_candidate_bits < _best_bits) {
|
if(_candidate_bits < _best_bits) {
|
||||||
@@ -2345,6 +2584,7 @@ FLAC__bool process_subframe_(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2367,6 +2607,9 @@ FLAC__bool add_subframe_(
|
|||||||
unsigned subframe_bps,
|
unsigned subframe_bps,
|
||||||
const FLAC__Subframe *subframe,
|
const FLAC__Subframe *subframe,
|
||||||
FLAC__BitBuffer *frame
|
FLAC__BitBuffer *frame
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
,unsigned subframe_bits
|
||||||
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
switch(subframe->type) {
|
switch(subframe->type) {
|
||||||
@@ -2383,6 +2626,9 @@ FLAC__bool add_subframe_(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FLAC__SUBFRAME_TYPE_LPC:
|
case FLAC__SUBFRAME_TYPE_LPC:
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
fprintf(stderr, "WIN:\tframe=%u\tsubframe=?\torder=%u\twindow=%s\tbits=%u\n", frame_header->number.frame_number, subframe->data.lpc.order, subframe->data.lpc.window_type, subframe_bits);
|
||||||
|
#endif
|
||||||
if(!FLAC__subframe_add_lpc(&(subframe->data.lpc), frame_header->blocksize - subframe->data.lpc.order, subframe_bps, subframe->wasted_bits, frame)) {
|
if(!FLAC__subframe_add_lpc(&(subframe->data.lpc), frame_header->blocksize - subframe->data.lpc.order, subframe_bps, subframe->wasted_bits, frame)) {
|
||||||
encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_ENCODING;
|
encoder->protected_->state = FLAC__STREAM_ENCODER_FATAL_ERROR_WHILE_ENCODING;
|
||||||
return false;
|
return false;
|
||||||
@@ -2490,6 +2736,11 @@ unsigned evaluate_lpc_subframe_(
|
|||||||
unsigned rice_parameter_search_dist,
|
unsigned rice_parameter_search_dist,
|
||||||
FLAC__Subframe *subframe,
|
FLAC__Subframe *subframe,
|
||||||
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
|
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
,unsigned frame_number
|
||||||
|
,unsigned subframe_number
|
||||||
|
,FLAC__ApodizationSpecification aspec
|
||||||
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
|
FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER];
|
||||||
@@ -2504,6 +2755,15 @@ unsigned evaluate_lpc_subframe_(
|
|||||||
qlp_coeff_precision = min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order));
|
qlp_coeff_precision = min(qlp_coeff_precision, 32 - subframe_bps - FLAC__bitmath_ilog2(order));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
if (aspec.type == FLAC__APODIZATION_GAUSS)
|
||||||
|
snprintf(subframe->data.lpc.window_type, sizeof subframe->data.lpc.window_type, "%s(%0.5f)", winstr[aspec.type], aspec.parameters.gauss.stddev);
|
||||||
|
else if (aspec.type == FLAC__APODIZATION_TUKEY)
|
||||||
|
snprintf(subframe->data.lpc.window_type, sizeof subframe->data.lpc.window_type, "%s(%0.5f)", winstr[aspec.type], aspec.parameters.tukey.p);
|
||||||
|
else
|
||||||
|
strncpy(subframe->data.lpc.window_type, winstr[aspec.type], sizeof subframe->data.lpc.window_type);
|
||||||
|
#endif
|
||||||
|
|
||||||
ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, qlp_coeff, &quantization);
|
ret = FLAC__lpc_quantize_coefficients(lp_coeff, order, qlp_coeff_precision, qlp_coeff, &quantization);
|
||||||
if(ret != 0)
|
if(ret != 0)
|
||||||
return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */
|
return 0; /* this is a hack to indicate to the caller that we can't do lp at this order on this subframe */
|
||||||
@@ -2547,6 +2807,9 @@ unsigned evaluate_lpc_subframe_(
|
|||||||
for(i = 0; i < order; i++)
|
for(i = 0; i < order; i++)
|
||||||
subframe->data.lpc.warmup[i] = signal[i];
|
subframe->data.lpc.warmup[i] = signal[i];
|
||||||
|
|
||||||
|
#ifdef WINDOW_DEBUG_OUTPUT
|
||||||
|
fprintf(stderr, "SWIN:\tframe=%u\tsubframe=%u\torder=%u\twindow=%s\tbits=%u\n", frame_number, subframe_number, order, subframe->data.lpc.window_type, 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);
|
||||||
|
#endif
|
||||||
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;
|
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;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -328,6 +328,17 @@ OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_blocksize(OggFLAC__FileEncoder
|
|||||||
return OggFLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
|
return OggFLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_apodization(OggFLAC__FileEncoder *encoder, const char *specification)
|
||||||
|
{
|
||||||
|
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 != OggFLAC__FILE_ENCODER_UNINITIALIZED)
|
||||||
|
return false;
|
||||||
|
return OggFLAC__seekable_stream_encoder_set_apodization(encoder->private_->seekable_stream_encoder, specification);
|
||||||
|
}
|
||||||
|
|
||||||
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_max_lpc_order(OggFLAC__FileEncoder *encoder, unsigned value)
|
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_max_lpc_order(OggFLAC__FileEncoder *encoder, unsigned value)
|
||||||
{
|
{
|
||||||
FLAC__ASSERT(0 != encoder);
|
FLAC__ASSERT(0 != encoder);
|
||||||
|
|||||||
@@ -335,6 +335,17 @@ OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_blocksize(OggFLAC__S
|
|||||||
return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
|
return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_apodization(OggFLAC__SeekableStreamEncoder *encoder, const char *specification)
|
||||||
|
{
|
||||||
|
FLAC__ASSERT(0 != encoder);
|
||||||
|
FLAC__ASSERT(0 != encoder->private_);
|
||||||
|
FLAC__ASSERT(0 != encoder->protected_);
|
||||||
|
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||||
|
if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
|
||||||
|
return false;
|
||||||
|
return FLAC__stream_encoder_set_apodization(encoder->private_->FLAC_stream_encoder, specification);
|
||||||
|
}
|
||||||
|
|
||||||
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_lpc_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
|
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_lpc_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
|
||||||
{
|
{
|
||||||
FLAC__ASSERT(0 != encoder);
|
FLAC__ASSERT(0 != encoder);
|
||||||
|
|||||||
@@ -290,6 +290,17 @@ OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_blocksize(OggFLAC__StreamEnco
|
|||||||
return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
|
return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_apodization(OggFLAC__StreamEncoder *encoder, const char *specification)
|
||||||
|
{
|
||||||
|
FLAC__ASSERT(0 != encoder);
|
||||||
|
FLAC__ASSERT(0 != encoder->private_);
|
||||||
|
FLAC__ASSERT(0 != encoder->protected_);
|
||||||
|
FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
|
||||||
|
if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
|
||||||
|
return false;
|
||||||
|
return FLAC__stream_encoder_set_apodization(encoder->private_->FLAC_stream_encoder, specification);
|
||||||
|
}
|
||||||
|
|
||||||
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_max_lpc_order(OggFLAC__StreamEncoder *encoder, unsigned value)
|
OggFLAC_API FLAC__bool OggFLAC__stream_encoder_set_max_lpc_order(OggFLAC__StreamEncoder *encoder, unsigned value)
|
||||||
{
|
{
|
||||||
FLAC__ASSERT(0 != encoder);
|
FLAC__ASSERT(0 != encoder);
|
||||||
|
|||||||
Reference in New Issue
Block a user