2001-02-08 00:38:41 +00:00
/* libFLAC - Free Lossless Audio Codec library
2001-01-16 20:17:53 +00:00
* Copyright ( C ) 2000 , 2001 Josh Coalson
2000-12-10 04:09:52 +00:00
*
* 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 <assert.h>
# include <stdio.h>
# include <stdlib.h> /* for malloc() */
# include <string.h> /* for memcpy() */
# include "FLAC/encoder.h"
2001-04-13 19:17:16 +00:00
# include "FLAC/seek_table.h"
2000-12-10 04:09:52 +00:00
# include "private/bitbuffer.h"
2001-03-30 00:45:22 +00:00
# include "private/bitmath.h"
2001-03-27 01:15:58 +00:00
# include "private/crc.h"
2000-12-10 04:09:52 +00:00
# include "private/encoder_framing.h"
# include "private/fixed.h"
# include "private/lpc.h"
2001-01-12 23:55:11 +00:00
# include "private/md5.h"
2000-12-10 04:09:52 +00:00
# ifdef min
# undef min
# endif
# define min(x,y) ((x)<(y)?(x):(y))
# ifdef max
# undef max
# endif
# define max(x,y) ((x)>(y)?(x):(y))
typedef struct FLAC__EncoderPrivate {
unsigned input_capacity ; /* current size (in samples) of the signal and residual buffers */
int32 * integer_signal [ FLAC__MAX_CHANNELS ] ; /* the integer version of the input signal */
int32 * integer_signal_mid_side [ 2 ] ; /* the integer version of the mid-side input signal (stereo only) */
real * real_signal [ FLAC__MAX_CHANNELS ] ; /* the floating-point version of the input signal */
real * real_signal_mid_side [ 2 ] ; /* the floating-point version of the mid-side input signal (stereo only) */
2001-03-28 22:17:05 +00:00
unsigned subframe_bps [ FLAC__MAX_CHANNELS ] ; /* the effective bits per sample of the input signal (stream bps - wasted bits) */
2001-03-28 23:10:22 +00:00
unsigned subframe_bps_mid_side [ 2 ] ; /* the effective bits per sample of the mid-side input signal (stream bps - wasted bits + 0/1) */
2001-01-25 10:41:06 +00:00
int32 * residual_workspace [ FLAC__MAX_CHANNELS ] [ 2 ] ; /* each channel has a candidate and best workspace where the subframe residual signals will be stored */
int32 * residual_workspace_mid_side [ 2 ] [ 2 ] ;
FLAC__Subframe subframe_workspace [ FLAC__MAX_CHANNELS ] [ 2 ] ;
FLAC__Subframe subframe_workspace_mid_side [ 2 ] [ 2 ] ;
FLAC__Subframe * subframe_workspace_ptr [ FLAC__MAX_CHANNELS ] [ 2 ] ;
FLAC__Subframe * subframe_workspace_ptr_mid_side [ 2 ] [ 2 ] ;
unsigned best_subframe [ FLAC__MAX_CHANNELS ] ; /* index into the above workspaces */
unsigned best_subframe_mid_side [ 2 ] ;
unsigned best_subframe_bits [ FLAC__MAX_CHANNELS ] ; /* size in bits of the best subframe for each channel */
unsigned best_subframe_bits_mid_side [ 2 ] ;
2001-04-12 22:22:34 +00:00
uint32 * abs_residual ; /* workspace where abs(candidate residual) is stored */
2001-04-18 02:20:52 +00:00
uint32 * abs_residual_partition_sums ; /* workspace where the sum of abs(candidate residual) for each partition is stored */
2001-04-24 01:25:42 +00:00
unsigned * raw_bits_per_partition ; /* workspace where the sum of silog2(candidate residual) for each partition is stored */
2000-12-10 04:09:52 +00:00
FLAC__BitBuffer frame ; /* the current frame being worked on */
bool current_frame_can_do_mid_side ; /* encoder sets this false when any given sample of a frame's side channel exceeds 16 bits */
2001-01-28 09:27:27 +00:00
double loose_mid_side_stereo_frames_exact ; /* exact number of frames the encoder will use before trying both independent and mid/side frames again */
unsigned loose_mid_side_stereo_frames ; /* rounded number of frames the encoder will use before trying both independent and mid/side frames again */
unsigned loose_mid_side_stereo_frame_count ; /* number of frames using the current channel assignment */
FLAC__ChannelAssignment last_channel_assignment ;
2000-12-10 04:09:52 +00:00
FLAC__StreamMetaData metadata ;
unsigned current_sample_number ;
unsigned current_frame_number ;
2001-01-12 23:55:11 +00:00
struct MD5Context md5context ;
2001-03-30 00:45:22 +00:00
bool use_slow ; /* use slow 64-bit versions of some functions */
2000-12-10 04:09:52 +00:00
FLAC__EncoderWriteStatus ( * write_callback ) ( const FLAC__Encoder * encoder , const byte buffer [ ] , unsigned bytes , unsigned samples , unsigned current_frame , void * client_data ) ;
void ( * metadata_callback ) ( const FLAC__Encoder * encoder , const FLAC__StreamMetaData * metadata , void * client_data ) ;
void * client_data ;
} FLAC__EncoderPrivate ;
static bool encoder_resize_buffers_ ( FLAC__Encoder * encoder , unsigned new_size ) ;
static bool encoder_process_frame_ ( FLAC__Encoder * encoder , bool is_last_frame ) ;
2001-01-25 10:41:06 +00:00
static bool encoder_process_subframes_ ( FLAC__Encoder * encoder , bool is_last_frame ) ;
2001-03-28 22:17:05 +00:00
static bool encoder_process_subframe_ ( FLAC__Encoder * encoder , unsigned max_partition_order , bool verbatim_only , const FLAC__FrameHeader * frame_header , unsigned subframe_bps , const int32 integer_signal [ ] , const real real_signal [ ] , FLAC__Subframe * subframe [ 2 ] , int32 * residual [ 2 ] , unsigned * best_subframe , unsigned * best_bits ) ;
static bool encoder_add_subframe_ ( FLAC__Encoder * encoder , const FLAC__FrameHeader * frame_header , unsigned subframe_bps , const FLAC__Subframe * subframe , FLAC__BitBuffer * frame ) ;
static unsigned encoder_evaluate_constant_subframe_ ( const int32 signal , unsigned subframe_bps , FLAC__Subframe * subframe ) ;
2001-04-24 01:25:42 +00:00
static unsigned encoder_evaluate_fixed_subframe_ ( const int32 signal [ ] , int32 residual [ ] , uint32 abs_residual [ ] , uint32 abs_residual_partition_sums [ ] , unsigned raw_bits_per_partition [ ] , unsigned blocksize , unsigned subframe_bps , unsigned order , unsigned rice_parameter , unsigned max_partition_order , FLAC__Subframe * subframe ) ;
static unsigned encoder_evaluate_lpc_subframe_ ( const int32 signal [ ] , int32 residual [ ] , uint32 abs_residual [ ] , uint32 abs_residual_partition_sums [ ] , unsigned raw_bits_per_partition [ ] , const real lp_coeff [ ] , unsigned blocksize , unsigned subframe_bps , unsigned order , unsigned qlp_coeff_precision , unsigned rice_parameter , unsigned max_partition_order , FLAC__Subframe * subframe ) ;
2001-03-28 22:17:05 +00:00
static unsigned encoder_evaluate_verbatim_subframe_ ( const int32 signal [ ] , unsigned blocksize , unsigned subframe_bps , FLAC__Subframe * subframe ) ;
2001-04-24 01:25:42 +00:00
static unsigned encoder_find_best_partition_order_ ( const int32 residual [ ] , uint32 abs_residual [ ] , uint32 abs_residual_partition_sums [ ] , unsigned raw_bits_per_partition [ ] , unsigned residual_samples , unsigned predictor_order , unsigned rice_parameter , unsigned max_partition_order , unsigned * best_partition_order , unsigned best_parameters [ ] , unsigned best_raw_bits [ ] ) ;
2001-04-24 22:54:07 +00:00
# if (defined FLAC__PRECOMPUTE_PARTITION_SUMS) || (defined FLAC__SEARCH_FOR_ESCAPES)
2001-04-24 01:25:42 +00:00
static unsigned encoder_precompute_partition_info_ ( const int32 residual [ ] , uint32 abs_residual [ ] , uint32 abs_residual_partition_sums [ ] , unsigned raw_bits_per_partition [ ] , unsigned residual_samples , unsigned predictor_order , unsigned max_partition_order ) ;
2001-04-18 22:59:25 +00:00
# endif
2001-04-24 01:25:42 +00:00
static bool encoder_set_partitioned_rice_ ( const uint32 abs_residual [ ] , const uint32 abs_residual_partition_sums [ ] , const unsigned raw_bits_per_partition [ ] , const unsigned residual_samples , const unsigned predictor_order , unsigned rice_parameter , const unsigned partition_order , unsigned parameters [ ] , unsigned raw_bits [ ] , unsigned * bits ) ;
2001-03-27 22:22:27 +00:00
static unsigned encoder_get_wasted_bits_ ( int32 signal [ ] , unsigned samples ) ;
2000-12-10 04:09:52 +00:00
2000-12-22 22:35:33 +00:00
const char * FLAC__EncoderWriteStatusString [ ] = {
" FLAC__ENCODER_WRITE_OK " ,
" FLAC__ENCODER_WRITE_FATAL_ERROR "
} ;
const char * FLAC__EncoderStateString [ ] = {
" FLAC__ENCODER_OK " ,
" FLAC__ENCODER_UNINITIALIZED " ,
" FLAC__ENCODER_INVALID_NUMBER_OF_CHANNELS " ,
" FLAC__ENCODER_INVALID_BITS_PER_SAMPLE " ,
" FLAC__ENCODER_INVALID_SAMPLE_RATE " ,
" FLAC__ENCODER_INVALID_BLOCK_SIZE " ,
" FLAC__ENCODER_INVALID_QLP_COEFF_PRECISION " ,
" FLAC__ENCODER_MID_SIDE_CHANNELS_MISMATCH " ,
" FLAC__ENCODER_MID_SIDE_SAMPLE_SIZE_MISMATCH " ,
2001-01-24 00:54:43 +00:00
" FLAC__ENCODER_ILLEGAL_MID_SIDE_FORCE " ,
2000-12-22 22:35:33 +00:00
" FLAC__ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER " ,
" FLAC__ENCODER_NOT_STREAMABLE " ,
" FLAC__ENCODER_FRAMING_ERROR " ,
" FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING " ,
" FLAC__ENCODER_FATAL_ERROR_WHILE_WRITING " ,
" FLAC__ENCODER_MEMORY_ALLOCATION_ERROR "
} ;
2000-12-10 04:09:52 +00:00
bool encoder_resize_buffers_ ( FLAC__Encoder * encoder , unsigned new_size )
{
bool ok ;
2001-01-25 10:41:06 +00:00
unsigned i , channel ;
2000-12-10 04:09:52 +00:00
int32 * previous_is , * current_is ;
real * previous_rs , * current_rs ;
int32 * residual ;
2001-01-20 01:27:55 +00:00
uint32 * abs_residual ;
2001-04-24 01:25:42 +00:00
unsigned * raw_bits_per_partition ;
2000-12-10 04:09:52 +00:00
assert ( new_size > 0 ) ;
assert ( encoder - > state = = FLAC__ENCODER_OK ) ;
assert ( encoder - > guts - > current_sample_number = = 0 ) ;
/* To avoid excessive malloc'ing, we only grow the buffer; no shrinking. */
if ( new_size < = encoder - > guts - > input_capacity )
return true ;
ok = 1 ;
if ( ok ) {
for ( i = 0 ; ok & & i < encoder - > channels ; i + + ) {
/* integer version of the signal */
previous_is = encoder - > guts - > integer_signal [ i ] ;
current_is = ( int32 * ) malloc ( sizeof ( int32 ) * new_size ) ;
if ( 0 = = current_is ) {
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
ok = 0 ;
}
else {
encoder - > guts - > integer_signal [ i ] = current_is ;
if ( previous_is ! = 0 )
free ( previous_is ) ;
}
/* real version of the signal */
previous_rs = encoder - > guts - > real_signal [ i ] ;
current_rs = ( real * ) malloc ( sizeof ( real ) * new_size ) ;
if ( 0 = = current_rs ) {
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
ok = 0 ;
}
else {
encoder - > guts - > real_signal [ i ] = current_rs ;
if ( previous_rs ! = 0 )
free ( previous_rs ) ;
}
}
}
if ( ok ) {
for ( i = 0 ; ok & & i < 2 ; i + + ) {
/* integer version of the signal */
previous_is = encoder - > guts - > integer_signal_mid_side [ i ] ;
current_is = ( int32 * ) malloc ( sizeof ( int32 ) * new_size ) ;
if ( 0 = = current_is ) {
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
ok = 0 ;
}
else {
encoder - > guts - > integer_signal_mid_side [ i ] = current_is ;
if ( previous_is ! = 0 )
free ( previous_is ) ;
}
/* real version of the signal */
previous_rs = encoder - > guts - > real_signal_mid_side [ i ] ;
current_rs = ( real * ) malloc ( sizeof ( real ) * new_size ) ;
if ( 0 = = current_rs ) {
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
ok = 0 ;
}
else {
encoder - > guts - > real_signal_mid_side [ i ] = current_rs ;
if ( previous_rs ! = 0 )
free ( previous_rs ) ;
}
}
}
if ( ok ) {
2001-01-25 10:41:06 +00:00
for ( channel = 0 ; channel < encoder - > channels ; channel + + ) {
for ( i = 0 ; i < 2 ; i + + ) {
residual = ( int32 * ) malloc ( sizeof ( int32 ) * new_size ) ;
if ( 0 = = residual ) {
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
ok = 0 ;
}
else {
if ( encoder - > guts - > residual_workspace [ channel ] [ i ] ! = 0 )
free ( encoder - > guts - > residual_workspace [ channel ] [ i ] ) ;
encoder - > guts - > residual_workspace [ channel ] [ i ] = residual ;
}
2000-12-10 04:09:52 +00:00
}
2001-01-25 10:41:06 +00:00
}
for ( channel = 0 ; channel < 2 ; channel + + ) {
for ( i = 0 ; i < 2 ; i + + ) {
residual = ( int32 * ) malloc ( sizeof ( int32 ) * new_size ) ;
if ( 0 = = residual ) {
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
ok = 0 ;
}
else {
if ( encoder - > guts - > residual_workspace_mid_side [ channel ] [ i ] ! = 0 )
free ( encoder - > guts - > residual_workspace_mid_side [ channel ] [ i ] ) ;
encoder - > guts - > residual_workspace_mid_side [ channel ] [ i ] = residual ;
}
2000-12-10 04:09:52 +00:00
}
}
2001-01-20 01:27:55 +00:00
abs_residual = ( uint32 * ) malloc ( sizeof ( uint32 ) * new_size ) ;
2001-04-18 02:20:52 +00:00
if ( 0 = = abs_residual ) {
2001-01-20 01:27:55 +00:00
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
ok = 0 ;
}
else {
if ( encoder - > guts - > abs_residual ! = 0 )
free ( encoder - > guts - > abs_residual ) ;
encoder - > guts - > abs_residual = abs_residual ;
}
2001-04-24 22:54:07 +00:00
# ifdef FLAC__PRECOMPUTE_PARTITION_SUMS
2001-04-18 02:20:52 +00:00
abs_residual = ( uint32 * ) malloc ( sizeof ( uint32 ) * ( new_size * 2 ) ) ;
if ( 0 = = abs_residual ) {
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
ok = 0 ;
}
else {
if ( encoder - > guts - > abs_residual_partition_sums ! = 0 )
free ( encoder - > guts - > abs_residual_partition_sums ) ;
encoder - > guts - > abs_residual_partition_sums = abs_residual ;
}
2001-04-24 01:30:10 +00:00
# endif
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
raw_bits_per_partition = ( unsigned * ) malloc ( sizeof ( unsigned ) * ( new_size * 2 ) ) ;
if ( 0 = = raw_bits_per_partition ) {
2001-04-12 22:22:34 +00:00
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
ok = 0 ;
}
else {
2001-04-24 01:25:42 +00:00
if ( encoder - > guts - > raw_bits_per_partition ! = 0 )
free ( encoder - > guts - > raw_bits_per_partition ) ;
encoder - > guts - > raw_bits_per_partition = raw_bits_per_partition ;
2001-04-12 22:22:34 +00:00
}
2001-04-24 01:30:10 +00:00
# endif
2000-12-10 04:09:52 +00:00
}
if ( ok )
encoder - > guts - > input_capacity = new_size ;
return ok ;
}
FLAC__Encoder * FLAC__encoder_get_new_instance ( )
{
FLAC__Encoder * encoder = ( FLAC__Encoder * ) malloc ( sizeof ( FLAC__Encoder ) ) ;
if ( encoder ! = 0 ) {
encoder - > state = FLAC__ENCODER_UNINITIALIZED ;
encoder - > guts = 0 ;
}
return encoder ;
}
void FLAC__encoder_free_instance ( FLAC__Encoder * encoder )
{
assert ( encoder ! = 0 ) ;
free ( encoder ) ;
}
FLAC__EncoderState FLAC__encoder_init ( FLAC__Encoder * encoder , FLAC__EncoderWriteStatus ( * write_callback ) ( const FLAC__Encoder * encoder , const byte buffer [ ] , unsigned bytes , unsigned samples , unsigned current_frame , void * client_data ) , void ( * metadata_callback ) ( const FLAC__Encoder * encoder , const FLAC__StreamMetaData * metadata , void * client_data ) , void * client_data )
{
unsigned i ;
2001-02-23 21:05:05 +00:00
FLAC__StreamMetaData padding ;
2001-04-13 19:17:16 +00:00
FLAC__StreamMetaData seek_table ;
2000-12-10 04:09:52 +00:00
assert ( sizeof ( int ) > = 4 ) ; /* we want to die right away if this is not true */
assert ( encoder ! = 0 ) ;
assert ( write_callback ! = 0 ) ;
assert ( metadata_callback ! = 0 ) ;
assert ( encoder - > state = = FLAC__ENCODER_UNINITIALIZED ) ;
assert ( encoder - > guts = = 0 ) ;
encoder - > state = FLAC__ENCODER_OK ;
if ( encoder - > channels = = 0 | | encoder - > channels > FLAC__MAX_CHANNELS )
return encoder - > state = FLAC__ENCODER_INVALID_NUMBER_OF_CHANNELS ;
if ( encoder - > do_mid_side_stereo & & encoder - > channels ! = 2 )
return encoder - > state = FLAC__ENCODER_MID_SIDE_CHANNELS_MISMATCH ;
2001-01-28 09:27:27 +00:00
if ( encoder - > loose_mid_side_stereo & & ! encoder - > do_mid_side_stereo )
2001-01-24 00:54:43 +00:00
return encoder - > state = FLAC__ENCODER_ILLEGAL_MID_SIDE_FORCE ;
2001-03-28 22:17:05 +00:00
if ( encoder - > bits_per_sample < FLAC__MIN_BITS_PER_SAMPLE | | encoder - > bits_per_sample > FLAC__MAX_BITS_PER_SAMPLE )
2000-12-10 04:09:52 +00:00
return encoder - > state = FLAC__ENCODER_INVALID_BITS_PER_SAMPLE ;
if ( encoder - > sample_rate = = 0 | | encoder - > sample_rate > FLAC__MAX_SAMPLE_RATE )
return encoder - > state = FLAC__ENCODER_INVALID_SAMPLE_RATE ;
if ( encoder - > blocksize < FLAC__MIN_BLOCK_SIZE | | encoder - > blocksize > FLAC__MAX_BLOCK_SIZE )
return encoder - > state = FLAC__ENCODER_INVALID_BLOCK_SIZE ;
if ( encoder - > blocksize < encoder - > max_lpc_order )
return encoder - > state = FLAC__ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER ;
if ( encoder - > qlp_coeff_precision = = 0 ) {
if ( encoder - > bits_per_sample < 16 ) {
/* @@@ need some data about how to set this here w.r.t. blocksize and sample rate */
/* @@@ until then we'll make a guess */
encoder - > qlp_coeff_precision = max ( 5 , 2 + encoder - > bits_per_sample / 2 ) ;
}
else if ( encoder - > bits_per_sample = = 16 ) {
if ( encoder - > blocksize < = 192 )
encoder - > qlp_coeff_precision = 7 ;
else if ( encoder - > blocksize < = 384 )
encoder - > qlp_coeff_precision = 8 ;
else if ( encoder - > blocksize < = 576 )
encoder - > qlp_coeff_precision = 9 ;
else if ( encoder - > blocksize < = 1152 )
encoder - > qlp_coeff_precision = 10 ;
else if ( encoder - > blocksize < = 2304 )
encoder - > qlp_coeff_precision = 11 ;
else if ( encoder - > blocksize < = 4608 )
encoder - > qlp_coeff_precision = 12 ;
else
encoder - > qlp_coeff_precision = 13 ;
}
else {
encoder - > qlp_coeff_precision = min ( 13 , 8 * sizeof ( int32 ) - encoder - > bits_per_sample - 1 ) ;
}
}
2001-02-26 20:29:56 +00:00
else if ( encoder - > qlp_coeff_precision < FLAC__MIN_QLP_COEFF_PRECISION | | encoder - > qlp_coeff_precision + encoder - > bits_per_sample > = 8 * sizeof ( uint32 ) | | encoder - > qlp_coeff_precision > = ( 1u < < FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN ) )
2000-12-10 04:09:52 +00:00
return encoder - > state = FLAC__ENCODER_INVALID_QLP_COEFF_PRECISION ;
if ( encoder - > streamable_subset ) {
2001-04-18 02:20:52 +00:00
//@@@ add check for blocksize here
2000-12-10 04:09:52 +00:00
if ( encoder - > bits_per_sample ! = 8 & & encoder - > bits_per_sample ! = 12 & & encoder - > bits_per_sample ! = 16 & & encoder - > bits_per_sample ! = 20 & & encoder - > bits_per_sample ! = 24 )
return encoder - > state = FLAC__ENCODER_NOT_STREAMABLE ;
if ( encoder - > sample_rate > 655350 )
return encoder - > state = FLAC__ENCODER_NOT_STREAMABLE ;
}
if ( encoder - > rice_optimization_level > = ( 1u < < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN ) )
encoder - > rice_optimization_level = ( 1u < < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN ) - 1 ;
encoder - > guts = ( FLAC__EncoderPrivate * ) malloc ( sizeof ( FLAC__EncoderPrivate ) ) ;
if ( encoder - > guts = = 0 )
return encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
encoder - > guts - > input_capacity = 0 ;
for ( i = 0 ; i < encoder - > channels ; i + + ) {
encoder - > guts - > integer_signal [ i ] = 0 ;
encoder - > guts - > real_signal [ i ] = 0 ;
}
for ( i = 0 ; i < 2 ; i + + ) {
encoder - > guts - > integer_signal_mid_side [ i ] = 0 ;
encoder - > guts - > real_signal_mid_side [ i ] = 0 ;
}
2001-01-25 10:41:06 +00:00
for ( i = 0 ; i < encoder - > channels ; i + + ) {
encoder - > guts - > residual_workspace [ i ] [ 0 ] = encoder - > guts - > residual_workspace [ i ] [ 1 ] = 0 ;
encoder - > guts - > best_subframe [ i ] = 0 ;
}
for ( i = 0 ; i < 2 ; i + + ) {
encoder - > guts - > residual_workspace_mid_side [ i ] [ 0 ] = encoder - > guts - > residual_workspace_mid_side [ i ] [ 1 ] = 0 ;
encoder - > guts - > best_subframe_mid_side [ i ] = 0 ;
}
for ( i = 0 ; i < encoder - > channels ; i + + ) {
encoder - > guts - > subframe_workspace_ptr [ i ] [ 0 ] = & encoder - > guts - > subframe_workspace [ i ] [ 0 ] ;
encoder - > guts - > subframe_workspace_ptr [ i ] [ 1 ] = & encoder - > guts - > subframe_workspace [ i ] [ 1 ] ;
}
for ( i = 0 ; i < 2 ; i + + ) {
encoder - > guts - > subframe_workspace_ptr_mid_side [ i ] [ 0 ] = & encoder - > guts - > subframe_workspace_mid_side [ i ] [ 0 ] ;
encoder - > guts - > subframe_workspace_ptr_mid_side [ i ] [ 1 ] = & encoder - > guts - > subframe_workspace_mid_side [ i ] [ 1 ] ;
}
2001-01-20 01:27:55 +00:00
encoder - > guts - > abs_residual = 0 ;
2001-04-18 02:20:52 +00:00
encoder - > guts - > abs_residual_partition_sums = 0 ;
2001-04-24 01:25:42 +00:00
encoder - > guts - > raw_bits_per_partition = 0 ;
2000-12-10 04:09:52 +00:00
encoder - > guts - > current_frame_can_do_mid_side = true ;
2001-01-28 09:27:27 +00:00
encoder - > guts - > loose_mid_side_stereo_frames_exact = ( double ) encoder - > sample_rate * 0.4 / ( double ) encoder - > blocksize ;
encoder - > guts - > loose_mid_side_stereo_frames = ( unsigned ) ( encoder - > guts - > loose_mid_side_stereo_frames_exact + 0.5 ) ;
if ( encoder - > guts - > loose_mid_side_stereo_frames = = 0 )
encoder - > guts - > loose_mid_side_stereo_frames = 1 ;
encoder - > guts - > loose_mid_side_stereo_frame_count = 0 ;
2000-12-10 04:09:52 +00:00
encoder - > guts - > current_sample_number = 0 ;
encoder - > guts - > current_frame_number = 0 ;
2001-03-30 00:45:22 +00:00
if ( encoder - > bits_per_sample + FLAC__bitmath_ilog2 ( encoder - > blocksize ) + 1 > 30 )
encoder - > guts - > use_slow = true ;
else
encoder - > guts - > use_slow = false ;
2000-12-10 04:09:52 +00:00
if ( ! encoder_resize_buffers_ ( encoder , encoder - > blocksize ) ) {
/* the above function sets the state for us in case of an error */
return encoder - > state ;
}
FLAC__bitbuffer_init ( & encoder - > guts - > frame ) ;
encoder - > guts - > write_callback = write_callback ;
encoder - > guts - > metadata_callback = metadata_callback ;
encoder - > guts - > client_data = client_data ;
/*
* write the stream header
*/
if ( ! FLAC__bitbuffer_clear ( & encoder - > guts - > frame ) )
return encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
if ( ! FLAC__bitbuffer_write_raw_uint32 ( & encoder - > guts - > frame , FLAC__STREAM_SYNC , FLAC__STREAM_SYNC_LEN ) )
return encoder - > state = FLAC__ENCODER_FRAMING_ERROR ;
2001-02-23 21:05:05 +00:00
encoder - > guts - > metadata . type = FLAC__METADATA_TYPE_STREAMINFO ;
2001-04-13 19:17:16 +00:00
encoder - > guts - > metadata . is_last = ( encoder - > seek_table = = 0 & & encoder - > padding = = 0 ) ;
2001-02-23 21:05:05 +00:00
encoder - > guts - > metadata . length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH ;
encoder - > guts - > metadata . data . stream_info . min_blocksize = encoder - > blocksize ; /* this encoder uses the same blocksize for the whole stream */
encoder - > guts - > metadata . data . stream_info . max_blocksize = encoder - > blocksize ;
encoder - > guts - > metadata . data . stream_info . min_framesize = 0 ; /* we don't know this yet; have to fill it in later */
encoder - > guts - > metadata . data . stream_info . max_framesize = 0 ; /* we don't know this yet; have to fill it in later */
encoder - > guts - > metadata . data . stream_info . sample_rate = encoder - > sample_rate ;
encoder - > guts - > metadata . data . stream_info . channels = encoder - > channels ;
encoder - > guts - > metadata . data . stream_info . bits_per_sample = encoder - > bits_per_sample ;
encoder - > guts - > metadata . data . stream_info . total_samples = encoder - > total_samples_estimate ; /* we will replace this later with the real total */
memset ( encoder - > guts - > metadata . data . stream_info . md5sum , 0 , 16 ) ; /* we don't know this yet; have to fill it in later */
2001-01-12 23:55:11 +00:00
MD5Init ( & encoder - > guts - > md5context ) ;
2000-12-10 04:09:52 +00:00
if ( ! FLAC__add_metadata_block ( & encoder - > guts - > metadata , & encoder - > guts - > frame ) )
return encoder - > state = FLAC__ENCODER_FRAMING_ERROR ;
2001-04-13 19:17:16 +00:00
if ( 0 ! = encoder - > seek_table ) {
if ( ! FLAC__seek_table_is_valid ( encoder - > seek_table ) )
return encoder - > state = FLAC__ENCODER_INVALID_SEEK_TABLE ;
seek_table . type = FLAC__METADATA_TYPE_SEEKTABLE ;
seek_table . is_last = ( encoder - > padding = = 0 ) ;
seek_table . length = encoder - > seek_table - > num_points * FLAC__STREAM_METADATA_SEEKPOINT_LEN ;
seek_table . data . seek_table = * encoder - > seek_table ;
if ( ! FLAC__add_metadata_block ( & seek_table , & encoder - > guts - > frame ) )
return encoder - > state = FLAC__ENCODER_FRAMING_ERROR ;
}
2001-02-23 21:05:05 +00:00
/* add a PADDING block if requested */
if ( encoder - > padding > 0 ) {
padding . type = FLAC__METADATA_TYPE_PADDING ;
padding . is_last = true ;
padding . length = encoder - > padding ;
if ( ! FLAC__add_metadata_block ( & padding , & encoder - > guts - > frame ) )
return encoder - > state = FLAC__ENCODER_FRAMING_ERROR ;
}
2000-12-10 04:09:52 +00:00
assert ( encoder - > guts - > frame . bits = = 0 ) ; /* assert that we're byte-aligned before writing */
assert ( encoder - > guts - > frame . total_consumed_bits = = 0 ) ; /* assert that no reading of the buffer was done */
if ( encoder - > guts - > write_callback ( encoder , encoder - > guts - > frame . buffer , encoder - > guts - > frame . bytes , 0 , encoder - > guts - > current_frame_number , encoder - > guts - > client_data ) ! = FLAC__ENCODER_WRITE_OK )
return encoder - > state = FLAC__ENCODER_FATAL_ERROR_WHILE_WRITING ;
2001-01-23 00:41:48 +00:00
/* now that the metadata block is written, we can init this to an absurdly-high value... */
2001-02-23 21:05:05 +00:00
encoder - > guts - > metadata . data . stream_info . min_framesize = ( 1u < < FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN ) - 1 ;
2001-01-23 00:41:48 +00:00
/* ... and clear this to 0 */
2001-02-23 21:05:05 +00:00
encoder - > guts - > metadata . data . stream_info . total_samples = 0 ;
2000-12-10 04:09:52 +00:00
return encoder - > state ;
}
void FLAC__encoder_finish ( FLAC__Encoder * encoder )
{
2001-01-25 10:41:06 +00:00
unsigned i , channel ;
2000-12-10 04:09:52 +00:00
assert ( encoder ! = 0 ) ;
if ( encoder - > state = = FLAC__ENCODER_UNINITIALIZED )
return ;
if ( encoder - > guts - > current_sample_number ! = 0 ) {
encoder - > blocksize = encoder - > guts - > current_sample_number ;
encoder_process_frame_ ( encoder , true ) ; /* true => is last frame */
}
2001-02-23 21:05:05 +00:00
MD5Final ( encoder - > guts - > metadata . data . stream_info . md5sum , & encoder - > guts - > md5context ) ;
2000-12-10 04:09:52 +00:00
encoder - > guts - > metadata_callback ( encoder , & encoder - > guts - > metadata , encoder - > guts - > client_data ) ;
if ( encoder - > guts ! = 0 ) {
for ( i = 0 ; i < encoder - > channels ; i + + ) {
if ( encoder - > guts - > integer_signal [ i ] ! = 0 ) {
free ( encoder - > guts - > integer_signal [ i ] ) ;
encoder - > guts - > integer_signal [ i ] = 0 ;
}
if ( encoder - > guts - > real_signal [ i ] ! = 0 ) {
free ( encoder - > guts - > real_signal [ i ] ) ;
encoder - > guts - > real_signal [ i ] = 0 ;
}
}
for ( i = 0 ; i < 2 ; i + + ) {
if ( encoder - > guts - > integer_signal_mid_side [ i ] ! = 0 ) {
free ( encoder - > guts - > integer_signal_mid_side [ i ] ) ;
encoder - > guts - > integer_signal_mid_side [ i ] = 0 ;
}
if ( encoder - > guts - > real_signal_mid_side [ i ] ! = 0 ) {
free ( encoder - > guts - > real_signal_mid_side [ i ] ) ;
encoder - > guts - > real_signal_mid_side [ i ] = 0 ;
}
}
2001-01-25 10:41:06 +00:00
for ( channel = 0 ; channel < encoder - > channels ; channel + + ) {
for ( i = 0 ; i < 2 ; i + + ) {
if ( encoder - > guts - > residual_workspace [ channel ] [ i ] ! = 0 ) {
free ( encoder - > guts - > residual_workspace [ channel ] [ i ] ) ;
encoder - > guts - > residual_workspace [ channel ] [ i ] = 0 ;
}
}
}
for ( channel = 0 ; channel < 2 ; channel + + ) {
for ( i = 0 ; i < 2 ; i + + ) {
if ( encoder - > guts - > residual_workspace_mid_side [ channel ] [ i ] ! = 0 ) {
free ( encoder - > guts - > residual_workspace_mid_side [ channel ] [ i ] ) ;
encoder - > guts - > residual_workspace_mid_side [ channel ] [ i ] = 0 ;
}
2000-12-10 04:09:52 +00:00
}
}
2001-01-20 01:27:55 +00:00
if ( encoder - > guts - > abs_residual ! = 0 ) {
free ( encoder - > guts - > abs_residual ) ;
encoder - > guts - > abs_residual = 0 ;
}
2001-04-18 02:20:52 +00:00
if ( encoder - > guts - > abs_residual_partition_sums ! = 0 ) {
free ( encoder - > guts - > abs_residual_partition_sums ) ;
encoder - > guts - > abs_residual_partition_sums = 0 ;
}
2001-04-24 01:25:42 +00:00
if ( encoder - > guts - > raw_bits_per_partition ! = 0 ) {
free ( encoder - > guts - > raw_bits_per_partition ) ;
encoder - > guts - > raw_bits_per_partition = 0 ;
2001-04-12 22:22:34 +00:00
}
2000-12-10 04:09:52 +00:00
FLAC__bitbuffer_free ( & encoder - > guts - > frame ) ;
free ( encoder - > guts ) ;
encoder - > guts = 0 ;
}
encoder - > state = FLAC__ENCODER_UNINITIALIZED ;
}
bool FLAC__encoder_process ( FLAC__Encoder * encoder , const int32 * buf [ ] , unsigned samples )
{
unsigned i , j , channel ;
int32 x , mid , side ;
const bool ms = encoder - > do_mid_side_stereo & & encoder - > channels = = 2 ;
const int32 min_side = - ( ( int64 ) 1 < < ( encoder - > bits_per_sample - 1 ) ) ;
const int32 max_side = ( ( int64 ) 1 < < ( encoder - > bits_per_sample - 1 ) ) - 1 ;
assert ( encoder ! = 0 ) ;
assert ( encoder - > state = = FLAC__ENCODER_OK ) ;
j = 0 ;
do {
for ( i = encoder - > guts - > current_sample_number ; i < encoder - > blocksize & & j < samples ; i + + , j + + ) {
for ( channel = 0 ; channel < encoder - > channels ; channel + + ) {
x = buf [ channel ] [ j ] ;
encoder - > guts - > integer_signal [ channel ] [ i ] = x ;
encoder - > guts - > real_signal [ channel ] [ i ] = ( real ) x ;
}
if ( ms & & encoder - > guts - > current_frame_can_do_mid_side ) {
side = buf [ 0 ] [ j ] - buf [ 1 ] [ j ] ;
if ( side < min_side | | side > max_side ) {
encoder - > guts - > current_frame_can_do_mid_side = false ;
}
else {
2001-01-28 09:27:27 +00:00
mid = ( buf [ 0 ] [ j ] + buf [ 1 ] [ j ] ) > > 1 ; /* NOTE: not the same as 'mid = (buf[0][j] + buf[1][j]) / 2' ! */
2000-12-10 04:09:52 +00:00
encoder - > guts - > integer_signal_mid_side [ 0 ] [ i ] = mid ;
encoder - > guts - > integer_signal_mid_side [ 1 ] [ i ] = side ;
encoder - > guts - > real_signal_mid_side [ 0 ] [ i ] = ( real ) mid ;
encoder - > guts - > real_signal_mid_side [ 1 ] [ i ] = ( real ) side ;
}
}
encoder - > guts - > current_sample_number + + ;
}
if ( i = = encoder - > blocksize ) {
if ( ! encoder_process_frame_ ( encoder , false ) ) /* false => not last frame */
return false ;
}
} while ( j < samples ) ;
return true ;
}
/* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
bool FLAC__encoder_process_interleaved ( FLAC__Encoder * encoder , const int32 buf [ ] , unsigned samples )
{
unsigned i , j , k , channel ;
int32 x , left = 0 , mid , side ;
const bool ms = encoder - > do_mid_side_stereo & & encoder - > channels = = 2 ;
const int32 min_side = - ( ( int64 ) 1 < < ( encoder - > bits_per_sample - 1 ) ) ;
const int32 max_side = ( ( int64 ) 1 < < ( encoder - > bits_per_sample - 1 ) ) - 1 ;
assert ( encoder ! = 0 ) ;
assert ( encoder - > state = = FLAC__ENCODER_OK ) ;
j = k = 0 ;
do {
for ( i = encoder - > guts - > current_sample_number ; i < encoder - > blocksize & & j < samples ; i + + , j + + , k + + ) {
for ( channel = 0 ; channel < encoder - > channels ; channel + + , k + + ) {
x = buf [ k ] ;
encoder - > guts - > integer_signal [ channel ] [ i ] = x ;
encoder - > guts - > real_signal [ channel ] [ i ] = ( real ) x ;
if ( ms & & encoder - > guts - > current_frame_can_do_mid_side ) {
if ( channel = = 0 ) {
left = x ;
}
else {
side = left - x ;
if ( side < min_side | | side > max_side ) {
encoder - > guts - > current_frame_can_do_mid_side = false ;
}
else {
2001-01-28 09:27:27 +00:00
mid = ( left + x ) > > 1 ; /* NOTE: not the same as 'mid = (left + x) / 2' ! */
2000-12-10 04:09:52 +00:00
encoder - > guts - > integer_signal_mid_side [ 0 ] [ i ] = mid ;
encoder - > guts - > integer_signal_mid_side [ 1 ] [ i ] = side ;
encoder - > guts - > real_signal_mid_side [ 0 ] [ i ] = ( real ) mid ;
encoder - > guts - > real_signal_mid_side [ 1 ] [ i ] = ( real ) side ;
}
}
}
}
encoder - > guts - > current_sample_number + + ;
}
if ( i = = encoder - > blocksize ) {
if ( ! encoder_process_frame_ ( encoder , false ) ) /* false => not last frame */
return false ;
}
} while ( j < samples ) ;
return true ;
}
bool encoder_process_frame_ ( FLAC__Encoder * encoder , bool is_last_frame )
{
assert ( encoder - > state = = FLAC__ENCODER_OK ) ;
2001-01-12 23:55:11 +00:00
/*
* Accumulate raw signal to the MD5 signature
*/
2001-04-16 05:33:22 +00:00
/* NOTE: some versions of GCC can't figure out const-ness right and will give you an 'incompatible pointer type' warning on arg 2 here: */
2001-01-12 23:55:11 +00:00
if ( ! FLAC__MD5Accumulate ( & encoder - > guts - > md5context , encoder - > guts - > integer_signal , encoder - > channels , encoder - > blocksize , ( encoder - > bits_per_sample + 7 ) / 8 ) ) {
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
2000-12-10 04:09:52 +00:00
/*
2001-01-25 10:41:06 +00:00
* Process the frame header and subframes into the frame bitbuffer
2000-12-10 04:09:52 +00:00
*/
2001-01-25 10:41:06 +00:00
if ( ! encoder_process_subframes_ ( encoder , is_last_frame ) ) {
/* the above function sets the state for us in case of an error */
2000-12-10 04:09:52 +00:00
return false ;
}
/*
* Zero - pad the frame to a byte_boundary
*/
2001-01-25 10:41:06 +00:00
if ( ! FLAC__bitbuffer_zero_pad_to_byte_boundary ( & encoder - > guts - > frame ) ) {
2000-12-10 04:09:52 +00:00
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
/*
2001-03-27 01:15:58 +00:00
* CRC - 16 the whole thing
2000-12-10 04:09:52 +00:00
*/
2001-03-27 01:15:58 +00:00
assert ( encoder - > guts - > frame . bits = = 0 ) ; /* assert that we're byte-aligned */
2001-01-25 10:41:06 +00:00
assert ( encoder - > guts - > frame . total_consumed_bits = = 0 ) ; /* assert that no reading of the buffer was done */
2001-03-27 01:15:58 +00:00
FLAC__bitbuffer_write_raw_uint32 ( & encoder - > guts - > frame , FLAC__crc16 ( encoder - > guts - > frame . buffer , encoder - > guts - > frame . bytes ) , FLAC__FRAME_FOOTER_CRC_LEN ) ;
/*
* Write it
*/
2001-01-25 10:41:06 +00:00
if ( encoder - > guts - > write_callback ( encoder , encoder - > guts - > frame . buffer , encoder - > guts - > frame . bytes , encoder - > blocksize , encoder - > guts - > current_frame_number , encoder - > guts - > client_data ) ! = FLAC__ENCODER_WRITE_OK ) {
2000-12-10 04:09:52 +00:00
encoder - > state = FLAC__ENCODER_FATAL_ERROR_WHILE_WRITING ;
return false ;
}
/*
* Get ready for the next frame
*/
encoder - > guts - > current_frame_can_do_mid_side = true ;
encoder - > guts - > current_sample_number = 0 ;
encoder - > guts - > current_frame_number + + ;
2001-02-23 21:05:05 +00:00
encoder - > guts - > metadata . data . stream_info . total_samples + = ( uint64 ) encoder - > blocksize ;
encoder - > guts - > metadata . data . stream_info . min_framesize = min ( encoder - > guts - > frame . bytes , encoder - > guts - > metadata . data . stream_info . min_framesize ) ;
encoder - > guts - > metadata . data . stream_info . max_framesize = max ( encoder - > guts - > frame . bytes , encoder - > guts - > metadata . data . stream_info . max_framesize ) ;
2000-12-10 04:09:52 +00:00
return true ;
}
2001-01-25 10:41:06 +00:00
bool encoder_process_subframes_ ( FLAC__Encoder * encoder , bool is_last_frame )
2000-12-10 04:09:52 +00:00
{
2001-01-25 10:41:06 +00:00
FLAC__FrameHeader frame_header ;
unsigned channel , max_partition_order ;
2001-01-28 09:27:27 +00:00
bool do_independent , do_mid_side ;
2000-12-10 04:09:52 +00:00
2001-01-25 10:41:06 +00:00
/*
* Calculate the max Rice partition order
*/
2000-12-10 04:09:52 +00:00
if ( is_last_frame ) {
max_partition_order = 0 ;
}
else {
unsigned limit = 0 , b = encoder - > blocksize ;
while ( ! ( b & 1 ) ) {
limit + + ;
b > > = 1 ;
}
max_partition_order = min ( encoder - > rice_optimization_level , limit ) ;
}
2001-01-25 10:41:06 +00:00
/*
* Setup the frame
*/
if ( ! FLAC__bitbuffer_clear ( & encoder - > guts - > frame ) ) {
encoder - > state = FLAC__ENCODER_MEMORY_ALLOCATION_ERROR ;
return false ;
}
frame_header . blocksize = encoder - > blocksize ;
frame_header . sample_rate = encoder - > sample_rate ;
frame_header . channels = encoder - > channels ;
frame_header . channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT ; /* the default unless the encoder determines otherwise */
frame_header . bits_per_sample = encoder - > bits_per_sample ;
frame_header . number . frame_number = encoder - > guts - > current_frame_number ;
2000-12-10 04:09:52 +00:00
2001-01-28 09:27:27 +00:00
/*
* Figure out what channel assignments to try
*/
if ( encoder - > do_mid_side_stereo ) {
if ( encoder - > loose_mid_side_stereo ) {
if ( encoder - > guts - > loose_mid_side_stereo_frame_count = = 0 ) {
do_independent = true ;
do_mid_side = true ;
}
else {
do_independent = ( encoder - > guts - > last_channel_assignment = = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT ) ;
do_mid_side = ! do_independent ;
}
}
else {
do_independent = true ;
do_mid_side = true ;
}
}
else {
do_independent = true ;
do_mid_side = false ;
}
if ( do_mid_side & & ! encoder - > guts - > current_frame_can_do_mid_side ) {
do_independent = true ;
do_mid_side = false ;
}
assert ( do_independent | | do_mid_side ) ;
2001-03-27 22:22:27 +00:00
/*
2001-03-28 22:17:05 +00:00
* Check for wasted bits ; set effective bps for each subframe
2001-03-27 22:22:27 +00:00
*/
if ( do_independent ) {
2001-03-28 22:17:05 +00:00
unsigned w ;
for ( channel = 0 ; channel < encoder - > channels ; channel + + ) {
w = encoder_get_wasted_bits_ ( encoder - > guts - > integer_signal [ channel ] , encoder - > blocksize ) ;
encoder - > guts - > subframe_workspace [ channel ] [ 0 ] . wasted_bits = encoder - > guts - > subframe_workspace [ channel ] [ 1 ] . wasted_bits = w ;
encoder - > guts - > subframe_bps [ channel ] = encoder - > bits_per_sample - w ;
}
2001-03-27 22:22:27 +00:00
}
if ( do_mid_side ) {
2001-03-28 22:17:05 +00:00
unsigned w ;
2001-03-27 22:22:27 +00:00
assert ( encoder - > channels = = 2 ) ;
2001-03-28 22:17:05 +00:00
for ( channel = 0 ; channel < 2 ; channel + + ) {
w = encoder_get_wasted_bits_ ( encoder - > guts - > integer_signal_mid_side [ channel ] , encoder - > blocksize ) ;
encoder - > guts - > subframe_workspace_mid_side [ channel ] [ 0 ] . wasted_bits = encoder - > guts - > subframe_workspace_mid_side [ channel ] [ 1 ] . wasted_bits = w ;
encoder - > guts - > subframe_bps_mid_side [ channel ] = encoder - > bits_per_sample - w + ( channel = = 0 ? 0 : 1 ) ;
}
2001-03-27 22:22:27 +00:00
}
2001-01-25 10:41:06 +00:00
/*
* First do a normal encoding pass of each independent channel
*/
2001-01-28 09:27:27 +00:00
if ( do_independent ) {
for ( channel = 0 ; channel < encoder - > channels ; channel + + ) {
2001-03-28 22:17:05 +00:00
if ( ! encoder_process_subframe_ ( encoder , max_partition_order , false , & frame_header , encoder - > guts - > subframe_bps [ channel ] , encoder - > guts - > integer_signal [ channel ] , encoder - > guts - > real_signal [ channel ] , encoder - > guts - > subframe_workspace_ptr [ channel ] , encoder - > guts - > residual_workspace [ channel ] , encoder - > guts - > best_subframe + channel , encoder - > guts - > best_subframe_bits + channel ) )
2001-01-28 09:27:27 +00:00
return false ;
}
2001-01-25 10:41:06 +00:00
}
/*
* Now do mid and side channels if requested
*/
2001-01-28 09:27:27 +00:00
if ( do_mid_side ) {
2001-01-25 10:41:06 +00:00
assert ( encoder - > channels = = 2 ) ;
for ( channel = 0 ; channel < 2 ; channel + + ) {
2001-03-28 22:17:05 +00:00
if ( ! encoder_process_subframe_ ( encoder , max_partition_order , false , & frame_header , encoder - > guts - > subframe_bps_mid_side [ channel ] , encoder - > guts - > integer_signal_mid_side [ channel ] , encoder - > guts - > real_signal_mid_side [ channel ] , encoder - > guts - > subframe_workspace_ptr_mid_side [ channel ] , encoder - > guts - > residual_workspace_mid_side [ channel ] , encoder - > guts - > best_subframe_mid_side + channel , encoder - > guts - > best_subframe_bits_mid_side + channel ) )
2001-01-25 10:41:06 +00:00
return false ;
}
}
/*
* Compose the frame bitbuffer
*/
2001-01-28 09:27:27 +00:00
if ( do_mid_side ) {
2001-03-28 22:17:05 +00:00
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 */
2001-01-28 09:27:27 +00:00
FLAC__ChannelAssignment channel_assignment ;
2001-01-25 10:41:06 +00:00
2001-01-28 09:27:27 +00:00
assert ( encoder - > channels = = 2 ) ;
2001-01-25 10:41:06 +00:00
2001-01-28 09:27:27 +00:00
if ( encoder - > loose_mid_side_stereo & & encoder - > guts - > loose_mid_side_stereo_frame_count > 0 ) {
channel_assignment = ( encoder - > guts - > last_channel_assignment = = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT ? FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT : FLAC__CHANNEL_ASSIGNMENT_MID_SIDE ) ;
}
else {
unsigned bits [ 4 ] ; /* WATCHOUT - indexed by FLAC__ChannelAssignment */
unsigned min_bits ;
FLAC__ChannelAssignment ca ;
assert ( do_independent & & do_mid_side ) ;
/* We have to figure out which channel assignent results in the smallest frame */
bits [ FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT ] = encoder - > guts - > best_subframe_bits [ 0 ] + encoder - > guts - > best_subframe_bits [ 1 ] ;
bits [ FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE ] = encoder - > guts - > best_subframe_bits [ 0 ] + encoder - > guts - > best_subframe_bits_mid_side [ 1 ] ;
bits [ FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE ] = encoder - > guts - > best_subframe_bits [ 1 ] + encoder - > guts - > best_subframe_bits_mid_side [ 1 ] ;
bits [ FLAC__CHANNEL_ASSIGNMENT_MID_SIDE ] = encoder - > guts - > best_subframe_bits_mid_side [ 0 ] + encoder - > guts - > best_subframe_bits_mid_side [ 1 ] ;
for ( channel_assignment = 0 , min_bits = bits [ 0 ] , ca = 1 ; ca < = 3 ; ca + + ) {
if ( bits [ ca ] < min_bits ) {
min_bits = bits [ ca ] ;
channel_assignment = ca ;
}
2001-01-25 10:41:06 +00:00
}
}
2001-01-28 09:27:27 +00:00
frame_header . channel_assignment = channel_assignment ;
2001-01-25 10:41:06 +00:00
if ( ! FLAC__frame_add_header ( & frame_header , encoder - > streamable_subset , is_last_frame , & encoder - > guts - > frame ) ) {
encoder - > state = FLAC__ENCODER_FRAMING_ERROR ;
return false ;
}
2001-01-28 09:27:27 +00:00
switch ( channel_assignment ) {
2001-01-25 10:41:06 +00:00
case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT :
2001-03-28 22:17:05 +00:00
left_subframe = & encoder - > guts - > subframe_workspace [ 0 ] [ encoder - > guts - > best_subframe [ 0 ] ] ;
right_subframe = & encoder - > guts - > subframe_workspace [ 1 ] [ encoder - > guts - > best_subframe [ 1 ] ] ;
2001-01-25 10:41:06 +00:00
break ;
case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE :
2001-03-28 22:17:05 +00:00
left_subframe = & encoder - > guts - > subframe_workspace [ 0 ] [ encoder - > guts - > best_subframe [ 0 ] ] ;
right_subframe = & encoder - > guts - > subframe_workspace_mid_side [ 1 ] [ encoder - > guts - > best_subframe_mid_side [ 1 ] ] ;
2001-01-25 10:41:06 +00:00
break ;
case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE :
2001-03-28 22:17:05 +00:00
left_subframe = & encoder - > guts - > subframe_workspace_mid_side [ 1 ] [ encoder - > guts - > best_subframe_mid_side [ 1 ] ] ;
right_subframe = & encoder - > guts - > subframe_workspace [ 1 ] [ encoder - > guts - > best_subframe [ 1 ] ] ;
2001-01-25 10:41:06 +00:00
break ;
case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE :
2001-03-28 22:17:05 +00:00
left_subframe = & encoder - > guts - > subframe_workspace_mid_side [ 0 ] [ encoder - > guts - > best_subframe_mid_side [ 0 ] ] ;
right_subframe = & encoder - > guts - > subframe_workspace_mid_side [ 1 ] [ encoder - > guts - > best_subframe_mid_side [ 1 ] ] ;
2001-01-25 10:41:06 +00:00
break ;
default :
assert ( 0 ) ;
}
2001-03-28 22:17:05 +00:00
switch ( channel_assignment ) {
case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT :
left_bps = encoder - > guts - > subframe_bps [ 0 ] ;
right_bps = encoder - > guts - > subframe_bps [ 1 ] ;
break ;
case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE :
left_bps = encoder - > guts - > subframe_bps [ 0 ] ;
right_bps = encoder - > guts - > subframe_bps_mid_side [ 1 ] ;
break ;
case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE :
left_bps = encoder - > guts - > subframe_bps_mid_side [ 1 ] ;
right_bps = encoder - > guts - > subframe_bps [ 1 ] ;
break ;
case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE :
left_bps = encoder - > guts - > subframe_bps_mid_side [ 0 ] ;
right_bps = encoder - > guts - > subframe_bps_mid_side [ 1 ] ;
break ;
default :
assert ( 0 ) ;
}
/* note that encoder_add_subframe_ sets the state for us in case of an error */
if ( ! encoder_add_subframe_ ( encoder , & frame_header , left_bps , left_subframe , & encoder - > guts - > frame ) )
return false ;
if ( ! encoder_add_subframe_ ( encoder , & frame_header , right_bps , right_subframe , & encoder - > guts - > frame ) )
return false ;
2001-01-25 10:41:06 +00:00
}
else {
if ( ! FLAC__frame_add_header ( & frame_header , encoder - > streamable_subset , is_last_frame , & encoder - > guts - > frame ) ) {
encoder - > state = FLAC__ENCODER_FRAMING_ERROR ;
return false ;
}
for ( channel = 0 ; channel < encoder - > channels ; channel + + ) {
2001-03-28 22:17:05 +00:00
if ( ! encoder_add_subframe_ ( encoder , & frame_header , encoder - > guts - > subframe_bps [ channel ] , & encoder - > guts - > subframe_workspace [ channel ] [ encoder - > guts - > best_subframe [ channel ] ] , & encoder - > guts - > frame ) ) {
2001-01-25 10:41:06 +00:00
/* the above function sets the state for us in case of an error */
return false ;
}
}
}
2001-01-28 09:27:27 +00:00
if ( encoder - > loose_mid_side_stereo ) {
encoder - > guts - > loose_mid_side_stereo_frame_count + + ;
if ( encoder - > guts - > loose_mid_side_stereo_frame_count > = encoder - > guts - > loose_mid_side_stereo_frames )
encoder - > guts - > loose_mid_side_stereo_frame_count = 0 ;
}
encoder - > guts - > last_channel_assignment = frame_header . channel_assignment ;
2001-01-25 10:41:06 +00:00
return true ;
}
2001-03-28 22:17:05 +00:00
bool encoder_process_subframe_ ( FLAC__Encoder * encoder , unsigned max_partition_order , bool verbatim_only , const FLAC__FrameHeader * frame_header , unsigned subframe_bps , const int32 integer_signal [ ] , const real real_signal [ ] , FLAC__Subframe * subframe [ 2 ] , int32 * residual [ 2 ] , unsigned * best_subframe , unsigned * best_bits )
2001-01-25 10:41:06 +00:00
{
real fixed_residual_bits_per_sample [ FLAC__MAX_FIXED_ORDER + 1 ] ;
real lpc_residual_bits_per_sample ;
real autoc [ FLAC__MAX_LPC_ORDER + 1 ] ;
real lp_coeff [ FLAC__MAX_LPC_ORDER ] [ FLAC__MAX_LPC_ORDER ] ;
real lpc_error [ FLAC__MAX_LPC_ORDER ] ;
unsigned min_lpc_order , max_lpc_order , lpc_order ;
unsigned min_fixed_order , max_fixed_order , guess_fixed_order , fixed_order ;
unsigned min_qlp_coeff_precision , max_qlp_coeff_precision , qlp_coeff_precision ;
unsigned rice_parameter ;
unsigned _candidate_bits , _best_bits ;
unsigned _best_subframe ;
/* verbatim subframe is the baseline against which we measure other compressed subframes */
_best_subframe = 0 ;
2001-03-28 22:17:05 +00:00
_best_bits = encoder_evaluate_verbatim_subframe_ ( integer_signal , frame_header - > blocksize , subframe_bps , subframe [ _best_subframe ] ) ;
2001-01-25 10:41:06 +00:00
if ( ! verbatim_only & & frame_header - > blocksize > = FLAC__MAX_FIXED_ORDER ) {
/* check for constant subframe */
2001-03-30 00:45:22 +00:00
if ( encoder - > guts - > use_slow )
guess_fixed_order = FLAC__fixed_compute_best_predictor_slow ( integer_signal + FLAC__MAX_FIXED_ORDER , frame_header - > blocksize - FLAC__MAX_FIXED_ORDER , fixed_residual_bits_per_sample ) ;
else
guess_fixed_order = FLAC__fixed_compute_best_predictor ( integer_signal + FLAC__MAX_FIXED_ORDER , frame_header - > blocksize - FLAC__MAX_FIXED_ORDER , fixed_residual_bits_per_sample ) ;
2001-01-25 10:41:06 +00:00
if ( fixed_residual_bits_per_sample [ 1 ] = = 0.0 ) {
/* the above means integer_signal+FLAC__MAX_FIXED_ORDER is constant, now we just have to check the warmup samples */
unsigned i , signal_is_constant = true ;
for ( i = 1 ; i < = FLAC__MAX_FIXED_ORDER ; i + + ) {
if ( integer_signal [ 0 ] ! = integer_signal [ i ] ) {
signal_is_constant = false ;
break ;
2000-12-17 19:07:46 +00:00
}
2001-01-25 10:41:06 +00:00
}
if ( signal_is_constant ) {
2001-03-28 22:17:05 +00:00
_candidate_bits = encoder_evaluate_constant_subframe_ ( integer_signal [ 0 ] , subframe_bps , subframe [ ! _best_subframe ] ) ;
2001-01-25 10:41:06 +00:00
if ( _candidate_bits < _best_bits ) {
_best_subframe = ! _best_subframe ;
_best_bits = _candidate_bits ;
2000-12-10 04:09:52 +00:00
}
}
2001-01-25 10:41:06 +00:00
}
else {
/* encode fixed */
if ( encoder - > do_exhaustive_model_search ) {
min_fixed_order = 0 ;
max_fixed_order = FLAC__MAX_FIXED_ORDER ;
}
2000-12-10 04:09:52 +00:00
else {
2001-01-25 10:41:06 +00:00
min_fixed_order = max_fixed_order = guess_fixed_order ;
}
for ( fixed_order = min_fixed_order ; fixed_order < = max_fixed_order ; fixed_order + + ) {
2001-03-28 22:17:05 +00:00
if ( fixed_residual_bits_per_sample [ fixed_order ] > = ( real ) subframe_bps )
2001-01-25 10:41:06 +00:00
continue ; /* don't even try */
2001-02-08 00:27:21 +00:00
rice_parameter = ( fixed_residual_bits_per_sample [ fixed_order ] > 0.0 ) ? ( unsigned ) ( fixed_residual_bits_per_sample [ fixed_order ] + 0.5 ) : 0 ; /* 0.5 is for rounding */
2001-04-24 22:54:07 +00:00
# ifndef FLAC__SYMMETRIC_RICE
2001-02-08 00:27:21 +00:00
rice_parameter + + ; /* to account for the signed->unsigned conversion during rice coding */
2001-03-17 01:07:00 +00:00
# endif
2001-01-25 10:41:06 +00:00
if ( rice_parameter > = ( 1u < < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN ) )
rice_parameter = ( 1u < < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN ) - 1 ;
2001-04-24 01:25:42 +00:00
_candidate_bits = encoder_evaluate_fixed_subframe_ ( integer_signal , residual [ ! _best_subframe ] , encoder - > guts - > abs_residual , encoder - > guts - > abs_residual_partition_sums , encoder - > guts - > raw_bits_per_partition , frame_header - > blocksize , subframe_bps , fixed_order , rice_parameter , max_partition_order , subframe [ ! _best_subframe ] ) ;
2001-01-25 10:41:06 +00:00
if ( _candidate_bits < _best_bits ) {
_best_subframe = ! _best_subframe ;
_best_bits = _candidate_bits ;
2000-12-10 04:09:52 +00:00
}
2001-01-25 10:41:06 +00:00
}
2000-12-10 04:09:52 +00:00
2001-01-25 10:41:06 +00:00
/* encode lpc */
if ( encoder - > max_lpc_order > 0 ) {
if ( encoder - > max_lpc_order > = frame_header - > blocksize )
max_lpc_order = frame_header - > blocksize - 1 ;
else
max_lpc_order = encoder - > max_lpc_order ;
if ( max_lpc_order > 0 ) {
FLAC__lpc_compute_autocorrelation ( real_signal , frame_header - > blocksize , max_lpc_order + 1 , autoc ) ;
2001-02-28 23:45:15 +00:00
/* 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 ) {
FLAC__lpc_compute_lp_coefficients ( autoc , max_lpc_order , lp_coeff , lpc_error ) ;
if ( encoder - > do_exhaustive_model_search ) {
min_lpc_order = 1 ;
}
else {
2001-03-28 22:17:05 +00:00
unsigned guess_lpc_order = FLAC__lpc_compute_best_order ( lpc_error , max_lpc_order , frame_header - > blocksize , subframe_bps ) ;
2001-02-28 23:45:15 +00:00
min_lpc_order = max_lpc_order = guess_lpc_order ;
}
if ( encoder - > do_qlp_coeff_prec_search ) {
min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION ;
2001-03-28 22:17:05 +00:00
max_qlp_coeff_precision = min ( 32 - subframe_bps - 1 , ( 1u < < FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN ) - 1 ) ;
2001-02-28 23:45:15 +00:00
}
else {
min_qlp_coeff_precision = max_qlp_coeff_precision = encoder - > qlp_coeff_precision ;
}
for ( lpc_order = min_lpc_order ; lpc_order < = max_lpc_order ; lpc_order + + ) {
lpc_residual_bits_per_sample = FLAC__lpc_compute_expected_bits_per_residual_sample ( lpc_error [ lpc_order - 1 ] , frame_header - > blocksize - lpc_order ) ;
2001-03-28 22:17:05 +00:00
if ( lpc_residual_bits_per_sample > = ( real ) subframe_bps )
2001-02-28 23:45:15 +00:00
continue ; /* don't even try */
rice_parameter = ( lpc_residual_bits_per_sample > 0.0 ) ? ( unsigned ) ( lpc_residual_bits_per_sample + 0.5 ) : 0 ; /* 0.5 is for rounding */
2001-04-24 22:54:07 +00:00
# ifndef FLAC__SYMMETRIC_RICE
2001-02-28 23:45:15 +00:00
rice_parameter + + ; /* to account for the signed->unsigned conversion during rice coding */
2001-03-17 01:07:00 +00:00
# endif
2001-02-28 23:45:15 +00:00
if ( rice_parameter > = ( 1u < < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN ) )
rice_parameter = ( 1u < < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN ) - 1 ;
for ( qlp_coeff_precision = min_qlp_coeff_precision ; qlp_coeff_precision < = max_qlp_coeff_precision ; qlp_coeff_precision + + ) {
2001-04-24 01:25:42 +00:00
_candidate_bits = encoder_evaluate_lpc_subframe_ ( integer_signal , residual [ ! _best_subframe ] , encoder - > guts - > abs_residual , encoder - > guts - > abs_residual_partition_sums , encoder - > guts - > raw_bits_per_partition , lp_coeff [ lpc_order - 1 ] , frame_header - > blocksize , subframe_bps , lpc_order , qlp_coeff_precision , rice_parameter , max_partition_order , subframe [ ! _best_subframe ] ) ;
2001-02-28 23:45:15 +00:00
if ( _candidate_bits > 0 ) { /* if == 0, there was a problem quantizing the lpcoeffs */
if ( _candidate_bits < _best_bits ) {
_best_subframe = ! _best_subframe ;
_best_bits = _candidate_bits ;
}
2000-12-10 04:09:52 +00:00
}
}
}
}
}
}
}
2001-01-25 10:41:06 +00:00
}
2000-12-10 04:09:52 +00:00
2001-01-25 10:41:06 +00:00
* best_subframe = _best_subframe ;
* best_bits = _best_bits ;
return true ;
}
2001-03-28 22:17:05 +00:00
bool encoder_add_subframe_ ( FLAC__Encoder * encoder , const FLAC__FrameHeader * frame_header , unsigned subframe_bps , const FLAC__Subframe * subframe , FLAC__BitBuffer * frame )
2001-01-25 10:41:06 +00:00
{
switch ( subframe - > type ) {
case FLAC__SUBFRAME_TYPE_CONSTANT :
2001-03-28 22:17:05 +00:00
if ( ! FLAC__subframe_add_constant ( & ( subframe - > data . constant ) , subframe_bps , subframe - > wasted_bits , frame ) ) {
2001-01-25 10:41:06 +00:00
encoder - > state = FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING ;
return false ;
}
break ;
case FLAC__SUBFRAME_TYPE_FIXED :
2001-03-28 22:17:05 +00:00
if ( ! FLAC__subframe_add_fixed ( & ( subframe - > data . fixed ) , frame_header - > blocksize - subframe - > data . fixed . order , subframe_bps , subframe - > wasted_bits , frame ) ) {
2001-01-25 10:41:06 +00:00
encoder - > state = FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING ;
return false ;
}
break ;
case FLAC__SUBFRAME_TYPE_LPC :
2001-03-28 22:17:05 +00:00
if ( ! FLAC__subframe_add_lpc ( & ( subframe - > data . lpc ) , frame_header - > blocksize - subframe - > data . lpc . order , subframe_bps , subframe - > wasted_bits , frame ) ) {
2001-01-25 10:41:06 +00:00
encoder - > state = FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING ;
return false ;
}
break ;
case FLAC__SUBFRAME_TYPE_VERBATIM :
2001-03-28 22:17:05 +00:00
if ( ! FLAC__subframe_add_verbatim ( & ( subframe - > data . verbatim ) , frame_header - > blocksize , subframe_bps , subframe - > wasted_bits , frame ) ) {
2001-01-25 10:41:06 +00:00
encoder - > state = FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING ;
return false ;
}
break ;
default :
assert ( 0 ) ;
2000-12-10 04:09:52 +00:00
}
return true ;
}
2001-03-28 22:17:05 +00:00
unsigned encoder_evaluate_constant_subframe_ ( const int32 signal , unsigned subframe_bps , FLAC__Subframe * subframe )
2000-12-10 04:09:52 +00:00
{
subframe - > type = FLAC__SUBFRAME_TYPE_CONSTANT ;
subframe - > data . constant . value = signal ;
2001-03-28 22:17:05 +00:00
return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + subframe_bps ;
2000-12-10 04:09:52 +00:00
}
2001-04-24 01:25:42 +00:00
unsigned encoder_evaluate_fixed_subframe_ ( const int32 signal [ ] , int32 residual [ ] , uint32 abs_residual [ ] , uint32 abs_residual_partition_sums [ ] , unsigned raw_bits_per_partition [ ] , unsigned blocksize , unsigned subframe_bps , unsigned order , unsigned rice_parameter , unsigned max_partition_order , FLAC__Subframe * subframe )
2000-12-10 04:09:52 +00:00
{
unsigned i , residual_bits ;
const unsigned residual_samples = blocksize - order ;
FLAC__fixed_compute_residual ( signal + order , residual_samples , order , residual ) ;
subframe - > type = FLAC__SUBFRAME_TYPE_FIXED ;
subframe - > data . fixed . entropy_coding_method . type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE ;
2001-01-25 10:41:06 +00:00
subframe - > data . fixed . residual = residual ;
2000-12-10 04:09:52 +00:00
2001-04-24 01:25:42 +00:00
residual_bits = encoder_find_best_partition_order_ ( residual , abs_residual , abs_residual_partition_sums , raw_bits_per_partition , residual_samples , order , rice_parameter , max_partition_order , & 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 ) ;
2000-12-10 04:09:52 +00:00
subframe - > data . fixed . order = order ;
for ( i = 0 ; i < order ; i + + )
subframe - > data . fixed . warmup [ i ] = signal [ i ] ;
2001-03-28 22:17:05 +00:00
return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + ( order * subframe_bps ) + residual_bits ;
2000-12-10 04:09:52 +00:00
}
2001-04-24 01:25:42 +00:00
unsigned encoder_evaluate_lpc_subframe_ ( const int32 signal [ ] , int32 residual [ ] , uint32 abs_residual [ ] , uint32 abs_residual_partition_sums [ ] , unsigned raw_bits_per_partition [ ] , const real lp_coeff [ ] , unsigned blocksize , unsigned subframe_bps , unsigned order , unsigned qlp_coeff_precision , unsigned rice_parameter , unsigned max_partition_order , FLAC__Subframe * subframe )
2000-12-10 04:09:52 +00:00
{
int32 qlp_coeff [ FLAC__MAX_LPC_ORDER ] ;
unsigned i , residual_bits ;
int quantization , ret ;
const unsigned residual_samples = blocksize - order ;
2001-03-28 22:17:05 +00:00
ret = FLAC__lpc_quantize_coefficients ( lp_coeff , order , qlp_coeff_precision , subframe_bps , qlp_coeff , & quantization ) ;
2000-12-10 04:09:52 +00:00
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 */
FLAC__lpc_compute_residual_from_qlp_coefficients ( signal + order , residual_samples , qlp_coeff , order , quantization , residual ) ;
subframe - > type = FLAC__SUBFRAME_TYPE_LPC ;
subframe - > data . lpc . entropy_coding_method . type = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE ;
2001-01-25 10:41:06 +00:00
subframe - > data . lpc . residual = residual ;
2000-12-10 04:09:52 +00:00
2001-04-24 01:25:42 +00:00
residual_bits = encoder_find_best_partition_order_ ( residual , abs_residual , abs_residual_partition_sums , raw_bits_per_partition , residual_samples , order , rice_parameter , max_partition_order , & 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 ) ;
2000-12-10 04:09:52 +00:00
subframe - > data . lpc . order = order ;
subframe - > data . lpc . qlp_coeff_precision = qlp_coeff_precision ;
subframe - > data . lpc . quantization_level = quantization ;
memcpy ( subframe - > data . lpc . qlp_coeff , qlp_coeff , sizeof ( int32 ) * FLAC__MAX_LPC_ORDER ) ;
for ( i = 0 ; i < order ; i + + )
subframe - > data . lpc . warmup [ i ] = signal [ i ] ;
2001-03-28 22:17:05 +00:00
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 ;
2000-12-10 04:09:52 +00:00
}
2001-03-28 22:17:05 +00:00
unsigned encoder_evaluate_verbatim_subframe_ ( const int32 signal [ ] , unsigned blocksize , unsigned subframe_bps , FLAC__Subframe * subframe )
2000-12-10 04:09:52 +00:00
{
subframe - > type = FLAC__SUBFRAME_TYPE_VERBATIM ;
2001-01-25 10:41:06 +00:00
subframe - > data . verbatim . data = signal ;
2001-03-28 22:17:05 +00:00
return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + ( blocksize * subframe_bps ) ;
2000-12-10 04:09:52 +00:00
}
2001-04-24 01:25:42 +00:00
unsigned encoder_find_best_partition_order_ ( const int32 residual [ ] , uint32 abs_residual [ ] , uint32 abs_residual_partition_sums [ ] , unsigned raw_bits_per_partition [ ] , unsigned residual_samples , unsigned predictor_order , unsigned rice_parameter , unsigned max_partition_order , unsigned * best_partition_order , unsigned best_parameters [ ] , unsigned best_raw_bits [ ] )
2000-12-10 04:09:52 +00:00
{
2001-04-18 02:20:52 +00:00
int32 r ;
2001-04-24 22:54:07 +00:00
# if (defined FLAC__PRECOMPUTE_PARTITION_SUMS) || (defined FLAC__SEARCH_FOR_ESCAPES)
2001-04-18 22:59:25 +00:00
unsigned sum ;
2001-04-24 01:25:42 +00:00
int partition_order ;
2001-04-18 22:59:25 +00:00
# else
unsigned partition_order ;
# endif
2000-12-10 04:09:52 +00:00
unsigned residual_bits , best_residual_bits = 0 ;
2001-04-18 22:59:25 +00:00
unsigned residual_sample ;
2001-04-12 22:22:34 +00:00
unsigned best_parameters_index = 0 , parameters [ 2 ] [ 1 < < FLAC__MAX_RICE_PARTITION_ORDER ] , raw_bits [ 2 ] [ 1 < < FLAC__MAX_RICE_PARTITION_ORDER ] ;
2001-04-18 02:20:52 +00:00
/* compute abs(residual) for use later */
for ( residual_sample = 0 ; residual_sample < residual_samples ; residual_sample + + ) {
r = residual [ residual_sample ] ;
abs_residual [ residual_sample ] = ( uint32 ) ( r < 0 ? - r : r ) ;
}
2001-04-24 22:54:07 +00:00
# if (defined FLAC__PRECOMPUTE_PARTITION_SUMS) || (defined FLAC__SEARCH_FOR_ESCAPES)
2001-04-24 01:25:42 +00:00
max_partition_order = encoder_precompute_partition_info_ ( residual , abs_residual , abs_residual_partition_sums , raw_bits_per_partition , residual_samples , predictor_order , max_partition_order ) ;
2001-04-18 02:20:52 +00:00
for ( partition_order = ( int ) max_partition_order , sum = 0 ; partition_order > = 0 ; partition_order - - ) {
2001-04-24 01:25:42 +00:00
if ( ! encoder_set_partitioned_rice_ ( abs_residual , abs_residual_partition_sums + sum , raw_bits_per_partition + sum , residual_samples , predictor_order , rice_parameter , ( unsigned ) partition_order , parameters [ ! best_parameters_index ] , raw_bits [ ! best_parameters_index ] , & residual_bits ) ) {
assert ( 0 ) ; /* encoder_precompute_partition_info_ should keep this from ever happening */
2001-04-18 02:20:52 +00:00
}
sum + = 1u < < partition_order ;
if ( best_residual_bits = = 0 | | residual_bits < best_residual_bits ) {
best_residual_bits = residual_bits ;
* best_partition_order = partition_order ;
best_parameters_index = ! best_parameters_index ;
}
}
2001-04-18 22:59:25 +00:00
# else
for ( partition_order = 0 ; partition_order < = max_partition_order ; partition_order + + ) {
2001-04-24 01:25:42 +00:00
if ( ! encoder_set_partitioned_rice_ ( abs_residual , 0 , 0 , residual_samples , predictor_order , rice_parameter , partition_order , parameters [ ! best_parameters_index ] , raw_bits [ ! best_parameters_index ] , & residual_bits ) ) {
2001-04-18 22:59:25 +00:00
assert ( best_residual_bits ! = 0 ) ;
break ;
}
if ( best_residual_bits = = 0 | | residual_bits < best_residual_bits ) {
best_residual_bits = residual_bits ;
* best_partition_order = partition_order ;
best_parameters_index = ! best_parameters_index ;
}
}
# endif
2001-04-18 02:20:52 +00:00
memcpy ( best_parameters , parameters [ best_parameters_index ] , sizeof ( unsigned ) * ( 1 < < ( * best_partition_order ) ) ) ;
memcpy ( best_raw_bits , raw_bits [ best_parameters_index ] , sizeof ( unsigned ) * ( 1 < < ( * best_partition_order ) ) ) ;
return best_residual_bits ;
}
2001-04-24 22:54:07 +00:00
# if (defined FLAC__PRECOMPUTE_PARTITION_SUMS) || (defined FLAC__SEARCH_FOR_ESCAPES)
2001-04-24 01:25:42 +00:00
unsigned encoder_precompute_partition_info_ ( const int32 residual [ ] , uint32 abs_residual [ ] , uint32 abs_residual_partition_sums [ ] , unsigned raw_bits_per_partition [ ] , unsigned residual_samples , unsigned predictor_order , unsigned max_partition_order )
2001-04-18 02:20:52 +00:00
{
int partition_order ;
2001-04-24 01:25:42 +00:00
unsigned from_partition , to_partition = 0 ;
2001-04-18 02:20:52 +00:00
const unsigned blocksize = residual_samples + predictor_order ;
2001-01-20 01:27:55 +00:00
2001-04-24 01:25:42 +00:00
/* first do max_partition_order */
2001-04-18 02:20:52 +00:00
for ( partition_order = ( int ) max_partition_order ; partition_order > = 0 ; partition_order - - ) {
2001-04-24 22:54:07 +00:00
# ifdef FLAC__PRECOMPUTE_PARTITION_SUMS
2001-04-18 02:20:52 +00:00
uint32 abs_residual_partition_sum ;
2001-04-24 01:25:42 +00:00
# endif
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
uint32 abs_residual_partition_max ;
unsigned abs_residual_partition_max_index = 0 ; /* initialized to silence superfluous compiler warning */
# endif
uint32 abs_r ;
unsigned partition , partition_sample , partition_samples , residual_sample ;
2001-04-18 02:20:52 +00:00
const unsigned partitions = 1u < < partition_order ;
const unsigned default_partition_samples = blocksize > > partition_order ;
if ( default_partition_samples < = predictor_order ) {
assert ( max_partition_order > 0 ) ;
max_partition_order - - ;
}
else {
for ( partition = residual_sample = 0 ; partition < partitions ; partition + + ) {
partition_samples = default_partition_samples ;
if ( partition = = 0 )
partition_samples - = predictor_order ;
2001-04-24 22:54:07 +00:00
# ifdef FLAC__PRECOMPUTE_PARTITION_SUMS
2001-04-18 02:20:52 +00:00
abs_residual_partition_sum = 0 ;
2001-04-24 01:25:42 +00:00
# endif
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
abs_residual_partition_max = 0 ;
# endif
for ( partition_sample = 0 ; partition_sample < partition_samples ; partition_sample + + ) {
abs_r = abs_residual [ residual_sample ] ;
2001-04-24 22:54:07 +00:00
# ifdef FLAC__PRECOMPUTE_PARTITION_SUMS
2001-04-24 01:25:42 +00:00
abs_residual_partition_sum + = abs_r ; /* @@@ this can overflow with small max_partition_order and (large blocksizes or bits-per-sample), FIX! */
# endif
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
if ( abs_r > abs_residual_partition_max ) {
abs_residual_partition_max = abs_r ;
abs_residual_partition_max_index = residual_sample ;
}
# endif
residual_sample + + ;
}
2001-04-24 22:54:07 +00:00
# ifdef FLAC__PRECOMPUTE_PARTITION_SUMS
2001-04-18 02:20:52 +00:00
abs_residual_partition_sums [ partition ] = abs_residual_partition_sum ;
2001-04-24 01:25:42 +00:00
# endif
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
if ( abs_residual_partition_max > 0 )
raw_bits_per_partition [ partition ] = FLAC__bitmath_silog2 ( residual [ abs_residual_partition_max_index ] ) ;
else
raw_bits_per_partition [ partition ] = FLAC__bitmath_silog2 ( 0 ) ;
# endif
2001-04-18 02:20:52 +00:00
}
2001-04-24 01:25:42 +00:00
to_partition = partitions ;
2001-04-18 02:20:52 +00:00
break ;
}
}
2001-04-18 02:28:11 +00:00
2001-04-24 01:25:42 +00:00
/* now merge for lower orders */
for ( from_partition = 0 ; partition_order > = 0 ; partition_order - - ) {
2001-04-24 22:54:07 +00:00
# ifdef FLAC__PRECOMPUTE_PARTITION_SUMS
2001-04-18 02:20:52 +00:00
uint32 s ;
2001-04-24 01:25:42 +00:00
# endif
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
unsigned m ;
# endif
unsigned i ;
2001-04-18 02:20:52 +00:00
const unsigned partitions = 1u < < partition_order ;
for ( i = 0 ; i < partitions ; i + + ) {
2001-04-24 22:54:07 +00:00
# ifdef FLAC__PRECOMPUTE_PARTITION_SUMS
2001-04-24 01:25:42 +00:00
s = abs_residual_partition_sums [ from_partition ] ;
# endif
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
m = raw_bits_per_partition [ from_partition ] ;
# endif
from_partition + + ;
2001-04-24 22:54:07 +00:00
# ifdef FLAC__PRECOMPUTE_PARTITION_SUMS
2001-04-24 01:25:42 +00:00
abs_residual_partition_sums [ to_partition ] = s + abs_residual_partition_sums [ from_partition ] ;
# endif
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
raw_bits_per_partition [ to_partition ] = max ( m , raw_bits_per_partition [ from_partition ] ) ;
# endif
from_partition + + ;
to_partition + + ;
2001-04-18 02:20:52 +00:00
}
}
2001-04-18 02:28:11 +00:00
return max_partition_order ;
2000-12-10 04:09:52 +00:00
}
2001-04-18 22:59:25 +00:00
# endif
2000-12-10 04:09:52 +00:00
2001-03-20 22:55:50 +00:00
# ifdef VARIABLE_RICE_BITS
# undef VARIABLE_RICE_BITS
2001-03-17 01:07:00 +00:00
# endif
2001-03-20 22:55:50 +00:00
# define VARIABLE_RICE_BITS(value, parameter) ((value) >> (parameter))
2001-01-20 01:27:55 +00:00
2001-04-24 01:25:42 +00:00
bool encoder_set_partitioned_rice_ ( const uint32 abs_residual [ ] , const uint32 abs_residual_partition_sums [ ] , const unsigned raw_bits_per_partition [ ] , const unsigned residual_samples , const unsigned predictor_order , unsigned rice_parameter , const unsigned partition_order , unsigned parameters [ ] , unsigned raw_bits [ ] , unsigned * bits )
2000-12-10 04:09:52 +00:00
{
2001-04-18 22:59:25 +00:00
unsigned partition_bits ;
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
unsigned flat_bits ;
2001-04-18 22:59:25 +00:00
# endif
2001-01-06 01:24:53 +00:00
unsigned bits_ = FLAC__ENTROPY_CODING_METHOD_TYPE_LEN + FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN ;
2000-12-10 04:09:52 +00:00
2001-04-12 22:22:34 +00:00
if ( rice_parameter > = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER )
rice_parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1 ;
2000-12-10 04:09:52 +00:00
if ( partition_order = = 0 ) {
unsigned i ;
2001-03-20 22:55:50 +00:00
2001-04-12 22:22:34 +00:00
partition_bits = 0 ;
2001-03-20 22:55:50 +00:00
{
# ifdef VARIABLE_RICE_BITS
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SYMMETRIC_RICE
2001-04-12 22:22:34 +00:00
partition_bits + = ( 2 + rice_parameter ) * residual_samples ;
2001-03-17 01:07:00 +00:00
# else
2001-03-20 22:55:50 +00:00
const unsigned rice_parameter_estimate = rice_parameter - 1 ;
2001-04-12 22:22:34 +00:00
partition_bits + = ( 1 + rice_parameter ) * residual_samples ;
2001-03-17 01:07:00 +00:00
# endif
2001-01-19 20:11:59 +00:00
# endif
2001-03-20 22:55:50 +00:00
parameters [ 0 ] = rice_parameter ;
2001-04-12 22:22:34 +00:00
partition_bits + = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN ;
2001-03-20 22:55:50 +00:00
for ( i = 0 ; i < residual_samples ; i + + ) {
# ifdef VARIABLE_RICE_BITS
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SYMMETRIC_RICE
2001-04-12 22:22:34 +00:00
partition_bits + = VARIABLE_RICE_BITS ( abs_residual [ i ] , rice_parameter ) ;
2001-03-17 01:07:00 +00:00
# else
2001-04-12 22:22:34 +00:00
partition_bits + = VARIABLE_RICE_BITS ( abs_residual [ i ] , rice_parameter_estimate ) ;
2001-03-17 01:07:00 +00:00
# endif
2001-01-19 20:11:59 +00:00
# else
2001-04-12 22:22:34 +00:00
partition_bits + = FLAC__bitbuffer_rice_bits ( residual [ i ] , rice_parameter ) ; /* NOTE: we will need to pass in residual[] instead of abs_residual[] */
2001-04-18 22:59:25 +00:00
# endif
2001-04-12 22:22:34 +00:00
}
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
flat_bits = raw_bits_per_partition [ 0 ] * residual_samples ;
2001-04-12 22:22:34 +00:00
if ( flat_bits < partition_bits ) {
parameters [ 0 ] = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER ;
2001-04-24 01:25:42 +00:00
raw_bits [ 0 ] = raw_bits_per_partition [ 0 ] ;
2001-04-12 22:22:34 +00:00
partition_bits = flat_bits ;
2001-03-20 22:55:50 +00:00
}
2001-04-18 22:59:25 +00:00
# endif
2001-04-24 01:25:42 +00:00
bits_ + = partition_bits ;
2001-03-20 22:55:50 +00:00
}
2000-12-10 04:09:52 +00:00
}
else {
2001-04-18 02:20:52 +00:00
unsigned i , j , k ;
2001-01-06 01:24:53 +00:00
unsigned mean , parameter , partition_samples ;
2000-12-10 04:09:52 +00:00
const unsigned max_parameter = ( 1u < < FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN ) - 1 ;
2001-04-18 02:20:52 +00:00
const unsigned partitions = 1u < < partition_order ;
for ( i = j = 0 ; i < partitions ; i + + ) {
2001-04-12 22:22:34 +00:00
partition_bits = 0 ;
2000-12-10 04:09:52 +00:00
partition_samples = ( residual_samples + predictor_order ) > > partition_order ;
if ( i = = 0 ) {
if ( partition_samples < = predictor_order )
return false ;
else
partition_samples - = predictor_order ;
}
mean = partition_samples > > 1 ;
2001-04-24 22:54:07 +00:00
# ifdef FLAC__PRECOMPUTE_PARTITION_SUMS
2001-04-18 02:20:52 +00:00
mean + = abs_residual_partition_sums [ i ] ;
2001-04-24 01:25:42 +00:00
# else
for ( k = 0 ; k < partition_samples ; j + + , k + + )
mean + = abs_residual [ j ] ;
j - = k ;
# endif
2000-12-10 04:09:52 +00:00
mean / = partition_samples ;
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SYMMETRIC_RICE
2001-03-20 22:55:50 +00:00
/* calc parameter = floor(log2(mean)) */
2001-01-06 01:24:53 +00:00
parameter = 0 ;
2001-03-20 22:55:50 +00:00
mean > > = 1 ;
2001-01-06 01:24:53 +00:00
while ( mean ) {
parameter + + ;
mean > > = 1 ;
}
2001-03-17 01:07:00 +00:00
# else
/* calc parameter = floor(log2(mean)) + 1 */
parameter = 0 ;
while ( mean ) {
parameter + + ;
mean > > = 1 ;
}
# endif
2000-12-10 04:09:52 +00:00
if ( parameter > max_parameter )
parameter = max_parameter ;
2001-04-12 22:22:34 +00:00
if ( parameter > = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER )
parameter = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER - 1 ;
2000-12-10 04:09:52 +00:00
parameters [ i ] = parameter ;
2001-04-12 22:22:34 +00:00
partition_bits + = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN ;
2001-03-20 22:55:50 +00:00
# ifdef VARIABLE_RICE_BITS
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SYMMETRIC_RICE
2001-04-12 22:22:34 +00:00
partition_bits + = ( 2 + parameter ) * partition_samples ;
2001-03-17 01:07:00 +00:00
# else
2001-04-12 22:22:34 +00:00
partition_bits + = ( 1 + parameter ) * partition_samples ;
2001-03-20 22:55:50 +00:00
- - parameter ;
2001-03-17 01:07:00 +00:00
# endif
2001-04-18 22:59:25 +00:00
# endif
2001-04-18 02:20:52 +00:00
for ( k = 0 ; k < partition_samples ; j + + , k + + ) {
2001-03-20 22:55:50 +00:00
# ifdef VARIABLE_RICE_BITS
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SYMMETRIC_RICE
2001-04-12 22:22:34 +00:00
partition_bits + = VARIABLE_RICE_BITS ( abs_residual [ j ] , parameter ) ;
2001-03-17 01:07:00 +00:00
# else
2001-04-12 22:22:34 +00:00
partition_bits + = VARIABLE_RICE_BITS ( abs_residual [ j ] , parameter ) ;
2001-03-17 01:07:00 +00:00
# endif
2001-01-19 20:11:59 +00:00
# else
2001-04-12 22:22:34 +00:00
partition_bits + = FLAC__bitbuffer_rice_bits ( residual [ j ] , parameter ) ; /* NOTE: we will need to pass in residual[] instead of abs_residual[] */
2001-04-18 22:59:25 +00:00
# endif
2001-04-12 22:22:34 +00:00
}
2001-04-24 22:54:07 +00:00
# ifdef FLAC__SEARCH_FOR_ESCAPES
2001-04-24 01:25:42 +00:00
flat_bits = raw_bits_per_partition [ i ] * partition_samples ;
2001-04-12 22:22:34 +00:00
if ( flat_bits < partition_bits ) {
parameters [ i ] = FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER ;
2001-04-24 01:25:42 +00:00
raw_bits [ i ] = raw_bits_per_partition [ i ] ;
2001-04-12 22:22:34 +00:00
partition_bits = flat_bits ;
}
2001-04-18 22:59:25 +00:00
# endif
2001-04-12 22:22:34 +00:00
bits_ + = partition_bits ;
2000-12-10 04:09:52 +00:00
}
}
* bits = bits_ ;
return true ;
}
2001-03-27 22:22:27 +00:00
static unsigned encoder_get_wasted_bits_ ( int32 signal [ ] , unsigned samples )
{
unsigned i , shift ;
int32 x = 0 ;
for ( i = 0 ; i < samples & & ! ( x & 1 ) ; i + + )
x | = signal [ i ] ;
if ( x = = 0 ) {
shift = 0 ;
}
else {
for ( shift = 0 ; ! ( x & 1 ) ; shift + + )
x > > = 1 ;
}
if ( shift > 0 ) {
for ( i = 0 ; i < samples ; i + + )
signal [ i ] > > = shift ;
}
return shift ;
}