Commit 215af574 authored by Josh Coalson's avatar Josh Coalson
Browse files

update for new format changes: frame crc-16, wasted bits field, longer sync...

update for new format changes: frame crc-16, wasted bits field, longer sync code, longer blocksize code
parent 6351ef6c
......@@ -162,16 +162,19 @@ extern const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /* = 5 bits */
/*****************************************************************************
*
* 8: subframe type
* xxxxxxx1: invalid, to prevent sync-fooling string of 1s (use to check for erroneous sync)
* 00000000: constant value
* 00000010: verbatim
* 000001x0: reserved
* 00001xx0: reserved
* 0001xxx0: fixed predictor, xxx=order <= 4, else reserved
* 001xxxx0: reserved
* 01xxxxx0: lpc, xxxxx=order-1
* 1xxxxxxx: invalid, to prevent sync-fooling string of 1s (use to check for erroneous sync)
* 1: zero pad, to prevent sync-fooling string of 1s (use to check for erroneous sync)
* 6: subframe type
* 000000: constant value
* 000001: verbatim
* 00001x: reserved
* 0001xx: reserved
* 001xxx: fixed predictor, xxx=order <= 4, else reserved
* 01xxxx: reserved
* 1xxxxx: lpc, xxxxx=order-1
* 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_*)
*/
typedef struct {
......@@ -182,13 +185,17 @@ typedef struct {
FLAC__Subframe_LPC lpc;
FLAC__Subframe_Verbatim verbatim;
} data;
unsigned wasted_bits;
} FLAC__Subframe;
extern const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BITS; /* = 0x00 */
extern const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BITS; /* = 0x02 */
extern const unsigned FLAC__SUBFRAME_TYPE_FIXED_BITS; /* = 0x10 */
extern const unsigned FLAC__SUBFRAME_TYPE_LPC_BITS; /* = 0x40 */
extern const unsigned FLAC__SUBFRAME_TYPE_LEN; /* = 8 bits */
extern const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN; /* = 1 bit */
extern const unsigned FLAC__SUBFRAME_TYPE_LEN; /* = 6 bits */
extern const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /* = 1 bit */
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'
* 3: blocksize in samples
* 000: get from stream header => implies constant blocksize throughout stream
* 001: 192 samples (AES/EBU) => implies constant blocksize throughout stream
* 010-101: 576 * (2^(2-n)) samples, i.e. 576/1152/2304/4608 => implies constant blocksize throughout stream
* 110: get 8 bit (blocksize-1) from end of header => variable blocksize throughout stream unless it's the last frame
* 111: get 16 bit (blocksize-1) from end of header => variable blocksize throughout stream unless it's the last frame
* 14: sync code '11111111111110'
+ 2: reserved
+ 00: currently required value
+ 01-11: reserved
* 4: blocksize in samples
* 0000: get from stream header => implies constant blocksize throughout stream
* 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:
* 0000: get from stream header
* 0001-0011: reserved
......@@ -267,20 +278,33 @@ typedef struct {
uint32 frame_number;
uint64 sample_number;
} number;
uint8 crc;
} FLAC__FrameHeader;
extern const unsigned FLAC__FRAME_HEADER_SYNC; /* = 0x1fe */
extern const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /* = 9 bits */
extern const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /* = 3 bits */
extern const unsigned FLAC__FRAME_HEADER_SYNC; /* = 0x3ffe */
extern const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /* = 14 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_CHANNEL_ASSIGNMENT_LEN; /* = 4 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_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 {
FLAC__FrameHeader header;
FLAC__Subframe subframes[FLAC__MAX_CHANNELS];
FLAC__FrameFooter footer;
} FLAC__Frame;
/*****************************************************************************/
......
......@@ -23,6 +23,7 @@
#include <string.h> /* for memcpy() */
#include "FLAC/encoder.h"
#include "private/bitbuffer.h"
#include "private/crc.h"
#include "private/encoder_framing.h"
#include "private/fixed.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;
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)
return encoder->state = FLAC__ENCODER_NOT_STREAMABLE;
if(encoder->sample_rate > 655350)
......@@ -594,10 +596,15 @@ bool encoder_process_frame_(FLAC__Encoder *encoder, bool is_last_frame)
}
/*
* Write it
* CRC-16 the whole thing
*/
assert(encoder->guts->frame.bits == 0); /* assert that we're byte-aligned before writing */
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
*/
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;
return false;
......@@ -956,7 +963,7 @@ unsigned encoder_evaluate_constant_subframe_(const int32 signal, unsigned bits_p
subframe->type = FLAC__SUBFRAME_TYPE_CONSTANT;
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)
......@@ -977,7 +984,7 @@ unsigned encoder_evaluate_fixed_subframe_(const int32 signal[], int32 residual[]
for(i = 0; i < order; 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)
......@@ -1007,7 +1014,7 @@ unsigned encoder_evaluate_lpc_subframe_(const int32 signal[], int32 residual[],
for(i = 0; i < order; 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)
......@@ -1016,7 +1023,7 @@ unsigned encoder_evaluate_verbatim_subframe_(const int32 signal[], unsigned bloc
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[])
......
......@@ -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)
{
unsigned u, crc_start, blocksize_hint, sample_rate_hint;
byte crc;
unsigned u, crc8_start, blocksize_hint, sample_rate_hint;
byte crc8;
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))
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);
blocksize_hint = 0;
switch(header->blocksize) {
case 192: u = 1; break;
case 576: u = 2; break;
case 1152: u = 3; break;
case 2304: u = 4; break;
case 4608: u = 5; break;
case 192: u = 1; break;
case 576: u = 2; break;
case 1152: u = 3; break;
case 2304: u = 4; 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:
if(streamable_subset || is_last_block) {
if(header->blocksize <= 0x100)
......@@ -210,10 +221,10 @@ bool FLAC__frame_add_header(const FLAC__FrameHeader *header, bool streamable_sub
}
/* 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 */
crc = FLAC__crc8(bb->buffer+crc_start, bb->bytes-crc_start);
if(!FLAC__bitbuffer_write_raw_uint32(bb, crc, FLAC__FRAME_HEADER_CRC8_LEN))
crc8 = FLAC__crc8(bb->buffer+crc8_start, bb->bytes-crc8_start);
if(!FLAC__bitbuffer_write_raw_uint32(bb, crc8, FLAC__FRAME_HEADER_CRC_LEN))
return false;
return true;
......@@ -224,7 +235,7 @@ bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsign
bool 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)
;
......@@ -235,7 +246,7 @@ bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned res
{
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;
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;
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;
for(i = 0; i < subframe->order; i++)
......@@ -294,7 +305,7 @@ bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsign
unsigned i;
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;
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_LENGTH_LEN = 24; /* bits */
const unsigned FLAC__FRAME_HEADER_SYNC = 0x1fe;
const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 9; /* bits */
const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 3; /* bits */
const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe;
const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* 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_CHANNEL_ASSIGNMENT_LEN = 4; /* 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_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_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_SHIFT_LEN = 5; /* bits */
const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BITS = 0x00;
const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BITS = 0x02;
const unsigned FLAC__SUBFRAME_TYPE_FIXED_BITS = 0x10;
const unsigned FLAC__SUBFRAME_TYPE_LPC_BITS = 0x40;
const unsigned FLAC__SUBFRAME_TYPE_LEN = 8; /* bits */
const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */
const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */
const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* 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[] = {
"CONSTANT",
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment