move common stuff into metadata_utils

This commit is contained in:
Josh Coalson
2003-01-10 05:40:09 +00:00
parent 26dff91df1
commit a52a5554bf
8 changed files with 105 additions and 831 deletions

View File

@@ -19,6 +19,7 @@
#include "decoders.h" #include "decoders.h"
extern "C" { extern "C" {
#include "file_utils.h" #include "file_utils.h"
#include "metadata_utils.h"
} }
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal() #include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal()
@@ -29,8 +30,8 @@ extern "C" {
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_; static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_;
static ::FLAC__StreamMetadata *expected_metadata_sequence_[6]; static ::FLAC__StreamMetadata *expected_metadata_sequence_[7];
static unsigned num_expected_; static unsigned num_expected_;
static const char *flacfilename_ = "metadata.flac"; static const char *flacfilename_ = "metadata.flac";
static unsigned flacfilesize_; static unsigned flacfilesize_;
@@ -41,106 +42,27 @@ static bool die_(const char *msg)
return false; return false;
} }
static void *malloc_or_die_(size_t size)
{
void *x = malloc(size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
exit(1);
}
return x;
}
static void init_metadata_blocks_() static void init_metadata_blocks_()
{ {
/* mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
most of the actual numbers and data in the blocks don't matter,
we just want to make sure the decoder parses them correctly
remember, the metadata interface gets tested after the decoders,
so we do all the metadata manipulation here without it.
*/
/* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
streaminfo_.is_last = false;
streaminfo_.type = ::FLAC__METADATA_TYPE_STREAMINFO;
streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
streaminfo_.data.stream_info.min_blocksize = 576;
streaminfo_.data.stream_info.max_blocksize = 576;
streaminfo_.data.stream_info.min_framesize = 0;
streaminfo_.data.stream_info.max_framesize = 0;
streaminfo_.data.stream_info.sample_rate = 44100;
streaminfo_.data.stream_info.channels = 1;
streaminfo_.data.stream_info.bits_per_sample = 8;
streaminfo_.data.stream_info.total_samples = 0;
memset(streaminfo_.data.stream_info.md5sum, 0, 16);
padding_.is_last = false;
padding_.type = ::FLAC__METADATA_TYPE_PADDING;
padding_.length = 1234;
seektable_.is_last = false;
seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE;
seektable_.data.seek_table.num_points = 2;
seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
seektable_.data.seek_table.points = (::FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetadata_SeekPoint));
seektable_.data.seek_table.points[0].sample_number = 0;
seektable_.data.seek_table.points[0].stream_offset = 0;
seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
seektable_.data.seek_table.points[1].stream_offset = 1000;
seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
application1_.is_last = false;
application1_.type = ::FLAC__METADATA_TYPE_APPLICATION;
application1_.length = 8;
memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
application1_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
application2_.is_last = false;
application2_.type = ::FLAC__METADATA_TYPE_APPLICATION;
application2_.length = 4;
memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
application2_.data.application.data = 0;
{
const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
vorbiscomment_.is_last = true;
vorbiscomment_.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment_.length = (4 + vendor_string_length) + 4 + (4 + 5) + (4 + 0);
vorbiscomment_.data.vorbis_comment.vendor_string.length = vendor_string_length;
vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
vorbiscomment_.data.vorbis_comment.num_comments = 2;
vorbiscomment_.data.vorbis_comment.comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
}
} }
static void free_metadata_blocks_() static void free_metadata_blocks_()
{ {
free(seektable_.data.seek_table.points); mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
free(application1_.data.application.data);
free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
free(vorbiscomment_.data.vorbis_comment.comments);
} }
static bool generate_file_() static bool generate_file_()
{ {
printf("\n\ngenerating FLAC file for decoder tests...\n"); printf("\n\ngenerating FLAC file for decoder tests...\n");
expected_metadata_sequence_[0] = &padding_; num_expected_ = 0;
expected_metadata_sequence_[1] = &seektable_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[2] = &application1_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[3] = &application2_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[4] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &application2_;
num_expected_ = 5; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!file_utils__generate_flacfile(flacfilename_, &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_)) if(!file_utils__generate_flacfile(flacfilename_, &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
return die_("creating the encoded file"); return die_("creating the encoded file");
@@ -521,6 +443,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -565,6 +488,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -592,6 +516,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -620,6 +545,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -654,6 +580,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -794,6 +721,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -837,6 +765,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
::fclose(decoder->file_); ::fclose(decoder->file_);
@@ -1229,6 +1158,7 @@ static bool test_seekable_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1273,6 +1203,7 @@ static bool test_seekable_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1300,6 +1231,7 @@ static bool test_seekable_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1328,6 +1260,7 @@ static bool test_seekable_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1362,6 +1295,7 @@ static bool test_seekable_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1502,6 +1436,7 @@ static bool test_seekable_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1545,6 +1480,7 @@ static bool test_seekable_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
::fclose(decoder->file_); ::fclose(decoder->file_);
@@ -1847,6 +1783,7 @@ static bool test_file_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1891,6 +1828,7 @@ static bool test_file_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1918,6 +1856,7 @@ static bool test_file_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1946,6 +1885,7 @@ static bool test_file_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -1980,6 +1920,7 @@ static bool test_file_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -2120,6 +2061,7 @@ static bool test_file_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -2163,6 +2105,7 @@ static bool test_file_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
printf("freeing decoder instance... "); printf("freeing decoder instance... ");
delete decoder; delete decoder;
@@ -2176,6 +2119,7 @@ static bool test_file_decoder()
bool test_decoders() bool test_decoders()
{ {
init_metadata_blocks_(); init_metadata_blocks_();
if(!generate_file_()) if(!generate_file_())
return false; return false;
@@ -2189,6 +2133,7 @@ bool test_decoders()
return false; return false;
(void) grabbag__file_remove_file(flacfilename_); (void) grabbag__file_remove_file(flacfilename_);
free_metadata_blocks_(); free_metadata_blocks_();
return true; return true;

View File

@@ -19,6 +19,7 @@
#include "encoders.h" #include "encoders.h"
extern "C" { extern "C" {
#include "file_utils.h" #include "file_utils.h"
#include "metadata_utils.h"
} }
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "FLAC++/encoder.h" #include "FLAC++/encoder.h"
@@ -26,96 +27,19 @@ extern "C" {
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_; static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_;
static ::FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_ }; static ::FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_ };
static const unsigned num_metadata_ = 5; static const unsigned num_metadata_ = sizeof(metadata_sequence_) / sizeof(metadata_sequence_[0]);
static const char *flacfilename_ = "metadata.flac"; static const char *flacfilename_ = "metadata.flac";
static void *malloc_or_die_(size_t size)
{
void *x = malloc(size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
exit(1);
}
return x;
}
static void init_metadata_blocks_() static void init_metadata_blocks_()
{ {
/* mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
most of the actual numbers and data in the blocks don't matter,
we just want to make sure the encoder encodes them correctly
remember, the metadata interface gets tested after the encoders,
so we do all the metadata manipulation here without it.
*/
/* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
streaminfo_.is_last = false;
streaminfo_.type = ::FLAC__METADATA_TYPE_STREAMINFO;
streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
streaminfo_.data.stream_info.min_blocksize = 576;
streaminfo_.data.stream_info.max_blocksize = 576;
streaminfo_.data.stream_info.min_framesize = 0;
streaminfo_.data.stream_info.max_framesize = 0;
streaminfo_.data.stream_info.sample_rate = 44100;
streaminfo_.data.stream_info.channels = 1;
streaminfo_.data.stream_info.bits_per_sample = 8;
streaminfo_.data.stream_info.total_samples = 0;
memset(streaminfo_.data.stream_info.md5sum, 0, 16);
padding_.is_last = false;
padding_.type = ::FLAC__METADATA_TYPE_PADDING;
padding_.length = 1234;
seektable_.is_last = false;
seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE;
seektable_.data.seek_table.num_points = 2;
seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
seektable_.data.seek_table.points = (::FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetadata_SeekPoint));
seektable_.data.seek_table.points[0].sample_number = 0;
seektable_.data.seek_table.points[0].stream_offset = 0;
seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
seektable_.data.seek_table.points[1].stream_offset = 1000;
seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
application1_.is_last = false;
application1_.type = ::FLAC__METADATA_TYPE_APPLICATION;
application1_.length = 8;
memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
application1_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
application2_.is_last = false;
application2_.type = ::FLAC__METADATA_TYPE_APPLICATION;
application2_.length = 4;
memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
application2_.data.application.data = 0;
vorbiscomment_.is_last = true;
vorbiscomment_.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0);
vorbiscomment_.data.vorbis_comment.vendor_string.length = 8;
vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(8);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "flac 1.x", 8);
vorbiscomment_.data.vorbis_comment.num_comments = 2;
vorbiscomment_.data.vorbis_comment.comments = (::FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(::FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
} }
static void free_metadata_blocks_() static void free_metadata_blocks_()
{ {
free(seektable_.data.seek_table.points); mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
free(application1_.data.application.data);
free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
free(vorbiscomment_.data.vorbis_comment.comments);
} }
class StreamEncoder : public FLAC::Encoder::Stream { class StreamEncoder : public FLAC::Encoder::Stream {

View File

@@ -105,179 +105,27 @@ static FLAC__bool die_f_(const char *msg, const FLAC__FileDecoder *decoder)
return false; return false;
} }
static void *malloc_or_die_(size_t size)
{
void *x = malloc(size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
exit(1);
}
return x;
}
static void *calloc_or_die_(size_t n, size_t size)
{
void *x = calloc(n, size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)n * (unsigned)size);
exit(1);
}
return x;
}
static void init_metadata_blocks_() static void init_metadata_blocks_()
{ {
/* mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
most of the actual numbers and data in the blocks don't matter,
we just want to make sure the decoder parses them correctly
remember, the metadata interface gets tested after the decoders,
so we do all the metadata manipulation here without it.
*/
/* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
streaminfo_.is_last = false;
streaminfo_.type = FLAC__METADATA_TYPE_STREAMINFO;
streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
streaminfo_.data.stream_info.min_blocksize = 576;
streaminfo_.data.stream_info.max_blocksize = 576;
streaminfo_.data.stream_info.min_framesize = 0;
streaminfo_.data.stream_info.max_framesize = 0;
streaminfo_.data.stream_info.sample_rate = 44100;
streaminfo_.data.stream_info.channels = 1;
streaminfo_.data.stream_info.bits_per_sample = 8;
streaminfo_.data.stream_info.total_samples = 0;
memset(streaminfo_.data.stream_info.md5sum, 0, 16);
padding_.is_last = false;
padding_.type = FLAC__METADATA_TYPE_PADDING;
padding_.length = 1234;
seektable_.is_last = false;
seektable_.type = FLAC__METADATA_TYPE_SEEKTABLE;
seektable_.data.seek_table.num_points = 2;
seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
seektable_.data.seek_table.points = malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint));
seektable_.data.seek_table.points[0].sample_number = 0;
seektable_.data.seek_table.points[0].stream_offset = 0;
seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
seektable_.data.seek_table.points[1].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
seektable_.data.seek_table.points[1].stream_offset = 1000;
seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
application1_.is_last = false;
application1_.type = FLAC__METADATA_TYPE_APPLICATION;
application1_.length = 8;
memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
application1_.data.application.data = malloc_or_die_(4);
memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
application2_.is_last = false;
application2_.type = FLAC__METADATA_TYPE_APPLICATION;
application2_.length = 4;
memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
application2_.data.application.data = 0;
{
const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
vorbiscomment_.is_last = true;
vorbiscomment_.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment_.length = (4 + vendor_string_length) + 4 + (4 + 5) + (4 + 0);
vorbiscomment_.data.vorbis_comment.vendor_string.length = vendor_string_length;
vorbiscomment_.data.vorbis_comment.vendor_string.entry = malloc_or_die_(vendor_string_length);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
vorbiscomment_.data.vorbis_comment.num_comments = 2;
vorbiscomment_.data.vorbis_comment.comments = malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
vorbiscomment_.data.vorbis_comment.comments[0].entry = malloc_or_die_(5);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
}
cuesheet_.is_last = true;
cuesheet_.type = FLAC__METADATA_TYPE_CUESHEET;
cuesheet_.length =
/* cuesheet guts */
(
FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN +
FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN +
FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN +
FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN +
FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN
) / 8 +
/* 2 tracks */
3 * (
FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN
) / 8 +
/* 3 index points */
3 * (
FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN +
FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN +
FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN
) / 8
;
memset(cuesheet_.data.cue_sheet.media_catalog_number, 0, sizeof(cuesheet_.data.cue_sheet.media_catalog_number));
cuesheet_.data.cue_sheet.media_catalog_number[0] = 'j';
cuesheet_.data.cue_sheet.media_catalog_number[1] = 'C';
cuesheet_.data.cue_sheet.lead_in = 2 * 44100;
cuesheet_.data.cue_sheet.is_cd = true;
cuesheet_.data.cue_sheet.num_tracks = 3;
cuesheet_.data.cue_sheet.tracks = calloc_or_die_(cuesheet_.data.cue_sheet.num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track));
cuesheet_.data.cue_sheet.tracks[0].offset = 0;
cuesheet_.data.cue_sheet.tracks[0].number = 1;
memcpy(cuesheet_.data.cue_sheet.tracks[0].isrc, "ACBDE1234567", sizeof(cuesheet_.data.cue_sheet.tracks[0].isrc));
cuesheet_.data.cue_sheet.tracks[0].type = 0;
cuesheet_.data.cue_sheet.tracks[0].pre_emphasis = 1;
cuesheet_.data.cue_sheet.tracks[0].num_indices = 2;
cuesheet_.data.cue_sheet.tracks[0].indices = malloc_or_die_(cuesheet_.data.cue_sheet.tracks[0].num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
cuesheet_.data.cue_sheet.tracks[0].indices[0].offset = 0;
cuesheet_.data.cue_sheet.tracks[0].indices[0].number = 0;
cuesheet_.data.cue_sheet.tracks[0].indices[1].offset = 123 * 588;
cuesheet_.data.cue_sheet.tracks[0].indices[1].number = 1;
cuesheet_.data.cue_sheet.tracks[1].offset = 1234 * 588;
cuesheet_.data.cue_sheet.tracks[1].number = 2;
memcpy(cuesheet_.data.cue_sheet.tracks[1].isrc, "ACBDE7654321", sizeof(cuesheet_.data.cue_sheet.tracks[1].isrc));
cuesheet_.data.cue_sheet.tracks[1].type = 1;
cuesheet_.data.cue_sheet.tracks[1].pre_emphasis = 0;
cuesheet_.data.cue_sheet.tracks[1].num_indices = 1;
cuesheet_.data.cue_sheet.tracks[1].indices = malloc_or_die_(cuesheet_.data.cue_sheet.tracks[1].num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
cuesheet_.data.cue_sheet.tracks[1].indices[0].offset = 0;
cuesheet_.data.cue_sheet.tracks[1].indices[0].number = 1;
cuesheet_.data.cue_sheet.tracks[2].offset = 12345 * 588;
cuesheet_.data.cue_sheet.tracks[2].number = 170;
cuesheet_.data.cue_sheet.tracks[2].num_indices = 0;
} }
static void free_metadata_blocks_() static void free_metadata_blocks_()
{ {
free(seektable_.data.seek_table.points); mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
free(application1_.data.application.data);
free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
free(vorbiscomment_.data.vorbis_comment.comments);
free(cuesheet_.data.cue_sheet.tracks[0].indices);
free(cuesheet_.data.cue_sheet.tracks[1].indices);
free(cuesheet_.data.cue_sheet.tracks);
} }
static FLAC__bool generate_file_() static FLAC__bool generate_file_()
{ {
printf("\n\ngenerating FLAC file for decoder tests...\n"); printf("\n\ngenerating FLAC file for decoder tests...\n");
expected_metadata_sequence_[0] = &padding_; num_expected_ = 0;
expected_metadata_sequence_[1] = &seektable_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[2] = &application1_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[3] = &application2_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[4] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[5] = &cuesheet_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
num_expected_ = 6; expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!file_utils__generate_flacfile(flacfilename_, &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_)) if(!file_utils__generate_flacfile(flacfilename_, &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
return die_("creating the encoded file"); return die_("creating the encoded file");
@@ -365,7 +213,7 @@ static void stream_decoder_metadata_callback_(const FLAC__StreamDecoder *decoder
dcd->error_occurred = true; dcd->error_occurred = true;
} }
else { else {
if(!compare_block_(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) { if(!mutils__compare_block(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) {
(void)die_("metadata block mismatch"); (void)die_("metadata block mismatch");
dcd->error_occurred = true; dcd->error_occurred = true;
} }

View File

@@ -18,6 +18,7 @@
#include "encoders.h" #include "encoders.h"
#include "file_utils.h" #include "file_utils.h"
#include "metadata_utils.h"
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "FLAC/file_encoder.h" #include "FLAC/file_encoder.h"
#include "FLAC/seekable_stream_encoder.h" #include "FLAC/seekable_stream_encoder.h"
@@ -29,7 +30,7 @@
static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_; static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_;
static FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_ }; static FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_ };
static const unsigned num_metadata_ = 6; static const unsigned num_metadata_ = sizeof(metadata_sequence_) / sizeof(metadata_sequence_[0]);
static const char *flacfilename_ = "metadata.flac"; static const char *flacfilename_ = "metadata.flac";
static FLAC__bool die_s_(const char *msg, const FLAC__StreamEncoder *encoder) static FLAC__bool die_s_(const char *msg, const FLAC__StreamEncoder *encoder)
@@ -98,163 +99,14 @@ static FLAC__bool die_f_(const char *msg, const FLAC__FileEncoder *encoder)
return false; return false;
} }
static void *malloc_or_die_(size_t size)
{
void *x = malloc(size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
exit(1);
}
return x;
}
static void *calloc_or_die_(size_t n, size_t size)
{
void *x = calloc(n, size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)n*(unsigned)size);
exit(1);
}
return x;
}
static void init_metadata_blocks_() static void init_metadata_blocks_()
{ {
/* mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
most of the actual numbers and data in the blocks don't matter,
we just want to make sure the encoder encodes them correctly
remember, the metadata interface gets tested after the encoders,
so we do all the metadata manipulation here without it.
*/
/* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
streaminfo_.is_last = false;
streaminfo_.type = FLAC__METADATA_TYPE_STREAMINFO;
streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
streaminfo_.data.stream_info.min_blocksize = 576;
streaminfo_.data.stream_info.max_blocksize = 576;
streaminfo_.data.stream_info.min_framesize = 0;
streaminfo_.data.stream_info.max_framesize = 0;
streaminfo_.data.stream_info.sample_rate = 44100;
streaminfo_.data.stream_info.channels = 1;
streaminfo_.data.stream_info.bits_per_sample = 8;
streaminfo_.data.stream_info.total_samples = 0;
memset(streaminfo_.data.stream_info.md5sum, 0, 16);
padding_.is_last = false;
padding_.type = FLAC__METADATA_TYPE_PADDING;
padding_.length = 1234;
seektable_.is_last = false;
seektable_.type = FLAC__METADATA_TYPE_SEEKTABLE;
seektable_.data.seek_table.num_points = 2;
seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
seektable_.data.seek_table.points = (FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint));
seektable_.data.seek_table.points[0].sample_number = 0;
seektable_.data.seek_table.points[0].stream_offset = 0;
seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
seektable_.data.seek_table.points[1].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
seektable_.data.seek_table.points[1].stream_offset = 1000;
seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
application1_.is_last = false;
application1_.type = FLAC__METADATA_TYPE_APPLICATION;
application1_.length = 8;
memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
application1_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
application2_.is_last = false;
application2_.type = FLAC__METADATA_TYPE_APPLICATION;
application2_.length = 4;
memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
application2_.data.application.data = 0;
vorbiscomment_.is_last = false;
vorbiscomment_.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0);
vorbiscomment_.data.vorbis_comment.vendor_string.length = 8;
vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(8);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "flac 1.x", 8);
vorbiscomment_.data.vorbis_comment.num_comments = 2;
vorbiscomment_.data.vorbis_comment.comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
cuesheet_.is_last = true;
cuesheet_.type = FLAC__METADATA_TYPE_CUESHEET;
cuesheet_.length =
/* cuesheet guts */
(
FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN +
FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN +
FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN +
FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN +
FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN
) / 8 +
/* 2 tracks */
3 * (
FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN +
FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN
) / 8 +
/* 3 index points */
3 * (
FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN +
FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN +
FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN
) / 8
;
memset(cuesheet_.data.cue_sheet.media_catalog_number, 0, sizeof(cuesheet_.data.cue_sheet.media_catalog_number));
cuesheet_.data.cue_sheet.media_catalog_number[0] = 'j';
cuesheet_.data.cue_sheet.media_catalog_number[1] = 'C';
cuesheet_.data.cue_sheet.lead_in = 2 * 44100;
cuesheet_.data.cue_sheet.is_cd = true;
cuesheet_.data.cue_sheet.num_tracks = 3;
cuesheet_.data.cue_sheet.tracks = calloc_or_die_(cuesheet_.data.cue_sheet.num_tracks, sizeof(FLAC__StreamMetadata_CueSheet_Track));
cuesheet_.data.cue_sheet.tracks[0].offset = 0;
cuesheet_.data.cue_sheet.tracks[0].number = 1;
memcpy(cuesheet_.data.cue_sheet.tracks[0].isrc, "ACBDE1234567", sizeof(cuesheet_.data.cue_sheet.tracks[0].isrc));
cuesheet_.data.cue_sheet.tracks[0].type = 0;
cuesheet_.data.cue_sheet.tracks[0].pre_emphasis = 1;
cuesheet_.data.cue_sheet.tracks[0].num_indices = 2;
cuesheet_.data.cue_sheet.tracks[0].indices = malloc_or_die_(cuesheet_.data.cue_sheet.tracks[0].num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
cuesheet_.data.cue_sheet.tracks[0].indices[0].offset = 0;
cuesheet_.data.cue_sheet.tracks[0].indices[0].number = 0;
cuesheet_.data.cue_sheet.tracks[0].indices[1].offset = 123 * 588;
cuesheet_.data.cue_sheet.tracks[0].indices[1].number = 1;
cuesheet_.data.cue_sheet.tracks[1].offset = 1234 * 588;
cuesheet_.data.cue_sheet.tracks[1].number = 2;
memcpy(cuesheet_.data.cue_sheet.tracks[1].isrc, "ACBDE7654321", sizeof(cuesheet_.data.cue_sheet.tracks[1].isrc));
cuesheet_.data.cue_sheet.tracks[1].type = 1;
cuesheet_.data.cue_sheet.tracks[1].pre_emphasis = 0;
cuesheet_.data.cue_sheet.tracks[1].num_indices = 1;
cuesheet_.data.cue_sheet.tracks[1].indices = malloc_or_die_(cuesheet_.data.cue_sheet.tracks[1].num_indices * sizeof(FLAC__StreamMetadata_CueSheet_Index));
cuesheet_.data.cue_sheet.tracks[1].indices[0].offset = 0;
cuesheet_.data.cue_sheet.tracks[1].indices[0].number = 1;
cuesheet_.data.cue_sheet.tracks[2].offset = 12345 * 588;
cuesheet_.data.cue_sheet.tracks[2].number = 170;
cuesheet_.data.cue_sheet.tracks[2].num_indices = 0;
} }
static void free_metadata_blocks_() static void free_metadata_blocks_()
{ {
free(seektable_.data.seek_table.points); mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
free(application1_.data.application.data);
free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
free(vorbiscomment_.data.vorbis_comment.comments);
free(cuesheet_.data.cue_sheet.tracks[0].indices);
free(cuesheet_.data.cue_sheet.tracks[1].indices);
free(cuesheet_.data.cue_sheet.tracks);
} }
static FLAC__StreamEncoderWriteStatus stream_encoder_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) static FLAC__StreamEncoderWriteStatus stream_encoder_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)

