diff --git a/doc/html/changelog.html b/doc/html/changelog.html
index b91843f1..e9a2c699 100644
--- a/doc/html/changelog.html
+++ b/doc/html/changelog.html
@@ -119,7 +119,7 @@
libFLAC:
- - (none)
+ - Added FLAC__format_sample_rate_is_subset()
diff --git a/include/FLAC/format.h b/include/FLAC/format.h
index 39d308fe..9e744cdd 100644
--- a/include/FLAC/format.h
+++ b/include/FLAC/format.h
@@ -851,8 +851,7 @@ extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bit
*
*****************************************************************************/
-/** Tests that a sample rate is valid for FLAC. Since the rules for valid
- * sample rates are slightly complex, they are encapsulated in this function.
+/** Tests that a sample rate is valid for FLAC.
*
* \param sample_rate The sample rate to test for compliance.
* \retval FLAC__bool
@@ -861,6 +860,17 @@ extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bit
*/
FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate);
+/** Tests that a sample rate is valid for the FLAC subset. The subset rules
+ * for valid sample rates are slightly more complex since the rate has to
+ * be expressible completely in the frame header.
+ *
+ * \param sample_rate The sample rate to test for compliance.
+ * \retval FLAC__bool
+ * \c true if the given sample rate conforms to the specification for the
+ * subset, else \c false.
+ */
+FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate);
+
/** Check a Vorbis comment entry name to see if it conforms to the Vorbis
* comment specification.
*
diff --git a/src/libFLAC/format.c b/src/libFLAC/format.c
index da341ad5..de911ac3 100644
--- a/src/libFLAC/format.c
+++ b/src/libFLAC/format.c
@@ -210,10 +210,18 @@ FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = {
};
FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate)
+{
+ if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) {
+ return false;
+ }
+ else
+ return true;
+}
+
+FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate)
{
if(
- sample_rate == 0 ||
- sample_rate > FLAC__MAX_SAMPLE_RATE ||
+ !FLAC__format_sample_rate_is_valid(sample_rate) ||
(
sample_rate >= (1u << 16) &&
!(sample_rate % 1000 == 0 || sample_rate % 10 == 0)
diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c
index 489c3220..76173f05 100644
--- a/src/libFLAC/stream_encoder.c
+++ b/src/libFLAC/stream_encoder.c
@@ -739,16 +739,7 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_(
encoder->protected_->blocksize != 16384
)
return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
- if(
- encoder->protected_->sample_rate != 8000 &&
- encoder->protected_->sample_rate != 16000 &&
- encoder->protected_->sample_rate != 22050 &&
- encoder->protected_->sample_rate != 24000 &&
- encoder->protected_->sample_rate != 32000 &&
- encoder->protected_->sample_rate != 44100 &&
- encoder->protected_->sample_rate != 48000 &&
- encoder->protected_->sample_rate != 96000
- )
+ if(!FLAC__format_sample_rate_is_subset(encoder->protected_->sample_rate))
return FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE;
if(
encoder->protected_->bits_per_sample != 8 &&
diff --git a/src/test_libFLAC/format.c b/src/test_libFLAC/format.c
index 74f62bed..5d68d03a 100644
--- a/src/test_libFLAC/format.c
+++ b/src/test_libFLAC/format.c
@@ -29,41 +29,46 @@ static const char *true_false_string_[2] = { "false", "true" };
static struct {
unsigned rate;
FLAC__bool valid;
+ FLAC__bool subset;
} SAMPLE_RATES[] = {
- { 0 , false },
- { 1 , true },
- { 9 , true },
- { 10 , true },
- { 4000 , true },
- { 8000 , true },
- { 11025 , true },
- { 12000 , true },
- { 16000 , true },
- { 22050 , true },
- { 24000 , true },
- { 32000 , true },
- { 32768 , true },
- { 44100 , true },
- { 48000 , true },
- { 65000 , true },
- { 65535 , true },
- { 65536 , false },
- { 65540 , true },
- { 65550 , true },
- { 65555 , false },
- { 66000 , true },
- { 66001 , false },
- { 96000 , true },
- { 100000 , true },
- { 100001 , false },
- { 192000 , true },
- { 500000 , true },
- { 500001 , false },
- { 500010 , true },
- { 700000 , false },
- { 700010 , false },
- { 1000000, false },
- { 1100000, false }
+ { 0 , false, false },
+ { 1 , true , true },
+ { 9 , true , true },
+ { 10 , true , true },
+ { 4000 , true , true },
+ { 8000 , true , true },
+ { 11025 , true , true },
+ { 12000 , true , true },
+ { 16000 , true , true },
+ { 22050 , true , true },
+ { 24000 , true , true },
+ { 32000 , true , true },
+ { 32768 , true , true },
+ { 44100 , true , true },
+ { 48000 , true , true },
+ { 65000 , true , true },
+ { 65535 , true , true },
+ { 65536 , true , false },
+ { 65540 , true , true },
+ { 65550 , true , true },
+ { 65555 , true , false },
+ { 66000 , true , true },
+ { 66001 , true , false },
+ { 96000 , true , true },
+ { 100000 , true , true },
+ { 100001 , true , false },
+ { 192000 , true , true },
+ { 500000 , true , true },
+ { 500001 , true , false },
+ { 500010 , true , true },
+ { 655349 , true , false },
+ { 655350 , true , true },
+ { 655351 , false, false },
+ { 655360 , false, false },
+ { 700000 , false, false },
+ { 700010 , false, false },
+ { 1000000, false, false },
+ { 1100000, false, false }
};
static struct {
@@ -200,6 +205,15 @@ FLAC__bool test_format(void)
printf("OK\n");
}
+ for(i = 0; i < sizeof(SAMPLE_RATES)/sizeof(SAMPLE_RATES[0]); i++) {
+ printf("testing FLAC__format_sample_rate_is_subset(%u)... ", SAMPLE_RATES[i].rate);
+ if(FLAC__format_sample_rate_is_subset(SAMPLE_RATES[i].rate) != SAMPLE_RATES[i].subset) {
+ printf("FAILED, expected %s, got %s\n", true_false_string_[SAMPLE_RATES[i].subset], true_false_string_[!SAMPLE_RATES[i].subset]);
+ return false;
+ }
+ printf("OK\n");
+ }
+
for(i = 0; i < sizeof(VCENTRY_NAMES)/sizeof(VCENTRY_NAMES[0]); i++) {
printf("testing FLAC__format_vorbiscomment_entry_name_is_legal(\"%s\")... ", VCENTRY_NAMES[i].string);
if(FLAC__format_vorbiscomment_entry_name_is_legal(VCENTRY_NAMES[i].string) != VCENTRY_NAMES[i].valid) {