limit subset further if sample rate is <=48kHz: max blocksize is 4608 and max LPC...
authorJosh Coalson <jcoalson@users.sourceforce.net>
Sat, 7 Oct 2006 06:50:08 +0000 (06:50 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Sat, 7 Oct 2006 06:50:08 +0000 (06:50 +0000)
13 files changed:
doc/html/changelog.html
doc/html/documentation.html
doc/html/faq.html
doc/html/format.html
include/FLAC/format.h
include/FLAC/stream_encoder.h
man/flac.sgml
src/flac/encode.c
src/flac/main.c
src/libFLAC/include/private/stream_encoder_framing.h
src/libFLAC/stream_encoder.c
src/libFLAC/stream_encoder_framing.c
test/test_streams.sh

index 82cfe8c..459c06c 100644 (file)
@@ -78,8 +78,9 @@
                        <li>
                                FLAC format:
                                <ul>
-                                       <li>New <a href="format.html#def_PICTURE"><span class="code">PICTURE</span></a> metadata block for storing things like cover art</li>
-                                       <li>Speaker assignments and channel orders for 3-6 channels (see <a href="format.html#frame_header">frame header</a>)</li>
+                                       <li>New <a href="format.html#def_PICTURE"><span class="code">PICTURE</span></a> metadata block for storing things like cover art.</li>
+                                       <li>Speaker assignments and channel orders for 3-6 channels (see <a href="format.html#frame_header">frame header</a>).</li>
+                                       <li>Further restrictions on the <a href="format.html#subset">FLAC subset</a> when the sample rate is &lt;=48kHz; in this case the maximum LPC order is now 12 and maximum blocksize is 4608.  This is to further limit the processing and memory requirements for hardware implementations while not measurably affecting compression.</li>
                                </ul>
                        </li>
                        <li>
index f31c9bc..52dc5c2 100644 (file)
                                        <span class="argument">-b #</span>, <span class="argument">--blocksize=#</span>
                                </td>
                                <td>
-                                       Specify the block size in samples.  The default is 1152 for -l 0, otherwise 4608.  Subset streams must use one of 192/576/1152/2304/4608/256/512/1024/2048/4096/8192/16384/32768.  The reference encoder uses the same block size for the entire stream.
+                                       Specify the block size in samples.  The default is 1152 for -l 0, otherwise 4608.  Subset streams must use one of 192/576/1152/2304/4608/256/512/1024/2048/4096 (and 8192/16384 if the sample rate is &gt;48kHz).  The reference encoder uses the same block size for the entire stream.
                                </td>
                        </tr>
                        <tr>
                                        <span class="argument">-l #</span>, <span class="argument">--max-lpc-order=#</span>
                                </td>
                                <td>
-                                       Specifies the maximum LPC order.  This number must be &lt;= 32.  If 0, the encoder will not attempt generic linear prediction, and use only fixed predictors.  Using fixed predictors is faster but usually results in files being 5-10% larger.
+                                       Specifies the maximum LPC order.  This number must be &lt;= 32.  For Subset streams, it must be &lt;=12 if the sample rate is &lt;=48kHz.  If 0, the encoder will not attempt generic linear prediction, and use only fixed predictors.  Using fixed predictors is faster but usually results in files being 5-10% larger.
                                </td>
                        </tr>
                        <tr>
index fa13f60..18fc085 100644 (file)
                <br />
                <a name="tools__not_streamable"><b>Why did I get "ERROR initializing encoder, state = FLAC__STREAM_ENCODER_NOT_STREAMABLE"?</b></a><br />
                <br />
-               You specified encoding options that are outside the <a href="format.html#subset">Streamable subset</a>.  If that is what you really wanted, you must also use <span class="code">flac --lax</span>.<br />
+               You specified encoding options that are outside the <a href="format.html#subset">Streamable subset</a>.  If that is what you really wanted and you understand the consequences, you can use <span class="code">flac --lax</span> to generate a non-Subset stream.  The resulting file may not be streamable or play in all players.<br />
                <br />
                <a name="tools__different_sizes"><b>Why doesn't the same file compressed on different machines with the same options yield the same FLAC file?</b></a><br />
                <br />
index 415d046..dc9e3ac 100644 (file)
                                <a name="subset" />FLAC specifies a subset of itself as the Subset format.  The purpose of this is to ensure that any streams encoded according to the Subset are truly "streamable", meaning that a decoder that cannot seek within the stream can still pick up in the middle of the stream and start decoding.  It also makes hardware decoder implementations more practical by limiting the encoding parameters such that decoder buffer sizes and other resource requirements can be easily determined.  "flac" generates Subset streams by default unless the "--lax" command-line option is used.  The Subset makes the following limitations on what may be used in the stream:
                                <ul>
                                <li>
-                                       The blocksize bits in the <a href="#frame_header">frame header</a> must be 0001-0101 or 1000-1110, specifying a fixed-blocksize stream (the exception being the last block as described in the table) and a few allowable blocksizes.  This also means that the STREAMINFO metadata block must specify equal mininum and maximum blocksizes.
+                                       The blocksize bits in the <a href="#frame_header">frame header</a> must be 0001-0101 or 1000-1110, specifying a fixed-blocksize stream (the exception being the last block as described in the table) and a few allowable blocksizes.  This also means that the STREAMINFO metadata block must specify equal mininum and maximum blocksizes.  If the sample rate is &lt;= 48000Hz, the blocksize must be &lt;=4608, i.e. blocksize bits 0001-0101 or 1000-1100.
                                </li>
                                <li>
                                        The sample rate bits in the <a href="#frame_header">frame header</a> must be 0001-1011.
                                        The bits-per-sample bits in the <a href="#frame_header">frame header</a> must be 001-111.
                                </li>
                                <li>
+                                       If the sample rate is &lt;= 48000Hz, the filter order in <a href="#subframe_lpc">LPC subframes</a> must be less than or equal to 12, i.e. the subframe type bits in the <a href="#subframe_header">subframe header</a> may not be 101100-111111.
+                               </li>
+                               <li>
                                        The Rice partition order in a <a href="#partitioned_rice">Rice-coded residual section</a> must be less than or equal to 8.
                                </li>
                                </ul>
index b0b93c0..b4c2a04 100644 (file)
@@ -97,6 +97,10 @@ extern "C" {
 /** The maximum block size, in samples, permitted by the format. */
 #define FLAC__MAX_BLOCK_SIZE (65535u)
 
+/** The maximum block size, in samples, permitted by the FLAC subset for
+ *  sample rates up to 48kHz. */
+#define FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ (4608u)
+
 /** The maximum number of channels permitted by the format. */
 #define FLAC__MAX_CHANNELS (8u)
 
@@ -125,6 +129,10 @@ extern "C" {
 /** The maximum LPC order permitted by the format. */
 #define FLAC__MAX_LPC_ORDER (32u)
 
+/** The maximum LPC order permitted by the FLAC subset for sample rates
+ *  up to 48kHz. */
+#define FLAC__SUBSET_MAX_LPC_ORDER_48000HZ (12u)
+
 /** The minimum quantized linear predictor coefficient precision
  *  permitted by the format.
  */
index 407b6ac..9770479 100644 (file)
@@ -298,7 +298,7 @@ typedef enum {
        /**< The specified block size is less than the maximum LPC order. */
 
        FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE,
-       /**< The encoder is bound to the "streamable subset" but other settings violate it. */
+       /**< The encoder is bound to the <A HREF="../format.html#subset">Subset</A> but other settings violate it. */
 
        FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA,
        /**< The metadata input to the encoder is invalid, in one of the following ways:
@@ -574,8 +574,8 @@ FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder);
  */
 FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value);
 
-/** Set the "streamable subset" flag.  If \c true, the encoder will comply
- *  with the subset (see the format specification) and will check the
+/** Set the <A HREF="../format.html#subset">Subset</A> flag.  If \c true,
+ *  the encoder will comply with the Subset and will check the
  *  settings during FLAC__stream_encoder_init() to see if all settings
  *  comply.  If \c false, the settings may take advantage of the full
  *  range that the format allows.
@@ -994,7 +994,7 @@ FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__St
  */
 FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder);
 
-/** Get the "streamable subset" flag.
+/** Get the <A HREF="../format.html#subset>Subset</A> flag.
  *
  * \param  encoder  An encoder instance to query.
  * \assert
index 0ef9b5f..24855be 100644 (file)
          <term><option>-b</option> <replaceable>#</replaceable>, <option>--blocksize</option>=<replaceable>#</replaceable></term>
 
          <listitem>
-           <para>Specify the block size in samples.  The default is 1152 for -l 0, else 4608; must be one of 192, 576, 1152, 2304, 4608, 256, 512, 1024, 2048, 4096, 8192, 16384, or 32768 (unless --lax is used)</para>
+           <para>Specify the block size in samples.  The default is 1152 for -l 0, else 4608.  Subset streams must use one of 192, 576, 1152, 2304, 4608, 256, 512, 1024, 2048, 4096 (and 8192 or 16384 if the sample rate is &gt;48kHz).</para>
          </listitem>
        </varlistentry>
 
          <term><option>-l</option> <replaceable>#</replaceable>, <option>--max-lpc-order</option>=<replaceable>#</replaceable></term>
 
          <listitem>
-           <para>Set the maximum LPC order; 0 means use only the fixed predictors</para>
+           <para>Specifies the maximum LPC order. This number must be &lt;= 32. For Subset streams, it must be &lt;=12 if the sample rate is &lt;=48kHz. If 0, the encoder will not attempt generic linear prediction, and use only fixed predictors. Using fixed predictors is faster but usually results in files being 5-10% larger.</para>
          </listitem>
        </varlistentry>
 
index 9cfb668..05af1dd 100644 (file)
@@ -2519,8 +2519,9 @@ void print_error_with_init_status(const EncoderSession *e, const char *message,
                flac__utils_printf(stderr, 1,
                        "\n"
                        "The encoding parameters specified do not conform to the FLAC Subset and may not\n"
-                       "be streamable or playable in hardware devices.  Add --lax to the command-line\n"
-                       "options to encode with these parameters anyway.\n"
+                       "be streamable or playable in hardware devices.  If you really understand the\n"
+                       "consequences, you can add --lax to the command-line options to encode with\n"
+                       "these parameters anyway.  See http://flac.sourceforge.net/format.html#subset\n"
                );
        }
 }
index 4c9a4a6..88a53b5 100644 (file)
@@ -1516,8 +1516,8 @@ void show_explain()
        printf("  -b, --blocksize=#            Specify the blocksize in samples; the default is\n");
        printf("                               1152 for -l 0, else 4608; must be one of 192,\n");
        printf("                               576, 1152, 2304, 4608, 256, 512, 1024, 2048,\n");
-       printf("                               4096, 8192, 16384, or 32768 (unless --lax is\n");
-       printf("                               used)\n");
+       printf("                               4096 (and 8192 or 16384 if the sample rate is\n");
+       printf("                               >48kHz) for Subset streams.\n");
        printf("  -0, --compression-level-0, --fast  Synonymous with -l 0 -b 1152 -r 2,2\n");
        printf("  -1, --compression-level-1          Synonymous with -l 0 -b 1152 -M -r 2,2\n");
        printf("  -2, --compression-level-2          Synonymous with -l 0 -b 1152 -m -r 3\n");
@@ -1544,7 +1544,9 @@ void show_explain()
        printf("                                     they are each tried in turn.  The encoder\n");
        printf("                                     chooses suitable defaults in the absence\n");
        printf("                                     of any -A options.\n");
-       printf("  -l, --max-lpc-order=#              Max LPC order; 0 => only fixed predictors\n");
+       printf("  -l, --max-lpc-order=#              Max LPC order; 0 => only fixed predictors.\n");
+       printf("                                     Must be <= 12 for Subset streams if sample\n");
+       printf("                                     rate is <=48kHz.\n");
        printf("  -p, --qlp-coeff-precision-search   Do exhaustive search of LP coefficient\n");
        printf("                                     quantization (expensive!); overrides -q;\n");
        printf("                                     does nothing if using -l 0\n");
index 389d47e..b394953 100644 (file)
@@ -36,7 +36,7 @@
 #include "bitbuffer.h"
 
 FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitBuffer *bb);
-FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__bool streamable_subset, FLAC__BitBuffer *bb);
+FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitBuffer *bb);
 FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb);
 FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb);
 FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitBuffer *bb);
index ead38c0..123708c 100644 (file)
@@ -742,6 +742,15 @@ FLAC_API FLAC__StreamEncoderInitStatus FLAC__stream_encoder_init_stream(FLAC__St
                        return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
                if(encoder->protected_->max_residual_partition_order > FLAC__SUBSET_MAX_RICE_PARTITION_ORDER)
                        return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
+               if(
+                       encoder->protected_->sample_rate <= 48000 &&
+                       (
+                               encoder->protected_->blocksize > FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ ||
+                               encoder->protected_->max_lpc_order > FLAC__SUBSET_MAX_LPC_ORDER_48000HZ
+                       )
+               ) {
+                       return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
+               }
        }
 
        if(encoder->protected_->max_residual_partition_order >= (1u << FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN))
@@ -2663,7 +2672,7 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f
 
                frame_header.channel_assignment = channel_assignment;
 
-               if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, encoder->private_->frame)) {
+               if(!FLAC__frame_add_header(&frame_header, encoder->private_->frame)) {
                        encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
                        return false;
                }
@@ -2740,7 +2749,7 @@ FLAC__bool process_subframes_(FLAC__StreamEncoder *encoder, FLAC__bool is_last_f
 #endif
        }
        else {
-               if(!FLAC__frame_add_header(&frame_header, encoder->protected_->streamable_subset, encoder->private_->frame)) {
+               if(!FLAC__frame_add_header(&frame_header, encoder->private_->frame)) {
                        encoder->protected_->state = FLAC__STREAM_ENCODER_FRAMING_ERROR;
                        return false;
                }
index 0478f9d..e126f9a 100644 (file)
@@ -216,7 +216,7 @@ FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__
        return true;
 }
 
-FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__bool streamable_subset, FLAC__BitBuffer *bb)
+FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitBuffer *bb)
 {
        unsigned u, blocksize_hint, sample_rate_hint;
 
@@ -251,10 +251,6 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__bool st
                                blocksize_hint = u = 6;
                        else if(header->blocksize <= 0x10000)
                                blocksize_hint = u = 7;
-                       else {
-                               FLAC__ASSERT(0);
-                               return false;
-                       }
                        break;
        }
        if(!FLAC__bitbuffer_write_raw_uint32(bb, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN))
@@ -278,10 +274,6 @@ FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__bool st
                                sample_rate_hint = u = 14;
                        else if(header->sample_rate <= 0xffff)
                                sample_rate_hint = u = 13;
-                       else if(streamable_subset) {
-                               FLAC__ASSERT(0);
-                               return false;
-                       }
                        else
                                u = 0;
                        break;
index 96f2eb4..d3d9fc9 100755 (executable)
@@ -141,50 +141,50 @@ echo "Testing noise through pipes..."
 test_file_piped noise 1 8 "-0"
 
 echo "Testing small files..."
-test_file test01 1 16 "-0 -l $max_lpc_order -m -e -p"
-test_file test02 2 16 "-0 -l $max_lpc_order -m -e -p"
-test_file test03 1 16 "-0 -l $max_lpc_order -m -e -p"
-test_file test04 2 16 "-0 -l $max_lpc_order -m -e -p"
+test_file test01 1 16 "-0 -l $max_lpc_order --lax -m -e -p"
+test_file test02 2 16 "-0 -l $max_lpc_order --lax -m -e -p"
+test_file test03 1 16 "-0 -l $max_lpc_order --lax -m -e -p"
+test_file test04 2 16 "-0 -l $max_lpc_order --lax -m -e -p"
 
 echo "Testing 8-bit full-scale deflection streams..."
 for b in 01 02 03 04 05 06 07 ; do
-       test_file fsd8-$b 1 8 "-0 -l $max_lpc_order -m -e -p"
+       test_file fsd8-$b 1 8 "-0 -l $max_lpc_order --lax -m -e -p"
 done
 
 echo "Testing 16-bit full-scale deflection streams..."
 for b in 01 02 03 04 05 06 07 ; do
-       test_file fsd16-$b 1 16 "-0 -l $max_lpc_order -m -e -p"
+       test_file fsd16-$b 1 16 "-0 -l $max_lpc_order --lax -m -e -p"
 done
 
 echo "Testing 24-bit full-scale deflection streams..."
 for b in 01 02 03 04 05 06 07 ; do
-       test_file fsd24-$b 1 24 "-0 -l $max_lpc_order -m -e -p"
+       test_file fsd24-$b 1 24 "-0 -l $max_lpc_order --lax -m -e -p"
 done
 
 echo "Testing 16-bit wasted-bits-per-sample streams..."
 for b in 01 ; do
-       test_file wbps16-$b 1 16 "-0 -l $max_lpc_order -m -e -p"
+       test_file wbps16-$b 1 16 "-0 -l $max_lpc_order --lax -m -e -p"
 done
 
 for bps in 8 16 24 ; do
        echo "Testing $bps-bit sine wave streams..."
        for b in 00 ; do
-               test_file sine${bps}-$b 1 $bps "-0 -l $max_lpc_order -m -e --sample-rate=48000"
+               test_file sine${bps}-$b 1 $bps "-0 -l $max_lpc_order --lax -m -e --sample-rate=48000"
        done
        for b in 01 ; do
-               test_file sine${bps}-$b 1 $bps "-0 -l $max_lpc_order -m -e --sample-rate=96000"
+               test_file sine${bps}-$b 1 $bps "-0 -l $max_lpc_order --lax -m -e --sample-rate=96000"
        done
        for b in 02 03 04 ; do
-               test_file sine${bps}-$b 1 $bps "-0 -l $max_lpc_order -m -e"
+               test_file sine${bps}-$b 1 $bps "-0 -l $max_lpc_order --lax -m -e"
        done
        for b in 10 11 ; do
-               test_file sine${bps}-$b 2 $bps "-0 -l $max_lpc_order -m -e --sample-rate=48000"
+               test_file sine${bps}-$b 2 $bps "-0 -l $max_lpc_order --lax -m -e --sample-rate=48000"
        done
        for b in 12 ; do
-               test_file sine${bps}-$b 2 $bps "-0 -l $max_lpc_order -m -e --sample-rate=96000"
+               test_file sine${bps}-$b 2 $bps "-0 -l $max_lpc_order --lax -m -e --sample-rate=96000"
        done
        for b in 13 14 15 16 17 18 19 ; do
-               test_file sine${bps}-$b 2 $bps "-0 -l $max_lpc_order -m -e"
+               test_file sine${bps}-$b 2 $bps "-0 -l $max_lpc_order --lax -m -e"
        done
 done
 
@@ -221,7 +221,7 @@ for f in 00 01 02 03 04 ; do
                                done
                        done
                        if [ "$FLAC__TEST_LEVEL" -gt 1 ] ; then
-                               test_file sine16-$f 1 16 "-b 16384 -m -r 8 -l $max_lpc_order -e -p $disable"
+                               test_file sine16-$f 1 16 "-b 16384 -m -r 8 -l $max_lpc_order --lax -e -p $disable"
                        fi
                fi
        done
@@ -238,7 +238,7 @@ for f in 10 11 12 13 14 15 16 17 18 19 ; do
                                done
                        done
                        if [ "$FLAC__TEST_LEVEL" -gt 1 ] ; then
-                               test_file sine16-$f 2 16 "-b 16384 -m -r 8 -l $max_lpc_order -e -p $disable"
+                               test_file sine16-$f 2 16 "-b 16384 -m -r 8 -l $max_lpc_order --lax -e -p $disable"
                        fi
                fi
        done
@@ -262,7 +262,7 @@ for disable in '' '--disable-verbatim-subframes --disable-constant-subframes' '-
                                                done
                                        done
                                        if [ "$FLAC__TEST_LEVEL" -gt 1 ] ; then
-                                               test_file noise $channels $bps "-b 16384 -m -r 8 -l $max_lpc_order -e -p $disable"
+                                               test_file noise $channels $bps "-b 16384 -m -r 8 -l $max_lpc_order --lax -e -p $disable"
                                        fi
                                done
                        fi