View File

@@ -19,6 +19,7 @@
#include "decoders.h" #include "decoders.h"
extern "C" { extern "C" {
#include "file_utils.h" #include "file_utils.h"
#include "metadata_utils.h"
} }
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal() #include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal()
@@ -29,8 +30,8 @@ extern "C" {
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_; static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_;
static ::FLAC__StreamMetadata *expected_metadata_sequence_[6]; static ::FLAC__StreamMetadata *expected_metadata_sequence_[7];
static unsigned num_expected_; static unsigned num_expected_;
static const char *oggflacfilename_ = "metadata.ogg"; static const char *oggflacfilename_ = "metadata.ogg";
static unsigned oggflacfilesize_; static unsigned oggflacfilesize_;
@@ -41,106 +42,27 @@ static bool die_(const char *msg)
return false; return false;
} }
static void *malloc_or_die_(size_t size)
{
void *x = malloc(size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
exit(1);
}
return x;
}
static void init_metadata_blocks_() static void init_metadata_blocks_()
{ {
/* mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
most of the actual numbers and data in the blocks don't matter,
we just want to make sure the decoder parses them correctly
remember, the metadata interface gets tested after the decoders,
so we do all the metadata manipulation here without it.
*/
/* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
streaminfo_.is_last = false;
streaminfo_.type = ::FLAC__METADATA_TYPE_STREAMINFO;
streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
streaminfo_.data.stream_info.min_blocksize = 576;
streaminfo_.data.stream_info.max_blocksize = 576;
streaminfo_.data.stream_info.min_framesize = 0;
streaminfo_.data.stream_info.max_framesize = 0;
streaminfo_.data.stream_info.sample_rate = 44100;
streaminfo_.data.stream_info.channels = 1;
streaminfo_.data.stream_info.bits_per_sample = 8;
streaminfo_.data.stream_info.total_samples = 0;
memset(streaminfo_.data.stream_info.md5sum, 0, 16);
padding_.is_last = false;
padding_.type = ::FLAC__METADATA_TYPE_PADDING;
padding_.length = 1234;
seektable_.is_last = false;
seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE;
seektable_.data.seek_table.num_points = 2;
seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
seektable_.data.seek_table.points = (::FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetadata_SeekPoint));
seektable_.data.seek_table.points[0].sample_number = 0;
seektable_.data.seek_table.points[0].stream_offset = 0;
seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
seektable_.data.seek_table.points[1].stream_offset = 1000;
seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
application1_.is_last = false;
application1_.type = ::FLAC__METADATA_TYPE_APPLICATION;
application1_.length = 8;
memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
application1_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
application2_.is_last = false;
application2_.type = ::FLAC__METADATA_TYPE_APPLICATION;
application2_.length = 4;
memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
application2_.data.application.data = 0;
{
const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
vorbiscomment_.is_last = true;
vorbiscomment_.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment_.length = (4 + vendor_string_length) + 4 + (4 + 5) + (4 + 0);
vorbiscomment_.data.vorbis_comment.vendor_string.length = vendor_string_length;
vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(vendor_string_length);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
vorbiscomment_.data.vorbis_comment.num_comments = 2;
vorbiscomment_.data.vorbis_comment.comments = (FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
}
} }
static void free_metadata_blocks_() static void free_metadata_blocks_()
{ {
free(seektable_.data.seek_table.points); mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
free(application1_.data.application.data);
free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
free(vorbiscomment_.data.vorbis_comment.comments);
} }
static bool generate_file_() static bool generate_file_()
{ {
printf("\n\ngenerating Ogg FLAC file for decoder tests...\n"); printf("\n\ngenerating Ogg FLAC file for decoder tests...\n");
expected_metadata_sequence_[0] = &padding_; num_expected_ = 0;
expected_metadata_sequence_[1] = &seektable_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[2] = &application1_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[3] = &application2_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[4] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &application2_;
num_expected_ = 5; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!file_utils__generate_oggflacfile(oggflacfilename_, &oggflacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_)) if(!file_utils__generate_oggflacfile(oggflacfilename_, &oggflacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
return die_("creating the encoded file"); return die_("creating the encoded file");
@@ -530,6 +452,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -574,6 +497,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -601,6 +525,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -629,6 +554,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -663,6 +589,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -803,6 +730,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!decoder->test_respond()) if(!decoder->test_respond())
return false; return false;
@@ -846,6 +774,7 @@ static bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
::fclose(decoder->file_); ::fclose(decoder->file_);

View File

@@ -19,6 +19,7 @@
#include "encoders.h" #include "encoders.h"
extern "C" { extern "C" {
#include "file_utils.h" #include "file_utils.h"
#include "metadata_utils.h"
} }
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "OggFLAC++/encoder.h" #include "OggFLAC++/encoder.h"
@@ -26,95 +27,18 @@ extern "C" {
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_; static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_;
static ::FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_ }; static ::FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_ };
static const unsigned num_metadata_ = 5; static const unsigned num_metadata_ = sizeof(metadata_sequence_) / sizeof(metadata_sequence_[0]);
static void *malloc_or_die_(size_t size)
{
void *x = malloc(size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
exit(1);
}
return x;
}
static void init_metadata_blocks_() static void init_metadata_blocks_()
{ {
/* mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
most of the actual numbers and data in the blocks don't matter,
we just want to make sure the encoder encodes them correctly
remember, the metadata interface gets tested after the encoders,
so we do all the metadata manipulation here without it.
*/
/* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
streaminfo_.is_last = false;
streaminfo_.type = ::FLAC__METADATA_TYPE_STREAMINFO;
streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
streaminfo_.data.stream_info.min_blocksize = 576;
streaminfo_.data.stream_info.max_blocksize = 576;
streaminfo_.data.stream_info.min_framesize = 0;
streaminfo_.data.stream_info.max_framesize = 0;
streaminfo_.data.stream_info.sample_rate = 44100;
streaminfo_.data.stream_info.channels = 1;
streaminfo_.data.stream_info.bits_per_sample = 8;
streaminfo_.data.stream_info.total_samples = 0;
memset(streaminfo_.data.stream_info.md5sum, 0, 16);
padding_.is_last = false;
padding_.type = ::FLAC__METADATA_TYPE_PADDING;
padding_.length = 1234;
seektable_.is_last = false;
seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE;
seektable_.data.seek_table.num_points = 2;
seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
seektable_.data.seek_table.points = (::FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetadata_SeekPoint));
seektable_.data.seek_table.points[0].sample_number = 0;
seektable_.data.seek_table.points[0].stream_offset = 0;
seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
seektable_.data.seek_table.points[1].stream_offset = 1000;
seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
application1_.is_last = false;
application1_.type = ::FLAC__METADATA_TYPE_APPLICATION;
application1_.length = 8;
memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
application1_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
application2_.is_last = false;
application2_.type = ::FLAC__METADATA_TYPE_APPLICATION;
application2_.length = 4;
memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
application2_.data.application.data = 0;
vorbiscomment_.is_last = true;
vorbiscomment_.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0);
vorbiscomment_.data.vorbis_comment.vendor_string.length = 8;
vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(8);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "flac 1.x", 8);
vorbiscomment_.data.vorbis_comment.num_comments = 2;
vorbiscomment_.data.vorbis_comment.comments = (::FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(::FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
} }
static void free_metadata_blocks_() static void free_metadata_blocks_()
{ {
free(seektable_.data.seek_table.points); mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
free(application1_.data.application.data);
free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
free(vorbiscomment_.data.vorbis_comment.comments);
} }
class StreamEncoder : public OggFLAC::Encoder::Stream { class StreamEncoder : public OggFLAC::Encoder::Stream {

View File

@@ -34,8 +34,8 @@ typedef struct {
FLAC__bool error_occurred; FLAC__bool error_occurred;
} stream_decoder_client_data_struct; } stream_decoder_client_data_struct;
static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_; static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_;
static FLAC__StreamMetadata *expected_metadata_sequence_[6]; static FLAC__StreamMetadata *expected_metadata_sequence_[7];
static unsigned num_expected_; static unsigned num_expected_;
static const char *oggflacfilename_ = "metadata.ogg"; static const char *oggflacfilename_ = "metadata.ogg";
static unsigned oggflacfilesize_; static unsigned oggflacfilesize_;
@@ -64,106 +64,27 @@ static FLAC__bool die_s_(const char *msg, const OggFLAC__StreamDecoder *decoder)
return false; return false;
} }
static void *malloc_or_die_(size_t size)
{
void *x = malloc(size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
exit(1);
}
return x;
}
static void init_metadata_blocks_() static void init_metadata_blocks_()
{ {
/* mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
most of the actual numbers and data in the blocks don't matter,
we just want to make sure the decoder parses them correctly
remember, the metadata interface gets tested after the decoders,
so we do all the metadata manipulation here without it.
*/
/* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
streaminfo_.is_last = false;
streaminfo_.type = FLAC__METADATA_TYPE_STREAMINFO;
streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
streaminfo_.data.stream_info.min_blocksize = 576;
streaminfo_.data.stream_info.max_blocksize = 576;
streaminfo_.data.stream_info.min_framesize = 0;
streaminfo_.data.stream_info.max_framesize = 0;
streaminfo_.data.stream_info.sample_rate = 44100;
streaminfo_.data.stream_info.channels = 1;
streaminfo_.data.stream_info.bits_per_sample = 8;
streaminfo_.data.stream_info.total_samples = 0;
memset(streaminfo_.data.stream_info.md5sum, 0, 16);
padding_.is_last = false;
padding_.type = FLAC__METADATA_TYPE_PADDING;
padding_.length = 1234;
seektable_.is_last = false;
seektable_.type = FLAC__METADATA_TYPE_SEEKTABLE;
seektable_.data.seek_table.num_points = 2;
seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
seektable_.data.seek_table.points = malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint));
seektable_.data.seek_table.points[0].sample_number = 0;
seektable_.data.seek_table.points[0].stream_offset = 0;
seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
seektable_.data.seek_table.points[1].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
seektable_.data.seek_table.points[1].stream_offset = 1000;
seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
application1_.is_last = false;
application1_.type = FLAC__METADATA_TYPE_APPLICATION;
application1_.length = 8;
memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
application1_.data.application.data = malloc_or_die_(4);
memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
application2_.is_last = false;
application2_.type = FLAC__METADATA_TYPE_APPLICATION;
application2_.length = 4;
memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
application2_.data.application.data = 0;
{
const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
vorbiscomment_.is_last = true;
vorbiscomment_.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment_.length = (4 + vendor_string_length) + 4 + (4 + 5) + (4 + 0);
vorbiscomment_.data.vorbis_comment.vendor_string.length = vendor_string_length;
vorbiscomment_.data.vorbis_comment.vendor_string.entry = malloc_or_die_(vendor_string_length);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length);
vorbiscomment_.data.vorbis_comment.num_comments = 2;
vorbiscomment_.data.vorbis_comment.comments = malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
vorbiscomment_.data.vorbis_comment.comments[0].entry = malloc_or_die_(5);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
}
} }
static void free_metadata_blocks_() static void free_metadata_blocks_()
{ {
free(seektable_.data.seek_table.points); mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
free(application1_.data.application.data);
free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
free(vorbiscomment_.data.vorbis_comment.comments);
} }
static FLAC__bool generate_file_() static FLAC__bool generate_file_()
{ {
printf("\n\ngenerating Ogg FLAC file for decoder tests...\n"); printf("\n\ngenerating Ogg FLAC file for decoder tests...\n");
expected_metadata_sequence_[0] = &padding_; num_expected_ = 0;
expected_metadata_sequence_[1] = &seektable_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[2] = &application1_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[3] = &application2_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[4] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &application2_;
num_expected_ = 5; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!file_utils__generate_oggflacfile(oggflacfilename_, &oggflacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_)) if(!file_utils__generate_oggflacfile(oggflacfilename_, &oggflacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
return die_("creating the encoded file"); return die_("creating the encoded file");
@@ -251,7 +172,7 @@ static void stream_decoder_metadata_callback_(const OggFLAC__StreamDecoder *deco
dcd->error_occurred = true; dcd->error_occurred = true;
} }
else { else {
if(!compare_block_(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) { if(!mutils__compare_block(expected_metadata_sequence_[dcd->current_metadata_number], metadata)) {
(void)die_("metadata block mismatch"); (void)die_("metadata block mismatch");
dcd->error_occurred = true; dcd->error_occurred = true;
} }
@@ -528,6 +449,7 @@ static FLAC__bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
return false; return false;
@@ -566,6 +488,7 @@ static FLAC__bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
return false; return false;
@@ -589,6 +512,7 @@ static FLAC__bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
return false; return false;
@@ -613,6 +537,7 @@ static FLAC__bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
return false; return false;
@@ -641,6 +566,7 @@ static FLAC__bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &padding_; expected_metadata_sequence_[num_expected_++] = &padding_;
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
return false; return false;
@@ -757,6 +683,7 @@ static FLAC__bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &seektable_; expected_metadata_sequence_[num_expected_++] = &seektable_;
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
if(!stream_decoder_test_respond_(decoder, &decoder_client_data)) if(!stream_decoder_test_respond_(decoder, &decoder_client_data))
return false; return false;
@@ -794,6 +721,7 @@ static FLAC__bool test_stream_decoder()
expected_metadata_sequence_[num_expected_++] = &application1_; expected_metadata_sequence_[num_expected_++] = &application1_;
expected_metadata_sequence_[num_expected_++] = &application2_; expected_metadata_sequence_[num_expected_++] = &application2_;
expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
expected_metadata_sequence_[num_expected_++] = &cuesheet_;
printf("testing OggFLAC__stream_decoder_delete()... "); printf("testing OggFLAC__stream_decoder_delete()... ");
OggFLAC__stream_decoder_delete(decoder); OggFLAC__stream_decoder_delete(decoder);

View File

@@ -18,6 +18,7 @@
#include "encoders.h" #include "encoders.h"
#include "file_utils.h" #include "file_utils.h"
#include "metadata_utils.h"
#include "FLAC/assert.h" #include "FLAC/assert.h"
#include "OggFLAC/stream_encoder.h" #include "OggFLAC/stream_encoder.h"
#include "share/grabbag.h" #include "share/grabbag.h"
@@ -25,9 +26,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_; static FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_;
static FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_ }; static FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_ };
static const unsigned num_metadata_ = 5; static const unsigned num_metadata_ = sizeof(metadata_sequence_) / sizeof(metadata_sequence_[0]);
static const char *oggflacfilename_ = "metadata.ogg"; static const char *oggflacfilename_ = "metadata.ogg";
static FLAC__bool die_s_(const char *msg, const OggFLAC__StreamEncoder *encoder) static FLAC__bool die_s_(const char *msg, const OggFLAC__StreamEncoder *encoder)
@@ -52,91 +53,14 @@ static FLAC__bool die_s_(const char *msg, const OggFLAC__StreamEncoder *encoder)
return false; return false;
} }
static void *malloc_or_die_(size_t size)
{
void *x = malloc(size);
if(0 == x) {
fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
exit(1);
}
return x;
}
static void init_metadata_blocks_() static void init_metadata_blocks_()
{ {
/* mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
most of the actual numbers and data in the blocks don't matter,
we just want to make sure the encoder encodes them correctly
remember, the metadata interface gets tested after the encoders,
so we do all the metadata manipulation here without it.
*/
/* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
streaminfo_.is_last = false;
streaminfo_.type = FLAC__METADATA_TYPE_STREAMINFO;
streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
streaminfo_.data.stream_info.min_blocksize = 576;
streaminfo_.data.stream_info.max_blocksize = 576;
streaminfo_.data.stream_info.min_framesize = 0;
streaminfo_.data.stream_info.max_framesize = 0;
streaminfo_.data.stream_info.sample_rate = 44100;
streaminfo_.data.stream_info.channels = 1;
streaminfo_.data.stream_info.bits_per_sample = 8;
streaminfo_.data.stream_info.total_samples = 0;
memset(streaminfo_.data.stream_info.md5sum, 0, 16);
padding_.is_last = false;
padding_.type = FLAC__METADATA_TYPE_PADDING;
padding_.length = 1234;
seektable_.is_last = false;
seektable_.type = FLAC__METADATA_TYPE_SEEKTABLE;
seektable_.data.seek_table.num_points = 2;
seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
seektable_.data.seek_table.points = malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(FLAC__StreamMetadata_SeekPoint));
seektable_.data.seek_table.points[0].sample_number = 0;
seektable_.data.seek_table.points[0].stream_offset = 0;
seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
seektable_.data.seek_table.points[1].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
seektable_.data.seek_table.points[1].stream_offset = 1000;
seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
application1_.is_last = false;
application1_.type = FLAC__METADATA_TYPE_APPLICATION;
application1_.length = 8;
memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
application1_.data.application.data = malloc_or_die_(4);
memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
application2_.is_last = false;
application2_.type = FLAC__METADATA_TYPE_APPLICATION;
application2_.length = 4;
memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
application2_.data.application.data = 0;
vorbiscomment_.is_last = true;
vorbiscomment_.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0);
vorbiscomment_.data.vorbis_comment.vendor_string.length = 8;
vorbiscomment_.data.vorbis_comment.vendor_string.entry = malloc_or_die_(8);
memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "flac 1.x", 8);
vorbiscomment_.data.vorbis_comment.num_comments = 2;
vorbiscomment_.data.vorbis_comment.comments = malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(FLAC__StreamMetadata_VorbisComment_Entry));
vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
vorbiscomment_.data.vorbis_comment.comments[0].entry = malloc_or_die_(5);
memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
} }
static void free_metadata_blocks_() static void free_metadata_blocks_()
{ {
free(seektable_.data.seek_table.points); mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_);
free(application1_.data.application.data);
free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
free(vorbiscomment_.data.vorbis_comment.comments);
} }
static FLAC__StreamEncoderWriteStatus stream_encoder_write_callback_(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) static FLAC__StreamEncoderWriteStatus stream_encoder_write_callback_(const OggFLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)