mirror of
https://github.com/claunia/flac.git
synced 2025-12-16 18:54:26 +00:00
update for new format changes: frame crc-16, wasted bits field, longer sync code, longer blocksize code
This commit is contained in:
@@ -162,16 +162,19 @@ extern const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /* = 5 bits */
|
|||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* 8: subframe type
|
* 1: zero pad, to prevent sync-fooling string of 1s (use to check for erroneous sync)
|
||||||
* xxxxxxx1: invalid, to prevent sync-fooling string of 1s (use to check for erroneous sync)
|
* 6: subframe type
|
||||||
* 00000000: constant value
|
* 000000: constant value
|
||||||
* 00000010: verbatim
|
* 000001: verbatim
|
||||||
* 000001x0: reserved
|
* 00001x: reserved
|
||||||
* 00001xx0: reserved
|
* 0001xx: reserved
|
||||||
* 0001xxx0: fixed predictor, xxx=order <= 4, else reserved
|
* 001xxx: fixed predictor, xxx=order <= 4, else reserved
|
||||||
* 001xxxx0: reserved
|
* 01xxxx: reserved
|
||||||
* 01xxxxx0: lpc, xxxxx=order-1
|
* 1xxxxx: lpc, xxxxx=order-1
|
||||||
* 1xxxxxxx: invalid, to prevent sync-fooling string of 1s (use to check for erroneous sync)
|
* 1: 'wasted bits' flag
|
||||||
|
* 0: no wasted bits in source subblock
|
||||||
|
* 1: all samples in source subblock contain n 0 least significant bits. n-1 follows, unary coded, i.e. n=3, 001 follows, n=7, 0000001 follows.
|
||||||
|
* ?: unary coded (n-1)
|
||||||
* ?: subframe-specific data (c.f. FLAC__Subframe_*)
|
* ?: subframe-specific data (c.f. FLAC__Subframe_*)
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -182,13 +185,17 @@ typedef struct {
|
|||||||
FLAC__Subframe_LPC lpc;
|
FLAC__Subframe_LPC lpc;
|
||||||
FLAC__Subframe_Verbatim verbatim;
|
FLAC__Subframe_Verbatim verbatim;
|
||||||
} data;
|
} data;
|
||||||
|
unsigned wasted_bits;
|
||||||
} FLAC__Subframe;
|
} FLAC__Subframe;
|
||||||
|
|
||||||
extern const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BITS; /* = 0x00 */
|
extern const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN; /* = 1 bit */
|
||||||
extern const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BITS; /* = 0x02 */
|
extern const unsigned FLAC__SUBFRAME_TYPE_LEN; /* = 6 bits */
|
||||||
extern const unsigned FLAC__SUBFRAME_TYPE_FIXED_BITS; /* = 0x10 */
|
extern const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /* = 1 bit */
|
||||||
extern const unsigned FLAC__SUBFRAME_TYPE_LPC_BITS; /* = 0x40 */
|
|
||||||
extern const unsigned FLAC__SUBFRAME_TYPE_LEN; /* = 8 bits */
|
extern const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK; /* = 0x00 */
|
||||||
|
extern const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK; /* = 0x02 */
|
||||||
|
extern const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK; /* = 0x10 */
|
||||||
|
extern const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK; /* = 0x40 */
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
@@ -209,13 +216,17 @@ extern const char *FLAC__ChannelAssignmentString[];
|
|||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* 9: sync code '111111110'
|
* 14: sync code '11111111111110'
|
||||||
* 3: blocksize in samples
|
+ 2: reserved
|
||||||
* 000: get from stream header => implies constant blocksize throughout stream
|
+ 00: currently required value
|
||||||
* 001: 192 samples (AES/EBU) => implies constant blocksize throughout stream
|
+ 01-11: reserved
|
||||||
* 010-101: 576 * (2^(2-n)) samples, i.e. 576/1152/2304/4608 => implies constant blocksize throughout stream
|
* 4: blocksize in samples
|
||||||
* 110: get 8 bit (blocksize-1) from end of header => variable blocksize throughout stream unless it's the last frame
|
* 0000: get from stream header => implies constant blocksize throughout stream
|
||||||
* 111: get 16 bit (blocksize-1) from end of header => variable blocksize throughout stream unless it's the last frame
|
* 0001: 192 samples (AES/EBU) => implies constant blocksize throughout stream
|
||||||
|
* 0010-0101: 576 * (2^(n-2)) samples, i.e. 576/1152/2304/4608 => implies constant blocksize throughout stream
|
||||||
|
* 0110: get 8 bit (blocksize-1) from end of header => possibly variable blocksize throughout stream unless it's the last frame
|
||||||
|
* 0111: get 16 bit (blocksize-1) from end of header => possibly variable blocksize throughout stream unless it's the last frame
|
||||||
|
* 1000-1111: 256 * (2^(n-8)) samples, i.e. 256/512/1024/2048/4096/8192/16384/32768 => implies constant blocksize throughout stream
|
||||||
* 4: sample rate:
|
* 4: sample rate:
|
||||||
* 0000: get from stream header
|
* 0000: get from stream header
|
||||||
* 0001-0011: reserved
|
* 0001-0011: reserved
|
||||||
@@ -267,20 +278,33 @@ typedef struct {
|
|||||||
uint32 frame_number;
|
uint32 frame_number;
|
||||||
uint64 sample_number;
|
uint64 sample_number;
|
||||||
} number;
|
} number;
|
||||||
|
uint8 crc;
|
||||||
} FLAC__FrameHeader;
|
} FLAC__FrameHeader;
|
||||||
|
|
||||||
extern const unsigned FLAC__FRAME_HEADER_SYNC; /* = 0x1fe */
|
extern const unsigned FLAC__FRAME_HEADER_SYNC; /* = 0x3ffe */
|
||||||
extern const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /* = 9 bits */
|
extern const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /* = 14 bits */
|
||||||
extern const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /* = 3 bits */
|
extern const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /* = 2 bits */
|
||||||
|
extern const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /* = 4 bits */
|
||||||
extern const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /* = 4 bits */
|
extern const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /* = 4 bits */
|
||||||
extern const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /* = 4 bits */
|
extern const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /* = 4 bits */
|
||||||
extern const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN; /* = 3 bits */
|
extern const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN; /* = 3 bits */
|
||||||
extern const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN; /* = 1 bit */
|
extern const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN; /* = 1 bit */
|
||||||
extern const unsigned FLAC__FRAME_HEADER_CRC8_LEN; /* = 8 bits */
|
extern const unsigned FLAC__FRAME_HEADER_CRC_LEN; /* = 8 bits */
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* 16: CRC-16 (polynomial = ) of everything before the crc, back to and including the frame header sync code
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint16 crc;
|
||||||
|
} FLAC__FrameFooter;
|
||||||
|
|
||||||
|
extern const unsigned FLAC__FRAME_FOOTER_CRC_LEN; /* = 16 bits */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FLAC__FrameHeader header;
|
FLAC__FrameHeader header;
|
||||||
FLAC__Subframe subframes[FLAC__MAX_CHANNELS];
|
FLAC__Subframe subframes[FLAC__MAX_CHANNELS];
|
||||||
|
FLAC__FrameFooter footer;
|
||||||
} FLAC__Frame;
|
} FLAC__Frame;
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <string.h> /* for memcpy() */
|
#include <string.h> /* for memcpy() */
|
||||||
#include "FLAC/encoder.h"
|
#include "FLAC/encoder.h"
|
||||||
#include "private/bitbuffer.h"
|
#include "private/bitbuffer.h"
|
||||||
|
#include "private/crc.h"
|
||||||
#include "private/encoder_framing.h"
|
#include "private/encoder_framing.h"
|
||||||
#include "private/fixed.h"
|
#include "private/fixed.h"
|
||||||
#include "private/lpc.h"
|
#include "private/lpc.h"
|
||||||
@@ -308,6 +309,7 @@ FLAC__EncoderState FLAC__encoder_init(FLAC__Encoder *encoder, FLAC__EncoderWrite
|
|||||||
return encoder->state = FLAC__ENCODER_INVALID_QLP_COEFF_PRECISION;
|
return encoder->state = FLAC__ENCODER_INVALID_QLP_COEFF_PRECISION;
|
||||||
|
|
||||||
if(encoder->streamable_subset) {
|
if(encoder->streamable_subset) {
|
||||||
|
//@@@ add check for blocksize here
|
||||||
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)
|
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;
|
return encoder->state = FLAC__ENCODER_NOT_STREAMABLE;
|
||||||
if(encoder->sample_rate > 655350)
|
if(encoder->sample_rate > 655350)
|
||||||
@@ -593,11 +595,16 @@ bool encoder_process_frame_(FLAC__Encoder *encoder, bool is_last_frame)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CRC-16 the whole thing
|
||||||
|
*/
|
||||||
|
assert(encoder->guts->frame.bits == 0); /* assert that we're byte-aligned */
|
||||||
|
assert(encoder->guts->frame.total_consumed_bits == 0); /* assert that no reading of the buffer was done */
|
||||||
|
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
|
* Write it
|
||||||
*/
|
*/
|
||||||
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, encoder->blocksize, encoder->guts->current_frame_number, encoder->guts->client_data) != FLAC__ENCODER_WRITE_OK) {
|
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) {
|
||||||
encoder->state = FLAC__ENCODER_FATAL_ERROR_WHILE_WRITING;
|
encoder->state = FLAC__ENCODER_FATAL_ERROR_WHILE_WRITING;
|
||||||
return false;
|
return false;
|
||||||
@@ -956,7 +963,7 @@ unsigned encoder_evaluate_constant_subframe_(const int32 signal, unsigned bits_p
|
|||||||
subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT;
|
subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT;
|
||||||
subframe->data.constant.value = signal;
|
subframe->data.constant.value = signal;
|
||||||
|
|
||||||
return FLAC__SUBFRAME_TYPE_LEN + bits_per_sample;
|
return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + bits_per_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[], uint32 abs_residual[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned rice_parameter, unsigned max_partition_order, FLAC__Subframe *subframe)
|
unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[], uint32 abs_residual[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned rice_parameter, unsigned max_partition_order, FLAC__Subframe *subframe)
|
||||||
@@ -977,7 +984,7 @@ unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[]
|
|||||||
for(i = 0; i < order; i++)
|
for(i = 0; i < order; i++)
|
||||||
subframe->data.fixed.warmup[i] = signal[i];
|
subframe->data.fixed.warmup[i] = signal[i];
|
||||||
|
|
||||||
return FLAC__SUBFRAME_TYPE_LEN + (order * bits_per_sample) + residual_bits;
|
return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + (order * bits_per_sample) + residual_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[], uint32 abs_residual[], const real lp_coeff[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned max_partition_order, FLAC__Subframe *subframe)
|
unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[], uint32 abs_residual[], const real lp_coeff[], unsigned blocksize, unsigned bits_per_sample, unsigned order, unsigned qlp_coeff_precision, unsigned rice_parameter, unsigned max_partition_order, FLAC__Subframe *subframe)
|
||||||
@@ -1007,7 +1014,7 @@ unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[],
|
|||||||
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];
|
||||||
|
|
||||||
return FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN + FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN + (order * (qlp_coeff_precision + bits_per_sample)) + 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 + bits_per_sample)) + residual_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned encoder_evaluate_verbatim_subframe_(const int32 signal[], unsigned blocksize, unsigned bits_per_sample, FLAC__Subframe *subframe)
|
unsigned encoder_evaluate_verbatim_subframe_(const int32 signal[], unsigned blocksize, unsigned bits_per_sample, FLAC__Subframe *subframe)
|
||||||
@@ -1016,7 +1023,7 @@ unsigned encoder_evaluate_verbatim_subframe_(const int32 signal[], unsigned bloc
|
|||||||
|
|
||||||
subframe->data.verbatim.data = signal;
|
subframe->data.verbatim.data = signal;
|
||||||
|
|
||||||
return FLAC__SUBFRAME_TYPE_LEN + (blocksize * bits_per_sample);
|
return FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN + (blocksize * bits_per_sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned encoder_find_best_partition_order_(const int32 residual[], uint32 abs_residual[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned max_partition_order, unsigned *best_partition_order, unsigned best_parameters[])
|
unsigned encoder_find_best_partition_order_(const int32 residual[], uint32 abs_residual[], unsigned residual_samples, unsigned predictor_order, unsigned rice_parameter, unsigned max_partition_order, unsigned *best_partition_order, unsigned best_parameters[])
|
||||||
|
|||||||
@@ -90,24 +90,35 @@ bool FLAC__add_metadata_block(const FLAC__StreamMetaData *metadata, FLAC__BitBuf
|
|||||||
|
|
||||||
bool FLAC__frame_add_header(const FLAC__FrameHeader *header, bool streamable_subset, bool is_last_block, FLAC__BitBuffer *bb)
|
bool FLAC__frame_add_header(const FLAC__FrameHeader *header, bool streamable_subset, bool is_last_block, FLAC__BitBuffer *bb)
|
||||||
{
|
{
|
||||||
unsigned u, crc_start, blocksize_hint, sample_rate_hint;
|
unsigned u, crc8_start, blocksize_hint, sample_rate_hint;
|
||||||
byte crc;
|
byte crc8;
|
||||||
|
|
||||||
assert(bb->bits == 0); /* assert that we're byte-aligned before writing */
|
assert(bb->bits == 0); /* assert that we're byte-aligned before writing */
|
||||||
|
|
||||||
crc_start = bb->bytes;
|
crc8_start = bb->bytes;
|
||||||
|
|
||||||
if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN))
|
if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if(!FLAC__bitbuffer_write_raw_uint32(bb, 0, FLAC__FRAME_HEADER_RESERVED_LEN))
|
||||||
|
return false;
|
||||||
|
|
||||||
assert(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE);
|
assert(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE);
|
||||||
blocksize_hint = 0;
|
blocksize_hint = 0;
|
||||||
switch(header->blocksize) {
|
switch(header->blocksize) {
|
||||||
case 192: u = 1; break;
|
case 192: u = 1; break;
|
||||||
case 576: u = 2; break;
|
case 576: u = 2; break;
|
||||||
case 1152: u = 3; break;
|
case 1152: u = 3; break;
|
||||||
case 2304: u = 4; break;
|
case 2304: u = 4; break;
|
||||||
case 4608: u = 5; break;
|
case 4608: u = 5; break;
|
||||||
|
case 256: u = 8; break;
|
||||||
|
case 512: u = 9; break;
|
||||||
|
case 1024: u = 10; break;
|
||||||
|
case 2048: u = 11; break;
|
||||||
|
case 4096: u = 12; break;
|
||||||
|
case 8192: u = 13; break;
|
||||||
|
case 16384: u = 14; break;
|
||||||
|
case 32768: u = 15; break;
|
||||||
default:
|
default:
|
||||||
if(streamable_subset || is_last_block) {
|
if(streamable_subset || is_last_block) {
|
||||||
if(header->blocksize <= 0x100)
|
if(header->blocksize <= 0x100)
|
||||||
@@ -210,10 +221,10 @@ bool FLAC__frame_add_header(const FLAC__FrameHeader *header, bool streamable_sub
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write the CRC */
|
/* write the CRC */
|
||||||
assert(bb->buffer[crc_start] == 0xff); /* MAGIC NUMBER for the first byte of the sync code */
|
assert(bb->buffer[crc8_start] == 0xff); /* MAGIC NUMBER for the first byte of the sync code */
|
||||||
assert(bb->bits == 0); /* assert that we're byte-aligned */
|
assert(bb->bits == 0); /* assert that we're byte-aligned */
|
||||||
crc = FLAC__crc8(bb->buffer+crc_start, bb->bytes-crc_start);
|
crc8 = FLAC__crc8(bb->buffer+crc8_start, bb->bytes-crc8_start);
|
||||||
if(!FLAC__bitbuffer_write_raw_uint32(bb, crc, FLAC__FRAME_HEADER_CRC8_LEN))
|
if(!FLAC__bitbuffer_write_raw_uint32(bb, crc8, FLAC__FRAME_HEADER_CRC_LEN))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -224,7 +235,7 @@ bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsign
|
|||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
ok =
|
ok =
|
||||||
FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_CONSTANT_BITS, FLAC__SUBFRAME_TYPE_LEN) &&
|
FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK, FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) &&
|
||||||
FLAC__bitbuffer_write_raw_int32(bb, subframe->value, bits_per_sample)
|
FLAC__bitbuffer_write_raw_int32(bb, subframe->value, bits_per_sample)
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -235,7 +246,7 @@ bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned res
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_FIXED_BITS | (subframe->order<<1), FLAC__SUBFRAME_TYPE_LEN))
|
if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK | (subframe->order<<1), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for(i = 0; i < subframe->order; i++)
|
for(i = 0; i < subframe->order; i++)
|
||||||
@@ -260,7 +271,7 @@ bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residua
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_LPC_BITS | ((subframe->order-1)<<1), FLAC__SUBFRAME_TYPE_LEN))
|
if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK | ((subframe->order-1)<<1), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for(i = 0; i < subframe->order; i++)
|
for(i = 0; i < subframe->order; i++)
|
||||||
@@ -294,7 +305,7 @@ bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsign
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
const int32 *signal = subframe->data;
|
const int32 *signal = subframe->data;
|
||||||
|
|
||||||
if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_VERBATIM_BITS, FLAC__SUBFRAME_TYPE_LEN))
|
if(!FLAC__bitbuffer_write_raw_uint32(bb, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK, FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for(i = 0; i < samples; i++)
|
for(i = 0; i < samples; i++)
|
||||||
|
|||||||
@@ -42,14 +42,17 @@ const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */
|
|||||||
const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
|
const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */
|
||||||
const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
|
const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */
|
||||||
|
|
||||||
const unsigned FLAC__FRAME_HEADER_SYNC = 0x1fe;
|
const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
|
||||||
const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 9; /* bits */
|
const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */
|
||||||
const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 3; /* bits */
|
const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 2; /* bits */
|
||||||
|
const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */
|
||||||
const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
|
const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */
|
||||||
const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
|
const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */
|
||||||
const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
|
const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */
|
||||||
const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
|
const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */
|
||||||
const unsigned FLAC__FRAME_HEADER_CRC8_LEN = 8; /* bits */
|
const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */
|
||||||
|
|
||||||
|
const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */
|
||||||
|
|
||||||
const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
|
const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */
|
||||||
const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
|
const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */
|
||||||
@@ -62,11 +65,14 @@ const char *FLAC__EntropyCodingMethodTypeString[] = {
|
|||||||
const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
|
const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */
|
||||||
const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
|
const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */
|
||||||
|
|
||||||
const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BITS = 0x00;
|
const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
|
||||||
const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BITS = 0x02;
|
const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
|
||||||
const unsigned FLAC__SUBFRAME_TYPE_FIXED_BITS = 0x10;
|
const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */
|
||||||
const unsigned FLAC__SUBFRAME_TYPE_LPC_BITS = 0x40;
|
|
||||||
const unsigned FLAC__SUBFRAME_TYPE_LEN = 8; /* bits */
|
const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00;
|
||||||
|
const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02;
|
||||||
|
const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10;
|
||||||
|
const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40;
|
||||||
|
|
||||||
const char *FLAC__SubframeTypeString[] = {
|
const char *FLAC__SubframeTypeString[] = {
|
||||||
"CONSTANT",
|
"CONSTANT",
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ typedef struct FLAC__StreamDecoderPrivate {
|
|||||||
bool has_stream_header;
|
bool has_stream_header;
|
||||||
FLAC__StreamMetaData stream_header;
|
FLAC__StreamMetaData stream_header;
|
||||||
FLAC__Frame frame;
|
FLAC__Frame frame;
|
||||||
|
byte header_warmup[2]; /* contains the sync code and reserved bits */
|
||||||
|
byte lookahead; /* temp storage when we need to look ahead one byte in the stream */
|
||||||
|
bool cached; /* true if there is a byte in lookahead */
|
||||||
} FLAC__StreamDecoderPrivate;
|
} FLAC__StreamDecoderPrivate;
|
||||||
|
|
||||||
static byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
|
static byte ID3V2_TAG_[3] = { 'I', 'D', '3' };
|
||||||
@@ -66,7 +69,6 @@ const char *FLAC__StreamDecoderStateString[] = {
|
|||||||
"FLAC__STREAM_DECODER_READ_METADATA",
|
"FLAC__STREAM_DECODER_READ_METADATA",
|
||||||
"FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC",
|
"FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC",
|
||||||
"FLAC__STREAM_DECODER_READ_FRAME",
|
"FLAC__STREAM_DECODER_READ_FRAME",
|
||||||
"FLAC__STREAM_DECODER_RESYNC_IN_HEADER",
|
|
||||||
"FLAC__STREAM_DECODER_END_OF_STREAM",
|
"FLAC__STREAM_DECODER_END_OF_STREAM",
|
||||||
"FLAC__STREAM_DECODER_ABORTED",
|
"FLAC__STREAM_DECODER_ABORTED",
|
||||||
"FLAC__STREAM_DECODER_UNPARSEABLE_STREAM",
|
"FLAC__STREAM_DECODER_UNPARSEABLE_STREAM",
|
||||||
@@ -86,7 +88,9 @@ const char *FLAC__StreamDecoderWriteStatusString[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char *FLAC__StreamDecoderErrorStatusString[] = {
|
const char *FLAC__StreamDecoderErrorStatusString[] = {
|
||||||
"FLAC__STREAM_DECODER_ERROR_LOST_SYNC"
|
"FLAC__STREAM_DECODER_ERROR_LOST_SYNC",
|
||||||
|
"FLAC__STREAM_DECODER_ERROR_BAD_HEADER",
|
||||||
|
"FLAC__STREAM_DECODER_ERROR_FRAME_CRC_MISMATCH"
|
||||||
};
|
};
|
||||||
|
|
||||||
FLAC__StreamDecoder *FLAC__stream_decoder_get_new_instance()
|
FLAC__StreamDecoder *FLAC__stream_decoder_get_new_instance()
|
||||||
@@ -148,6 +152,7 @@ FLAC__StreamDecoderState FLAC__stream_decoder_init(
|
|||||||
decoder->guts->last_frame_number = 0;
|
decoder->guts->last_frame_number = 0;
|
||||||
decoder->guts->samples_decoded = 0;
|
decoder->guts->samples_decoded = 0;
|
||||||
decoder->guts->has_stream_header = false;
|
decoder->guts->has_stream_header = false;
|
||||||
|
decoder->guts->cached = false;
|
||||||
|
|
||||||
return decoder->state;
|
return decoder->state;
|
||||||
}
|
}
|
||||||
@@ -388,15 +393,21 @@ bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder)
|
|||||||
{
|
{
|
||||||
uint32 x;
|
uint32 x;
|
||||||
unsigned i, id;
|
unsigned i, id;
|
||||||
bool first = 1;
|
bool first = true;
|
||||||
|
|
||||||
assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */
|
assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */
|
||||||
|
|
||||||
for(i = id = 0; i < 4; ) {
|
for(i = id = 0; i < 4; ) {
|
||||||
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
if(decoder->guts->cached) {
|
||||||
return false; /* the read_callback_ sets the state for us */
|
x = (uint32)decoder->guts->lookahead;
|
||||||
|
decoder->guts->cached = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
||||||
|
return false; /* the read_callback_ sets the state for us */
|
||||||
|
}
|
||||||
if(x == FLAC__STREAM_SYNC_STRING[i]) {
|
if(x == FLAC__STREAM_SYNC_STRING[i]) {
|
||||||
first = 1;
|
first = true;
|
||||||
i++;
|
i++;
|
||||||
id = 0;
|
id = 0;
|
||||||
continue;
|
continue;
|
||||||
@@ -411,10 +422,18 @@ bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
|
if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
|
||||||
unsigned y;
|
decoder->guts->header_warmup[0] = (byte)x;
|
||||||
if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
|
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
||||||
return false; /* the read_callback_ sets the state for us */
|
return false; /* the read_callback_ sets the state for us */
|
||||||
if(!y) { /* MAGIC NUMBER for the last sync bit */
|
|
||||||
|
/* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */
|
||||||
|
/* else we have to check if the second byte is the end of a sync code */
|
||||||
|
if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
|
||||||
|
decoder->guts->lookahead = (byte)x;
|
||||||
|
decoder->guts->cached = true;
|
||||||
|
}
|
||||||
|
else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
|
||||||
|
decoder->guts->header_warmup[1] = (byte)x;
|
||||||
decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
|
decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -422,7 +441,7 @@ bool stream_decoder_find_metadata_(FLAC__StreamDecoder *decoder)
|
|||||||
i = 0;
|
i = 0;
|
||||||
if(first) {
|
if(first) {
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
||||||
first = 0;
|
first = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,7 +565,7 @@ bool stream_decoder_skip_id3v2_tag_(FLAC__StreamDecoder *decoder)
|
|||||||
bool stream_decoder_frame_sync_(FLAC__StreamDecoder *decoder)
|
bool stream_decoder_frame_sync_(FLAC__StreamDecoder *decoder)
|
||||||
{
|
{
|
||||||
uint32 x;
|
uint32 x;
|
||||||
bool first = 1;
|
bool first = true;
|
||||||
|
|
||||||
/* If we know the total number of samples in the stream, stop if we've read that many. */
|
/* If we know the total number of samples in the stream, stop if we've read that many. */
|
||||||
/* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
|
/* This will stop us, for example, from wasting time trying to sync on an ID3V1 tag. */
|
||||||
@@ -564,13 +583,27 @@ bool stream_decoder_frame_sync_(FLAC__StreamDecoder *decoder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
if(decoder->guts->cached) {
|
||||||
return false; /* the read_callback_ sets the state for us */
|
x = (uint32)decoder->guts->lookahead;
|
||||||
if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
|
decoder->guts->cached = false;
|
||||||
unsigned y;
|
}
|
||||||
if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
|
else {
|
||||||
|
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
||||||
return false; /* the read_callback_ sets the state for us */
|
return false; /* the read_callback_ sets the state for us */
|
||||||
if(!y) { /* MAGIC NUMBER for the last sync bit */
|
}
|
||||||
|
if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
|
||||||
|
decoder->guts->header_warmup[0] = (byte)x;
|
||||||
|
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
||||||
|
return false; /* the read_callback_ sets the state for us */
|
||||||
|
|
||||||
|
/* we have to check if we just read two 0xff's in a row; the second may actually be the beginning of the sync code */
|
||||||
|
/* else we have to check if the second byte is the end of a sync code */
|
||||||
|
if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
|
||||||
|
decoder->guts->lookahead = (byte)x;
|
||||||
|
decoder->guts->cached = true;
|
||||||
|
}
|
||||||
|
else if(x >> 2 == 0x3e) { /* MAGIC NUMBER for the last 6 sync bits */
|
||||||
|
decoder->guts->header_warmup[1] = (byte)x;
|
||||||
decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
|
decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -589,18 +622,21 @@ bool stream_decoder_read_frame_(FLAC__StreamDecoder *decoder, bool *got_a_frame)
|
|||||||
unsigned channel;
|
unsigned channel;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int32 mid, side, left, right;
|
int32 mid, side, left, right;
|
||||||
|
uint16 frame_crc; /* the one we calculate from the input stream */
|
||||||
|
uint32 x;
|
||||||
|
|
||||||
*got_a_frame = false;
|
*got_a_frame = false;
|
||||||
|
|
||||||
|
/* init the CRC */
|
||||||
|
frame_crc = 0;
|
||||||
|
FLAC__CRC16_UPDATE(decoder->guts->header_warmup[0], frame_crc);
|
||||||
|
FLAC__CRC16_UPDATE(decoder->guts->header_warmup[1], frame_crc);
|
||||||
|
FLAC__bitbuffer_init_read_crc16(&decoder->guts->input, frame_crc);
|
||||||
|
|
||||||
if(!stream_decoder_read_frame_header_(decoder))
|
if(!stream_decoder_read_frame_header_(decoder))
|
||||||
return false;
|
return false;
|
||||||
if(decoder->state != FLAC__STREAM_DECODER_READ_FRAME) {
|
if(decoder->state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC)
|
||||||
if(decoder->state == FLAC__STREAM_DECODER_RESYNC_IN_HEADER)
|
|
||||||
decoder->state = FLAC__STREAM_DECODER_READ_FRAME;
|
|
||||||
else
|
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
if(!stream_decoder_allocate_output_(decoder, decoder->guts->frame.header.blocksize, decoder->guts->frame.header.channels))
|
if(!stream_decoder_allocate_output_(decoder, decoder->guts->frame.header.blocksize, decoder->guts->frame.header.channels))
|
||||||
return false;
|
return false;
|
||||||
for(channel = 0; channel < decoder->guts->frame.header.channels; channel++) {
|
for(channel = 0; channel < decoder->guts->frame.header.channels; channel++) {
|
||||||
@@ -640,38 +676,53 @@ bool stream_decoder_read_frame_(FLAC__StreamDecoder *decoder, bool *got_a_frame)
|
|||||||
if(!stream_decoder_read_zero_padding_(decoder))
|
if(!stream_decoder_read_zero_padding_(decoder))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Undo any special channel coding */
|
/*
|
||||||
switch(decoder->guts->frame.header.channel_assignment) {
|
* Read the frame CRC-16 from the footer and check
|
||||||
case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
|
*/
|
||||||
/* do nothing */
|
frame_crc = decoder->guts->input.read_crc16;
|
||||||
break;
|
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__FRAME_FOOTER_CRC_LEN, read_callback_, decoder))
|
||||||
case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
|
return false; /* the read_callback_ sets the state for us */
|
||||||
assert(decoder->guts->frame.header.channels == 2);
|
if(frame_crc == (uint16)x) {
|
||||||
for(i = 0; i < decoder->guts->frame.header.blocksize; i++)
|
/* Undo any special channel coding */
|
||||||
decoder->guts->output[1][i] = decoder->guts->output[0][i] - decoder->guts->output[1][i];
|
switch(decoder->guts->frame.header.channel_assignment) {
|
||||||
break;
|
case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT:
|
||||||
case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
|
/* do nothing */
|
||||||
assert(decoder->guts->frame.header.channels == 2);
|
break;
|
||||||
for(i = 0; i < decoder->guts->frame.header.blocksize; i++)
|
case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE:
|
||||||
decoder->guts->output[0][i] += decoder->guts->output[1][i];
|
assert(decoder->guts->frame.header.channels == 2);
|
||||||
break;
|
for(i = 0; i < decoder->guts->frame.header.blocksize; i++)
|
||||||
case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
|
decoder->guts->output[1][i] = decoder->guts->output[0][i] - decoder->guts->output[1][i];
|
||||||
assert(decoder->guts->frame.header.channels == 2);
|
break;
|
||||||
for(i = 0; i < decoder->guts->frame.header.blocksize; i++) {
|
case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE:
|
||||||
mid = decoder->guts->output[0][i];
|
assert(decoder->guts->frame.header.channels == 2);
|
||||||
side = decoder->guts->output[1][i];
|
for(i = 0; i < decoder->guts->frame.header.blocksize; i++)
|
||||||
mid <<= 1;
|
decoder->guts->output[0][i] += decoder->guts->output[1][i];
|
||||||
if(side & 1) /* i.e. if 'side' is odd... */
|
break;
|
||||||
mid++;
|
case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE:
|
||||||
left = mid + side;
|
assert(decoder->guts->frame.header.channels == 2);
|
||||||
right = mid - side;
|
for(i = 0; i < decoder->guts->frame.header.blocksize; i++) {
|
||||||
decoder->guts->output[0][i] = left >> 1;
|
mid = decoder->guts->output[0][i];
|
||||||
decoder->guts->output[1][i] = right >> 1;
|
side = decoder->guts->output[1][i];
|
||||||
}
|
mid <<= 1;
|
||||||
break;
|
if(side & 1) /* i.e. if 'side' is odd... */
|
||||||
default:
|
mid++;
|
||||||
assert(0);
|
left = mid + side;
|
||||||
break;
|
right = mid - side;
|
||||||
|
decoder->guts->output[0][i] = left >> 1;
|
||||||
|
decoder->guts->output[1][i] = right >> 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Bad frame, emit error and zero the output signal */
|
||||||
|
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_FRAME_CRC_MISMATCH, decoder->guts->client_data);
|
||||||
|
for(channel = 0; channel < decoder->guts->frame.header.channels; channel++) {
|
||||||
|
memset(decoder->guts->output[channel], 0, sizeof(int32) * decoder->guts->frame.header.blocksize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*got_a_frame = true;
|
*got_a_frame = true;
|
||||||
@@ -698,15 +749,29 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
uint32 x;
|
uint32 x;
|
||||||
uint64 xx;
|
uint64 xx;
|
||||||
unsigned i, blocksize_hint = 0, sample_rate_hint = 0;
|
unsigned i, blocksize_hint = 0, sample_rate_hint = 0;
|
||||||
byte crc, raw_header[15]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
|
byte crc8, raw_header[16]; /* MAGIC NUMBER based on the maximum frame header size, including CRC */
|
||||||
unsigned raw_header_len;
|
unsigned raw_header_len;
|
||||||
bool is_unparseable = false;
|
bool is_unparseable = false;
|
||||||
|
|
||||||
assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */
|
assert(decoder->guts->input.consumed_bits == 0); /* make sure we're byte aligned */
|
||||||
|
|
||||||
/* init the raw header with the first 8 bits of the sync code */
|
/* init the raw header with the saved bits from synchronization */
|
||||||
raw_header[0] = 0xff; /* MAGIC NUMBER for the first 8 frame sync bits */
|
raw_header[0] = decoder->guts->header_warmup[0];
|
||||||
raw_header_len = 1;
|
raw_header[1] = decoder->guts->header_warmup[1];
|
||||||
|
raw_header_len = 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check to make sure that the reserved bits are 0
|
||||||
|
*/
|
||||||
|
if(raw_header[1] & 0x03) { /* MAGIC NUMBER */
|
||||||
|
is_unparseable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that along the way as we read the header, we look for a sync
|
||||||
|
* code inside. If we find one it would indicate that our original
|
||||||
|
* sync was bad since there cannot be a sync code in a valid header.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read in the raw header as bytes so we can CRC it, and parse it on the way
|
* read in the raw header as bytes so we can CRC it, and parse it on the way
|
||||||
@@ -714,26 +779,18 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
for(i = 0; i < 2; i++) {
|
for(i = 0; i < 2; i++) {
|
||||||
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
||||||
return false; /* the read_callback_ sets the state for us */
|
return false; /* the read_callback_ sets the state for us */
|
||||||
else if(x == 0xff) { /* MAGIC NUMBER for the first part of the sync code */
|
if(x == 0xff) { /* MAGIC NUMBER for the first 8 frame sync bits */
|
||||||
/* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */
|
/* if we get here it means our original sync was erroneous since the sync code cannot appear in the header */
|
||||||
uint32 y;
|
decoder->guts->lookahead = (byte)x;
|
||||||
if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
|
decoder->guts->cached = true;
|
||||||
return false; /* the read_callback_ sets the state for us */
|
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
|
||||||
if(!y) { /* MAGIC NUMBER for the last sync bit */
|
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
||||||
decoder->state = FLAC__STREAM_DECODER_RESYNC_IN_HEADER;
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
raw_header[raw_header_len++] = (byte)x;
|
raw_header[raw_header_len++] = (byte)x;
|
||||||
}
|
}
|
||||||
assert(!(raw_header[1] & 0x80)); /* last sync bit should be confirmed zero before we get here */
|
|
||||||
|
|
||||||
switch(x = raw_header[1] >> 4) {
|
switch(x = raw_header[2] >> 4) {
|
||||||
case 0:
|
case 0:
|
||||||
if(decoder->guts->has_stream_header && decoder->guts->stream_header.data.stream_info.min_blocksize == decoder->guts->stream_header.data.stream_info.max_blocksize) /* i.e. it's a fixed-blocksize stream */
|
if(decoder->guts->has_stream_header && decoder->guts->stream_header.data.stream_info.min_blocksize == decoder->guts->stream_header.data.stream_info.max_blocksize) /* i.e. it's a fixed-blocksize stream */
|
||||||
decoder->guts->frame.header.blocksize = decoder->guts->stream_header.data.stream_info.min_blocksize;
|
decoder->guts->frame.header.blocksize = decoder->guts->stream_header.data.stream_info.min_blocksize;
|
||||||
@@ -753,12 +810,22 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
case 7:
|
case 7:
|
||||||
blocksize_hint = x;
|
blocksize_hint = x;
|
||||||
break;
|
break;
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 12:
|
||||||
|
case 13:
|
||||||
|
case 14:
|
||||||
|
case 15:
|
||||||
|
decoder->guts->frame.header.blocksize = 256 << (x-8);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(x = raw_header[1] & 0x0f) {
|
switch(x = raw_header[2] & 0x0f) {
|
||||||
case 0:
|
case 0:
|
||||||
if(decoder->guts->has_stream_header)
|
if(decoder->guts->has_stream_header)
|
||||||
decoder->guts->frame.header.sample_rate = decoder->guts->stream_header.data.stream_info.sample_rate;
|
decoder->guts->frame.header.sample_rate = decoder->guts->stream_header.data.stream_info.sample_rate;
|
||||||
@@ -800,14 +867,14 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
sample_rate_hint = x;
|
sample_rate_hint = x;
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
x = (unsigned)(raw_header[2] >> 4);
|
x = (unsigned)(raw_header[3] >> 4);
|
||||||
if(x & 8) {
|
if(x & 8) {
|
||||||
decoder->guts->frame.header.channels = 2;
|
decoder->guts->frame.header.channels = 2;
|
||||||
switch(x & 7) {
|
switch(x & 7) {
|
||||||
@@ -830,7 +897,7 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
decoder->guts->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
|
decoder->guts->frame.header.channel_assignment = FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(x = (unsigned)(raw_header[2] & 0x0e) >> 1) {
|
switch(x = (unsigned)(raw_header[3] & 0x0e) >> 1) {
|
||||||
case 0:
|
case 0:
|
||||||
if(decoder->guts->has_stream_header)
|
if(decoder->guts->has_stream_header)
|
||||||
decoder->guts->frame.header.bits_per_sample = decoder->guts->stream_header.data.stream_info.bits_per_sample;
|
decoder->guts->frame.header.bits_per_sample = decoder->guts->stream_header.data.stream_info.bits_per_sample;
|
||||||
@@ -861,8 +928,8 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(raw_header[2] & 0x01) { /* this should be a zero padding bit */
|
if(raw_header[3] & 0x01) { /* this should be a zero padding bit */
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -870,26 +937,12 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
if(blocksize_hint) {
|
if(blocksize_hint) {
|
||||||
if(!FLAC__bitbuffer_read_utf8_uint64(&decoder->guts->input, &xx, read_callback_, decoder, raw_header, &raw_header_len))
|
if(!FLAC__bitbuffer_read_utf8_uint64(&decoder->guts->input, &xx, read_callback_, decoder, raw_header, &raw_header_len))
|
||||||
return false; /* the read_callback_ sets the state for us */
|
return false; /* the read_callback_ sets the state for us */
|
||||||
if(xx == 0xffffffffffffffff) {
|
if(xx == 0xffffffffffffffff) { /* i.e. non-UTF8 code... */
|
||||||
if(raw_header[raw_header_len-1] == 0xff) { /* MAGIC NUMBER for sync code */
|
decoder->guts->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
|
||||||
uint32 y;
|
decoder->guts->cached = true;
|
||||||
if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
|
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
|
||||||
return false; /* the read_callback_ sets the state for us */
|
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
||||||
if(!y) { /* MAGIC NUMBER for the last sync bit */
|
return true;
|
||||||
decoder->state = FLAC__STREAM_DECODER_RESYNC_IN_HEADER;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(decoder->guts->has_stream_header && decoder->guts->stream_header.data.stream_info.min_blocksize == decoder->guts->stream_header.data.stream_info.max_blocksize) /* i.e. it's a fixed-blocksize stream */
|
if(decoder->guts->has_stream_header && decoder->guts->stream_header.data.stream_info.min_blocksize == decoder->guts->stream_header.data.stream_info.max_blocksize) /* i.e. it's a fixed-blocksize stream */
|
||||||
decoder->guts->frame.header.number.sample_number = (uint64)decoder->guts->last_frame_number * (int64)decoder->guts->stream_header.data.stream_info.min_blocksize + xx;
|
decoder->guts->frame.header.number.sample_number = (uint64)decoder->guts->last_frame_number * (int64)decoder->guts->stream_header.data.stream_info.min_blocksize + xx;
|
||||||
@@ -899,26 +952,12 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
else {
|
else {
|
||||||
if(!FLAC__bitbuffer_read_utf8_uint32(&decoder->guts->input, &x, read_callback_, decoder, raw_header, &raw_header_len))
|
if(!FLAC__bitbuffer_read_utf8_uint32(&decoder->guts->input, &x, read_callback_, decoder, raw_header, &raw_header_len))
|
||||||
return false; /* the read_callback_ sets the state for us */
|
return false; /* the read_callback_ sets the state for us */
|
||||||
if(x == 0xffffffff) {
|
if(x == 0xffffffff) { /* i.e. non-UTF8 code... */
|
||||||
if(raw_header[raw_header_len-1] == 0xff) { /* MAGIC NUMBER for sync code */
|
decoder->guts->lookahead = raw_header[raw_header_len-1]; /* back up as much as we can */
|
||||||
uint32 y;
|
decoder->guts->cached = true;
|
||||||
if(!FLAC__bitbuffer_peek_bit(&decoder->guts->input, &y, read_callback_, decoder))
|
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
|
||||||
return false; /* the read_callback_ sets the state for us */
|
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
||||||
if(!y) { /* MAGIC NUMBER for the last sync bit */
|
return true;
|
||||||
decoder->state = FLAC__STREAM_DECODER_RESYNC_IN_HEADER;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
decoder->guts->last_frame_number = x;
|
decoder->guts->last_frame_number = x;
|
||||||
if(decoder->guts->has_stream_header) {
|
if(decoder->guts->has_stream_header) {
|
||||||
@@ -962,13 +1001,13 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
decoder->guts->frame.header.sample_rate = x*10;
|
decoder->guts->frame.header.sample_rate = x*10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the crc byte */
|
/* read the CRC-8 byte */
|
||||||
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder))
|
||||||
return false; /* the read_callback_ sets the state for us */
|
return false; /* the read_callback_ sets the state for us */
|
||||||
crc = (byte)x;
|
crc8 = (byte)x;
|
||||||
|
|
||||||
if(FLAC__crc8(raw_header, raw_header_len) != crc) {
|
if(FLAC__crc8(raw_header, raw_header_len) != crc8) {
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_BAD_HEADER, decoder->guts->client_data);
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -984,34 +1023,57 @@ bool stream_decoder_read_frame_header_(FLAC__StreamDecoder *decoder)
|
|||||||
bool stream_decoder_read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
|
bool stream_decoder_read_subframe_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
|
||||||
{
|
{
|
||||||
uint32 x;
|
uint32 x;
|
||||||
|
bool wasted_bits;
|
||||||
|
|
||||||
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, FLAC__SUBFRAME_TYPE_LEN, read_callback_, decoder))
|
if(!FLAC__bitbuffer_read_raw_uint32(&decoder->guts->input, &x, 8, read_callback_, decoder)) /* MAGIC NUMBER */
|
||||||
return false; /* the read_callback_ sets the state for us */
|
return false; /* the read_callback_ sets the state for us */
|
||||||
if(x & 0x01 || x & 0x80) {
|
|
||||||
|
wasted_bits = (x & 1);
|
||||||
|
x &= 0xfe;
|
||||||
|
|
||||||
|
if(wasted_bits) {
|
||||||
|
unsigned u;
|
||||||
|
if(!FLAC__bitbuffer_read_unary_unsigned(&decoder->guts->input, &u, read_callback_, decoder))
|
||||||
|
return false; /* the read_callback_ sets the state for us */
|
||||||
|
decoder->guts->frame.subframes[channel].wasted_bits = u+1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
decoder->guts->frame.subframes[channel].wasted_bits = 0;
|
||||||
|
|
||||||
|
if(x & 0x80) {
|
||||||
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
decoder->guts->error_callback(decoder, FLAC__STREAM_DECODER_ERROR_LOST_SYNC, decoder->guts->client_data);
|
||||||
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
decoder->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(x == 0) {
|
else if(x == 0) {
|
||||||
return stream_decoder_read_subframe_constant_(decoder, channel, bps);
|
if(!stream_decoder_read_subframe_constant_(decoder, channel, bps))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else if(x == 2) {
|
else if(x == 2) {
|
||||||
return stream_decoder_read_subframe_verbatim_(decoder, channel, bps);
|
if(!stream_decoder_read_subframe_verbatim_(decoder, channel, bps))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else if(x < 16) {
|
else if(x < 16) {
|
||||||
decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
|
decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(x <= 24) {
|
else if(x <= 24) {
|
||||||
return stream_decoder_read_subframe_fixed_(decoder, channel, bps, (x>>1)&7);
|
if(!stream_decoder_read_subframe_fixed_(decoder, channel, bps, (x>>1)&7))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else if(x < 64) {
|
else if(x < 64) {
|
||||||
decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
|
decoder->state = FLAC__STREAM_DECODER_UNPARSEABLE_STREAM;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return stream_decoder_read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1);
|
if(!stream_decoder_read_subframe_lpc_(decoder, channel, bps, ((x>>1)&31)+1))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(wasted_bits) {
|
||||||
|
fprintf(stderr,"@@@ CAN'T DEAL WITH WASTED BITS YET!!!\n");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stream_decoder_read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
|
bool stream_decoder_read_subframe_constant_(FLAC__StreamDecoder *decoder, unsigned channel, unsigned bps)
|
||||||
|
|||||||
Reference in New Issue
Block a user