massive glob of checkins: improved tests, more tests, bugfixes

This commit is contained in:
Josh Coalson
2002-06-07 05:27:37 +00:00
parent 7b2e3a3797
commit 57ba6f4eb7
68 changed files with 6453 additions and 1324 deletions

View File

@@ -0,0 +1,34 @@
# test_libFLAC++ - Unit tester for libFLAC++
# Copyright (C) 2002 Josh Coalson
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
CFLAGS = @CFLAGS@
noinst_PROGRAMS = test_libFLAC++
test_libFLAC___LDADD = $(top_builddir)/src/libFLAC++/libFLAC++.la $(top_builddir)/src/libFLAC/libFLAC.la -lm
test_libFLAC___SOURCES = \
decoders.cc \
encoders.cc \
file_utils.c \
main.cc \
metadata.cc \
metadata_manip.cc \
metadata_object.cc \
bitbuffer.h \
decoders.h \
encoders.h \
file_utils.h \
metadata.h

View File

@@ -0,0 +1,38 @@
# test_libFLAC++ - Unit tester for libFLAC++
# Copyright (C) 2002 Josh Coalson
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# GNU makefile
#
PROGRAM_NAME = test_libFLAC++
INCLUDES = -I../../include
LIBS = -lFLAC++ -lFLAC -lm
OBJS = \
decoders.o \
encoders.o \
file_utils.o \
main.o \
metadata.o \
metadata_manip.o \
metadata_object.o
include ../../build/exe.mk
LINK = $(CCC) $(LINKAGE)
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@@ -0,0 +1,73 @@
# test_libFLAC++ - Unit tester for libFLAC++
# Copyright (C) 2002 Josh Coalson
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
!include <win32.mak>
SUFFIXES = .cpp
!IFDEF DEBUG
.c.obj:
$(cc) $(cdebug) $(cflags) /I "..\..\include" /I ".\include" -DSTRICT -DVERSION=\"1.0.3\" -YX /Od /D "_DEBUG" $<
!else
.c.obj:
$(cc) /O2 $(crelease) $(cflags) /I "..\..\include" /I ".\include" -DSTRICT -DVERSION=\"1.0.3\" -YX -DNODEBUG $<
!endif
!IFDEF DEBUG
.cc.obj:
$(cc) /D "_LIB" /GX $(cdebug) $(cflags) /I "..\..\include" -DSTRICT -YX /Od /D "_DEBUG" $<
!else
.cc.obj:
$(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG $<
!endif
C_FILES= \
file_utils.c
CC_FILES= \
decoders.cc \
encoders.cc \
main.cc \
metadata.cc \
metadata_manip.cc \
metadata_object.cc
OBJS= $(C_FILES:.c=.obj)
OBJS= $(CC_FILES:.cc=.obj)
# can't figure out how to get it to take .cc so we just hack it for now:
decoders.obj: decoders.cc
$(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP decoders.cc
encoders.obj: encoders.cc
$(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP encoders.cc
main.obj: main.cc
$(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP main.cc
metadata.obj: metadata.cc
$(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP metadata.cc
metadata_manip.obj: metadata_manip.cc
$(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP metadata_manip.cc
metadata_object.obj: metadata_object.cc
$(cc) /D "_LIB" /O2 $(crelease) $(cflags) /I "..\..\include" -DSTRICT -YX -DNODEBUG /TP metadata_object.cc
all: test_libFLAC++.exe
test_libFLAC++.exe: $(OBJS)
link.exe /libpath:"..\..\obj\lib" -out:../../obj/bin/$*.exe $(OBJS) libFLAC++.lib libFLAC.lib
clean:
-del *.obj *.pch
-del ..\..\obj\bin\test_libFLAC++.exe

View File

@@ -0,0 +1,4 @@
NOTE: files file_utils.c and file_utils.h are copied from the
../test_libFLAC directory. It's too much pain to make a
convenience library for these and CVS can't do soft links, so
we put up with having two copies of these sources.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
/* test_libFLAC++ - Unit tester for libFLAC++
* Copyright (C) 2002 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef FLAC__TEST_LIBFLACPP_DECODERS_H
#define FLAC__TEST_LIBFLACPP_DECODERS_H
bool test_decoders();
#endif

View File

@@ -0,0 +1,414 @@
/* test_libFLAC++ - Unit tester for libFLAC++
* Copyright (C) 2002 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "encoders.h"
extern "C" {
#include "file_utils.h"
}
#include "FLAC/assert.h"
#include "FLAC++/encoder.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static ::FLAC__StreamMetaData streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_;
static ::FLAC__StreamMetaData *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_ };
static const unsigned num_metadata_ = 5;
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_()
{
/*
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_()
{
free(seektable_.data.seek_table.points);
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 {
public:
StreamEncoder(): FLAC::Encoder::Stream() { }
~StreamEncoder() { }
// from FLAC::Encoder::Stream
::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame);
void metadata_callback(const ::FLAC__StreamMetaData *metadata);
bool die(const char *msg = 0) const;
};
::FLAC__StreamEncoderWriteStatus StreamEncoder::write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame)
{
(void)buffer, (void)bytes, (void)samples, (void)current_frame;
return ::FLAC__STREAM_ENCODER_WRITE_OK;
}
void StreamEncoder::metadata_callback(const ::FLAC__StreamMetaData *metadata)
{
(void)metadata;
}
bool StreamEncoder::die(const char *msg) const
{
State state = get_state();
if(msg)
printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring());
else
printf("FAILED, state = %u (%s)\n", (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring());
return false;
}
static bool test_stream_encoder()
{
StreamEncoder *encoder;
FLAC__int32 samples[1024];
FLAC__int32 *samples_array[1] = { samples };
unsigned i;
printf("\n+++ unit test: FLAC::Encoder::Stream\n\n");
printf("allocating encoder instance... ");
encoder = new StreamEncoder();
if(0 == encoder) {
printf("FAILED, new returned NULL\n");
return false;
}
printf("OK\n");
printf("testing is_valid()... ");
if(!encoder->is_valid()) {
printf("FAILED, returned false\n");
return false;
}
printf("OK\n");
printf("testing set_streamable_subset()... ");
if(!encoder->set_streamable_subset(true))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_do_mid_side_stereo()... ");
if(!encoder->set_do_mid_side_stereo(false))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_loose_mid_side_stereo()... ");
if(!encoder->set_loose_mid_side_stereo(false))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_channels()... ");
if(!encoder->set_channels(streaminfo_.data.stream_info.channels))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_bits_per_sample()... ");
if(!encoder->set_bits_per_sample(streaminfo_.data.stream_info.bits_per_sample))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_sample_rate()... ");
if(!encoder->set_sample_rate(streaminfo_.data.stream_info.sample_rate))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_blocksize()... ");
if(!encoder->set_blocksize(streaminfo_.data.stream_info.min_blocksize))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_max_lpc_order()... ");
if(!encoder->set_max_lpc_order(0))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_qlp_coeff_precision()... ");
if(!encoder->set_qlp_coeff_precision(0))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_do_qlp_coeff_prec_search()... ");
if(!encoder->set_do_qlp_coeff_prec_search(false))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_do_escape_coding()... ");
if(!encoder->set_do_escape_coding(false))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_do_exhaustive_model_search()... ");
if(!encoder->set_do_exhaustive_model_search(false))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_min_residual_partition_order()... ");
if(!encoder->set_min_residual_partition_order(0))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_max_residual_partition_order()... ");
if(!encoder->set_max_residual_partition_order(0))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_rice_parameter_search_dist()... ");
if(!encoder->set_rice_parameter_search_dist(0))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_total_samples_estimate()... ");
if(!encoder->set_total_samples_estimate(streaminfo_.data.stream_info.total_samples))
return encoder->die("returned false");
printf("OK\n");
printf("testing set_metadata()... ");
if(!encoder->set_metadata(metadata_sequence_, num_metadata_))
return encoder->die("returned false");
printf("OK\n");
printf("testing init()... ");
if(encoder->init() != ::FLAC__STREAM_ENCODER_OK)
return encoder->die();
printf("OK\n");
printf("testing get_state()... ");
FLAC::Encoder::Stream::State state = encoder->get_state();
printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring());
printf("testing get_streamable_subset()... ");
if(encoder->get_streamable_subset() != true) {
printf("FAILED, expected true, got false\n");
return false;
}
printf("OK\n");
printf("testing get_do_mid_side_stereo()... ");
if(encoder->get_do_mid_side_stereo() != false) {
printf("FAILED, expected false, got true\n");
return false;
}
printf("OK\n");
printf("testing get_loose_mid_side_stereo()... ");
if(encoder->get_loose_mid_side_stereo() != false) {
printf("FAILED, expected false, got true\n");
return false;
}
printf("OK\n");
printf("testing get_channels()... ");
if(encoder->get_channels() != streaminfo_.data.stream_info.channels) {
printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.channels, encoder->get_channels());
return false;
}
printf("OK\n");
printf("testing get_bits_per_sample()... ");
if(encoder->get_bits_per_sample() != streaminfo_.data.stream_info.bits_per_sample) {
printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.bits_per_sample, encoder->get_bits_per_sample());
return false;
}
printf("OK\n");
printf("testing get_sample_rate()... ");
if(encoder->get_sample_rate() != streaminfo_.data.stream_info.sample_rate) {
printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.sample_rate, encoder->get_sample_rate());
return false;
}
printf("OK\n");
printf("testing get_blocksize()... ");
if(encoder->get_blocksize() != streaminfo_.data.stream_info.min_blocksize) {
printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.min_blocksize, encoder->get_blocksize());
return false;
}
printf("OK\n");
printf("testing get_max_lpc_order()... ");
if(encoder->get_max_lpc_order() != 0) {
printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_lpc_order());
return false;
}
printf("OK\n");
printf("testing get_qlp_coeff_precision()... ");
(void)encoder->get_qlp_coeff_precision();
/* we asked the encoder to auto select this so we accept anything */
printf("OK\n");
printf("testing get_do_qlp_coeff_prec_search()... ");
if(encoder->get_do_qlp_coeff_prec_search() != false) {
printf("FAILED, expected false, got true\n");
return false;
}
printf("OK\n");
printf("testing get_do_escape_coding()... ");
if(encoder->get_do_escape_coding() != false) {
printf("FAILED, expected false, got true\n");
return false;
}
printf("OK\n");
printf("testing get_do_exhaustive_model_search()... ");
if(encoder->get_do_exhaustive_model_search() != false) {
printf("FAILED, expected false, got true\n");
return false;
}
printf("OK\n");
printf("testing get_min_residual_partition_order()... ");
if(encoder->get_min_residual_partition_order() != 0) {
printf("FAILED, expected %u, got %u\n", 0, encoder->get_min_residual_partition_order());
return false;
}
printf("OK\n");
printf("testing get_max_residual_partition_order()... ");
if(encoder->get_max_residual_partition_order() != 0) {
printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_residual_partition_order());
return false;
}
printf("OK\n");
printf("testing get_rice_parameter_search_dist()... ");
if(encoder->get_rice_parameter_search_dist() != 0) {
printf("FAILED, expected %u, got %u\n", 0, encoder->get_rice_parameter_search_dist());
return false;
}
printf("OK\n");
/* init the dummy sample buffer */
for(i = 0; i < sizeof(samples) / sizeof(FLAC__int32); i++)
samples[i] = i & 7;
printf("testing process()... ");
if(!encoder->process(samples_array, sizeof(samples) / sizeof(FLAC__int32)))
return encoder->die("returned false");
printf("OK\n");
printf("testing process_interleaved()... ");
if(!encoder->process_interleaved(samples, sizeof(samples) / sizeof(FLAC__int32)))
return encoder->die("returned false");
printf("OK\n");
printf("testing finish()... ");
encoder->finish();
printf("OK\n");
printf("freeing encoder instance... ");
delete encoder;
printf("OK\n");
printf("\nPASSED!\n");
return true;
}
bool test_encoders()
{
init_metadata_blocks_();
if(!test_stream_encoder())
return false;
free_metadata_blocks_();
return true;
}

View File

@@ -0,0 +1,24 @@
/* test_libFLAC++ - Unit tester for libFLAC++
* Copyright (C) 2002 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef FLAC__TEST_LIBFLACPP_ENCODERS_H
#define FLAC__TEST_LIBFLACPP_ENCODERS_H
bool test_encoders();
#endif

View File

@@ -0,0 +1,173 @@
/* test_libFLAC - Unit tester for libFLAC
* Copyright (C) 2002 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "file_utils.h"
#include "FLAC/assert.h"
#include "FLAC/stream_encoder.h"
#include <stdio.h>
#include <stdlib.h>
#if defined _MSC_VER || defined __MINGW32__
#include <io.h> /* for chmod(), unlink */
#endif
#include <sys/stat.h> /* for stat(), chmod() */
#if defined _WIN32 && !defined __CYGWIN__
#else
#include <unistd.h> /* for unlink() */
#endif
#ifdef min
#undef min
#endif
#define min(a,b) ((a)<(b)?(a):(b))
typedef struct {
FILE *file;
} encoder_client_struct;
static FLAC__StreamEncoderWriteStatus encoder_write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
{
encoder_client_struct *ecd = (encoder_client_struct*)client_data;
(void)encoder, (void)samples, (void)current_frame;
if(fwrite(buffer, 1, bytes, ecd->file) != bytes)
return FLAC__STREAM_ENCODER_WRITE_FATAL_ERROR;
else
return FLAC__STREAM_ENCODER_WRITE_OK;
}
static void encoder_metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetaData *metadata, void *client_data)
{
(void)encoder, (void)metadata, (void)client_data;
}
FLAC__bool file_utils__change_stats(const char *filename, FLAC__bool read_only)
{
struct stat stats;
if(0 == stat(filename, &stats)) {
#if !defined _MSC_VER && !defined __MINGW32__
if(read_only) {
stats.st_mode &= ~S_IWUSR;
stats.st_mode &= ~S_IWGRP;
stats.st_mode &= ~S_IWOTH;
}
else {
stats.st_mode |= S_IWUSR;
stats.st_mode |= S_IWGRP;
stats.st_mode |= S_IWOTH;
}
#else
if(read_only)
stats.st_mode &= ~S_IWRITE;
else
stats.st_mode |= S_IWRITE;
#endif
if(0 != chmod(filename, stats.st_mode))
return false;
}
else
return false;
return true;
}
FLAC__bool file_utils__remove_file(const char *filename)
{
return file_utils__change_stats(filename, /*read_only=*/false) && 0 == unlink(filename);
}
FLAC__bool file_utils__generate_flacfile(const char *output_filename, unsigned *output_filesize, unsigned length, const FLAC__StreamMetaData *streaminfo, FLAC__StreamMetaData **metadata, unsigned num_metadata)
{
FLAC__int32 samples[1024];
FLAC__StreamEncoder *encoder;
encoder_client_struct encoder_client_data;
unsigned i, n;
FLAC__ASSERT(0 != output_filename);
FLAC__ASSERT(0 != streaminfo);
FLAC__ASSERT(streaminfo->type == FLAC__METADATA_TYPE_STREAMINFO);
FLAC__ASSERT((streaminfo->is_last && num_metadata == 0) || (!streaminfo->is_last && num_metadata > 0));
if(0 == (encoder_client_data.file = fopen(output_filename, "wb")))
return false;
encoder = FLAC__stream_encoder_new();
if(0 == encoder) {
fclose(encoder_client_data.file);
return false;
}
FLAC__stream_encoder_set_streamable_subset(encoder, true);
FLAC__stream_encoder_set_do_mid_side_stereo(encoder, false);
FLAC__stream_encoder_set_loose_mid_side_stereo(encoder, false);
FLAC__stream_encoder_set_channels(encoder, streaminfo->data.stream_info.channels);
FLAC__stream_encoder_set_bits_per_sample(encoder, streaminfo->data.stream_info.bits_per_sample);
FLAC__stream_encoder_set_sample_rate(encoder, streaminfo->data.stream_info.sample_rate);
FLAC__stream_encoder_set_blocksize(encoder, streaminfo->data.stream_info.min_blocksize);
FLAC__stream_encoder_set_max_lpc_order(encoder, 0);
FLAC__stream_encoder_set_qlp_coeff_precision(encoder, 0);
FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder, false);
FLAC__stream_encoder_set_do_escape_coding(encoder, false);
FLAC__stream_encoder_set_do_exhaustive_model_search(encoder, false);
FLAC__stream_encoder_set_min_residual_partition_order(encoder, 0);
FLAC__stream_encoder_set_max_residual_partition_order(encoder, 0);
FLAC__stream_encoder_set_rice_parameter_search_dist(encoder, 0);
FLAC__stream_encoder_set_total_samples_estimate(encoder, streaminfo->data.stream_info.total_samples);
FLAC__stream_encoder_set_metadata(encoder, metadata, num_metadata);
FLAC__stream_encoder_set_write_callback(encoder, encoder_write_callback_);
FLAC__stream_encoder_set_metadata_callback(encoder, encoder_metadata_callback_);
FLAC__stream_encoder_set_client_data(encoder, &encoder_client_data);
if(FLAC__stream_encoder_init(encoder) != FLAC__STREAM_ENCODER_OK) {
fclose(encoder_client_data.file);
return false;
}
/* init the dummy sample buffer */
for(i = 0; i < sizeof(samples) / sizeof(FLAC__int32); i++)
samples[i] = i & 7;
while(length > 0) {
n = min(length, sizeof(samples) / sizeof(FLAC__int32));
if(!FLAC__stream_encoder_process_interleaved(encoder, samples, n)) {
fclose(encoder_client_data.file);
return false;
}
length -= n;
}
FLAC__stream_encoder_finish(encoder);
fclose(encoder_client_data.file);
FLAC__stream_encoder_delete(encoder);
if(0 != output_filesize) {
struct stat filestats;
if(stat(output_filename, &filestats) != 0)
return false;
else
*output_filesize = (unsigned)filestats.st_size;
}
return true;
}

View File

@@ -0,0 +1,30 @@
/* test_libFLAC - Unit tester for libFLAC
* Copyright (C) 2002 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef FLAC__TEST_LIBFLAC_FILE_UTILS_H
#define FLAC__TEST_LIBFLAC_FILE_UTILS_H
#include "FLAC/format.h"
FLAC__bool file_utils__change_stats(const char *filename, FLAC__bool read_only);
FLAC__bool file_utils__remove_file(const char *filename);
FLAC__bool file_utils__generate_flacfile(const char *output_filename, unsigned *output_filesize, unsigned length, const FLAC__StreamMetaData *streaminfo, FLAC__StreamMetaData **metadata, unsigned num_metadata);
#endif

View File

@@ -0,0 +1,37 @@
/* test_libFLAC++ - Unit tester for libFLAC++
* Copyright (C) 2002 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "decoders.h"
#include "encoders.h"
#include "metadata.h"
int main(int argc, char *argv[])
{
(void)argc, (void)argv;
if(!test_encoders())
return 1;
if(!test_decoders())
return 1;
if(!test_metadata())
return 1;
return 0;
}

View File

@@ -0,0 +1,36 @@
/* test_libFLAC++ - Unit tester for libFLAC++
* Copyright (C) 2002 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "metadata.h"
#include <stdio.h>
extern int test_metadata_object();
extern int test_metadata_file_manipulation();
bool test_metadata()
{
if(!test_metadata_object())
return false;
if(!test_metadata_file_manipulation())
return false;
printf("\nPASSED!\n");
return true;
}

View File

@@ -0,0 +1,24 @@
/* test_libFLAC++ - Unit tester for libFLAC++
* Copyright (C) 2002 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef FLAC__TEST_LIBFLACPP_METADATA_H
#define FLAC__TEST_LIBFLACPP_METADATA_H
bool test_metadata();
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,379 @@
/* test_libFLAC++ - Unit tester for libFLAC++
* Copyright (C) 2002 Josh Coalson
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "FLAC/assert.h"
#include "FLAC++/metadata.h"
#include <stdio.h>
#include <stdlib.h> /* for malloc() */
#include <string.h> /* for memcmp() */
static ::FLAC__StreamMetaData streaminfo_, padding_, seektable_, application_, vorbiscomment_;
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_()
{
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;
application_.is_last = false;
application_.type = ::FLAC__METADATA_TYPE_APPLICATION;
application_.length = 8;
memcpy(application_.data.application.id, "\xfe\xdc\xba\x98", 4);
application_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
memcpy(application_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
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_()
{
free(seektable_.data.seek_table.points);
free(application_.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);
}
bool test_metadata_object_streaminfo()
{
FLAC::Metadata::StreamInfo block;
unsigned expected_length;
printf("\n+++ unit test: metadata objects (libFLAC++)\n\n");
printf("testing FLAC::Metadata::StreamInfo\n");
printf("testing FLAC::Metadata::StreamInfo::StreamInfo()... ");
if(!block.is_valid()) {
printf("FAILED, !block.is_valid()\n");
return false;
}
expected_length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
if(block.get_length() != expected_length) {
printf("FAILED, bad length, expected %u, got %u\n", expected_length, block.get_length());
return false;
}
printf("OK\n");
printf("testing FLAC::MetaData::StreamInfo::StreamInfo(const StreamInfo &)... ");
{
FLAC::Metadata::StreamInfo blockcopy(block);
if(blockcopy != block) {
printf("FAILED, copy is not identical to original\n");
return false;
}
printf("OK\n");
printf("testing FLAC::Metadata::StreamInfo::~StreamInfo()... ");
}
printf("OK\n");
printf("testing FLAC::Metadata::StreamInfo::operator=(const ::FLAC__StreamMetaData &)... ");
{
FLAC::Metadata::StreamInfo blockcopy(streaminfo_, /*copy=*/true);
if(!blockcopy.is_valid()) {
printf("FAILED, !block.is_valid()\n");
return false;
}
if(blockcopy != streaminfo_) {
printf("FAILED, copy is not identical to original\n");
return false;
}
}
printf("OK\n");
printf("testing FLAC::Metadata::StreamInfo::operator=(const ::FLAC__StreamMetaData *)... ");
{
FLAC::Metadata::StreamInfo blockcopy(&streaminfo_, /*copy=*/true);
if(!blockcopy.is_valid()) {
printf("FAILED, !block.is_valid()\n");
return false;
}
if(blockcopy != streaminfo_) {
printf("FAILED, copy is not identical to original\n");
return false;
}
}
printf("OK\n");
printf("testing FLAC::Metadata::StreamInfo::operator=(const StreamInfo &)... ");
{
FLAC::Metadata::StreamInfo blockcopy = block;
if(!blockcopy.is_valid()) {
printf("FAILED, !block.is_valid()\n");
return false;
}
if(blockcopy != block) {
printf("FAILED, copy is not identical to original\n");
return false;
}
}
printf("OK\n");
return true;
}
bool test_metadata_object()
{
init_metadata_blocks_();
if(!test_metadata_object_streaminfo())
return false;
free_metadata_blocks_();
return true;
}
#if 0
// ============================================================
//
// Metadata objects
//
// ============================================================
// NOTE: When the get_*() methods return you a const pointer,
// DO NOT disobey and write into it. Always use the set_*()
// methods.
// base class for all metadata blocks
class Prototype {
protected:
Prototype(::FLAC__StreamMetaData *object, bool copy);
virtual ~Prototype();
void operator=(const Prototype &);
void operator=(const ::FLAC__StreamMetaData &);
void operator=(const ::FLAC__StreamMetaData *);
inline bool operator==(const FLAC::Metadata::Prototype &block)
{ return ::FLAC__metadata_object_is_equal(object_, block.object_); }
virtual void clear();
::FLAC__StreamMetaData *object_;
public:
friend class SimpleIterator;
friend class Iterator;
inline bool is_valid() const { return 0 != object_; }
inline operator bool() const { return is_valid(); }
bool get_is_last() const;
FLAC__MetaDataType get_type() const;
unsigned get_length() const; // NOTE: does not include the header, per spec
private:
Prototype(); // Private and undefined so you can't use it
// These are used only by Iterator
bool is_reference_;
inline void set_reference(bool x) { is_reference_ = x; }
};
class StreamInfo : public Prototype {
public:
unsigned get_min_blocksize() const;
unsigned get_max_blocksize() const;
unsigned get_min_framesize() const;
unsigned get_max_framesize() const;
unsigned get_sample_rate() const;
unsigned get_channels() const;
unsigned get_bits_per_sample() const;
FLAC__uint64 get_total_samples() const;
const FLAC__byte *get_md5sum() const;
void set_min_blocksize(unsigned value);
void set_max_blocksize(unsigned value);
void set_min_framesize(unsigned value);
void set_max_framesize(unsigned value);
void set_sample_rate(unsigned value);
void set_channels(unsigned value);
void set_bits_per_sample(unsigned value);
void set_total_samples(FLAC__uint64 value);
void set_md5sum(const FLAC__byte value[16]);
};
class Padding : public Prototype {
public:
Padding();
Padding(::FLAC__StreamMetaData *object, bool copy = false);
~Padding();
inline void operator=(const Padding &object) { Prototype::operator=(object); }
inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
void set_length(unsigned length);
};
class Application : public Prototype {
public:
Application();
Application(::FLAC__StreamMetaData *object, bool copy = false);
~Application();
inline void operator=(const Application &object) { Prototype::operator=(object); }
inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
const FLAC__byte *get_id() const;
const FLAC__byte *get_data() const;
void set_id(FLAC__byte value[4]);
bool set_data(FLAC__byte *data, unsigned length, bool copy = false);
};
class SeekTable : public Prototype {
public:
SeekTable();
SeekTable(::FLAC__StreamMetaData *object, bool copy = false);
~SeekTable();
inline void operator=(const SeekTable &object) { Prototype::operator=(object); }
inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
unsigned get_num_points() const;
::FLAC__StreamMetaData_SeekPoint get_point(unsigned index) const;
void set_point(unsigned index, const ::FLAC__StreamMetaData_SeekPoint &point);
bool insert_point(unsigned index, const ::FLAC__StreamMetaData_SeekPoint &point);
bool delete_point(unsigned index);
bool is_legal() const;
};
class VorbisComment : public Prototype {
public:
class Entry {
public:
Entry();
Entry(const char *field, unsigned field_length);
Entry(const char *field_name, const char *field_value, unsigned field_value_length);
Entry(const Entry &entry);
void operator=(const Entry &entry);
virtual ~Entry();
virtual bool is_valid() const;
inline operator bool() const { return is_valid(); }
unsigned get_field_length() const;
unsigned get_field_name_length() const;
unsigned get_field_value_length() const;
::FLAC__StreamMetaData_VorbisComment_Entry get_entry() const;
const char *get_field() const;
const char *get_field_name() const;
const char *get_field_value() const;
bool set_field(const char *field, unsigned field_length);
bool set_field_name(const char *field_name);
bool set_field_value(const char *field_value, unsigned field_value_length);
protected:
bool is_valid_;
::FLAC__StreamMetaData_VorbisComment_Entry entry_;
char *field_name_;
unsigned field_name_length_;
char *field_value_;
unsigned field_value_length_;
private:
void zero();
void clear();
void clear_entry();
void clear_field_name();
void clear_field_value();
void construct(const char *field, unsigned field_length);
void construct(const char *field_name, const char *field_value, unsigned field_value_length);
void compose_field();
void parse_field();
};
VorbisComment();
VorbisComment(::FLAC__StreamMetaData *object, bool copy = false);
~VorbisComment();
inline void operator=(const VorbisComment &object) { Prototype::operator=(object); }
inline void operator=(const ::FLAC__StreamMetaData &object) { Prototype::operator=(object); }
inline void operator=(const ::FLAC__StreamMetaData *object) { Prototype::operator=(object); }
unsigned get_num_comments() const;
Entry get_vendor_string() const;
Entry get_comment(unsigned index) const;
bool set_vendor_string(const Entry &entry);
bool set_comment(unsigned index, const Entry &entry);
bool insert_comment(unsigned index, const Entry &entry);
bool delete_comment(unsigned index);
};
#endif