| @@ -1,120 +0,0 @@ | |||
| #!/usr/bin/make -f | |||
| # Makefile for juce_audio_formats # | |||
| # ------------------------------- # | |||
| # Created by falkTX | |||
| # | |||
| CWD=../.. | |||
| MODULENAME=juce_audio_formats | |||
| include ../Makefile.mk | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| BUILD_CXX_FLAGS += $(JUCE_AUDIO_FORMATS_FLAGS) -I.. | |||
| BUILD_CXX_FLAGS += -DHAVE_LROUND | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| ifeq ($(MACOS),true) | |||
| OBJS = $(OBJDIR)/$(MODULENAME).mm.o | |||
| OBJS_posix32 = $(OBJDIR)/$(MODULENAME).mm.posix32.o | |||
| OBJS_posix64 = $(OBJDIR)/$(MODULENAME).mm.posix64.o | |||
| else | |||
| OBJS = $(OBJDIR)/$(MODULENAME).cpp.o | |||
| OBJS_posix32 = $(OBJDIR)/$(MODULENAME).cpp.posix32.o | |||
| OBJS_posix64 = $(OBJDIR)/$(MODULENAME).cpp.posix64.o | |||
| endif | |||
| OBJS_win32 = $(OBJDIR)/$(MODULENAME).cpp.win32.o | |||
| OBJS_win64 = $(OBJDIR)/$(MODULENAME).cpp.win64.o | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| all: $(MODULEDIR)/$(MODULENAME).a | |||
| posix32: $(MODULEDIR)/$(MODULENAME).posix32.a | |||
| posix64: $(MODULEDIR)/$(MODULENAME).posix64.a | |||
| win32: $(MODULEDIR)/$(MODULENAME).win32.a | |||
| win64: $(MODULEDIR)/$(MODULENAME).win64.a | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| clean: | |||
| rm -f $(OBJDIR)/*.o $(MODULEDIR)/$(MODULENAME)*.a | |||
| debug: | |||
| $(MAKE) DEBUG=true | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| $(MODULEDIR)/$(MODULENAME).a: $(OBJS) | |||
| -@mkdir -p $(MODULEDIR) | |||
| @echo "Creating $(MODULENAME).a" | |||
| @rm -f $@ | |||
| @$(AR) crs $@ $^ | |||
| $(MODULEDIR)/$(MODULENAME).posix32.a: $(OBJS_posix32) | |||
| -@mkdir -p $(MODULEDIR) | |||
| @echo "Creating $(MODULENAME).posix32.a" | |||
| @rm -f $@ | |||
| @$(AR) crs $@ $^ | |||
| $(MODULEDIR)/$(MODULENAME).posix64.a: $(OBJS_posix64) | |||
| -@mkdir -p $(MODULEDIR) | |||
| @echo "Creating $(MODULENAME).posix64.a" | |||
| @rm -f $@ | |||
| @$(AR) crs $@ $^ | |||
| $(MODULEDIR)/$(MODULENAME).win32.a: $(OBJS_win32) | |||
| -@mkdir -p $(MODULEDIR) | |||
| @echo "Creating $(MODULENAME).win32.a" | |||
| @rm -f $@ | |||
| @$(AR) crs $@ $^ | |||
| $(MODULEDIR)/$(MODULENAME).win64.a: $(OBJS_win64) | |||
| -@mkdir -p $(MODULEDIR) | |||
| @echo "Creating $(MODULENAME).win64.a" | |||
| @rm -f $@ | |||
| @$(AR) crs $@ $^ | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| $(OBJDIR)/$(MODULENAME).cpp.o: $(MODULENAME).cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling $<" | |||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@ | |||
| $(OBJDIR)/$(MODULENAME).cpp.%32.o: $(MODULENAME).cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling $< (32bit)" | |||
| @$(CXX) $< $(BUILD_CXX_FLAGS) $(32BIT_FLAGS) -c -o $@ | |||
| $(OBJDIR)/$(MODULENAME).cpp.%64.o: $(MODULENAME).cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling $< (64bit)" | |||
| @$(CXX) $< $(BUILD_CXX_FLAGS) $(64BIT_FLAGS) -c -o $@ | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| $(OBJDIR)/$(MODULENAME).mm.o: $(MODULENAME).cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling $<" | |||
| @$(CXX) $< $(BUILD_CXX_FLAGS) -ObjC++ -c -o $@ | |||
| $(OBJDIR)/$(MODULENAME).mm.%32.o: $(MODULENAME).cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling $< (32bit)" | |||
| @$(CXX) $< $(BUILD_CXX_FLAGS) $(32BIT_FLAGS) -ObjC++ -c -o $@ | |||
| $(OBJDIR)/$(MODULENAME).mm.%64.o: $(MODULENAME).cpp | |||
| -@mkdir -p $(OBJDIR) | |||
| @echo "Compiling $< (64bit)" | |||
| @$(CXX) $< $(BUILD_CXX_FLAGS) $(64BIT_FLAGS) -ObjC++ -c -o $@ | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| -include $(OBJS:%.o=%.d) | |||
| -include $(OBJS_posix32:%.o=%.d) | |||
| -include $(OBJS_posix64:%.o=%.d) | |||
| -include $(OBJS_win32:%.o=%.d) | |||
| -include $(OBJS_win64:%.o=%.d) | |||
| # ---------------------------------------------------------------------------------------------------------------------------- | |||
| @@ -1,49 +0,0 @@ | |||
| ===================================================================== | |||
| I've incorporated FLAC directly into the Juce codebase because it makes | |||
| things much easier than having to make all your builds link correctly to | |||
| the appropriate libraries on every different platform. | |||
| I've made minimal changes to the FLAC code - just tweaked a few include paths | |||
| to make it build smoothly, added some headers to allow you to turn off FLAC | |||
| compilation, and commented-out a couple of unused bits of code. | |||
| ===================================================================== | |||
| The following license is the BSD-style license that comes with the | |||
| Flac distribution, and which applies just to the files I've | |||
| included in this directory. For more info, and to get the rest of the | |||
| distribution, visit the Flac homepage: flac.sourceforge.net | |||
| ===================================================================== | |||
| Copyright (C) 2000,2001,2002,2003,2004,2005,2006 Josh Coalson | |||
| Redistribution and use in source and binary forms, with or without | |||
| modification, are permitted provided that the following conditions | |||
| are met: | |||
| - Redistributions of source code must retain the above copyright | |||
| notice, this list of conditions and the following disclaimer. | |||
| - Redistributions in binary form must reproduce the above copyright | |||
| notice, this list of conditions and the following disclaimer in the | |||
| documentation and/or other materials provided with the distribution. | |||
| - Neither the name of the Xiph.org Foundation nor the names of its | |||
| contributors may be used to endorse or promote products derived from | |||
| this software without specific prior written permission. | |||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| @@ -1,371 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__ALL_H | |||
| #define FLAC__ALL_H | |||
| #include "export.h" | |||
| #include "assert.h" | |||
| #include "callback.h" | |||
| #include "format.h" | |||
| #include "metadata.h" | |||
| #include "ordinals.h" | |||
| #include "stream_decoder.h" | |||
| #include "stream_encoder.h" | |||
| /** \mainpage | |||
| * | |||
| * \section intro Introduction | |||
| * | |||
| * This is the documentation for the FLAC C and C++ APIs. It is | |||
| * highly interconnected; this introduction should give you a top | |||
| * level idea of the structure and how to find the information you | |||
| * need. As a prerequisite you should have at least a basic | |||
| * knowledge of the FLAC format, documented | |||
| * <A HREF="../format.html">here</A>. | |||
| * | |||
| * \section c_api FLAC C API | |||
| * | |||
| * The FLAC C API is the interface to libFLAC, a set of structures | |||
| * describing the components of FLAC streams, and functions for | |||
| * encoding and decoding streams, as well as manipulating FLAC | |||
| * metadata in files. The public include files will be installed | |||
| * in your include area (for example /usr/include/FLAC/...). | |||
| * | |||
| * By writing a little code and linking against libFLAC, it is | |||
| * relatively easy to add FLAC support to another program. The | |||
| * library is licensed under <A HREF="../license.html">Xiph's BSD license</A>. | |||
| * Complete source code of libFLAC as well as the command-line | |||
| * encoder and plugins is available and is a useful source of | |||
| * examples. | |||
| * | |||
| * Aside from encoders and decoders, libFLAC provides a powerful | |||
| * metadata interface for manipulating metadata in FLAC files. It | |||
| * allows the user to add, delete, and modify FLAC metadata blocks | |||
| * and it can automatically take advantage of PADDING blocks to avoid | |||
| * rewriting the entire FLAC file when changing the size of the | |||
| * metadata. | |||
| * | |||
| * libFLAC usually only requires the standard C library and C math | |||
| * library. In particular, threading is not used so there is no | |||
| * dependency on a thread library. However, libFLAC does not use | |||
| * global variables and should be thread-safe. | |||
| * | |||
| * libFLAC also supports encoding to and decoding from Ogg FLAC. | |||
| * However the metadata editing interfaces currently have limited | |||
| * read-only support for Ogg FLAC files. | |||
| * | |||
| * \section cpp_api FLAC C++ API | |||
| * | |||
| * The FLAC C++ API is a set of classes that encapsulate the | |||
| * structures and functions in libFLAC. They provide slightly more | |||
| * functionality with respect to metadata but are otherwise | |||
| * equivalent. For the most part, they share the same usage as | |||
| * their counterparts in libFLAC, and the FLAC C API documentation | |||
| * can be used as a supplement. The public include files | |||
| * for the C++ API will be installed in your include area (for | |||
| * example /usr/include/FLAC++/...). | |||
| * | |||
| * libFLAC++ is also licensed under | |||
| * <A HREF="../license.html">Xiph's BSD license</A>. | |||
| * | |||
| * \section getting_started Getting Started | |||
| * | |||
| * A good starting point for learning the API is to browse through | |||
| * the <A HREF="modules.html">modules</A>. Modules are logical | |||
| * groupings of related functions or classes, which correspond roughly | |||
| * to header files or sections of header files. Each module includes a | |||
| * detailed description of the general usage of its functions or | |||
| * classes. | |||
| * | |||
| * From there you can go on to look at the documentation of | |||
| * individual functions. You can see different views of the individual | |||
| * functions through the links in top bar across this page. | |||
| * | |||
| * If you prefer a more hands-on approach, you can jump right to some | |||
| * <A HREF="../documentation_example_code.html">example code</A>. | |||
| * | |||
| * \section porting_guide Porting Guide | |||
| * | |||
| * Starting with FLAC 1.1.3 a \link porting Porting Guide \endlink | |||
| * has been introduced which gives detailed instructions on how to | |||
| * port your code to newer versions of FLAC. | |||
| * | |||
| * \section embedded_developers Embedded Developers | |||
| * | |||
| * libFLAC has grown larger over time as more functionality has been | |||
| * included, but much of it may be unnecessary for a particular embedded | |||
| * implementation. Unused parts may be pruned by some simple editing of | |||
| * src/libFLAC/Makefile.am. In general, the decoders, encoders, and | |||
| * metadata interface are all independent from each other. | |||
| * | |||
| * It is easiest to just describe the dependencies: | |||
| * | |||
| * - All modules depend on the \link flac_format Format \endlink module. | |||
| * - The decoders and encoders depend on the bitbuffer. | |||
| * - The decoder is independent of the encoder. The encoder uses the | |||
| * decoder because of the verify feature, but this can be removed if | |||
| * not needed. | |||
| * - Parts of the metadata interface require the stream decoder (but not | |||
| * the encoder). | |||
| * - Ogg support is selectable through the compile time macro | |||
| * \c FLAC__HAS_OGG. | |||
| * | |||
| * For example, if your application only requires the stream decoder, no | |||
| * encoder, and no metadata interface, you can remove the stream encoder | |||
| * and the metadata interface, which will greatly reduce the size of the | |||
| * library. | |||
| * | |||
| * Also, there are several places in the libFLAC code with comments marked | |||
| * with "OPT:" where a #define can be changed to enable code that might be | |||
| * faster on a specific platform. Experimenting with these can yield faster | |||
| * binaries. | |||
| */ | |||
| /** \defgroup porting Porting Guide for New Versions | |||
| * | |||
| * This module describes differences in the library interfaces from | |||
| * version to version. It assists in the porting of code that uses | |||
| * the libraries to newer versions of FLAC. | |||
| * | |||
| * One simple facility for making porting easier that has been added | |||
| * in FLAC 1.1.3 is a set of \c #defines in \c export.h of each | |||
| * library's includes (e.g. \c include/FLAC/export.h). The | |||
| * \c #defines mirror the libraries' | |||
| * <A HREF="http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning">libtool version numbers</A>, | |||
| * e.g. in libFLAC there are \c FLAC_API_VERSION_CURRENT, | |||
| * \c FLAC_API_VERSION_REVISION, and \c FLAC_API_VERSION_AGE. | |||
| * These can be used to support multiple versions of an API during the | |||
| * transition phase, e.g. | |||
| * | |||
| * \code | |||
| * #if !defined(FLAC_API_VERSION_CURRENT) || FLAC_API_VERSION_CURRENT <= 7 | |||
| * legacy code | |||
| * #else | |||
| * new code | |||
| * #endif | |||
| * \endcode | |||
| * | |||
| * The the source will work for multiple versions and the legacy code can | |||
| * easily be removed when the transition is complete. | |||
| * | |||
| * Another available symbol is FLAC_API_SUPPORTS_OGG_FLAC (defined in | |||
| * include/FLAC/export.h), which can be used to determine whether or not | |||
| * the library has been compiled with support for Ogg FLAC. This is | |||
| * simpler than trying to call an Ogg init function and catching the | |||
| * error. | |||
| */ | |||
| /** \defgroup porting_1_1_2_to_1_1_3 Porting from FLAC 1.1.2 to 1.1.3 | |||
| * \ingroup porting | |||
| * | |||
| * \brief | |||
| * This module describes porting from FLAC 1.1.2 to FLAC 1.1.3. | |||
| * | |||
| * The main change between the APIs in 1.1.2 and 1.1.3 is that they have | |||
| * been simplified. First, libOggFLAC has been merged into libFLAC and | |||
| * libOggFLAC++ has been merged into libFLAC++. Second, both the three | |||
| * decoding layers and three encoding layers have been merged into a | |||
| * single stream decoder and stream encoder. That is, the functionality | |||
| * of FLAC__SeekableStreamDecoder and FLAC__FileDecoder has been merged | |||
| * into FLAC__StreamDecoder, and FLAC__SeekableStreamEncoder and | |||
| * FLAC__FileEncoder into FLAC__StreamEncoder. Only the | |||
| * FLAC__StreamDecoder and FLAC__StreamEncoder remain. What this means | |||
| * is there is now a single API that can be used to encode or decode | |||
| * streams to/from native FLAC or Ogg FLAC and the single API can work | |||
| * on both seekable and non-seekable streams. | |||
| * | |||
| * Instead of creating an encoder or decoder of a certain layer, now the | |||
| * client will always create a FLAC__StreamEncoder or | |||
| * FLAC__StreamDecoder. The old layers are now differentiated by the | |||
| * initialization function. For example, for the decoder, | |||
| * FLAC__stream_decoder_init() has been replaced by | |||
| * FLAC__stream_decoder_init_stream(). This init function takes | |||
| * callbacks for the I/O, and the seeking callbacks are optional. This | |||
| * allows the client to use the same object for seekable and | |||
| * non-seekable streams. For decoding a FLAC file directly, the client | |||
| * can use FLAC__stream_decoder_init_file() and pass just a filename | |||
| * and fewer callbacks; most of the other callbacks are supplied | |||
| * internally. For situations where fopen()ing by filename is not | |||
| * possible (e.g. Unicode filenames on Windows) the client can instead | |||
| * open the file itself and supply the FILE* to | |||
| * FLAC__stream_decoder_init_FILE(). The init functions now returns a | |||
| * FLAC__StreamDecoderInitStatus instead of FLAC__StreamDecoderState. | |||
| * Since the callbacks and client data are now passed to the init | |||
| * function, the FLAC__stream_decoder_set_*_callback() functions and | |||
| * FLAC__stream_decoder_set_client_data() are no longer needed. The | |||
| * rest of the calls to the decoder are the same as before. | |||
| * | |||
| * There are counterpart init functions for Ogg FLAC, e.g. | |||
| * FLAC__stream_decoder_init_ogg_stream(). All the rest of the calls | |||
| * and callbacks are the same as for native FLAC. | |||
| * | |||
| * As an example, in FLAC 1.1.2 a seekable stream decoder would have | |||
| * been set up like so: | |||
| * | |||
| * \code | |||
| * FLAC__SeekableStreamDecoder *decoder = FLAC__seekable_stream_decoder_new(); | |||
| * if(decoder == NULL) do_something; | |||
| * FLAC__seekable_stream_decoder_set_md5_checking(decoder, true); | |||
| * [... other settings ...] | |||
| * FLAC__seekable_stream_decoder_set_read_callback(decoder, my_read_callback); | |||
| * FLAC__seekable_stream_decoder_set_seek_callback(decoder, my_seek_callback); | |||
| * FLAC__seekable_stream_decoder_set_tell_callback(decoder, my_tell_callback); | |||
| * FLAC__seekable_stream_decoder_set_length_callback(decoder, my_length_callback); | |||
| * FLAC__seekable_stream_decoder_set_eof_callback(decoder, my_eof_callback); | |||
| * FLAC__seekable_stream_decoder_set_write_callback(decoder, my_write_callback); | |||
| * FLAC__seekable_stream_decoder_set_metadata_callback(decoder, my_metadata_callback); | |||
| * FLAC__seekable_stream_decoder_set_error_callback(decoder, my_error_callback); | |||
| * FLAC__seekable_stream_decoder_set_client_data(decoder, my_client_data); | |||
| * if(FLAC__seekable_stream_decoder_init(decoder) != FLAC__SEEKABLE_STREAM_DECODER_OK) do_something; | |||
| * \endcode | |||
| * | |||
| * In FLAC 1.1.3 it is like this: | |||
| * | |||
| * \code | |||
| * FLAC__StreamDecoder *decoder = FLAC__stream_decoder_new(); | |||
| * if(decoder == NULL) do_something; | |||
| * FLAC__stream_decoder_set_md5_checking(decoder, true); | |||
| * [... other settings ...] | |||
| * if(FLAC__stream_decoder_init_stream( | |||
| * decoder, | |||
| * my_read_callback, | |||
| * my_seek_callback, // or NULL | |||
| * my_tell_callback, // or NULL | |||
| * my_length_callback, // or NULL | |||
| * my_eof_callback, // or NULL | |||
| * my_write_callback, | |||
| * my_metadata_callback, // or NULL | |||
| * my_error_callback, | |||
| * my_client_data | |||
| * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; | |||
| * \endcode | |||
| * | |||
| * or you could do; | |||
| * | |||
| * \code | |||
| * [...] | |||
| * FILE *file = fopen("somefile.flac","rb"); | |||
| * if(file == NULL) do_somthing; | |||
| * if(FLAC__stream_decoder_init_FILE( | |||
| * decoder, | |||
| * file, | |||
| * my_write_callback, | |||
| * my_metadata_callback, // or NULL | |||
| * my_error_callback, | |||
| * my_client_data | |||
| * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; | |||
| * \endcode | |||
| * | |||
| * or just: | |||
| * | |||
| * \code | |||
| * [...] | |||
| * if(FLAC__stream_decoder_init_file( | |||
| * decoder, | |||
| * "somefile.flac", | |||
| * my_write_callback, | |||
| * my_metadata_callback, // or NULL | |||
| * my_error_callback, | |||
| * my_client_data | |||
| * ) != FLAC__STREAM_DECODER_INIT_STATUS_OK) do_something; | |||
| * \endcode | |||
| * | |||
| * Another small change to the decoder is in how it handles unparseable | |||
| * streams. Before, when the decoder found an unparseable stream | |||
| * (reserved for when the decoder encounters a stream from a future | |||
| * encoder that it can't parse), it changed the state to | |||
| * \c FLAC__STREAM_DECODER_UNPARSEABLE_STREAM. Now the decoder instead | |||
| * drops sync and calls the error callback with a new error code | |||
| * \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM. This is | |||
| * more robust. If your error callback does not discriminate on the the | |||
| * error state, your code does not need to be changed. | |||
| * | |||
| * The encoder now has a new setting: | |||
| * FLAC__stream_encoder_set_apodization(). This is for setting the | |||
| * method used to window the data before LPC analysis. You only need to | |||
| * add a call to this function if the default is not suitable. There | |||
| * are also two new convenience functions that may be useful: | |||
| * FLAC__metadata_object_cuesheet_calculate_cddb_id() and | |||
| * FLAC__metadata_get_cuesheet(). | |||
| * | |||
| * The \a bytes parameter to FLAC__StreamDecoderReadCallback, | |||
| * FLAC__StreamEncoderReadCallback, and FLAC__StreamEncoderWriteCallback | |||
| * is now \c size_t instead of \c unsigned. | |||
| */ | |||
| /** \defgroup porting_1_1_3_to_1_1_4 Porting from FLAC 1.1.3 to 1.1.4 | |||
| * \ingroup porting | |||
| * | |||
| * \brief | |||
| * This module describes porting from FLAC 1.1.3 to FLAC 1.1.4. | |||
| * | |||
| * There were no changes to any of the interfaces from 1.1.3 to 1.1.4. | |||
| * There was a slight change in the implementation of | |||
| * FLAC__stream_encoder_set_metadata(); the function now makes a copy | |||
| * of the \a metadata array of pointers so the client no longer needs | |||
| * to maintain it after the call. The objects themselves that are | |||
| * pointed to by the array are still not copied though and must be | |||
| * maintained until the call to FLAC__stream_encoder_finish(). | |||
| */ | |||
| /** \defgroup porting_1_1_4_to_1_2_0 Porting from FLAC 1.1.4 to 1.2.0 | |||
| * \ingroup porting | |||
| * | |||
| * \brief | |||
| * This module describes porting from FLAC 1.1.4 to FLAC 1.2.0. | |||
| * | |||
| * There were only very minor changes to the interfaces from 1.1.4 to 1.2.0. | |||
| * In libFLAC, \c FLAC__format_sample_rate_is_subset() was added. | |||
| * In libFLAC++, \c FLAC::Decoder::Stream::get_decode_position() was added. | |||
| * | |||
| * Finally, value of the constant \c FLAC__FRAME_HEADER_RESERVED_LEN | |||
| * has changed to reflect the conversion of one of the reserved bits | |||
| * into active use. It used to be \c 2 and now is \c 1. However the | |||
| * FLAC frame header length has not changed, so to skip the proper | |||
| * number of bits, use \c FLAC__FRAME_HEADER_RESERVED_LEN + | |||
| * \c FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN | |||
| */ | |||
| /** \defgroup flac FLAC C API | |||
| * | |||
| * The FLAC C API is the interface to libFLAC, a set of structures | |||
| * describing the components of FLAC streams, and functions for | |||
| * encoding and decoding streams, as well as manipulating FLAC | |||
| * metadata in files. | |||
| * | |||
| * You should start with the format components as all other modules | |||
| * are dependent on it. | |||
| */ | |||
| #endif | |||
| @@ -1,212 +0,0 @@ | |||
| /* alloc - Convenience routines for safely allocating memory | |||
| * Copyright (C) 2007-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__SHARE__ALLOC_H | |||
| #define FLAC__SHARE__ALLOC_H | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| /* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early | |||
| * before #including this file, otherwise SIZE_MAX might not be defined | |||
| */ | |||
| // JUCE: removed as JUCE already includes standard headers and including | |||
| // these in FlacNamespace will cause problems | |||
| //#include <limits.h> /* for SIZE_MAX */ | |||
| //#if HAVE_STDINT_H | |||
| //#include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */ | |||
| //#endif | |||
| //#include <stdlib.h> /* for size_t, malloc(), etc */ | |||
| #include "compat.h" | |||
| #ifndef SIZE_MAX | |||
| # ifndef SIZE_T_MAX | |||
| # ifdef _MSC_VER | |||
| # ifdef _WIN64 | |||
| # define SIZE_T_MAX 0xffffffffffffffffui64 | |||
| # else | |||
| # define SIZE_T_MAX 0xffffffff | |||
| # endif | |||
| # else | |||
| # error | |||
| # endif | |||
| # endif | |||
| # define SIZE_MAX SIZE_T_MAX | |||
| #endif | |||
| /* avoid malloc()ing 0 bytes, see: | |||
| * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 | |||
| */ | |||
| static inline void *safe_malloc_(size_t size) | |||
| { | |||
| /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||
| if(!size) | |||
| size++; | |||
| return malloc(size); | |||
| } | |||
| static inline void *safe_calloc_(size_t nmemb, size_t size) | |||
| { | |||
| if(!nmemb || !size) | |||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||
| return calloc(nmemb, size); | |||
| } | |||
| /*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */ | |||
| static inline void *safe_malloc_add_2op_(size_t size1, size_t size2) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| return safe_malloc_(size2); | |||
| } | |||
| static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| size3 += size2; | |||
| if(size3 < size2) | |||
| return 0; | |||
| return safe_malloc_(size3); | |||
| } | |||
| static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| size3 += size2; | |||
| if(size3 < size2) | |||
| return 0; | |||
| size4 += size3; | |||
| if(size4 < size3) | |||
| return 0; | |||
| return safe_malloc_(size4); | |||
| } | |||
| void *safe_malloc_mul_2op_(size_t size1, size_t size2) ; | |||
| static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) | |||
| { | |||
| if(!size1 || !size2 || !size3) | |||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||
| if(size1 > SIZE_MAX / size2) | |||
| return 0; | |||
| size1 *= size2; | |||
| if(size1 > SIZE_MAX / size3) | |||
| return 0; | |||
| return malloc(size1*size3); | |||
| } | |||
| /* size1*size2 + size3 */ | |||
| static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) | |||
| { | |||
| if(!size1 || !size2) | |||
| return safe_malloc_(size3); | |||
| if(size1 > SIZE_MAX / size2) | |||
| return 0; | |||
| return safe_malloc_add_2op_(size1*size2, size3); | |||
| } | |||
| /* size1 * (size2 + size3) */ | |||
| static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) | |||
| { | |||
| if(!size1 || (!size2 && !size3)) | |||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||
| size2 += size3; | |||
| if(size2 < size3) | |||
| return 0; | |||
| if(size1 > SIZE_MAX / size2) | |||
| return 0; | |||
| return malloc(size1*size2); | |||
| } | |||
| static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| return realloc(ptr, size2); | |||
| } | |||
| static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| size3 += size2; | |||
| if(size3 < size2) | |||
| return 0; | |||
| return realloc(ptr, size3); | |||
| } | |||
| static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) | |||
| { | |||
| size2 += size1; | |||
| if(size2 < size1) | |||
| return 0; | |||
| size3 += size2; | |||
| if(size3 < size2) | |||
| return 0; | |||
| size4 += size3; | |||
| if(size4 < size3) | |||
| return 0; | |||
| return realloc(ptr, size4); | |||
| } | |||
| static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) | |||
| { | |||
| if(!size1 || !size2) | |||
| return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | |||
| if(size1 > SIZE_MAX / size2) | |||
| return 0; | |||
| return realloc(ptr, size1*size2); | |||
| } | |||
| /* size1 * (size2 + size3) */ | |||
| static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) | |||
| { | |||
| if(!size1 || (!size2 && !size3)) | |||
| return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ | |||
| size2 += size3; | |||
| if(size2 < size3) | |||
| return 0; | |||
| return safe_realloc_mul_2op_(ptr, size1, size2); | |||
| } | |||
| #endif | |||
| @@ -1,49 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__ASSERT_H | |||
| #define FLAC__ASSERT_H | |||
| /* we need this since some compilers (like MSVC) leave assert()s on release code (and we don't want to use their ASSERT) */ | |||
| #ifdef DEBUG | |||
| // JUCE: removed as JUCE already includes standard headers and including | |||
| // these in FlacNamespace will cause problems | |||
| //#include <assert.h> | |||
| #define FLAC__ASSERT(x) assert(x) | |||
| #define FLAC__ASSERT_DECLARATION(x) x | |||
| #else | |||
| #define FLAC__ASSERT(x) | |||
| #define FLAC__ASSERT_DECLARATION(x) | |||
| #endif | |||
| #endif | |||
| @@ -1,188 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__CALLBACK_H | |||
| #define FLAC__CALLBACK_H | |||
| #include "ordinals.h" | |||
| // JUCE: removed as JUCE already includes this and including stdlib | |||
| // in FlacNamespace will cause problems | |||
| //#include <stdlib.h> | |||
| /** \file include/FLAC/callback.h | |||
| * | |||
| * \brief | |||
| * This module defines the structures for describing I/O callbacks | |||
| * to the other FLAC interfaces. | |||
| * | |||
| * See the detailed documentation for callbacks in the | |||
| * \link flac_callbacks callbacks \endlink module. | |||
| */ | |||
| /** \defgroup flac_callbacks FLAC/callback.h: I/O callback structures | |||
| * \ingroup flac | |||
| * | |||
| * \brief | |||
| * This module defines the structures for describing I/O callbacks | |||
| * to the other FLAC interfaces. | |||
| * | |||
| * The purpose of the I/O callback functions is to create a common way | |||
| * for the metadata interfaces to handle I/O. | |||
| * | |||
| * Originally the metadata interfaces required filenames as the way of | |||
| * specifying FLAC files to operate on. This is problematic in some | |||
| * environments so there is an additional option to specify a set of | |||
| * callbacks for doing I/O on the FLAC file, instead of the filename. | |||
| * | |||
| * In addition to the callbacks, a FLAC__IOHandle type is defined as an | |||
| * opaque structure for a data source. | |||
| * | |||
| * The callback function prototypes are similar (but not identical) to the | |||
| * stdio functions fread, fwrite, fseek, ftell, feof, and fclose. If you use | |||
| * stdio streams to implement the callbacks, you can pass fread, fwrite, and | |||
| * fclose anywhere a FLAC__IOCallback_Read, FLAC__IOCallback_Write, or | |||
| * FLAC__IOCallback_Close is required, and a FILE* anywhere a FLAC__IOHandle | |||
| * is required. \warning You generally CANNOT directly use fseek or ftell | |||
| * for FLAC__IOCallback_Seek or FLAC__IOCallback_Tell since on most systems | |||
| * these use 32-bit offsets and FLAC requires 64-bit offsets to deal with | |||
| * large files. You will have to find an equivalent function (e.g. ftello), | |||
| * or write a wrapper. The same is true for feof() since this is usually | |||
| * implemented as a macro, not as a function whose address can be taken. | |||
| * | |||
| * \{ | |||
| */ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /** This is the opaque handle type used by the callbacks. Typically | |||
| * this is a \c FILE* or address of a file descriptor. | |||
| */ | |||
| typedef void* FLAC__IOHandle; | |||
| /** Signature for the read callback. | |||
| * The signature and semantics match POSIX fread() implementations | |||
| * and can generally be used interchangeably. | |||
| * | |||
| * \param ptr The address of the read buffer. | |||
| * \param size The size of the records to be read. | |||
| * \param nmemb The number of records to be read. | |||
| * \param handle The handle to the data source. | |||
| * \retval size_t | |||
| * The number of records read. | |||
| */ | |||
| typedef size_t (*FLAC__IOCallback_Read) (void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); | |||
| /** Signature for the write callback. | |||
| * The signature and semantics match POSIX fwrite() implementations | |||
| * and can generally be used interchangeably. | |||
| * | |||
| * \param ptr The address of the write buffer. | |||
| * \param size The size of the records to be written. | |||
| * \param nmemb The number of records to be written. | |||
| * \param handle The handle to the data source. | |||
| * \retval size_t | |||
| * The number of records written. | |||
| */ | |||
| typedef size_t (*FLAC__IOCallback_Write) (const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle); | |||
| /** Signature for the seek callback. | |||
| * The signature and semantics mostly match POSIX fseek() WITH ONE IMPORTANT | |||
| * EXCEPTION: the offset is a 64-bit type whereas fseek() is generally 'long' | |||
| * and 32-bits wide. | |||
| * | |||
| * \param handle The handle to the data source. | |||
| * \param offset The new position, relative to \a whence | |||
| * \param whence \c SEEK_SET, \c SEEK_CUR, or \c SEEK_END | |||
| * \retval int | |||
| * \c 0 on success, \c -1 on error. | |||
| */ | |||
| typedef int (*FLAC__IOCallback_Seek) (FLAC__IOHandle handle, FLAC__int64 offset, int whence); | |||
| /** Signature for the tell callback. | |||
| * The signature and semantics mostly match POSIX ftell() WITH ONE IMPORTANT | |||
| * EXCEPTION: the offset is a 64-bit type whereas ftell() is generally 'long' | |||
| * and 32-bits wide. | |||
| * | |||
| * \param handle The handle to the data source. | |||
| * \retval FLAC__int64 | |||
| * The current position on success, \c -1 on error. | |||
| */ | |||
| typedef FLAC__int64 (*FLAC__IOCallback_Tell) (FLAC__IOHandle handle); | |||
| /** Signature for the EOF callback. | |||
| * The signature and semantics mostly match POSIX feof() but WATCHOUT: | |||
| * on many systems, feof() is a macro, so in this case a wrapper function | |||
| * must be provided instead. | |||
| * | |||
| * \param handle The handle to the data source. | |||
| * \retval int | |||
| * \c 0 if not at end of file, nonzero if at end of file. | |||
| */ | |||
| typedef int (*FLAC__IOCallback_Eof) (FLAC__IOHandle handle); | |||
| /** Signature for the close callback. | |||
| * The signature and semantics match POSIX fclose() implementations | |||
| * and can generally be used interchangeably. | |||
| * | |||
| * \param handle The handle to the data source. | |||
| * \retval int | |||
| * \c 0 on success, \c EOF on error. | |||
| */ | |||
| typedef int (*FLAC__IOCallback_Close) (FLAC__IOHandle handle); | |||
| /** A structure for holding a set of callbacks. | |||
| * Each FLAC interface that requires a FLAC__IOCallbacks structure will | |||
| * describe which of the callbacks are required. The ones that are not | |||
| * required may be set to NULL. | |||
| * | |||
| * If the seek requirement for an interface is optional, you can signify that | |||
| * a data sorce is not seekable by setting the \a seek field to \c NULL. | |||
| */ | |||
| typedef struct { | |||
| FLAC__IOCallback_Read read; | |||
| FLAC__IOCallback_Write write; | |||
| FLAC__IOCallback_Seek seek; | |||
| FLAC__IOCallback_Tell tell; | |||
| FLAC__IOCallback_Eof eof; | |||
| FLAC__IOCallback_Close close; | |||
| } FLAC__IOCallbacks; | |||
| /* \} */ | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif | |||
| @@ -1,167 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2012-2014 Xiph.org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| /* This is the prefered location of all CPP hackery to make $random_compiler | |||
| * work like something approaching a C99 (or maybe more accurately GNU99) | |||
| * compiler. | |||
| * | |||
| * It is assumed that this header will be included after "config.h". | |||
| */ | |||
| #ifndef FLAC__SHARE__COMPAT_H | |||
| #define FLAC__SHARE__COMPAT_H | |||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ | |||
| #define FLAC__off_t __int64 /* use this instead of off_t to fix the 2 GB limit */ | |||
| #if !defined __MINGW32__ | |||
| #define fseeko _fseeki64 | |||
| #define ftello _ftelli64 | |||
| #else /* MinGW */ | |||
| #if !defined(HAVE_FSEEKO) | |||
| #define fseeko fseeko64 | |||
| #define ftello ftello64 | |||
| #endif | |||
| #endif | |||
| #else | |||
| #define FLAC__off_t off_t | |||
| #endif | |||
| #if defined(_MSC_VER) | |||
| #define strtoll _strtoi64 | |||
| #define strtoull _strtoui64 | |||
| #endif | |||
| #if defined(_MSC_VER) | |||
| #define inline __inline | |||
| #endif | |||
| #if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64) | |||
| /* MSVS generates VERY slow 32-bit code with __restrict */ | |||
| #define flac_restrict __restrict | |||
| #elif defined __GNUC__ | |||
| #define flac_restrict __restrict__ | |||
| #else | |||
| #define flac_restrict | |||
| #endif | |||
| #define FLAC__U64L(x) x##ULL | |||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ | |||
| #define FLAC__STRCASECMP stricmp | |||
| #define FLAC__STRNCASECMP strnicmp | |||
| #else | |||
| #define FLAC__STRCASECMP strcasecmp | |||
| #define FLAC__STRNCASECMP strncasecmp | |||
| #endif | |||
| #if defined _MSC_VER | |||
| # if _MSC_VER >= 1600 | |||
| /* Visual Studio 2010 has decent C99 support */ | |||
| # define PRIu64 "llu" | |||
| # define PRId64 "lld" | |||
| # define PRIx64 "llx" | |||
| # else | |||
| # ifndef UINT32_MAX | |||
| # define UINT32_MAX _UI32_MAX | |||
| # endif | |||
| typedef unsigned __int64 uint64_t; | |||
| typedef unsigned __int32 uint32_t; | |||
| typedef unsigned __int16 uint16_t; | |||
| typedef unsigned __int8 uint8_t; | |||
| typedef __int64 int64_t; | |||
| typedef __int32 int32_t; | |||
| typedef __int16 int16_t; | |||
| typedef __int8 int8_t; | |||
| # define PRIu64 "I64u" | |||
| # define PRId64 "I64d" | |||
| # define PRIx64 "I64x" | |||
| # endif | |||
| #endif /* defined _MSC_VER */ | |||
| #ifdef _WIN32 | |||
| /* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */ | |||
| #include "win_utf8_io.h" | |||
| #define flac_printf printf_utf8 | |||
| #define flac_fprintf fprintf_utf8 | |||
| #define flac_vfprintf vfprintf_utf8 | |||
| #define flac_fopen fopen_utf8 | |||
| #define flac_chmod chmod_utf8 | |||
| #define flac_utime utime_utf8 | |||
| #define flac_unlink unlink_utf8 | |||
| #define flac_rename rename_utf8 | |||
| #define flac_stat _stat64_utf8 | |||
| #else | |||
| #define flac_printf printf | |||
| #define flac_fprintf fprintf | |||
| #define flac_vfprintf vfprintf | |||
| #define flac_fopen fopen | |||
| #define flac_chmod chmod | |||
| #define flac_utime utime | |||
| #define flac_unlink unlink | |||
| #define flac_rename rename | |||
| #define flac_stat stat | |||
| #endif | |||
| #ifdef _WIN32 | |||
| #define flac_stat_s __stat64 /* stat struct */ | |||
| #define flac_fstat _fstat64 | |||
| #else | |||
| #define flac_stat_s stat /* stat struct */ | |||
| #define flac_fstat fstat | |||
| #endif | |||
| #ifndef M_LN2 | |||
| #define M_LN2 0.69314718055994530942 | |||
| #endif | |||
| #ifndef M_PI | |||
| #define M_PI 3.14159265358979323846 | |||
| #endif | |||
| /* FLAC needs to compile and work correctly on systems with a normal ISO C99 | |||
| * snprintf as well as Microsoft Visual Studio which has an non-standards | |||
| * conformant snprint_s function. | |||
| * | |||
| * This function wraps the MS version to behave more like the the ISO version. | |||
| */ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| int flac_snprintf(char *str, size_t size, const char *fmt, ...); | |||
| int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif /* FLAC__SHARE__COMPAT_H */ | |||
| @@ -1,80 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2012-2014 Xiph.org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| /* It is assumed that this header will be included after "config.h". */ | |||
| #if HAVE_BSWAP32 /* GCC and Clang */ | |||
| /* GCC prior to 4.8 didn't provide bswap16 on x86_64 */ | |||
| #if ! HAVE_BSWAP16 | |||
| static inline unsigned short __builtin_bswap16(unsigned short a) | |||
| { | |||
| return (a<<8)|(a>>8); | |||
| } | |||
| #endif | |||
| #define ENDSWAP_16(x) (__builtin_bswap16 (x)) | |||
| #define ENDSWAP_32(x) (__builtin_bswap32 (x)) | |||
| #elif defined _MSC_VER /* Windows. Apparently in <stdlib.h>. */ | |||
| #define ENDSWAP_16(x) (_byteswap_ushort (x)) | |||
| #define ENDSWAP_32(x) (_byteswap_ulong (x)) | |||
| #elif defined HAVE_BYTESWAP_H /* Linux */ | |||
| // JUCE: removed as JUCE already includes standard headers and including | |||
| // these in FlacNamespace will cause problems | |||
| //#include <byteswap.h> | |||
| #define ENDSWAP_16(x) (bswap_16 (x)) | |||
| #define ENDSWAP_32(x) (bswap_32 (x)) | |||
| #else | |||
| #define ENDSWAP_16(x) ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8)) | |||
| #define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) & 0xFF00) << 8) | (((x) & 0xFF) << 24)) | |||
| #endif | |||
| /* Host to little-endian byte swapping. */ | |||
| #if CPU_IS_BIG_ENDIAN | |||
| #define H2LE_16(x) ENDSWAP_16 (x) | |||
| #define H2LE_32(x) ENDSWAP_32 (x) | |||
| #else | |||
| #define H2LE_16(x) (x) | |||
| #define H2LE_32(x) (x) | |||
| #endif | |||
| @@ -1,97 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__EXPORT_H | |||
| #define FLAC__EXPORT_H | |||
| /** \file include/FLAC/export.h | |||
| * | |||
| * \brief | |||
| * This module contains #defines and symbols for exporting function | |||
| * calls, and providing version information and compiled-in features. | |||
| * | |||
| * See the \link flac_export export \endlink module. | |||
| */ | |||
| /** \defgroup flac_export FLAC/export.h: export symbols | |||
| * \ingroup flac | |||
| * | |||
| * \brief | |||
| * This module contains #defines and symbols for exporting function | |||
| * calls, and providing version information and compiled-in features. | |||
| * | |||
| * If you are compiling with MSVC and will link to the static library | |||
| * (libFLAC.lib) you should define FLAC__NO_DLL in your project to | |||
| * make sure the symbols are exported properly. | |||
| * | |||
| * \{ | |||
| */ | |||
| #if defined(FLAC__NO_DLL) | |||
| #define FLAC_API | |||
| #elif defined(_MSC_VER) | |||
| #ifdef FLAC_API_EXPORTS | |||
| #define FLAC_API __declspec(dllexport) | |||
| #else | |||
| #define FLAC_API __declspec(dllimport) | |||
| #endif | |||
| #elif defined(FLAC__USE_VISIBILITY_ATTR) | |||
| #define FLAC_API __attribute__ ((visibility ("default"))) | |||
| #else | |||
| #define FLAC_API | |||
| #endif | |||
| /** These #defines will mirror the libtool-based library version number, see | |||
| * http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning | |||
| */ | |||
| #define FLAC_API_VERSION_CURRENT 11 | |||
| #define FLAC_API_VERSION_REVISION 0 /**< see above */ | |||
| #define FLAC_API_VERSION_AGE 3 /**< see above */ | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| /** \c 1 if the library has been compiled with support for Ogg FLAC, else \c 0. */ | |||
| extern FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC; | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| /* \} */ | |||
| #endif | |||
| @@ -1,109 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/bitmath.h" | |||
| /* An example of what FLAC__bitmath_silog2() computes: | |||
| * | |||
| * silog2(-10) = 5 | |||
| * silog2(- 9) = 5 | |||
| * silog2(- 8) = 4 | |||
| * silog2(- 7) = 4 | |||
| * silog2(- 6) = 4 | |||
| * silog2(- 5) = 4 | |||
| * silog2(- 4) = 3 | |||
| * silog2(- 3) = 3 | |||
| * silog2(- 2) = 2 | |||
| * silog2(- 1) = 2 | |||
| * silog2( 0) = 0 | |||
| * silog2( 1) = 2 | |||
| * silog2( 2) = 3 | |||
| * silog2( 3) = 3 | |||
| * silog2( 4) = 4 | |||
| * silog2( 5) = 4 | |||
| * silog2( 6) = 4 | |||
| * silog2( 7) = 4 | |||
| * silog2( 8) = 5 | |||
| * silog2( 9) = 5 | |||
| * silog2( 10) = 5 | |||
| */ | |||
| unsigned FLAC__bitmath_silog2(int v) | |||
| { | |||
| while(1) { | |||
| if(v == 0) { | |||
| return 0; | |||
| } | |||
| else if(v > 0) { | |||
| unsigned l = 0; | |||
| while(v) { | |||
| l++; | |||
| v >>= 1; | |||
| } | |||
| return l+1; | |||
| } | |||
| else if(v == -1) { | |||
| return 2; | |||
| } | |||
| else { | |||
| v++; | |||
| v = -v; | |||
| } | |||
| } | |||
| } | |||
| unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v) | |||
| { | |||
| while(1) { | |||
| if(v == 0) { | |||
| return 0; | |||
| } | |||
| else if(v > 0) { | |||
| unsigned l = 0; | |||
| while(v) { | |||
| l++; | |||
| v >>= 1; | |||
| } | |||
| return l+1; | |||
| } | |||
| else if(v == -1) { | |||
| return 2; | |||
| } | |||
| else { | |||
| v++; | |||
| v = -v; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,842 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include "include/private/bitwriter.h" | |||
| #include "include/private/crc.h" | |||
| #include "../assert.h" | |||
| #include "../alloc.h" | |||
| #include "../compat.h" | |||
| #include "../endswap.h" | |||
| /* Things should be fastest when this matches the machine word size */ | |||
| /* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */ | |||
| /* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */ | |||
| #define FLAC__BYTES_PER_WORD 4 | |||
| #define FLAC__BITS_PER_WORD (8 * FLAC__BYTES_PER_WORD) | |||
| #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff) | |||
| /* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */ | |||
| #if WORDS_BIGENDIAN | |||
| #define SWAP_BE_WORD_TO_HOST(x) (x) | |||
| #else | |||
| #define SWAP_BE_WORD_TO_HOST(x) ENDSWAP_32(x) | |||
| #endif | |||
| /* | |||
| * The default capacity here doesn't matter too much. The buffer always grows | |||
| * to hold whatever is written to it. Usually the encoder will stop adding at | |||
| * a frame or metadata block, then write that out and clear the buffer for the | |||
| * next one. | |||
| */ | |||
| static const unsigned FLAC__BITWRITER_DEFAULT_CAPACITY = 32768u / sizeof(uint32_t); /* size in words */ | |||
| /* When growing, increment 4K at a time */ | |||
| static const unsigned FLAC__BITWRITER_DEFAULT_INCREMENT = 4096u / sizeof(uint32_t); /* size in words */ | |||
| #define FLAC__WORDS_TO_BITS(words) ((words) * FLAC__BITS_PER_WORD) | |||
| #define FLAC__TOTAL_BITS(bw) (FLAC__WORDS_TO_BITS((bw)->words) + (bw)->bits) | |||
| struct FLAC__BitWriter { | |||
| uint32_t *buffer; | |||
| uint32_t accum; /* accumulator; bits are right-justified; when full, accum is appended to buffer */ | |||
| unsigned capacity; /* capacity of buffer in words */ | |||
| unsigned words; /* # of complete words in buffer */ | |||
| unsigned bits; /* # of used bits in accum */ | |||
| }; | |||
| /* * WATCHOUT: The current implementation only grows the buffer. */ | |||
| #ifndef __SUNPRO_C | |||
| static | |||
| #endif | |||
| FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, unsigned bits_to_add) | |||
| { | |||
| unsigned new_capacity; | |||
| uint32_t *new_buffer; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| /* calculate total words needed to store 'bits_to_add' additional bits */ | |||
| new_capacity = bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD); | |||
| /* it's possible (due to pessimism in the growth estimation that | |||
| * leads to this call) that we don't actually need to grow | |||
| */ | |||
| if(bw->capacity >= new_capacity) | |||
| return true; | |||
| /* round up capacity increase to the nearest FLAC__BITWRITER_DEFAULT_INCREMENT */ | |||
| if((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT) | |||
| new_capacity += FLAC__BITWRITER_DEFAULT_INCREMENT - ((new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT); | |||
| /* make sure we got everything right */ | |||
| FLAC__ASSERT(0 == (new_capacity - bw->capacity) % FLAC__BITWRITER_DEFAULT_INCREMENT); | |||
| FLAC__ASSERT(new_capacity > bw->capacity); | |||
| FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD)); | |||
| new_buffer = (uint32_t*) safe_realloc_mul_2op_(bw->buffer, sizeof(uint32_t), /*times*/new_capacity); | |||
| if(new_buffer == 0) | |||
| return false; | |||
| bw->buffer = new_buffer; | |||
| bw->capacity = new_capacity; | |||
| return true; | |||
| } | |||
| /*********************************************************************** | |||
| * | |||
| * Class constructor/destructor | |||
| * | |||
| ***********************************************************************/ | |||
| FLAC__BitWriter *FLAC__bitwriter_new(void) | |||
| { | |||
| FLAC__BitWriter *bw = (FLAC__BitWriter*) calloc(1, sizeof(FLAC__BitWriter)); | |||
| /* note that calloc() sets all members to 0 for us */ | |||
| return bw; | |||
| } | |||
| void FLAC__bitwriter_delete(FLAC__BitWriter *bw) | |||
| { | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__bitwriter_free(bw); | |||
| free(bw); | |||
| } | |||
| /*********************************************************************** | |||
| * | |||
| * Public class methods | |||
| * | |||
| ***********************************************************************/ | |||
| FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw) | |||
| { | |||
| FLAC__ASSERT(0 != bw); | |||
| bw->words = bw->bits = 0; | |||
| bw->capacity = FLAC__BITWRITER_DEFAULT_CAPACITY; | |||
| bw->buffer = (uint32_t*) malloc(sizeof(uint32_t) * bw->capacity); | |||
| if(bw->buffer == 0) | |||
| return false; | |||
| return true; | |||
| } | |||
| void FLAC__bitwriter_free(FLAC__BitWriter *bw) | |||
| { | |||
| FLAC__ASSERT(0 != bw); | |||
| if(0 != bw->buffer) | |||
| free(bw->buffer); | |||
| bw->buffer = 0; | |||
| bw->capacity = 0; | |||
| bw->words = bw->bits = 0; | |||
| } | |||
| void FLAC__bitwriter_clear(FLAC__BitWriter *bw) | |||
| { | |||
| bw->words = bw->bits = 0; | |||
| } | |||
| void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out) | |||
| { | |||
| unsigned i, j; | |||
| if(bw == 0) { | |||
| fprintf(out, "bitwriter is NULL\n"); | |||
| } | |||
| else { | |||
| fprintf(out, "bitwriter: capacity=%u words=%u bits=%u total_bits=%u\n", bw->capacity, bw->words, bw->bits, FLAC__TOTAL_BITS(bw)); | |||
| for(i = 0; i < bw->words; i++) { | |||
| fprintf(out, "%08X: ", i); | |||
| for(j = 0; j < FLAC__BITS_PER_WORD; j++) | |||
| fprintf(out, "%01u", bw->buffer[i] & (1 << (FLAC__BITS_PER_WORD-j-1)) ? 1:0); | |||
| fprintf(out, "\n"); | |||
| } | |||
| if(bw->bits > 0) { | |||
| fprintf(out, "%08X: ", i); | |||
| for(j = 0; j < bw->bits; j++) | |||
| fprintf(out, "%01u", bw->accum & (1 << (bw->bits-j-1)) ? 1:0); | |||
| fprintf(out, "\n"); | |||
| } | |||
| } | |||
| } | |||
| FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc) | |||
| { | |||
| const FLAC__byte *buffer; | |||
| size_t bytes; | |||
| FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */ | |||
| if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes)) | |||
| return false; | |||
| *crc = (FLAC__uint16)FLAC__crc16(buffer, bytes); | |||
| FLAC__bitwriter_release_buffer(bw); | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc) | |||
| { | |||
| const FLAC__byte *buffer; | |||
| size_t bytes; | |||
| FLAC__ASSERT((bw->bits & 7) == 0); /* assert that we're byte-aligned */ | |||
| if(!FLAC__bitwriter_get_buffer(bw, &buffer, &bytes)) | |||
| return false; | |||
| *crc = FLAC__crc8(buffer, bytes); | |||
| FLAC__bitwriter_release_buffer(bw); | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw) | |||
| { | |||
| return ((bw->bits & 7) == 0); | |||
| } | |||
| unsigned FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw) | |||
| { | |||
| return FLAC__TOTAL_BITS(bw); | |||
| } | |||
| FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes) | |||
| { | |||
| FLAC__ASSERT((bw->bits & 7) == 0); | |||
| /* double protection */ | |||
| if(bw->bits & 7) | |||
| return false; | |||
| /* if we have bits in the accumulator we have to flush those to the buffer first */ | |||
| if(bw->bits) { | |||
| FLAC__ASSERT(bw->words <= bw->capacity); | |||
| if(bw->words == bw->capacity && !bitwriter_grow_(bw, FLAC__BITS_PER_WORD)) | |||
| return false; | |||
| /* append bits as complete word to buffer, but don't change bw->accum or bw->bits */ | |||
| bw->buffer[bw->words] = SWAP_BE_WORD_TO_HOST(bw->accum << (FLAC__BITS_PER_WORD-bw->bits)); | |||
| } | |||
| /* now we can just return what we have */ | |||
| *buffer = (FLAC__byte*)bw->buffer; | |||
| *bytes = (FLAC__BYTES_PER_WORD * bw->words) + (bw->bits >> 3); | |||
| return true; | |||
| } | |||
| void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw) | |||
| { | |||
| /* nothing to do. in the future, strict checking of a 'writer-is-in- | |||
| * get-mode' flag could be added everywhere and then cleared here | |||
| */ | |||
| (void)bw; | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits) | |||
| { | |||
| unsigned n; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| if(bits == 0) | |||
| return true; | |||
| /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ | |||
| if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits)) | |||
| return false; | |||
| /* first part gets to word alignment */ | |||
| if(bw->bits) { | |||
| n = flac_min(FLAC__BITS_PER_WORD - bw->bits, bits); | |||
| bw->accum <<= n; | |||
| bits -= n; | |||
| bw->bits += n; | |||
| if(bw->bits == FLAC__BITS_PER_WORD) { | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); | |||
| bw->bits = 0; | |||
| } | |||
| else | |||
| return true; | |||
| } | |||
| /* do whole words */ | |||
| while(bits >= FLAC__BITS_PER_WORD) { | |||
| bw->buffer[bw->words++] = 0; | |||
| bits -= FLAC__BITS_PER_WORD; | |||
| } | |||
| /* do any leftovers */ | |||
| if(bits > 0) { | |||
| bw->accum = 0; | |||
| bw->bits = bits; | |||
| } | |||
| return true; | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits) | |||
| { | |||
| unsigned left; | |||
| /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ | |||
| FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(bits <= 32); | |||
| if(bits == 0) | |||
| return true; | |||
| /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+bits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ | |||
| if(bw->capacity <= bw->words + bits && !bitwriter_grow_(bw, bits)) | |||
| return false; | |||
| left = FLAC__BITS_PER_WORD - bw->bits; | |||
| if(bits < left) { | |||
| bw->accum <<= bits; | |||
| bw->accum |= val; | |||
| bw->bits += bits; | |||
| } | |||
| else if(bw->bits) { /* WATCHOUT: if bw->bits == 0, left==FLAC__BITS_PER_WORD and bw->accum<<=left is a NOP instead of setting to 0 */ | |||
| bw->accum <<= left; | |||
| bw->accum |= val >> (bw->bits = bits - left); | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); | |||
| bw->accum = val; | |||
| } | |||
| else { | |||
| bw->accum = val; | |||
| bw->bits = 0; | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(val); | |||
| } | |||
| return true; | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits) | |||
| { | |||
| /* zero-out unused bits */ | |||
| if(bits < 32) | |||
| val &= (~(0xffffffff << bits)); | |||
| return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits); | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits) | |||
| { | |||
| /* this could be a little faster but it's not used for much */ | |||
| if(bits > 32) { | |||
| return | |||
| FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)(val>>32), bits-32) && | |||
| FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, 32); | |||
| } | |||
| else | |||
| return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, bits); | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val) | |||
| { | |||
| /* this doesn't need to be that fast as currently it is only used for vorbis comments */ | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, val & 0xff, 8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, (val>>8) & 0xff, 8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, (val>>16) & 0xff, 8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, val>>24, 8)) | |||
| return false; | |||
| return true; | |||
| } | |||
| inline FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals) | |||
| { | |||
| unsigned i; | |||
| /* this could be faster but currently we don't need it to be since it's only used for writing metadata */ | |||
| for(i = 0; i < nvals; i++) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)(vals[i]), 8)) | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, unsigned val) | |||
| { | |||
| if(val < 32) | |||
| return FLAC__bitwriter_write_raw_uint32(bw, 1, ++val); | |||
| else | |||
| return | |||
| FLAC__bitwriter_write_zeroes(bw, val) && | |||
| FLAC__bitwriter_write_raw_uint32(bw, 1, 1); | |||
| } | |||
| unsigned FLAC__bitwriter_rice_bits(FLAC__int32 val, unsigned parameter) | |||
| { | |||
| FLAC__uint32 uval; | |||
| FLAC__ASSERT(parameter < sizeof(unsigned)*8); | |||
| /* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */ | |||
| uval = (val<<1) ^ (val>>31); | |||
| return 1 + parameter + (uval >> parameter); | |||
| } | |||
| #if 0 /* UNUSED */ | |||
| unsigned FLAC__bitwriter_golomb_bits_signed(int val, unsigned parameter) | |||
| { | |||
| unsigned bits, msbs, uval; | |||
| unsigned k; | |||
| FLAC__ASSERT(parameter > 0); | |||
| /* fold signed to unsigned */ | |||
| if(val < 0) | |||
| uval = (unsigned)(((-(++val)) << 1) + 1); | |||
| else | |||
| uval = (unsigned)(val << 1); | |||
| k = FLAC__bitmath_ilog2(parameter); | |||
| if(parameter == 1u<<k) { | |||
| FLAC__ASSERT(k <= 30); | |||
| msbs = uval >> k; | |||
| bits = 1 + k + msbs; | |||
| } | |||
| else { | |||
| unsigned q, r, d; | |||
| d = (1 << (k+1)) - parameter; | |||
| q = uval / parameter; | |||
| r = uval - (q * parameter); | |||
| bits = 1 + q + k; | |||
| if(r >= d) | |||
| bits++; | |||
| } | |||
| return bits; | |||
| } | |||
| unsigned FLAC__bitwriter_golomb_bits_unsigned(unsigned uval, unsigned parameter) | |||
| { | |||
| unsigned bits, msbs; | |||
| unsigned k; | |||
| FLAC__ASSERT(parameter > 0); | |||
| k = FLAC__bitmath_ilog2(parameter); | |||
| if(parameter == 1u<<k) { | |||
| FLAC__ASSERT(k <= 30); | |||
| msbs = uval >> k; | |||
| bits = 1 + k + msbs; | |||
| } | |||
| else { | |||
| unsigned q, r, d; | |||
| d = (1 << (k+1)) - parameter; | |||
| q = uval / parameter; | |||
| r = uval - (q * parameter); | |||
| bits = 1 + q + k; | |||
| if(r >= d) | |||
| bits++; | |||
| } | |||
| return bits; | |||
| } | |||
| #endif /* UNUSED */ | |||
| FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, unsigned parameter) | |||
| { | |||
| unsigned total_bits, interesting_bits, msbs; | |||
| FLAC__uint32 uval, pattern; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(parameter < 8*sizeof(uval)); | |||
| /* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */ | |||
| uval = (val<<1) ^ (val>>31); | |||
| msbs = uval >> parameter; | |||
| interesting_bits = 1 + parameter; | |||
| total_bits = interesting_bits + msbs; | |||
| pattern = 1 << parameter; /* the unary end bit */ | |||
| pattern |= (uval & ((1<<parameter)-1)); /* the binary LSBs */ | |||
| if(total_bits <= 32) | |||
| return FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits); | |||
| else | |||
| return | |||
| FLAC__bitwriter_write_zeroes(bw, msbs) && /* write the unary MSBs */ | |||
| FLAC__bitwriter_write_raw_uint32(bw, pattern, interesting_bits); /* write the unary end bit and binary LSBs */ | |||
| } | |||
| FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, unsigned nvals, unsigned parameter) | |||
| { | |||
| const FLAC__uint32 mask1 = FLAC__WORD_ALL_ONES << parameter; /* we val|=mask1 to set the stop bit above it... */ | |||
| const FLAC__uint32 mask2 = FLAC__WORD_ALL_ONES >> (31-parameter); /* ...then mask off the bits above the stop bit with val&=mask2*/ | |||
| FLAC__uint32 uval; | |||
| unsigned left; | |||
| const unsigned lsbits = 1 + parameter; | |||
| unsigned msbits; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(parameter < 8*sizeof(uint32_t)-1); | |||
| /* WATCHOUT: code does not work with <32bit words; we can make things much faster with this assertion */ | |||
| FLAC__ASSERT(FLAC__BITS_PER_WORD >= 32); | |||
| while(nvals) { | |||
| /* fold signed to unsigned; actual formula is: negative(v)? -2v-1 : 2v */ | |||
| uval = (*vals<<1) ^ (*vals>>31); | |||
| msbits = uval >> parameter; | |||
| if(bw->bits && bw->bits + msbits + lsbits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */ | |||
| /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */ | |||
| bw->bits = bw->bits + msbits + lsbits; | |||
| uval |= mask1; /* set stop bit */ | |||
| uval &= mask2; /* mask off unused top bits */ | |||
| bw->accum <<= msbits + lsbits; | |||
| bw->accum |= uval; | |||
| } | |||
| else { | |||
| /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ | |||
| /* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */ | |||
| if(bw->capacity <= bw->words + bw->bits + msbits + 1/*lsbits always fit in 1 uint32_t*/ && !bitwriter_grow_(bw, msbits+lsbits)) | |||
| return false; | |||
| if(msbits) { | |||
| /* first part gets to word alignment */ | |||
| if(bw->bits) { | |||
| left = FLAC__BITS_PER_WORD - bw->bits; | |||
| if(msbits < left) { | |||
| bw->accum <<= msbits; | |||
| bw->bits += msbits; | |||
| goto break1; | |||
| } | |||
| else { | |||
| bw->accum <<= left; | |||
| msbits -= left; | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); | |||
| bw->bits = 0; | |||
| } | |||
| } | |||
| /* do whole words */ | |||
| while(msbits >= FLAC__BITS_PER_WORD) { | |||
| bw->buffer[bw->words++] = 0; | |||
| msbits -= FLAC__BITS_PER_WORD; | |||
| } | |||
| /* do any leftovers */ | |||
| if(msbits > 0) { | |||
| bw->accum = 0; | |||
| bw->bits = msbits; | |||
| } | |||
| } | |||
| break1: | |||
| uval |= mask1; /* set stop bit */ | |||
| uval &= mask2; /* mask off unused top bits */ | |||
| left = FLAC__BITS_PER_WORD - bw->bits; | |||
| if(lsbits < left) { | |||
| bw->accum <<= lsbits; | |||
| bw->accum |= uval; | |||
| bw->bits += lsbits; | |||
| } | |||
| else { | |||
| /* if bw->bits == 0, left==FLAC__BITS_PER_WORD which will always | |||
| * be > lsbits (because of previous assertions) so it would have | |||
| * triggered the (lsbits<left) case above. | |||
| */ | |||
| FLAC__ASSERT(bw->bits); | |||
| FLAC__ASSERT(left < FLAC__BITS_PER_WORD); | |||
| bw->accum <<= left; | |||
| bw->accum |= uval >> (bw->bits = lsbits - left); | |||
| bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); | |||
| bw->accum = uval; | |||
| } | |||
| } | |||
| vals++; | |||
| nvals--; | |||
| } | |||
| return true; | |||
| } | |||
| #if 0 /* UNUSED */ | |||
| FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, unsigned parameter) | |||
| { | |||
| unsigned total_bits, msbs, uval; | |||
| unsigned k; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(parameter > 0); | |||
| /* fold signed to unsigned */ | |||
| if(val < 0) | |||
| uval = (unsigned)(((-(++val)) << 1) + 1); | |||
| else | |||
| uval = (unsigned)(val << 1); | |||
| k = FLAC__bitmath_ilog2(parameter); | |||
| if(parameter == 1u<<k) { | |||
| unsigned pattern; | |||
| FLAC__ASSERT(k <= 30); | |||
| msbs = uval >> k; | |||
| total_bits = 1 + k + msbs; | |||
| pattern = 1 << k; /* the unary end bit */ | |||
| pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */ | |||
| if(total_bits <= 32) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits)) | |||
| return false; | |||
| } | |||
| else { | |||
| /* write the unary MSBs */ | |||
| if(!FLAC__bitwriter_write_zeroes(bw, msbs)) | |||
| return false; | |||
| /* write the unary end bit and binary LSBs */ | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1)) | |||
| return false; | |||
| } | |||
| } | |||
| else { | |||
| unsigned q, r, d; | |||
| d = (1 << (k+1)) - parameter; | |||
| q = uval / parameter; | |||
| r = uval - (q * parameter); | |||
| /* write the unary MSBs */ | |||
| if(!FLAC__bitwriter_write_zeroes(bw, q)) | |||
| return false; | |||
| /* write the unary end bit */ | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1)) | |||
| return false; | |||
| /* write the binary LSBs */ | |||
| if(r >= d) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1)) | |||
| return false; | |||
| } | |||
| else { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, r, k)) | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, unsigned uval, unsigned parameter) | |||
| { | |||
| unsigned total_bits, msbs; | |||
| unsigned k; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(parameter > 0); | |||
| k = FLAC__bitmath_ilog2(parameter); | |||
| if(parameter == 1u<<k) { | |||
| unsigned pattern; | |||
| FLAC__ASSERT(k <= 30); | |||
| msbs = uval >> k; | |||
| total_bits = 1 + k + msbs; | |||
| pattern = 1 << k; /* the unary end bit */ | |||
| pattern |= (uval & ((1u<<k)-1)); /* the binary LSBs */ | |||
| if(total_bits <= 32) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, total_bits)) | |||
| return false; | |||
| } | |||
| else { | |||
| /* write the unary MSBs */ | |||
| if(!FLAC__bitwriter_write_zeroes(bw, msbs)) | |||
| return false; | |||
| /* write the unary end bit and binary LSBs */ | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pattern, k+1)) | |||
| return false; | |||
| } | |||
| } | |||
| else { | |||
| unsigned q, r, d; | |||
| d = (1 << (k+1)) - parameter; | |||
| q = uval / parameter; | |||
| r = uval - (q * parameter); | |||
| /* write the unary MSBs */ | |||
| if(!FLAC__bitwriter_write_zeroes(bw, q)) | |||
| return false; | |||
| /* write the unary end bit */ | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, 1, 1)) | |||
| return false; | |||
| /* write the binary LSBs */ | |||
| if(r >= d) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, r+d, k+1)) | |||
| return false; | |||
| } | |||
| else { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, r, k)) | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| #endif /* UNUSED */ | |||
| FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val) | |||
| { | |||
| FLAC__bool ok = 1; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(!(val & 0x80000000)); /* this version only handles 31 bits */ | |||
| if(val < 0x80) { | |||
| return FLAC__bitwriter_write_raw_uint32(bw, val, 8); | |||
| } | |||
| else if(val < 0x800) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xC0 | (val>>6), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| else if(val < 0x10000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xE0 | (val>>12), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| else if(val < 0x200000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF0 | (val>>18), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| else if(val < 0x4000000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF8 | (val>>24), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| else { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xFC | (val>>30), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>24)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | ((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (val&0x3F), 8); | |||
| } | |||
| return ok; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val) | |||
| { | |||
| FLAC__bool ok = 1; | |||
| FLAC__ASSERT(0 != bw); | |||
| FLAC__ASSERT(0 != bw->buffer); | |||
| FLAC__ASSERT(!(val & FLAC__U64L(0xFFFFFFF000000000))); /* this version only handles 36 bits */ | |||
| if(val < 0x80) { | |||
| return FLAC__bitwriter_write_raw_uint32(bw, (FLAC__uint32)val, 8); | |||
| } | |||
| else if(val < 0x800) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xC0 | (FLAC__uint32)(val>>6), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else if(val < 0x10000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xE0 | (FLAC__uint32)(val>>12), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else if(val < 0x200000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF0 | (FLAC__uint32)(val>>18), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else if(val < 0x4000000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xF8 | (FLAC__uint32)(val>>24), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else if(val < 0x80000000) { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xFC | (FLAC__uint32)(val>>30), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| else { | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0xFE, 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>30)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>24)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>18)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>12)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)((val>>6)&0x3F), 8); | |||
| ok &= FLAC__bitwriter_write_raw_uint32(bw, 0x80 | (FLAC__uint32)(val&0x3F), 8); | |||
| } | |||
| return ok; | |||
| } | |||
| FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw) | |||
| { | |||
| /* 0-pad to byte boundary */ | |||
| if(bw->bits & 7u) | |||
| return FLAC__bitwriter_write_zeroes(bw, 8 - (bw->bits & 7u)); | |||
| else | |||
| return true; | |||
| } | |||
| /* These functions are declared inline in this file but are also callable as | |||
| * externs from elsewhere. | |||
| * According to the C99 spec, section 6.7.4, simply providing a function | |||
| * prototype in a header file without 'inline' and making the function inline | |||
| * in this file should be sufficient. | |||
| * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To | |||
| * fix that we add extern declarations here. | |||
| */ | |||
| extern FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits); | |||
| extern FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits); | |||
| extern FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits); | |||
| extern FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); | |||
| extern FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals); | |||
| @@ -1,494 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/cpu.h" | |||
| #if 0 | |||
| #include <stdlib.h> | |||
| #include <memory.h> | |||
| #include <stdio.h> | |||
| #endif | |||
| #if defined FLAC__CPU_IA32 | |||
| # include <signal.h> | |||
| static void disable_sse(FLAC__CPUInfo *info) | |||
| { | |||
| info->ia32.sse = false; | |||
| info->ia32.sse2 = false; | |||
| info->ia32.sse3 = false; | |||
| info->ia32.ssse3 = false; | |||
| info->ia32.sse41 = false; | |||
| info->ia32.sse42 = false; | |||
| } | |||
| static void disable_avx(FLAC__CPUInfo *info) | |||
| { | |||
| info->ia32.avx = false; | |||
| info->ia32.avx2 = false; | |||
| info->ia32.fma = false; | |||
| } | |||
| #elif defined FLAC__CPU_X86_64 | |||
| static void disable_avx(FLAC__CPUInfo *info) | |||
| { | |||
| info->x86.avx = false; | |||
| info->x86.avx2 = false; | |||
| info->x86.fma = false; | |||
| } | |||
| #endif | |||
| #if defined (__NetBSD__) || defined(__OpenBSD__) | |||
| #include <sys/param.h> | |||
| #include <sys/sysctl.h> | |||
| #include <machine/cpu.h> | |||
| #endif | |||
| #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) | |||
| #include <sys/types.h> | |||
| #include <sys/sysctl.h> | |||
| #endif | |||
| #if defined(__APPLE__) | |||
| /* how to get sysctlbyname()? */ | |||
| #endif | |||
| #ifdef FLAC__CPU_IA32 | |||
| /* these are flags in EDX of CPUID AX=00000001 */ | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000; | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000; | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000; | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000; | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000; | |||
| #endif | |||
| /* these are flags in ECX of CPUID AX=00000001 */ | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001; | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200; | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000; | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000; | |||
| #if defined FLAC__AVX_SUPPORTED | |||
| /* these are flags in ECX of CPUID AX=00000001 */ | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000; | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000; | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000; | |||
| /* these are flags in EBX of CPUID AX=00000007 */ | |||
| static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020; | |||
| #endif | |||
| /* | |||
| * Extra stuff needed for detection of OS support for SSE on IA-32 | |||
| */ | |||
| #if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS | |||
| # if defined(__linux__) | |||
| /* | |||
| * If the OS doesn't support SSE, we will get here with a SIGILL. We | |||
| * modify the return address to jump over the offending SSE instruction | |||
| * and also the operation following it that indicates the instruction | |||
| * executed successfully. In this way we use no global variables and | |||
| * stay thread-safe. | |||
| * | |||
| * 3 + 3 + 6: | |||
| * 3 bytes for "xorps xmm0,xmm0" | |||
| * 3 bytes for estimate of how long the follwing "inc var" instruction is | |||
| * 6 bytes extra in case our estimate is wrong | |||
| * 12 bytes puts us in the NOP "landing zone" | |||
| */ | |||
| # include <sys/ucontext.h> | |||
| static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc) | |||
| { | |||
| (void)signal, (void)si; | |||
| ((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6; | |||
| } | |||
| # elif defined(_MSC_VER) | |||
| # include <windows.h> | |||
| # endif | |||
| #endif | |||
| void FLAC__cpu_info(FLAC__CPUInfo *info) | |||
| { | |||
| /* | |||
| * IA32-specific | |||
| */ | |||
| #ifdef FLAC__CPU_IA32 | |||
| FLAC__bool ia32_fxsr = false; | |||
| FLAC__bool ia32_osxsave = false; | |||
| (void) ia32_fxsr; (void) ia32_osxsave; /* to avoid warnings about unused variables */ | |||
| memset(info, 0, sizeof(*info)); | |||
| info->type = FLAC__CPUINFO_TYPE_IA32; | |||
| #if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) | |||
| info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */ | |||
| #ifdef FLAC__HAS_X86INTRIN | |||
| if(!FLAC__cpu_have_cpuid_x86()) | |||
| return; | |||
| #else | |||
| if(!FLAC__cpu_have_cpuid_asm_ia32()) | |||
| return; | |||
| #endif | |||
| { | |||
| /* http://www.sandpile.org/x86/cpuid.htm */ | |||
| #ifdef FLAC__HAS_X86INTRIN | |||
| FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; | |||
| FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); | |||
| #else | |||
| FLAC__uint32 flags_ecx, flags_edx; | |||
| FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx); | |||
| #endif | |||
| info->ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false; | |||
| info->ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false; | |||
| ia32_fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false; | |||
| info->ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false; | |||
| info->ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false; | |||
| info->ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false; | |||
| info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false; | |||
| info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false; | |||
| info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false; | |||
| #if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED | |||
| ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false; | |||
| info->ia32.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false; | |||
| info->ia32.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false; | |||
| FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); | |||
| info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false; | |||
| #endif | |||
| } | |||
| #ifdef DEBUG | |||
| fprintf(stderr, "CPU info (IA-32):\n"); | |||
| fprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n'); | |||
| fprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n'); | |||
| fprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n'); | |||
| fprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n'); | |||
| fprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n'); | |||
| fprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n'); | |||
| fprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n'); | |||
| fprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n'); | |||
| # if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED | |||
| fprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n'); | |||
| fprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n'); | |||
| fprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n'); | |||
| # endif | |||
| #endif | |||
| /* | |||
| * now have to check for OS support of SSE instructions | |||
| */ | |||
| if(info->ia32.sse) { | |||
| #if defined FLAC__NO_SSE_OS | |||
| /* assume user knows better than us; turn it off */ | |||
| disable_sse(info); | |||
| #elif defined FLAC__SSE_OS | |||
| /* assume user knows better than us; leave as detected above */ | |||
| #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__) | |||
| int sse = 0; | |||
| size_t len; | |||
| /* at least one of these must work: */ | |||
| len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse); | |||
| len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */ | |||
| if(!sse) | |||
| disable_sse(info); | |||
| #elif defined(__NetBSD__) || defined (__OpenBSD__) | |||
| # if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__) | |||
| int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE }; | |||
| size_t len = sizeof(val); | |||
| if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) | |||
| disable_sse(info); | |||
| else { /* double-check SSE2 */ | |||
| mib[1] = CPU_SSE2; | |||
| len = sizeof(val); | |||
| if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) { | |||
| disable_sse(info); | |||
| info->ia32.sse = true; | |||
| } | |||
| } | |||
| # else | |||
| disable_sse(info); | |||
| # endif | |||
| #elif defined(__linux__) | |||
| int sse = 0; | |||
| struct sigaction sigill_save; | |||
| struct sigaction sigill_sse; | |||
| sigill_sse.sa_sigaction = sigill_handler_sse_os; | |||
| #ifdef __ANDROID__ | |||
| sigemptyset (&sigill_sse.sa_mask); | |||
| #else | |||
| __sigemptyset(&sigill_sse.sa_mask); | |||
| #endif | |||
| sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */ | |||
| if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save)) | |||
| { | |||
| /* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */ | |||
| /* see sigill_handler_sse_os() for an explanation of the following: */ | |||
| asm volatile ( | |||
| "xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */ | |||
| "incl %0\n\t" /* SIGILL handler will jump over this */ | |||
| /* landing zone */ | |||
| "nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */ | |||
| "nop\n\t" | |||
| "nop\n\t" | |||
| "nop\n\t" | |||
| "nop\n\t" | |||
| "nop\n\t" | |||
| "nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */ | |||
| "nop\n\t" | |||
| "nop" /* SIGILL jump lands here if "inc" is 1 byte */ | |||
| : "=r"(sse) | |||
| : "0"(sse) | |||
| ); | |||
| sigaction(SIGILL, &sigill_save, NULL); | |||
| } | |||
| if(!sse) | |||
| disable_sse(info); | |||
| #elif defined(_MSC_VER) | |||
| __try { | |||
| __asm { | |||
| xorps xmm0,xmm0 | |||
| } | |||
| } | |||
| __except(EXCEPTION_EXECUTE_HANDLER) { | |||
| if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION) | |||
| disable_sse(info); | |||
| } | |||
| #elif defined(__GNUC__) /* MinGW goes here */ | |||
| int sse = 0; | |||
| /* Based on the idea described in Agner Fog's manual "Optimizing subroutines in assembly language" */ | |||
| /* In theory, not guaranteed to detect lack of OS SSE support on some future Intel CPUs, but in practice works (see the aforementioned manual) */ | |||
| if (ia32_fxsr) { | |||
| struct { | |||
| FLAC__uint32 buff[128]; | |||
| } __attribute__((aligned(16))) fxsr; | |||
| FLAC__uint32 old_val, new_val; | |||
| asm volatile ("fxsave %0" : "=m" (fxsr) : "m" (fxsr)); | |||
| old_val = fxsr.buff[50]; | |||
| fxsr.buff[50] ^= 0x0013c0de; /* change value in the buffer */ | |||
| asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* try to change SSE register */ | |||
| fxsr.buff[50] = old_val; /* restore old value in the buffer */ | |||
| asm volatile ("fxsave %0 " : "=m" (fxsr) : "m" (fxsr)); /* old value will be overwritten if SSE register was changed */ | |||
| new_val = fxsr.buff[50]; /* == old_val if FXRSTOR didn't change SSE register and (old_val ^ 0x0013c0de) otherwise */ | |||
| fxsr.buff[50] = old_val; /* again restore old value in the buffer */ | |||
| asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* restore old values of registers */ | |||
| if ((old_val^new_val) == 0x0013c0de) | |||
| sse = 1; | |||
| } | |||
| if(!sse) | |||
| disable_sse(info); | |||
| #else | |||
| /* no way to test, disable to be safe */ | |||
| disable_sse(info); | |||
| #endif | |||
| #ifdef DEBUG | |||
| fprintf(stderr, " SSE OS sup . %c\n", info->ia32.sse ? 'Y' : 'n'); | |||
| #endif | |||
| } | |||
| else /* info->ia32.sse == false */ | |||
| disable_sse(info); | |||
| /* | |||
| * now have to check for OS support of AVX instructions | |||
| */ | |||
| if(info->ia32.avx && ia32_osxsave) { | |||
| FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86(); | |||
| if ((ecr & 0x6) != 0x6) | |||
| disable_avx(info); | |||
| #ifdef DEBUG | |||
| fprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n'); | |||
| #endif | |||
| } | |||
| else /* no OS AVX support*/ | |||
| disable_avx(info); | |||
| #else | |||
| info->use_asm = false; | |||
| #endif | |||
| /* | |||
| * x86-64-specific | |||
| */ | |||
| #elif defined FLAC__CPU_X86_64 | |||
| FLAC__bool x86_osxsave = false; | |||
| (void) x86_osxsave; /* to avoid warnings about unused variables */ | |||
| memset(info, 0, sizeof(*info)); | |||
| info->type = FLAC__CPUINFO_TYPE_X86_64; | |||
| #if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN | |||
| info->use_asm = true; | |||
| { | |||
| /* http://www.sandpile.org/x86/cpuid.htm */ | |||
| FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; | |||
| FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); | |||
| info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false; | |||
| info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false; | |||
| info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false; | |||
| info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false; | |||
| #if defined FLAC__AVX_SUPPORTED | |||
| x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false; | |||
| info->x86.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false; | |||
| info->x86.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false; | |||
| FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); | |||
| info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false; | |||
| #endif | |||
| } | |||
| #ifdef DEBUG | |||
| fprintf(stderr, "CPU info (x86-64):\n"); | |||
| fprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n'); | |||
| fprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n'); | |||
| fprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n'); | |||
| fprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n'); | |||
| # if defined FLAC__AVX_SUPPORTED | |||
| fprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n'); | |||
| fprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n'); | |||
| fprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n'); | |||
| # endif | |||
| #endif | |||
| /* | |||
| * now have to check for OS support of AVX instructions | |||
| */ | |||
| if(info->x86.avx && x86_osxsave) { | |||
| FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86(); | |||
| if ((ecr & 0x6) != 0x6) | |||
| disable_avx(info); | |||
| #ifdef DEBUG | |||
| fprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n'); | |||
| #endif | |||
| } | |||
| else /* no OS AVX support*/ | |||
| disable_avx(info); | |||
| #else | |||
| info->use_asm = false; | |||
| #endif | |||
| /* | |||
| * unknown CPU | |||
| */ | |||
| #else | |||
| info->type = FLAC__CPUINFO_TYPE_UNKNOWN; | |||
| info->use_asm = false; | |||
| #endif | |||
| } | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN | |||
| #if defined _MSC_VER | |||
| #include <intrin.h> /* for __cpuid() and _xgetbv() */ | |||
| #elif defined __GNUC__ && defined HAVE_CPUID_H | |||
| #include <cpuid.h> /* for __get_cpuid() and __get_cpuid_max() */ | |||
| #endif | |||
| FLAC__uint32 FLAC__cpu_have_cpuid_x86(void) | |||
| { | |||
| #ifdef FLAC__CPU_X86_64 | |||
| return 1; | |||
| #else | |||
| # if defined _MSC_VER || defined __INTEL_COMPILER /* Do they support CPUs w/o CPUID support (or OSes that work on those CPUs)? */ | |||
| FLAC__uint32 flags1, flags2; | |||
| __asm { | |||
| pushfd | |||
| pushfd | |||
| pop eax | |||
| mov flags1, eax | |||
| xor eax, 0x200000 | |||
| push eax | |||
| popfd | |||
| pushfd | |||
| pop eax | |||
| mov flags2, eax | |||
| popfd | |||
| } | |||
| if (((flags1^flags2) & 0x200000) != 0) | |||
| return 1; | |||
| else | |||
| return 0; | |||
| # elif defined __GNUC__ && defined HAVE_CPUID_H | |||
| if (__get_cpuid_max(0, 0) != 0) | |||
| return 1; | |||
| else | |||
| return 0; | |||
| # else | |||
| return 0; | |||
| # endif | |||
| #endif | |||
| } | |||
| void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx) | |||
| { | |||
| (void) level; | |||
| #if defined _MSC_VER || defined __INTEL_COMPILER | |||
| int cpuinfo[4]; | |||
| int ext = level & 0x80000000; | |||
| __cpuid(cpuinfo, ext); | |||
| if((unsigned)cpuinfo[0] < level) { | |||
| *eax = *ebx = *ecx = *edx = 0; | |||
| return; | |||
| } | |||
| #if defined FLAC__AVX_SUPPORTED | |||
| __cpuidex(cpuinfo, level, 0); /* for AVX2 detection */ | |||
| #else | |||
| __cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */ | |||
| #endif | |||
| *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3]; | |||
| #elif defined __GNUC__ && defined HAVE_CPUID_H | |||
| FLAC__uint32 ext = level & 0x80000000; | |||
| __cpuid(ext, *eax, *ebx, *ecx, *edx); | |||
| if (*eax < level) { | |||
| *eax = *ebx = *ecx = *edx = 0; | |||
| return; | |||
| } | |||
| __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx); | |||
| #else | |||
| *eax = *ebx = *ecx = *edx = 0; | |||
| #endif | |||
| } | |||
| FLAC__uint32 FLAC__cpu_xgetbv_x86(void) | |||
| { | |||
| #if (defined _MSC_VER || defined __INTEL_COMPILER) && defined FLAC__AVX_SUPPORTED | |||
| return (FLAC__uint32)_xgetbv(0); | |||
| #elif defined __GNUC__ | |||
| FLAC__uint32 lo, hi; | |||
| asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0)); | |||
| return lo; | |||
| #else | |||
| return 0; | |||
| #endif | |||
| } | |||
| #endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ | |||
| @@ -1,143 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "include/private/crc.h" | |||
| /* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */ | |||
| FLAC__byte const FLAC__crc8_table[256] = { | |||
| 0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, | |||
| 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D, | |||
| 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, | |||
| 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, | |||
| 0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, | |||
| 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, | |||
| 0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, | |||
| 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, | |||
| 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, | |||
| 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, | |||
| 0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, | |||
| 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, | |||
| 0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, | |||
| 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, | |||
| 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, | |||
| 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, | |||
| 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, | |||
| 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, | |||
| 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, | |||
| 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, | |||
| 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, | |||
| 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, | |||
| 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, | |||
| 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, | |||
| 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, | |||
| 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, | |||
| 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, | |||
| 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, | |||
| 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, | |||
| 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, | |||
| 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, | |||
| 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3 | |||
| }; | |||
| /* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */ | |||
| unsigned const FLAC__crc16_table[256] = { | |||
| 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, | |||
| 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, | |||
| 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, | |||
| 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, | |||
| 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, | |||
| 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, | |||
| 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, | |||
| 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, | |||
| 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, | |||
| 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, | |||
| 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, | |||
| 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, | |||
| 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, | |||
| 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, | |||
| 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, | |||
| 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, | |||
| 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, | |||
| 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, | |||
| 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, | |||
| 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, | |||
| 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, | |||
| 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, | |||
| 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, | |||
| 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, | |||
| 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, | |||
| 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, | |||
| 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, | |||
| 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, | |||
| 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, | |||
| 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, | |||
| 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, | |||
| 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 | |||
| }; | |||
| void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc) | |||
| { | |||
| *crc = FLAC__crc8_table[*crc ^ data]; | |||
| } | |||
| void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc) | |||
| { | |||
| while(len--) | |||
| *crc = FLAC__crc8_table[*crc ^ *data++]; | |||
| } | |||
| FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len) | |||
| { | |||
| FLAC__uint8 crc = 0; | |||
| while(len--) | |||
| crc = FLAC__crc8_table[crc ^ *data++]; | |||
| return crc; | |||
| } | |||
| unsigned FLAC__crc16(const FLAC__byte *data, unsigned len) | |||
| { | |||
| unsigned crc = 0; | |||
| while(len--) | |||
| crc = ((crc<<8) ^ FLAC__crc16_table[(crc>>8) ^ *data++]) & 0xffff; | |||
| return crc; | |||
| } | |||
| @@ -1,418 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <math.h> | |||
| #include <string.h> | |||
| #include "../compat.h" | |||
| #include "include/private/bitmath.h" | |||
| #include "include/private/fixed.h" | |||
| #include "../assert.h" | |||
| #ifdef local_abs | |||
| #undef local_abs | |||
| #endif | |||
| #define local_abs(x) ((unsigned)((x)<0? -(x) : (x))) | |||
| #ifdef FLAC__INTEGER_ONLY_LIBRARY | |||
| /* rbps stands for residual bits per sample | |||
| * | |||
| * (ln(2) * err) | |||
| * rbps = log (-----------) | |||
| * 2 ( n ) | |||
| */ | |||
| static FLAC__fixedpoint local__compute_rbps_integerized(FLAC__uint32 err, FLAC__uint32 n) | |||
| { | |||
| FLAC__uint32 rbps; | |||
| unsigned bits; /* the number of bits required to represent a number */ | |||
| int fracbits; /* the number of bits of rbps that comprise the fractional part */ | |||
| FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); | |||
| FLAC__ASSERT(err > 0); | |||
| FLAC__ASSERT(n > 0); | |||
| FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); | |||
| if(err <= n) | |||
| return 0; | |||
| /* | |||
| * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. | |||
| * These allow us later to know we won't lose too much precision in the | |||
| * fixed-point division (err<<fracbits)/n. | |||
| */ | |||
| fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2(err)+1); | |||
| err <<= fracbits; | |||
| err /= n; | |||
| /* err now holds err/n with fracbits fractional bits */ | |||
| /* | |||
| * Whittle err down to 16 bits max. 16 significant bits is enough for | |||
| * our purposes. | |||
| */ | |||
| FLAC__ASSERT(err > 0); | |||
| bits = FLAC__bitmath_ilog2(err)+1; | |||
| if(bits > 16) { | |||
| err >>= (bits-16); | |||
| fracbits -= (bits-16); | |||
| } | |||
| rbps = (FLAC__uint32)err; | |||
| /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ | |||
| rbps *= FLAC__FP_LN2; | |||
| fracbits += 16; | |||
| FLAC__ASSERT(fracbits >= 0); | |||
| /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ | |||
| { | |||
| const int f = fracbits & 3; | |||
| if(f) { | |||
| rbps >>= f; | |||
| fracbits -= f; | |||
| } | |||
| } | |||
| rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1)); | |||
| if(rbps == 0) | |||
| return 0; | |||
| /* | |||
| * The return value must have 16 fractional bits. Since the whole part | |||
| * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits | |||
| * must be >= -3, these assertion allows us to be able to shift rbps | |||
| * left if necessary to get 16 fracbits without losing any bits of the | |||
| * whole part of rbps. | |||
| * | |||
| * There is a slight chance due to accumulated error that the whole part | |||
| * will require 6 bits, so we use 6 in the assertion. Really though as | |||
| * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. | |||
| */ | |||
| FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); | |||
| FLAC__ASSERT(fracbits >= -3); | |||
| /* now shift the decimal point into place */ | |||
| if(fracbits < 16) | |||
| return rbps << (16-fracbits); | |||
| else if(fracbits > 16) | |||
| return rbps >> (fracbits-16); | |||
| else | |||
| return rbps; | |||
| } | |||
| static FLAC__fixedpoint local__compute_rbps_wide_integerized(FLAC__uint64 err, FLAC__uint32 n) | |||
| { | |||
| FLAC__uint32 rbps; | |||
| unsigned bits; /* the number of bits required to represent a number */ | |||
| int fracbits; /* the number of bits of rbps that comprise the fractional part */ | |||
| FLAC__ASSERT(sizeof(rbps) == sizeof(FLAC__fixedpoint)); | |||
| FLAC__ASSERT(err > 0); | |||
| FLAC__ASSERT(n > 0); | |||
| FLAC__ASSERT(n <= FLAC__MAX_BLOCK_SIZE); | |||
| if(err <= n) | |||
| return 0; | |||
| /* | |||
| * The above two things tell us 1) n fits in 16 bits; 2) err/n > 1. | |||
| * These allow us later to know we won't lose too much precision in the | |||
| * fixed-point division (err<<fracbits)/n. | |||
| */ | |||
| fracbits = (8*sizeof(err)) - (FLAC__bitmath_ilog2_wide(err)+1); | |||
| err <<= fracbits; | |||
| err /= n; | |||
| /* err now holds err/n with fracbits fractional bits */ | |||
| /* | |||
| * Whittle err down to 16 bits max. 16 significant bits is enough for | |||
| * our purposes. | |||
| */ | |||
| FLAC__ASSERT(err > 0); | |||
| bits = FLAC__bitmath_ilog2_wide(err)+1; | |||
| if(bits > 16) { | |||
| err >>= (bits-16); | |||
| fracbits -= (bits-16); | |||
| } | |||
| rbps = (FLAC__uint32)err; | |||
| /* Multiply by fixed-point version of ln(2), with 16 fractional bits */ | |||
| rbps *= FLAC__FP_LN2; | |||
| fracbits += 16; | |||
| FLAC__ASSERT(fracbits >= 0); | |||
| /* FLAC__fixedpoint_log2 requires fracbits%4 to be 0 */ | |||
| { | |||
| const int f = fracbits & 3; | |||
| if(f) { | |||
| rbps >>= f; | |||
| fracbits -= f; | |||
| } | |||
| } | |||
| rbps = FLAC__fixedpoint_log2(rbps, fracbits, (unsigned)(-1)); | |||
| if(rbps == 0) | |||
| return 0; | |||
| /* | |||
| * The return value must have 16 fractional bits. Since the whole part | |||
| * of the base-2 log of a 32 bit number must fit in 5 bits, and fracbits | |||
| * must be >= -3, these assertion allows us to be able to shift rbps | |||
| * left if necessary to get 16 fracbits without losing any bits of the | |||
| * whole part of rbps. | |||
| * | |||
| * There is a slight chance due to accumulated error that the whole part | |||
| * will require 6 bits, so we use 6 in the assertion. Really though as | |||
| * long as it fits in 13 bits (32 - (16 - (-3))) we are fine. | |||
| */ | |||
| FLAC__ASSERT((int)FLAC__bitmath_ilog2(rbps)+1 <= fracbits + 6); | |||
| FLAC__ASSERT(fracbits >= -3); | |||
| /* now shift the decimal point into place */ | |||
| if(fracbits < 16) | |||
| return rbps << (16-fracbits); | |||
| else if(fracbits > 16) | |||
| return rbps >> (fracbits-16); | |||
| else | |||
| return rbps; | |||
| } | |||
| #endif | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | |||
| #else | |||
| unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | |||
| #endif | |||
| { | |||
| FLAC__int32 last_error_0 = data[-1]; | |||
| FLAC__int32 last_error_1 = data[-1] - data[-2]; | |||
| FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); | |||
| FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); | |||
| FLAC__int32 error, save; | |||
| FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; | |||
| unsigned i, order; | |||
| for(i = 0; i < data_len; i++) { | |||
| error = data[i] ; total_error_0 += local_abs(error); save = error; | |||
| error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; | |||
| error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; | |||
| error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; | |||
| error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | |||
| } | |||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||
| order = 0; | |||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||
| order = 1; | |||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||
| order = 2; | |||
| else if(total_error_3 < total_error_4) | |||
| order = 3; | |||
| else | |||
| order = 4; | |||
| /* Estimate the expected number of bits per residual signal sample. */ | |||
| /* 'total_error*' is linearly related to the variance of the residual */ | |||
| /* signal, so we use it directly to compute E(|x|) */ | |||
| FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| #else | |||
| residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_integerized(total_error_0, data_len) : 0; | |||
| residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_integerized(total_error_1, data_len) : 0; | |||
| residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_integerized(total_error_2, data_len) : 0; | |||
| residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_integerized(total_error_3, data_len) : 0; | |||
| residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_integerized(total_error_4, data_len) : 0; | |||
| #endif | |||
| return order; | |||
| } | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | |||
| #else | |||
| unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]) | |||
| #endif | |||
| { | |||
| FLAC__int32 last_error_0 = data[-1]; | |||
| FLAC__int32 last_error_1 = data[-1] - data[-2]; | |||
| FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]); | |||
| FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]); | |||
| FLAC__int32 error, save; | |||
| /* total_error_* are 64-bits to avoid overflow when encoding | |||
| * erratic signals when the bits-per-sample and blocksize are | |||
| * large. | |||
| */ | |||
| FLAC__uint64 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0; | |||
| unsigned i, order; | |||
| for(i = 0; i < data_len; i++) { | |||
| error = data[i] ; total_error_0 += local_abs(error); save = error; | |||
| error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error; | |||
| error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error; | |||
| error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error; | |||
| error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save; | |||
| } | |||
| if(total_error_0 < flac_min(flac_min(flac_min(total_error_1, total_error_2), total_error_3), total_error_4)) | |||
| order = 0; | |||
| else if(total_error_1 < flac_min(flac_min(total_error_2, total_error_3), total_error_4)) | |||
| order = 1; | |||
| else if(total_error_2 < flac_min(total_error_3, total_error_4)) | |||
| order = 2; | |||
| else if(total_error_3 < total_error_4) | |||
| order = 3; | |||
| else | |||
| order = 4; | |||
| /* Estimate the expected number of bits per residual signal sample. */ | |||
| /* 'total_error*' is linearly related to the variance of the residual */ | |||
| /* signal, so we use it directly to compute E(|x|) */ | |||
| FLAC__ASSERT(data_len > 0 || total_error_0 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_1 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_2 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_3 == 0); | |||
| FLAC__ASSERT(data_len > 0 || total_error_4 == 0); | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); | |||
| #else | |||
| residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0; | |||
| residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0; | |||
| residual_bits_per_sample[2] = (total_error_2 > 0) ? local__compute_rbps_wide_integerized(total_error_2, data_len) : 0; | |||
| residual_bits_per_sample[3] = (total_error_3 > 0) ? local__compute_rbps_wide_integerized(total_error_3, data_len) : 0; | |||
| residual_bits_per_sample[4] = (total_error_4 > 0) ? local__compute_rbps_wide_integerized(total_error_4, data_len) : 0; | |||
| #endif | |||
| return order; | |||
| } | |||
| void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[]) | |||
| { | |||
| const int idata_len = (int)data_len; | |||
| int i; | |||
| switch(order) { | |||
| case 0: | |||
| FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); | |||
| memcpy(residual, data, sizeof(residual[0])*data_len); | |||
| break; | |||
| case 1: | |||
| for(i = 0; i < idata_len; i++) | |||
| residual[i] = data[i] - data[i-1]; | |||
| break; | |||
| case 2: | |||
| for(i = 0; i < idata_len; i++) | |||
| #if 1 /* OPT: may be faster with some compilers on some systems */ | |||
| residual[i] = data[i] - (data[i-1] << 1) + data[i-2]; | |||
| #else | |||
| residual[i] = data[i] - 2*data[i-1] + data[i-2]; | |||
| #endif | |||
| break; | |||
| case 3: | |||
| for(i = 0; i < idata_len; i++) | |||
| #if 1 /* OPT: may be faster with some compilers on some systems */ | |||
| residual[i] = data[i] - (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) - data[i-3]; | |||
| #else | |||
| residual[i] = data[i] - 3*data[i-1] + 3*data[i-2] - data[i-3]; | |||
| #endif | |||
| break; | |||
| case 4: | |||
| for(i = 0; i < idata_len; i++) | |||
| #if 1 /* OPT: may be faster with some compilers on some systems */ | |||
| residual[i] = data[i] - ((data[i-1]+data[i-3])<<2) + ((data[i-2]<<2) + (data[i-2]<<1)) + data[i-4]; | |||
| #else | |||
| residual[i] = data[i] - 4*data[i-1] + 6*data[i-2] - 4*data[i-3] + data[i-4]; | |||
| #endif | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| } | |||
| void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[]) | |||
| { | |||
| int i, idata_len = (int)data_len; | |||
| switch(order) { | |||
| case 0: | |||
| FLAC__ASSERT(sizeof(residual[0]) == sizeof(data[0])); | |||
| memcpy(data, residual, sizeof(residual[0])*data_len); | |||
| break; | |||
| case 1: | |||
| for(i = 0; i < idata_len; i++) | |||
| data[i] = residual[i] + data[i-1]; | |||
| break; | |||
| case 2: | |||
| for(i = 0; i < idata_len; i++) | |||
| #if 1 /* OPT: may be faster with some compilers on some systems */ | |||
| data[i] = residual[i] + (data[i-1]<<1) - data[i-2]; | |||
| #else | |||
| data[i] = residual[i] + 2*data[i-1] - data[i-2]; | |||
| #endif | |||
| break; | |||
| case 3: | |||
| for(i = 0; i < idata_len; i++) | |||
| #if 1 /* OPT: may be faster with some compilers on some systems */ | |||
| data[i] = residual[i] + (((data[i-1]-data[i-2])<<1) + (data[i-1]-data[i-2])) + data[i-3]; | |||
| #else | |||
| data[i] = residual[i] + 3*data[i-1] - 3*data[i-2] + data[i-3]; | |||
| #endif | |||
| break; | |||
| case 4: | |||
| for(i = 0; i < idata_len; i++) | |||
| #if 1 /* OPT: may be faster with some compilers on some systems */ | |||
| data[i] = residual[i] + ((data[i-1]+data[i-3])<<2) - ((data[i-2]<<2) + (data[i-2]<<1)) - data[i-4]; | |||
| #else | |||
| data[i] = residual[i] + 4*data[i-1] - 6*data[i-2] + 4*data[i-3] - data[i-4]; | |||
| #endif | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| } | |||
| @@ -1,302 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include "../assert.h" | |||
| #include "../compat.h" | |||
| #include "include/private/float.h" | |||
| #ifdef FLAC__INTEGER_ONLY_LIBRARY | |||
| const FLAC__fixedpoint FLAC__FP_ZERO = 0; | |||
| const FLAC__fixedpoint FLAC__FP_ONE_HALF = 0x00008000; | |||
| const FLAC__fixedpoint FLAC__FP_ONE = 0x00010000; | |||
| const FLAC__fixedpoint FLAC__FP_LN2 = 45426; | |||
| const FLAC__fixedpoint FLAC__FP_E = 178145; | |||
| /* Lookup tables for Knuth's logarithm algorithm */ | |||
| #define LOG2_LOOKUP_PRECISION 16 | |||
| static const FLAC__uint32 log2_lookup[][LOG2_LOOKUP_PRECISION] = { | |||
| { | |||
| /* | |||
| * 0 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00000001, | |||
| /* lg(4/3) = */ 0x00000000, | |||
| /* lg(8/7) = */ 0x00000000, | |||
| /* lg(16/15) = */ 0x00000000, | |||
| /* lg(32/31) = */ 0x00000000, | |||
| /* lg(64/63) = */ 0x00000000, | |||
| /* lg(128/127) = */ 0x00000000, | |||
| /* lg(256/255) = */ 0x00000000, | |||
| /* lg(512/511) = */ 0x00000000, | |||
| /* lg(1024/1023) = */ 0x00000000, | |||
| /* lg(2048/2047) = */ 0x00000000, | |||
| /* lg(4096/4095) = */ 0x00000000, | |||
| /* lg(8192/8191) = */ 0x00000000, | |||
| /* lg(16384/16383) = */ 0x00000000, | |||
| /* lg(32768/32767) = */ 0x00000000 | |||
| }, | |||
| { | |||
| /* | |||
| * 4 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00000010, | |||
| /* lg(4/3) = */ 0x00000007, | |||
| /* lg(8/7) = */ 0x00000003, | |||
| /* lg(16/15) = */ 0x00000001, | |||
| /* lg(32/31) = */ 0x00000001, | |||
| /* lg(64/63) = */ 0x00000000, | |||
| /* lg(128/127) = */ 0x00000000, | |||
| /* lg(256/255) = */ 0x00000000, | |||
| /* lg(512/511) = */ 0x00000000, | |||
| /* lg(1024/1023) = */ 0x00000000, | |||
| /* lg(2048/2047) = */ 0x00000000, | |||
| /* lg(4096/4095) = */ 0x00000000, | |||
| /* lg(8192/8191) = */ 0x00000000, | |||
| /* lg(16384/16383) = */ 0x00000000, | |||
| /* lg(32768/32767) = */ 0x00000000 | |||
| }, | |||
| { | |||
| /* | |||
| * 8 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00000100, | |||
| /* lg(4/3) = */ 0x0000006a, | |||
| /* lg(8/7) = */ 0x00000031, | |||
| /* lg(16/15) = */ 0x00000018, | |||
| /* lg(32/31) = */ 0x0000000c, | |||
| /* lg(64/63) = */ 0x00000006, | |||
| /* lg(128/127) = */ 0x00000003, | |||
| /* lg(256/255) = */ 0x00000001, | |||
| /* lg(512/511) = */ 0x00000001, | |||
| /* lg(1024/1023) = */ 0x00000000, | |||
| /* lg(2048/2047) = */ 0x00000000, | |||
| /* lg(4096/4095) = */ 0x00000000, | |||
| /* lg(8192/8191) = */ 0x00000000, | |||
| /* lg(16384/16383) = */ 0x00000000, | |||
| /* lg(32768/32767) = */ 0x00000000 | |||
| }, | |||
| { | |||
| /* | |||
| * 12 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00001000, | |||
| /* lg(4/3) = */ 0x000006a4, | |||
| /* lg(8/7) = */ 0x00000315, | |||
| /* lg(16/15) = */ 0x0000017d, | |||
| /* lg(32/31) = */ 0x000000bc, | |||
| /* lg(64/63) = */ 0x0000005d, | |||
| /* lg(128/127) = */ 0x0000002e, | |||
| /* lg(256/255) = */ 0x00000017, | |||
| /* lg(512/511) = */ 0x0000000c, | |||
| /* lg(1024/1023) = */ 0x00000006, | |||
| /* lg(2048/2047) = */ 0x00000003, | |||
| /* lg(4096/4095) = */ 0x00000001, | |||
| /* lg(8192/8191) = */ 0x00000001, | |||
| /* lg(16384/16383) = */ 0x00000000, | |||
| /* lg(32768/32767) = */ 0x00000000 | |||
| }, | |||
| { | |||
| /* | |||
| * 16 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00010000, | |||
| /* lg(4/3) = */ 0x00006a40, | |||
| /* lg(8/7) = */ 0x00003151, | |||
| /* lg(16/15) = */ 0x000017d6, | |||
| /* lg(32/31) = */ 0x00000bba, | |||
| /* lg(64/63) = */ 0x000005d1, | |||
| /* lg(128/127) = */ 0x000002e6, | |||
| /* lg(256/255) = */ 0x00000172, | |||
| /* lg(512/511) = */ 0x000000b9, | |||
| /* lg(1024/1023) = */ 0x0000005c, | |||
| /* lg(2048/2047) = */ 0x0000002e, | |||
| /* lg(4096/4095) = */ 0x00000017, | |||
| /* lg(8192/8191) = */ 0x0000000c, | |||
| /* lg(16384/16383) = */ 0x00000006, | |||
| /* lg(32768/32767) = */ 0x00000003 | |||
| }, | |||
| { | |||
| /* | |||
| * 20 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x00100000, | |||
| /* lg(4/3) = */ 0x0006a3fe, | |||
| /* lg(8/7) = */ 0x00031513, | |||
| /* lg(16/15) = */ 0x00017d60, | |||
| /* lg(32/31) = */ 0x0000bb9d, | |||
| /* lg(64/63) = */ 0x00005d10, | |||
| /* lg(128/127) = */ 0x00002e59, | |||
| /* lg(256/255) = */ 0x00001721, | |||
| /* lg(512/511) = */ 0x00000b8e, | |||
| /* lg(1024/1023) = */ 0x000005c6, | |||
| /* lg(2048/2047) = */ 0x000002e3, | |||
| /* lg(4096/4095) = */ 0x00000171, | |||
| /* lg(8192/8191) = */ 0x000000b9, | |||
| /* lg(16384/16383) = */ 0x0000005c, | |||
| /* lg(32768/32767) = */ 0x0000002e | |||
| }, | |||
| { | |||
| /* | |||
| * 24 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x01000000, | |||
| /* lg(4/3) = */ 0x006a3fe6, | |||
| /* lg(8/7) = */ 0x00315130, | |||
| /* lg(16/15) = */ 0x0017d605, | |||
| /* lg(32/31) = */ 0x000bb9ca, | |||
| /* lg(64/63) = */ 0x0005d0fc, | |||
| /* lg(128/127) = */ 0x0002e58f, | |||
| /* lg(256/255) = */ 0x0001720e, | |||
| /* lg(512/511) = */ 0x0000b8d8, | |||
| /* lg(1024/1023) = */ 0x00005c61, | |||
| /* lg(2048/2047) = */ 0x00002e2d, | |||
| /* lg(4096/4095) = */ 0x00001716, | |||
| /* lg(8192/8191) = */ 0x00000b8b, | |||
| /* lg(16384/16383) = */ 0x000005c5, | |||
| /* lg(32768/32767) = */ 0x000002e3 | |||
| }, | |||
| { | |||
| /* | |||
| * 28 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ 0x10000000, | |||
| /* lg(4/3) = */ 0x06a3fe5c, | |||
| /* lg(8/7) = */ 0x03151301, | |||
| /* lg(16/15) = */ 0x017d6049, | |||
| /* lg(32/31) = */ 0x00bb9ca6, | |||
| /* lg(64/63) = */ 0x005d0fba, | |||
| /* lg(128/127) = */ 0x002e58f7, | |||
| /* lg(256/255) = */ 0x001720da, | |||
| /* lg(512/511) = */ 0x000b8d87, | |||
| /* lg(1024/1023) = */ 0x0005c60b, | |||
| /* lg(2048/2047) = */ 0x0002e2d7, | |||
| /* lg(4096/4095) = */ 0x00017160, | |||
| /* lg(8192/8191) = */ 0x0000b8ad, | |||
| /* lg(16384/16383) = */ 0x00005c56, | |||
| /* lg(32768/32767) = */ 0x00002e2b | |||
| } | |||
| }; | |||
| #if 0 | |||
| static const FLAC__uint64 log2_lookup_wide[] = { | |||
| { | |||
| /* | |||
| * 32 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ FLAC__U64L(0x100000000), | |||
| /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c6), | |||
| /* lg(8/7) = */ FLAC__U64L(0x31513015), | |||
| /* lg(16/15) = */ FLAC__U64L(0x17d60497), | |||
| /* lg(32/31) = */ FLAC__U64L(0x0bb9ca65), | |||
| /* lg(64/63) = */ FLAC__U64L(0x05d0fba2), | |||
| /* lg(128/127) = */ FLAC__U64L(0x02e58f74), | |||
| /* lg(256/255) = */ FLAC__U64L(0x01720d9c), | |||
| /* lg(512/511) = */ FLAC__U64L(0x00b8d875), | |||
| /* lg(1024/1023) = */ FLAC__U64L(0x005c60aa), | |||
| /* lg(2048/2047) = */ FLAC__U64L(0x002e2d72), | |||
| /* lg(4096/4095) = */ FLAC__U64L(0x00171600), | |||
| /* lg(8192/8191) = */ FLAC__U64L(0x000b8ad2), | |||
| /* lg(16384/16383) = */ FLAC__U64L(0x0005c55d), | |||
| /* lg(32768/32767) = */ FLAC__U64L(0x0002e2ac) | |||
| }, | |||
| { | |||
| /* | |||
| * 48 fraction bits | |||
| */ | |||
| /* undefined */ 0x00000000, | |||
| /* lg(2/1) = */ FLAC__U64L(0x1000000000000), | |||
| /* lg(4/3) = */ FLAC__U64L(0x6a3fe5c60429), | |||
| /* lg(8/7) = */ FLAC__U64L(0x315130157f7a), | |||
| /* lg(16/15) = */ FLAC__U64L(0x17d60496cfbb), | |||
| /* lg(32/31) = */ FLAC__U64L(0xbb9ca64ecac), | |||
| /* lg(64/63) = */ FLAC__U64L(0x5d0fba187cd), | |||
| /* lg(128/127) = */ FLAC__U64L(0x2e58f7441ee), | |||
| /* lg(256/255) = */ FLAC__U64L(0x1720d9c06a8), | |||
| /* lg(512/511) = */ FLAC__U64L(0xb8d8752173), | |||
| /* lg(1024/1023) = */ FLAC__U64L(0x5c60aa252e), | |||
| /* lg(2048/2047) = */ FLAC__U64L(0x2e2d71b0d8), | |||
| /* lg(4096/4095) = */ FLAC__U64L(0x1716001719), | |||
| /* lg(8192/8191) = */ FLAC__U64L(0xb8ad1de1b), | |||
| /* lg(16384/16383) = */ FLAC__U64L(0x5c55d640d), | |||
| /* lg(32768/32767) = */ FLAC__U64L(0x2e2abcf52) | |||
| } | |||
| }; | |||
| #endif | |||
| FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision) | |||
| { | |||
| const FLAC__uint32 ONE = (1u << fracbits); | |||
| const FLAC__uint32 *table = log2_lookup[fracbits >> 2]; | |||
| FLAC__ASSERT(fracbits < 32); | |||
| FLAC__ASSERT((fracbits & 0x3) == 0); | |||
| if(x < ONE) | |||
| return 0; | |||
| if(precision > LOG2_LOOKUP_PRECISION) | |||
| precision = LOG2_LOOKUP_PRECISION; | |||
| /* Knuth's algorithm for computing logarithms, optimized for base-2 with lookup tables */ | |||
| { | |||
| FLAC__uint32 y = 0; | |||
| FLAC__uint32 z = x >> 1, k = 1; | |||
| while (x > ONE && k < precision) { | |||
| if (x - z >= ONE) { | |||
| x -= z; | |||
| z = x >> k; | |||
| y += table[k]; | |||
| } | |||
| else { | |||
| z >>= 1; | |||
| k++; | |||
| } | |||
| } | |||
| return y; | |||
| } | |||
| } | |||
| #endif /* defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| @@ -1,584 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <stdio.h> | |||
| #include <stdlib.h> /* for qsort() */ | |||
| #include <string.h> /* for memset() */ | |||
| #include "../assert.h" | |||
| #include "../format.h" | |||
| #include "../compat.h" | |||
| #include "include/private/format.h" | |||
| /* VERSION should come from configure */ | |||
| FLAC_API const char *FLAC__VERSION_STRING = VERSION; | |||
| FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20141125"; | |||
| FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; | |||
| FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143; | |||
| FLAC_API const unsigned FLAC__STREAM_SYNC_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN = 16; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN = 16; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN = 24; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN = 24; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN = 20; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN = 3; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN = 5; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN = 36; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN = 128; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN = 64; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN = 64; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN = 16; /* bits */ | |||
| FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER = FLAC__U64L(0xffffffffffffffff); | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN = 64; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN = 8; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN = 3*8; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN = 64; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN = 8; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN = 12*8; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN = 1; /* bit */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN = 1; /* bit */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN = 6+13*8; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN = 8; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN = 128*8; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN = 64; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN = 1; /* bit */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN = 7+258*8; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN = 8; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN = 32; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN = 1; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN = 7; /* bits */ | |||
| FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN = 24; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC = 0x3ffe; | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN = 14; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN = 1; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN = 1; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN = 4; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN = 4; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN = 4; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN = 3; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN = 1; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN = 8; /* bits */ | |||
| FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN = 16; /* bits */ | |||
| FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN = 2; /* bits */ | |||
| FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN = 4; /* bits */ | |||
| FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN = 4; /* bits */ | |||
| FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN = 5; /* bits */ | |||
| FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN = 5; /* bits */ | |||
| FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER = 15; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN)-1 */ | |||
| FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER = 31; /* == (1<<FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN)-1 */ | |||
| FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[] = { | |||
| "PARTITIONED_RICE", | |||
| "PARTITIONED_RICE2" | |||
| }; | |||
| FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN = 4; /* bits */ | |||
| FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN = 5; /* bits */ | |||
| FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN = 1; /* bits */ | |||
| FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN = 6; /* bits */ | |||
| FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN = 1; /* bits */ | |||
| FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK = 0x00; | |||
| FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK = 0x02; | |||
| FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK = 0x10; | |||
| FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK = 0x40; | |||
| FLAC_API const char * const FLAC__SubframeTypeString[] = { | |||
| "CONSTANT", | |||
| "VERBATIM", | |||
| "FIXED", | |||
| "LPC" | |||
| }; | |||
| FLAC_API const char * const FLAC__ChannelAssignmentString[] = { | |||
| "INDEPENDENT", | |||
| "LEFT_SIDE", | |||
| "RIGHT_SIDE", | |||
| "MID_SIDE" | |||
| }; | |||
| FLAC_API const char * const FLAC__FrameNumberTypeString[] = { | |||
| "FRAME_NUMBER_TYPE_FRAME_NUMBER", | |||
| "FRAME_NUMBER_TYPE_SAMPLE_NUMBER" | |||
| }; | |||
| FLAC_API const char * const FLAC__MetadataTypeString[] = { | |||
| "STREAMINFO", | |||
| "PADDING", | |||
| "APPLICATION", | |||
| "SEEKTABLE", | |||
| "VORBIS_COMMENT", | |||
| "CUESHEET", | |||
| "PICTURE" | |||
| }; | |||
| FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[] = { | |||
| "Other", | |||
| "32x32 pixels 'file icon' (PNG only)", | |||
| "Other file icon", | |||
| "Cover (front)", | |||
| "Cover (back)", | |||
| "Leaflet page", | |||
| "Media (e.g. label side of CD)", | |||
| "Lead artist/lead performer/soloist", | |||
| "Artist/performer", | |||
| "Conductor", | |||
| "Band/Orchestra", | |||
| "Composer", | |||
| "Lyricist/text writer", | |||
| "Recording Location", | |||
| "During recording", | |||
| "During performance", | |||
| "Movie/video screen capture", | |||
| "A bright coloured fish", | |||
| "Illustration", | |||
| "Band/artist logotype", | |||
| "Publisher/Studio logotype" | |||
| }; | |||
| FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate) | |||
| { | |||
| if(sample_rate == 0 || sample_rate > FLAC__MAX_SAMPLE_RATE) { | |||
| return false; | |||
| } | |||
| else | |||
| return true; | |||
| } | |||
| FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate) | |||
| { | |||
| if(blocksize > 16384) | |||
| return false; | |||
| else if(sample_rate <= 48000 && blocksize > 4608) | |||
| return false; | |||
| else | |||
| return true; | |||
| } | |||
| FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate) | |||
| { | |||
| if( | |||
| !FLAC__format_sample_rate_is_valid(sample_rate) || | |||
| ( | |||
| sample_rate >= (1u << 16) && | |||
| !(sample_rate % 1000 == 0 || sample_rate % 10 == 0) | |||
| ) | |||
| ) { | |||
| return false; | |||
| } | |||
| else | |||
| return true; | |||
| } | |||
| /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | |||
| FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table) | |||
| { | |||
| unsigned i; | |||
| FLAC__uint64 prev_sample_number = 0; | |||
| FLAC__bool got_prev = false; | |||
| FLAC__ASSERT(0 != seek_table); | |||
| for(i = 0; i < seek_table->num_points; i++) { | |||
| if(got_prev) { | |||
| if( | |||
| seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER && | |||
| seek_table->points[i].sample_number <= prev_sample_number | |||
| ) | |||
| return false; | |||
| } | |||
| prev_sample_number = seek_table->points[i].sample_number; | |||
| got_prev = true; | |||
| } | |||
| return true; | |||
| } | |||
| /* used as the sort predicate for qsort() */ | |||
| static int seekpoint_compare_(const FLAC__StreamMetadata_SeekPoint *l, const FLAC__StreamMetadata_SeekPoint *r) | |||
| { | |||
| /* we don't just 'return l->sample_number - r->sample_number' since the result (FLAC__int64) might overflow an 'int' */ | |||
| if(l->sample_number == r->sample_number) | |||
| return 0; | |||
| else if(l->sample_number < r->sample_number) | |||
| return -1; | |||
| else | |||
| return 1; | |||
| } | |||
| /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | |||
| FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table) | |||
| { | |||
| unsigned i, j; | |||
| FLAC__bool first; | |||
| FLAC__ASSERT(0 != seek_table); | |||
| /* sort the seekpoints */ | |||
| qsort(seek_table->points, seek_table->num_points, sizeof(FLAC__StreamMetadata_SeekPoint), (int (*)(const void *, const void *))seekpoint_compare_); | |||
| /* uniquify the seekpoints */ | |||
| first = true; | |||
| for(i = j = 0; i < seek_table->num_points; i++) { | |||
| if(seek_table->points[i].sample_number != FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER) { | |||
| if(!first) { | |||
| if(seek_table->points[i].sample_number == seek_table->points[j-1].sample_number) | |||
| continue; | |||
| } | |||
| } | |||
| first = false; | |||
| seek_table->points[j++] = seek_table->points[i]; | |||
| } | |||
| for(i = j; i < seek_table->num_points; i++) { | |||
| seek_table->points[i].sample_number = FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; | |||
| seek_table->points[i].stream_offset = 0; | |||
| seek_table->points[i].frame_samples = 0; | |||
| } | |||
| return j; | |||
| } | |||
| /* | |||
| * also disallows non-shortest-form encodings, c.f. | |||
| * http://www.unicode.org/versions/corrigendum1.html | |||
| * and a more clear explanation at the end of this section: | |||
| * http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 | |||
| */ | |||
| static unsigned utf8len_(const FLAC__byte *utf8) | |||
| { | |||
| FLAC__ASSERT(0 != utf8); | |||
| if ((utf8[0] & 0x80) == 0) { | |||
| return 1; | |||
| } | |||
| else if ((utf8[0] & 0xE0) == 0xC0 && (utf8[1] & 0xC0) == 0x80) { | |||
| if ((utf8[0] & 0xFE) == 0xC0) /* overlong sequence check */ | |||
| return 0; | |||
| return 2; | |||
| } | |||
| else if ((utf8[0] & 0xF0) == 0xE0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80) { | |||
| if (utf8[0] == 0xE0 && (utf8[1] & 0xE0) == 0x80) /* overlong sequence check */ | |||
| return 0; | |||
| /* illegal surrogates check (U+D800...U+DFFF and U+FFFE...U+FFFF) */ | |||
| if (utf8[0] == 0xED && (utf8[1] & 0xE0) == 0xA0) /* D800-DFFF */ | |||
| return 0; | |||
| if (utf8[0] == 0xEF && utf8[1] == 0xBF && (utf8[2] & 0xFE) == 0xBE) /* FFFE-FFFF */ | |||
| return 0; | |||
| return 3; | |||
| } | |||
| else if ((utf8[0] & 0xF8) == 0xF0 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80) { | |||
| if (utf8[0] == 0xF0 && (utf8[1] & 0xF0) == 0x80) /* overlong sequence check */ | |||
| return 0; | |||
| return 4; | |||
| } | |||
| else if ((utf8[0] & 0xFC) == 0xF8 && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80) { | |||
| if (utf8[0] == 0xF8 && (utf8[1] & 0xF8) == 0x80) /* overlong sequence check */ | |||
| return 0; | |||
| return 5; | |||
| } | |||
| else if ((utf8[0] & 0xFE) == 0xFC && (utf8[1] & 0xC0) == 0x80 && (utf8[2] & 0xC0) == 0x80 && (utf8[3] & 0xC0) == 0x80 && (utf8[4] & 0xC0) == 0x80 && (utf8[5] & 0xC0) == 0x80) { | |||
| if (utf8[0] == 0xFC && (utf8[1] & 0xFC) == 0x80) /* overlong sequence check */ | |||
| return 0; | |||
| return 6; | |||
| } | |||
| else { | |||
| return 0; | |||
| } | |||
| } | |||
| FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name) | |||
| { | |||
| char c; | |||
| for(c = *name; c; c = *(++name)) | |||
| if(c < 0x20 || c == 0x3d || c > 0x7d) | |||
| return false; | |||
| return true; | |||
| } | |||
| FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length) | |||
| { | |||
| if(length == (unsigned)(-1)) { | |||
| while(*value) { | |||
| unsigned n = utf8len_(value); | |||
| if(n == 0) | |||
| return false; | |||
| value += n; | |||
| } | |||
| } | |||
| else { | |||
| const FLAC__byte *end = value + length; | |||
| while(value < end) { | |||
| unsigned n = utf8len_(value); | |||
| if(n == 0) | |||
| return false; | |||
| value += n; | |||
| } | |||
| if(value != end) | |||
| return false; | |||
| } | |||
| return true; | |||
| } | |||
| FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length) | |||
| { | |||
| const FLAC__byte *s, *end; | |||
| for(s = entry, end = s + length; s < end && *s != '='; s++) { | |||
| if(*s < 0x20 || *s > 0x7D) | |||
| return false; | |||
| } | |||
| if(s == end) | |||
| return false; | |||
| s++; /* skip '=' */ | |||
| while(s < end) { | |||
| unsigned n = utf8len_(s); | |||
| if(n == 0) | |||
| return false; | |||
| s += n; | |||
| } | |||
| if(s != end) | |||
| return false; | |||
| return true; | |||
| } | |||
| /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | |||
| FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation) | |||
| { | |||
| unsigned i, j; | |||
| if(check_cd_da_subset) { | |||
| if(cue_sheet->lead_in < 2 * 44100) { | |||
| if(violation) *violation = "CD-DA cue sheet must have a lead-in length of at least 2 seconds"; | |||
| return false; | |||
| } | |||
| if(cue_sheet->lead_in % 588 != 0) { | |||
| if(violation) *violation = "CD-DA cue sheet lead-in length must be evenly divisible by 588 samples"; | |||
| return false; | |||
| } | |||
| } | |||
| if(cue_sheet->num_tracks == 0) { | |||
| if(violation) *violation = "cue sheet must have at least one track (the lead-out)"; | |||
| return false; | |||
| } | |||
| if(check_cd_da_subset && cue_sheet->tracks[cue_sheet->num_tracks-1].number != 170) { | |||
| if(violation) *violation = "CD-DA cue sheet must have a lead-out track number 170 (0xAA)"; | |||
| return false; | |||
| } | |||
| for(i = 0; i < cue_sheet->num_tracks; i++) { | |||
| if(cue_sheet->tracks[i].number == 0) { | |||
| if(violation) *violation = "cue sheet may not have a track number 0"; | |||
| return false; | |||
| } | |||
| if(check_cd_da_subset) { | |||
| if(!((cue_sheet->tracks[i].number >= 1 && cue_sheet->tracks[i].number <= 99) || cue_sheet->tracks[i].number == 170)) { | |||
| if(violation) *violation = "CD-DA cue sheet track number must be 1-99 or 170"; | |||
| return false; | |||
| } | |||
| } | |||
| if(check_cd_da_subset && cue_sheet->tracks[i].offset % 588 != 0) { | |||
| if(violation) { | |||
| if(i == cue_sheet->num_tracks-1) /* the lead-out track... */ | |||
| *violation = "CD-DA cue sheet lead-out offset must be evenly divisible by 588 samples"; | |||
| else | |||
| *violation = "CD-DA cue sheet track offset must be evenly divisible by 588 samples"; | |||
| } | |||
| return false; | |||
| } | |||
| if(i < cue_sheet->num_tracks - 1) { | |||
| if(cue_sheet->tracks[i].num_indices == 0) { | |||
| if(violation) *violation = "cue sheet track must have at least one index point"; | |||
| return false; | |||
| } | |||
| if(cue_sheet->tracks[i].indices[0].number > 1) { | |||
| if(violation) *violation = "cue sheet track's first index number must be 0 or 1"; | |||
| return false; | |||
| } | |||
| } | |||
| for(j = 0; j < cue_sheet->tracks[i].num_indices; j++) { | |||
| if(check_cd_da_subset && cue_sheet->tracks[i].indices[j].offset % 588 != 0) { | |||
| if(violation) *violation = "CD-DA cue sheet track index offset must be evenly divisible by 588 samples"; | |||
| return false; | |||
| } | |||
| if(j > 0) { | |||
| if(cue_sheet->tracks[i].indices[j].number != cue_sheet->tracks[i].indices[j-1].number + 1) { | |||
| if(violation) *violation = "cue sheet track index numbers must increase by 1"; | |||
| return false; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| /* @@@@ add to unit tests; it is already indirectly tested by the metadata_object tests */ | |||
| FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation) | |||
| { | |||
| char *p; | |||
| FLAC__byte *b; | |||
| for(p = picture->mime_type; *p; p++) { | |||
| if(*p < 0x20 || *p > 0x7e) { | |||
| if(violation) *violation = "MIME type string must contain only printable ASCII characters (0x20-0x7e)"; | |||
| return false; | |||
| } | |||
| } | |||
| for(b = picture->description; *b; ) { | |||
| unsigned n = utf8len_(b); | |||
| if(n == 0) { | |||
| if(violation) *violation = "description string must be valid UTF-8"; | |||
| return false; | |||
| } | |||
| b += n; | |||
| } | |||
| return true; | |||
| } | |||
| /* | |||
| * These routines are private to libFLAC | |||
| */ | |||
| unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order) | |||
| { | |||
| return | |||
| FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order( | |||
| FLAC__format_get_max_rice_partition_order_from_blocksize(blocksize), | |||
| blocksize, | |||
| predictor_order | |||
| ); | |||
| } | |||
| unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize) | |||
| { | |||
| unsigned max_rice_partition_order = 0; | |||
| while(!(blocksize & 1)) { | |||
| max_rice_partition_order++; | |||
| blocksize >>= 1; | |||
| } | |||
| return flac_min(FLAC__MAX_RICE_PARTITION_ORDER, max_rice_partition_order); | |||
| } | |||
| unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order) | |||
| { | |||
| unsigned max_rice_partition_order = limit; | |||
| while(max_rice_partition_order > 0 && (blocksize >> max_rice_partition_order) <= predictor_order) | |||
| max_rice_partition_order--; | |||
| FLAC__ASSERT( | |||
| (max_rice_partition_order == 0 && blocksize >= predictor_order) || | |||
| (max_rice_partition_order > 0 && blocksize >> max_rice_partition_order > predictor_order) | |||
| ); | |||
| return max_rice_partition_order; | |||
| } | |||
| void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) | |||
| { | |||
| FLAC__ASSERT(0 != object); | |||
| object->parameters = 0; | |||
| object->raw_bits = 0; | |||
| object->capacity_by_order = 0; | |||
| } | |||
| void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object) | |||
| { | |||
| FLAC__ASSERT(0 != object); | |||
| if(0 != object->parameters) | |||
| free(object->parameters); | |||
| if(0 != object->raw_bits) | |||
| free(object->raw_bits); | |||
| FLAC__format_entropy_coding_method_partitioned_rice_contents_init(object); | |||
| } | |||
| FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order) | |||
| { | |||
| FLAC__ASSERT(0 != object); | |||
| FLAC__ASSERT(object->capacity_by_order > 0 || (0 == object->parameters && 0 == object->raw_bits)); | |||
| if(object->capacity_by_order < max_partition_order) { | |||
| if(0 == (object->parameters = (unsigned int*) realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order)))) | |||
| return false; | |||
| if(0 == (object->raw_bits = (unsigned int*) realloc(object->raw_bits, sizeof(unsigned)*(1 << max_partition_order)))) | |||
| return false; | |||
| memset(object->raw_bits, 0, sizeof(unsigned)*(1 << max_partition_order)); | |||
| object->capacity_by_order = max_partition_order; | |||
| } | |||
| return true; | |||
| } | |||
| @@ -1,50 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__ALL_H | |||
| #define FLAC__PRIVATE__ALL_H | |||
| #include "bitmath.h" | |||
| #include "bitreader.h" | |||
| #include "bitwriter.h" | |||
| #include "cpu.h" | |||
| #include "crc.h" | |||
| #include "fixed.h" | |||
| #include "float.h" | |||
| #include "format.h" | |||
| #include "lpc.h" | |||
| #include "md5.h" | |||
| #include "memory.h" | |||
| #include "metadata.h" | |||
| #include "stream_encoder_framing.h" | |||
| #endif | |||
| @@ -1,186 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__BITMATH_H | |||
| #define FLAC__PRIVATE__BITMATH_H | |||
| #include "../../../ordinals.h" | |||
| #include "../../../assert.h" | |||
| /* for CHAR_BIT */ | |||
| #include <limits.h> | |||
| #include "../../../compat.h" | |||
| #if defined(_MSC_VER) && (_MSC_VER >= 1400) | |||
| #include <intrin.h> /* for _BitScanReverse* */ | |||
| #endif | |||
| /* Will never be emitted for MSVC, GCC, Intel compilers */ | |||
| static inline unsigned int FLAC__clz_soft_uint32(unsigned int word) | |||
| { | |||
| static const unsigned char byte_to_unary_table[] = { | |||
| 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, | |||
| 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | |||
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||
| 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| }; | |||
| return (word) > 0xffffff ? byte_to_unary_table[(word) >> 24] : | |||
| (word) > 0xffff ? byte_to_unary_table[(word) >> 16] + 8 : | |||
| (word) > 0xff ? byte_to_unary_table[(word) >> 8] + 16 : | |||
| byte_to_unary_table[(word)] + 24; | |||
| } | |||
| static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v) | |||
| { | |||
| /* Never used with input 0 */ | |||
| FLAC__ASSERT(v > 0); | |||
| #if defined(__INTEL_COMPILER) | |||
| return _bit_scan_reverse(v) ^ 31U; | |||
| #elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | |||
| /* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on | |||
| * -march= setting or to a software routine in exotic machines. */ | |||
| return __builtin_clz(v); | |||
| #elif defined(_MSC_VER) && (_MSC_VER >= 1400) | |||
| { | |||
| unsigned long idx; | |||
| _BitScanReverse(&idx, v); | |||
| return idx ^ 31U; | |||
| } | |||
| #else | |||
| return FLAC__clz_soft_uint32(v); | |||
| #endif | |||
| } | |||
| /* This one works with input 0 */ | |||
| static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v) | |||
| { | |||
| if (!v) | |||
| return 32; | |||
| return FLAC__clz_uint32(v); | |||
| } | |||
| /* An example of what FLAC__bitmath_ilog2() computes: | |||
| * | |||
| * ilog2( 0) = assertion failure | |||
| * ilog2( 1) = 0 | |||
| * ilog2( 2) = 1 | |||
| * ilog2( 3) = 1 | |||
| * ilog2( 4) = 2 | |||
| * ilog2( 5) = 2 | |||
| * ilog2( 6) = 2 | |||
| * ilog2( 7) = 2 | |||
| * ilog2( 8) = 3 | |||
| * ilog2( 9) = 3 | |||
| * ilog2(10) = 3 | |||
| * ilog2(11) = 3 | |||
| * ilog2(12) = 3 | |||
| * ilog2(13) = 3 | |||
| * ilog2(14) = 3 | |||
| * ilog2(15) = 3 | |||
| * ilog2(16) = 4 | |||
| * ilog2(17) = 4 | |||
| * ilog2(18) = 4 | |||
| */ | |||
| static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v) | |||
| { | |||
| FLAC__ASSERT(v > 0); | |||
| #if defined(__INTEL_COMPILER) | |||
| return _bit_scan_reverse(v); | |||
| #elif defined(_MSC_VER) && (_MSC_VER >= 1400) | |||
| { | |||
| unsigned long idx; | |||
| _BitScanReverse(&idx, v); | |||
| return idx; | |||
| } | |||
| #else | |||
| return sizeof(FLAC__uint32) * CHAR_BIT - 1 - FLAC__clz_uint32(v); | |||
| #endif | |||
| } | |||
| #ifdef FLAC__INTEGER_ONLY_LIBRARY /* Unused otherwise */ | |||
| static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v) | |||
| { | |||
| FLAC__ASSERT(v > 0); | |||
| #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) | |||
| return sizeof(FLAC__uint64) * CHAR_BIT - 1 - __builtin_clzll(v); | |||
| /* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */ | |||
| #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_M_X64)) | |||
| { | |||
| unsigned long idx; | |||
| _BitScanReverse64(&idx, v); | |||
| return idx; | |||
| } | |||
| #else | |||
| /* Brain-damaged compilers will use the fastest possible way that is, | |||
| de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf) | |||
| (C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 CC0 (Public domain). | |||
| */ | |||
| { | |||
| static const unsigned char DEBRUIJN_IDX64[64]={ | |||
| 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40, | |||
| 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, | |||
| 63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56, | |||
| 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 | |||
| }; | |||
| v|= v>>1; | |||
| v|= v>>2; | |||
| v|= v>>4; | |||
| v|= v>>8; | |||
| v|= v>>16; | |||
| v|= v>>32; | |||
| v= (v>>1)+1; | |||
| return DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F]; | |||
| } | |||
| #endif | |||
| } | |||
| #endif | |||
| unsigned FLAC__bitmath_silog2(int v); | |||
| unsigned FLAC__bitmath_silog2_wide(FLAC__int64 v); | |||
| #endif | |||
| @@ -1,91 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__BITREADER_H | |||
| #define FLAC__PRIVATE__BITREADER_H | |||
| #include <stdio.h> /* for FILE */ | |||
| #include "../../../ordinals.h" | |||
| #include "cpu.h" | |||
| /* | |||
| * opaque structure definition | |||
| */ | |||
| struct FLAC__BitReader; | |||
| typedef struct FLAC__BitReader FLAC__BitReader; | |||
| typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *bytes, void *client_data); | |||
| /* | |||
| * construction, deletion, initialization, etc functions | |||
| */ | |||
| FLAC__BitReader *FLAC__bitreader_new(void); | |||
| void FLAC__bitreader_delete(FLAC__BitReader *br); | |||
| FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd); | |||
| void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */ | |||
| FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br); | |||
| void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out); | |||
| /* | |||
| * CRC functions | |||
| */ | |||
| void FLAC__bitreader_reset_read_crc16(FLAC__BitReader *br, FLAC__uint16 seed); | |||
| FLAC__uint16 FLAC__bitreader_get_read_crc16(FLAC__BitReader *br); | |||
| /* | |||
| * info functions | |||
| */ | |||
| FLAC__bool FLAC__bitreader_is_consumed_byte_aligned(const FLAC__BitReader *br); | |||
| unsigned FLAC__bitreader_bits_left_for_byte_alignment(const FLAC__BitReader *br); | |||
| unsigned FLAC__bitreader_get_input_bits_unconsumed(const FLAC__BitReader *br); | |||
| /* | |||
| * read functions | |||
| */ | |||
| FLAC__bool FLAC__bitreader_read_raw_uint32(FLAC__BitReader *br, FLAC__uint32 *val, unsigned bits); | |||
| FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, unsigned bits); | |||
| FLAC__bool FLAC__bitreader_read_raw_uint64(FLAC__BitReader *br, FLAC__uint64 *val, unsigned bits); | |||
| FLAC__bool FLAC__bitreader_read_uint32_little_endian(FLAC__BitReader *br, FLAC__uint32 *val); /*only for bits=32*/ | |||
| FLAC__bool FLAC__bitreader_skip_bits_no_crc(FLAC__BitReader *br, unsigned bits); /* WATCHOUT: does not CRC the skipped data! */ /*@@@@ add to unit tests */ | |||
| FLAC__bool FLAC__bitreader_skip_byte_block_aligned_no_crc(FLAC__BitReader *br, unsigned nvals); /* WATCHOUT: does not CRC the read data! */ | |||
| FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, FLAC__byte *val, unsigned nvals); /* WATCHOUT: does not CRC the read data! */ | |||
| FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val); | |||
| FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter); | |||
| FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter); | |||
| #if 0 /* UNUSED */ | |||
| FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter); | |||
| FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter); | |||
| #endif | |||
| FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen); | |||
| FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen); | |||
| #endif | |||
| @@ -1,104 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__BITWRITER_H | |||
| #define FLAC__PRIVATE__BITWRITER_H | |||
| #include <stdio.h> /* for FILE */ | |||
| #include "../../../ordinals.h" | |||
| /* | |||
| * opaque structure definition | |||
| */ | |||
| struct FLAC__BitWriter; | |||
| typedef struct FLAC__BitWriter FLAC__BitWriter; | |||
| /* | |||
| * construction, deletion, initialization, etc functions | |||
| */ | |||
| FLAC__BitWriter *FLAC__bitwriter_new(void); | |||
| void FLAC__bitwriter_delete(FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__bitwriter_init(FLAC__BitWriter *bw); | |||
| void FLAC__bitwriter_free(FLAC__BitWriter *bw); /* does not 'free(buffer)' */ | |||
| void FLAC__bitwriter_clear(FLAC__BitWriter *bw); | |||
| void FLAC__bitwriter_dump(const FLAC__BitWriter *bw, FILE *out); | |||
| /* | |||
| * CRC functions | |||
| * | |||
| * non-const *bw because they have to cal FLAC__bitwriter_get_buffer() | |||
| */ | |||
| FLAC__bool FLAC__bitwriter_get_write_crc16(FLAC__BitWriter *bw, FLAC__uint16 *crc); | |||
| FLAC__bool FLAC__bitwriter_get_write_crc8(FLAC__BitWriter *bw, FLAC__byte *crc); | |||
| /* | |||
| * info functions | |||
| */ | |||
| FLAC__bool FLAC__bitwriter_is_byte_aligned(const FLAC__BitWriter *bw); | |||
| unsigned FLAC__bitwriter_get_input_bits_unconsumed(const FLAC__BitWriter *bw); /* can be called anytime, returns total # of bits unconsumed */ | |||
| /* | |||
| * direct buffer access | |||
| * | |||
| * there may be no calls on the bitwriter between get and release. | |||
| * the bitwriter continues to own the returned buffer. | |||
| * before get, bitwriter MUST be byte aligned: check with FLAC__bitwriter_is_byte_aligned() | |||
| */ | |||
| FLAC__bool FLAC__bitwriter_get_buffer(FLAC__BitWriter *bw, const FLAC__byte **buffer, size_t *bytes); | |||
| void FLAC__bitwriter_release_buffer(FLAC__BitWriter *bw); | |||
| /* | |||
| * write functions | |||
| */ | |||
| FLAC__bool FLAC__bitwriter_write_zeroes(FLAC__BitWriter *bw, unsigned bits); | |||
| FLAC__bool FLAC__bitwriter_write_raw_uint32(FLAC__BitWriter *bw, FLAC__uint32 val, unsigned bits); | |||
| FLAC__bool FLAC__bitwriter_write_raw_int32(FLAC__BitWriter *bw, FLAC__int32 val, unsigned bits); | |||
| FLAC__bool FLAC__bitwriter_write_raw_uint64(FLAC__BitWriter *bw, FLAC__uint64 val, unsigned bits); | |||
| FLAC__bool FLAC__bitwriter_write_raw_uint32_little_endian(FLAC__BitWriter *bw, FLAC__uint32 val); /*only for bits=32*/ | |||
| FLAC__bool FLAC__bitwriter_write_byte_block(FLAC__BitWriter *bw, const FLAC__byte vals[], unsigned nvals); | |||
| FLAC__bool FLAC__bitwriter_write_unary_unsigned(FLAC__BitWriter *bw, unsigned val); | |||
| unsigned FLAC__bitwriter_rice_bits(FLAC__int32 val, unsigned parameter); | |||
| #if 0 /* UNUSED */ | |||
| unsigned FLAC__bitwriter_golomb_bits_signed(int val, unsigned parameter); | |||
| unsigned FLAC__bitwriter_golomb_bits_unsigned(unsigned val, unsigned parameter); | |||
| #endif | |||
| FLAC__bool FLAC__bitwriter_write_rice_signed(FLAC__BitWriter *bw, FLAC__int32 val, unsigned parameter); | |||
| FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FLAC__int32 *vals, unsigned nvals, unsigned parameter); | |||
| #if 0 /* UNUSED */ | |||
| FLAC__bool FLAC__bitwriter_write_golomb_signed(FLAC__BitWriter *bw, int val, unsigned parameter); | |||
| FLAC__bool FLAC__bitwriter_write_golomb_unsigned(FLAC__BitWriter *bw, unsigned val, unsigned parameter); | |||
| #endif | |||
| FLAC__bool FLAC__bitwriter_write_utf8_uint32(FLAC__BitWriter *bw, FLAC__uint32 val); | |||
| FLAC__bool FLAC__bitwriter_write_utf8_uint64(FLAC__BitWriter *bw, FLAC__uint64 val); | |||
| FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw); | |||
| #endif | |||
| @@ -1,99 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__CPU_H | |||
| #define FLAC__PRIVATE__CPU_H | |||
| #include "../../../ordinals.h" | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| typedef enum { | |||
| FLAC__CPUINFO_TYPE_IA32, | |||
| FLAC__CPUINFO_TYPE_X86_64, | |||
| FLAC__CPUINFO_TYPE_UNKNOWN | |||
| } FLAC__CPUInfo_Type; | |||
| #if defined FLAC__CPU_IA32 | |||
| typedef struct { | |||
| FLAC__bool cmov; | |||
| FLAC__bool mmx; | |||
| FLAC__bool sse; | |||
| FLAC__bool sse2; | |||
| FLAC__bool sse3; | |||
| FLAC__bool ssse3; | |||
| FLAC__bool sse41; | |||
| FLAC__bool sse42; | |||
| FLAC__bool avx; | |||
| FLAC__bool avx2; | |||
| FLAC__bool fma; | |||
| } FLAC__CPUInfo_IA32; | |||
| #elif defined FLAC__CPU_X86_64 | |||
| typedef struct { | |||
| FLAC__bool sse3; | |||
| FLAC__bool ssse3; | |||
| FLAC__bool sse41; | |||
| FLAC__bool sse42; | |||
| FLAC__bool avx; | |||
| FLAC__bool avx2; | |||
| FLAC__bool fma; | |||
| } FLAC__CPUInfo_x86; | |||
| #endif | |||
| typedef struct { | |||
| FLAC__bool use_asm; | |||
| FLAC__CPUInfo_Type type; | |||
| #if defined FLAC__CPU_IA32 | |||
| FLAC__CPUInfo_IA32 ia32; | |||
| #elif defined FLAC__CPU_X86_64 | |||
| FLAC__CPUInfo_x86 x86; | |||
| #endif | |||
| } FLAC__CPUInfo; | |||
| void FLAC__cpu_info(FLAC__CPUInfo *info); | |||
| #ifndef FLAC__NO_ASM | |||
| # if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM | |||
| FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void); | |||
| void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx); | |||
| # endif | |||
| # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN | |||
| FLAC__uint32 FLAC__cpu_have_cpuid_x86(void); | |||
| void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx); | |||
| FLAC__uint32 FLAC__cpu_xgetbv_x86(void); | |||
| # endif | |||
| #endif | |||
| #endif | |||
| @@ -1,62 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__CRC_H | |||
| #define FLAC__PRIVATE__CRC_H | |||
| #include "../../../ordinals.h" | |||
| /* 8 bit CRC generator, MSB shifted first | |||
| ** polynomial = x^8 + x^2 + x^1 + x^0 | |||
| ** init = 0 | |||
| */ | |||
| extern FLAC__byte const FLAC__crc8_table[256]; | |||
| #define FLAC__CRC8_UPDATE(data, crc) (crc) = FLAC__crc8_table[(crc) ^ (data)]; | |||
| void FLAC__crc8_update(const FLAC__byte data, FLAC__uint8 *crc); | |||
| void FLAC__crc8_update_block(const FLAC__byte *data, unsigned len, FLAC__uint8 *crc); | |||
| FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len); | |||
| /* 16 bit CRC generator, MSB shifted first | |||
| ** polynomial = x^16 + x^15 + x^2 + x^0 | |||
| ** init = 0 | |||
| */ | |||
| extern unsigned const FLAC__crc16_table[256]; | |||
| #define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) | |||
| /* this alternate may be faster on some systems/compilers */ | |||
| #if 0 | |||
| #define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff) | |||
| #endif | |||
| unsigned FLAC__crc16(const FLAC__byte *data, unsigned len); | |||
| #endif | |||
| @@ -1,107 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__FIXED_H | |||
| #define FLAC__PRIVATE__FIXED_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include "cpu.h" | |||
| #include "float.h" | |||
| #include "../../../format.h" | |||
| /* | |||
| * FLAC__fixed_compute_best_predictor() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the best fixed predictor and the expected bits-per-sample | |||
| * of the residual signal for each order. The _wide() version uses | |||
| * 64-bit integers which is statistically necessary when bits-per- | |||
| * sample + log2(blocksize) > 30 | |||
| * | |||
| * IN data[0,data_len-1] | |||
| * IN data_len | |||
| * OUT residual_bits_per_sample[0,FLAC__MAX_FIXED_ORDER] | |||
| */ | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| # ifndef FLAC__NO_ASM | |||
| # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN | |||
| # ifdef FLAC__SSE2_SUPPORTED | |||
| unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); | |||
| unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); | |||
| # endif | |||
| # ifdef FLAC__SSSE3_SUPPORTED | |||
| unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); | |||
| # endif | |||
| # endif | |||
| # if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM | |||
| unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| # endif | |||
| # endif | |||
| #else | |||
| unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); | |||
| #endif | |||
| /* | |||
| * FLAC__fixed_compute_residual() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the residual signal obtained from sutracting the predicted | |||
| * signal from the original. | |||
| * | |||
| * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) | |||
| * IN data_len length of original signal | |||
| * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order | |||
| * OUT residual[0,data_len-1] residual signal | |||
| */ | |||
| void FLAC__fixed_compute_residual(const FLAC__int32 data[], unsigned data_len, unsigned order, FLAC__int32 residual[]); | |||
| /* | |||
| * FLAC__fixed_restore_signal() | |||
| * -------------------------------------------------------------------- | |||
| * Restore the original signal by summing the residual and the | |||
| * predictor. | |||
| * | |||
| * IN residual[0,data_len-1] residual signal | |||
| * IN data_len length of original signal | |||
| * IN order <= FLAC__MAX_FIXED_ORDER fixed-predictor order | |||
| * *** IMPORTANT: the caller must pass in the historical samples: | |||
| * IN data[-order,-1] previously-reconstructed historical samples | |||
| * OUT data[0,data_len-1] original signal | |||
| */ | |||
| void FLAC__fixed_restore_signal(const FLAC__int32 residual[], unsigned data_len, unsigned order, FLAC__int32 data[]); | |||
| #endif | |||
| @@ -1,98 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2004-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__FLOAT_H | |||
| #define FLAC__PRIVATE__FLOAT_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include "../../../ordinals.h" | |||
| /* | |||
| * These typedefs make it easier to ensure that integer versions of | |||
| * the library really only contain integer operations. All the code | |||
| * in libFLAC should use FLAC__float and FLAC__double in place of | |||
| * float and double, and be protected by checks of the macro | |||
| * FLAC__INTEGER_ONLY_LIBRARY. | |||
| * | |||
| * FLAC__real is the basic floating point type used in LPC analysis. | |||
| */ | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| typedef double FLAC__double; | |||
| typedef float FLAC__float; | |||
| /* | |||
| * WATCHOUT: changing FLAC__real will change the signatures of many | |||
| * functions that have assembly language equivalents and break them. | |||
| */ | |||
| typedef float FLAC__real; | |||
| #else | |||
| /* | |||
| * The convention for FLAC__fixedpoint is to use the upper 16 bits | |||
| * for the integer part and lower 16 bits for the fractional part. | |||
| */ | |||
| typedef FLAC__int32 FLAC__fixedpoint; | |||
| extern const FLAC__fixedpoint FLAC__FP_ZERO; | |||
| extern const FLAC__fixedpoint FLAC__FP_ONE_HALF; | |||
| extern const FLAC__fixedpoint FLAC__FP_ONE; | |||
| extern const FLAC__fixedpoint FLAC__FP_LN2; | |||
| extern const FLAC__fixedpoint FLAC__FP_E; | |||
| #define FLAC__fixedpoint_trunc(x) ((x)>>16) | |||
| #define FLAC__fixedpoint_mul(x, y) ( (FLAC__fixedpoint) ( ((FLAC__int64)(x)*(FLAC__int64)(y)) >> 16 ) ) | |||
| #define FLAC__fixedpoint_div(x, y) ( (FLAC__fixedpoint) ( ( ((FLAC__int64)(x)<<32) / (FLAC__int64)(y) ) >> 16 ) ) | |||
| /* | |||
| * FLAC__fixedpoint_log2() | |||
| * -------------------------------------------------------------------- | |||
| * Returns the base-2 logarithm of the fixed-point number 'x' using an | |||
| * algorithm by Knuth for x >= 1.0 | |||
| * | |||
| * 'fracbits' is the number of fractional bits of 'x'. 'fracbits' must | |||
| * be < 32 and evenly divisible by 4 (0 is OK but not very precise). | |||
| * | |||
| * 'precision' roughly limits the number of iterations that are done; | |||
| * use (unsigned)(-1) for maximum precision. | |||
| * | |||
| * If 'x' is less than one -- that is, x < (1<<fracbits) -- then this | |||
| * function will punt and return 0. | |||
| * | |||
| * The return value will also have 'fracbits' fractional bits. | |||
| */ | |||
| FLAC__uint32 FLAC__fixedpoint_log2(FLAC__uint32 x, unsigned fracbits, unsigned precision); | |||
| #endif | |||
| #endif | |||
| @@ -1,45 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__FORMAT_H | |||
| #define FLAC__PRIVATE__FORMAT_H | |||
| #include "../../../format.h" | |||
| unsigned FLAC__format_get_max_rice_partition_order(unsigned blocksize, unsigned predictor_order); | |||
| unsigned FLAC__format_get_max_rice_partition_order_from_blocksize(unsigned blocksize); | |||
| unsigned FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(unsigned limit, unsigned blocksize, unsigned predictor_order); | |||
| void FLAC__format_entropy_coding_method_partitioned_rice_contents_init(FLAC__EntropyCodingMethod_PartitionedRiceContents *object); | |||
| void FLAC__format_entropy_coding_method_partitioned_rice_contents_clear(FLAC__EntropyCodingMethod_PartitionedRiceContents *object); | |||
| FLAC__bool FLAC__format_entropy_coding_method_partitioned_rice_contents_ensure_size(FLAC__EntropyCodingMethod_PartitionedRiceContents *object, unsigned max_partition_order); | |||
| #endif | |||
| @@ -1,246 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__LPC_H | |||
| #define FLAC__PRIVATE__LPC_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include "cpu.h" | |||
| #include "float.h" | |||
| #include "../../../format.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| /* | |||
| * FLAC__lpc_window_data() | |||
| * -------------------------------------------------------------------- | |||
| * Applies the given window to the data. | |||
| * OPT: asm implementation | |||
| * | |||
| * IN in[0,data_len-1] | |||
| * IN window[0,data_len-1] | |||
| * OUT out[0,lag-1] | |||
| * IN data_len | |||
| */ | |||
| void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len); | |||
| /* | |||
| * FLAC__lpc_compute_autocorrelation() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the autocorrelation for lags between 0 and lag-1. | |||
| * Assumes data[] outside of [0,data_len-1] == 0. | |||
| * Asserts that lag > 0. | |||
| * | |||
| * IN data[0,data_len-1] | |||
| * IN data_len | |||
| * IN 0 < lag <= data_len | |||
| * OUT autoc[0,lag-1] | |||
| */ | |||
| void FLAC__lpc_compute_autocorrelation(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| #ifndef FLAC__NO_ASM | |||
| # ifdef FLAC__CPU_IA32 | |||
| # ifdef FLAC__HAS_NASM | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| # endif | |||
| # endif | |||
| # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN | |||
| # ifdef FLAC__SSE_SUPPORTED | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); | |||
| # endif | |||
| # endif | |||
| #endif | |||
| /* | |||
| * FLAC__lpc_compute_lp_coefficients() | |||
| * -------------------------------------------------------------------- | |||
| * Computes LP coefficients for orders 1..max_order. | |||
| * Do not call if autoc[0] == 0.0. This means the signal is zero | |||
| * and there is no point in calculating a predictor. | |||
| * | |||
| * IN autoc[0,max_order] autocorrelation values | |||
| * IN 0 < max_order <= FLAC__MAX_LPC_ORDER max LP order to compute | |||
| * OUT lp_coeff[0,max_order-1][0,max_order-1] LP coefficients for each order | |||
| * *** IMPORTANT: | |||
| * *** lp_coeff[0,max_order-1][max_order,FLAC__MAX_LPC_ORDER-1] are untouched | |||
| * OUT error[0,max_order-1] error for each order (more | |||
| * specifically, the variance of | |||
| * the error signal times # of | |||
| * samples in the signal) | |||
| * | |||
| * Example: if max_order is 9, the LP coefficients for order 9 will be | |||
| * in lp_coeff[8][0,8], the LP coefficients for order 8 will be | |||
| * in lp_coeff[7][0,7], etc. | |||
| */ | |||
| void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_order, FLAC__real lp_coeff[][FLAC__MAX_LPC_ORDER], FLAC__double error[]); | |||
| /* | |||
| * FLAC__lpc_quantize_coefficients() | |||
| * -------------------------------------------------------------------- | |||
| * Quantizes the LP coefficients. NOTE: precision + bits_per_sample | |||
| * must be less than 32 (sizeof(FLAC__int32)*8). | |||
| * | |||
| * IN lp_coeff[0,order-1] LP coefficients | |||
| * IN order LP order | |||
| * IN FLAC__MIN_QLP_COEFF_PRECISION < precision | |||
| * desired precision (in bits, including sign | |||
| * bit) of largest coefficient | |||
| * OUT qlp_coeff[0,order-1] quantized coefficients | |||
| * OUT shift # of bits to shift right to get approximated | |||
| * LP coefficients. NOTE: could be negative. | |||
| * RETURN 0 => quantization OK | |||
| * 1 => coefficients require too much shifting for *shift to | |||
| * fit in the LPC subframe header. 'shift' is unset. | |||
| * 2 => coefficients are all zero, which is bad. 'shift' is | |||
| * unset. | |||
| */ | |||
| int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, unsigned precision, FLAC__int32 qlp_coeff[], int *shift); | |||
| /* | |||
| * FLAC__lpc_compute_residual_from_qlp_coefficients() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the residual signal obtained from sutracting the predicted | |||
| * signal from the original. | |||
| * | |||
| * IN data[-order,data_len-1] original signal (NOTE THE INDICES!) | |||
| * IN data_len length of original signal | |||
| * IN qlp_coeff[0,order-1] quantized LP coefficients | |||
| * IN order > 0 LP order | |||
| * IN lp_quantization quantization of LP coefficients in bits | |||
| * OUT residual[0,data_len-1] residual signal | |||
| */ | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| #ifndef FLAC__NO_ASM | |||
| # ifdef FLAC__CPU_IA32 | |||
| # ifdef FLAC__HAS_NASM | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| # endif | |||
| # endif | |||
| # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN | |||
| # ifdef FLAC__SSE2_SUPPORTED | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| # endif | |||
| # ifdef FLAC__SSE4_1_SUPPORTED | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| # endif | |||
| # ifdef FLAC__AVX2_SUPPORTED | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); | |||
| # endif | |||
| # endif | |||
| #endif | |||
| #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| /* | |||
| * FLAC__lpc_restore_signal() | |||
| * -------------------------------------------------------------------- | |||
| * Restore the original signal by summing the residual and the | |||
| * predictor. | |||
| * | |||
| * IN residual[0,data_len-1] residual signal | |||
| * IN data_len length of original signal | |||
| * IN qlp_coeff[0,order-1] quantized LP coefficients | |||
| * IN order > 0 LP order | |||
| * IN lp_quantization quantization of LP coefficients in bits | |||
| * *** IMPORTANT: the caller must pass in the historical samples: | |||
| * IN data[-order,-1] previously-reconstructed historical samples | |||
| * OUT data[0,data_len-1] original signal | |||
| */ | |||
| void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | |||
| void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | |||
| #ifndef FLAC__NO_ASM | |||
| # ifdef FLAC__CPU_IA32 | |||
| # ifdef FLAC__HAS_NASM | |||
| void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | |||
| void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | |||
| void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | |||
| # endif /* FLAC__HAS_NASM */ | |||
| # endif /* FLAC__CPU_IA32 */ | |||
| # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN | |||
| # ifdef FLAC__SSE2_SUPPORTED | |||
| void FLAC__lpc_restore_signal_16_intrin_sse2(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | |||
| # endif | |||
| # ifdef FLAC__SSE4_1_SUPPORTED | |||
| void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); | |||
| # endif | |||
| # endif | |||
| #endif /* FLAC__NO_ASM */ | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| /* | |||
| * FLAC__lpc_compute_expected_bits_per_residual_sample() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the expected number of bits per residual signal sample | |||
| * based on the LP error (which is related to the residual variance). | |||
| * | |||
| * IN lpc_error >= 0.0 error returned from calculating LP coefficients | |||
| * IN total_samples > 0 # of samples in residual signal | |||
| * RETURN expected bits per sample | |||
| */ | |||
| FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples); | |||
| FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample_with_error_scale(FLAC__double lpc_error, FLAC__double error_scale); | |||
| /* | |||
| * FLAC__lpc_compute_best_order() | |||
| * -------------------------------------------------------------------- | |||
| * Compute the best order from the array of signal errors returned | |||
| * during coefficient computation. | |||
| * | |||
| * IN lpc_error[0,max_order-1] >= 0.0 error returned from calculating LP coefficients | |||
| * IN max_order > 0 max LP order | |||
| * IN total_samples > 0 # of samples in residual signal | |||
| * IN overhead_bits_per_order # of bits overhead for each increased LP order | |||
| * (includes warmup sample size and quantized LP coefficient) | |||
| * RETURN [1,max_order] best order | |||
| */ | |||
| unsigned FLAC__lpc_compute_best_order(const FLAC__double lpc_error[], unsigned max_order, unsigned total_samples, unsigned overhead_bits_per_order); | |||
| #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| #endif | |||
| @@ -1,50 +0,0 @@ | |||
| #ifndef FLAC__PRIVATE__MD5_H | |||
| #define FLAC__PRIVATE__MD5_H | |||
| /* | |||
| * This is the header file for the MD5 message-digest algorithm. | |||
| * The algorithm is due to Ron Rivest. This code was | |||
| * written by Colin Plumb in 1993, no copyright is claimed. | |||
| * This code is in the public domain; do with it what you wish. | |||
| * | |||
| * Equivalent code is available from RSA Data Security, Inc. | |||
| * This code has been tested against that, and is equivalent, | |||
| * except that you don't need to include two pages of legalese | |||
| * with every copy. | |||
| * | |||
| * To compute the message digest of a chunk of bytes, declare an | |||
| * MD5Context structure, pass it to MD5Init, call MD5Update as | |||
| * needed on buffers full of bytes, and then call MD5Final, which | |||
| * will fill a supplied 16-byte array with the digest. | |||
| * | |||
| * Changed so as no longer to depend on Colin Plumb's `usual.h' | |||
| * header definitions; now uses stuff from dpkg's config.h | |||
| * - Ian Jackson <ijackson@nyx.cs.du.edu>. | |||
| * Still in the public domain. | |||
| * | |||
| * Josh Coalson: made some changes to integrate with libFLAC. | |||
| * Still in the public domain, with no warranty. | |||
| */ | |||
| #include "../../../ordinals.h" | |||
| typedef union { | |||
| FLAC__byte *p8; | |||
| FLAC__int16 *p16; | |||
| FLAC__int32 *p32; | |||
| } FLAC__multibyte; | |||
| typedef struct { | |||
| FLAC__uint32 in[16]; | |||
| FLAC__uint32 buf[4]; | |||
| FLAC__uint32 bytes[2]; | |||
| FLAC__multibyte internal_buf; | |||
| size_t capacity; | |||
| } FLAC__MD5Context; | |||
| void FLAC__MD5Init(FLAC__MD5Context *context); | |||
| void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *context); | |||
| FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample); | |||
| #endif | |||
| @@ -1,58 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__MEMORY_H | |||
| #define FLAC__PRIVATE__MEMORY_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include <stdlib.h> /* for size_t */ | |||
| #include "float.h" | |||
| #include "../../../ordinals.h" /* for FLAC__bool */ | |||
| /* Returns the unaligned address returned by malloc. | |||
| * Use free() on this address to deallocate. | |||
| */ | |||
| void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address); | |||
| FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer); | |||
| FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer); | |||
| FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer); | |||
| FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer); | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer); | |||
| #endif | |||
| void *safe_malloc_mul_2op_p(size_t size1, size_t size2); | |||
| #endif | |||
| @@ -1,46 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2002-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__METADATA_H | |||
| #define FLAC__PRIVATE__METADATA_H | |||
| #include "../../../metadata.h" | |||
| /* WATCHOUT: all malloc()ed data in the block is free()ed; this may not | |||
| * be a consistent state (e.g. PICTURE) or equivalent to the initial | |||
| * state after FLAC__metadata_object_new() | |||
| */ | |||
| void FLAC__metadata_object_delete_data(FLAC__StreamMetadata *object); | |||
| void FLAC__metadata_object_cuesheet_track_delete_data(FLAC__StreamMetadata_CueSheet_Track *object); | |||
| #endif | |||
| @@ -1,67 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__STREAM_ENCODER_H | |||
| #define FLAC__PRIVATE__STREAM_ENCODER_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| /* | |||
| * This is used to avoid overflow with unusual signals in 32-bit | |||
| * accumulator in the *precompute_partition_info_sums_* functions. | |||
| */ | |||
| #define FLAC__MAX_EXTRA_RESIDUAL_BPS 4 | |||
| #if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN | |||
| #include "cpu.h" | |||
| #include "../../../format.h" | |||
| #ifdef FLAC__SSE2_SUPPORTED | |||
| extern void FLAC__precompute_partition_info_sums_intrin_sse2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], | |||
| unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps); | |||
| #endif | |||
| #ifdef FLAC__SSSE3_SUPPORTED | |||
| extern void FLAC__precompute_partition_info_sums_intrin_ssse3(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], | |||
| unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps); | |||
| #endif | |||
| #ifdef FLAC__AVX2_SUPPORTED | |||
| extern void FLAC__precompute_partition_info_sums_intrin_avx2(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], | |||
| unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps); | |||
| #endif | |||
| #endif | |||
| #endif | |||
| @@ -1,46 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H | |||
| #define FLAC__PRIVATE__STREAM_ENCODER_FRAMING_H | |||
| #include "../../../format.h" | |||
| #include "bitwriter.h" | |||
| FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw); | |||
| FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw); | |||
| #endif | |||
| @@ -1,74 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2006-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PRIVATE__WINDOW_H | |||
| #define FLAC__PRIVATE__WINDOW_H | |||
| #ifdef HAVE_CONFIG_H | |||
| #include <config.h> | |||
| #endif | |||
| #include "float.h" | |||
| #include "../../../format.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| /* | |||
| * FLAC__window_*() | |||
| * -------------------------------------------------------------------- | |||
| * Calculates window coefficients according to different apodization | |||
| * functions. | |||
| * | |||
| * OUT window[0,L-1] | |||
| * IN L (number of points in window) | |||
| */ | |||
| void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev); /* 0.0 < stddev <= 0.5 */ | |||
| void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L); | |||
| void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p); | |||
| void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end); | |||
| void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end); | |||
| void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L); | |||
| #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| #endif | |||
| @@ -1,39 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PROTECTED__ALL_H | |||
| #define FLAC__PROTECTED__ALL_H | |||
| #include "stream_decoder.h" | |||
| #include "stream_encoder.h" | |||
| #endif | |||
| @@ -1,60 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PROTECTED__STREAM_DECODER_H | |||
| #define FLAC__PROTECTED__STREAM_DECODER_H | |||
| #include "../../../stream_decoder.h" | |||
| #if FLAC__HAS_OGG | |||
| #include "../private/ogg_decoder_aspect.h" | |||
| #endif | |||
| typedef struct FLAC__StreamDecoderProtected { | |||
| FLAC__StreamDecoderState state; | |||
| FLAC__StreamDecoderInitStatus initstate; | |||
| unsigned channels; | |||
| FLAC__ChannelAssignment channel_assignment; | |||
| unsigned bits_per_sample; | |||
| unsigned sample_rate; /* in Hz */ | |||
| unsigned blocksize; /* in samples (per channel) */ | |||
| FLAC__bool md5_checking; /* if true, generate MD5 signature of decoded data and compare against signature in the STREAMINFO metadata block */ | |||
| #if FLAC__HAS_OGG | |||
| FLAC__OggDecoderAspect ogg_decoder_aspect; | |||
| #endif | |||
| } FLAC__StreamDecoderProtected; | |||
| /* | |||
| * return the number of input bytes consumed | |||
| */ | |||
| unsigned FLAC__stream_decoder_get_input_bytes_unconsumed(const FLAC__StreamDecoder *decoder); | |||
| #endif | |||
| @@ -1,118 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__PROTECTED__STREAM_ENCODER_H | |||
| #define FLAC__PROTECTED__STREAM_ENCODER_H | |||
| #include "../../../stream_encoder.h" | |||
| #if FLAC__HAS_OGG | |||
| #include "../private/ogg_encoder_aspect.h" | |||
| #endif | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| #include "../private/float.h" | |||
| #define FLAC__MAX_APODIZATION_FUNCTIONS 32 | |||
| typedef enum { | |||
| FLAC__APODIZATION_BARTLETT, | |||
| FLAC__APODIZATION_BARTLETT_HANN, | |||
| FLAC__APODIZATION_BLACKMAN, | |||
| FLAC__APODIZATION_BLACKMAN_HARRIS_4TERM_92DB_SIDELOBE, | |||
| FLAC__APODIZATION_CONNES, | |||
| FLAC__APODIZATION_FLATTOP, | |||
| FLAC__APODIZATION_GAUSS, | |||
| FLAC__APODIZATION_HAMMING, | |||
| FLAC__APODIZATION_HANN, | |||
| FLAC__APODIZATION_KAISER_BESSEL, | |||
| FLAC__APODIZATION_NUTTALL, | |||
| FLAC__APODIZATION_RECTANGLE, | |||
| FLAC__APODIZATION_TRIANGLE, | |||
| FLAC__APODIZATION_TUKEY, | |||
| FLAC__APODIZATION_PARTIAL_TUKEY, | |||
| FLAC__APODIZATION_PUNCHOUT_TUKEY, | |||
| FLAC__APODIZATION_WELCH | |||
| } FLAC__ApodizationFunction; | |||
| typedef struct { | |||
| FLAC__ApodizationFunction type; | |||
| union { | |||
| struct { | |||
| FLAC__real stddev; | |||
| } gauss; | |||
| struct { | |||
| FLAC__real p; | |||
| } tukey; | |||
| struct { | |||
| FLAC__real p; | |||
| FLAC__real start; | |||
| FLAC__real end; | |||
| } multiple_tukey; | |||
| } parameters; | |||
| } FLAC__ApodizationSpecification; | |||
| #endif // #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| typedef struct FLAC__StreamEncoderProtected { | |||
| FLAC__StreamEncoderState state; | |||
| FLAC__bool verify; | |||
| FLAC__bool streamable_subset; | |||
| FLAC__bool do_md5; | |||
| FLAC__bool do_mid_side_stereo; | |||
| FLAC__bool loose_mid_side_stereo; | |||
| unsigned channels; | |||
| unsigned bits_per_sample; | |||
| unsigned sample_rate; | |||
| unsigned blocksize; | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| unsigned num_apodizations; | |||
| FLAC__ApodizationSpecification apodizations[FLAC__MAX_APODIZATION_FUNCTIONS]; | |||
| #endif | |||
| unsigned max_lpc_order; | |||
| unsigned qlp_coeff_precision; | |||
| FLAC__bool do_qlp_coeff_prec_search; | |||
| FLAC__bool do_exhaustive_model_search; | |||
| FLAC__bool do_escape_coding; | |||
| unsigned min_residual_partition_order; | |||
| unsigned max_residual_partition_order; | |||
| unsigned rice_parameter_search_dist; | |||
| FLAC__uint64 total_samples_estimate; | |||
| FLAC__StreamMetadata **metadata; | |||
| unsigned num_metadata_blocks; | |||
| FLAC__uint64 streaminfo_offset, seektable_offset, audio_offset; | |||
| #if FLAC__HAS_OGG | |||
| FLAC__OggEncoderAspect ogg_encoder_aspect; | |||
| #endif | |||
| } FLAC__StreamEncoderProtected; | |||
| #endif | |||
| @@ -1,518 +0,0 @@ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <stdlib.h> /* for malloc() */ | |||
| #include <string.h> /* for memcpy() */ | |||
| #include "include/private/md5.h" | |||
| #include "../alloc.h" | |||
| #include "../endswap.h" | |||
| /* | |||
| * This code implements the MD5 message-digest algorithm. | |||
| * The algorithm is due to Ron Rivest. This code was | |||
| * written by Colin Plumb in 1993, no copyright is claimed. | |||
| * This code is in the public domain; do with it what you wish. | |||
| * | |||
| * Equivalent code is available from RSA Data Security, Inc. | |||
| * This code has been tested against that, and is equivalent, | |||
| * except that you don't need to include two pages of legalese | |||
| * with every copy. | |||
| * | |||
| * To compute the message digest of a chunk of bytes, declare an | |||
| * MD5Context structure, pass it to MD5Init, call MD5Update as | |||
| * needed on buffers full of bytes, and then call MD5Final, which | |||
| * will fill a supplied 16-byte array with the digest. | |||
| * | |||
| * Changed so as no longer to depend on Colin Plumb's `usual.h' header | |||
| * definitions; now uses stuff from dpkg's config.h. | |||
| * - Ian Jackson <ijackson@nyx.cs.du.edu>. | |||
| * Still in the public domain. | |||
| * | |||
| * Josh Coalson: made some changes to integrate with libFLAC. | |||
| * Still in the public domain. | |||
| */ | |||
| /* The four core functions - F1 is optimized somewhat */ | |||
| /* #define F1(x, y, z) (x & y | ~x & z) */ | |||
| #define F1(x, y, z) (z ^ (x & (y ^ z))) | |||
| #define F2(x, y, z) F1(z, x, y) | |||
| #define F3(x, y, z) (x ^ y ^ z) | |||
| #define F4(x, y, z) (y ^ (x | ~z)) | |||
| /* This is the central step in the MD5 algorithm. */ | |||
| #define MD5STEP(f,w,x,y,z,in,s) \ | |||
| (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x) | |||
| /* | |||
| * The core of the MD5 algorithm, this alters an existing MD5 hash to | |||
| * reflect the addition of 16 longwords of new data. MD5Update blocks | |||
| * the data and converts bytes into longwords for this routine. | |||
| */ | |||
| static void FLAC__MD5Transform(FLAC__uint32 buf[4], FLAC__uint32 const in[16]) | |||
| { | |||
| FLAC__uint32 a, b, c, d; | |||
| a = buf[0]; | |||
| b = buf[1]; | |||
| c = buf[2]; | |||
| d = buf[3]; | |||
| MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); | |||
| MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); | |||
| MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); | |||
| MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); | |||
| MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); | |||
| MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); | |||
| MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); | |||
| MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); | |||
| MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); | |||
| MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); | |||
| MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); | |||
| MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); | |||
| MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); | |||
| MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); | |||
| MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); | |||
| MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); | |||
| MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); | |||
| MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); | |||
| MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); | |||
| MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); | |||
| MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); | |||
| MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); | |||
| MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); | |||
| MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); | |||
| MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); | |||
| MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); | |||
| MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); | |||
| MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); | |||
| MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); | |||
| MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); | |||
| MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); | |||
| MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); | |||
| MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); | |||
| MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); | |||
| MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); | |||
| MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); | |||
| MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); | |||
| MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); | |||
| MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); | |||
| MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); | |||
| MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); | |||
| MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); | |||
| MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); | |||
| MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); | |||
| MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); | |||
| MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); | |||
| MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); | |||
| MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); | |||
| MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); | |||
| MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); | |||
| MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); | |||
| MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); | |||
| MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); | |||
| MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); | |||
| MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); | |||
| MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); | |||
| MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); | |||
| MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); | |||
| MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); | |||
| MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); | |||
| MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); | |||
| MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); | |||
| MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); | |||
| MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); | |||
| buf[0] += a; | |||
| buf[1] += b; | |||
| buf[2] += c; | |||
| buf[3] += d; | |||
| } | |||
| #if WORDS_BIGENDIAN | |||
| //@@@@@@ OPT: use bswap/intrinsics | |||
| static void byteSwap(FLAC__uint32 *buf, unsigned words) | |||
| { | |||
| register FLAC__uint32 x; | |||
| do { | |||
| x = *buf; | |||
| x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); | |||
| *buf++ = (x >> 16) | (x << 16); | |||
| } while (--words); | |||
| } | |||
| static void byteSwapX16(FLAC__uint32 *buf) | |||
| { | |||
| register FLAC__uint32 x; | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf++ = (x >> 16) | (x << 16); | |||
| x = *buf; x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff); *buf = (x >> 16) | (x << 16); | |||
| } | |||
| #else | |||
| #define byteSwap(buf, words) | |||
| #define byteSwapX16(buf) | |||
| #endif | |||
| /* | |||
| * Update context to reflect the concatenation of another buffer full | |||
| * of bytes. | |||
| */ | |||
| static void FLAC__MD5Update(FLAC__MD5Context *ctx, FLAC__byte const *buf, unsigned len) | |||
| { | |||
| FLAC__uint32 t; | |||
| /* Update byte count */ | |||
| t = ctx->bytes[0]; | |||
| if ((ctx->bytes[0] = t + len) < t) | |||
| ctx->bytes[1]++; /* Carry from low to high */ | |||
| t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */ | |||
| if (t > len) { | |||
| memcpy((FLAC__byte *)ctx->in + 64 - t, buf, len); | |||
| return; | |||
| } | |||
| /* First chunk is an odd size */ | |||
| memcpy((FLAC__byte *)ctx->in + 64 - t, buf, t); | |||
| byteSwapX16(ctx->in); | |||
| FLAC__MD5Transform(ctx->buf, ctx->in); | |||
| buf += t; | |||
| len -= t; | |||
| /* Process data in 64-byte chunks */ | |||
| while (len >= 64) { | |||
| memcpy(ctx->in, buf, 64); | |||
| byteSwapX16(ctx->in); | |||
| FLAC__MD5Transform(ctx->buf, ctx->in); | |||
| buf += 64; | |||
| len -= 64; | |||
| } | |||
| /* Handle any remaining bytes of data. */ | |||
| memcpy(ctx->in, buf, len); | |||
| } | |||
| /* | |||
| * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious | |||
| * initialization constants. | |||
| */ | |||
| void FLAC__MD5Init(FLAC__MD5Context *ctx) | |||
| { | |||
| ctx->buf[0] = 0x67452301; | |||
| ctx->buf[1] = 0xefcdab89; | |||
| ctx->buf[2] = 0x98badcfe; | |||
| ctx->buf[3] = 0x10325476; | |||
| ctx->bytes[0] = 0; | |||
| ctx->bytes[1] = 0; | |||
| ctx->internal_buf.p8= 0; | |||
| ctx->capacity = 0; | |||
| } | |||
| /* | |||
| * Final wrapup - pad to 64-byte boundary with the bit pattern | |||
| * 1 0* (64-bit count of bits processed, MSB-first) | |||
| */ | |||
| void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx) | |||
| { | |||
| int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ | |||
| FLAC__byte *p = (FLAC__byte *)ctx->in + count; | |||
| /* Set the first char of padding to 0x80. There is always room. */ | |||
| *p++ = 0x80; | |||
| /* Bytes of padding needed to make 56 bytes (-8..55) */ | |||
| count = 56 - 1 - count; | |||
| if (count < 0) { /* Padding forces an extra block */ | |||
| memset(p, 0, count + 8); | |||
| byteSwapX16(ctx->in); | |||
| FLAC__MD5Transform(ctx->buf, ctx->in); | |||
| p = (FLAC__byte *)ctx->in; | |||
| count = 56; | |||
| } | |||
| memset(p, 0, count); | |||
| byteSwap(ctx->in, 14); | |||
| /* Append length in bits and transform */ | |||
| ctx->in[14] = ctx->bytes[0] << 3; | |||
| ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; | |||
| FLAC__MD5Transform(ctx->buf, ctx->in); | |||
| byteSwap(ctx->buf, 4); | |||
| memcpy(digest, ctx->buf, 16); | |||
| if (0 != ctx->internal_buf.p8) { | |||
| free(ctx->internal_buf.p8); | |||
| ctx->internal_buf.p8= 0; | |||
| ctx->capacity = 0; | |||
| } | |||
| memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ | |||
| } | |||
| /* | |||
| * Convert the incoming audio signal to a byte stream | |||
| */ | |||
| static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) | |||
| { | |||
| FLAC__byte *buf_ = mbuf->p8; | |||
| FLAC__int16 *buf16 = mbuf->p16; | |||
| FLAC__int32 *buf32 = mbuf->p32; | |||
| FLAC__int32 a_word; | |||
| unsigned channel, sample; | |||
| /* Storage in the output buffer, buf, is little endian. */ | |||
| #define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels) | |||
| /* First do the most commonly used combinations. */ | |||
| switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) { | |||
| /* One byte per sample. */ | |||
| case (BYTES_CHANNEL_SELECTOR (1, 1)): | |||
| for (sample = 0; sample < samples; sample++) | |||
| *buf_++ = signal[0][sample]; | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (1, 2)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf_++ = signal[0][sample]; | |||
| *buf_++ = signal[1][sample]; | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (1, 4)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf_++ = signal[0][sample]; | |||
| *buf_++ = signal[1][sample]; | |||
| *buf_++ = signal[2][sample]; | |||
| *buf_++ = signal[3][sample]; | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (1, 6)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf_++ = signal[0][sample]; | |||
| *buf_++ = signal[1][sample]; | |||
| *buf_++ = signal[2][sample]; | |||
| *buf_++ = signal[3][sample]; | |||
| *buf_++ = signal[4][sample]; | |||
| *buf_++ = signal[5][sample]; | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (1, 8)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf_++ = signal[0][sample]; | |||
| *buf_++ = signal[1][sample]; | |||
| *buf_++ = signal[2][sample]; | |||
| *buf_++ = signal[3][sample]; | |||
| *buf_++ = signal[4][sample]; | |||
| *buf_++ = signal[5][sample]; | |||
| *buf_++ = signal[6][sample]; | |||
| *buf_++ = signal[7][sample]; | |||
| } | |||
| return; | |||
| /* Two bytes per sample. */ | |||
| case (BYTES_CHANNEL_SELECTOR (2, 1)): | |||
| for (sample = 0; sample < samples; sample++) | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (2, 2)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| *buf16++ = H2LE_16(signal[1][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (2, 4)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| *buf16++ = H2LE_16(signal[1][sample]); | |||
| *buf16++ = H2LE_16(signal[2][sample]); | |||
| *buf16++ = H2LE_16(signal[3][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (2, 6)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| *buf16++ = H2LE_16(signal[1][sample]); | |||
| *buf16++ = H2LE_16(signal[2][sample]); | |||
| *buf16++ = H2LE_16(signal[3][sample]); | |||
| *buf16++ = H2LE_16(signal[4][sample]); | |||
| *buf16++ = H2LE_16(signal[5][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (2, 8)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf16++ = H2LE_16(signal[0][sample]); | |||
| *buf16++ = H2LE_16(signal[1][sample]); | |||
| *buf16++ = H2LE_16(signal[2][sample]); | |||
| *buf16++ = H2LE_16(signal[3][sample]); | |||
| *buf16++ = H2LE_16(signal[4][sample]); | |||
| *buf16++ = H2LE_16(signal[5][sample]); | |||
| *buf16++ = H2LE_16(signal[6][sample]); | |||
| *buf16++ = H2LE_16(signal[7][sample]); | |||
| } | |||
| return; | |||
| /* Three bytes per sample. */ | |||
| case (BYTES_CHANNEL_SELECTOR (3, 1)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| a_word = signal[0][sample]; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (3, 2)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| a_word = signal[0][sample]; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; | |||
| a_word = signal[1][sample]; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; | |||
| } | |||
| return; | |||
| /* Four bytes per sample. */ | |||
| case (BYTES_CHANNEL_SELECTOR (4, 1)): | |||
| for (sample = 0; sample < samples; sample++) | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (4, 2)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| *buf32++ = H2LE_32(signal[1][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (4, 4)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| *buf32++ = H2LE_32(signal[1][sample]); | |||
| *buf32++ = H2LE_32(signal[2][sample]); | |||
| *buf32++ = H2LE_32(signal[3][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (4, 6)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| *buf32++ = H2LE_32(signal[1][sample]); | |||
| *buf32++ = H2LE_32(signal[2][sample]); | |||
| *buf32++ = H2LE_32(signal[3][sample]); | |||
| *buf32++ = H2LE_32(signal[4][sample]); | |||
| *buf32++ = H2LE_32(signal[5][sample]); | |||
| } | |||
| return; | |||
| case (BYTES_CHANNEL_SELECTOR (4, 8)): | |||
| for (sample = 0; sample < samples; sample++) { | |||
| *buf32++ = H2LE_32(signal[0][sample]); | |||
| *buf32++ = H2LE_32(signal[1][sample]); | |||
| *buf32++ = H2LE_32(signal[2][sample]); | |||
| *buf32++ = H2LE_32(signal[3][sample]); | |||
| *buf32++ = H2LE_32(signal[4][sample]); | |||
| *buf32++ = H2LE_32(signal[5][sample]); | |||
| *buf32++ = H2LE_32(signal[6][sample]); | |||
| *buf32++ = H2LE_32(signal[7][sample]); | |||
| } | |||
| return; | |||
| default: | |||
| break; | |||
| } | |||
| /* General version. */ | |||
| switch (bytes_per_sample) { | |||
| case 1: | |||
| for (sample = 0; sample < samples; sample++) | |||
| for (channel = 0; channel < channels; channel++) | |||
| *buf_++ = signal[channel][sample]; | |||
| return; | |||
| case 2: | |||
| for (sample = 0; sample < samples; sample++) | |||
| for (channel = 0; channel < channels; channel++) | |||
| *buf16++ = H2LE_16(signal[channel][sample]); | |||
| return; | |||
| case 3: | |||
| for (sample = 0; sample < samples; sample++) | |||
| for (channel = 0; channel < channels; channel++) { | |||
| a_word = signal[channel][sample]; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; a_word >>= 8; | |||
| *buf_++ = (FLAC__byte)a_word; | |||
| } | |||
| return; | |||
| case 4: | |||
| for (sample = 0; sample < samples; sample++) | |||
| for (channel = 0; channel < channels; channel++) | |||
| *buf32++ = H2LE_32(signal[channel][sample]); | |||
| return; | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| /* | |||
| * Convert the incoming audio signal to a byte stream and FLAC__MD5Update it. | |||
| */ | |||
| FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) | |||
| { | |||
| const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample; | |||
| /* overflow check */ | |||
| if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample) | |||
| return false; | |||
| if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples) | |||
| return false; | |||
| if (ctx->capacity < bytes_needed) { | |||
| FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf.p8, bytes_needed); | |||
| if (0 == tmp) { | |||
| free(ctx->internal_buf.p8); | |||
| if (0 == (ctx->internal_buf.p8= (FLAC__byte*) safe_malloc_(bytes_needed))) | |||
| return false; | |||
| } | |||
| else | |||
| ctx->internal_buf.p8= tmp; | |||
| ctx->capacity = bytes_needed; | |||
| } | |||
| format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample); | |||
| FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed); | |||
| return true; | |||
| } | |||
| @@ -1,218 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2001-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #ifdef HAVE_STDINT_H | |||
| #include <stdint.h> | |||
| #endif | |||
| #include "include/private/memory.h" | |||
| #include "../assert.h" | |||
| #include "../alloc.h" | |||
| void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) | |||
| { | |||
| void *x; | |||
| FLAC__ASSERT(0 != aligned_address); | |||
| #ifdef FLAC__ALIGN_MALLOC_DATA | |||
| /* align on 32-byte (256-bit) boundary */ | |||
| x = safe_malloc_add_2op_(bytes, /*+*/31L); | |||
| *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L); | |||
| #else | |||
| x = safe_malloc_(bytes); | |||
| *aligned_address = x; | |||
| #endif | |||
| return x; | |||
| } | |||
| FLAC__bool FLAC__memory_alloc_aligned_int32_array(size_t elements, FLAC__int32 **unaligned_pointer, FLAC__int32 **aligned_pointer) | |||
| { | |||
| FLAC__int32 *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| FLAC__int32 *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = (FLAC__int32*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| FLAC__bool FLAC__memory_alloc_aligned_uint32_array(size_t elements, FLAC__uint32 **unaligned_pointer, FLAC__uint32 **aligned_pointer) | |||
| { | |||
| FLAC__uint32 *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| FLAC__uint32 *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = (FLAC__uint32*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| FLAC__bool FLAC__memory_alloc_aligned_uint64_array(size_t elements, FLAC__uint64 **unaligned_pointer, FLAC__uint64 **aligned_pointer) | |||
| { | |||
| FLAC__uint64 *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| FLAC__uint64 *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = (FLAC__uint64*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| FLAC__bool FLAC__memory_alloc_aligned_unsigned_array(size_t elements, unsigned **unaligned_pointer, unsigned **aligned_pointer) | |||
| { | |||
| unsigned *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| unsigned *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = (unsigned int*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| FLAC__bool FLAC__memory_alloc_aligned_real_array(size_t elements, FLAC__real **unaligned_pointer, FLAC__real **aligned_pointer) | |||
| { | |||
| FLAC__real *pu; /* unaligned pointer */ | |||
| union { /* union needed to comply with C99 pointer aliasing rules */ | |||
| FLAC__real *pa; /* aligned pointer */ | |||
| void *pv; /* aligned pointer alias */ | |||
| } u; | |||
| FLAC__ASSERT(elements > 0); | |||
| FLAC__ASSERT(0 != unaligned_pointer); | |||
| FLAC__ASSERT(0 != aligned_pointer); | |||
| FLAC__ASSERT(unaligned_pointer != aligned_pointer); | |||
| if(elements > SIZE_MAX / sizeof(*pu)) /* overflow check */ | |||
| return false; | |||
| pu = (FLAC__real*) FLAC__memory_alloc_aligned(sizeof(*pu) * elements, &u.pv); | |||
| if(0 == pu) { | |||
| return false; | |||
| } | |||
| else { | |||
| if(*unaligned_pointer != 0) | |||
| free(*unaligned_pointer); | |||
| *unaligned_pointer = pu; | |||
| *aligned_pointer = u.pa; | |||
| return true; | |||
| } | |||
| } | |||
| #endif | |||
| void *safe_malloc_mul_2op_p(size_t size1, size_t size2) | |||
| { | |||
| if(!size1 || !size2) | |||
| return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ | |||
| if(size1 > SIZE_MAX / size2) | |||
| return 0; | |||
| return malloc(size1*size2); | |||
| } | |||
| @@ -1,549 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <stdio.h> | |||
| #include <string.h> /* for strlen() */ | |||
| #include "include/private/stream_encoder_framing.h" | |||
| #include "include/private/crc.h" | |||
| #include "../assert.h" | |||
| static FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method); | |||
| static FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended); | |||
| FLAC__bool FLAC__add_metadata_block(const FLAC__StreamMetadata *metadata, FLAC__BitWriter *bw) | |||
| { | |||
| unsigned i, j; | |||
| const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->is_last, FLAC__STREAM_METADATA_IS_LAST_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->type, FLAC__STREAM_METADATA_TYPE_LEN)) | |||
| return false; | |||
| /* | |||
| * First, for VORBIS_COMMENTs, adjust the length to reflect our vendor string | |||
| */ | |||
| i = metadata->length; | |||
| if(metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) { | |||
| FLAC__ASSERT(metadata->data.vorbis_comment.vendor_string.length == 0 || 0 != metadata->data.vorbis_comment.vendor_string.entry); | |||
| i -= metadata->data.vorbis_comment.vendor_string.length; | |||
| i += vendor_string_length; | |||
| } | |||
| FLAC__ASSERT(i < (1u << FLAC__STREAM_METADATA_LENGTH_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, i, FLAC__STREAM_METADATA_LENGTH_LEN)) | |||
| return false; | |||
| switch(metadata->type) { | |||
| case FLAC__METADATA_TYPE_STREAMINFO: | |||
| FLAC__ASSERT(metadata->data.stream_info.min_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.max_blocksize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_blocksize, FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.min_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.min_framesize, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.max_framesize < (1u << FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.max_framesize, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(FLAC__format_sample_rate_is_valid(metadata->data.stream_info.sample_rate)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.sample_rate, FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.channels > 0); | |||
| FLAC__ASSERT(metadata->data.stream_info.channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.channels-1, FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(metadata->data.stream_info.bits_per_sample > 0); | |||
| FLAC__ASSERT(metadata->data.stream_info.bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.stream_info.bits_per_sample-1, FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.stream_info.total_samples, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.stream_info.md5sum, 16)) | |||
| return false; | |||
| break; | |||
| case FLAC__METADATA_TYPE_PADDING: | |||
| if(!FLAC__bitwriter_write_zeroes(bw, metadata->length * 8)) | |||
| return false; | |||
| break; | |||
| case FLAC__METADATA_TYPE_APPLICATION: | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.id, FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.application.data, metadata->length - (FLAC__STREAM_METADATA_APPLICATION_ID_LEN / 8))) | |||
| return false; | |||
| break; | |||
| case FLAC__METADATA_TYPE_SEEKTABLE: | |||
| for(i = 0; i < metadata->data.seek_table.num_points; i++) { | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].sample_number, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.seek_table.points[i].stream_offset, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.seek_table.points[i].frame_samples, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN)) | |||
| return false; | |||
| } | |||
| break; | |||
| case FLAC__METADATA_TYPE_VORBIS_COMMENT: | |||
| if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, vendor_string_length)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)FLAC__VENDOR_STRING, vendor_string_length)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.num_comments)) | |||
| return false; | |||
| for(i = 0; i < metadata->data.vorbis_comment.num_comments; i++) { | |||
| if(!FLAC__bitwriter_write_raw_uint32_little_endian(bw, metadata->data.vorbis_comment.comments[i].length)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.vorbis_comment.comments[i].entry, metadata->data.vorbis_comment.comments[i].length)) | |||
| return false; | |||
| } | |||
| break; | |||
| case FLAC__METADATA_TYPE_CUESHEET: | |||
| FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN % 8 == 0); | |||
| if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.cue_sheet.media_catalog_number, FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN/8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, metadata->data.cue_sheet.lead_in, FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.is_cd? 1 : 0, FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.cue_sheet.num_tracks, FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN)) | |||
| return false; | |||
| for(i = 0; i < metadata->data.cue_sheet.num_tracks; i++) { | |||
| const FLAC__StreamMetadata_CueSheet_Track *track = metadata->data.cue_sheet.tracks + i; | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, track->offset, FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, track->number, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN % 8 == 0); | |||
| if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)track->isrc, FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN/8)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, track->type, FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, track->pre_emphasis, FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, track->num_indices, FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN)) | |||
| return false; | |||
| for(j = 0; j < track->num_indices; j++) { | |||
| const FLAC__StreamMetadata_CueSheet_Index *indx = track->indices + j; | |||
| if(!FLAC__bitwriter_write_raw_uint64(bw, indx->offset, FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, indx->number, FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_zeroes(bw, FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN)) | |||
| return false; | |||
| } | |||
| } | |||
| break; | |||
| case FLAC__METADATA_TYPE_PICTURE: | |||
| { | |||
| size_t len; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.type, FLAC__STREAM_METADATA_PICTURE_TYPE_LEN)) | |||
| return false; | |||
| len = strlen(metadata->data.picture.mime_type); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, (const FLAC__byte*)metadata->data.picture.mime_type, len)) | |||
| return false; | |||
| len = strlen((const char *)metadata->data.picture.description); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, len, FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.description, len)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.width, FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.height, FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.depth, FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.colors, FLAC__STREAM_METADATA_PICTURE_COLORS_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, metadata->data.picture.data_length, FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.picture.data, metadata->data.picture.data_length)) | |||
| return false; | |||
| } | |||
| break; | |||
| default: | |||
| if(!FLAC__bitwriter_write_byte_block(bw, metadata->data.unknown.data, metadata->length)) | |||
| return false; | |||
| break; | |||
| } | |||
| FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw)); | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__frame_add_header(const FLAC__FrameHeader *header, FLAC__BitWriter *bw) | |||
| { | |||
| unsigned u, blocksize_hint, sample_rate_hint; | |||
| FLAC__byte crc; | |||
| FLAC__ASSERT(FLAC__bitwriter_is_byte_aligned(bw)); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__FRAME_HEADER_SYNC, FLAC__FRAME_HEADER_SYNC_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_RESERVED_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, (header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER)? 0 : 1, FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(header->blocksize > 0 && header->blocksize <= FLAC__MAX_BLOCK_SIZE); | |||
| /* when this assertion holds true, any legal blocksize can be expressed in the frame header */ | |||
| FLAC__ASSERT(FLAC__MAX_BLOCK_SIZE <= 65535u); | |||
| blocksize_hint = 0; | |||
| switch(header->blocksize) { | |||
| case 192: u = 1; break; | |||
| case 576: u = 2; break; | |||
| case 1152: u = 3; break; | |||
| case 2304: u = 4; break; | |||
| case 4608: u = 5; break; | |||
| case 256: u = 8; break; | |||
| case 512: u = 9; break; | |||
| case 1024: u = 10; break; | |||
| case 2048: u = 11; break; | |||
| case 4096: u = 12; break; | |||
| case 8192: u = 13; break; | |||
| case 16384: u = 14; break; | |||
| case 32768: u = 15; break; | |||
| default: | |||
| if(header->blocksize <= 0x100) | |||
| blocksize_hint = u = 6; | |||
| else | |||
| blocksize_hint = u = 7; | |||
| break; | |||
| } | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BLOCK_SIZE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(FLAC__format_sample_rate_is_valid(header->sample_rate)); | |||
| sample_rate_hint = 0; | |||
| switch(header->sample_rate) { | |||
| case 88200: u = 1; break; | |||
| case 176400: u = 2; break; | |||
| case 192000: u = 3; break; | |||
| case 8000: u = 4; break; | |||
| case 16000: u = 5; break; | |||
| case 22050: u = 6; break; | |||
| case 24000: u = 7; break; | |||
| case 32000: u = 8; break; | |||
| case 44100: u = 9; break; | |||
| case 48000: u = 10; break; | |||
| case 96000: u = 11; break; | |||
| default: | |||
| if(header->sample_rate <= 255000 && header->sample_rate % 1000 == 0) | |||
| sample_rate_hint = u = 12; | |||
| else if(header->sample_rate % 10 == 0) | |||
| sample_rate_hint = u = 14; | |||
| else if(header->sample_rate <= 0xffff) | |||
| sample_rate_hint = u = 13; | |||
| else | |||
| u = 0; | |||
| break; | |||
| } | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_SAMPLE_RATE_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(header->channels > 0 && header->channels <= (1u << FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN) && header->channels <= FLAC__MAX_CHANNELS); | |||
| switch(header->channel_assignment) { | |||
| case FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT: | |||
| u = header->channels - 1; | |||
| break; | |||
| case FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE: | |||
| FLAC__ASSERT(header->channels == 2); | |||
| u = 8; | |||
| break; | |||
| case FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE: | |||
| FLAC__ASSERT(header->channels == 2); | |||
| u = 9; | |||
| break; | |||
| case FLAC__CHANNEL_ASSIGNMENT_MID_SIDE: | |||
| FLAC__ASSERT(header->channels == 2); | |||
| u = 10; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN)) | |||
| return false; | |||
| FLAC__ASSERT(header->bits_per_sample > 0 && header->bits_per_sample <= (1u << FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN)); | |||
| switch(header->bits_per_sample) { | |||
| case 8 : u = 1; break; | |||
| case 12: u = 2; break; | |||
| case 16: u = 4; break; | |||
| case 20: u = 5; break; | |||
| case 24: u = 6; break; | |||
| default: u = 0; break; | |||
| } | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, u, FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, 0, FLAC__FRAME_HEADER_ZERO_PAD_LEN)) | |||
| return false; | |||
| if(header->number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER) { | |||
| if(!FLAC__bitwriter_write_utf8_uint32(bw, header->number.frame_number)) | |||
| return false; | |||
| } | |||
| else { | |||
| if(!FLAC__bitwriter_write_utf8_uint64(bw, header->number.sample_number)) | |||
| return false; | |||
| } | |||
| if(blocksize_hint) | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, header->blocksize-1, (blocksize_hint==6)? 8:16)) | |||
| return false; | |||
| switch(sample_rate_hint) { | |||
| case 12: | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 1000, 8)) | |||
| return false; | |||
| break; | |||
| case 13: | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate, 16)) | |||
| return false; | |||
| break; | |||
| case 14: | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, header->sample_rate / 10, 16)) | |||
| return false; | |||
| break; | |||
| } | |||
| /* write the CRC */ | |||
| if(!FLAC__bitwriter_get_write_crc8(bw, &crc)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, crc, FLAC__FRAME_HEADER_CRC_LEN)) | |||
| return false; | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__subframe_add_constant(const FLAC__Subframe_Constant *subframe, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw) | |||
| { | |||
| FLAC__bool ok; | |||
| ok = | |||
| FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN) && | |||
| (wasted_bits? FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1) : true) && | |||
| FLAC__bitwriter_write_raw_int32(bw, subframe->value, subframe_bps) | |||
| ; | |||
| return ok; | |||
| } | |||
| FLAC__bool FLAC__subframe_add_fixed(const FLAC__Subframe_Fixed *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw) | |||
| { | |||
| unsigned i; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK | (subframe->order<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) | |||
| return false; | |||
| if(wasted_bits) | |||
| if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) | |||
| return false; | |||
| for(i = 0; i < subframe->order; i++) | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps)) | |||
| return false; | |||
| if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method)) | |||
| return false; | |||
| switch(subframe->entropy_coding_method.type) { | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: | |||
| if(!add_residual_partitioned_rice_( | |||
| bw, | |||
| subframe->residual, | |||
| residual_samples, | |||
| subframe->order, | |||
| subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, | |||
| subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, | |||
| subframe->entropy_coding_method.data.partitioned_rice.order, | |||
| /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 | |||
| )) | |||
| return false; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__subframe_add_lpc(const FLAC__Subframe_LPC *subframe, unsigned residual_samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw) | |||
| { | |||
| unsigned i; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK | ((subframe->order-1)<<1) | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) | |||
| return false; | |||
| if(wasted_bits) | |||
| if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) | |||
| return false; | |||
| for(i = 0; i < subframe->order; i++) | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, subframe->warmup[i], subframe_bps)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, subframe->qlp_coeff_precision-1, FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, subframe->quantization_level, FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN)) | |||
| return false; | |||
| for(i = 0; i < subframe->order; i++) | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, subframe->qlp_coeff[i], subframe->qlp_coeff_precision)) | |||
| return false; | |||
| if(!add_entropy_coding_method_(bw, &subframe->entropy_coding_method)) | |||
| return false; | |||
| switch(subframe->entropy_coding_method.type) { | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: | |||
| if(!add_residual_partitioned_rice_( | |||
| bw, | |||
| subframe->residual, | |||
| residual_samples, | |||
| subframe->order, | |||
| subframe->entropy_coding_method.data.partitioned_rice.contents->parameters, | |||
| subframe->entropy_coding_method.data.partitioned_rice.contents->raw_bits, | |||
| subframe->entropy_coding_method.data.partitioned_rice.order, | |||
| /*is_extended=*/subframe->entropy_coding_method.type == FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 | |||
| )) | |||
| return false; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool FLAC__subframe_add_verbatim(const FLAC__Subframe_Verbatim *subframe, unsigned samples, unsigned subframe_bps, unsigned wasted_bits, FLAC__BitWriter *bw) | |||
| { | |||
| unsigned i; | |||
| const FLAC__int32 *signal = subframe->data; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK | (wasted_bits? 1:0), FLAC__SUBFRAME_ZERO_PAD_LEN + FLAC__SUBFRAME_TYPE_LEN + FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN)) | |||
| return false; | |||
| if(wasted_bits) | |||
| if(!FLAC__bitwriter_write_unary_unsigned(bw, wasted_bits-1)) | |||
| return false; | |||
| for(i = 0; i < samples; i++) | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, signal[i], subframe_bps)) | |||
| return false; | |||
| return true; | |||
| } | |||
| FLAC__bool add_entropy_coding_method_(FLAC__BitWriter *bw, const FLAC__EntropyCodingMethod *method) | |||
| { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, method->type, FLAC__ENTROPY_CODING_METHOD_TYPE_LEN)) | |||
| return false; | |||
| switch(method->type) { | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE: | |||
| case FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2: | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, method->data.partitioned_rice.order, FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN)) | |||
| return false; | |||
| break; | |||
| default: | |||
| FLAC__ASSERT(0); | |||
| } | |||
| return true; | |||
| } | |||
| FLAC__bool add_residual_partitioned_rice_(FLAC__BitWriter *bw, const FLAC__int32 residual[], const unsigned residual_samples, const unsigned predictor_order, const unsigned rice_parameters[], const unsigned raw_bits[], const unsigned partition_order, const FLAC__bool is_extended) | |||
| { | |||
| const unsigned plen = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; | |||
| const unsigned pesc = is_extended? FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_ESCAPE_PARAMETER : FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; | |||
| if(partition_order == 0) { | |||
| unsigned i; | |||
| if(raw_bits[0] == 0) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[0], plen)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_rice_signed_block(bw, residual, residual_samples, rice_parameters[0])) | |||
| return false; | |||
| } | |||
| else { | |||
| FLAC__ASSERT(rice_parameters[0] == 0); | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[0], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) | |||
| return false; | |||
| for(i = 0; i < residual_samples; i++) { | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, residual[i], raw_bits[0])) | |||
| return false; | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| else { | |||
| unsigned i, j, k = 0, k_last = 0; | |||
| unsigned partition_samples; | |||
| const unsigned default_partition_samples = (residual_samples+predictor_order) >> partition_order; | |||
| for(i = 0; i < (1u<<partition_order); i++) { | |||
| partition_samples = default_partition_samples; | |||
| if(i == 0) | |||
| partition_samples -= predictor_order; | |||
| k += partition_samples; | |||
| if(raw_bits[i] == 0) { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, rice_parameters[i], plen)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_rice_signed_block(bw, residual+k_last, k-k_last, rice_parameters[i])) | |||
| return false; | |||
| } | |||
| else { | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, pesc, plen)) | |||
| return false; | |||
| if(!FLAC__bitwriter_write_raw_uint32(bw, raw_bits[i], FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN)) | |||
| return false; | |||
| for(j = k_last; j < k; j++) { | |||
| if(!FLAC__bitwriter_write_raw_int32(bw, residual[j], raw_bits[i])) | |||
| return false; | |||
| } | |||
| } | |||
| k_last = k; | |||
| } | |||
| return true; | |||
| } | |||
| } | |||
| @@ -1,281 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2006-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef HAVE_CONFIG_H | |||
| # include <config.h> | |||
| #endif | |||
| #include <math.h> | |||
| #include "../assert.h" | |||
| #include "../format.h" | |||
| #include "include/private/window.h" | |||
| #ifndef FLAC__INTEGER_ONLY_LIBRARY | |||
| void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| if (L & 1) { | |||
| for (n = 0; n <= N/2; n++) | |||
| window[n] = 2.0f * n / (float)N; | |||
| for (; n <= N; n++) | |||
| window[n] = 2.0f - 2.0f * n / (float)N; | |||
| } | |||
| else { | |||
| for (n = 0; n <= L/2-1; n++) | |||
| window[n] = 2.0f * n / (float)N; | |||
| for (; n <= N; n++) | |||
| window[n] = 2.0f - 2.0f * n / (float)N; | |||
| } | |||
| } | |||
| void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N-0.5f) - 0.38f * cos(2.0f * M_PI * ((float)n/(float)N))); | |||
| } | |||
| void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.42f - 0.5f * cos(2.0f * M_PI * n / N) + 0.08f * cos(4.0f * M_PI * n / N)); | |||
| } | |||
| /* 4-term -92dB side-lobe */ | |||
| void FLAC__window_blackman_harris_4term_92db_sidelobe(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n <= N; n++) | |||
| window[n] = (FLAC__real)(0.35875f - 0.48829f * cos(2.0f * M_PI * n / N) + 0.14128f * cos(4.0f * M_PI * n / N) - 0.01168f * cos(6.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_connes(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| const double N2 = (double)N / 2.; | |||
| FLAC__int32 n; | |||
| for (n = 0; n <= N; n++) { | |||
| double k = ((double)n - N2) / N2; | |||
| k = 1.0f - k * k; | |||
| window[n] = (FLAC__real)(k * k); | |||
| } | |||
| } | |||
| void FLAC__window_flattop(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(1.0f - 1.93f * cos(2.0f * M_PI * n / N) + 1.29f * cos(4.0f * M_PI * n / N) - 0.388f * cos(6.0f * M_PI * n / N) + 0.0322f * cos(8.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_gauss(FLAC__real *window, const FLAC__int32 L, const FLAC__real stddev) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| const double N2 = (double)N / 2.; | |||
| FLAC__int32 n; | |||
| for (n = 0; n <= N; n++) { | |||
| const double k = ((double)n - N2) / (stddev * N2); | |||
| window[n] = (FLAC__real)exp(-0.5f * k * k); | |||
| } | |||
| } | |||
| void FLAC__window_hamming(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.54f - 0.46f * cos(2.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_hann(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cos(2.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_kaiser_bessel(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.402f - 0.498f * cos(2.0f * M_PI * n / N) + 0.098f * cos(4.0f * M_PI * n / N) - 0.001f * cos(6.0f * M_PI * n / N)); | |||
| } | |||
| void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = (FLAC__real)(0.3635819f - 0.4891775f*cos(2.0f*M_PI*n/N) + 0.1365995f*cos(4.0f*M_PI*n/N) - 0.0106411f*cos(6.0f*M_PI*n/N)); | |||
| } | |||
| void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| FLAC__int32 n; | |||
| for (n = 0; n < L; n++) | |||
| window[n] = 1.0f; | |||
| } | |||
| void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| FLAC__int32 n; | |||
| if (L & 1) { | |||
| for (n = 1; n <= (L+1)/2; n++) | |||
| window[n-1] = 2.0f * n / ((float)L + 1.0f); | |||
| for (; n <= L; n++) | |||
| window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); | |||
| } | |||
| else { | |||
| for (n = 1; n <= L/2; n++) | |||
| window[n-1] = 2.0f * n / ((float)L + 1.0f); | |||
| for (; n <= L; n++) | |||
| window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); | |||
| } | |||
| } | |||
| void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p) | |||
| { | |||
| if (p <= 0.0) | |||
| FLAC__window_rectangle(window, L); | |||
| else if (p >= 1.0) | |||
| FLAC__window_hann(window, L); | |||
| else { | |||
| const FLAC__int32 Np = (FLAC__int32)(p / 2.0f * L) - 1; | |||
| FLAC__int32 n; | |||
| /* start with rectangle... */ | |||
| FLAC__window_rectangle(window, L); | |||
| /* ...replace ends with hann */ | |||
| if (Np > 0) { | |||
| for (n = 0; n <= Np; n++) { | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * n / Np)); | |||
| window[L-Np-1+n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * (n+Np) / Np)); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) | |||
| { | |||
| const FLAC__int32 start_n = (FLAC__int32)(start * L); | |||
| const FLAC__int32 end_n = (FLAC__int32)(end * L); | |||
| const FLAC__int32 N = end_n - start_n; | |||
| FLAC__int32 Np, n, i; | |||
| if (p <= 0.0f) | |||
| FLAC__window_partial_tukey(window, L, 0.05f, start, end); | |||
| else if (p >= 1.0f) | |||
| FLAC__window_partial_tukey(window, L, 0.95f, start, end); | |||
| else { | |||
| Np = (FLAC__int32)(p / 2.0f * N); | |||
| for (n = 0; n < start_n && n < L; n++) | |||
| window[n] = 0.0f; | |||
| for (i = 1; n < (start_n+Np) && n < L; n++, i++) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np)); | |||
| for (; n < (end_n-Np) && n < L; n++) | |||
| window[n] = 1.0f; | |||
| for (i = Np; n < end_n && n < L; n++, i--) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np)); | |||
| for (; n < L; n++) | |||
| window[n] = 0.0f; | |||
| } | |||
| } | |||
| void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) | |||
| { | |||
| const FLAC__int32 start_n = (FLAC__int32)(start * L); | |||
| const FLAC__int32 end_n = (FLAC__int32)(end * L); | |||
| FLAC__int32 Ns, Ne, n, i; | |||
| if (p <= 0.0f) | |||
| FLAC__window_punchout_tukey(window, L, 0.05f, start, end); | |||
| else if (p >= 1.0f) | |||
| FLAC__window_punchout_tukey(window, L, 0.95f, start, end); | |||
| else { | |||
| Ns = (FLAC__int32)(p / 2.0f * start_n); | |||
| Ne = (FLAC__int32)(p / 2.0f * (L - end_n)); | |||
| for (n = 0, i = 1; n < Ns && n < L; n++, i++) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns)); | |||
| for (; n < start_n-Ns && n < L; n++) | |||
| window[n] = 1.0f; | |||
| for (i = Ns; n < start_n && n < L; n++, i--) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns)); | |||
| for (; n < end_n && n < L; n++) | |||
| window[n] = 0.0f; | |||
| for (i = 1; n < end_n+Ne && n < L; n++, i++) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne)); | |||
| for (; n < L - (Ne) && n < L; n++) | |||
| window[n] = 1.0f; | |||
| for (i = Ne; n < L; n++, i--) | |||
| window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne)); | |||
| } | |||
| } | |||
| void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) | |||
| { | |||
| const FLAC__int32 N = L - 1; | |||
| const double N2 = (double)N / 2.; | |||
| FLAC__int32 n; | |||
| for (n = 0; n <= N; n++) { | |||
| const double k = ((double)n - N2) / N2; | |||
| window[n] = (FLAC__real)(1.0f - k * k); | |||
| } | |||
| } | |||
| #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ | |||
| @@ -1,86 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2000-2009 Josh Coalson | |||
| * Copyright (C) 2011-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifndef FLAC__ORDINALS_H | |||
| #define FLAC__ORDINALS_H | |||
| #if defined(_MSC_VER) && _MSC_VER < 1600 | |||
| /* Microsoft Visual Studio earlier than the 2010 version did not provide | |||
| * the 1999 ISO C Standard header file <stdint.h>. | |||
| */ | |||
| typedef __int8 FLAC__int8; | |||
| typedef unsigned __int8 FLAC__uint8; | |||
| typedef __int16 FLAC__int16; | |||
| typedef __int32 FLAC__int32; | |||
| typedef __int64 FLAC__int64; | |||
| typedef unsigned __int16 FLAC__uint16; | |||
| typedef unsigned __int32 FLAC__uint32; | |||
| typedef unsigned __int64 FLAC__uint64; | |||
| #else | |||
| /* For MSVC 2010 and everything else which provides <stdint.h>. */ | |||
| #include <stdint.h> | |||
| typedef int8_t FLAC__int8; | |||
| typedef uint8_t FLAC__uint8; | |||
| typedef int16_t FLAC__int16; | |||
| typedef int32_t FLAC__int32; | |||
| typedef int64_t FLAC__int64; | |||
| typedef uint16_t FLAC__uint16; | |||
| typedef uint32_t FLAC__uint32; | |||
| typedef uint64_t FLAC__uint64; | |||
| #endif | |||
| typedef int FLAC__bool; | |||
| typedef FLAC__uint8 FLAC__byte; | |||
| #ifdef true | |||
| #undef true | |||
| #endif | |||
| #ifdef false | |||
| #undef false | |||
| #endif | |||
| #ifndef __cplusplus | |||
| #define true 1 | |||
| #define false 0 | |||
| #endif | |||
| #endif | |||
| @@ -1,64 +0,0 @@ | |||
| /* libFLAC - Free Lossless Audio Codec library | |||
| * Copyright (C) 2013-2014 Xiph.Org Foundation | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * - Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * - Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in the | |||
| * documentation and/or other materials provided with the distribution. | |||
| * | |||
| * - Neither the name of the Xiph.org Foundation nor the names of its | |||
| * contributors may be used to endorse or promote products derived from | |||
| * this software without specific prior written permission. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | |||
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| */ | |||
| #ifdef _WIN32 | |||
| #ifndef flac__win_utf8_io_h | |||
| #define flac__win_utf8_io_h | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| int get_utf8_argv(int *argc, char ***argv); | |||
| int printf_utf8(const char *format, ...); | |||
| int fprintf_utf8(FILE *stream, const char *format, ...); | |||
| int vfprintf_utf8(FILE *stream, const char *format, va_list argptr); | |||
| FILE *fopen_utf8(const char *filename, const char *mode); | |||
| int stat_utf8(const char *path, struct stat *buffer); | |||
| int _stat64_utf8(const char *path, struct __stat64 *buffer); | |||
| int chmod_utf8(const char *filename, int pmode); | |||
| int utime_utf8(const char *filename, struct utimbuf *times); | |||
| int unlink_utf8(const char *filename); | |||
| int rename_utf8(const char *oldname, const char *newname); | |||
| size_t strlen_utf8(const char *str); | |||
| int win_get_console_width(void); | |||
| int print_console(FILE *stream, const wchar_t *text, size_t len); | |||
| HANDLE WINAPI CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); | |||
| #ifdef __cplusplus | |||
| } /* extern "C" */ | |||
| #endif | |||
| #endif | |||
| #endif | |||
| @@ -1,92 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| //============================================================================== | |||
| /** | |||
| Reads and Writes AIFF format audio files. | |||
| @see AudioFormat | |||
| */ | |||
| class JUCE_API AiffAudioFormat : public AudioFormat | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates an format object. */ | |||
| AiffAudioFormat(); | |||
| /** Destructor. */ | |||
| ~AiffAudioFormat(); | |||
| //============================================================================== | |||
| /** Metadata property name used when reading a aiff file with a basc chunk. */ | |||
| static const char* const appleOneShot; | |||
| /** Metadata property name used when reading a aiff file with a basc chunk. */ | |||
| static const char* const appleRootSet; | |||
| /** Metadata property name used when reading a aiff file with a basc chunk. */ | |||
| static const char* const appleRootNote; | |||
| /** Metadata property name used when reading a aiff file with a basc chunk. */ | |||
| static const char* const appleBeats; | |||
| /** Metadata property name used when reading a aiff file with a basc chunk. */ | |||
| static const char* const appleDenominator; | |||
| /** Metadata property name used when reading a aiff file with a basc chunk. */ | |||
| static const char* const appleNumerator; | |||
| /** Metadata property name used when reading a aiff file with a basc chunk. */ | |||
| static const char* const appleTag; | |||
| /** Metadata property name used when reading a aiff file with a basc chunk. */ | |||
| static const char* const appleKey; | |||
| //============================================================================== | |||
| Array<int> getPossibleSampleRates() override; | |||
| Array<int> getPossibleBitDepths() override; | |||
| bool canDoStereo() override; | |||
| bool canDoMono() override; | |||
| #if JUCE_MAC | |||
| bool canHandleFile (const File& fileToTest) override; | |||
| #endif | |||
| //============================================================================== | |||
| AudioFormatReader* createReaderFor (InputStream* sourceStream, | |||
| bool deleteStreamIfOpeningFails) override; | |||
| MemoryMappedAudioFormatReader* createMemoryMappedReader (const File&) override; | |||
| MemoryMappedAudioFormatReader* createMemoryMappedReader (FileInputStream*) override; | |||
| AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, | |||
| double sampleRateToUse, | |||
| unsigned int numberOfChannels, | |||
| int bitsPerSample, | |||
| const StringPairArray& metadataValues, | |||
| int qualityOptionIndex) override; | |||
| private: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(AiffAudioFormat) | |||
| }; | |||
| } // namespace juce | |||
| @@ -1,840 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| #if JUCE_MAC || JUCE_IOS | |||
| #include "../../juce_audio_basics/native/juce_mac_CoreAudioLayouts.h" | |||
| namespace juce | |||
| { | |||
| //============================================================================== | |||
| namespace | |||
| { | |||
| const char* const coreAudioFormatName = "CoreAudio supported file"; | |||
| StringArray findFileExtensionsForCoreAudioCodecs() | |||
| { | |||
| StringArray extensionsArray; | |||
| CFArrayRef extensions = nullptr; | |||
| UInt32 sizeOfArray = sizeof (extensions); | |||
| if (AudioFileGetGlobalInfo (kAudioFileGlobalInfo_AllExtensions, 0, 0, &sizeOfArray, &extensions) == noErr) | |||
| { | |||
| const CFIndex numValues = CFArrayGetCount (extensions); | |||
| for (CFIndex i = 0; i < numValues; ++i) | |||
| extensionsArray.add ("." + String::fromCFString ((CFStringRef) CFArrayGetValueAtIndex (extensions, i))); | |||
| CFRelease (extensions); | |||
| } | |||
| return extensionsArray; | |||
| } | |||
| } | |||
| //============================================================================== | |||
| const char* const CoreAudioFormat::midiDataBase64 = "midiDataBase64"; | |||
| const char* const CoreAudioFormat::tempo = "tempo"; | |||
| const char* const CoreAudioFormat::timeSig = "time signature"; | |||
| const char* const CoreAudioFormat::keySig = "key signature"; | |||
| //============================================================================== | |||
| struct CoreAudioFormatMetatdata | |||
| { | |||
| static uint32 chunkName (const char* const name) noexcept { return ByteOrder::bigEndianInt (name); } | |||
| //============================================================================== | |||
| struct FileHeader | |||
| { | |||
| FileHeader (InputStream& input) | |||
| { | |||
| fileType = (uint32) input.readIntBigEndian(); | |||
| fileVersion = (uint16) input.readShortBigEndian(); | |||
| fileFlags = (uint16) input.readShortBigEndian(); | |||
| } | |||
| uint32 fileType; | |||
| uint16 fileVersion; | |||
| uint16 fileFlags; | |||
| }; | |||
| //============================================================================== | |||
| struct ChunkHeader | |||
| { | |||
| ChunkHeader (InputStream& input) | |||
| { | |||
| chunkType = (uint32) input.readIntBigEndian(); | |||
| chunkSize = (int64) input.readInt64BigEndian(); | |||
| } | |||
| uint32 chunkType; | |||
| int64 chunkSize; | |||
| }; | |||
| //============================================================================== | |||
| struct AudioDescriptionChunk | |||
| { | |||
| AudioDescriptionChunk (InputStream& input) | |||
| { | |||
| sampleRate = input.readDoubleBigEndian(); | |||
| formatID = (uint32) input.readIntBigEndian(); | |||
| formatFlags = (uint32) input.readIntBigEndian(); | |||
| bytesPerPacket = (uint32) input.readIntBigEndian(); | |||
| framesPerPacket = (uint32) input.readIntBigEndian(); | |||
| channelsPerFrame = (uint32) input.readIntBigEndian(); | |||
| bitsPerChannel = (uint32) input.readIntBigEndian(); | |||
| } | |||
| double sampleRate; | |||
| uint32 formatID; | |||
| uint32 formatFlags; | |||
| uint32 bytesPerPacket; | |||
| uint32 framesPerPacket; | |||
| uint32 channelsPerFrame; | |||
| uint32 bitsPerChannel; | |||
| }; | |||
| //============================================================================== | |||
| static StringPairArray parseUserDefinedChunk (InputStream& input, int64 size) | |||
| { | |||
| StringPairArray infoStrings; | |||
| const int64 originalPosition = input.getPosition(); | |||
| uint8 uuid[16]; | |||
| input.read (uuid, sizeof (uuid)); | |||
| if (memcmp (uuid, "\x29\x81\x92\x73\xB5\xBF\x4A\xEF\xB7\x8D\x62\xD1\xEF\x90\xBB\x2C", 16) == 0) | |||
| { | |||
| const uint32 numEntries = (uint32) input.readIntBigEndian(); | |||
| for (uint32 i = 0; i < numEntries && input.getPosition() < originalPosition + size; ++i) | |||
| { | |||
| String keyName = input.readString(); | |||
| infoStrings.set (keyName, input.readString()); | |||
| } | |||
| } | |||
| input.setPosition (originalPosition + size); | |||
| return infoStrings; | |||
| } | |||
| //============================================================================== | |||
| static StringPairArray parseMidiChunk (InputStream& input, int64 size) | |||
| { | |||
| const int64 originalPosition = input.getPosition(); | |||
| MemoryBlock midiBlock; | |||
| input.readIntoMemoryBlock (midiBlock, (ssize_t) size); | |||
| MemoryInputStream midiInputStream (midiBlock, false); | |||
| StringPairArray midiMetadata; | |||
| MidiFile midiFile; | |||
| if (midiFile.readFrom (midiInputStream)) | |||
| { | |||
| midiMetadata.set (CoreAudioFormat::midiDataBase64, midiBlock.toBase64Encoding()); | |||
| findTempoEvents (midiFile, midiMetadata); | |||
| findTimeSigEvents (midiFile, midiMetadata); | |||
| findKeySigEvents (midiFile, midiMetadata); | |||
| } | |||
| input.setPosition (originalPosition + size); | |||
| return midiMetadata; | |||
| } | |||
| static void findTempoEvents (MidiFile& midiFile, StringPairArray& midiMetadata) | |||
| { | |||
| MidiMessageSequence tempoEvents; | |||
| midiFile.findAllTempoEvents (tempoEvents); | |||
| const int numTempoEvents = tempoEvents.getNumEvents(); | |||
| MemoryOutputStream tempoSequence; | |||
| for (int i = 0; i < numTempoEvents; ++i) | |||
| { | |||
| const double tempo = getTempoFromTempoMetaEvent (tempoEvents.getEventPointer (i)); | |||
| if (tempo > 0.0) | |||
| { | |||
| if (i == 0) | |||
| midiMetadata.set (CoreAudioFormat::tempo, String (tempo)); | |||
| if (numTempoEvents > 1) | |||
| tempoSequence << String (tempo) << ',' << tempoEvents.getEventTime (i) << ';'; | |||
| } | |||
| } | |||
| if (tempoSequence.getDataSize() > 0) | |||
| midiMetadata.set ("tempo sequence", tempoSequence.toUTF8()); | |||
| } | |||
| static double getTempoFromTempoMetaEvent (MidiMessageSequence::MidiEventHolder* holder) | |||
| { | |||
| if (holder != nullptr) | |||
| { | |||
| const MidiMessage& midiMessage = holder->message; | |||
| if (midiMessage.isTempoMetaEvent()) | |||
| { | |||
| const double tempoSecondsPerQuarterNote = midiMessage.getTempoSecondsPerQuarterNote(); | |||
| if (tempoSecondsPerQuarterNote > 0.0) | |||
| return 60.0 / tempoSecondsPerQuarterNote; | |||
| } | |||
| } | |||
| return 0.0; | |||
| } | |||
| static void findTimeSigEvents (MidiFile& midiFile, StringPairArray& midiMetadata) | |||
| { | |||
| MidiMessageSequence timeSigEvents; | |||
| midiFile.findAllTimeSigEvents (timeSigEvents); | |||
| const int numTimeSigEvents = timeSigEvents.getNumEvents(); | |||
| MemoryOutputStream timeSigSequence; | |||
| for (int i = 0; i < numTimeSigEvents; ++i) | |||
| { | |||
| int numerator, denominator; | |||
| timeSigEvents.getEventPointer(i)->message.getTimeSignatureInfo (numerator, denominator); | |||
| String timeSigString; | |||
| timeSigString << numerator << '/' << denominator; | |||
| if (i == 0) | |||
| midiMetadata.set (CoreAudioFormat::timeSig, timeSigString); | |||
| if (numTimeSigEvents > 1) | |||
| timeSigSequence << timeSigString << ',' << timeSigEvents.getEventTime (i) << ';'; | |||
| } | |||
| if (timeSigSequence.getDataSize() > 0) | |||
| midiMetadata.set ("time signature sequence", timeSigSequence.toUTF8()); | |||
| } | |||
| static void findKeySigEvents (MidiFile& midiFile, StringPairArray& midiMetadata) | |||
| { | |||
| MidiMessageSequence keySigEvents; | |||
| midiFile.findAllKeySigEvents (keySigEvents); | |||
| const int numKeySigEvents = keySigEvents.getNumEvents(); | |||
| MemoryOutputStream keySigSequence; | |||
| for (int i = 0; i < numKeySigEvents; ++i) | |||
| { | |||
| const MidiMessage& message (keySigEvents.getEventPointer (i)->message); | |||
| const int key = jlimit (0, 14, message.getKeySignatureNumberOfSharpsOrFlats() + 7); | |||
| const bool isMajor = message.isKeySignatureMajorKey(); | |||
| static const char* majorKeys[] = { "Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#" }; | |||
| static const char* minorKeys[] = { "Ab", "Eb", "Bb", "F", "C", "G", "D", "A", "E", "B", "F#", "C#", "G#", "D#", "A#" }; | |||
| String keySigString (isMajor ? majorKeys[key] | |||
| : minorKeys[key]); | |||
| if (! isMajor) | |||
| keySigString << 'm'; | |||
| if (i == 0) | |||
| midiMetadata.set (CoreAudioFormat::keySig, keySigString); | |||
| if (numKeySigEvents > 1) | |||
| keySigSequence << keySigString << ',' << keySigEvents.getEventTime (i) << ';'; | |||
| } | |||
| if (keySigSequence.getDataSize() > 0) | |||
| midiMetadata.set ("key signature sequence", keySigSequence.toUTF8()); | |||
| } | |||
| //============================================================================== | |||
| static StringPairArray parseInformationChunk (InputStream& input) | |||
| { | |||
| StringPairArray infoStrings; | |||
| const uint32 numEntries = (uint32) input.readIntBigEndian(); | |||
| for (uint32 i = 0; i < numEntries; ++i) | |||
| infoStrings.set (input.readString(), input.readString()); | |||
| return infoStrings; | |||
| } | |||
| //============================================================================== | |||
| static bool read (InputStream& input, StringPairArray& metadataValues) | |||
| { | |||
| const int64 originalPos = input.getPosition(); | |||
| const FileHeader cafFileHeader (input); | |||
| const bool isCafFile = cafFileHeader.fileType == chunkName ("caff"); | |||
| if (isCafFile) | |||
| { | |||
| while (! input.isExhausted()) | |||
| { | |||
| const ChunkHeader chunkHeader (input); | |||
| if (chunkHeader.chunkType == chunkName ("desc")) | |||
| { | |||
| AudioDescriptionChunk audioDescriptionChunk (input); | |||
| } | |||
| else if (chunkHeader.chunkType == chunkName ("uuid")) | |||
| { | |||
| metadataValues.addArray (parseUserDefinedChunk (input, chunkHeader.chunkSize)); | |||
| } | |||
| else if (chunkHeader.chunkType == chunkName ("data")) | |||
| { | |||
| // -1 signifies an unknown data size so the data has to be at the | |||
| // end of the file so we must have finished the header | |||
| if (chunkHeader.chunkSize == -1) | |||
| break; | |||
| input.skipNextBytes (chunkHeader.chunkSize); | |||
| } | |||
| else if (chunkHeader.chunkType == chunkName ("midi")) | |||
| { | |||
| metadataValues.addArray (parseMidiChunk (input, chunkHeader.chunkSize)); | |||
| } | |||
| else if (chunkHeader.chunkType == chunkName ("info")) | |||
| { | |||
| metadataValues.addArray (parseInformationChunk (input)); | |||
| } | |||
| else | |||
| { | |||
| // we aren't decoding this chunk yet so just skip over it | |||
| input.skipNextBytes (chunkHeader.chunkSize); | |||
| } | |||
| } | |||
| } | |||
| input.setPosition (originalPos); | |||
| return isCafFile; | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| class CoreAudioReader : public AudioFormatReader | |||
| { | |||
| public: | |||
| CoreAudioReader (InputStream* const inp) | |||
| : AudioFormatReader (inp, coreAudioFormatName), | |||
| ok (false), lastReadPosition (0) | |||
| { | |||
| usesFloatingPointData = true; | |||
| bitsPerSample = 32; | |||
| if (input != nullptr) | |||
| CoreAudioFormatMetatdata::read (*input, metadataValues); | |||
| OSStatus status = AudioFileOpenWithCallbacks (this, | |||
| &readCallback, | |||
| nullptr, // write needs to be null to avoid permisisions errors | |||
| &getSizeCallback, | |||
| nullptr, // setSize needs to be null to avoid permisisions errors | |||
| 0, // AudioFileTypeID inFileTypeHint | |||
| &audioFileID); | |||
| if (status == noErr) | |||
| { | |||
| status = ExtAudioFileWrapAudioFileID (audioFileID, false, &audioFileRef); | |||
| if (status == noErr) | |||
| { | |||
| AudioStreamBasicDescription sourceAudioFormat; | |||
| UInt32 audioStreamBasicDescriptionSize = sizeof (AudioStreamBasicDescription); | |||
| ExtAudioFileGetProperty (audioFileRef, | |||
| kExtAudioFileProperty_FileDataFormat, | |||
| &audioStreamBasicDescriptionSize, | |||
| &sourceAudioFormat); | |||
| numChannels = sourceAudioFormat.mChannelsPerFrame; | |||
| sampleRate = sourceAudioFormat.mSampleRate; | |||
| UInt32 sizeOfLengthProperty = sizeof (int64); | |||
| ExtAudioFileGetProperty (audioFileRef, | |||
| kExtAudioFileProperty_FileLengthFrames, | |||
| &sizeOfLengthProperty, | |||
| &lengthInSamples); | |||
| HeapBlock<AudioChannelLayout> caLayout; | |||
| bool hasLayout = false; | |||
| UInt32 sizeOfLayout = 0, isWritable = 0; | |||
| status = AudioFileGetPropertyInfo (audioFileID, kAudioFilePropertyChannelLayout, &sizeOfLayout, &isWritable); | |||
| if (status == noErr) | |||
| { | |||
| caLayout.malloc (1, static_cast<size_t> (sizeOfLayout)); | |||
| status = AudioFileGetProperty (audioFileID, kAudioFilePropertyChannelLayout, | |||
| &sizeOfLayout, caLayout.get()); | |||
| if (status == noErr) | |||
| { | |||
| auto fileLayout = CoreAudioLayouts::fromCoreAudio (*caLayout.get()); | |||
| if (fileLayout.size() == static_cast<int> (numChannels)) | |||
| { | |||
| hasLayout = true; | |||
| channelSet = fileLayout; | |||
| } | |||
| } | |||
| } | |||
| destinationAudioFormat.mSampleRate = sampleRate; | |||
| destinationAudioFormat.mFormatID = kAudioFormatLinearPCM; | |||
| destinationAudioFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsNonInterleaved | kAudioFormatFlagsNativeEndian; | |||
| destinationAudioFormat.mBitsPerChannel = sizeof (float) * 8; | |||
| destinationAudioFormat.mChannelsPerFrame = numChannels; | |||
| destinationAudioFormat.mBytesPerFrame = sizeof (float); | |||
| destinationAudioFormat.mFramesPerPacket = 1; | |||
| destinationAudioFormat.mBytesPerPacket = destinationAudioFormat.mFramesPerPacket * destinationAudioFormat.mBytesPerFrame; | |||
| status = ExtAudioFileSetProperty (audioFileRef, | |||
| kExtAudioFileProperty_ClientDataFormat, | |||
| sizeof (AudioStreamBasicDescription), | |||
| &destinationAudioFormat); | |||
| if (status == noErr) | |||
| { | |||
| bufferList.malloc (1, sizeof (AudioBufferList) + numChannels * sizeof (::AudioBuffer)); | |||
| bufferList->mNumberBuffers = numChannels; | |||
| channelMap.malloc (numChannels); | |||
| if (hasLayout && caLayout != nullptr) | |||
| { | |||
| auto caOrder = CoreAudioLayouts::getCoreAudioLayoutChannels (*caLayout); | |||
| for (int i = 0; i < static_cast<int> (numChannels); ++i) | |||
| { | |||
| auto idx = channelSet.getChannelIndexForType (caOrder.getReference (i)); | |||
| jassert (isPositiveAndBelow (idx, static_cast<int> (numChannels))); | |||
| channelMap[i] = idx; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = 0; i < static_cast<int> (numChannels); ++i) | |||
| channelMap[i] = i; | |||
| } | |||
| ok = true; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| ~CoreAudioReader() | |||
| { | |||
| ExtAudioFileDispose (audioFileRef); | |||
| AudioFileClose (audioFileID); | |||
| } | |||
| //============================================================================== | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) override | |||
| { | |||
| clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, | |||
| startSampleInFile, numSamples, lengthInSamples); | |||
| if (numSamples <= 0) | |||
| return true; | |||
| if (lastReadPosition != startSampleInFile) | |||
| { | |||
| OSStatus status = ExtAudioFileSeek (audioFileRef, startSampleInFile); | |||
| if (status != noErr) | |||
| return false; | |||
| lastReadPosition = startSampleInFile; | |||
| } | |||
| while (numSamples > 0) | |||
| { | |||
| const int numThisTime = jmin (8192, numSamples); | |||
| const size_t numBytes = sizeof (float) * (size_t) numThisTime; | |||
| audioDataBlock.ensureSize (numBytes * numChannels, false); | |||
| float* data = static_cast<float*> (audioDataBlock.getData()); | |||
| for (int j = (int) numChannels; --j >= 0;) | |||
| { | |||
| bufferList->mBuffers[j].mNumberChannels = 1; | |||
| bufferList->mBuffers[j].mDataByteSize = (UInt32) numBytes; | |||
| bufferList->mBuffers[j].mData = data; | |||
| data += numThisTime; | |||
| } | |||
| UInt32 numFramesToRead = (UInt32) numThisTime; | |||
| OSStatus status = ExtAudioFileRead (audioFileRef, &numFramesToRead, bufferList); | |||
| if (status != noErr) | |||
| return false; | |||
| for (int i = numDestChannels; --i >= 0;) | |||
| { | |||
| int* dest = destSamples[(i < (int) numChannels ? channelMap[i] : i)]; | |||
| if (dest != nullptr) | |||
| { | |||
| if (i < (int) numChannels) | |||
| memcpy (dest + startOffsetInDestBuffer, bufferList->mBuffers[i].mData, numBytes); | |||
| else | |||
| zeromem (dest + startOffsetInDestBuffer, numBytes); | |||
| } | |||
| } | |||
| startOffsetInDestBuffer += numThisTime; | |||
| numSamples -= numThisTime; | |||
| lastReadPosition += numThisTime; | |||
| } | |||
| return true; | |||
| } | |||
| AudioChannelSet getChannelLayout() override | |||
| { | |||
| if (channelSet.size() == static_cast<int> (numChannels)) return channelSet; | |||
| return AudioFormatReader::getChannelLayout(); | |||
| } | |||
| bool ok; | |||
| private: | |||
| AudioFileID audioFileID; | |||
| ExtAudioFileRef audioFileRef; | |||
| AudioChannelSet channelSet; | |||
| AudioStreamBasicDescription destinationAudioFormat; | |||
| MemoryBlock audioDataBlock; | |||
| HeapBlock<AudioBufferList> bufferList; | |||
| int64 lastReadPosition; | |||
| HeapBlock<int> channelMap; | |||
| static SInt64 getSizeCallback (void* inClientData) | |||
| { | |||
| return static_cast<CoreAudioReader*> (inClientData)->input->getTotalLength(); | |||
| } | |||
| static OSStatus readCallback (void* inClientData, | |||
| SInt64 inPosition, | |||
| UInt32 requestCount, | |||
| void* buffer, | |||
| UInt32* actualCount) | |||
| { | |||
| CoreAudioReader* const reader = static_cast<CoreAudioReader*> (inClientData); | |||
| reader->input->setPosition (inPosition); | |||
| *actualCount = (UInt32) reader->input->read (buffer, (int) requestCount); | |||
| return noErr; | |||
| } | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioReader) | |||
| }; | |||
| //============================================================================== | |||
| CoreAudioFormat::CoreAudioFormat() | |||
| : AudioFormat (coreAudioFormatName, findFileExtensionsForCoreAudioCodecs()) | |||
| { | |||
| } | |||
| CoreAudioFormat::~CoreAudioFormat() {} | |||
| Array<int> CoreAudioFormat::getPossibleSampleRates() { return Array<int>(); } | |||
| Array<int> CoreAudioFormat::getPossibleBitDepths() { return Array<int>(); } | |||
| bool CoreAudioFormat::canDoStereo() { return true; } | |||
| bool CoreAudioFormat::canDoMono() { return true; } | |||
| //============================================================================== | |||
| AudioFormatReader* CoreAudioFormat::createReaderFor (InputStream* sourceStream, | |||
| bool deleteStreamIfOpeningFails) | |||
| { | |||
| ScopedPointer<CoreAudioReader> r (new CoreAudioReader (sourceStream)); | |||
| if (r->ok) | |||
| return r.release(); | |||
| if (! deleteStreamIfOpeningFails) | |||
| r->input = nullptr; | |||
| return nullptr; | |||
| } | |||
| AudioFormatWriter* CoreAudioFormat::createWriterFor (OutputStream*, | |||
| double /*sampleRateToUse*/, | |||
| unsigned int /*numberOfChannels*/, | |||
| int /*bitsPerSample*/, | |||
| const StringPairArray& /*metadataValues*/, | |||
| int /*qualityOptionIndex*/) | |||
| { | |||
| jassertfalse; // not yet implemented! | |||
| return nullptr; | |||
| } | |||
| //============================================================================== | |||
| // Unit tests for Core Audio layout conversions | |||
| //============================================================================== | |||
| #if JUCE_UNIT_TESTS | |||
| #define DEFINE_CHANNEL_LAYOUT_DFL_ENTRY(x) CoreAudioChannelLayoutTag { x, #x, AudioChannelSet() } | |||
| #define DEFINE_CHANNEL_LAYOUT_TAG_ENTRY(x, y) CoreAudioChannelLayoutTag { x, #x, y } | |||
| class CoreAudioLayoutsUnitTest : public UnitTest | |||
| { | |||
| public: | |||
| CoreAudioLayoutsUnitTest() : UnitTest ("Core Audio Layout <-> JUCE channel layout conversion", "Audio") {} | |||
| void runTest() override | |||
| { | |||
| auto& knownTags = getAllKnownLayoutTags(); | |||
| { | |||
| // Check that all known tags defined in CoreAudio SDK version 10.12.4 are known to JUCE | |||
| // Include all defined tags even if there are duplicates as Apple will sometimes change | |||
| // definitions | |||
| beginTest ("All CA tags handled"); | |||
| for (auto tagEntry : knownTags) | |||
| { | |||
| auto labels = CoreAudioLayouts::fromCoreAudio (tagEntry.tag); | |||
| expect (! labels.isDiscreteLayout(), String ("Tag \"") + String (tagEntry.name) + "\" is not handled by JUCE"); | |||
| } | |||
| } | |||
| { | |||
| beginTest ("Number of speakers"); | |||
| for (auto tagEntry : knownTags) | |||
| { | |||
| auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag); | |||
| expect (labels.size() == (tagEntry.tag & 0xffff), String ("Tag \"") + String (tagEntry.name) + "\" has incorrect channel count"); | |||
| } | |||
| } | |||
| { | |||
| beginTest ("No duplicate speaker"); | |||
| for (auto tagEntry : knownTags) | |||
| { | |||
| auto labels = CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag); | |||
| labels.sort(); | |||
| for (int i = 0; i < (labels.size() - 1); ++i) | |||
| expect (labels.getReference (i) != labels.getReference (i + 1), | |||
| String ("Tag \"") + String (tagEntry.name) + "\" has the same speaker twice"); | |||
| } | |||
| } | |||
| { | |||
| beginTest ("CA speaker list and juce layouts are consistent"); | |||
| for (auto tagEntry : knownTags) | |||
| expect (AudioChannelSet::channelSetWithChannels (CoreAudioLayouts::getSpeakerLayoutForCoreAudioTag (tagEntry.tag)) | |||
| == CoreAudioLayouts::fromCoreAudio (tagEntry.tag), | |||
| String ("Tag \"") + String (tagEntry.name) + "\" is not converted consistantly by JUCE"); | |||
| } | |||
| { | |||
| beginTest ("AudioChannelSet documentation is correct"); | |||
| for (auto tagEntry : knownTags) | |||
| { | |||
| if (tagEntry.equivalentChannelSet.isDisabled()) | |||
| continue; | |||
| expect (CoreAudioLayouts::fromCoreAudio (tagEntry.tag) == tagEntry.equivalentChannelSet, | |||
| String ("Documentation for tag \"") + String (tagEntry.name) + "\" is incorrect"); | |||
| } | |||
| } | |||
| { | |||
| beginTest ("CA tag reverse conversion"); | |||
| for (auto tagEntry : knownTags) | |||
| { | |||
| if (tagEntry.equivalentChannelSet.isDisabled()) | |||
| continue; | |||
| expect (CoreAudioLayouts::toCoreAudio (tagEntry.equivalentChannelSet) == tagEntry.tag, | |||
| String ("Incorrect reverse conversion for tag \"") + String (tagEntry.name) + "\""); | |||
| } | |||
| } | |||
| } | |||
| private: | |||
| struct CoreAudioChannelLayoutTag | |||
| { | |||
| AudioChannelLayoutTag tag; | |||
| const char* name; | |||
| AudioChannelSet equivalentChannelSet; /* referred to this in the AudioChannelSet documentation */ | |||
| }; | |||
| //============================================================================== | |||
| const Array<CoreAudioChannelLayoutTag>& getAllKnownLayoutTags() const | |||
| { | |||
| static CoreAudioChannelLayoutTag tags[] = { | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Mono, AudioChannelSet::mono()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Stereo, AudioChannelSet::stereo()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_StereoHeadphones), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MatrixStereo), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MidSide), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_XY), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Binaural), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Ambisonic_B_Format, AudioChannelSet::ambisonic()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Quadraphonic, AudioChannelSet::quadraphonic()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Pentagonal, AudioChannelSet::pentagonal()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Hexagonal, AudioChannelSet::hexagonal()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_Octagonal, AudioChannelSet::octagonal()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Cube), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_1_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_2_0), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_3_0_A, AudioChannelSet::createLCR()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_3_0_B), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_4_0_A, AudioChannelSet::createLCRS()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_4_0_B), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_A, AudioChannelSet::create5point0()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_C), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_0_D), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_A, AudioChannelSet::create5point1()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_C), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_5_1_D), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_6_1_A, AudioChannelSet::create6point1()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_A, AudioChannelSet::create7point1SDDS()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_B), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_MPEG_7_1_C, AudioChannelSet::create7point1()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_Emagic_Default_7_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_SMPTE_DTV), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_1_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_2_0), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_ITU_2_1, AudioChannelSet::createLRS()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_2_2), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_2), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_2_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_ITU_3_4_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_2), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_3), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_4), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_5), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_6), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_7), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_8), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_9), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_10), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_11), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_12), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_13), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_14), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_15), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_16), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_17), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_18), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_19), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DVD_20), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_4), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_5), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_6), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_8), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_5_0), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_AudioUnit_6_0, AudioChannelSet::create6point0()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_0, AudioChannelSet::create7point0()), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_0_Front, AudioChannelSet::create7point0SDDS()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_5_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_6_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AudioUnit_7_1_Front), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_3_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_Quadraphonic), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_4_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_5_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_5_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_6_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_6_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_1_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_7_1_C), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AAC_Octagonal), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_TMH_10_2_std), | |||
| // DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_TMH_10_2_full), no indicatoin on how to handle this tag | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_1_0_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_0_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_2_1_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_AC3_3_1_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC_6_0_A), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC_7_0_A), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_6_1_A), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_6_1_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_6_1_C), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_A), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_C), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_D), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_E), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_F), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_G), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_EAC3_7_1_H), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_3_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_4_1), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_DTS_6_0_A, AudioChannelSet::create6point0Music()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_0_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_0_C), | |||
| DEFINE_CHANNEL_LAYOUT_TAG_ENTRY (kAudioChannelLayoutTag_DTS_6_1_A, AudioChannelSet::create6point1Music()), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_C), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_7_0), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_7_1), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_0_A), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_0_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_1_A), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_8_1_B), | |||
| DEFINE_CHANNEL_LAYOUT_DFL_ENTRY (kAudioChannelLayoutTag_DTS_6_1_D) | |||
| }; | |||
| static Array<CoreAudioChannelLayoutTag> knownTags (tags, sizeof (tags) / sizeof (CoreAudioChannelLayoutTag)); | |||
| return knownTags; | |||
| } | |||
| }; | |||
| static CoreAudioLayoutsUnitTest coreAudioLayoutsUnitTest; | |||
| #endif | |||
| } // namespace juce | |||
| #endif | |||
| @@ -1,84 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #if JUCE_MAC || JUCE_IOS || DOXYGEN | |||
| //============================================================================== | |||
| /** | |||
| OSX and iOS only - This uses the AudioToolbox framework to read any audio | |||
| format that the system has a codec for. | |||
| This should be able to understand formats such as mp3, m4a, etc. | |||
| @see AudioFormat | |||
| */ | |||
| class JUCE_API CoreAudioFormat : public AudioFormat | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates a format object. */ | |||
| CoreAudioFormat(); | |||
| /** Destructor. */ | |||
| ~CoreAudioFormat(); | |||
| //============================================================================== | |||
| /** Metadata property name used when reading a caf file with a MIDI chunk. */ | |||
| static const char* const midiDataBase64; | |||
| /** Metadata property name used when reading a caf file with tempo information. */ | |||
| static const char* const tempo; | |||
| /** Metadata property name used when reading a caf file time signature information. */ | |||
| static const char* const timeSig; | |||
| /** Metadata property name used when reading a caf file time signature information. */ | |||
| static const char* const keySig; | |||
| //============================================================================== | |||
| Array<int> getPossibleSampleRates() override; | |||
| Array<int> getPossibleBitDepths() override; | |||
| bool canDoStereo() override; | |||
| bool canDoMono() override; | |||
| //============================================================================== | |||
| AudioFormatReader* createReaderFor (InputStream*, | |||
| bool deleteStreamIfOpeningFails) override; | |||
| AudioFormatWriter* createWriterFor (OutputStream*, | |||
| double sampleRateToUse, | |||
| unsigned int numberOfChannels, | |||
| int bitsPerSample, | |||
| const StringPairArray& metadataValues, | |||
| int qualityOptionIndex) override; | |||
| private: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioFormat) | |||
| }; | |||
| #endif | |||
| } // namespace juce | |||
| @@ -1,633 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #if JUCE_USE_FLAC | |||
| } | |||
| #if defined _WIN32 && !defined __CYGWIN__ | |||
| #include <io.h> | |||
| #else | |||
| #include <unistd.h> | |||
| #endif | |||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ | |||
| #include <sys/types.h> /* for off_t */ | |||
| #endif | |||
| #if HAVE_INTTYPES_H | |||
| #define __STDC_FORMAT_MACROS | |||
| #include <inttypes.h> | |||
| #endif | |||
| #if defined _MSC_VER || defined __MINGW32__ || defined __CYGWIN__ || defined __EMX__ | |||
| #include <io.h> /* for _setmode(), chmod() */ | |||
| #include <fcntl.h> /* for _O_BINARY */ | |||
| #else | |||
| #include <unistd.h> /* for chown(), unlink() */ | |||
| #endif | |||
| #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ | |||
| #if defined __BORLANDC__ | |||
| #include <utime.h> /* for utime() */ | |||
| #else | |||
| #include <sys/utime.h> /* for utime() */ | |||
| #endif | |||
| #else | |||
| #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */ | |||
| #include <utime.h> /* for utime() */ | |||
| #endif | |||
| #if defined _MSC_VER | |||
| #if _MSC_VER >= 1600 | |||
| #include <stdint.h> | |||
| #else | |||
| #include <limits.h> | |||
| #endif | |||
| #endif | |||
| #ifdef _WIN32 | |||
| #include <stdio.h> | |||
| #include <sys/stat.h> | |||
| #include <stdarg.h> | |||
| #include <windows.h> | |||
| #endif | |||
| #ifdef DEBUG | |||
| #include <assert.h> | |||
| #endif | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| namespace juce | |||
| { | |||
| namespace FlacNamespace | |||
| { | |||
| #if JUCE_INCLUDE_FLAC_CODE || ! defined (JUCE_INCLUDE_FLAC_CODE) | |||
| #undef VERSION | |||
| #define VERSION "1.3.1" | |||
| #define FLAC__NO_DLL 1 | |||
| #if JUCE_MSVC | |||
| #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4312 4505 4365 4005 4334 181 111) | |||
| #else | |||
| #define HAVE_LROUND 1 | |||
| #endif | |||
| #if JUCE_MAC | |||
| #define FLAC__SYS_DARWIN 1 | |||
| #endif | |||
| #ifndef SIZE_MAX | |||
| #define SIZE_MAX 0xffffffff | |||
| #endif | |||
| #if JUCE_CLANG | |||
| #pragma clang diagnostic push | |||
| #pragma clang diagnostic ignored "-Wconversion" | |||
| #pragma clang diagnostic ignored "-Wshadow" | |||
| #pragma clang diagnostic ignored "-Wdeprecated-register" | |||
| #elif JUCE_GCC && (__GNUC__ >= 7) | |||
| #pragma GCC diagnostic push | |||
| #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" | |||
| #endif | |||
| #if JUCE_INTEL | |||
| #if JUCE_32BIT | |||
| #define FLAC__CPU_IA32 1 | |||
| #endif | |||
| #if JUCE_64BIT | |||
| #define FLAC__CPU_X86_64 1 | |||
| #endif | |||
| #define FLAC__HAS_X86INTRIN 1 | |||
| #endif | |||
| #undef __STDC_LIMIT_MACROS | |||
| #define __STDC_LIMIT_MACROS 1 | |||
| #define flac_max jmax | |||
| #define flac_min jmin | |||
| #undef DEBUG // (some flac code dumps debug trace if the app defines this macro) | |||
| #include "flac/all.h" | |||
| #include "flac/libFLAC/bitmath.c" | |||
| #include "flac/libFLAC/bitreader.c" | |||
| #include "flac/libFLAC/bitwriter.c" | |||
| #include "flac/libFLAC/cpu.c" | |||
| #include "flac/libFLAC/crc.c" | |||
| #include "flac/libFLAC/fixed.c" | |||
| #include "flac/libFLAC/float.c" | |||
| #include "flac/libFLAC/format.c" | |||
| #include "flac/libFLAC/lpc_flac.c" | |||
| #include "flac/libFLAC/md5.c" | |||
| #include "flac/libFLAC/memory.c" | |||
| #include "flac/libFLAC/stream_decoder.c" | |||
| #include "flac/libFLAC/stream_encoder.c" | |||
| #include "flac/libFLAC/stream_encoder_framing.c" | |||
| #include "flac/libFLAC/window_flac.c" | |||
| #undef VERSION | |||
| #else | |||
| #include <FLAC/all.h> | |||
| #endif | |||
| #if JUCE_CLANG | |||
| #pragma clang diagnostic pop | |||
| #elif JUCE_GCC && (__GNUC__ >= 7) | |||
| #pragma GCC diagnostic pop | |||
| #endif | |||
| } | |||
| #undef max | |||
| #undef min | |||
| //============================================================================== | |||
| static const char* const flacFormatName = "FLAC file"; | |||
| //============================================================================== | |||
| class FlacReader : public AudioFormatReader | |||
| { | |||
| public: | |||
| FlacReader (InputStream* const in) | |||
| : AudioFormatReader (in, flacFormatName), | |||
| reservoirStart (0), | |||
| samplesInReservoir (0), | |||
| scanningForLength (false) | |||
| { | |||
| using namespace FlacNamespace; | |||
| lengthInSamples = 0; | |||
| decoder = FLAC__stream_decoder_new(); | |||
| ok = FLAC__stream_decoder_init_stream (decoder, | |||
| readCallback_, seekCallback_, tellCallback_, lengthCallback_, | |||
| eofCallback_, writeCallback_, metadataCallback_, errorCallback_, | |||
| this) == FLAC__STREAM_DECODER_INIT_STATUS_OK; | |||
| if (ok) | |||
| { | |||
| FLAC__stream_decoder_process_until_end_of_metadata (decoder); | |||
| if (lengthInSamples == 0 && sampleRate > 0) | |||
| { | |||
| // the length hasn't been stored in the metadata, so we'll need to | |||
| // work it out the length the hard way, by scanning the whole file.. | |||
| scanningForLength = true; | |||
| FLAC__stream_decoder_process_until_end_of_stream (decoder); | |||
| scanningForLength = false; | |||
| const int64 tempLength = lengthInSamples; | |||
| FLAC__stream_decoder_reset (decoder); | |||
| FLAC__stream_decoder_process_until_end_of_metadata (decoder); | |||
| lengthInSamples = tempLength; | |||
| } | |||
| } | |||
| } | |||
| ~FlacReader() | |||
| { | |||
| FlacNamespace::FLAC__stream_decoder_delete (decoder); | |||
| } | |||
| void useMetadata (const FlacNamespace::FLAC__StreamMetadata_StreamInfo& info) | |||
| { | |||
| sampleRate = info.sample_rate; | |||
| bitsPerSample = info.bits_per_sample; | |||
| lengthInSamples = (unsigned int) info.total_samples; | |||
| numChannels = info.channels; | |||
| reservoir.setSize ((int) numChannels, 2 * (int) info.max_blocksize, false, false, true); | |||
| } | |||
| // returns the number of samples read | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) override | |||
| { | |||
| using namespace FlacNamespace; | |||
| if (! ok) | |||
| return false; | |||
| while (numSamples > 0) | |||
| { | |||
| if (startSampleInFile >= reservoirStart | |||
| && startSampleInFile < reservoirStart + samplesInReservoir) | |||
| { | |||
| const int num = (int) jmin ((int64) numSamples, | |||
| reservoirStart + samplesInReservoir - startSampleInFile); | |||
| jassert (num > 0); | |||
| for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;) | |||
| if (destSamples[i] != nullptr) | |||
| memcpy (destSamples[i] + startOffsetInDestBuffer, | |||
| reservoir.getReadPointer (i, (int) (startSampleInFile - reservoirStart)), | |||
| sizeof (int) * (size_t) num); | |||
| startOffsetInDestBuffer += num; | |||
| startSampleInFile += num; | |||
| numSamples -= num; | |||
| } | |||
| else | |||
| { | |||
| if (startSampleInFile >= (int) lengthInSamples) | |||
| { | |||
| samplesInReservoir = 0; | |||
| } | |||
| else if (startSampleInFile < reservoirStart | |||
| || startSampleInFile > reservoirStart + jmax (samplesInReservoir, 511)) | |||
| { | |||
| // had some problems with flac crashing if the read pos is aligned more | |||
| // accurately than this. Probably fixed in newer versions of the library, though. | |||
| reservoirStart = (int) (startSampleInFile & ~511); | |||
| samplesInReservoir = 0; | |||
| FLAC__stream_decoder_seek_absolute (decoder, (FLAC__uint64) reservoirStart); | |||
| } | |||
| else | |||
| { | |||
| reservoirStart += samplesInReservoir; | |||
| samplesInReservoir = 0; | |||
| FLAC__stream_decoder_process_single (decoder); | |||
| } | |||
| if (samplesInReservoir == 0) | |||
| break; | |||
| } | |||
| } | |||
| if (numSamples > 0) | |||
| { | |||
| for (int i = numDestChannels; --i >= 0;) | |||
| if (destSamples[i] != nullptr) | |||
| zeromem (destSamples[i] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples); | |||
| } | |||
| return true; | |||
| } | |||
| void useSamples (const FlacNamespace::FLAC__int32* const buffer[], int numSamples) | |||
| { | |||
| if (scanningForLength) | |||
| { | |||
| lengthInSamples += numSamples; | |||
| } | |||
| else | |||
| { | |||
| if (numSamples > reservoir.getNumSamples()) | |||
| reservoir.setSize ((int) numChannels, numSamples, false, false, true); | |||
| const unsigned int bitsToShift = 32 - bitsPerSample; | |||
| for (int i = 0; i < (int) numChannels; ++i) | |||
| { | |||
| const FlacNamespace::FLAC__int32* src = buffer[i]; | |||
| int n = i; | |||
| while (src == 0 && n > 0) | |||
| src = buffer [--n]; | |||
| if (src != nullptr) | |||
| { | |||
| int* const dest = reinterpret_cast<int*> (reservoir.getWritePointer(i)); | |||
| for (int j = 0; j < numSamples; ++j) | |||
| dest[j] = src[j] << bitsToShift; | |||
| } | |||
| } | |||
| samplesInReservoir = numSamples; | |||
| } | |||
| } | |||
| //============================================================================== | |||
| static FlacNamespace::FLAC__StreamDecoderReadStatus readCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__byte buffer[], size_t* bytes, void* client_data) | |||
| { | |||
| using namespace FlacNamespace; | |||
| *bytes = (size_t) static_cast<const FlacReader*> (client_data)->input->read (buffer, (int) *bytes); | |||
| return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; | |||
| } | |||
| static FlacNamespace::FLAC__StreamDecoderSeekStatus seekCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64 absolute_byte_offset, void* client_data) | |||
| { | |||
| using namespace FlacNamespace; | |||
| static_cast<const FlacReader*> (client_data)->input->setPosition ((int) absolute_byte_offset); | |||
| return FLAC__STREAM_DECODER_SEEK_STATUS_OK; | |||
| } | |||
| static FlacNamespace::FLAC__StreamDecoderTellStatus tellCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data) | |||
| { | |||
| using namespace FlacNamespace; | |||
| *absolute_byte_offset = (uint64) static_cast<const FlacReader*> (client_data)->input->getPosition(); | |||
| return FLAC__STREAM_DECODER_TELL_STATUS_OK; | |||
| } | |||
| static FlacNamespace::FLAC__StreamDecoderLengthStatus lengthCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__uint64* stream_length, void* client_data) | |||
| { | |||
| using namespace FlacNamespace; | |||
| *stream_length = (uint64) static_cast<const FlacReader*> (client_data)->input->getTotalLength(); | |||
| return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; | |||
| } | |||
| static FlacNamespace::FLAC__bool eofCallback_ (const FlacNamespace::FLAC__StreamDecoder*, void* client_data) | |||
| { | |||
| return static_cast<const FlacReader*> (client_data)->input->isExhausted(); | |||
| } | |||
| static FlacNamespace::FLAC__StreamDecoderWriteStatus writeCallback_ (const FlacNamespace::FLAC__StreamDecoder*, | |||
| const FlacNamespace::FLAC__Frame* frame, | |||
| const FlacNamespace::FLAC__int32* const buffer[], | |||
| void* client_data) | |||
| { | |||
| using namespace FlacNamespace; | |||
| static_cast<FlacReader*> (client_data)->useSamples (buffer, (int) frame->header.blocksize); | |||
| return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; | |||
| } | |||
| static void metadataCallback_ (const FlacNamespace::FLAC__StreamDecoder*, | |||
| const FlacNamespace::FLAC__StreamMetadata* metadata, | |||
| void* client_data) | |||
| { | |||
| static_cast<FlacReader*> (client_data)->useMetadata (metadata->data.stream_info); | |||
| } | |||
| static void errorCallback_ (const FlacNamespace::FLAC__StreamDecoder*, FlacNamespace::FLAC__StreamDecoderErrorStatus, void*) | |||
| { | |||
| } | |||
| private: | |||
| FlacNamespace::FLAC__StreamDecoder* decoder; | |||
| AudioSampleBuffer reservoir; | |||
| int reservoirStart, samplesInReservoir; | |||
| bool ok, scanningForLength; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacReader) | |||
| }; | |||
| //============================================================================== | |||
| class FlacWriter : public AudioFormatWriter | |||
| { | |||
| public: | |||
| FlacWriter (OutputStream* const out, double rate, uint32 numChans, uint32 bits, int qualityOptionIndex) | |||
| : AudioFormatWriter (out, flacFormatName, rate, numChans, bits), | |||
| streamStartPos (output != nullptr ? jmax (output->getPosition(), 0ll) : 0ll) | |||
| { | |||
| using namespace FlacNamespace; | |||
| encoder = FLAC__stream_encoder_new(); | |||
| if (qualityOptionIndex > 0) | |||
| FLAC__stream_encoder_set_compression_level (encoder, (uint32) jmin (8, qualityOptionIndex)); | |||
| FLAC__stream_encoder_set_do_mid_side_stereo (encoder, numChannels == 2); | |||
| FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, numChannels == 2); | |||
| FLAC__stream_encoder_set_channels (encoder, numChannels); | |||
| FLAC__stream_encoder_set_bits_per_sample (encoder, jmin ((unsigned int) 24, bitsPerSample)); | |||
| FLAC__stream_encoder_set_sample_rate (encoder, (unsigned int) sampleRate); | |||
| FLAC__stream_encoder_set_blocksize (encoder, 0); | |||
| FLAC__stream_encoder_set_do_escape_coding (encoder, true); | |||
| ok = FLAC__stream_encoder_init_stream (encoder, | |||
| encodeWriteCallback, encodeSeekCallback, | |||
| encodeTellCallback, encodeMetadataCallback, | |||
| this) == FLAC__STREAM_ENCODER_INIT_STATUS_OK; | |||
| } | |||
| ~FlacWriter() | |||
| { | |||
| if (ok) | |||
| { | |||
| FlacNamespace::FLAC__stream_encoder_finish (encoder); | |||
| output->flush(); | |||
| } | |||
| else | |||
| { | |||
| output = nullptr; // to stop the base class deleting this, as it needs to be returned | |||
| // to the caller of createWriter() | |||
| } | |||
| FlacNamespace::FLAC__stream_encoder_delete (encoder); | |||
| } | |||
| //============================================================================== | |||
| bool write (const int** samplesToWrite, int numSamples) override | |||
| { | |||
| using namespace FlacNamespace; | |||
| if (! ok) | |||
| return false; | |||
| HeapBlock<int*> channels; | |||
| HeapBlock<int> temp; | |||
| const int bitsToShift = 32 - (int) bitsPerSample; | |||
| if (bitsToShift > 0) | |||
| { | |||
| temp.malloc (numChannels * (size_t) numSamples); | |||
| channels.calloc (numChannels + 1); | |||
| for (unsigned int i = 0; i < numChannels; ++i) | |||
| { | |||
| if (samplesToWrite[i] == nullptr) | |||
| break; | |||
| int* const destData = temp.get() + i * (size_t) numSamples; | |||
| channels[i] = destData; | |||
| for (int j = 0; j < numSamples; ++j) | |||
| destData[j] = (samplesToWrite[i][j] >> bitsToShift); | |||
| } | |||
| samplesToWrite = const_cast<const int**> (channels.get()); | |||
| } | |||
| return FLAC__stream_encoder_process (encoder, (const FLAC__int32**) samplesToWrite, (unsigned) numSamples) != 0; | |||
| } | |||
| bool writeData (const void* const data, const int size) const | |||
| { | |||
| return output->write (data, (size_t) size); | |||
| } | |||
| static void packUint32 (FlacNamespace::FLAC__uint32 val, FlacNamespace::FLAC__byte* b, const int bytes) | |||
| { | |||
| b += bytes; | |||
| for (int i = 0; i < bytes; ++i) | |||
| { | |||
| *(--b) = (FlacNamespace::FLAC__byte) (val & 0xff); | |||
| val >>= 8; | |||
| } | |||
| } | |||
| void writeMetaData (const FlacNamespace::FLAC__StreamMetadata* metadata) | |||
| { | |||
| using namespace FlacNamespace; | |||
| const FLAC__StreamMetadata_StreamInfo& info = metadata->data.stream_info; | |||
| unsigned char buffer [FLAC__STREAM_METADATA_STREAMINFO_LENGTH]; | |||
| const unsigned int channelsMinus1 = info.channels - 1; | |||
| const unsigned int bitsMinus1 = info.bits_per_sample - 1; | |||
| packUint32 (info.min_blocksize, buffer, 2); | |||
| packUint32 (info.max_blocksize, buffer + 2, 2); | |||
| packUint32 (info.min_framesize, buffer + 4, 3); | |||
| packUint32 (info.max_framesize, buffer + 7, 3); | |||
| buffer[10] = (uint8) ((info.sample_rate >> 12) & 0xff); | |||
| buffer[11] = (uint8) ((info.sample_rate >> 4) & 0xff); | |||
| buffer[12] = (uint8) (((info.sample_rate & 0x0f) << 4) | (channelsMinus1 << 1) | (bitsMinus1 >> 4)); | |||
| buffer[13] = (FLAC__byte) (((bitsMinus1 & 0x0f) << 4) | (unsigned int) ((info.total_samples >> 32) & 0x0f)); | |||
| packUint32 ((FLAC__uint32) info.total_samples, buffer + 14, 4); | |||
| memcpy (buffer + 18, info.md5sum, 16); | |||
| const bool seekOk = output->setPosition (streamStartPos + 4); | |||
| ignoreUnused (seekOk); | |||
| // if this fails, you've given it an output stream that can't seek! It needs | |||
| // to be able to seek back to write the header | |||
| jassert (seekOk); | |||
| output->writeIntBigEndian (FLAC__STREAM_METADATA_STREAMINFO_LENGTH); | |||
| output->write (buffer, FLAC__STREAM_METADATA_STREAMINFO_LENGTH); | |||
| } | |||
| //============================================================================== | |||
| static FlacNamespace::FLAC__StreamEncoderWriteStatus encodeWriteCallback (const FlacNamespace::FLAC__StreamEncoder*, | |||
| const FlacNamespace::FLAC__byte buffer[], | |||
| size_t bytes, | |||
| unsigned int /*samples*/, | |||
| unsigned int /*current_frame*/, | |||
| void* client_data) | |||
| { | |||
| using namespace FlacNamespace; | |||
| return static_cast<FlacWriter*> (client_data)->writeData (buffer, (int) bytes) | |||
| ? FLAC__STREAM_ENCODER_WRITE_STATUS_OK | |||
| : FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | |||
| } | |||
| static FlacNamespace::FLAC__StreamEncoderSeekStatus encodeSeekCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64, void*) | |||
| { | |||
| using namespace FlacNamespace; | |||
| return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED; | |||
| } | |||
| static FlacNamespace::FLAC__StreamEncoderTellStatus encodeTellCallback (const FlacNamespace::FLAC__StreamEncoder*, FlacNamespace::FLAC__uint64* absolute_byte_offset, void* client_data) | |||
| { | |||
| using namespace FlacNamespace; | |||
| if (client_data == nullptr) | |||
| return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED; | |||
| *absolute_byte_offset = (FLAC__uint64) static_cast<FlacWriter*> (client_data)->output->getPosition(); | |||
| return FLAC__STREAM_ENCODER_TELL_STATUS_OK; | |||
| } | |||
| static void encodeMetadataCallback (const FlacNamespace::FLAC__StreamEncoder*, const FlacNamespace::FLAC__StreamMetadata* metadata, void* client_data) | |||
| { | |||
| static_cast<FlacWriter*> (client_data)->writeMetaData (metadata); | |||
| } | |||
| bool ok; | |||
| private: | |||
| FlacNamespace::FLAC__StreamEncoder* encoder; | |||
| int64 streamStartPos; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacWriter) | |||
| }; | |||
| //============================================================================== | |||
| FlacAudioFormat::FlacAudioFormat() | |||
| : AudioFormat (flacFormatName, ".flac") | |||
| { | |||
| } | |||
| FlacAudioFormat::~FlacAudioFormat() | |||
| { | |||
| } | |||
| Array<int> FlacAudioFormat::getPossibleSampleRates() | |||
| { | |||
| const int rates[] = { 8000, 11025, 12000, 16000, 22050, 32000, 44100, 48000, | |||
| 88200, 96000, 176400, 192000, 352800, 384000 }; | |||
| return Array<int> (rates, numElementsInArray (rates)); | |||
| } | |||
| Array<int> FlacAudioFormat::getPossibleBitDepths() | |||
| { | |||
| const int depths[] = { 16, 24 }; | |||
| return Array<int> (depths, numElementsInArray (depths)); | |||
| } | |||
| bool FlacAudioFormat::canDoStereo() { return true; } | |||
| bool FlacAudioFormat::canDoMono() { return true; } | |||
| bool FlacAudioFormat::isCompressed() { return true; } | |||
| AudioFormatReader* FlacAudioFormat::createReaderFor (InputStream* in, const bool deleteStreamIfOpeningFails) | |||
| { | |||
| ScopedPointer<FlacReader> r (new FlacReader (in)); | |||
| if (r->sampleRate > 0) | |||
| return r.release(); | |||
| if (! deleteStreamIfOpeningFails) | |||
| r->input = nullptr; | |||
| return nullptr; | |||
| } | |||
| AudioFormatWriter* FlacAudioFormat::createWriterFor (OutputStream* out, | |||
| double sampleRate, | |||
| unsigned int numberOfChannels, | |||
| int bitsPerSample, | |||
| const StringPairArray& /*metadataValues*/, | |||
| int qualityOptionIndex) | |||
| { | |||
| if (out != nullptr && getPossibleBitDepths().contains (bitsPerSample)) | |||
| { | |||
| ScopedPointer<FlacWriter> w (new FlacWriter (out, sampleRate, numberOfChannels, | |||
| (uint32) bitsPerSample, qualityOptionIndex)); | |||
| if (w->ok) | |||
| return w.release(); | |||
| } | |||
| return nullptr; | |||
| } | |||
| StringArray FlacAudioFormat::getQualityOptions() | |||
| { | |||
| static const char* options[] = { "0 (Fastest)", "1", "2", "3", "4", "5 (Default)","6", "7", "8 (Highest quality)", 0 }; | |||
| return StringArray (options); | |||
| } | |||
| #endif | |||
| } // namespace juce | |||
| @@ -1,72 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #if JUCE_USE_FLAC || defined (DOXYGEN) | |||
| //============================================================================== | |||
| /** | |||
| Reads and writes the lossless-compression FLAC audio format. | |||
| To compile this, you'll need to set the JUCE_USE_FLAC flag. | |||
| @see AudioFormat | |||
| */ | |||
| class JUCE_API FlacAudioFormat : public AudioFormat | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| FlacAudioFormat(); | |||
| ~FlacAudioFormat(); | |||
| //============================================================================== | |||
| Array<int> getPossibleSampleRates() override; | |||
| Array<int> getPossibleBitDepths() override; | |||
| bool canDoStereo() override; | |||
| bool canDoMono() override; | |||
| bool isCompressed() override; | |||
| StringArray getQualityOptions() override; | |||
| //============================================================================== | |||
| AudioFormatReader* createReaderFor (InputStream* sourceStream, | |||
| bool deleteStreamIfOpeningFails) override; | |||
| AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, | |||
| double sampleRateToUse, | |||
| unsigned int numberOfChannels, | |||
| int bitsPerSample, | |||
| const StringPairArray& metadataValues, | |||
| int qualityOptionIndex) override; | |||
| private: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FlacAudioFormat) | |||
| }; | |||
| #endif | |||
| } // namespace juce | |||
| @@ -1,232 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #if JUCE_USE_LAME_AUDIO_FORMAT | |||
| class LAMEEncoderAudioFormat::Writer : public AudioFormatWriter | |||
| { | |||
| public: | |||
| Writer (OutputStream* destStream, const String& formatName, | |||
| const File& appFile, int vbr, int cbr, | |||
| double sampleRate, unsigned int numberOfChannels, | |||
| int bitsPerSample, const StringPairArray& metadata) | |||
| : AudioFormatWriter (destStream, formatName, sampleRate, | |||
| numberOfChannels, (unsigned int) bitsPerSample), | |||
| vbrLevel (vbr), cbrBitrate (cbr), | |||
| tempWav (".wav") | |||
| { | |||
| WavAudioFormat wavFormat; | |||
| if (FileOutputStream* out = tempWav.getFile().createOutputStream()) | |||
| { | |||
| writer = wavFormat.createWriterFor (out, sampleRate, numChannels, | |||
| bitsPerSample, metadata, 0); | |||
| args.add (appFile.getFullPathName()); | |||
| args.add ("--quiet"); | |||
| if (cbrBitrate == 0) | |||
| { | |||
| args.add ("--vbr-new"); | |||
| args.add ("-V"); | |||
| args.add (String (vbrLevel)); | |||
| } | |||
| else | |||
| { | |||
| args.add ("--cbr"); | |||
| args.add ("-b"); | |||
| args.add (String (cbrBitrate)); | |||
| } | |||
| addMetadataArg (metadata, "id3title", "--tt"); | |||
| addMetadataArg (metadata, "id3artist", "--ta"); | |||
| addMetadataArg (metadata, "id3album", "--tl"); | |||
| addMetadataArg (metadata, "id3comment", "--tc"); | |||
| addMetadataArg (metadata, "id3date", "--ty"); | |||
| addMetadataArg (metadata, "id3genre", "--tg"); | |||
| addMetadataArg (metadata, "id3trackNumber", "--tn"); | |||
| } | |||
| } | |||
| void addMetadataArg (const StringPairArray& metadata, const char* key, const char* lameFlag) | |||
| { | |||
| const String value (metadata.getValue (key, String())); | |||
| if (value.isNotEmpty()) | |||
| { | |||
| args.add (lameFlag); | |||
| args.add (value); | |||
| } | |||
| } | |||
| ~Writer() | |||
| { | |||
| if (writer != nullptr) | |||
| { | |||
| writer = nullptr; | |||
| if (! convertToMP3()) | |||
| convertToMP3(); // try again | |||
| } | |||
| } | |||
| bool write (const int** samplesToWrite, int numSamples) | |||
| { | |||
| return writer != nullptr && writer->write (samplesToWrite, numSamples); | |||
| } | |||
| private: | |||
| int vbrLevel, cbrBitrate; | |||
| TemporaryFile tempWav; | |||
| ScopedPointer<AudioFormatWriter> writer; | |||
| StringArray args; | |||
| bool runLameChildProcess (const TemporaryFile& tempMP3, const StringArray& processArgs) const | |||
| { | |||
| ChildProcess cp; | |||
| if (cp.start (processArgs)) | |||
| { | |||
| const String childOutput (cp.readAllProcessOutput()); | |||
| DBG (childOutput); ignoreUnused (childOutput); | |||
| cp.waitForProcessToFinish (10000); | |||
| return tempMP3.getFile().getSize() > 0; | |||
| } | |||
| return false; | |||
| } | |||
| bool convertToMP3() const | |||
| { | |||
| TemporaryFile tempMP3 (".mp3"); | |||
| StringArray args2 (args); | |||
| args2.add (tempWav.getFile().getFullPathName()); | |||
| args2.add (tempMP3.getFile().getFullPathName()); | |||
| DBG (args2.joinIntoString (" ")); | |||
| if (runLameChildProcess (tempMP3, args2)) | |||
| { | |||
| FileInputStream fis (tempMP3.getFile()); | |||
| if (fis.openedOk() && output->writeFromInputStream (fis, -1) > 0) | |||
| { | |||
| output->flush(); | |||
| return true; | |||
| } | |||
| } | |||
| return false; | |||
| } | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Writer) | |||
| }; | |||
| //============================================================================== | |||
| LAMEEncoderAudioFormat::LAMEEncoderAudioFormat (const File& lameApplication) | |||
| : AudioFormat ("MP3 file", ".mp3"), | |||
| lameApp (lameApplication) | |||
| { | |||
| } | |||
| LAMEEncoderAudioFormat::~LAMEEncoderAudioFormat() | |||
| { | |||
| } | |||
| bool LAMEEncoderAudioFormat::canHandleFile (const File&) | |||
| { | |||
| return false; | |||
| } | |||
| Array<int> LAMEEncoderAudioFormat::getPossibleSampleRates() | |||
| { | |||
| const int rates[] = { 32000, 44100, 48000, 0 }; | |||
| return Array<int> (rates); | |||
| } | |||
| Array<int> LAMEEncoderAudioFormat::getPossibleBitDepths() | |||
| { | |||
| const int depths[] = { 16, 0 }; | |||
| return Array<int> (depths); | |||
| } | |||
| bool LAMEEncoderAudioFormat::canDoStereo() { return true; } | |||
| bool LAMEEncoderAudioFormat::canDoMono() { return true; } | |||
| bool LAMEEncoderAudioFormat::isCompressed() { return true; } | |||
| StringArray LAMEEncoderAudioFormat::getQualityOptions() | |||
| { | |||
| static const char* vbrOptions[] = { "VBR quality 0 (best)", "VBR quality 1", "VBR quality 2", "VBR quality 3", | |||
| "VBR quality 4 (normal)", "VBR quality 5", "VBR quality 6", "VBR quality 7", | |||
| "VBR quality 8", "VBR quality 9 (smallest)", nullptr }; | |||
| StringArray opts (vbrOptions); | |||
| const int cbrRates[] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }; | |||
| for (int i = 0; i < numElementsInArray (cbrRates); ++i) | |||
| opts.add (String (cbrRates[i]) + " Kb/s CBR"); | |||
| return opts; | |||
| } | |||
| AudioFormatReader* LAMEEncoderAudioFormat::createReaderFor (InputStream*, const bool) | |||
| { | |||
| return nullptr; | |||
| } | |||
| AudioFormatWriter* LAMEEncoderAudioFormat::createWriterFor (OutputStream* streamToWriteTo, | |||
| double sampleRateToUse, | |||
| unsigned int numberOfChannels, | |||
| int bitsPerSample, | |||
| const StringPairArray& metadataValues, | |||
| int qualityOptionIndex) | |||
| { | |||
| if (streamToWriteTo == nullptr) | |||
| return nullptr; | |||
| int vbr = 4; | |||
| int cbr = 0; | |||
| const String qual (getQualityOptions() [qualityOptionIndex]); | |||
| if (qual.contains ("VBR")) | |||
| vbr = qual.retainCharacters ("0123456789").getIntValue(); | |||
| else | |||
| cbr = qual.getIntValue(); | |||
| return new Writer (streamToWriteTo, getFormatName(), lameApp, vbr, cbr, | |||
| sampleRateToUse, numberOfChannels, bitsPerSample, metadataValues); | |||
| } | |||
| #endif | |||
| } // namespace juce | |||
| @@ -1,78 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #if JUCE_USE_LAME_AUDIO_FORMAT || defined (DOXYGEN) | |||
| //============================================================================== | |||
| /** | |||
| An AudioFormat class which can use an installed version of the LAME mp3 | |||
| encoder to encode a file. | |||
| This format can't read MP3s, it just writes them. Internally, the | |||
| AudioFormatWriter object that is returned writes the incoming audio data | |||
| to a temporary WAV file, and then when the writer is deleted, it invokes | |||
| the LAME executable to convert the data to an MP3, whose data is then | |||
| piped into the original OutputStream that was used when first creating | |||
| the writer. | |||
| @see AudioFormat | |||
| */ | |||
| class JUCE_API LAMEEncoderAudioFormat : public AudioFormat | |||
| { | |||
| public: | |||
| /** Creates a LAMEEncoderAudioFormat that expects to find a working LAME | |||
| executable at the location given. | |||
| */ | |||
| LAMEEncoderAudioFormat (const File& lameExecutableToUse); | |||
| ~LAMEEncoderAudioFormat(); | |||
| bool canHandleFile (const File&); | |||
| Array<int> getPossibleSampleRates(); | |||
| Array<int> getPossibleBitDepths(); | |||
| bool canDoStereo(); | |||
| bool canDoMono(); | |||
| bool isCompressed(); | |||
| StringArray getQualityOptions(); | |||
| AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails); | |||
| AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse, | |||
| unsigned int numberOfChannels, int bitsPerSample, | |||
| const StringPairArray& metadataValues, int qualityOptionIndex); | |||
| private: | |||
| File lameApp; | |||
| class Writer; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LAMEEncoderAudioFormat) | |||
| }; | |||
| #endif | |||
| } // namespace juce | |||
| @@ -1,71 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #if JUCE_USE_MP3AUDIOFORMAT || DOXYGEN | |||
| //============================================================================== | |||
| /** | |||
| Software-based MP3 decoding format (doesn't currently provide an encoder). | |||
| IMPORTANT DISCLAIMER: By choosing to enable the JUCE_USE_MP3AUDIOFORMAT flag and | |||
| to compile the MP3 code into your software, you do so AT YOUR OWN RISK! By doing so, | |||
| you are agreeing that ROLI Ltd. is in no way responsible for any patent, copyright, | |||
| or other legal issues that you may suffer as a result. | |||
| The code in juce_MP3AudioFormat.cpp is NOT guaranteed to be free from infringements of 3rd-party | |||
| intellectual property. If you wish to use it, please seek your own independent advice about the | |||
| legality of doing so. If you are not willing to accept full responsibility for the consequences | |||
| of using this code, then do not enable the JUCE_USE_MP3AUDIOFORMAT setting. | |||
| */ | |||
| class MP3AudioFormat : public AudioFormat | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| MP3AudioFormat(); | |||
| ~MP3AudioFormat(); | |||
| //============================================================================== | |||
| Array<int> getPossibleSampleRates() override; | |||
| Array<int> getPossibleBitDepths() override; | |||
| bool canDoStereo() override; | |||
| bool canDoMono() override; | |||
| bool isCompressed() override; | |||
| StringArray getQualityOptions() override; | |||
| //============================================================================== | |||
| AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails) override; | |||
| AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse, | |||
| unsigned int numberOfChannels, int bitsPerSample, | |||
| const StringPairArray& metadataValues, int qualityOptionIndex) override; | |||
| }; | |||
| #endif | |||
| } // namespace juce | |||
| @@ -1,550 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #if JUCE_USE_OGGVORBIS | |||
| #if JUCE_MAC && ! defined (__MACOSX__) | |||
| #define __MACOSX__ 1 | |||
| #endif | |||
| namespace OggVorbisNamespace | |||
| { | |||
| #if JUCE_INCLUDE_OGGVORBIS_CODE || ! defined (JUCE_INCLUDE_OGGVORBIS_CODE) | |||
| #if JUCE_MSVC | |||
| #pragma warning (push) | |||
| #pragma warning (disable: 4267 4127 4244 4996 4100 4701 4702 4013 4133 4206 4305 4189 4706 4995 4365 4456 4457 4459) | |||
| #elif JUCE_CLANG | |||
| #pragma clang diagnostic push | |||
| #pragma clang diagnostic ignored "-Wconversion" | |||
| #pragma clang diagnostic ignored "-Wshadow" | |||
| #pragma clang diagnostic ignored "-Wdeprecated-register" | |||
| #elif JUCE_GCC | |||
| #pragma GCC diagnostic push | |||
| #pragma GCC diagnostic ignored "-Wshadow" | |||
| #if (__GNUC__ >= 6) | |||
| #pragma GCC diagnostic ignored "-Wmisleading-indentation" | |||
| #if (__GNUC__ >= 7) | |||
| #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" | |||
| #endif | |||
| #endif | |||
| #endif | |||
| #include "oggvorbis/vorbisenc.h" | |||
| #include "oggvorbis/codec.h" | |||
| #include "oggvorbis/vorbisfile.h" | |||
| #include "oggvorbis/bitwise.c" | |||
| #include "oggvorbis/framing.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/analysis.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/bitrate.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/block.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/codebook.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/envelope.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/floor0.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/floor1.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/info.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/lpc.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/lsp.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/mapping0.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/mdct.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/psy.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/registry.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/res0.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/sharedbook.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/smallft.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/synthesis.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/vorbisenc.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/vorbisfile.c" | |||
| #include "oggvorbis/libvorbis-1.3.2/lib/window.c" | |||
| #if JUCE_MSVC | |||
| #pragma warning (pop) | |||
| #elif JUCE_CLANG | |||
| #pragma clang diagnostic pop | |||
| #elif JUCE_GCC | |||
| #pragma GCC diagnostic pop | |||
| #endif | |||
| #else | |||
| #include <vorbis/vorbisenc.h> | |||
| #include <vorbis/codec.h> | |||
| #include <vorbis/vorbisfile.h> | |||
| #endif | |||
| } | |||
| #undef max | |||
| #undef min | |||
| //============================================================================== | |||
| static const char* const oggFormatName = "Ogg-Vorbis file"; | |||
| const char* const OggVorbisAudioFormat::encoderName = "encoder"; | |||
| const char* const OggVorbisAudioFormat::id3title = "id3title"; | |||
| const char* const OggVorbisAudioFormat::id3artist = "id3artist"; | |||
| const char* const OggVorbisAudioFormat::id3album = "id3album"; | |||
| const char* const OggVorbisAudioFormat::id3comment = "id3comment"; | |||
| const char* const OggVorbisAudioFormat::id3date = "id3date"; | |||
| const char* const OggVorbisAudioFormat::id3genre = "id3genre"; | |||
| const char* const OggVorbisAudioFormat::id3trackNumber = "id3trackNumber"; | |||
| //============================================================================== | |||
| class OggReader : public AudioFormatReader | |||
| { | |||
| public: | |||
| OggReader (InputStream* const inp) | |||
| : AudioFormatReader (inp, oggFormatName), | |||
| reservoirStart (0), | |||
| samplesInReservoir (0) | |||
| { | |||
| using namespace OggVorbisNamespace; | |||
| sampleRate = 0; | |||
| usesFloatingPointData = true; | |||
| callbacks.read_func = &oggReadCallback; | |||
| callbacks.seek_func = &oggSeekCallback; | |||
| callbacks.close_func = &oggCloseCallback; | |||
| callbacks.tell_func = &oggTellCallback; | |||
| const int err = ov_open_callbacks (input, &ovFile, 0, 0, callbacks); | |||
| if (err == 0) | |||
| { | |||
| vorbis_info* info = ov_info (&ovFile, -1); | |||
| vorbis_comment* const comment = ov_comment (&ovFile, -1); | |||
| addMetadataItem (comment, "ENCODER", OggVorbisAudioFormat::encoderName); | |||
| addMetadataItem (comment, "TITLE", OggVorbisAudioFormat::id3title); | |||
| addMetadataItem (comment, "ARTIST", OggVorbisAudioFormat::id3artist); | |||
| addMetadataItem (comment, "ALBUM", OggVorbisAudioFormat::id3album); | |||
| addMetadataItem (comment, "COMMENT", OggVorbisAudioFormat::id3comment); | |||
| addMetadataItem (comment, "DATE", OggVorbisAudioFormat::id3date); | |||
| addMetadataItem (comment, "GENRE", OggVorbisAudioFormat::id3genre); | |||
| addMetadataItem (comment, "TRACKNUMBER", OggVorbisAudioFormat::id3trackNumber); | |||
| lengthInSamples = (uint32) ov_pcm_total (&ovFile, -1); | |||
| numChannels = (unsigned int) info->channels; | |||
| bitsPerSample = 16; | |||
| sampleRate = info->rate; | |||
| reservoir.setSize ((int) numChannels, (int) jmin (lengthInSamples, (int64) 4096)); | |||
| } | |||
| } | |||
| ~OggReader() | |||
| { | |||
| OggVorbisNamespace::ov_clear (&ovFile); | |||
| } | |||
| void addMetadataItem (OggVorbisNamespace::vorbis_comment* comment, const char* name, const char* metadataName) | |||
| { | |||
| if (const char* value = vorbis_comment_query (comment, name, 0)) | |||
| metadataValues.set (metadataName, value); | |||
| } | |||
| //============================================================================== | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) override | |||
| { | |||
| while (numSamples > 0) | |||
| { | |||
| const int numAvailable = (int) (reservoirStart + samplesInReservoir - startSampleInFile); | |||
| if (startSampleInFile >= reservoirStart && numAvailable > 0) | |||
| { | |||
| // got a few samples overlapping, so use them before seeking.. | |||
| const int numToUse = jmin (numSamples, numAvailable); | |||
| for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;) | |||
| if (destSamples[i] != nullptr) | |||
| memcpy (destSamples[i] + startOffsetInDestBuffer, | |||
| reservoir.getReadPointer (i, (int) (startSampleInFile - reservoirStart)), | |||
| sizeof (float) * (size_t) numToUse); | |||
| startSampleInFile += numToUse; | |||
| numSamples -= numToUse; | |||
| startOffsetInDestBuffer += numToUse; | |||
| if (numSamples == 0) | |||
| break; | |||
| } | |||
| if (startSampleInFile < reservoirStart | |||
| || startSampleInFile + numSamples > reservoirStart + samplesInReservoir) | |||
| { | |||
| // buffer miss, so refill the reservoir | |||
| int bitStream = 0; | |||
| reservoirStart = jmax (0, (int) startSampleInFile); | |||
| samplesInReservoir = reservoir.getNumSamples(); | |||
| if (reservoirStart != (int) OggVorbisNamespace::ov_pcm_tell (&ovFile)) | |||
| OggVorbisNamespace::ov_pcm_seek (&ovFile, reservoirStart); | |||
| int offset = 0; | |||
| int numToRead = samplesInReservoir; | |||
| while (numToRead > 0) | |||
| { | |||
| float** dataIn = nullptr; | |||
| const long samps = OggVorbisNamespace::ov_read_float (&ovFile, &dataIn, numToRead, &bitStream); | |||
| if (samps <= 0) | |||
| break; | |||
| jassert (samps <= numToRead); | |||
| for (int i = jmin ((int) numChannels, reservoir.getNumChannels()); --i >= 0;) | |||
| memcpy (reservoir.getWritePointer (i, offset), dataIn[i], sizeof (float) * (size_t) samps); | |||
| numToRead -= samps; | |||
| offset += samps; | |||
| } | |||
| if (numToRead > 0) | |||
| reservoir.clear (offset, numToRead); | |||
| } | |||
| } | |||
| if (numSamples > 0) | |||
| { | |||
| for (int i = numDestChannels; --i >= 0;) | |||
| if (destSamples[i] != nullptr) | |||
| zeromem (destSamples[i] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples); | |||
| } | |||
| return true; | |||
| } | |||
| //============================================================================== | |||
| static size_t oggReadCallback (void* ptr, size_t size, size_t nmemb, void* datasource) | |||
| { | |||
| return (size_t) (static_cast<InputStream*> (datasource)->read (ptr, (int) (size * nmemb))) / size; | |||
| } | |||
| static int oggSeekCallback (void* datasource, OggVorbisNamespace::ogg_int64_t offset, int whence) | |||
| { | |||
| InputStream* const in = static_cast<InputStream*> (datasource); | |||
| if (whence == SEEK_CUR) | |||
| offset += in->getPosition(); | |||
| else if (whence == SEEK_END) | |||
| offset += in->getTotalLength(); | |||
| in->setPosition (offset); | |||
| return 0; | |||
| } | |||
| static int oggCloseCallback (void*) | |||
| { | |||
| return 0; | |||
| } | |||
| static long oggTellCallback (void* datasource) | |||
| { | |||
| return (long) static_cast<InputStream*> (datasource)->getPosition(); | |||
| } | |||
| private: | |||
| OggVorbisNamespace::OggVorbis_File ovFile; | |||
| OggVorbisNamespace::ov_callbacks callbacks; | |||
| AudioSampleBuffer reservoir; | |||
| int reservoirStart, samplesInReservoir; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OggReader) | |||
| }; | |||
| //============================================================================== | |||
| class OggWriter : public AudioFormatWriter | |||
| { | |||
| public: | |||
| OggWriter (OutputStream* const out, | |||
| const double sampleRate_, | |||
| const unsigned int numChannels_, | |||
| const unsigned int bitsPerSample_, | |||
| const int qualityIndex, | |||
| const StringPairArray& metadata) | |||
| : AudioFormatWriter (out, oggFormatName, sampleRate_, numChannels_, bitsPerSample_), | |||
| ok (false) | |||
| { | |||
| using namespace OggVorbisNamespace; | |||
| vorbis_info_init (&vi); | |||
| if (vorbis_encode_init_vbr (&vi, (int) numChannels_, (int) sampleRate_, | |||
| jlimit (0.0f, 1.0f, qualityIndex * 0.1f)) == 0) | |||
| { | |||
| vorbis_comment_init (&vc); | |||
| addMetadata (metadata, OggVorbisAudioFormat::encoderName, "ENCODER"); | |||
| addMetadata (metadata, OggVorbisAudioFormat::id3title, "TITLE"); | |||
| addMetadata (metadata, OggVorbisAudioFormat::id3artist, "ARTIST"); | |||
| addMetadata (metadata, OggVorbisAudioFormat::id3album, "ALBUM"); | |||
| addMetadata (metadata, OggVorbisAudioFormat::id3comment, "COMMENT"); | |||
| addMetadata (metadata, OggVorbisAudioFormat::id3date, "DATE"); | |||
| addMetadata (metadata, OggVorbisAudioFormat::id3genre, "GENRE"); | |||
| addMetadata (metadata, OggVorbisAudioFormat::id3trackNumber, "TRACKNUMBER"); | |||
| vorbis_analysis_init (&vd, &vi); | |||
| vorbis_block_init (&vd, &vb); | |||
| ogg_stream_init (&os, Random::getSystemRandom().nextInt()); | |||
| ogg_packet header; | |||
| ogg_packet header_comm; | |||
| ogg_packet header_code; | |||
| vorbis_analysis_headerout (&vd, &vc, &header, &header_comm, &header_code); | |||
| ogg_stream_packetin (&os, &header); | |||
| ogg_stream_packetin (&os, &header_comm); | |||
| ogg_stream_packetin (&os, &header_code); | |||
| for (;;) | |||
| { | |||
| if (ogg_stream_flush (&os, &og) == 0) | |||
| break; | |||
| output->write (og.header, (size_t) og.header_len); | |||
| output->write (og.body, (size_t) og.body_len); | |||
| } | |||
| ok = true; | |||
| } | |||
| } | |||
| ~OggWriter() | |||
| { | |||
| using namespace OggVorbisNamespace; | |||
| if (ok) | |||
| { | |||
| // write a zero-length packet to show ogg that we're finished.. | |||
| writeSamples (0); | |||
| ogg_stream_clear (&os); | |||
| vorbis_block_clear (&vb); | |||
| vorbis_dsp_clear (&vd); | |||
| vorbis_comment_clear (&vc); | |||
| vorbis_info_clear (&vi); | |||
| output->flush(); | |||
| } | |||
| else | |||
| { | |||
| vorbis_info_clear (&vi); | |||
| output = nullptr; // to stop the base class deleting this, as it needs to be returned | |||
| // to the caller of createWriter() | |||
| } | |||
| } | |||
| //============================================================================== | |||
| bool write (const int** samplesToWrite, int numSamples) override | |||
| { | |||
| if (ok) | |||
| { | |||
| using namespace OggVorbisNamespace; | |||
| if (numSamples > 0) | |||
| { | |||
| const double gain = 1.0 / 0x80000000u; | |||
| float** const vorbisBuffer = vorbis_analysis_buffer (&vd, numSamples); | |||
| for (int i = (int) numChannels; --i >= 0;) | |||
| { | |||
| float* const dst = vorbisBuffer[i]; | |||
| const int* const src = samplesToWrite [i]; | |||
| if (src != nullptr && dst != nullptr) | |||
| { | |||
| for (int j = 0; j < numSamples; ++j) | |||
| dst[j] = (float) (src[j] * gain); | |||
| } | |||
| } | |||
| } | |||
| writeSamples (numSamples); | |||
| } | |||
| return ok; | |||
| } | |||
| void writeSamples (int numSamples) | |||
| { | |||
| using namespace OggVorbisNamespace; | |||
| vorbis_analysis_wrote (&vd, numSamples); | |||
| while (vorbis_analysis_blockout (&vd, &vb) == 1) | |||
| { | |||
| vorbis_analysis (&vb, 0); | |||
| vorbis_bitrate_addblock (&vb); | |||
| while (vorbis_bitrate_flushpacket (&vd, &op)) | |||
| { | |||
| ogg_stream_packetin (&os, &op); | |||
| for (;;) | |||
| { | |||
| if (ogg_stream_pageout (&os, &og) == 0) | |||
| break; | |||
| output->write (og.header, (size_t) og.header_len); | |||
| output->write (og.body, (size_t) og.body_len); | |||
| if (ogg_page_eos (&og)) | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| bool ok; | |||
| private: | |||
| OggVorbisNamespace::ogg_stream_state os; | |||
| OggVorbisNamespace::ogg_page og; | |||
| OggVorbisNamespace::ogg_packet op; | |||
| OggVorbisNamespace::vorbis_info vi; | |||
| OggVorbisNamespace::vorbis_comment vc; | |||
| OggVorbisNamespace::vorbis_dsp_state vd; | |||
| OggVorbisNamespace::vorbis_block vb; | |||
| void addMetadata (const StringPairArray& metadata, const char* name, const char* vorbisName) | |||
| { | |||
| const String s (metadata [name]); | |||
| if (s.isNotEmpty()) | |||
| vorbis_comment_add_tag (&vc, vorbisName, const_cast<char*> (s.toRawUTF8())); | |||
| } | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OggWriter) | |||
| }; | |||
| //============================================================================== | |||
| OggVorbisAudioFormat::OggVorbisAudioFormat() : AudioFormat (oggFormatName, ".ogg") | |||
| { | |||
| } | |||
| OggVorbisAudioFormat::~OggVorbisAudioFormat() | |||
| { | |||
| } | |||
| Array<int> OggVorbisAudioFormat::getPossibleSampleRates() | |||
| { | |||
| const int rates[] = { 8000, 11025, 12000, 16000, 22050, 32000, | |||
| 44100, 48000, 88200, 96000, 176400, 192000 }; | |||
| return Array<int> (rates, numElementsInArray (rates)); | |||
| } | |||
| Array<int> OggVorbisAudioFormat::getPossibleBitDepths() | |||
| { | |||
| const int depths[] = { 32 }; | |||
| return Array<int> (depths, numElementsInArray (depths)); | |||
| } | |||
| bool OggVorbisAudioFormat::canDoStereo() { return true; } | |||
| bool OggVorbisAudioFormat::canDoMono() { return true; } | |||
| bool OggVorbisAudioFormat::isCompressed() { return true; } | |||
| AudioFormatReader* OggVorbisAudioFormat::createReaderFor (InputStream* in, const bool deleteStreamIfOpeningFails) | |||
| { | |||
| ScopedPointer<OggReader> r (new OggReader (in)); | |||
| if (r->sampleRate > 0) | |||
| return r.release(); | |||
| if (! deleteStreamIfOpeningFails) | |||
| r->input = nullptr; | |||
| return nullptr; | |||
| } | |||
| AudioFormatWriter* OggVorbisAudioFormat::createWriterFor (OutputStream* out, | |||
| double sampleRate, | |||
| unsigned int numChannels, | |||
| int bitsPerSample, | |||
| const StringPairArray& metadataValues, | |||
| int qualityOptionIndex) | |||
| { | |||
| if (out == nullptr) | |||
| return nullptr; | |||
| ScopedPointer<OggWriter> w (new OggWriter (out, sampleRate, numChannels, | |||
| (unsigned int) bitsPerSample, | |||
| qualityOptionIndex, metadataValues)); | |||
| return w->ok ? w.release() : nullptr; | |||
| } | |||
| StringArray OggVorbisAudioFormat::getQualityOptions() | |||
| { | |||
| static const char* options[] = { "64 kbps", "80 kbps", "96 kbps", "112 kbps", "128 kbps", "160 kbps", | |||
| "192 kbps", "224 kbps", "256 kbps", "320 kbps", "500 kbps", 0 }; | |||
| return StringArray (options); | |||
| } | |||
| int OggVorbisAudioFormat::estimateOggFileQuality (const File& source) | |||
| { | |||
| if (FileInputStream* const in = source.createInputStream()) | |||
| { | |||
| ScopedPointer<AudioFormatReader> r (createReaderFor (in, true)); | |||
| if (r != nullptr) | |||
| { | |||
| const double lengthSecs = r->lengthInSamples / r->sampleRate; | |||
| const int approxBitsPerSecond = (int) (source.getSize() * 8 / lengthSecs); | |||
| const StringArray qualities (getQualityOptions()); | |||
| int bestIndex = 0; | |||
| int bestDiff = 10000; | |||
| for (int i = qualities.size(); --i >= 0;) | |||
| { | |||
| const int diff = std::abs (qualities[i].getIntValue() - approxBitsPerSecond); | |||
| if (diff < bestDiff) | |||
| { | |||
| bestDiff = diff; | |||
| bestIndex = i; | |||
| } | |||
| } | |||
| return bestIndex; | |||
| } | |||
| } | |||
| return 0; | |||
| } | |||
| #endif | |||
| } // namespace juce | |||
| @@ -1,100 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #if JUCE_USE_OGGVORBIS || defined (DOXYGEN) | |||
| //============================================================================== | |||
| /** | |||
| Reads and writes the Ogg-Vorbis audio format. | |||
| To compile this, you'll need to set the JUCE_USE_OGGVORBIS flag. | |||
| @see AudioFormat, | |||
| */ | |||
| class JUCE_API OggVorbisAudioFormat : public AudioFormat | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| OggVorbisAudioFormat(); | |||
| ~OggVorbisAudioFormat(); | |||
| //============================================================================== | |||
| Array<int> getPossibleSampleRates() override; | |||
| Array<int> getPossibleBitDepths() override; | |||
| bool canDoStereo() override; | |||
| bool canDoMono() override; | |||
| bool isCompressed() override; | |||
| StringArray getQualityOptions() override; | |||
| //============================================================================== | |||
| /** Tries to estimate the quality level of an ogg file based on its size. | |||
| If it can't read the file for some reason, this will just return 1 (medium quality), | |||
| otherwise it will return the approximate quality setting that would have been used | |||
| to create the file. | |||
| @see getQualityOptions | |||
| */ | |||
| int estimateOggFileQuality (const File& source); | |||
| //============================================================================== | |||
| /** Metadata property name used by the Ogg writer - if you set a string for this | |||
| value, it will be written into the ogg file as the name of the encoder app. | |||
| @see createWriterFor | |||
| */ | |||
| static const char* const encoderName; | |||
| static const char* const id3title; /**< Metadata key for setting an ID3 title. */ | |||
| static const char* const id3artist; /**< Metadata key for setting an ID3 artist name. */ | |||
| static const char* const id3album; /**< Metadata key for setting an ID3 album. */ | |||
| static const char* const id3comment; /**< Metadata key for setting an ID3 comment. */ | |||
| static const char* const id3date; /**< Metadata key for setting an ID3 date. */ | |||
| static const char* const id3genre; /**< Metadata key for setting an ID3 genre. */ | |||
| static const char* const id3trackNumber; /**< Metadata key for setting an ID3 track number. */ | |||
| //============================================================================== | |||
| AudioFormatReader* createReaderFor (InputStream* sourceStream, | |||
| bool deleteStreamIfOpeningFails) override; | |||
| AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, | |||
| double sampleRateToUse, | |||
| unsigned int numberOfChannels, | |||
| int bitsPerSample, | |||
| const StringPairArray& metadataValues, | |||
| int qualityOptionIndex) override; | |||
| private: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OggVorbisAudioFormat) | |||
| }; | |||
| #endif | |||
| } // namespace juce | |||
| @@ -1,225 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| //============================================================================== | |||
| /** | |||
| Reads and Writes WAV format audio files. | |||
| @see AudioFormat | |||
| */ | |||
| class JUCE_API WavAudioFormat : public AudioFormat | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| /** Creates a format object. */ | |||
| WavAudioFormat(); | |||
| /** Destructor. */ | |||
| ~WavAudioFormat(); | |||
| //============================================================================== | |||
| // BWAV chunk properties: | |||
| static const char* const bwavDescription; /**< Metadata property name used in BWAV chunks. */ | |||
| static const char* const bwavOriginator; /**< Metadata property name used in BWAV chunks. */ | |||
| static const char* const bwavOriginatorRef; /**< Metadata property name used in BWAV chunks. */ | |||
| static const char* const bwavOriginationDate; /**< Metadata property name used in BWAV chunks. The format should be: yyyy-mm-dd */ | |||
| static const char* const bwavOriginationTime; /**< Metadata property name used in BWAV chunks. The format should be: format is: hh-mm-ss */ | |||
| static const char* const bwavCodingHistory; /**< Metadata property name used in BWAV chunks. */ | |||
| /** Metadata property name used in BWAV chunks. | |||
| This is the number of samples from the start of an edit that the | |||
| file is supposed to begin at. Seems like an obvious mistake to | |||
| only allow a file to occur in an edit once, but that's the way | |||
| it is.. | |||
| @see AudioFormatReader::metadataValues, createWriterFor | |||
| */ | |||
| static const char* const bwavTimeReference; | |||
| /** Utility function to fill out the appropriate metadata for a BWAV file. | |||
| This just makes it easier than using the property names directly, and it | |||
| fills out the time and date in the right format. | |||
| */ | |||
| static StringPairArray createBWAVMetadata (const String& description, | |||
| const String& originator, | |||
| const String& originatorRef, | |||
| Time dateAndTime, | |||
| int64 timeReferenceSamples, | |||
| const String& codingHistory); | |||
| //============================================================================== | |||
| // 'acid' chunk properties: | |||
| static const char* const acidOneShot; /**< Metadata property name used in acid chunks. */ | |||
| static const char* const acidRootSet; /**< Metadata property name used in acid chunks. */ | |||
| static const char* const acidStretch; /**< Metadata property name used in acid chunks. */ | |||
| static const char* const acidDiskBased; /**< Metadata property name used in acid chunks. */ | |||
| static const char* const acidizerFlag; /**< Metadata property name used in acid chunks. */ | |||
| static const char* const acidRootNote; /**< Metadata property name used in acid chunks. */ | |||
| static const char* const acidBeats; /**< Metadata property name used in acid chunks. */ | |||
| static const char* const acidDenominator; /**< Metadata property name used in acid chunks. */ | |||
| static const char* const acidNumerator; /**< Metadata property name used in acid chunks. */ | |||
| static const char* const acidTempo; /**< Metadata property name used in acid chunks. */ | |||
| //============================================================================== | |||
| // INFO chunk properties: | |||
| static const char* const riffInfoArchivalLocation; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoArtist; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoBaseURL; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoCinematographer; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoComment; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoComment2; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoComments; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoCommissioned; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoCopyright; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoCostumeDesigner; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoCountry; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoCropped; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoDateCreated; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoDateTimeOriginal; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoDefaultAudioStream; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoDimension; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoDirectory; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoDistributedBy; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoDotsPerInch; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoEditedBy; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoEighthLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoEncodedBy; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoEndTimecode; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoEngineer; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoFifthLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoFirstLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoFourthLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoGenre; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoKeywords; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoLength; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoLightness; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoLocation; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoLogoIconURL; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoLogoURL; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoMedium; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoMoreInfoBannerImage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoMoreInfoBannerURL; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoMoreInfoText; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoMoreInfoURL; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoMusicBy; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoNinthLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoNumberOfParts; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoOrganisation; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoPart; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoProducedBy; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoProductName; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoProductionDesigner; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoProductionStudio; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoRate; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoRated; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoRating; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoRippedBy; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSecondaryGenre; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSecondLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSeventhLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSharpness; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSixthLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSoftware; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSoundSchemeTitle; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSource; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSourceFrom; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoStarring_ISTR; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoStarring_STAR; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoStartTimecode; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoStatistics; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoSubject; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoTapeName; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoTechnician; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoThirdLanguage; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoTimeCode; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoTitle; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoTrackNo; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoTrackNumber; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoURL; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoVegasVersionMajor; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoVegasVersionMinor; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoVersion; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoWatermarkURL; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoWrittenBy; /**< Metadata property name used in INFO chunks. */ | |||
| static const char* const riffInfoYear; /**< Metadata property name used in INFO chunks. */ | |||
| //============================================================================== | |||
| /** Metadata property name used when reading an ISRC code from an AXML chunk. */ | |||
| static const char* const ISRC; | |||
| /** Metadata property name used when reading a WAV file with a Tracktion chunk. */ | |||
| static const char* const tracktionLoopInfo; | |||
| //============================================================================== | |||
| Array<int> getPossibleSampleRates() override; | |||
| Array<int> getPossibleBitDepths() override; | |||
| bool canDoStereo() override; | |||
| bool canDoMono() override; | |||
| bool isChannelLayoutSupported (const AudioChannelSet& channelSet) override; | |||
| //============================================================================== | |||
| AudioFormatReader* createReaderFor (InputStream* sourceStream, | |||
| bool deleteStreamIfOpeningFails) override; | |||
| MemoryMappedAudioFormatReader* createMemoryMappedReader (const File&) override; | |||
| MemoryMappedAudioFormatReader* createMemoryMappedReader (FileInputStream*) override; | |||
| AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, | |||
| double sampleRateToUse, | |||
| unsigned int numberOfChannels, | |||
| int bitsPerSample, | |||
| const StringPairArray& metadataValues, | |||
| int qualityOptionIndex) override; | |||
| AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, | |||
| double sampleRateToUse, | |||
| const AudioChannelSet& channelLayout, | |||
| int bitsPerSample, | |||
| const StringPairArray& metadataValues, | |||
| int qualityOptionIndex) override; | |||
| //============================================================================== | |||
| /** Utility function to replace the metadata in a wav file with a new set of values. | |||
| If possible, this cheats by overwriting just the metadata region of the file, rather | |||
| than by copying the whole file again. | |||
| */ | |||
| bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata); | |||
| private: | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavAudioFormat) | |||
| }; | |||
| } // namespace juce | |||
| @@ -1,360 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| namespace WindowsMediaCodec | |||
| { | |||
| class JuceIStream : public ComBaseClassHelper <IStream> | |||
| { | |||
| public: | |||
| JuceIStream (InputStream& in) noexcept | |||
| : ComBaseClassHelper <IStream> (0), source (in) | |||
| { | |||
| } | |||
| JUCE_COMRESULT Commit (DWORD) { return S_OK; } | |||
| JUCE_COMRESULT Write (const void*, ULONG, ULONG*) { return E_NOTIMPL; } | |||
| JUCE_COMRESULT Clone (IStream**) { return E_NOTIMPL; } | |||
| JUCE_COMRESULT SetSize (ULARGE_INTEGER) { return E_NOTIMPL; } | |||
| JUCE_COMRESULT Revert() { return E_NOTIMPL; } | |||
| JUCE_COMRESULT LockRegion (ULARGE_INTEGER, ULARGE_INTEGER, DWORD) { return E_NOTIMPL; } | |||
| JUCE_COMRESULT UnlockRegion (ULARGE_INTEGER, ULARGE_INTEGER, DWORD) { return E_NOTIMPL; } | |||
| JUCE_COMRESULT Read (void* dest, ULONG numBytes, ULONG* bytesRead) | |||
| { | |||
| const int numRead = source.read (dest, numBytes); | |||
| if (bytesRead != nullptr) | |||
| *bytesRead = numRead; | |||
| return (numRead == (int) numBytes) ? S_OK : S_FALSE; | |||
| } | |||
| JUCE_COMRESULT Seek (LARGE_INTEGER position, DWORD origin, ULARGE_INTEGER* resultPosition) | |||
| { | |||
| int64 newPos = (int64) position.QuadPart; | |||
| if (origin == STREAM_SEEK_CUR) | |||
| { | |||
| newPos += source.getPosition(); | |||
| } | |||
| else if (origin == STREAM_SEEK_END) | |||
| { | |||
| const int64 len = source.getTotalLength(); | |||
| if (len < 0) | |||
| return E_NOTIMPL; | |||
| newPos += len; | |||
| } | |||
| if (resultPosition != nullptr) | |||
| resultPosition->QuadPart = newPos; | |||
| return source.setPosition (newPos) ? S_OK : E_NOTIMPL; | |||
| } | |||
| JUCE_COMRESULT CopyTo (IStream* destStream, ULARGE_INTEGER numBytesToDo, | |||
| ULARGE_INTEGER* bytesRead, ULARGE_INTEGER* bytesWritten) | |||
| { | |||
| uint64 totalCopied = 0; | |||
| int64 numBytes = numBytesToDo.QuadPart; | |||
| while (numBytes > 0 && ! source.isExhausted()) | |||
| { | |||
| char buffer [1024]; | |||
| const int numToCopy = (int) jmin ((int64) sizeof (buffer), (int64) numBytes); | |||
| const int numRead = source.read (buffer, numToCopy); | |||
| if (numRead <= 0) | |||
| break; | |||
| destStream->Write (buffer, numRead, nullptr); | |||
| totalCopied += numRead; | |||
| } | |||
| if (bytesRead != nullptr) bytesRead->QuadPart = totalCopied; | |||
| if (bytesWritten != nullptr) bytesWritten->QuadPart = totalCopied; | |||
| return S_OK; | |||
| } | |||
| JUCE_COMRESULT Stat (STATSTG* stat, DWORD) | |||
| { | |||
| if (stat == nullptr) | |||
| return STG_E_INVALIDPOINTER; | |||
| zerostruct (*stat); | |||
| stat->type = STGTY_STREAM; | |||
| stat->cbSize.QuadPart = jmax ((int64) 0, source.getTotalLength()); | |||
| return S_OK; | |||
| } | |||
| private: | |||
| InputStream& source; | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JuceIStream) | |||
| }; | |||
| //============================================================================== | |||
| static const char* wmFormatName = "Windows Media"; | |||
| static const char* const extensions[] = { ".mp3", ".wmv", ".asf", ".wm", ".wma", 0 }; | |||
| //============================================================================== | |||
| class WMAudioReader : public AudioFormatReader | |||
| { | |||
| public: | |||
| WMAudioReader (InputStream* const input_) | |||
| : AudioFormatReader (input_, TRANS (wmFormatName)), | |||
| wmvCoreLib ("Wmvcore.dll") | |||
| { | |||
| JUCE_LOAD_WINAPI_FUNCTION (wmvCoreLib, WMCreateSyncReader, wmCreateSyncReader, | |||
| HRESULT, (IUnknown*, DWORD, IWMSyncReader**)) | |||
| if (wmCreateSyncReader != nullptr) | |||
| { | |||
| checkCoInitialiseCalled(); | |||
| HRESULT hr = wmCreateSyncReader (nullptr, WMT_RIGHT_PLAYBACK, wmSyncReader.resetAndGetPointerAddress()); | |||
| if (SUCCEEDED (hr)) | |||
| hr = wmSyncReader->OpenStream (new JuceIStream (*input)); | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| WORD streamNum = 1; | |||
| hr = wmSyncReader->GetStreamNumberForOutput (0, &streamNum); | |||
| hr = wmSyncReader->SetReadStreamSamples (streamNum, false); | |||
| scanFileForDetails(); | |||
| } | |||
| } | |||
| } | |||
| ~WMAudioReader() | |||
| { | |||
| if (wmSyncReader != nullptr) | |||
| wmSyncReader->Close(); | |||
| } | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) override | |||
| { | |||
| if (sampleRate <= 0) | |||
| return false; | |||
| checkCoInitialiseCalled(); | |||
| clearSamplesBeyondAvailableLength (destSamples, numDestChannels, startOffsetInDestBuffer, | |||
| startSampleInFile, numSamples, lengthInSamples); | |||
| const int stride = numChannels * sizeof (int16); | |||
| while (numSamples > 0) | |||
| { | |||
| if (! bufferedRange.contains (startSampleInFile)) | |||
| { | |||
| const bool hasJumped = (startSampleInFile != bufferedRange.getEnd()); | |||
| if (hasJumped) | |||
| wmSyncReader->SetRange ((QWORD) (startSampleInFile * 10000000 / (int64) sampleRate), 0); | |||
| ComSmartPtr<INSSBuffer> sampleBuffer; | |||
| QWORD sampleTime, duration; | |||
| DWORD flags, outputNum; | |||
| WORD streamNum; | |||
| HRESULT hr = wmSyncReader->GetNextSample (1, sampleBuffer.resetAndGetPointerAddress(), | |||
| &sampleTime, &duration, &flags, &outputNum, &streamNum); | |||
| if (sampleBuffer != nullptr) | |||
| { | |||
| BYTE* rawData = nullptr; | |||
| DWORD dataLength = 0; | |||
| hr = sampleBuffer->GetBufferAndLength (&rawData, &dataLength); | |||
| if (dataLength == 0) | |||
| return false; | |||
| if (hasJumped) | |||
| bufferedRange.setStart ((int64) ((sampleTime * (int64) sampleRate) / 10000000)); | |||
| else | |||
| bufferedRange.setStart (bufferedRange.getEnd()); // (because the positions returned often aren't continguous) | |||
| bufferedRange.setLength ((int64) (dataLength / stride)); | |||
| buffer.ensureSize ((int) dataLength); | |||
| memcpy (buffer.getData(), rawData, (size_t) dataLength); | |||
| } | |||
| else if (hr == NS_E_NO_MORE_SAMPLES) | |||
| { | |||
| bufferedRange.setStart (startSampleInFile); | |||
| bufferedRange.setLength (256); | |||
| buffer.ensureSize (256 * stride); | |||
| buffer.fillWith (0); | |||
| } | |||
| else | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| const int offsetInBuffer = (int) (startSampleInFile - bufferedRange.getStart()); | |||
| const int16* const rawData = static_cast<const int16*> (addBytesToPointer (buffer.getData(), offsetInBuffer * stride)); | |||
| const int numToDo = jmin (numSamples, (int) (bufferedRange.getLength() - offsetInBuffer)); | |||
| for (int i = 0; i < numDestChannels; ++i) | |||
| { | |||
| jassert (destSamples[i] != nullptr); | |||
| const int srcChan = jmin (i, (int) numChannels - 1); | |||
| const int16* src = rawData + srcChan; | |||
| int* const dst = destSamples[i] + startOffsetInDestBuffer; | |||
| for (int j = 0; j < numToDo; ++j) | |||
| { | |||
| dst[j] = ((uint32) *src) << 16; | |||
| src += numChannels; | |||
| } | |||
| } | |||
| startSampleInFile += numToDo; | |||
| startOffsetInDestBuffer += numToDo; | |||
| numSamples -= numToDo; | |||
| } | |||
| return true; | |||
| } | |||
| private: | |||
| DynamicLibrary wmvCoreLib; | |||
| ComSmartPtr<IWMSyncReader> wmSyncReader; | |||
| MemoryBlock buffer; | |||
| Range<int64> bufferedRange; | |||
| void checkCoInitialiseCalled() | |||
| { | |||
| CoInitialize (0); | |||
| } | |||
| void scanFileForDetails() | |||
| { | |||
| ComSmartPtr<IWMHeaderInfo> wmHeaderInfo; | |||
| HRESULT hr = wmSyncReader.QueryInterface (wmHeaderInfo); | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| QWORD lengthInNanoseconds = 0; | |||
| WORD lengthOfLength = sizeof (lengthInNanoseconds); | |||
| WORD streamNum = 0; | |||
| WMT_ATTR_DATATYPE wmAttrDataType; | |||
| hr = wmHeaderInfo->GetAttributeByName (&streamNum, L"Duration", &wmAttrDataType, | |||
| (BYTE*) &lengthInNanoseconds, &lengthOfLength); | |||
| ComSmartPtr<IWMProfile> wmProfile; | |||
| hr = wmSyncReader.QueryInterface (wmProfile); | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| ComSmartPtr<IWMStreamConfig> wmStreamConfig; | |||
| hr = wmProfile->GetStream (0, wmStreamConfig.resetAndGetPointerAddress()); | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| ComSmartPtr<IWMMediaProps> wmMediaProperties; | |||
| hr = wmStreamConfig.QueryInterface (wmMediaProperties); | |||
| if (SUCCEEDED (hr)) | |||
| { | |||
| DWORD sizeMediaType; | |||
| hr = wmMediaProperties->GetMediaType (0, &sizeMediaType); | |||
| HeapBlock<WM_MEDIA_TYPE> mediaType; | |||
| mediaType.malloc (sizeMediaType, 1); | |||
| hr = wmMediaProperties->GetMediaType (mediaType, &sizeMediaType); | |||
| if (mediaType->majortype == WMMEDIATYPE_Audio) | |||
| { | |||
| const WAVEFORMATEX* const inputFormat = reinterpret_cast<WAVEFORMATEX*> (mediaType->pbFormat); | |||
| sampleRate = inputFormat->nSamplesPerSec; | |||
| numChannels = inputFormat->nChannels; | |||
| bitsPerSample = inputFormat->wBitsPerSample != 0 ? inputFormat->wBitsPerSample : 16; | |||
| lengthInSamples = (lengthInNanoseconds * (int) sampleRate) / 10000000; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WMAudioReader) | |||
| }; | |||
| } | |||
| //============================================================================== | |||
| WindowsMediaAudioFormat::WindowsMediaAudioFormat() | |||
| : AudioFormat (TRANS (WindowsMediaCodec::wmFormatName), | |||
| StringArray (WindowsMediaCodec::extensions)) | |||
| { | |||
| } | |||
| WindowsMediaAudioFormat::~WindowsMediaAudioFormat() {} | |||
| Array<int> WindowsMediaAudioFormat::getPossibleSampleRates() { return Array<int>(); } | |||
| Array<int> WindowsMediaAudioFormat::getPossibleBitDepths() { return Array<int>(); } | |||
| bool WindowsMediaAudioFormat::canDoStereo() { return true; } | |||
| bool WindowsMediaAudioFormat::canDoMono() { return true; } | |||
| bool WindowsMediaAudioFormat::isCompressed() { return true; } | |||
| //============================================================================== | |||
| AudioFormatReader* WindowsMediaAudioFormat::createReaderFor (InputStream* sourceStream, bool deleteStreamIfOpeningFails) | |||
| { | |||
| ScopedPointer<WindowsMediaCodec::WMAudioReader> r (new WindowsMediaCodec::WMAudioReader (sourceStream)); | |||
| if (r->sampleRate > 0) | |||
| return r.release(); | |||
| if (! deleteStreamIfOpeningFails) | |||
| r->input = nullptr; | |||
| return nullptr; | |||
| } | |||
| AudioFormatWriter* WindowsMediaAudioFormat::createWriterFor (OutputStream* /*streamToWriteTo*/, double /*sampleRateToUse*/, | |||
| unsigned int /*numberOfChannels*/, int /*bitsPerSample*/, | |||
| const StringPairArray& /*metadataValues*/, int /*qualityOptionIndex*/) | |||
| { | |||
| jassertfalse; // not yet implemented! | |||
| return nullptr; | |||
| } | |||
| } // namespace juce | |||
| @@ -1,60 +0,0 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library. | |||
| Copyright (c) 2017 - ROLI Ltd. | |||
| JUCE is an open source library subject to commercial or open-source | |||
| licensing. | |||
| By using JUCE, you agree to the terms of both the JUCE 5 End-User License | |||
| Agreement and JUCE 5 Privacy Policy (both updated and effective as of the | |||
| 27th April 2017). | |||
| End User License Agreement: www.juce.com/juce-5-licence | |||
| Privacy Policy: www.juce.com/juce-5-privacy-policy | |||
| Or: You may also use this code under the terms of the GPL v3 (see | |||
| www.gnu.org/licenses). | |||
| JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER | |||
| EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE | |||
| DISCLAIMED. | |||
| ============================================================================== | |||
| */ | |||
| namespace juce | |||
| { | |||
| #if JUCE_WINDOWS || DOXYGEN | |||
| //============================================================================== | |||
| /** | |||
| Audio format which uses the Windows Media codecs (Windows only). | |||
| */ | |||
| class WindowsMediaAudioFormat : public AudioFormat | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| WindowsMediaAudioFormat(); | |||
| ~WindowsMediaAudioFormat(); | |||
| //============================================================================== | |||
| Array<int> getPossibleSampleRates() override; | |||
| Array<int> getPossibleBitDepths() override; | |||
| bool canDoStereo() override; | |||
| bool canDoMono() override; | |||
| bool isCompressed() override; | |||
| //============================================================================== | |||
| AudioFormatReader* createReaderFor (InputStream*, bool deleteStreamIfOpeningFails) override; | |||
| AudioFormatWriter* createWriterFor (OutputStream*, double sampleRateToUse, | |||
| unsigned int numberOfChannels, int bitsPerSample, | |||
| const StringPairArray& metadataValues, int qualityOptionIndex) override; | |||
| }; | |||
| #endif | |||
| } | |||
| @@ -1,47 +0,0 @@ | |||
| ===================================================================== | |||
| I've incorporated Ogg-Vorbis directly into the Juce codebase because it makes | |||
| things much easier than having to make all your builds link correctly to | |||
| the appropriate libraries on every different platform. | |||
| I've made minimal changes to the Ogg-Vorbis code - just tweaked a few include | |||
| paths to make it build smoothly, and added some headers to allow you to exclude | |||
| it from the build. | |||
| ===================================================================== | |||
| The following license is the BSD-style license that comes with the | |||
| Ogg-Vorbis distribution, and which applies just to the header files I've | |||
| included in this directory. For more info, and to get the rest of the | |||
| distribution, visit the Ogg-Vorbis homepage: www.vorbis.com | |||
| ===================================================================== | |||
| Copyright (c) 2002-2004 Xiph.org Foundation | |||
| Redistribution and use in source and binary forms, with or without | |||
| modification, are permitted provided that the following conditions | |||
| are met: | |||
| - Redistributions of source code must retain the above copyright | |||
| notice, this list of conditions and the following disclaimer. | |||
| - Redistributions in binary form must reproduce the above copyright | |||
| notice, this list of conditions and the following disclaimer in the | |||
| documentation and/or other materials provided with the distribution. | |||
| - Neither the name of the Xiph.org Foundation nor the names of its | |||
| contributors may be used to endorse or promote products derived from | |||
| this software without specific prior written permission. | |||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION | |||
| OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| @@ -1,788 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: packing variable sized words into an octet stream | |||
| last mod: $Id: bitwise.c,v 1.1 2007/06/07 17:48:18 jules_rms Exp $ | |||
| ********************************************************************/ | |||
| #ifdef JUCE_MSVC | |||
| #pragma warning (disable: 4456 4457 4459) | |||
| #endif | |||
| /* We're 'LSb' endian; if we write a word but read individual bits, | |||
| then we'll read the lsb first */ | |||
| #include <string.h> | |||
| #include <stdlib.h> | |||
| #include "ogg.h" | |||
| #define BUFFER_INCREMENT 256 | |||
| static const unsigned long mask[]= | |||
| {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, | |||
| 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, | |||
| 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, | |||
| 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, | |||
| 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, | |||
| 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, | |||
| 0x3fffffff,0x7fffffff,0xffffffff }; | |||
| static const unsigned int mask8B[]= | |||
| {0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; | |||
| void oggpack_writeinit(oggpack_buffer *b){ | |||
| memset(b,0,sizeof(*b)); | |||
| b->ptr=b->buffer=(unsigned char*) _ogg_malloc(BUFFER_INCREMENT); | |||
| b->buffer[0]='\0'; | |||
| b->storage=BUFFER_INCREMENT; | |||
| } | |||
| void oggpackB_writeinit(oggpack_buffer *b){ | |||
| oggpack_writeinit(b); | |||
| } | |||
| void oggpack_writetrunc(oggpack_buffer *b,long bits){ | |||
| long bytes=bits>>3; | |||
| bits-=bytes*8; | |||
| b->ptr=b->buffer+bytes; | |||
| b->endbit=bits; | |||
| b->endbyte=bytes; | |||
| *b->ptr&=mask[bits]; | |||
| } | |||
| void oggpackB_writetrunc(oggpack_buffer *b,long bits){ | |||
| long bytes=bits>>3; | |||
| bits-=bytes*8; | |||
| b->ptr=b->buffer+bytes; | |||
| b->endbit=bits; | |||
| b->endbyte=bytes; | |||
| *b->ptr&=mask8B[bits]; | |||
| } | |||
| /* Takes only up to 32 bits. */ | |||
| void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ | |||
| if(b->endbyte+4>=b->storage){ | |||
| b->buffer=(unsigned char*) _ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); | |||
| b->storage+=BUFFER_INCREMENT; | |||
| b->ptr=b->buffer+b->endbyte; | |||
| } | |||
| value&=mask[bits]; | |||
| bits+=b->endbit; | |||
| b->ptr[0]|=value<<b->endbit; | |||
| if(bits>=8){ | |||
| b->ptr[1]=(unsigned char)(value>>(8-b->endbit)); | |||
| if(bits>=16){ | |||
| b->ptr[2]=(unsigned char)(value>>(16-b->endbit)); | |||
| if(bits>=24){ | |||
| b->ptr[3]=(unsigned char)(value>>(24-b->endbit)); | |||
| if(bits>=32){ | |||
| if(b->endbit) | |||
| b->ptr[4]=(unsigned char)(value>>(32-b->endbit)); | |||
| else | |||
| b->ptr[4]=0; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| b->endbyte+=bits/8; | |||
| b->ptr+=bits/8; | |||
| b->endbit=bits&7; | |||
| } | |||
| /* Takes only up to 32 bits. */ | |||
| void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ | |||
| if(b->endbyte+4>=b->storage){ | |||
| b->buffer=(unsigned char*) _ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); | |||
| b->storage+=BUFFER_INCREMENT; | |||
| b->ptr=b->buffer+b->endbyte; | |||
| } | |||
| value=(value&mask[bits])<<(32-bits); | |||
| bits+=b->endbit; | |||
| b->ptr[0]|=value>>(24+b->endbit); | |||
| if(bits>=8){ | |||
| b->ptr[1]=(unsigned char)(value>>(16+b->endbit)); | |||
| if(bits>=16){ | |||
| b->ptr[2]=(unsigned char)(value>>(8+b->endbit)); | |||
| if(bits>=24){ | |||
| b->ptr[3]=(unsigned char)(value>>(b->endbit)); | |||
| if(bits>=32){ | |||
| if(b->endbit) | |||
| b->ptr[4]=(unsigned char)(value<<(8-b->endbit)); | |||
| else | |||
| b->ptr[4]=0; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| b->endbyte+=bits/8; | |||
| b->ptr+=bits/8; | |||
| b->endbit=bits&7; | |||
| } | |||
| void oggpack_writealign(oggpack_buffer *b){ | |||
| int bits=8-b->endbit; | |||
| if(bits<8) | |||
| oggpack_write(b,0,bits); | |||
| } | |||
| void oggpackB_writealign(oggpack_buffer *b){ | |||
| int bits=8-b->endbit; | |||
| if(bits<8) | |||
| oggpackB_write(b,0,bits); | |||
| } | |||
| static void oggpack_writecopy_helper(oggpack_buffer *b, | |||
| void *source, | |||
| long bits, | |||
| void (*w)(oggpack_buffer *, | |||
| unsigned long, | |||
| int), | |||
| int msb){ | |||
| unsigned char *ptr=(unsigned char *)source; | |||
| long bytes=bits/8; | |||
| bits-=bytes*8; | |||
| if(b->endbit){ | |||
| int i; | |||
| /* unaligned copy. Do it the hard way. */ | |||
| for(i=0;i<bytes;i++) | |||
| w(b,(unsigned long)(ptr[i]),8); | |||
| }else{ | |||
| /* aligned block copy */ | |||
| if(b->endbyte+bytes+1>=b->storage){ | |||
| b->storage=b->endbyte+bytes+BUFFER_INCREMENT; | |||
| b->buffer=(unsigned char*) _ogg_realloc(b->buffer,b->storage); | |||
| b->ptr=b->buffer+b->endbyte; | |||
| } | |||
| memmove(b->ptr,source,bytes); | |||
| b->ptr+=bytes; | |||
| b->endbyte+=bytes; | |||
| *b->ptr=0; | |||
| } | |||
| if(bits){ | |||
| if(msb) | |||
| w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); | |||
| else | |||
| w(b,(unsigned long)(ptr[bytes]),bits); | |||
| } | |||
| } | |||
| void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ | |||
| oggpack_writecopy_helper(b,source,bits,oggpack_write,0); | |||
| } | |||
| void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ | |||
| oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); | |||
| } | |||
| void oggpack_reset(oggpack_buffer *b){ | |||
| b->ptr=b->buffer; | |||
| b->buffer[0]=0; | |||
| b->endbit=b->endbyte=0; | |||
| } | |||
| void oggpackB_reset(oggpack_buffer *b){ | |||
| oggpack_reset(b); | |||
| } | |||
| void oggpack_writeclear(oggpack_buffer *b){ | |||
| _ogg_free(b->buffer); | |||
| memset(b,0,sizeof(*b)); | |||
| } | |||
| void oggpackB_writeclear(oggpack_buffer *b){ | |||
| oggpack_writeclear(b); | |||
| } | |||
| void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ | |||
| memset(b,0,sizeof(*b)); | |||
| b->buffer=b->ptr=buf; | |||
| b->storage=bytes; | |||
| } | |||
| void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ | |||
| oggpack_readinit(b,buf,bytes); | |||
| } | |||
| /* Read in bits without advancing the bitptr; bits <= 32 */ | |||
| long oggpack_look(oggpack_buffer *b,int bits){ | |||
| unsigned long ret; | |||
| unsigned long m=mask[bits]; | |||
| bits+=b->endbit; | |||
| if(b->endbyte+4>=b->storage){ | |||
| /* not the main path */ | |||
| if(b->endbyte*8+bits>b->storage*8)return(-1); | |||
| } | |||
| ret=b->ptr[0]>>b->endbit; | |||
| if(bits>8){ | |||
| ret|=b->ptr[1]<<(8-b->endbit); | |||
| if(bits>16){ | |||
| ret|=b->ptr[2]<<(16-b->endbit); | |||
| if(bits>24){ | |||
| ret|=b->ptr[3]<<(24-b->endbit); | |||
| if(bits>32 && b->endbit) | |||
| ret|=b->ptr[4]<<(32-b->endbit); | |||
| } | |||
| } | |||
| } | |||
| return(m&ret); | |||
| } | |||
| /* Read in bits without advancing the bitptr; bits <= 32 */ | |||
| long oggpackB_look(oggpack_buffer *b,int bits){ | |||
| unsigned long ret; | |||
| int m=32-bits; | |||
| bits+=b->endbit; | |||
| if(b->endbyte+4>=b->storage){ | |||
| /* not the main path */ | |||
| if(b->endbyte*8+bits>b->storage*8)return(-1); | |||
| } | |||
| ret=b->ptr[0]<<(24+b->endbit); | |||
| if(bits>8){ | |||
| ret|=b->ptr[1]<<(16+b->endbit); | |||
| if(bits>16){ | |||
| ret|=b->ptr[2]<<(8+b->endbit); | |||
| if(bits>24){ | |||
| ret|=b->ptr[3]<<(b->endbit); | |||
| if(bits>32 && b->endbit) | |||
| ret|=b->ptr[4]>>(8-b->endbit); | |||
| } | |||
| } | |||
| } | |||
| return ((ret&0xffffffff)>>(m>>1))>>((m+1)>>1); | |||
| } | |||
| long oggpack_look1(oggpack_buffer *b){ | |||
| if(b->endbyte>=b->storage)return(-1); | |||
| return((b->ptr[0]>>b->endbit)&1); | |||
| } | |||
| long oggpackB_look1(oggpack_buffer *b){ | |||
| if(b->endbyte>=b->storage)return(-1); | |||
| return((b->ptr[0]>>(7-b->endbit))&1); | |||
| } | |||
| void oggpack_adv(oggpack_buffer *b,int bits){ | |||
| bits+=b->endbit; | |||
| b->ptr+=bits/8; | |||
| b->endbyte+=bits/8; | |||
| b->endbit=bits&7; | |||
| } | |||
| void oggpackB_adv(oggpack_buffer *b,int bits){ | |||
| oggpack_adv(b,bits); | |||
| } | |||
| void oggpack_adv1(oggpack_buffer *b){ | |||
| if(++(b->endbit)>7){ | |||
| b->endbit=0; | |||
| b->ptr++; | |||
| b->endbyte++; | |||
| } | |||
| } | |||
| void oggpackB_adv1(oggpack_buffer *b){ | |||
| oggpack_adv1(b); | |||
| } | |||
| /* bits <= 32 */ | |||
| long oggpack_read(oggpack_buffer *b,int bits){ | |||
| long ret; | |||
| unsigned long m=mask[bits]; | |||
| bits+=b->endbit; | |||
| if(b->endbyte+4>=b->storage){ | |||
| /* not the main path */ | |||
| ret=-1L; | |||
| if(b->endbyte*8+bits>b->storage*8)goto overflow; | |||
| } | |||
| ret=b->ptr[0]>>b->endbit; | |||
| if(bits>8){ | |||
| ret|=b->ptr[1]<<(8-b->endbit); | |||
| if(bits>16){ | |||
| ret|=b->ptr[2]<<(16-b->endbit); | |||
| if(bits>24){ | |||
| ret|=b->ptr[3]<<(24-b->endbit); | |||
| if(bits>32 && b->endbit){ | |||
| ret|=b->ptr[4]<<(32-b->endbit); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| ret&=m; | |||
| overflow: | |||
| b->ptr+=bits/8; | |||
| b->endbyte+=bits/8; | |||
| b->endbit=bits&7; | |||
| return(ret); | |||
| } | |||
| /* bits <= 32 */ | |||
| long oggpackB_read(oggpack_buffer *b,int bits){ | |||
| long ret; | |||
| long m=32-bits; | |||
| bits+=b->endbit; | |||
| if(b->endbyte+4>=b->storage){ | |||
| /* not the main path */ | |||
| ret=-1L; | |||
| if(b->endbyte*8+bits>b->storage*8)goto overflow; | |||
| } | |||
| ret=b->ptr[0]<<(24+b->endbit); | |||
| if(bits>8){ | |||
| ret|=b->ptr[1]<<(16+b->endbit); | |||
| if(bits>16){ | |||
| ret|=b->ptr[2]<<(8+b->endbit); | |||
| if(bits>24){ | |||
| ret|=b->ptr[3]<<(b->endbit); | |||
| if(bits>32 && b->endbit) | |||
| ret|=b->ptr[4]>>(8-b->endbit); | |||
| } | |||
| } | |||
| } | |||
| ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); | |||
| overflow: | |||
| b->ptr+=bits/8; | |||
| b->endbyte+=bits/8; | |||
| b->endbit=bits&7; | |||
| return(ret); | |||
| } | |||
| long oggpack_read1(oggpack_buffer *b){ | |||
| long ret; | |||
| if(b->endbyte>=b->storage){ | |||
| /* not the main path */ | |||
| ret=-1L; | |||
| goto overflow; | |||
| } | |||
| ret=(b->ptr[0]>>b->endbit)&1; | |||
| overflow: | |||
| b->endbit++; | |||
| if(b->endbit>7){ | |||
| b->endbit=0; | |||
| b->ptr++; | |||
| b->endbyte++; | |||
| } | |||
| return(ret); | |||
| } | |||
| long oggpackB_read1(oggpack_buffer *b){ | |||
| long ret; | |||
| if(b->endbyte>=b->storage){ | |||
| /* not the main path */ | |||
| ret=-1L; | |||
| goto overflow; | |||
| } | |||
| ret=(b->ptr[0]>>(7-b->endbit))&1; | |||
| overflow: | |||
| b->endbit++; | |||
| if(b->endbit>7){ | |||
| b->endbit=0; | |||
| b->ptr++; | |||
| b->endbyte++; | |||
| } | |||
| return(ret); | |||
| } | |||
| long oggpack_bytes(oggpack_buffer *b){ | |||
| return(b->endbyte+(b->endbit+7)/8); | |||
| } | |||
| long oggpack_bits(oggpack_buffer *b){ | |||
| return(b->endbyte*8+b->endbit); | |||
| } | |||
| long oggpackB_bytes(oggpack_buffer *b){ | |||
| return oggpack_bytes(b); | |||
| } | |||
| long oggpackB_bits(oggpack_buffer *b){ | |||
| return oggpack_bits(b); | |||
| } | |||
| unsigned char *oggpack_get_buffer(oggpack_buffer *b){ | |||
| return(b->buffer); | |||
| } | |||
| unsigned char *oggpackB_get_buffer(oggpack_buffer *b){ | |||
| return oggpack_get_buffer(b); | |||
| } | |||
| /* Self test of the bitwise routines; everything else is based on | |||
| them, so they damned well better be solid. */ | |||
| #ifdef _V_SELFTEST | |||
| #include <stdio.h> | |||
| static int ilog(unsigned int v){ | |||
| int ret=0; | |||
| while(v){ | |||
| ret++; | |||
| v>>=1; | |||
| } | |||
| return(ret); | |||
| } | |||
| oggpack_buffer o; | |||
| oggpack_buffer r; | |||
| void report(char *in){ | |||
| fprintf(stderr,"%s",in); | |||
| exit(1); | |||
| } | |||
| void cliptest(unsigned long *b,int vals,int bits,int *comp,int compsize){ | |||
| long bytes,i; | |||
| unsigned char *buffer; | |||
| oggpack_reset(&o); | |||
| for(i=0;i<vals;i++) | |||
| oggpack_write(&o,b[i],bits?bits:ilog(b[i])); | |||
| buffer=oggpack_get_buffer(&o); | |||
| bytes=oggpack_bytes(&o); | |||
| if(bytes!=compsize)report("wrong number of bytes!\n"); | |||
| for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ | |||
| for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); | |||
| report("wrote incorrect value!\n"); | |||
| } | |||
| oggpack_readinit(&r,buffer,bytes); | |||
| for(i=0;i<vals;i++){ | |||
| int tbit=bits?bits:ilog(b[i]); | |||
| if(oggpack_look(&r,tbit)==-1) | |||
| report("out of data!\n"); | |||
| if(oggpack_look(&r,tbit)!=(b[i]&mask[tbit])) | |||
| report("looked at incorrect value!\n"); | |||
| if(tbit==1) | |||
| if(oggpack_look1(&r)!=(b[i]&mask[tbit])) | |||
| report("looked at single bit incorrect value!\n"); | |||
| if(tbit==1){ | |||
| if(oggpack_read1(&r)!=(b[i]&mask[tbit])) | |||
| report("read incorrect single bit value!\n"); | |||
| }else{ | |||
| if(oggpack_read(&r,tbit)!=(b[i]&mask[tbit])) | |||
| report("read incorrect value!\n"); | |||
| } | |||
| } | |||
| if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); | |||
| } | |||
| void cliptestB(unsigned long *b,int vals,int bits,int *comp,int compsize){ | |||
| long bytes,i; | |||
| unsigned char *buffer; | |||
| oggpackB_reset(&o); | |||
| for(i=0;i<vals;i++) | |||
| oggpackB_write(&o,b[i],bits?bits:ilog(b[i])); | |||
| buffer=oggpackB_get_buffer(&o); | |||
| bytes=oggpackB_bytes(&o); | |||
| if(bytes!=compsize)report("wrong number of bytes!\n"); | |||
| for(i=0;i<bytes;i++)if(buffer[i]!=comp[i]){ | |||
| for(i=0;i<bytes;i++)fprintf(stderr,"%x %x\n",(int)buffer[i],(int)comp[i]); | |||
| report("wrote incorrect value!\n"); | |||
| } | |||
| oggpackB_readinit(&r,buffer,bytes); | |||
| for(i=0;i<vals;i++){ | |||
| int tbit=bits?bits:ilog(b[i]); | |||
| if(oggpackB_look(&r,tbit)==-1) | |||
| report("out of data!\n"); | |||
| if(oggpackB_look(&r,tbit)!=(b[i]&mask[tbit])) | |||
| report("looked at incorrect value!\n"); | |||
| if(tbit==1) | |||
| if(oggpackB_look1(&r)!=(b[i]&mask[tbit])) | |||
| report("looked at single bit incorrect value!\n"); | |||
| if(tbit==1){ | |||
| if(oggpackB_read1(&r)!=(b[i]&mask[tbit])) | |||
| report("read incorrect single bit value!\n"); | |||
| }else{ | |||
| if(oggpackB_read(&r,tbit)!=(b[i]&mask[tbit])) | |||
| report("read incorrect value!\n"); | |||
| } | |||
| } | |||
| if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); | |||
| } | |||
| int main(void){ | |||
| unsigned char *buffer; | |||
| long bytes,i; | |||
| static unsigned long testbuffer1[]= | |||
| {18,12,103948,4325,543,76,432,52,3,65,4,56,32,42,34,21,1,23,32,546,456,7, | |||
| 567,56,8,8,55,3,52,342,341,4,265,7,67,86,2199,21,7,1,5,1,4}; | |||
| int test1size=43; | |||
| static unsigned long testbuffer2[]= | |||
| {216531625L,1237861823,56732452,131,3212421,12325343,34547562,12313212, | |||
| 1233432,534,5,346435231,14436467,7869299,76326614,167548585, | |||
| 85525151,0,12321,1,349528352}; | |||
| int test2size=21; | |||
| static unsigned long testbuffer3[]= | |||
| {1,0,14,0,1,0,12,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1, | |||
| 0,1,30,1,1,1,0,0,1,0,0,0,12,0,11,0,1,0,0,1}; | |||
| int test3size=56; | |||
| static unsigned long large[]= | |||
| {2136531625L,2137861823,56732452,131,3212421,12325343,34547562,12313212, | |||
| 1233432,534,5,2146435231,14436467,7869299,76326614,167548585, | |||
| 85525151,0,12321,1,2146528352}; | |||
| int onesize=33; | |||
| static int one[33]={146,25,44,151,195,15,153,176,233,131,196,65,85,172,47,40, | |||
| 34,242,223,136,35,222,211,86,171,50,225,135,214,75,172, | |||
| 223,4}; | |||
| static int oneB[33]={150,101,131,33,203,15,204,216,105,193,156,65,84,85,222, | |||
| 8,139,145,227,126,34,55,244,171,85,100,39,195,173,18, | |||
| 245,251,128}; | |||
| int twosize=6; | |||
| static int two[6]={61,255,255,251,231,29}; | |||
| static int twoB[6]={247,63,255,253,249,120}; | |||
| int threesize=54; | |||
| static int three[54]={169,2,232,252,91,132,156,36,89,13,123,176,144,32,254, | |||
| 142,224,85,59,121,144,79,124,23,67,90,90,216,79,23,83, | |||
| 58,135,196,61,55,129,183,54,101,100,170,37,127,126,10, | |||
| 100,52,4,14,18,86,77,1}; | |||
| static int threeB[54]={206,128,42,153,57,8,183,251,13,89,36,30,32,144,183, | |||
| 130,59,240,121,59,85,223,19,228,180,134,33,107,74,98, | |||
| 233,253,196,135,63,2,110,114,50,155,90,127,37,170,104, | |||
| 200,20,254,4,58,106,176,144,0}; | |||
| int foursize=38; | |||
| static int four[38]={18,6,163,252,97,194,104,131,32,1,7,82,137,42,129,11,72, | |||
| 132,60,220,112,8,196,109,64,179,86,9,137,195,208,122,169, | |||
| 28,2,133,0,1}; | |||
| static int fourB[38]={36,48,102,83,243,24,52,7,4,35,132,10,145,21,2,93,2,41, | |||
| 1,219,184,16,33,184,54,149,170,132,18,30,29,98,229,67, | |||
| 129,10,4,32}; | |||
| int fivesize=45; | |||
| static int five[45]={169,2,126,139,144,172,30,4,80,72,240,59,130,218,73,62, | |||
| 241,24,210,44,4,20,0,248,116,49,135,100,110,130,181,169, | |||
| 84,75,159,2,1,0,132,192,8,0,0,18,22}; | |||
| static int fiveB[45]={1,84,145,111,245,100,128,8,56,36,40,71,126,78,213,226, | |||
| 124,105,12,0,133,128,0,162,233,242,67,152,77,205,77, | |||
| 172,150,169,129,79,128,0,6,4,32,0,27,9,0}; | |||
| int sixsize=7; | |||
| static int six[7]={17,177,170,242,169,19,148}; | |||
| static int sixB[7]={136,141,85,79,149,200,41}; | |||
| /* Test read/write together */ | |||
| /* Later we test against pregenerated bitstreams */ | |||
| oggpack_writeinit(&o); | |||
| fprintf(stderr,"\nSmall preclipped packing (LSb): "); | |||
| cliptest(testbuffer1,test1size,0,one,onesize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nNull bit call (LSb): "); | |||
| cliptest(testbuffer3,test3size,0,two,twosize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nLarge preclipped packing (LSb): "); | |||
| cliptest(testbuffer2,test2size,0,three,threesize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\n32 bit preclipped packing (LSb): "); | |||
| oggpack_reset(&o); | |||
| for(i=0;i<test2size;i++) | |||
| oggpack_write(&o,large[i],32); | |||
| buffer=oggpack_get_buffer(&o); | |||
| bytes=oggpack_bytes(&o); | |||
| oggpack_readinit(&r,buffer,bytes); | |||
| for(i=0;i<test2size;i++){ | |||
| if(oggpack_look(&r,32)==-1)report("out of data. failed!"); | |||
| if(oggpack_look(&r,32)!=large[i]){ | |||
| fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpack_look(&r,32),large[i], | |||
| oggpack_look(&r,32),large[i]); | |||
| report("read incorrect value!\n"); | |||
| } | |||
| oggpack_adv(&r,32); | |||
| } | |||
| if(oggpack_bytes(&r)!=bytes)report("leftover bytes after read!\n"); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nSmall unclipped packing (LSb): "); | |||
| cliptest(testbuffer1,test1size,7,four,foursize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nLarge unclipped packing (LSb): "); | |||
| cliptest(testbuffer2,test2size,17,five,fivesize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nSingle bit unclipped packing (LSb): "); | |||
| cliptest(testbuffer3,test3size,1,six,sixsize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nTesting read past end (LSb): "); | |||
| oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8); | |||
| for(i=0;i<64;i++){ | |||
| if(oggpack_read(&r,1)!=0){ | |||
| fprintf(stderr,"failed; got -1 prematurely.\n"); | |||
| exit(1); | |||
| } | |||
| } | |||
| if(oggpack_look(&r,1)!=-1 || | |||
| oggpack_read(&r,1)!=-1){ | |||
| fprintf(stderr,"failed; read past end without -1.\n"); | |||
| exit(1); | |||
| } | |||
| oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8); | |||
| if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){ | |||
| fprintf(stderr,"failed 2; got -1 prematurely.\n"); | |||
| exit(1); | |||
| } | |||
| if(oggpack_look(&r,18)!=0 || | |||
| oggpack_look(&r,18)!=0){ | |||
| fprintf(stderr,"failed 3; got -1 prematurely.\n"); | |||
| exit(1); | |||
| } | |||
| if(oggpack_look(&r,19)!=-1 || | |||
| oggpack_look(&r,19)!=-1){ | |||
| fprintf(stderr,"failed; read past end without -1.\n"); | |||
| exit(1); | |||
| } | |||
| if(oggpack_look(&r,32)!=-1 || | |||
| oggpack_look(&r,32)!=-1){ | |||
| fprintf(stderr,"failed; read past end without -1.\n"); | |||
| exit(1); | |||
| } | |||
| oggpack_writeclear(&o); | |||
| fprintf(stderr,"ok.\n"); | |||
| /********** lazy, cut-n-paste retest with MSb packing ***********/ | |||
| /* Test read/write together */ | |||
| /* Later we test against pregenerated bitstreams */ | |||
| oggpackB_writeinit(&o); | |||
| fprintf(stderr,"\nSmall preclipped packing (MSb): "); | |||
| cliptestB(testbuffer1,test1size,0,oneB,onesize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nNull bit call (MSb): "); | |||
| cliptestB(testbuffer3,test3size,0,twoB,twosize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nLarge preclipped packing (MSb): "); | |||
| cliptestB(testbuffer2,test2size,0,threeB,threesize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\n32 bit preclipped packing (MSb): "); | |||
| oggpackB_reset(&o); | |||
| for(i=0;i<test2size;i++) | |||
| oggpackB_write(&o,large[i],32); | |||
| buffer=oggpackB_get_buffer(&o); | |||
| bytes=oggpackB_bytes(&o); | |||
| oggpackB_readinit(&r,buffer,bytes); | |||
| for(i=0;i<test2size;i++){ | |||
| if(oggpackB_look(&r,32)==-1)report("out of data. failed!"); | |||
| if(oggpackB_look(&r,32)!=large[i]){ | |||
| fprintf(stderr,"%ld != %ld (%lx!=%lx):",oggpackB_look(&r,32),large[i], | |||
| oggpackB_look(&r,32),large[i]); | |||
| report("read incorrect value!\n"); | |||
| } | |||
| oggpackB_adv(&r,32); | |||
| } | |||
| if(oggpackB_bytes(&r)!=bytes)report("leftover bytes after read!\n"); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nSmall unclipped packing (MSb): "); | |||
| cliptestB(testbuffer1,test1size,7,fourB,foursize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nLarge unclipped packing (MSb): "); | |||
| cliptestB(testbuffer2,test2size,17,fiveB,fivesize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nSingle bit unclipped packing (MSb): "); | |||
| cliptestB(testbuffer3,test3size,1,sixB,sixsize); | |||
| fprintf(stderr,"ok."); | |||
| fprintf(stderr,"\nTesting read past end (MSb): "); | |||
| oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8); | |||
| for(i=0;i<64;i++){ | |||
| if(oggpackB_read(&r,1)!=0){ | |||
| fprintf(stderr,"failed; got -1 prematurely.\n"); | |||
| exit(1); | |||
| } | |||
| } | |||
| if(oggpackB_look(&r,1)!=-1 || | |||
| oggpackB_read(&r,1)!=-1){ | |||
| fprintf(stderr,"failed; read past end without -1.\n"); | |||
| exit(1); | |||
| } | |||
| oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8); | |||
| if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){ | |||
| fprintf(stderr,"failed 2; got -1 prematurely.\n"); | |||
| exit(1); | |||
| } | |||
| if(oggpackB_look(&r,18)!=0 || | |||
| oggpackB_look(&r,18)!=0){ | |||
| fprintf(stderr,"failed 3; got -1 prematurely.\n"); | |||
| exit(1); | |||
| } | |||
| if(oggpackB_look(&r,19)!=-1 || | |||
| oggpackB_look(&r,19)!=-1){ | |||
| fprintf(stderr,"failed; read past end without -1.\n"); | |||
| exit(1); | |||
| } | |||
| if(oggpackB_look(&r,32)!=-1 || | |||
| oggpackB_look(&r,32)!=-1){ | |||
| fprintf(stderr,"failed; read past end without -1.\n"); | |||
| exit(1); | |||
| } | |||
| oggpackB_writeclear(&o); | |||
| fprintf(stderr,"ok.\n\n"); | |||
| return(0); | |||
| } | |||
| #endif /* _V_SELFTEST */ | |||
| #undef BUFFER_INCREMENT | |||
| @@ -1,242 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| ******************************************************************** | |||
| function: libvorbis codec headers | |||
| last mod: $Id: codec.h 17021 2010-03-24 09:29:41Z xiphmont $ | |||
| ********************************************************************/ | |||
| #ifndef _vorbis_codec_h_ | |||
| #define _vorbis_codec_h_ | |||
| #ifdef __cplusplus | |||
| extern "C" | |||
| { | |||
| #endif /* __cplusplus */ | |||
| #include "ogg.h" | |||
| typedef struct vorbis_info{ | |||
| int version; | |||
| int channels; | |||
| long rate; | |||
| /* The below bitrate declarations are *hints*. | |||
| Combinations of the three values carry the following implications: | |||
| all three set to the same value: | |||
| implies a fixed rate bitstream | |||
| only nominal set: | |||
| implies a VBR stream that averages the nominal bitrate. No hard | |||
| upper/lower limit | |||
| upper and or lower set: | |||
| implies a VBR bitstream that obeys the bitrate limits. nominal | |||
| may also be set to give a nominal rate. | |||
| none set: | |||
| the coder does not care to speculate. | |||
| */ | |||
| long bitrate_upper; | |||
| long bitrate_nominal; | |||
| long bitrate_lower; | |||
| long bitrate_window; | |||
| void *codec_setup; | |||
| } vorbis_info; | |||
| /* vorbis_dsp_state buffers the current vorbis audio | |||
| analysis/synthesis state. The DSP state belongs to a specific | |||
| logical bitstream ****************************************************/ | |||
| typedef struct vorbis_dsp_state{ | |||
| int analysisp; | |||
| vorbis_info *vi; | |||
| float **pcm; | |||
| float **pcmret; | |||
| int pcm_storage; | |||
| int pcm_current; | |||
| int pcm_returned; | |||
| int preextrapolate; | |||
| int eofflag; | |||
| long lW; | |||
| long W; | |||
| long nW; | |||
| long centerW; | |||
| ogg_int64_t granulepos; | |||
| ogg_int64_t sequence; | |||
| ogg_int64_t glue_bits; | |||
| ogg_int64_t time_bits; | |||
| ogg_int64_t floor_bits; | |||
| ogg_int64_t res_bits; | |||
| void *backend_state; | |||
| } vorbis_dsp_state; | |||
| typedef struct vorbis_block{ | |||
| /* necessary stream state for linking to the framing abstraction */ | |||
| float **pcm; /* this is a pointer into local storage */ | |||
| oggpack_buffer opb; | |||
| long lW; | |||
| long W; | |||
| long nW; | |||
| int pcmend; | |||
| int mode; | |||
| int eofflag; | |||
| ogg_int64_t granulepos; | |||
| ogg_int64_t sequence; | |||
| vorbis_dsp_state *vd; /* For read-only access of configuration */ | |||
| /* local storage to avoid remallocing; it's up to the mapping to | |||
| structure it */ | |||
| void *localstore; | |||
| long localtop; | |||
| long localalloc; | |||
| long totaluse; | |||
| struct alloc_chain *reap; | |||
| /* bitmetrics for the frame */ | |||
| long glue_bits; | |||
| long time_bits; | |||
| long floor_bits; | |||
| long res_bits; | |||
| void *internal; | |||
| } vorbis_block; | |||
| /* vorbis_block is a single block of data to be processed as part of | |||
| the analysis/synthesis stream; it belongs to a specific logical | |||
| bitstream, but is independent from other vorbis_blocks belonging to | |||
| that logical bitstream. *************************************************/ | |||
| struct alloc_chain{ | |||
| void *ptr; | |||
| struct alloc_chain *next; | |||
| }; | |||
| /* vorbis_info contains all the setup information specific to the | |||
| specific compression/decompression mode in progress (eg, | |||
| psychoacoustic settings, channel setup, options, codebook | |||
| etc). vorbis_info and substructures are in backends.h. | |||
| *********************************************************************/ | |||
| /* the comments are not part of vorbis_info so that vorbis_info can be | |||
| static storage */ | |||
| typedef struct vorbis_comment{ | |||
| /* unlimited user comment fields. libvorbis writes 'libvorbis' | |||
| whatever vendor is set to in encode */ | |||
| char **user_comments; | |||
| int *comment_lengths; | |||
| int comments; | |||
| char *vendor; | |||
| } vorbis_comment; | |||
| /* libvorbis encodes in two abstraction layers; first we perform DSP | |||
| and produce a packet (see docs/analysis.txt). The packet is then | |||
| coded into a framed OggSquish bitstream by the second layer (see | |||
| docs/framing.txt). Decode is the reverse process; we sync/frame | |||
| the bitstream and extract individual packets, then decode the | |||
| packet back into PCM audio. | |||
| The extra framing/packetizing is used in streaming formats, such as | |||
| files. Over the net (such as with UDP), the framing and | |||
| packetization aren't necessary as they're provided by the transport | |||
| and the streaming layer is not used */ | |||
| /* Vorbis PRIMITIVES: general ***************************************/ | |||
| extern void vorbis_info_init(vorbis_info *vi); | |||
| extern void vorbis_info_clear(vorbis_info *vi); | |||
| extern int vorbis_info_blocksize(vorbis_info *vi,int zo); | |||
| extern void vorbis_comment_init(vorbis_comment *vc); | |||
| extern void vorbis_comment_add(vorbis_comment *vc, const char *comment); | |||
| extern void vorbis_comment_add_tag(vorbis_comment *vc, | |||
| const char *tag, const char *contents); | |||
| extern char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count); | |||
| extern int vorbis_comment_query_count(vorbis_comment *vc, const char *tag); | |||
| extern void vorbis_comment_clear(vorbis_comment *vc); | |||
| extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); | |||
| extern int vorbis_block_clear(vorbis_block *vb); | |||
| extern void vorbis_dsp_clear(vorbis_dsp_state *v); | |||
| extern double vorbis_granule_time(vorbis_dsp_state *v, | |||
| ogg_int64_t granulepos); | |||
| extern const char *vorbis_version_string(void); | |||
| /* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ | |||
| extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); | |||
| extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); | |||
| extern int vorbis_analysis_headerout(vorbis_dsp_state *v, | |||
| vorbis_comment *vc, | |||
| ogg_packet *op, | |||
| ogg_packet *op_comm, | |||
| ogg_packet *op_code); | |||
| extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); | |||
| extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); | |||
| extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); | |||
| extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); | |||
| extern int vorbis_bitrate_addblock(vorbis_block *vb); | |||
| extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, | |||
| ogg_packet *op); | |||
| /* Vorbis PRIMITIVES: synthesis layer *******************************/ | |||
| extern int vorbis_synthesis_idheader(ogg_packet *op); | |||
| extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, | |||
| ogg_packet *op); | |||
| extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); | |||
| extern int vorbis_synthesis_restart(vorbis_dsp_state *v); | |||
| extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); | |||
| extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); | |||
| extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); | |||
| extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); | |||
| extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); | |||
| extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); | |||
| extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); | |||
| extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); | |||
| extern int vorbis_synthesis_halfrate_p(vorbis_info *v); | |||
| /* Vorbis ERRORS and return codes ***********************************/ | |||
| #define OV_FALSE -1 | |||
| #define OV_EOF -2 | |||
| #define OV_HOLE -3 | |||
| #define OV_EREAD -128 | |||
| #define OV_EFAULT -129 | |||
| #define OV_EIMPL -130 | |||
| #define OV_EINVAL -131 | |||
| #define OV_ENOTVORBIS -132 | |||
| #define OV_EBADHEADER -133 | |||
| #define OV_EVERSION -134 | |||
| #define OV_ENOTAUDIO -135 | |||
| #define OV_EBADPACKET -136 | |||
| #define OV_EBADLINK -137 | |||
| #define OV_ENOSEEK -138 | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif /* __cplusplus */ | |||
| #endif | |||
| @@ -1,10 +0,0 @@ | |||
| #ifndef __CONFIG_TYPES_H__ | |||
| #define __CONFIG_TYPES_H__ | |||
| typedef int16_t ogg_int16_t; | |||
| typedef unsigned short ogg_uint16_t; | |||
| typedef int32_t ogg_int32_t; | |||
| typedef unsigned int ogg_uint32_t; | |||
| typedef int64_t ogg_int64_t; | |||
| #endif | |||
| @@ -1,3 +0,0 @@ | |||
| Monty <monty@xiph.org> | |||
| and the rest of the Xiph.org Foundation. | |||
| @@ -1,126 +0,0 @@ | |||
| libvorbis 1.3.2 (2010-11-01) -- "Xiph.Org libVorbis I 20101101 (Schaufenugget)" | |||
| * vorbis: additional proofing against invalid/malicious | |||
| streams in floor, residue, and bos/eos packet trimming | |||
| code (see SVN for details). | |||
| * vorbis: Added programming documentation tree for the | |||
| low-level calls | |||
| * vorbisfile: Correct handling of serial numbers array | |||
| element [0] on non-seekable streams | |||
| * vorbisenc: Back out an [old] AoTuV HF weighting that was | |||
| first enabled in 1.3.0; there are a few samples where I | |||
| really don't like the effect it causes. | |||
| * vorbis: return correct timestamp for granule positions | |||
| with high bit set. | |||
| * vorbisfile: the [undocumented] half-rate decode api made no | |||
| attempt to keep the pcm offset tracking consistent in seeks. | |||
| Fix and add a testing mode to seeking_example.c to torture | |||
| test seeking in halfrate mode. Also remove requirement that | |||
| halfrate mode only work with seekable files. | |||
| * vorbisfile: Fix a chaining bug in raw_seeks where seeking | |||
| out of the current link would fail due to not | |||
| reinitializing the decode machinery. | |||
| * vorbisfile: improve seeking strategy. Reduces the | |||
| necessary number of seek callbacks in an open or seek | |||
| operation by well over 2/3. | |||
| libvorbis 1.3.1 (2010-02-26) -- "Xiph.Org libVorbis I 20100325 (Everywhere)" | |||
| * tweak + minor arithmetic fix in floor1 fit | |||
| * revert noise norm to conservative 1.2.3 behavior pending | |||
| more listening testing | |||
| libvorbis 1.3.0 (2010-02-25) -- unreleased staging snapshot | |||
| * Optimized surround support for 5.1 encoding at 44.1/48kHz | |||
| * Added encoder control call to disable channel coupling | |||
| * Correct an overflow bug in very low-bitrate encoding on 32 bit | |||
| machines that caused inflated bitrates | |||
| * Numerous API hardening, leak and build fixes | |||
| * Correct bug in 22kHz compand setup that could cause a crash | |||
| * Correct bug in 16kHz codebooks that could cause unstable pure | |||
| tones at high bitrates | |||
| libvorbis 1.2.3 (2009-07-09) -- "Xiph.Org libVorbis I 20090709" | |||
| * correct a vorbisfile bug that prevented proper playback of | |||
| Vorbis files where all audio in a logical stream is in a | |||
| single page | |||
| * Additional decode setup hardening against malicious streams | |||
| * Add 'OV_EXCLUDE_STATIC_CALLBACKS' define for developers who | |||
| wish to avoid unused symbol warnings from the static callbacks | |||
| defined in vorbisfile.h | |||
| libvorbis 1.2.2 (2009-06-24) -- "Xiph.Org libVorbis I 20090624" | |||
| * define VENDOR and ENCODER strings | |||
| * seek correctly in files bigger than 2 GB (Windows) | |||
| * fix regression from CVE-2008-1420; 1.0b1 files work again | |||
| * mark all tables as constant to reduce memory occupation | |||
| * additional decoder hardening against malicious streams | |||
| * substantially reduce amount of seeking performed by Vorbisfile | |||
| * Multichannel decode bugfix | |||
| * build system updates | |||
| * minor specification clarifications/fixes | |||
| libvorbis 1.2.1 (unreleased) -- "Xiph.Org libVorbis I 20080501" | |||
| * Improved robustness with corrupt streams. | |||
| * New ov_read_filter() vorbisfile call allows filtering decoded | |||
| audio as floats before converting to integer samples. | |||
| * Fix an encoder bug with multichannel streams. | |||
| * Replaced RTP payload format draft with RFC 5215. | |||
| * Bare bones self test under 'make check'. | |||
| * Fix a problem encoding some streams between 14 and 28 kHz. | |||
| * Fix a numerical instability in the edge extrapolation filter. | |||
| * Build system improvements. | |||
| * Specification correction. | |||
| libvorbis 1.2.0 (2007-07-25) -- "Xiph.Org libVorbis I 20070622" | |||
| * new ov_fopen() convenience call that avoids the common | |||
| stdio conflicts with ov_open() and MSVC runtimes. | |||
| * libvorbisfile now handles multiplexed streams | |||
| * improve robustness to corrupt input streams | |||
| * fix a minor encoder bug | |||
| * updated RTP draft | |||
| * build system updates | |||
| * minor corrections to the specification | |||
| libvorbis 1.1.2 (2005-11-27) -- "Xiph.Org libVorbis I 20050304" | |||
| * fix a serious encoder bug with gcc 4 optimized builds | |||
| * documentation and spec fixes | |||
| * updated VS2003 and XCode builds | |||
| * new draft RTP encapsulation spec | |||
| libvorbis 1.1.1 (2005-06-27) -- "Xiph.Org libVorbis I 20050304" | |||
| * bug fix to the bitrate management encoder interface | |||
| * bug fix to properly set packetno field in the encoder | |||
| * new draft RTP encapsulation spec | |||
| * library API documentation improvements | |||
| libvorbis 1.1.0 (2004-09-22) -- "Xiph.Org libVorbis I 20040629" | |||
| * merges tuning improvements from Aoyumi's aoTuV with fixups | |||
| * new managed bitrate (CBR) mode support | |||
| * new vorbis_encoder_ctl() interface | |||
| * extensive documentation updates | |||
| * application/ogg mimetype is now official | |||
| * autotools cleanup from Thomas Vander Stichele | |||
| * SymbianOS build support from Colin Ward at CSIRO | |||
| * various bugfixes | |||
| * various packaging improvements | |||
| libvorbis 1.0.1 (2003-11-17) -- "Xiph.Org libVorbis I 20030909" | |||
| * numerous bug fixes | |||
| * specification corrections | |||
| * new crosslap and halfrate APIs for game use | |||
| * packaging and build updates | |||
| libvorbis 1.0.0 (2002-07-19) -- "Xiph.Org libVorbis I 20020717" | |||
| * first stable release | |||
| @@ -1,28 +0,0 @@ | |||
| Copyright (c) 2002-2008 Xiph.org Foundation | |||
| Redistribution and use in source and binary forms, with or without | |||
| modification, are permitted provided that the following conditions | |||
| are met: | |||
| - Redistributions of source code must retain the above copyright | |||
| notice, this list of conditions and the following disclaimer. | |||
| - Redistributions in binary form must reproduce the above copyright | |||
| notice, this list of conditions and the following disclaimer in the | |||
| documentation and/or other materials provided with the distribution. | |||
| - Neither the name of the Xiph.org Foundation nor the names of its | |||
| contributors may be used to endorse or promote products derived from | |||
| this software without specific prior written permission. | |||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION | |||
| OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
| @@ -1,134 +0,0 @@ | |||
| ******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * | |||
| * by the Xiph.org Foundation, http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| Vorbis is a general purpose audio and music encoding format | |||
| contemporary to MPEG-4's AAC and TwinVQ, the next generation beyond | |||
| MPEG audio layer 3. Unlike the MPEG sponsored formats (and other | |||
| proprietary formats such as RealAudio G2 and Windows' flavor of the | |||
| month), the Vorbis CODEC specification belongs to the public domain. | |||
| All the technical details are published and documented, and any | |||
| software entity may make full use of the format without license | |||
| fee, royalty or patent concerns. | |||
| This package contains: | |||
| * libvorbis, a BSD-style license software implementation of | |||
| the Vorbis specification by the Xiph.Org Foundation | |||
| (http://www.xiph.org/) | |||
| * libvorbisfile, a BSD-style license convenience library | |||
| built on Vorbis designed to simplify common uses | |||
| * libvorbisenc, a BSD-style license library that provides a simple, | |||
| programmatic encoding setup interface | |||
| * example code making use of libogg, libvorbis, libvorbisfile and | |||
| libvorbisenc | |||
| WHAT'S HERE: | |||
| This source distribution includes libvorbis and an example | |||
| encoder/player to demonstrate use of libvorbis as well as | |||
| documentation on the Ogg Vorbis audio coding format. | |||
| You'll need libogg (distributed separately) to compile this library. | |||
| A more comprehensive set of utilities is available in the vorbis-tools | |||
| package. | |||
| Directory: | |||
| ./lib The source for the libraries, a BSD-license implementation | |||
| of the public domain Ogg Vorbis audio encoding format. | |||
| ./include Library API headers | |||
| ./debian Rules/spec files for building Debian .deb packages | |||
| ./doc Vorbis documentation | |||
| ./examples Example code illustrating programmatic use of libvorbis, | |||
| libvorbisfile and libvorbisenc | |||
| ./mac Codewarrior project files and build tweaks for MacOS. | |||
| ./macosx Project files for MacOS X. | |||
| ./win32 Win32 projects files and build automation | |||
| ./vq Internal utilities for training/building new LSP/residue | |||
| and auxiliary codebooks. | |||
| CONTACT: | |||
| The Ogg homepage is located at 'http://www.xiph.org/ogg/'. | |||
| Vorbis's homepage is located at 'http://www.xiph.org/vorbis/'. | |||
| Up to date technical documents, contact information, source code and | |||
| pre-built utilities may be found there. | |||
| The user website for Ogg Vorbis software and audio is http://vorbis.com/ | |||
| BUILDING FROM TRUNK: | |||
| Development source is under subversion revision control at | |||
| https://svn.xiph.org/trunk/vorbis/. You will also need the | |||
| newest versions of autoconf, automake, libtool and pkg-config in | |||
| order to compile Vorbis from development source. A configure script | |||
| is provided for you in the source tarball distributions. | |||
| [update or checkout latest source] | |||
| ./autogen.sh | |||
| make | |||
| and as root if desired: | |||
| make install | |||
| This will install the Vorbis libraries (static and shared) into | |||
| /usr/local/lib, includes into /usr/local/include and API manpages | |||
| (once we write some) into /usr/local/man. | |||
| Documentation building requires xsltproc and pdfxmltex. | |||
| BUILDING FROM TARBALL DISTRIBUTIONS: | |||
| ./configure | |||
| make | |||
| and optionally (as root): | |||
| make install | |||
| BUILDING RPMS: | |||
| after normal configuring: | |||
| make dist | |||
| rpm -ta libvorbis-<version>.tar.gz | |||
| BUILDING ON MACOS 9: | |||
| Vorbis on MacOS 9 is built using Metroworks CodeWarrior. To build it, | |||
| first verify that the Ogg libraries are already built following the | |||
| instructions in the Ogg module README. Open vorbis/mac/libvorbis.mcp, | |||
| switch to the "Targets" pane, select everything, and make the project. | |||
| Do the same thing to build libvorbisenc.mcp, and libvorbisfile.mcp (in | |||
| that order). In vorbis/mac/Output you will now have both debug and final | |||
| versions of Vorbis shared libraries to link your projects against. | |||
| To build a project using Ogg Vorbis, add access paths to your | |||
| CodeWarrior project for the ogg/include, ogg/mac/Output, | |||
| vorbis/include, and vorbis/mac/Output folders. Be sure that | |||
| "interpret DOS and Unix paths" is turned on in your project; it can | |||
| be found in the "access paths" pane in your project settings. Now | |||
| simply add the shared libraries you need to your project (OggLib and | |||
| VorbisLib at least) and #include "ogg/ogg.h" and "vorbis/codec.h" | |||
| wherever you need to access Ogg and Vorbis functionality. | |||
| @@ -1,109 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: single-block PCM analysis mode dispatch | |||
| last mod: $Id: analysis.c 16226 2009-07-08 06:43:49Z xiphmont $ | |||
| ********************************************************************/ | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <math.h> | |||
| #include "../../ogg.h" | |||
| #include "../../codec.h" | |||
| #include "codec_internal.h" | |||
| #include "registry.h" | |||
| #include "scales.h" | |||
| #include "os.h" | |||
| #include "misc.h" | |||
| /* decides between modes, dispatches to the appropriate mapping. */ | |||
| int vorbis_analysis(vorbis_block *vb, ogg_packet *op){ | |||
| int ret,i; | |||
| vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal; | |||
| vb->glue_bits=0; | |||
| vb->time_bits=0; | |||
| vb->floor_bits=0; | |||
| vb->res_bits=0; | |||
| /* first things first. Make sure encode is ready */ | |||
| for(i=0;i<PACKETBLOBS;i++) | |||
| oggpack_reset(vbi->packetblob[i]); | |||
| /* we only have one mapping type (0), and we let the mapping code | |||
| itself figure out what soft mode to use. This allows easier | |||
| bitrate management */ | |||
| if((ret=_mapping_P[0]->forward(vb))) | |||
| return(ret); | |||
| if(op){ | |||
| if(vorbis_bitrate_managed(vb)) | |||
| /* The app is using a bitmanaged mode... but not using the | |||
| bitrate management interface. */ | |||
| return(OV_EINVAL); | |||
| op->packet=oggpack_get_buffer(&vb->opb); | |||
| op->bytes=oggpack_bytes(&vb->opb); | |||
| op->b_o_s=0; | |||
| op->e_o_s=vb->eofflag; | |||
| op->granulepos=vb->granulepos; | |||
| op->packetno=vb->sequence; /* for sake of completeness */ | |||
| } | |||
| return(0); | |||
| } | |||
| #ifdef ANALYSIS | |||
| int analysis_noisy=1; | |||
| /* there was no great place to put this.... */ | |||
| void _analysis_output_always(char *base,int i,float *v,int n,int bark,int dB,ogg_int64_t off){ | |||
| int j; | |||
| FILE *of; | |||
| char buffer[80]; | |||
| sprintf(buffer,"%s_%d.m",base,i); | |||
| of=fopen(buffer,"w"); | |||
| if(!of)perror("failed to open data dump file"); | |||
| for(j=0;j<n;j++){ | |||
| if(bark){ | |||
| float b=toBARK((4000.f*j/n)+.25); | |||
| fprintf(of,"%f ",b); | |||
| }else | |||
| if(off!=0) | |||
| fprintf(of,"%f ",(double)(j+off)/8000.); | |||
| else | |||
| fprintf(of,"%f ",(double)j); | |||
| if(dB){ | |||
| float val; | |||
| if(v[j]==0.) | |||
| val=-140.; | |||
| else | |||
| val=todB(v+j); | |||
| fprintf(of,"%f\n",val); | |||
| }else{ | |||
| fprintf(of,"%f\n",v[j]); | |||
| } | |||
| } | |||
| fclose(of); | |||
| } | |||
| void _analysis_output(char *base,int i,float *v,int n,int bark,int dB, | |||
| ogg_int64_t off){ | |||
| if(analysis_noisy)_analysis_output_always(base,i,v,n,bark,dB,off); | |||
| } | |||
| #endif | |||
| @@ -1,144 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: libvorbis backend and mapping structures; needed for | |||
| static mode headers | |||
| last mod: $Id: backends.h 16962 2010-03-11 07:30:34Z xiphmont $ | |||
| ********************************************************************/ | |||
| /* this is exposed up here because we need it for static modes. | |||
| Lookups for each backend aren't exposed because there's no reason | |||
| to do so */ | |||
| #ifndef _vorbis_backend_h_ | |||
| #define _vorbis_backend_h_ | |||
| #include "codec_internal.h" | |||
| /* this would all be simpler/shorter with templates, but.... */ | |||
| /* Floor backend generic *****************************************/ | |||
| typedef struct{ | |||
| void (*pack) (vorbis_info_floor *,oggpack_buffer *); | |||
| vorbis_info_floor *(*unpack)(vorbis_info *,oggpack_buffer *); | |||
| vorbis_look_floor *(*look) (vorbis_dsp_state *,vorbis_info_floor *); | |||
| void (*free_info) (vorbis_info_floor *); | |||
| void (*free_look) (vorbis_look_floor *); | |||
| void *(*inverse1) (struct vorbis_block *,vorbis_look_floor *); | |||
| int (*inverse2) (struct vorbis_block *,vorbis_look_floor *, | |||
| void *buffer,float *); | |||
| } vorbis_func_floor; | |||
| typedef struct{ | |||
| int order; | |||
| long rate; | |||
| long barkmap; | |||
| int ampbits; | |||
| int ampdB; | |||
| int numbooks; /* <= 16 */ | |||
| int books[16]; | |||
| float lessthan; /* encode-only config setting hacks for libvorbis */ | |||
| float greaterthan; /* encode-only config setting hacks for libvorbis */ | |||
| } vorbis_info_floor0; | |||
| #define VIF_POSIT 63 | |||
| #define VIF_CLASS 16 | |||
| #define VIF_PARTS 31 | |||
| typedef struct{ | |||
| int partitions; /* 0 to 31 */ | |||
| int partitionclass[VIF_PARTS]; /* 0 to 15 */ | |||
| int class_dim[VIF_CLASS]; /* 1 to 8 */ | |||
| int class_subs[VIF_CLASS]; /* 0,1,2,3 (bits: 1<<n poss) */ | |||
| int class_book[VIF_CLASS]; /* subs ^ dim entries */ | |||
| int class_subbook[VIF_CLASS][8]; /* [VIF_CLASS][subs] */ | |||
| int mult; /* 1 2 3 or 4 */ | |||
| int postlist[VIF_POSIT+2]; /* first two implicit */ | |||
| /* encode side analysis parameters */ | |||
| float maxover; | |||
| float maxunder; | |||
| float maxerr; | |||
| float twofitweight; | |||
| float twofitatten; | |||
| int n; | |||
| } vorbis_info_floor1; | |||
| /* Residue backend generic *****************************************/ | |||
| typedef struct{ | |||
| void (*pack) (vorbis_info_residue *,oggpack_buffer *); | |||
| vorbis_info_residue *(*unpack)(vorbis_info *,oggpack_buffer *); | |||
| vorbis_look_residue *(*look) (vorbis_dsp_state *, | |||
| vorbis_info_residue *); | |||
| void (*free_info) (vorbis_info_residue *); | |||
| void (*free_look) (vorbis_look_residue *); | |||
| long **(*classx) (struct vorbis_block *,vorbis_look_residue *, | |||
| int **,int *,int); | |||
| int (*forward) (oggpack_buffer *,struct vorbis_block *, | |||
| vorbis_look_residue *, | |||
| int **,int *,int,long **,int); | |||
| int (*inverse) (struct vorbis_block *,vorbis_look_residue *, | |||
| float **,int *,int); | |||
| } vorbis_func_residue; | |||
| typedef struct vorbis_info_residue0{ | |||
| /* block-partitioned VQ coded straight residue */ | |||
| long begin; | |||
| long end; | |||
| /* first stage (lossless partitioning) */ | |||
| int grouping; /* group n vectors per partition */ | |||
| int partitions; /* possible codebooks for a partition */ | |||
| int partvals; /* partitions ^ groupbook dim */ | |||
| int groupbook; /* huffbook for partitioning */ | |||
| int secondstages[64]; /* expanded out to pointers in lookup */ | |||
| int booklist[512]; /* list of second stage books */ | |||
| /*const*/ int classmetric1[64]; | |||
| /*const*/ int classmetric2[64]; | |||
| } vorbis_info_residue0; | |||
| /* Mapping backend generic *****************************************/ | |||
| typedef struct{ | |||
| void (*pack) (vorbis_info *,vorbis_info_mapping *, | |||
| oggpack_buffer *); | |||
| vorbis_info_mapping *(*unpack)(vorbis_info *,oggpack_buffer *); | |||
| void (*free_info) (vorbis_info_mapping *); | |||
| int (*forward) (struct vorbis_block *vb); | |||
| int (*inverse) (struct vorbis_block *vb,vorbis_info_mapping *); | |||
| } vorbis_func_mapping; | |||
| typedef struct vorbis_info_mapping0{ | |||
| int submaps; /* <= 16 */ | |||
| int chmuxlist[256]; /* up to 256 channels in a Vorbis stream */ | |||
| int floorsubmap[16]; /* [mux] submap to floors */ | |||
| int residuesubmap[16]; /* [mux] submap to residue */ | |||
| int coupling_steps; | |||
| int coupling_mag[256]; | |||
| int coupling_ang[256]; | |||
| } vorbis_info_mapping0; | |||
| #endif | |||
| @@ -1,253 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: bitrate tracking and management | |||
| last mod: $Id: bitrate.c 16227 2009-07-08 06:58:46Z xiphmont $ | |||
| ********************************************************************/ | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <math.h> | |||
| #include "../../ogg.h" | |||
| #include "../../codec.h" | |||
| #include "codec_internal.h" | |||
| #include "os.h" | |||
| #include "misc.h" | |||
| #include "bitrate.h" | |||
| /* compute bitrate tracking setup */ | |||
| void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bm){ | |||
| codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | |||
| bitrate_manager_info *bi=&ci->bi; | |||
| memset(bm,0,sizeof(*bm)); | |||
| if(bi && (bi->reservoir_bits>0)){ | |||
| long ratesamples=vi->rate; | |||
| int halfsamples=ci->blocksizes[0]>>1; | |||
| bm->short_per_long=ci->blocksizes[1]/ci->blocksizes[0]; | |||
| bm->managed=1; | |||
| bm->avg_bitsper= (int) rint(1.*bi->avg_rate*halfsamples/ratesamples); | |||
| bm->min_bitsper= (int) rint(1.*bi->min_rate*halfsamples/ratesamples); | |||
| bm->max_bitsper= (int) rint(1.*bi->max_rate*halfsamples/ratesamples); | |||
| bm->avgfloat=PACKETBLOBS/2; | |||
| /* not a necessary fix, but one that leads to a more balanced | |||
| typical initialization */ | |||
| { | |||
| long desired_fill = (long) (bi->reservoir_bits*bi->reservoir_bias); | |||
| bm->minmax_reservoir=desired_fill; | |||
| bm->avg_reservoir=desired_fill; | |||
| } | |||
| } | |||
| } | |||
| void vorbis_bitrate_clear(bitrate_manager_state *bm){ | |||
| memset(bm,0,sizeof(*bm)); | |||
| return; | |||
| } | |||
| int vorbis_bitrate_managed(vorbis_block *vb){ | |||
| vorbis_dsp_state *vd=vb->vd; | |||
| private_state *b=(private_state*)vd->backend_state; | |||
| bitrate_manager_state *bm=&b->bms; | |||
| if(bm && bm->managed)return(1); | |||
| return(0); | |||
| } | |||
| /* finish taking in the block we just processed */ | |||
| int vorbis_bitrate_addblock(vorbis_block *vb){ | |||
| vorbis_block_internal *vbi=(vorbis_block_internal*)vb->internal; | |||
| vorbis_dsp_state *vd=vb->vd; | |||
| private_state *b=(private_state*)vd->backend_state; | |||
| bitrate_manager_state *bm=&b->bms; | |||
| vorbis_info *vi=vd->vi; | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| bitrate_manager_info *bi=&ci->bi; | |||
| int choice = (int) rint(bm->avgfloat); | |||
| long this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | |||
| long min_target_bits=(vb->W?bm->min_bitsper*bm->short_per_long:bm->min_bitsper); | |||
| long max_target_bits=(vb->W?bm->max_bitsper*bm->short_per_long:bm->max_bitsper); | |||
| int samples=ci->blocksizes[vb->W]>>1; | |||
| long desired_fill = (long) (bi->reservoir_bits*bi->reservoir_bias); | |||
| if(!bm->managed){ | |||
| /* not a bitrate managed stream, but for API simplicity, we'll | |||
| buffer the packet to keep the code path clean */ | |||
| if(bm->vb)return(-1); /* one has been submitted without | |||
| being claimed */ | |||
| bm->vb=vb; | |||
| return(0); | |||
| } | |||
| bm->vb=vb; | |||
| /* look ahead for avg floater */ | |||
| if(bm->avg_bitsper>0){ | |||
| double slew=0.; | |||
| long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper); | |||
| double slewlimit= 15./bi->slew_damp; | |||
| /* choosing a new floater: | |||
| if we're over target, we slew down | |||
| if we're under target, we slew up | |||
| choose slew as follows: look through packetblobs of this frame | |||
| and set slew as the first in the appropriate direction that | |||
| gives us the slew we want. This may mean no slew if delta is | |||
| already favorable. | |||
| Then limit slew to slew max */ | |||
| if(bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){ | |||
| while(choice>0 && this_bits>avg_target_bits && | |||
| bm->avg_reservoir+(this_bits-avg_target_bits)>desired_fill){ | |||
| choice--; | |||
| this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | |||
| } | |||
| }else if(bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){ | |||
| while(choice+1<PACKETBLOBS && this_bits<avg_target_bits && | |||
| bm->avg_reservoir+(this_bits-avg_target_bits)<desired_fill){ | |||
| choice++; | |||
| this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | |||
| } | |||
| } | |||
| slew=rint(choice-bm->avgfloat)/samples*vi->rate; | |||
| if(slew<-slewlimit)slew=-slewlimit; | |||
| if(slew>slewlimit)slew=slewlimit; | |||
| choice = (int) rint(bm->avgfloat+= slew/vi->rate*samples); | |||
| this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | |||
| } | |||
| /* enforce min(if used) on the current floater (if used) */ | |||
| if(bm->min_bitsper>0){ | |||
| /* do we need to force the bitrate up? */ | |||
| if(this_bits<min_target_bits){ | |||
| while(bm->minmax_reservoir-(min_target_bits-this_bits)<0){ | |||
| choice++; | |||
| if(choice>=PACKETBLOBS)break; | |||
| this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | |||
| } | |||
| } | |||
| } | |||
| /* enforce max (if used) on the current floater (if used) */ | |||
| if(bm->max_bitsper>0){ | |||
| /* do we need to force the bitrate down? */ | |||
| if(this_bits>max_target_bits){ | |||
| while(bm->minmax_reservoir+(this_bits-max_target_bits)>bi->reservoir_bits){ | |||
| choice--; | |||
| if(choice<0)break; | |||
| this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | |||
| } | |||
| } | |||
| } | |||
| /* Choice of packetblobs now made based on floater, and min/max | |||
| requirements. Now boundary check extreme choices */ | |||
| if(choice<0){ | |||
| /* choosing a smaller packetblob is insufficient to trim bitrate. | |||
| frame will need to be truncated */ | |||
| long maxsize=(max_target_bits+(bi->reservoir_bits-bm->minmax_reservoir))/8; | |||
| bm->choice=choice=0; | |||
| if(oggpack_bytes(vbi->packetblob[choice])>maxsize){ | |||
| oggpack_writetrunc(vbi->packetblob[choice],maxsize*8); | |||
| this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | |||
| } | |||
| }else{ | |||
| long minsize=(min_target_bits-bm->minmax_reservoir+7)/8; | |||
| if(choice>=PACKETBLOBS) | |||
| choice=PACKETBLOBS-1; | |||
| bm->choice=choice; | |||
| /* prop up bitrate according to demand. pad this frame out with zeroes */ | |||
| minsize-=oggpack_bytes(vbi->packetblob[choice]); | |||
| while(minsize-->0)oggpack_write(vbi->packetblob[choice],0,8); | |||
| this_bits=oggpack_bytes(vbi->packetblob[choice])*8; | |||
| } | |||
| /* now we have the final packet and the final packet size. Update statistics */ | |||
| /* min and max reservoir */ | |||
| if(bm->min_bitsper>0 || bm->max_bitsper>0){ | |||
| if(max_target_bits>0 && this_bits>max_target_bits){ | |||
| bm->minmax_reservoir+=(this_bits-max_target_bits); | |||
| }else if(min_target_bits>0 && this_bits<min_target_bits){ | |||
| bm->minmax_reservoir+=(this_bits-min_target_bits); | |||
| }else{ | |||
| /* inbetween; we want to take reservoir toward but not past desired_fill */ | |||
| if(bm->minmax_reservoir>desired_fill){ | |||
| if(max_target_bits>0){ /* logical bulletproofing against initialization state */ | |||
| bm->minmax_reservoir+=(this_bits-max_target_bits); | |||
| if(bm->minmax_reservoir<desired_fill)bm->minmax_reservoir=desired_fill; | |||
| }else{ | |||
| bm->minmax_reservoir=desired_fill; | |||
| } | |||
| }else{ | |||
| if(min_target_bits>0){ /* logical bulletproofing against initialization state */ | |||
| bm->minmax_reservoir+=(this_bits-min_target_bits); | |||
| if(bm->minmax_reservoir>desired_fill)bm->minmax_reservoir=desired_fill; | |||
| }else{ | |||
| bm->minmax_reservoir=desired_fill; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /* avg reservoir */ | |||
| if(bm->avg_bitsper>0){ | |||
| long avg_target_bits=(vb->W?bm->avg_bitsper*bm->short_per_long:bm->avg_bitsper); | |||
| bm->avg_reservoir+=this_bits-avg_target_bits; | |||
| } | |||
| return(0); | |||
| } | |||
| int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd,ogg_packet *op){ | |||
| private_state *b=(private_state*)vd->backend_state; | |||
| bitrate_manager_state *bm=&b->bms; | |||
| vorbis_block *vb=bm->vb; | |||
| int choice=PACKETBLOBS/2; | |||
| if(!vb)return 0; | |||
| if(op){ | |||
| vorbis_block_internal *vbi=(vorbis_block_internal*)vb->internal; | |||
| if(vorbis_bitrate_managed(vb)) | |||
| choice=bm->choice; | |||
| op->packet=oggpack_get_buffer(vbi->packetblob[choice]); | |||
| op->bytes=oggpack_bytes(vbi->packetblob[choice]); | |||
| op->b_o_s=0; | |||
| op->e_o_s=vb->eofflag; | |||
| op->granulepos=vb->granulepos; | |||
| op->packetno=vb->sequence; /* for sake of completeness */ | |||
| } | |||
| bm->vb=0; | |||
| return(1); | |||
| } | |||
| @@ -1,59 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: bitrate tracking and management | |||
| last mod: $Id: bitrate.h 13293 2007-07-24 00:09:47Z xiphmont $ | |||
| ********************************************************************/ | |||
| #ifndef _V_BITRATE_H_ | |||
| #define _V_BITRATE_H_ | |||
| #include "../../codec.h" | |||
| #include "codec_internal.h" | |||
| #include "os.h" | |||
| /* encode side bitrate tracking */ | |||
| typedef struct bitrate_manager_state { | |||
| int managed; | |||
| long avg_reservoir; | |||
| long minmax_reservoir; | |||
| long avg_bitsper; | |||
| long min_bitsper; | |||
| long max_bitsper; | |||
| long short_per_long; | |||
| double avgfloat; | |||
| vorbis_block *vb; | |||
| int choice; | |||
| } bitrate_manager_state; | |||
| typedef struct bitrate_manager_info{ | |||
| long avg_rate; | |||
| long min_rate; | |||
| long max_rate; | |||
| long reservoir_bits; | |||
| double reservoir_bias; | |||
| double slew_damp; | |||
| } bitrate_manager_info; | |||
| extern void vorbis_bitrate_init(vorbis_info *vi,bitrate_manager_state *bs); | |||
| extern void vorbis_bitrate_clear(bitrate_manager_state *bs); | |||
| extern int vorbis_bitrate_managed(vorbis_block *vb); | |||
| extern int vorbis_bitrate_addblock(vorbis_block *vb); | |||
| extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, ogg_packet *op); | |||
| #endif | |||
| @@ -1,479 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: basic codebook pack/unpack/code/decode operations | |||
| last mod: $Id: codebook.c 17553 2010-10-21 17:54:26Z tterribe $ | |||
| ********************************************************************/ | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <math.h> | |||
| #include "../../ogg.h" | |||
| #include "../../codec.h" | |||
| #include "codebook.h" | |||
| #include "scales.h" | |||
| #include "misc.h" | |||
| #include "os.h" | |||
| /* packs the given codebook into the bitstream **************************/ | |||
| int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){ | |||
| long i,j; | |||
| int ordered=0; | |||
| /* first the basic parameters */ | |||
| oggpack_write(opb,0x564342,24); | |||
| oggpack_write(opb,c->dim,16); | |||
| oggpack_write(opb,c->entries,24); | |||
| /* pack the codewords. There are two packings; length ordered and | |||
| length random. Decide between the two now. */ | |||
| for(i=1;i<c->entries;i++) | |||
| if(c->lengthlist[i-1]==0 || c->lengthlist[i]<c->lengthlist[i-1])break; | |||
| if(i==c->entries)ordered=1; | |||
| if(ordered){ | |||
| /* length ordered. We only need to say how many codewords of | |||
| each length. The actual codewords are generated | |||
| deterministically */ | |||
| long count=0; | |||
| oggpack_write(opb,1,1); /* ordered */ | |||
| oggpack_write(opb,c->lengthlist[0]-1,5); /* 1 to 32 */ | |||
| for(i=1;i<c->entries;i++){ | |||
| long thisx=c->lengthlist[i]; | |||
| long last=c->lengthlist[i-1]; | |||
| if(thisx>last){ | |||
| for(j=last;j<thisx;j++){ | |||
| oggpack_write(opb,i-count,_ilog(c->entries-count)); | |||
| count=i; | |||
| } | |||
| } | |||
| } | |||
| oggpack_write(opb,i-count,_ilog(c->entries-count)); | |||
| }else{ | |||
| /* length random. Again, we don't code the codeword itself, just | |||
| the length. This time, though, we have to encode each length */ | |||
| oggpack_write(opb,0,1); /* unordered */ | |||
| /* algortihmic mapping has use for 'unused entries', which we tag | |||
| here. The algorithmic mapping happens as usual, but the unused | |||
| entry has no codeword. */ | |||
| for(i=0;i<c->entries;i++) | |||
| if(c->lengthlist[i]==0)break; | |||
| if(i==c->entries){ | |||
| oggpack_write(opb,0,1); /* no unused entries */ | |||
| for(i=0;i<c->entries;i++) | |||
| oggpack_write(opb,c->lengthlist[i]-1,5); | |||
| }else{ | |||
| oggpack_write(opb,1,1); /* we have unused entries; thus we tag */ | |||
| for(i=0;i<c->entries;i++){ | |||
| if(c->lengthlist[i]==0){ | |||
| oggpack_write(opb,0,1); | |||
| }else{ | |||
| oggpack_write(opb,1,1); | |||
| oggpack_write(opb,c->lengthlist[i]-1,5); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /* is the entry number the desired return value, or do we have a | |||
| mapping? If we have a mapping, what type? */ | |||
| oggpack_write(opb,c->maptype,4); | |||
| switch(c->maptype){ | |||
| case 0: | |||
| /* no mapping */ | |||
| break; | |||
| case 1:case 2: | |||
| /* implicitly populated value mapping */ | |||
| /* explicitly populated value mapping */ | |||
| if(!c->quantlist){ | |||
| /* no quantlist? error */ | |||
| return(-1); | |||
| } | |||
| /* values that define the dequantization */ | |||
| oggpack_write(opb,c->q_min,32); | |||
| oggpack_write(opb,c->q_delta,32); | |||
| oggpack_write(opb,c->q_quant-1,4); | |||
| oggpack_write(opb,c->q_sequencep,1); | |||
| { | |||
| int quantvals; | |||
| switch(c->maptype){ | |||
| case 1: | |||
| /* a single column of (c->entries/c->dim) quantized values for | |||
| building a full value list algorithmically (square lattice) */ | |||
| quantvals=_book_maptype1_quantvals(c); | |||
| break; | |||
| case 2: | |||
| /* every value (c->entries*c->dim total) specified explicitly */ | |||
| quantvals=c->entries*c->dim; | |||
| break; | |||
| default: /* NOT_REACHABLE */ | |||
| quantvals=-1; | |||
| } | |||
| /* quantized values */ | |||
| for(i=0;i<quantvals;i++) | |||
| oggpack_write(opb,labs(c->quantlist[i]),c->q_quant); | |||
| } | |||
| break; | |||
| default: | |||
| /* error case; we don't have any other map types now */ | |||
| return(-1); | |||
| } | |||
| return(0); | |||
| } | |||
| /* unpacks a codebook from the packet buffer into the codebook struct, | |||
| readies the codebook auxiliary structures for decode *************/ | |||
| static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){ | |||
| long i,j; | |||
| static_codebook *s=(static_codebook*)_ogg_calloc(1,sizeof(*s)); | |||
| s->allocedp=1; | |||
| /* make sure alignment is correct */ | |||
| if(oggpack_read(opb,24)!=0x564342)goto _eofout; | |||
| /* first the basic parameters */ | |||
| s->dim=oggpack_read(opb,16); | |||
| s->entries=oggpack_read(opb,24); | |||
| if(s->entries==-1)goto _eofout; | |||
| if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout; | |||
| /* codeword ordering.... length ordered or unordered? */ | |||
| switch((int)oggpack_read(opb,1)){ | |||
| case 0:{ | |||
| long unused; | |||
| /* allocated but unused entries? */ | |||
| unused=oggpack_read(opb,1); | |||
| if((s->entries*(unused?1:5)+7)>>3>opb->storage-oggpack_bytes(opb)) | |||
| goto _eofout; | |||
| /* unordered */ | |||
| s->lengthlist=(long*)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); | |||
| /* allocated but unused entries? */ | |||
| if(unused){ | |||
| /* yes, unused entries */ | |||
| for(i=0;i<s->entries;i++){ | |||
| if(oggpack_read(opb,1)){ | |||
| long num=oggpack_read(opb,5); | |||
| if(num==-1)goto _eofout; | |||
| s->lengthlist[i]=num+1; | |||
| }else | |||
| s->lengthlist[i]=0; | |||
| } | |||
| }else{ | |||
| /* all entries used; no tagging */ | |||
| for(i=0;i<s->entries;i++){ | |||
| long num=oggpack_read(opb,5); | |||
| if(num==-1)goto _eofout; | |||
| s->lengthlist[i]=num+1; | |||
| } | |||
| } | |||
| break; | |||
| } | |||
| case 1: | |||
| /* ordered */ | |||
| { | |||
| long length=oggpack_read(opb,5)+1; | |||
| if(length==0)goto _eofout; | |||
| s->lengthlist=(long*)_ogg_malloc(sizeof(*s->lengthlist)*s->entries); | |||
| for(i=0;i<s->entries;){ | |||
| long num=oggpack_read(opb,_ilog(s->entries-i)); | |||
| if(num==-1)goto _eofout; | |||
| if(length>32 || num>s->entries-i || | |||
| (num>0 && (num-1)>>(length-1)>1)){ | |||
| goto _errout; | |||
| } | |||
| if(length>32)goto _errout; | |||
| for(j=0;j<num;j++,i++) | |||
| s->lengthlist[i]=length; | |||
| length++; | |||
| } | |||
| } | |||
| break; | |||
| default: | |||
| /* EOF */ | |||
| goto _eofout; | |||
| } | |||
| /* Do we have a mapping to unpack? */ | |||
| switch((s->maptype=oggpack_read(opb,4))){ | |||
| case 0: | |||
| /* no mapping */ | |||
| break; | |||
| case 1: case 2: | |||
| /* implicitly populated value mapping */ | |||
| /* explicitly populated value mapping */ | |||
| s->q_min=oggpack_read(opb,32); | |||
| s->q_delta=oggpack_read(opb,32); | |||
| s->q_quant=oggpack_read(opb,4)+1; | |||
| s->q_sequencep=oggpack_read(opb,1); | |||
| if(s->q_sequencep==-1)goto _eofout; | |||
| { | |||
| int quantvals=0; | |||
| switch(s->maptype){ | |||
| case 1: | |||
| quantvals=(s->dim==0?0:_book_maptype1_quantvals(s)); | |||
| break; | |||
| case 2: | |||
| quantvals=s->entries*s->dim; | |||
| break; | |||
| } | |||
| /* quantized values */ | |||
| if(((quantvals * s->q_quant + 7) >> 3) > opb->storage-oggpack_bytes(opb)) | |||
| goto _eofout; | |||
| s->quantlist=(long*)_ogg_malloc(sizeof(*s->quantlist)*quantvals); | |||
| for(i=0;i<quantvals;i++) | |||
| s->quantlist[i]=oggpack_read(opb,s->q_quant); | |||
| if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout; | |||
| } | |||
| break; | |||
| default: | |||
| goto _errout; | |||
| } | |||
| /* all set */ | |||
| return(s); | |||
| _errout: | |||
| _eofout: | |||
| vorbis_staticbook_destroy(s); | |||
| return(NULL); | |||
| } | |||
| /* returns the number of bits ************************************************/ | |||
| int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b){ | |||
| if(a<0 || a>=book->c->entries)return(0); | |||
| oggpack_write(b,book->codelist[a],book->c->lengthlist[a]); | |||
| return(book->c->lengthlist[a]); | |||
| } | |||
| /* the 'eliminate the decode tree' optimization actually requires the | |||
| codewords to be MSb first, not LSb. This is an annoying inelegancy | |||
| (and one of the first places where carefully thought out design | |||
| turned out to be wrong; Vorbis II and future Ogg codecs should go | |||
| to an MSb bitpacker), but not actually the huge hit it appears to | |||
| be. The first-stage decode table catches most words so that | |||
| bitreverse is not in the main execution path. */ | |||
| static ogg_uint32_t bitreverse(ogg_uint32_t x){ | |||
| x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000); | |||
| x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00); | |||
| x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0); | |||
| x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc); | |||
| return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa); | |||
| } | |||
| STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){ | |||
| int read=book->dec_maxlength; | |||
| long lo,hi; | |||
| long lok = oggpack_look(b,book->dec_firsttablen); | |||
| if (lok >= 0) { | |||
| long entry = book->dec_firsttable[lok]; | |||
| if(entry&0x80000000UL){ | |||
| lo=(entry>>15)&0x7fff; | |||
| hi=book->used_entries-(entry&0x7fff); | |||
| }else{ | |||
| oggpack_adv(b, book->dec_codelengths[entry-1]); | |||
| return(entry-1); | |||
| } | |||
| }else{ | |||
| lo=0; | |||
| hi=book->used_entries; | |||
| } | |||
| lok = oggpack_look(b, read); | |||
| while(lok<0 && read>1) | |||
| lok = oggpack_look(b, --read); | |||
| if(lok<0)return -1; | |||
| /* bisect search for the codeword in the ordered list */ | |||
| { | |||
| ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok); | |||
| while(hi-lo>1){ | |||
| long p=(hi-lo)>>1; | |||
| long test=book->codelist[lo+p]>testword; | |||
| lo+=p&(test-1); | |||
| hi-=p&(-test); | |||
| } | |||
| if(book->dec_codelengths[lo]<=read){ | |||
| oggpack_adv(b, book->dec_codelengths[lo]); | |||
| return(lo); | |||
| } | |||
| } | |||
| oggpack_adv(b, read); | |||
| return(-1); | |||
| } | |||
| /* Decode side is specced and easier, because we don't need to find | |||
| matches using different criteria; we simply read and map. There are | |||
| two things we need to do 'depending': | |||
| We may need to support interleave. We don't really, but it's | |||
| convenient to do it here rather than rebuild the vector later. | |||
| Cascades may be additive or multiplicitive; this is not inherent in | |||
| the codebook, but set in the code using the codebook. Like | |||
| interleaving, it's easiest to do it here. | |||
| addmul==0 -> declarative (set the value) | |||
| addmul==1 -> additive | |||
| addmul==2 -> multiplicitive */ | |||
| /* returns the [original, not compacted] entry number or -1 on eof *********/ | |||
| long vorbis_book_decode(codebook *book, oggpack_buffer *b){ | |||
| if(book->used_entries>0){ | |||
| long packed_entry=decode_packed_entry_number(book,b); | |||
| if(packed_entry>=0) | |||
| return(book->dec_index[packed_entry]); | |||
| } | |||
| /* if there's no dec_index, the codebook unpacking isn't collapsed */ | |||
| return(-1); | |||
| } | |||
| /* returns 0 on OK or -1 on eof *************************************/ | |||
| long vorbis_book_decodevs_add(codebook *book,float *a,oggpack_buffer *b,int n){ | |||
| if(book->used_entries>0){ | |||
| int step=n/book->dim; | |||
| long *entry = (long*)alloca(sizeof(*entry)*step); | |||
| float **t = (float**)alloca(sizeof(*t)*step); | |||
| int i,j,o; | |||
| for (i = 0; i < step; i++) { | |||
| entry[i]=decode_packed_entry_number(book,b); | |||
| if(entry[i]==-1)return(-1); | |||
| t[i] = book->valuelist+entry[i]*book->dim; | |||
| } | |||
| for(i=0,o=0;i<book->dim;i++,o+=step) | |||
| for (j=0;j<step;j++) | |||
| a[o+j]+=t[j][i]; | |||
| } | |||
| return(0); | |||
| } | |||
| long vorbis_book_decodev_add(codebook *book,float *a,oggpack_buffer *b,int n){ | |||
| if(book->used_entries>0){ | |||
| int i,j,entry; | |||
| float *t; | |||
| if(book->dim>8){ | |||
| for(i=0;i<n;){ | |||
| entry = decode_packed_entry_number(book,b); | |||
| if(entry==-1)return(-1); | |||
| t = book->valuelist+entry*book->dim; | |||
| for (j=0;j<book->dim;) | |||
| a[i++]+=t[j++]; | |||
| } | |||
| }else{ | |||
| for(i=0;i<n;){ | |||
| entry = decode_packed_entry_number(book,b); | |||
| if(entry==-1)return(-1); | |||
| t = book->valuelist+entry*book->dim; | |||
| j=0; | |||
| switch((int)book->dim){ | |||
| case 8: | |||
| a[i++]+=t[j++]; | |||
| case 7: | |||
| a[i++]+=t[j++]; | |||
| case 6: | |||
| a[i++]+=t[j++]; | |||
| case 5: | |||
| a[i++]+=t[j++]; | |||
| case 4: | |||
| a[i++]+=t[j++]; | |||
| case 3: | |||
| a[i++]+=t[j++]; | |||
| case 2: | |||
| a[i++]+=t[j++]; | |||
| case 1: | |||
| a[i++]+=t[j++]; | |||
| case 0: | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| return(0); | |||
| } | |||
| long vorbis_book_decodev_set(codebook *book,float *a,oggpack_buffer *b,int n){ | |||
| if(book->used_entries>0){ | |||
| int i,j,entry; | |||
| float *t; | |||
| for(i=0;i<n;){ | |||
| entry = decode_packed_entry_number(book,b); | |||
| if(entry==-1)return(-1); | |||
| t = book->valuelist+entry*book->dim; | |||
| for (j=0;j<book->dim;) | |||
| a[i++]=t[j++]; | |||
| } | |||
| }else{ | |||
| int i,j; | |||
| for(i=0;i<n;){ | |||
| for (j=0;j<book->dim;) | |||
| a[i++]=0.f; | |||
| } | |||
| } | |||
| return(0); | |||
| } | |||
| long vorbis_book_decodevv_add(codebook *book,float **a,long offset,int ch, | |||
| oggpack_buffer *b,int n){ | |||
| long i,j,entry; | |||
| int chptr=0; | |||
| if(book->used_entries>0){ | |||
| for(i=offset/ch;i<(offset+n)/ch;){ | |||
| entry = decode_packed_entry_number(book,b); | |||
| if(entry==-1)return(-1); | |||
| { | |||
| const float *t = book->valuelist+entry*book->dim; | |||
| for (j=0;j<book->dim;j++){ | |||
| a[chptr++][i]+=t[j]; | |||
| if(chptr==ch){ | |||
| chptr=0; | |||
| i++; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| return(0); | |||
| } | |||
| @@ -1,119 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: basic shared codebook operations | |||
| last mod: $Id: codebook.h 17030 2010-03-25 06:52:55Z xiphmont $ | |||
| ********************************************************************/ | |||
| #ifndef _V_CODEBOOK_H_ | |||
| #define _V_CODEBOOK_H_ | |||
| #include "../../ogg.h" | |||
| /* This structure encapsulates huffman and VQ style encoding books; it | |||
| doesn't do anything specific to either. | |||
| valuelist/quantlist are nonNULL (and q_* significant) only if | |||
| there's entry->value mapping to be done. | |||
| If encode-side mapping must be done (and thus the entry needs to be | |||
| hunted), the auxiliary encode pointer will point to a decision | |||
| tree. This is true of both VQ and huffman, but is mostly useful | |||
| with VQ. | |||
| */ | |||
| typedef struct static_codebook{ | |||
| long dim; /* codebook dimensions (elements per vector) */ | |||
| long entries; /* codebook entries */ | |||
| long *lengthlist; /* codeword lengths in bits */ | |||
| /* mapping ***************************************************************/ | |||
| int maptype; /* 0=none | |||
| 1=implicitly populated values from map column | |||
| 2=listed arbitrary values */ | |||
| /* The below does a linear, single monotonic sequence mapping. */ | |||
| long q_min; /* packed 32 bit float; quant value 0 maps to minval */ | |||
| long q_delta; /* packed 32 bit float; val 1 - val 0 == delta */ | |||
| int q_quant; /* bits: 0 < quant <= 16 */ | |||
| int q_sequencep; /* bitflag */ | |||
| long *quantlist; /* map == 1: (int)(entries^(1/dim)) element column map | |||
| map == 2: list of dim*entries quantized entry vals | |||
| */ | |||
| int allocedp; | |||
| } static_codebook; | |||
| typedef struct codebook{ | |||
| long dim; /* codebook dimensions (elements per vector) */ | |||
| long entries; /* codebook entries */ | |||
| long used_entries; /* populated codebook entries */ | |||
| const static_codebook *c; | |||
| /* for encode, the below are entry-ordered, fully populated */ | |||
| /* for decode, the below are ordered by bitreversed codeword and only | |||
| used entries are populated */ | |||
| float *valuelist; /* list of dim*entries actual entry values */ | |||
| ogg_uint32_t *codelist; /* list of bitstream codewords for each entry */ | |||
| int *dec_index; /* only used if sparseness collapsed */ | |||
| char *dec_codelengths; | |||
| ogg_uint32_t *dec_firsttable; | |||
| int dec_firsttablen; | |||
| int dec_maxlength; | |||
| /* The current encoder uses only centered, integer-only lattice books. */ | |||
| int quantvals; | |||
| int minval; | |||
| int delta; | |||
| } codebook; | |||
| extern void vorbis_staticbook_destroy(static_codebook *b); | |||
| extern int vorbis_book_init_encode(codebook *dest,const static_codebook *source); | |||
| extern int vorbis_book_init_decode(codebook *dest,const static_codebook *source); | |||
| extern void vorbis_book_clear(codebook *b); | |||
| extern float *_book_unquantize(const static_codebook *b,int n,int *map); | |||
| extern float *_book_logdist(const static_codebook *b,float *vals); | |||
| extern float _float32_unpack(long val); | |||
| extern long _float32_pack(float val); | |||
| extern int _best(codebook *book, float *a, int step); | |||
| extern int _ilog(unsigned int v); | |||
| extern long _book_maptype1_quantvals(const static_codebook *b); | |||
| extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul); | |||
| extern long vorbis_book_codeword(codebook *book,int entry); | |||
| extern long vorbis_book_codelen(codebook *book,int entry); | |||
| extern int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *b); | |||
| extern static_codebook *vorbis_staticbook_unpack(oggpack_buffer *b); | |||
| extern int vorbis_book_encode(codebook *book, int a, oggpack_buffer *b); | |||
| extern long vorbis_book_decode(codebook *book, oggpack_buffer *b); | |||
| extern long vorbis_book_decodevs_add(codebook *book, float *a, | |||
| oggpack_buffer *b,int n); | |||
| extern long vorbis_book_decodev_set(codebook *book, float *a, | |||
| oggpack_buffer *b,int n); | |||
| extern long vorbis_book_decodev_add(codebook *book, float *a, | |||
| oggpack_buffer *b,int n); | |||
| extern long vorbis_book_decodevv_add(codebook *book, float **a, | |||
| long off,int ch, | |||
| oggpack_buffer *b,int n); | |||
| #endif | |||
| @@ -1,187 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: libvorbis codec headers | |||
| last mod: $Id: codec_internal.h 16227 2009-07-08 06:58:46Z xiphmont $ | |||
| ********************************************************************/ | |||
| #ifndef _V_CODECI_H_ | |||
| #define _V_CODECI_H_ | |||
| #include "envelope.h" | |||
| #include "codebook.h" | |||
| #define BLOCKTYPE_IMPULSE 0 | |||
| #define BLOCKTYPE_PADDING 1 | |||
| #define BLOCKTYPE_TRANSITION 0 | |||
| #define BLOCKTYPE_LONG 1 | |||
| #define PACKETBLOBS 15 | |||
| typedef struct vorbis_block_internal{ | |||
| float **pcmdelay; /* this is a pointer into local storage */ | |||
| float ampmax; | |||
| int blocktype; | |||
| oggpack_buffer *packetblob[PACKETBLOBS]; /* initialized, must be freed; | |||
| blob [PACKETBLOBS/2] points to | |||
| the oggpack_buffer in the | |||
| main vorbis_block */ | |||
| } vorbis_block_internal; | |||
| typedef void vorbis_look_floor; | |||
| typedef void vorbis_look_residue; | |||
| typedef void vorbis_look_transform; | |||
| /* mode ************************************************************/ | |||
| typedef struct { | |||
| int blockflag; | |||
| int windowtype; | |||
| int transformtype; | |||
| int mapping; | |||
| } vorbis_info_mode; | |||
| typedef void vorbis_info_floor; | |||
| typedef void vorbis_info_residue; | |||
| typedef void vorbis_info_mapping; | |||
| #include "psy.h" | |||
| #include "bitrate.h" | |||
| static int ilog(unsigned int v){ | |||
| int ret=0; | |||
| while(v){ | |||
| ret++; | |||
| v>>=1; | |||
| } | |||
| return(ret); | |||
| } | |||
| static int ilog2(unsigned int v){ | |||
| int ret=0; | |||
| if(v)--v; | |||
| while(v){ | |||
| ret++; | |||
| v>>=1; | |||
| } | |||
| return(ret); | |||
| } | |||
| typedef struct private_state { | |||
| /* local lookup storage */ | |||
| envelope_lookup *ve; /* envelope lookup */ | |||
| int window[2]; | |||
| vorbis_look_transform **transform[2]; /* block, type */ | |||
| drft_lookup fft_look[2]; | |||
| int modebits; | |||
| vorbis_look_floor **flr; | |||
| vorbis_look_residue **residue; | |||
| vorbis_look_psy *psy; | |||
| vorbis_look_psy_global *psy_g_look; | |||
| /* local storage, only used on the encoding side. This way the | |||
| application does not need to worry about freeing some packets' | |||
| memory and not others'; packet storage is always tracked. | |||
| Cleared next call to a _dsp_ function */ | |||
| unsigned char *header; | |||
| unsigned char *header1; | |||
| unsigned char *header2; | |||
| bitrate_manager_state bms; | |||
| ogg_int64_t sample_count; | |||
| } private_state; | |||
| /* codec_setup_info contains all the setup information specific to the | |||
| specific compression/decompression mode in progress (eg, | |||
| psychoacoustic settings, channel setup, options, codebook | |||
| etc). | |||
| *********************************************************************/ | |||
| #include "highlevel.h" | |||
| typedef struct codec_setup_info { | |||
| /* Vorbis supports only short and long blocks, but allows the | |||
| encoder to choose the sizes */ | |||
| long blocksizes[2]; | |||
| /* modes are the primary means of supporting on-the-fly different | |||
| blocksizes, different channel mappings (LR or M/A), | |||
| different residue backends, etc. Each mode consists of a | |||
| blocksize flag and a mapping (along with the mapping setup */ | |||
| int modes; | |||
| int maps; | |||
| int floors; | |||
| int residues; | |||
| int books; | |||
| int psys; /* encode only */ | |||
| vorbis_info_mode *mode_param[64]; | |||
| int map_type[64]; | |||
| vorbis_info_mapping *map_param[64]; | |||
| int floor_type[64]; | |||
| vorbis_info_floor *floor_param[64]; | |||
| int residue_type[64]; | |||
| vorbis_info_residue *residue_param[64]; | |||
| static_codebook *book_param[256]; | |||
| codebook *fullbooks; | |||
| vorbis_info_psy *psy_param[4]; /* encode only */ | |||
| vorbis_info_psy_global psy_g_param; | |||
| bitrate_manager_info bi; | |||
| highlevel_encode_setup hi; /* used only by vorbisenc.c. It's a | |||
| highly redundant structure, but | |||
| improves clarity of program flow. */ | |||
| int halfrate_flag; /* painless downsample for decode */ | |||
| } codec_setup_info; | |||
| extern vorbis_look_psy_global *_vp_global_look(vorbis_info *vi); | |||
| extern void _vp_global_free(vorbis_look_psy_global *look); | |||
| typedef struct { | |||
| int sorted_index[VIF_POSIT+2]; | |||
| int forward_index[VIF_POSIT+2]; | |||
| int reverse_index[VIF_POSIT+2]; | |||
| int hineighbor[VIF_POSIT]; | |||
| int loneighbor[VIF_POSIT]; | |||
| int posts; | |||
| int n; | |||
| int quant_q; | |||
| vorbis_info_floor1 *vi; | |||
| long phrasebits; | |||
| long postbits; | |||
| long frames; | |||
| } vorbis_look_floor1; | |||
| extern int *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look, | |||
| const float *logmdct, /* in */ | |||
| const float *logmask); | |||
| extern int *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look, | |||
| int *A,int *B, | |||
| int del); | |||
| extern int floor1_encode(oggpack_buffer *opb,vorbis_block *vb, | |||
| vorbis_look_floor1 *look, | |||
| int *post,int *ilogmask); | |||
| #endif | |||
| @@ -1,375 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: PCM data envelope analysis | |||
| last mod: $Id: envelope.c 16227 2009-07-08 06:58:46Z xiphmont $ | |||
| ********************************************************************/ | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <math.h> | |||
| #include "../../ogg.h" | |||
| #include "../../codec.h" | |||
| #include "codec_internal.h" | |||
| #include "os.h" | |||
| #include "scales.h" | |||
| #include "envelope.h" | |||
| #include "mdct.h" | |||
| #include "misc.h" | |||
| void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi){ | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| vorbis_info_psy_global *gi=&ci->psy_g_param; | |||
| int ch=vi->channels; | |||
| int i,j; | |||
| int n=e->winlength=128; | |||
| e->searchstep=64; /* not random */ | |||
| e->minenergy=gi->preecho_minenergy; | |||
| e->ch=ch; | |||
| e->storage=128; | |||
| e->cursor=ci->blocksizes[1]/2; | |||
| e->mdct_win=(float*)_ogg_calloc(n,sizeof(*e->mdct_win)); | |||
| mdct_init(&e->mdct,n); | |||
| for(i=0;i<n;i++){ | |||
| e->mdct_win[i]=sin(i/(n-1.)*M_PI); | |||
| e->mdct_win[i]*=e->mdct_win[i]; | |||
| } | |||
| /* magic follows */ | |||
| e->band[0].begin=2; e->band[0].end=4; | |||
| e->band[1].begin=4; e->band[1].end=5; | |||
| e->band[2].begin=6; e->band[2].end=6; | |||
| e->band[3].begin=9; e->band[3].end=8; | |||
| e->band[4].begin=13; e->band[4].end=8; | |||
| e->band[5].begin=17; e->band[5].end=8; | |||
| e->band[6].begin=22; e->band[6].end=8; | |||
| for(j=0;j<VE_BANDS;j++){ | |||
| n=e->band[j].end; | |||
| e->band[j].window=(float*)_ogg_malloc(n*sizeof(*e->band[0].window)); | |||
| for(i=0;i<n;i++){ | |||
| e->band[j].window[i]=sin((i+.5)/n*M_PI); | |||
| e->band[j].total+=e->band[j].window[i]; | |||
| } | |||
| e->band[j].total=1./e->band[j].total; | |||
| } | |||
| e->filter=(envelope_filter_state*)_ogg_calloc(VE_BANDS*ch,sizeof(*e->filter)); | |||
| e->mark=(int*)_ogg_calloc(e->storage,sizeof(*e->mark)); | |||
| } | |||
| void _ve_envelope_clear(envelope_lookup *e){ | |||
| int i; | |||
| mdct_clear(&e->mdct); | |||
| for(i=0;i<VE_BANDS;i++) | |||
| _ogg_free(e->band[i].window); | |||
| _ogg_free(e->mdct_win); | |||
| _ogg_free(e->filter); | |||
| _ogg_free(e->mark); | |||
| memset(e,0,sizeof(*e)); | |||
| } | |||
| /* fairly straight threshhold-by-band based until we find something | |||
| that works better and isn't patented. */ | |||
| static int _ve_amp(envelope_lookup *ve, | |||
| vorbis_info_psy_global *gi, | |||
| float *data, | |||
| envelope_band *bands, | |||
| envelope_filter_state *filters){ | |||
| long n=ve->winlength; | |||
| int ret=0; | |||
| long i,j; | |||
| float decay; | |||
| /* we want to have a 'minimum bar' for energy, else we're just | |||
| basing blocks on quantization noise that outweighs the signal | |||
| itself (for low power signals) */ | |||
| float minV=ve->minenergy; | |||
| float *vec=(float*) alloca(n*sizeof(*vec)); | |||
| /* stretch is used to gradually lengthen the number of windows | |||
| considered prevoius-to-potential-trigger */ | |||
| int stretch=max(VE_MINSTRETCH,ve->stretch/2); | |||
| float penalty=gi->stretch_penalty-(ve->stretch/2-VE_MINSTRETCH); | |||
| if(penalty<0.f)penalty=0.f; | |||
| if(penalty>gi->stretch_penalty)penalty=gi->stretch_penalty; | |||
| /*_analysis_output_always("lpcm",seq2,data,n,0,0, | |||
| totalshift+pos*ve->searchstep);*/ | |||
| /* window and transform */ | |||
| for(i=0;i<n;i++) | |||
| vec[i]=data[i]*ve->mdct_win[i]; | |||
| mdct_forward(&ve->mdct,vec,vec); | |||
| /*_analysis_output_always("mdct",seq2,vec,n/2,0,1,0); */ | |||
| /* near-DC spreading function; this has nothing to do with | |||
| psychoacoustics, just sidelobe leakage and window size */ | |||
| { | |||
| float temp=vec[0]*vec[0]+.7*vec[1]*vec[1]+.2*vec[2]*vec[2]; | |||
| int ptr=filters->nearptr; | |||
| /* the accumulation is regularly refreshed from scratch to avoid | |||
| floating point creep */ | |||
| if(ptr==0){ | |||
| decay=filters->nearDC_acc=filters->nearDC_partialacc+temp; | |||
| filters->nearDC_partialacc=temp; | |||
| }else{ | |||
| decay=filters->nearDC_acc+=temp; | |||
| filters->nearDC_partialacc+=temp; | |||
| } | |||
| filters->nearDC_acc-=filters->nearDC[ptr]; | |||
| filters->nearDC[ptr]=temp; | |||
| decay*=(1./(VE_NEARDC+1)); | |||
| filters->nearptr++; | |||
| if(filters->nearptr>=VE_NEARDC)filters->nearptr=0; | |||
| decay=todB(&decay)*.5-15.f; | |||
| } | |||
| /* perform spreading and limiting, also smooth the spectrum. yes, | |||
| the MDCT results in all real coefficients, but it still *behaves* | |||
| like real/imaginary pairs */ | |||
| for(i=0;i<n/2;i+=2){ | |||
| float val=vec[i]*vec[i]+vec[i+1]*vec[i+1]; | |||
| val=todB(&val)*.5f; | |||
| if(val<decay)val=decay; | |||
| if(val<minV)val=minV; | |||
| vec[i>>1]=val; | |||
| decay-=8.; | |||
| } | |||
| /*_analysis_output_always("spread",seq2++,vec,n/4,0,0,0);*/ | |||
| /* perform preecho/postecho triggering by band */ | |||
| for(j=0;j<VE_BANDS;j++){ | |||
| float acc=0.; | |||
| float valmax,valmin; | |||
| /* accumulate amplitude */ | |||
| for(i=0;i<bands[j].end;i++) | |||
| acc+=vec[i+bands[j].begin]*bands[j].window[i]; | |||
| acc*=bands[j].total; | |||
| /* convert amplitude to delta */ | |||
| { | |||
| int p,thisx=filters[j].ampptr; | |||
| float postmax,postmin,premax=-99999.f,premin=99999.f; | |||
| p=thisx; | |||
| p--; | |||
| if(p<0)p+=VE_AMP; | |||
| postmax=max(acc,filters[j].ampbuf[p]); | |||
| postmin=min(acc,filters[j].ampbuf[p]); | |||
| for(i=0;i<stretch;i++){ | |||
| p--; | |||
| if(p<0)p+=VE_AMP; | |||
| premax=max(premax,filters[j].ampbuf[p]); | |||
| premin=min(premin,filters[j].ampbuf[p]); | |||
| } | |||
| valmin=postmin-premin; | |||
| valmax=postmax-premax; | |||
| /*filters[j].markers[pos]=valmax;*/ | |||
| filters[j].ampbuf[thisx]=acc; | |||
| filters[j].ampptr++; | |||
| if(filters[j].ampptr>=VE_AMP)filters[j].ampptr=0; | |||
| } | |||
| /* look at min/max, decide trigger */ | |||
| if(valmax>gi->preecho_thresh[j]+penalty){ | |||
| ret|=1; | |||
| ret|=4; | |||
| } | |||
| if(valmin<gi->postecho_thresh[j]-penalty)ret|=2; | |||
| } | |||
| return(ret); | |||
| } | |||
| #if 0 | |||
| static int seq=0; | |||
| static ogg_int64_t totalshift=-1024; | |||
| #endif | |||
| long _ve_envelope_search(vorbis_dsp_state *v){ | |||
| vorbis_info *vi=v->vi; | |||
| codec_setup_info *ci=(codec_setup_info *)vi->codec_setup; | |||
| vorbis_info_psy_global *gi=&ci->psy_g_param; | |||
| envelope_lookup *ve=((private_state *)(v->backend_state))->ve; | |||
| long i,j; | |||
| int first=ve->current/ve->searchstep; | |||
| int last=v->pcm_current/ve->searchstep-VE_WIN; | |||
| if(first<0)first=0; | |||
| /* make sure we have enough storage to match the PCM */ | |||
| if(last+VE_WIN+VE_POST>ve->storage){ | |||
| ve->storage=last+VE_WIN+VE_POST; /* be sure */ | |||
| ve->mark=(int*)_ogg_realloc(ve->mark,ve->storage*sizeof(*ve->mark)); | |||
| } | |||
| for(j=first;j<last;j++){ | |||
| int ret=0; | |||
| ve->stretch++; | |||
| if(ve->stretch>VE_MAXSTRETCH*2) | |||
| ve->stretch=VE_MAXSTRETCH*2; | |||
| for(i=0;i<ve->ch;i++){ | |||
| float *pcm=v->pcm[i]+ve->searchstep*(j); | |||
| ret|=_ve_amp(ve,gi,pcm,ve->band,ve->filter+i*VE_BANDS); | |||
| } | |||
| ve->mark[j+VE_POST]=0; | |||
| if(ret&1){ | |||
| ve->mark[j]=1; | |||
| ve->mark[j+1]=1; | |||
| } | |||
| if(ret&2){ | |||
| ve->mark[j]=1; | |||
| if(j>0)ve->mark[j-1]=1; | |||
| } | |||
| if(ret&4)ve->stretch=-1; | |||
| } | |||
| ve->current=last*ve->searchstep; | |||
| { | |||
| long centerW=v->centerW; | |||
| long testW= | |||
| centerW+ | |||
| ci->blocksizes[v->W]/4+ | |||
| ci->blocksizes[1]/2+ | |||
| ci->blocksizes[0]/4; | |||
| j=ve->cursor; | |||
| while(j<ve->current-(ve->searchstep)){/* account for postecho | |||
| working back one window */ | |||
| if(j>=testW)return(1); | |||
| ve->cursor=j; | |||
| if(ve->mark[j/ve->searchstep]){ | |||
| if(j>centerW){ | |||
| #if 0 | |||
| if(j>ve->curmark){ | |||
| float *marker=(float*)alloca(v->pcm_current*sizeof(*marker)); | |||
| int l,m; | |||
| memset(marker,0,sizeof(*marker)*v->pcm_current); | |||
| fprintf(stderr,"mark! seq=%d, cursor:%fs time:%fs\n", | |||
| seq, | |||
| (totalshift+ve->cursor)/44100., | |||
| (totalshift+j)/44100.); | |||
| _analysis_output_always("pcmL",seq,v->pcm[0],v->pcm_current,0,0,totalshift); | |||
| _analysis_output_always("pcmR",seq,v->pcm[1],v->pcm_current,0,0,totalshift); | |||
| _analysis_output_always("markL",seq,v->pcm[0],j,0,0,totalshift); | |||
| _analysis_output_always("markR",seq,v->pcm[1],j,0,0,totalshift); | |||
| for(m=0;m<VE_BANDS;m++){ | |||
| char buf[80]; | |||
| sprintf(buf,"delL%d",m); | |||
| for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->filter[m].markers[l]*.1; | |||
| _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift); | |||
| } | |||
| for(m=0;m<VE_BANDS;m++){ | |||
| char buf[80]; | |||
| sprintf(buf,"delR%d",m); | |||
| for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->filter[m+VE_BANDS].markers[l]*.1; | |||
| _analysis_output_always(buf,seq,marker,v->pcm_current,0,0,totalshift); | |||
| } | |||
| for(l=0;l<last;l++)marker[l*ve->searchstep]=ve->mark[l]*.4; | |||
| _analysis_output_always("mark",seq,marker,v->pcm_current,0,0,totalshift); | |||
| seq++; | |||
| } | |||
| #endif | |||
| ve->curmark=j; | |||
| if(j>=testW)return(1); | |||
| return(0); | |||
| } | |||
| } | |||
| j+=ve->searchstep; | |||
| } | |||
| } | |||
| return(-1); | |||
| } | |||
| int _ve_envelope_mark(vorbis_dsp_state *v){ | |||
| envelope_lookup *ve=((private_state *)(v->backend_state))->ve; | |||
| vorbis_info *vi=v->vi; | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| long centerW=v->centerW; | |||
| long beginW=centerW-ci->blocksizes[v->W]/4; | |||
| long endW=centerW+ci->blocksizes[v->W]/4; | |||
| if(v->W){ | |||
| beginW-=ci->blocksizes[v->lW]/4; | |||
| endW+=ci->blocksizes[v->nW]/4; | |||
| }else{ | |||
| beginW-=ci->blocksizes[0]/4; | |||
| endW+=ci->blocksizes[0]/4; | |||
| } | |||
| if(ve->curmark>=beginW && ve->curmark<endW)return(1); | |||
| { | |||
| long first=beginW/ve->searchstep; | |||
| long last=endW/ve->searchstep; | |||
| long i; | |||
| for(i=first;i<last;i++) | |||
| if(ve->mark[i])return(1); | |||
| } | |||
| return(0); | |||
| } | |||
| void _ve_envelope_shift(envelope_lookup *e,long shift){ | |||
| int smallsize=e->current/e->searchstep+VE_POST; /* adjust for placing marks | |||
| ahead of ve->current */ | |||
| int smallshift=shift/e->searchstep; | |||
| memmove(e->mark,e->mark+smallshift,(smallsize-smallshift)*sizeof(*e->mark)); | |||
| #if 0 | |||
| for(i=0;i<VE_BANDS*e->ch;i++) | |||
| memmove(e->filter[i].markers, | |||
| e->filter[i].markers+smallshift, | |||
| (1024-smallshift)*sizeof(*(*e->filter).markers)); | |||
| totalshift+=shift; | |||
| #endif | |||
| e->current-=shift; | |||
| if(e->curmark>=0) | |||
| e->curmark-=shift; | |||
| e->cursor-=shift; | |||
| } | |||
| @@ -1,80 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: PCM data envelope analysis and manipulation | |||
| last mod: $Id: envelope.h 16227 2009-07-08 06:58:46Z xiphmont $ | |||
| ********************************************************************/ | |||
| #ifndef _V_ENVELOPE_ | |||
| #define _V_ENVELOPE_ | |||
| #include "mdct.h" | |||
| #define VE_PRE 16 | |||
| #define VE_WIN 4 | |||
| #define VE_POST 2 | |||
| #define VE_AMP (VE_PRE+VE_POST-1) | |||
| #define VE_BANDS 7 | |||
| #define VE_NEARDC 15 | |||
| #define VE_MINSTRETCH 2 /* a bit less than short block */ | |||
| #define VE_MAXSTRETCH 12 /* one-third full block */ | |||
| typedef struct { | |||
| float ampbuf[VE_AMP]; | |||
| int ampptr; | |||
| float nearDC[VE_NEARDC]; | |||
| float nearDC_acc; | |||
| float nearDC_partialacc; | |||
| int nearptr; | |||
| } envelope_filter_state; | |||
| typedef struct { | |||
| int begin; | |||
| int end; | |||
| float *window; | |||
| float total; | |||
| } envelope_band; | |||
| typedef struct { | |||
| int ch; | |||
| int winlength; | |||
| int searchstep; | |||
| float minenergy; | |||
| mdct_lookup mdct; | |||
| float *mdct_win; | |||
| envelope_band band[VE_BANDS]; | |||
| envelope_filter_state *filter; | |||
| int stretch; | |||
| int *mark; | |||
| long storage; | |||
| long current; | |||
| long curmark; | |||
| long cursor; | |||
| } envelope_lookup; | |||
| extern void _ve_envelope_init(envelope_lookup *e,vorbis_info *vi); | |||
| extern void _ve_envelope_clear(envelope_lookup *e); | |||
| extern long _ve_envelope_search(vorbis_dsp_state *v); | |||
| extern void _ve_envelope_shift(envelope_lookup *e,long shift); | |||
| extern int _ve_envelope_mark(vorbis_dsp_state *v); | |||
| #endif | |||
| @@ -1,223 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: floor backend 0 implementation | |||
| last mod: $Id: floor0.c 17558 2010-10-22 00:24:41Z tterribe $ | |||
| ********************************************************************/ | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <math.h> | |||
| #include "../../ogg.h" | |||
| #include "../../codec.h" | |||
| #include "codec_internal.h" | |||
| #include "registry.h" | |||
| #include "lpc.h" | |||
| #include "lsp.h" | |||
| #include "codebook.h" | |||
| #include "scales.h" | |||
| #include "misc.h" | |||
| #include "os.h" | |||
| #include "misc.h" | |||
| #include <stdio.h> | |||
| typedef struct { | |||
| int ln; | |||
| int m; | |||
| int **linearmap; | |||
| int n[2]; | |||
| vorbis_info_floor0 *vi; | |||
| long bits; | |||
| long frames; | |||
| } vorbis_look_floor0; | |||
| /***********************************************/ | |||
| static void floor0_free_info(vorbis_info_floor *i){ | |||
| vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; | |||
| if(info){ | |||
| memset(info,0,sizeof(*info)); | |||
| _ogg_free(info); | |||
| } | |||
| } | |||
| static void floor0_free_look(vorbis_look_floor *i){ | |||
| vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; | |||
| if(look){ | |||
| if(look->linearmap){ | |||
| if(look->linearmap[0])_ogg_free(look->linearmap[0]); | |||
| if(look->linearmap[1])_ogg_free(look->linearmap[1]); | |||
| _ogg_free(look->linearmap); | |||
| } | |||
| memset(look,0,sizeof(*look)); | |||
| _ogg_free(look); | |||
| } | |||
| } | |||
| static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){ | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| int j; | |||
| vorbis_info_floor0 *info=(vorbis_info_floor0*)_ogg_malloc(sizeof(*info)); | |||
| info->order=oggpack_read(opb,8); | |||
| info->rate=oggpack_read(opb,16); | |||
| info->barkmap=oggpack_read(opb,16); | |||
| info->ampbits=oggpack_read(opb,6); | |||
| info->ampdB=oggpack_read(opb,8); | |||
| info->numbooks=oggpack_read(opb,4)+1; | |||
| if(info->order<1)goto err_out; | |||
| if(info->rate<1)goto err_out; | |||
| if(info->barkmap<1)goto err_out; | |||
| if(info->numbooks<1)goto err_out; | |||
| for(j=0;j<info->numbooks;j++){ | |||
| info->books[j]=oggpack_read(opb,8); | |||
| if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out; | |||
| if(ci->book_param[info->books[j]]->maptype==0)goto err_out; | |||
| if(ci->book_param[info->books[j]]->dim<1)goto err_out; | |||
| } | |||
| return(info); | |||
| err_out: | |||
| floor0_free_info(info); | |||
| return(NULL); | |||
| } | |||
| /* initialize Bark scale and normalization lookups. We could do this | |||
| with static tables, but Vorbis allows a number of possible | |||
| combinations, so it's best to do it computationally. | |||
| The below is authoritative in terms of defining scale mapping. | |||
| Note that the scale depends on the sampling rate as well as the | |||
| linear block and mapping sizes */ | |||
| static void floor0_map_lazy_init(vorbis_block *vb, | |||
| vorbis_info_floor *infoX, | |||
| vorbis_look_floor0 *look){ | |||
| if(!look->linearmap[vb->W]){ | |||
| vorbis_dsp_state *vd=vb->vd; | |||
| vorbis_info *vi=vd->vi; | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| vorbis_info_floor0 *info=(vorbis_info_floor0 *)infoX; | |||
| int W=vb->W; | |||
| int n=ci->blocksizes[W]/2,j; | |||
| /* we choose a scaling constant so that: | |||
| floor(bark(rate/2-1)*C)=mapped-1 | |||
| floor(bark(rate/2)*C)=mapped */ | |||
| float scale=look->ln/toBARK(info->rate/2.f); | |||
| /* the mapping from a linear scale to a smaller bark scale is | |||
| straightforward. We do *not* make sure that the linear mapping | |||
| does not skip bark-scale bins; the decoder simply skips them and | |||
| the encoder may do what it wishes in filling them. They're | |||
| necessary in some mapping combinations to keep the scale spacing | |||
| accurate */ | |||
| look->linearmap[W]=(int*)_ogg_malloc((n+1)*sizeof(**look->linearmap)); | |||
| for(j=0;j<n;j++){ | |||
| int val=floor( toBARK((info->rate/2.f)/n*j) | |||
| *scale); /* bark numbers represent band edges */ | |||
| if(val>=look->ln)val=look->ln-1; /* guard against the approximation */ | |||
| look->linearmap[W][j]=val; | |||
| } | |||
| look->linearmap[W][j]=-1; | |||
| look->n[W]=n; | |||
| } | |||
| } | |||
| static vorbis_look_floor *floor0_look(vorbis_dsp_state* /* vd */, | |||
| vorbis_info_floor *i){ | |||
| vorbis_info_floor0 *info=(vorbis_info_floor0 *)i; | |||
| vorbis_look_floor0 *look=(vorbis_look_floor0*)_ogg_calloc(1,sizeof(*look)); | |||
| look->m=info->order; | |||
| look->ln=info->barkmap; | |||
| look->vi=info; | |||
| look->linearmap=(int**)_ogg_calloc(2,sizeof(*look->linearmap)); | |||
| return look; | |||
| } | |||
| static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){ | |||
| vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; | |||
| vorbis_info_floor0 *info=look->vi; | |||
| int j,k; | |||
| int ampraw=oggpack_read(&vb->opb,info->ampbits); | |||
| if(ampraw>0){ /* also handles the -1 out of data case */ | |||
| long maxval=(1<<info->ampbits)-1; | |||
| float amp=(float)ampraw/maxval*info->ampdB; | |||
| int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks)); | |||
| if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */ | |||
| codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup; | |||
| codebook *b=ci->fullbooks+info->books[booknum]; | |||
| float last=0.f; | |||
| /* the additional b->dim is a guard against any possible stack | |||
| smash; b->dim is provably more than we can overflow the | |||
| vector */ | |||
| float *lsp=(float*)_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+b->dim+1)); | |||
| for(j=0;j<look->m;j+=b->dim) | |||
| if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim)==-1)goto eop; | |||
| for(j=0;j<look->m;){ | |||
| for(k=0;k<b->dim;k++,j++)lsp[j]+=last; | |||
| last=lsp[j-1]; | |||
| } | |||
| lsp[look->m]=amp; | |||
| return(lsp); | |||
| } | |||
| } | |||
| eop: | |||
| return(NULL); | |||
| } | |||
| static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i, | |||
| void *memo,float *out){ | |||
| vorbis_look_floor0 *look=(vorbis_look_floor0 *)i; | |||
| vorbis_info_floor0 *info=look->vi; | |||
| floor0_map_lazy_init(vb,info,look); | |||
| if(memo){ | |||
| float *lsp=(float *)memo; | |||
| float amp=lsp[look->m]; | |||
| /* take the coefficients back to a spectral envelope curve */ | |||
| vorbis_lsp_to_curve(out, | |||
| look->linearmap[vb->W], | |||
| look->n[vb->W], | |||
| look->ln, | |||
| lsp,look->m,amp,(float)info->ampdB); | |||
| return(1); | |||
| } | |||
| memset(out,0,sizeof(*out)*look->n[vb->W]); | |||
| return(0); | |||
| } | |||
| /* export hooks */ | |||
| const vorbis_func_floor floor0_exportbundle={ | |||
| NULL,&floor0_unpack,&floor0_look,&floor0_free_info, | |||
| &floor0_free_look,&floor0_inverse1,&floor0_inverse2 | |||
| }; | |||
| @@ -1,58 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: highlevel encoder setup struct separated out for vorbisenc clarity | |||
| last mod: $Id: highlevel.h 17195 2010-05-05 21:49:51Z giles $ | |||
| ********************************************************************/ | |||
| typedef struct highlevel_byblocktype { | |||
| double tone_mask_setting; | |||
| double tone_peaklimit_setting; | |||
| double noise_bias_setting; | |||
| double noise_compand_setting; | |||
| } highlevel_byblocktype; | |||
| typedef struct highlevel_encode_setup { | |||
| int set_in_stone; | |||
| const void *setup; | |||
| double base_setting; | |||
| double impulse_noisetune; | |||
| /* bitrate management below all settable */ | |||
| float req; | |||
| int managed; | |||
| long bitrate_min; | |||
| long bitrate_av; | |||
| double bitrate_av_damp; | |||
| long bitrate_max; | |||
| long bitrate_reservoir; | |||
| double bitrate_reservoir_bias; | |||
| int impulse_block_p; | |||
| int noise_normalize_p; | |||
| int coupling_p; | |||
| double stereo_point_setting; | |||
| double lowpass_kHz; | |||
| int lowpass_altered; | |||
| double ath_floating_dB; | |||
| double ath_absolute_dB; | |||
| double amplitude_track_dBpersec; | |||
| double trigger_setting; | |||
| highlevel_byblocktype block[4]; /* padding, impulse, transition, long */ | |||
| } highlevel_encode_setup; | |||
| @@ -1,660 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: maintain the info structure, info <-> header packets | |||
| last mod: $Id: info.c 17584 2010-11-01 19:26:16Z xiphmont $ | |||
| ********************************************************************/ | |||
| /* general handling of the header and the vorbis_info structure (and | |||
| substructures) */ | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <ctype.h> | |||
| #include "../../ogg.h" | |||
| #include "../../codec.h" | |||
| #include "codec_internal.h" | |||
| #include "codebook.h" | |||
| #include "registry.h" | |||
| #include "window.h" | |||
| #include "psy.h" | |||
| #include "misc.h" | |||
| #include "os.h" | |||
| #define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.3.2" | |||
| #define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20101101 (Schaufenugget)" | |||
| /* helpers */ | |||
| static void _v_writestring(oggpack_buffer *o,const char *s, int bytes){ | |||
| while(bytes--){ | |||
| oggpack_write(o,*s++,8); | |||
| } | |||
| } | |||
| static void _v_readstring(oggpack_buffer *o,char *buf,int bytes){ | |||
| while(bytes--){ | |||
| *buf++=oggpack_read(o,8); | |||
| } | |||
| } | |||
| void vorbis_comment_init(vorbis_comment *vc){ | |||
| memset(vc,0,sizeof(*vc)); | |||
| } | |||
| void vorbis_comment_add(vorbis_comment *vc,const char *comment){ | |||
| vc->user_comments=(char**)_ogg_realloc(vc->user_comments, | |||
| (vc->comments+2)*sizeof(*vc->user_comments)); | |||
| vc->comment_lengths=(int*)_ogg_realloc(vc->comment_lengths, | |||
| (vc->comments+2)*sizeof(*vc->comment_lengths)); | |||
| vc->comment_lengths[vc->comments]=strlen(comment); | |||
| vc->user_comments[vc->comments]=(char*)_ogg_malloc(vc->comment_lengths[vc->comments]+1); | |||
| strcpy(vc->user_comments[vc->comments], comment); | |||
| vc->comments++; | |||
| vc->user_comments[vc->comments]=NULL; | |||
| } | |||
| void vorbis_comment_add_tag(vorbis_comment *vc, const char *tag, const char *contents){ | |||
| char *comment=(char*)alloca(strlen(tag)+strlen(contents)+2); /* +2 for = and \0 */ | |||
| strcpy(comment, tag); | |||
| strcat(comment, "="); | |||
| strcat(comment, contents); | |||
| vorbis_comment_add(vc, comment); | |||
| } | |||
| /* This is more or less the same as strncasecmp - but that doesn't exist | |||
| * everywhere, and this is a fairly trivial function, so we include it */ | |||
| static int tagcompare(const char *s1, const char *s2, int n){ | |||
| int c=0; | |||
| while(c < n){ | |||
| if(toupper(s1[c]) != toupper(s2[c])) | |||
| return !0; | |||
| c++; | |||
| } | |||
| return 0; | |||
| } | |||
| char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count){ | |||
| long i; | |||
| int found = 0; | |||
| int taglen = strlen(tag)+1; /* +1 for the = we append */ | |||
| char *fulltag = (char*)alloca(taglen+ 1); | |||
| strcpy(fulltag, tag); | |||
| strcat(fulltag, "="); | |||
| for(i=0;i<vc->comments;i++){ | |||
| if(!tagcompare(vc->user_comments[i], fulltag, taglen)){ | |||
| if(count == found) | |||
| /* We return a pointer to the data, not a copy */ | |||
| return vc->user_comments[i] + taglen; | |||
| else | |||
| found++; | |||
| } | |||
| } | |||
| return NULL; /* didn't find anything */ | |||
| } | |||
| int vorbis_comment_query_count(vorbis_comment *vc, const char *tag){ | |||
| int i,count=0; | |||
| int taglen = strlen(tag)+1; /* +1 for the = we append */ | |||
| char *fulltag = (char*)alloca(taglen+1); | |||
| strcpy(fulltag,tag); | |||
| strcat(fulltag, "="); | |||
| for(i=0;i<vc->comments;i++){ | |||
| if(!tagcompare(vc->user_comments[i], fulltag, taglen)) | |||
| count++; | |||
| } | |||
| return count; | |||
| } | |||
| void vorbis_comment_clear(vorbis_comment *vc){ | |||
| if(vc){ | |||
| long i; | |||
| if(vc->user_comments){ | |||
| for(i=0;i<vc->comments;i++) | |||
| if(vc->user_comments[i])_ogg_free(vc->user_comments[i]); | |||
| _ogg_free(vc->user_comments); | |||
| } | |||
| if(vc->comment_lengths)_ogg_free(vc->comment_lengths); | |||
| if(vc->vendor)_ogg_free(vc->vendor); | |||
| memset(vc,0,sizeof(*vc)); | |||
| } | |||
| } | |||
| /* blocksize 0 is guaranteed to be short, 1 is guaranteed to be long. | |||
| They may be equal, but short will never ge greater than long */ | |||
| int vorbis_info_blocksize(vorbis_info *vi,int zo){ | |||
| codec_setup_info *ci = (codec_setup_info*)vi->codec_setup; | |||
| return ci ? ci->blocksizes[zo] : -1; | |||
| } | |||
| /* used by synthesis, which has a full, alloced vi */ | |||
| void vorbis_info_init(vorbis_info *vi){ | |||
| memset(vi,0,sizeof(*vi)); | |||
| vi->codec_setup=_ogg_calloc(1,sizeof(codec_setup_info)); | |||
| } | |||
| void vorbis_info_clear(vorbis_info *vi){ | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| int i; | |||
| if(ci){ | |||
| for(i=0;i<ci->modes;i++) | |||
| if(ci->mode_param[i])_ogg_free(ci->mode_param[i]); | |||
| for(i=0;i<ci->maps;i++) /* unpack does the range checking */ | |||
| if(ci->map_param[i]) /* this may be cleaning up an aborted | |||
| unpack, in which case the below type | |||
| cannot be trusted */ | |||
| _mapping_P[ci->map_type[i]]->free_info(ci->map_param[i]); | |||
| for(i=0;i<ci->floors;i++) /* unpack does the range checking */ | |||
| if(ci->floor_param[i]) /* this may be cleaning up an aborted | |||
| unpack, in which case the below type | |||
| cannot be trusted */ | |||
| _floor_P[ci->floor_type[i]]->free_info(ci->floor_param[i]); | |||
| for(i=0;i<ci->residues;i++) /* unpack does the range checking */ | |||
| if(ci->residue_param[i]) /* this may be cleaning up an aborted | |||
| unpack, in which case the below type | |||
| cannot be trusted */ | |||
| _residue_P[ci->residue_type[i]]->free_info(ci->residue_param[i]); | |||
| for(i=0;i<ci->books;i++){ | |||
| if(ci->book_param[i]){ | |||
| /* knows if the book was not alloced */ | |||
| vorbis_staticbook_destroy(ci->book_param[i]); | |||
| } | |||
| if(ci->fullbooks) | |||
| vorbis_book_clear(ci->fullbooks+i); | |||
| } | |||
| if(ci->fullbooks) | |||
| _ogg_free(ci->fullbooks); | |||
| for(i=0;i<ci->psys;i++) | |||
| _vi_psy_free(ci->psy_param[i]); | |||
| _ogg_free(ci); | |||
| } | |||
| memset(vi,0,sizeof(*vi)); | |||
| } | |||
| /* Header packing/unpacking ********************************************/ | |||
| static int _vorbis_unpack_info(vorbis_info *vi,oggpack_buffer *opb){ | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| if(!ci)return(OV_EFAULT); | |||
| vi->version=oggpack_read(opb,32); | |||
| if(vi->version!=0)return(OV_EVERSION); | |||
| vi->channels=oggpack_read(opb,8); | |||
| vi->rate=oggpack_read(opb,32); | |||
| vi->bitrate_upper=oggpack_read(opb,32); | |||
| vi->bitrate_nominal=oggpack_read(opb,32); | |||
| vi->bitrate_lower=oggpack_read(opb,32); | |||
| ci->blocksizes[0]=1<<oggpack_read(opb,4); | |||
| ci->blocksizes[1]=1<<oggpack_read(opb,4); | |||
| if(vi->rate<1)goto err_out; | |||
| if(vi->channels<1)goto err_out; | |||
| if(ci->blocksizes[0]<64)goto err_out; | |||
| if(ci->blocksizes[1]<ci->blocksizes[0])goto err_out; | |||
| if(ci->blocksizes[1]>8192)goto err_out; | |||
| if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ | |||
| return(0); | |||
| err_out: | |||
| vorbis_info_clear(vi); | |||
| return(OV_EBADHEADER); | |||
| } | |||
| static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){ | |||
| int i; | |||
| int vendorlen=oggpack_read(opb,32); | |||
| if(vendorlen<0)goto err_out; | |||
| if(vendorlen>opb->storage-8)goto err_out; | |||
| vc->vendor=(char*)_ogg_calloc(vendorlen+1,1); | |||
| _v_readstring(opb,vc->vendor,vendorlen); | |||
| i=oggpack_read(opb,32); | |||
| if(i<0)goto err_out; | |||
| if(i>((opb->storage-oggpack_bytes(opb))>>2))goto err_out; | |||
| vc->comments=i; | |||
| vc->user_comments=(char**)_ogg_calloc(vc->comments+1,sizeof(*vc->user_comments)); | |||
| vc->comment_lengths=(int*)_ogg_calloc(vc->comments+1, sizeof(*vc->comment_lengths)); | |||
| for(i=0;i<vc->comments;i++){ | |||
| int len=oggpack_read(opb,32); | |||
| if(len<0)goto err_out; | |||
| if(len>opb->storage-oggpack_bytes(opb))goto err_out; | |||
| vc->comment_lengths[i]=len; | |||
| vc->user_comments[i]=(char*)_ogg_calloc(len+1,1); | |||
| _v_readstring(opb,vc->user_comments[i],len); | |||
| } | |||
| if(oggpack_read(opb,1)!=1)goto err_out; /* EOP check */ | |||
| return(0); | |||
| err_out: | |||
| vorbis_comment_clear(vc); | |||
| return(OV_EBADHEADER); | |||
| } | |||
| /* all of the real encoding details are here. The modes, books, | |||
| everything */ | |||
| static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){ | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| int i; | |||
| if(!ci)return(OV_EFAULT); | |||
| /* codebooks */ | |||
| ci->books=oggpack_read(opb,8)+1; | |||
| if(ci->books<=0)goto err_out; | |||
| for(i=0;i<ci->books;i++){ | |||
| ci->book_param[i]=vorbis_staticbook_unpack(opb); | |||
| if(!ci->book_param[i])goto err_out; | |||
| } | |||
| /* time backend settings; hooks are unused */ | |||
| { | |||
| int times=oggpack_read(opb,6)+1; | |||
| if(times<=0)goto err_out; | |||
| for(i=0;i<times;i++){ | |||
| int test=oggpack_read(opb,16); | |||
| if(test<0 || test>=VI_TIMEB)goto err_out; | |||
| } | |||
| } | |||
| /* floor backend settings */ | |||
| ci->floors=oggpack_read(opb,6)+1; | |||
| if(ci->floors<=0)goto err_out; | |||
| for(i=0;i<ci->floors;i++){ | |||
| ci->floor_type[i]=oggpack_read(opb,16); | |||
| if(ci->floor_type[i]<0 || ci->floor_type[i]>=VI_FLOORB)goto err_out; | |||
| ci->floor_param[i]=_floor_P[ci->floor_type[i]]->unpack(vi,opb); | |||
| if(!ci->floor_param[i])goto err_out; | |||
| } | |||
| /* residue backend settings */ | |||
| ci->residues=oggpack_read(opb,6)+1; | |||
| if(ci->residues<=0)goto err_out; | |||
| for(i=0;i<ci->residues;i++){ | |||
| ci->residue_type[i]=oggpack_read(opb,16); | |||
| if(ci->residue_type[i]<0 || ci->residue_type[i]>=VI_RESB)goto err_out; | |||
| ci->residue_param[i]=_residue_P[ci->residue_type[i]]->unpack(vi,opb); | |||
| if(!ci->residue_param[i])goto err_out; | |||
| } | |||
| /* map backend settings */ | |||
| ci->maps=oggpack_read(opb,6)+1; | |||
| if(ci->maps<=0)goto err_out; | |||
| for(i=0;i<ci->maps;i++){ | |||
| ci->map_type[i]=oggpack_read(opb,16); | |||
| if(ci->map_type[i]<0 || ci->map_type[i]>=VI_MAPB)goto err_out; | |||
| ci->map_param[i]=_mapping_P[ci->map_type[i]]->unpack(vi,opb); | |||
| if(!ci->map_param[i])goto err_out; | |||
| } | |||
| /* mode settings */ | |||
| ci->modes=oggpack_read(opb,6)+1; | |||
| if(ci->modes<=0)goto err_out; | |||
| for(i=0;i<ci->modes;i++){ | |||
| ci->mode_param[i]=(vorbis_info_mode*)_ogg_calloc(1,sizeof(*ci->mode_param[i])); | |||
| ci->mode_param[i]->blockflag=oggpack_read(opb,1); | |||
| ci->mode_param[i]->windowtype=oggpack_read(opb,16); | |||
| ci->mode_param[i]->transformtype=oggpack_read(opb,16); | |||
| ci->mode_param[i]->mapping=oggpack_read(opb,8); | |||
| if(ci->mode_param[i]->windowtype>=VI_WINDOWB)goto err_out; | |||
| if(ci->mode_param[i]->transformtype>=VI_WINDOWB)goto err_out; | |||
| if(ci->mode_param[i]->mapping>=ci->maps)goto err_out; | |||
| if(ci->mode_param[i]->mapping<0)goto err_out; | |||
| } | |||
| if(oggpack_read(opb,1)!=1)goto err_out; /* top level EOP check */ | |||
| return(0); | |||
| err_out: | |||
| vorbis_info_clear(vi); | |||
| return(OV_EBADHEADER); | |||
| } | |||
| /* Is this packet a vorbis ID header? */ | |||
| int vorbis_synthesis_idheader(ogg_packet *op){ | |||
| oggpack_buffer opb; | |||
| char buffer[6]; | |||
| if(op){ | |||
| oggpack_readinit(&opb,op->packet,op->bytes); | |||
| if(!op->b_o_s) | |||
| return(0); /* Not the initial packet */ | |||
| if(oggpack_read(&opb,8) != 1) | |||
| return 0; /* not an ID header */ | |||
| memset(buffer,0,6); | |||
| _v_readstring(&opb,buffer,6); | |||
| if(memcmp(buffer,"vorbis",6)) | |||
| return 0; /* not vorbis */ | |||
| return 1; | |||
| } | |||
| return 0; | |||
| } | |||
| /* The Vorbis header is in three packets; the initial small packet in | |||
| the first page that identifies basic parameters, a second packet | |||
| with bitstream comments and a third packet that holds the | |||
| codebook. */ | |||
| int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op){ | |||
| oggpack_buffer opb; | |||
| if(op){ | |||
| oggpack_readinit(&opb,op->packet,op->bytes); | |||
| /* Which of the three types of header is this? */ | |||
| /* Also verify header-ness, vorbis */ | |||
| { | |||
| char buffer[6]; | |||
| int packtype=oggpack_read(&opb,8); | |||
| memset(buffer,0,6); | |||
| _v_readstring(&opb,buffer,6); | |||
| if(memcmp(buffer,"vorbis",6)){ | |||
| /* not a vorbis header */ | |||
| return(OV_ENOTVORBIS); | |||
| } | |||
| switch(packtype){ | |||
| case 0x01: /* least significant *bit* is read first */ | |||
| if(!op->b_o_s){ | |||
| /* Not the initial packet */ | |||
| return(OV_EBADHEADER); | |||
| } | |||
| if(vi->rate!=0){ | |||
| /* previously initialized info header */ | |||
| return(OV_EBADHEADER); | |||
| } | |||
| return(_vorbis_unpack_info(vi,&opb)); | |||
| case 0x03: /* least significant *bit* is read first */ | |||
| if(vi->rate==0){ | |||
| /* um... we didn't get the initial header */ | |||
| return(OV_EBADHEADER); | |||
| } | |||
| return(_vorbis_unpack_comment(vc,&opb)); | |||
| case 0x05: /* least significant *bit* is read first */ | |||
| if(vi->rate==0 || vc->vendor==NULL){ | |||
| /* um... we didn;t get the initial header or comments yet */ | |||
| return(OV_EBADHEADER); | |||
| } | |||
| return(_vorbis_unpack_books(vi,&opb)); | |||
| default: | |||
| /* Not a valid vorbis header type */ | |||
| return(OV_EBADHEADER); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| return(OV_EBADHEADER); | |||
| } | |||
| /* pack side **********************************************************/ | |||
| static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){ | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| if(!ci)return(OV_EFAULT); | |||
| /* preamble */ | |||
| oggpack_write(opb,0x01,8); | |||
| _v_writestring(opb,"vorbis", 6); | |||
| /* basic information about the stream */ | |||
| oggpack_write(opb,0x00,32); | |||
| oggpack_write(opb,vi->channels,8); | |||
| oggpack_write(opb,vi->rate,32); | |||
| oggpack_write(opb,vi->bitrate_upper,32); | |||
| oggpack_write(opb,vi->bitrate_nominal,32); | |||
| oggpack_write(opb,vi->bitrate_lower,32); | |||
| oggpack_write(opb,ilog2(ci->blocksizes[0]),4); | |||
| oggpack_write(opb,ilog2(ci->blocksizes[1]),4); | |||
| oggpack_write(opb,1,1); | |||
| return(0); | |||
| } | |||
| static int _vorbis_pack_comment(oggpack_buffer *opb,vorbis_comment *vc){ | |||
| int bytes = strlen(ENCODE_VENDOR_STRING); | |||
| /* preamble */ | |||
| oggpack_write(opb,0x03,8); | |||
| _v_writestring(opb,"vorbis", 6); | |||
| /* vendor */ | |||
| oggpack_write(opb,bytes,32); | |||
| _v_writestring(opb,ENCODE_VENDOR_STRING, bytes); | |||
| /* comments */ | |||
| oggpack_write(opb,vc->comments,32); | |||
| if(vc->comments){ | |||
| int i; | |||
| for(i=0;i<vc->comments;i++){ | |||
| if(vc->user_comments[i]){ | |||
| oggpack_write(opb,vc->comment_lengths[i],32); | |||
| _v_writestring(opb,vc->user_comments[i], vc->comment_lengths[i]); | |||
| }else{ | |||
| oggpack_write(opb,0,32); | |||
| } | |||
| } | |||
| } | |||
| oggpack_write(opb,1,1); | |||
| return(0); | |||
| } | |||
| static int _vorbis_pack_books(oggpack_buffer *opb,vorbis_info *vi){ | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| int i; | |||
| if(!ci)return(OV_EFAULT); | |||
| oggpack_write(opb,0x05,8); | |||
| _v_writestring(opb,"vorbis", 6); | |||
| /* books */ | |||
| oggpack_write(opb,ci->books-1,8); | |||
| for(i=0;i<ci->books;i++) | |||
| if(vorbis_staticbook_pack(ci->book_param[i],opb))goto err_out; | |||
| /* times; hook placeholders */ | |||
| oggpack_write(opb,0,6); | |||
| oggpack_write(opb,0,16); | |||
| /* floors */ | |||
| oggpack_write(opb,ci->floors-1,6); | |||
| for(i=0;i<ci->floors;i++){ | |||
| oggpack_write(opb,ci->floor_type[i],16); | |||
| if(_floor_P[ci->floor_type[i]]->pack) | |||
| _floor_P[ci->floor_type[i]]->pack(ci->floor_param[i],opb); | |||
| else | |||
| goto err_out; | |||
| } | |||
| /* residues */ | |||
| oggpack_write(opb,ci->residues-1,6); | |||
| for(i=0;i<ci->residues;i++){ | |||
| oggpack_write(opb,ci->residue_type[i],16); | |||
| _residue_P[ci->residue_type[i]]->pack(ci->residue_param[i],opb); | |||
| } | |||
| /* maps */ | |||
| oggpack_write(opb,ci->maps-1,6); | |||
| for(i=0;i<ci->maps;i++){ | |||
| oggpack_write(opb,ci->map_type[i],16); | |||
| _mapping_P[ci->map_type[i]]->pack(vi,ci->map_param[i],opb); | |||
| } | |||
| /* modes */ | |||
| oggpack_write(opb,ci->modes-1,6); | |||
| for(i=0;i<ci->modes;i++){ | |||
| oggpack_write(opb,ci->mode_param[i]->blockflag,1); | |||
| oggpack_write(opb,ci->mode_param[i]->windowtype,16); | |||
| oggpack_write(opb,ci->mode_param[i]->transformtype,16); | |||
| oggpack_write(opb,ci->mode_param[i]->mapping,8); | |||
| } | |||
| oggpack_write(opb,1,1); | |||
| return(0); | |||
| err_out: | |||
| return(-1); | |||
| } | |||
| int vorbis_commentheader_out(vorbis_comment *vc, | |||
| ogg_packet *op){ | |||
| oggpack_buffer opb; | |||
| oggpack_writeinit(&opb); | |||
| if(_vorbis_pack_comment(&opb,vc)) return OV_EIMPL; | |||
| op->packet = (unsigned char*) _ogg_malloc(oggpack_bytes(&opb)); | |||
| memcpy(op->packet, opb.buffer, oggpack_bytes(&opb)); | |||
| op->bytes=oggpack_bytes(&opb); | |||
| op->b_o_s=0; | |||
| op->e_o_s=0; | |||
| op->granulepos=0; | |||
| op->packetno=1; | |||
| return 0; | |||
| } | |||
| int vorbis_analysis_headerout(vorbis_dsp_state *v, | |||
| vorbis_comment *vc, | |||
| ogg_packet *op, | |||
| ogg_packet *op_comm, | |||
| ogg_packet *op_code){ | |||
| int ret=OV_EIMPL; | |||
| vorbis_info *vi=v->vi; | |||
| oggpack_buffer opb; | |||
| private_state *b=(private_state*)v->backend_state; | |||
| if(!b){ | |||
| ret=OV_EFAULT; | |||
| goto err_out; | |||
| } | |||
| /* first header packet **********************************************/ | |||
| oggpack_writeinit(&opb); | |||
| if(_vorbis_pack_info(&opb,vi))goto err_out; | |||
| /* build the packet */ | |||
| if(b->header)_ogg_free(b->header); | |||
| b->header=(unsigned char*) _ogg_malloc(oggpack_bytes(&opb)); | |||
| memcpy(b->header,opb.buffer,oggpack_bytes(&opb)); | |||
| op->packet=b->header; | |||
| op->bytes=oggpack_bytes(&opb); | |||
| op->b_o_s=1; | |||
| op->e_o_s=0; | |||
| op->granulepos=0; | |||
| op->packetno=0; | |||
| /* second header packet (comments) **********************************/ | |||
| oggpack_reset(&opb); | |||
| if(_vorbis_pack_comment(&opb,vc))goto err_out; | |||
| if(b->header1)_ogg_free(b->header1); | |||
| b->header1=(unsigned char*) _ogg_malloc(oggpack_bytes(&opb)); | |||
| memcpy(b->header1,opb.buffer,oggpack_bytes(&opb)); | |||
| op_comm->packet=b->header1; | |||
| op_comm->bytes=oggpack_bytes(&opb); | |||
| op_comm->b_o_s=0; | |||
| op_comm->e_o_s=0; | |||
| op_comm->granulepos=0; | |||
| op_comm->packetno=1; | |||
| /* third header packet (modes/codebooks) ****************************/ | |||
| oggpack_reset(&opb); | |||
| if(_vorbis_pack_books(&opb,vi))goto err_out; | |||
| if(b->header2)_ogg_free(b->header2); | |||
| b->header2=(unsigned char*) _ogg_malloc(oggpack_bytes(&opb)); | |||
| memcpy(b->header2,opb.buffer,oggpack_bytes(&opb)); | |||
| op_code->packet=b->header2; | |||
| op_code->bytes=oggpack_bytes(&opb); | |||
| op_code->b_o_s=0; | |||
| op_code->e_o_s=0; | |||
| op_code->granulepos=0; | |||
| op_code->packetno=2; | |||
| oggpack_writeclear(&opb); | |||
| return(0); | |||
| err_out: | |||
| memset(op,0,sizeof(*op)); | |||
| memset(op_comm,0,sizeof(*op_comm)); | |||
| memset(op_code,0,sizeof(*op_code)); | |||
| if(b){ | |||
| oggpack_writeclear(&opb); | |||
| if(b->header)_ogg_free(b->header); | |||
| if(b->header1)_ogg_free(b->header1); | |||
| if(b->header2)_ogg_free(b->header2); | |||
| b->header=NULL; | |||
| b->header1=NULL; | |||
| b->header2=NULL; | |||
| } | |||
| return(ret); | |||
| } | |||
| double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){ | |||
| if(granulepos == -1) return -1; | |||
| /* We're not guaranteed a 64 bit unsigned type everywhere, so we | |||
| have to put the unsigned granpo in a signed type. */ | |||
| if(granulepos>=0){ | |||
| return((double)granulepos/v->vi->rate); | |||
| }else{ | |||
| ogg_int64_t granuleoff=0xffffffff; | |||
| granuleoff<<=31; | |||
| #ifdef __GNUC__ | |||
| granuleoff |= 0x7ffffffffLL; | |||
| #else | |||
| granuleoff |= 0x7ffffffff; | |||
| #endif | |||
| return(((double)granulepos+2+granuleoff+granuleoff)/v->vi->rate); | |||
| } | |||
| } | |||
| const char *vorbis_version_string(void){ | |||
| return GENERAL_VENDOR_STRING; | |||
| } | |||
| @@ -1,94 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: lookup based functions | |||
| last mod: $Id: lookup.c 16227 2009-07-08 06:58:46Z xiphmont $ | |||
| ********************************************************************/ | |||
| #include <math.h> | |||
| #include "lookup.h" | |||
| #include "lookup_data.h" | |||
| #include "os.h" | |||
| #include "misc.h" | |||
| #ifdef FLOAT_LOOKUP | |||
| /* interpolated lookup based cos function, domain 0 to PI only */ | |||
| float vorbis_coslook(float a){ | |||
| double d=a*(.31830989*(float)COS_LOOKUP_SZ); | |||
| int i=vorbis_ftoi(d-.5); | |||
| return COS_LOOKUP[i]+ (d-i)*(COS_LOOKUP[i+1]-COS_LOOKUP[i]); | |||
| } | |||
| /* interpolated 1./sqrt(p) where .5 <= p < 1. */ | |||
| float vorbis_invsqlook(float a){ | |||
| double d=a*(2.f*(float)INVSQ_LOOKUP_SZ)-(float)INVSQ_LOOKUP_SZ; | |||
| int i=vorbis_ftoi(d-.5f); | |||
| return INVSQ_LOOKUP[i]+ (d-i)*(INVSQ_LOOKUP[i+1]-INVSQ_LOOKUP[i]); | |||
| } | |||
| /* interpolated 1./sqrt(p) where .5 <= p < 1. */ | |||
| float vorbis_invsq2explook(int a){ | |||
| return INVSQ2EXP_LOOKUP[a-INVSQ2EXP_LOOKUP_MIN]; | |||
| } | |||
| #include <stdio.h> | |||
| /* interpolated lookup based fromdB function, domain -140dB to 0dB only */ | |||
| float vorbis_fromdBlook(float a){ | |||
| int i=vorbis_ftoi(a*((float)(-(1<<FROMdB2_SHIFT)))-.5f); | |||
| return (i<0)?1.f: | |||
| ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f: | |||
| FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]); | |||
| } | |||
| #endif | |||
| #ifdef INT_LOOKUP | |||
| /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in | |||
| 16.16 format | |||
| returns in m.8 format */ | |||
| long vorbis_invsqlook_i(long a,long e){ | |||
| long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1); | |||
| long d=(a&INVSQ_LOOKUP_I_MASK)<<(16-INVSQ_LOOKUP_I_SHIFT); /* 0.16 */ | |||
| long val=INVSQ_LOOKUP_I[i]- /* 1.16 */ | |||
| (((INVSQ_LOOKUP_I[i]-INVSQ_LOOKUP_I[i+1])* /* 0.16 */ | |||
| d)>>16); /* result 1.16 */ | |||
| e+=32; | |||
| if(e&1)val=(val*5792)>>13; /* multiply val by 1/sqrt(2) */ | |||
| e=(e>>1)-8; | |||
| return(val>>e); | |||
| } | |||
| /* interpolated lookup based fromdB function, domain -140dB to 0dB only */ | |||
| /* a is in n.12 format */ | |||
| float vorbis_fromdBlook_i(long a){ | |||
| int i=(-a)>>(12-FROMdB2_SHIFT); | |||
| return (i<0)?1.f: | |||
| ((i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))?0.f: | |||
| FROMdB_LOOKUP[i>>FROMdB_SHIFT]*FROMdB2_LOOKUP[i&FROMdB2_MASK]); | |||
| } | |||
| /* interpolated lookup based cos function, domain 0 to PI only */ | |||
| /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */ | |||
| long vorbis_coslook_i(long a){ | |||
| int i=a>>COS_LOOKUP_I_SHIFT; | |||
| int d=a&COS_LOOKUP_I_MASK; | |||
| return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>> | |||
| COS_LOOKUP_I_SHIFT); | |||
| } | |||
| #endif | |||
| @@ -1,32 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: lookup based functions | |||
| last mod: $Id: lookup.h 16227 2009-07-08 06:58:46Z xiphmont $ | |||
| ********************************************************************/ | |||
| #ifndef _V_LOOKUP_H_ | |||
| #ifdef FLOAT_LOOKUP | |||
| extern float vorbis_coslook(float a); | |||
| extern float vorbis_invsqlook(float a); | |||
| extern float vorbis_invsq2explook(int a); | |||
| extern float vorbis_fromdBlook(float a); | |||
| #endif | |||
| #ifdef INT_LOOKUP | |||
| extern long vorbis_invsqlook_i(long a,long e); | |||
| extern long vorbis_coslook_i(long a); | |||
| extern float vorbis_fromdBlook_i(long a); | |||
| #endif | |||
| #endif | |||
| @@ -1,192 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: lookup data; generated by lookups.pl; edit there | |||
| last mod: $Id: lookup_data.h 16037 2009-05-26 21:10:58Z xiphmont $ | |||
| ********************************************************************/ | |||
| #ifndef _V_LOOKUP_DATA_H_ | |||
| #ifdef FLOAT_LOOKUP | |||
| #define COS_LOOKUP_SZ 128 | |||
| static const float COS_LOOKUP[COS_LOOKUP_SZ+1]={ | |||
| +1.0000000000000f,+0.9996988186962f,+0.9987954562052f,+0.9972904566787f, | |||
| +0.9951847266722f,+0.9924795345987f,+0.9891765099648f,+0.9852776423889f, | |||
| +0.9807852804032f,+0.9757021300385f,+0.9700312531945f,+0.9637760657954f, | |||
| +0.9569403357322f,+0.9495281805930f,+0.9415440651830f,+0.9329927988347f, | |||
| +0.9238795325113f,+0.9142097557035f,+0.9039892931234f,+0.8932243011955f, | |||
| +0.8819212643484f,+0.8700869911087f,+0.8577286100003f,+0.8448535652497f, | |||
| +0.8314696123025f,+0.8175848131516f,+0.8032075314806f,+0.7883464276266f, | |||
| +0.7730104533627f,+0.7572088465065f,+0.7409511253550f,+0.7242470829515f, | |||
| +0.7071067811865f,+0.6895405447371f,+0.6715589548470f,+0.6531728429538f, | |||
| +0.6343932841636f,+0.6152315905806f,+0.5956993044924f,+0.5758081914178f, | |||
| +0.5555702330196f,+0.5349976198871f,+0.5141027441932f,+0.4928981922298f, | |||
| +0.4713967368260f,+0.4496113296546f,+0.4275550934303f,+0.4052413140050f, | |||
| +0.3826834323651f,+0.3598950365350f,+0.3368898533922f,+0.3136817403989f, | |||
| +0.2902846772545f,+0.2667127574749f,+0.2429801799033f,+0.2191012401569f, | |||
| +0.1950903220161f,+0.1709618887603f,+0.1467304744554f,+0.1224106751992f, | |||
| +0.0980171403296f,+0.0735645635997f,+0.0490676743274f,+0.0245412285229f, | |||
| +0.0000000000000f,-0.0245412285229f,-0.0490676743274f,-0.0735645635997f, | |||
| -0.0980171403296f,-0.1224106751992f,-0.1467304744554f,-0.1709618887603f, | |||
| -0.1950903220161f,-0.2191012401569f,-0.2429801799033f,-0.2667127574749f, | |||
| -0.2902846772545f,-0.3136817403989f,-0.3368898533922f,-0.3598950365350f, | |||
| -0.3826834323651f,-0.4052413140050f,-0.4275550934303f,-0.4496113296546f, | |||
| -0.4713967368260f,-0.4928981922298f,-0.5141027441932f,-0.5349976198871f, | |||
| -0.5555702330196f,-0.5758081914178f,-0.5956993044924f,-0.6152315905806f, | |||
| -0.6343932841636f,-0.6531728429538f,-0.6715589548470f,-0.6895405447371f, | |||
| -0.7071067811865f,-0.7242470829515f,-0.7409511253550f,-0.7572088465065f, | |||
| -0.7730104533627f,-0.7883464276266f,-0.8032075314806f,-0.8175848131516f, | |||
| -0.8314696123025f,-0.8448535652497f,-0.8577286100003f,-0.8700869911087f, | |||
| -0.8819212643484f,-0.8932243011955f,-0.9039892931234f,-0.9142097557035f, | |||
| -0.9238795325113f,-0.9329927988347f,-0.9415440651830f,-0.9495281805930f, | |||
| -0.9569403357322f,-0.9637760657954f,-0.9700312531945f,-0.9757021300385f, | |||
| -0.9807852804032f,-0.9852776423889f,-0.9891765099648f,-0.9924795345987f, | |||
| -0.9951847266722f,-0.9972904566787f,-0.9987954562052f,-0.9996988186962f, | |||
| -1.0000000000000f, | |||
| }; | |||
| #define INVSQ_LOOKUP_SZ 32 | |||
| static const float INVSQ_LOOKUP[INVSQ_LOOKUP_SZ+1]={ | |||
| 1.414213562373f,1.392621247646f,1.371988681140f,1.352246807566f, | |||
| 1.333333333333f,1.315191898443f,1.297771369046f,1.281025230441f, | |||
| 1.264911064067f,1.249390095109f,1.234426799697f,1.219988562661f, | |||
| 1.206045378311f,1.192569588000f,1.179535649239f,1.166919931983f, | |||
| 1.154700538379f,1.142857142857f,1.131370849898f,1.120224067222f, | |||
| 1.109400392450f,1.098884511590f,1.088662107904f,1.078719779941f, | |||
| 1.069044967650f,1.059625885652f,1.050451462878f,1.041511287847f, | |||
| 1.032795558989f,1.024295039463f,1.016001016002f,1.007905261358f, | |||
| 1.000000000000f, | |||
| }; | |||
| #define INVSQ2EXP_LOOKUP_MIN (-32) | |||
| #define INVSQ2EXP_LOOKUP_MAX 32 | |||
| static const float INVSQ2EXP_LOOKUP[INVSQ2EXP_LOOKUP_MAX-\ | |||
| INVSQ2EXP_LOOKUP_MIN+1]={ | |||
| 65536.f, 46340.95001f, 32768.f, 23170.47501f, | |||
| 16384.f, 11585.2375f, 8192.f, 5792.618751f, | |||
| 4096.f, 2896.309376f, 2048.f, 1448.154688f, | |||
| 1024.f, 724.0773439f, 512.f, 362.038672f, | |||
| 256.f, 181.019336f, 128.f, 90.50966799f, | |||
| 64.f, 45.254834f, 32.f, 22.627417f, | |||
| 16.f, 11.3137085f, 8.f, 5.656854249f, | |||
| 4.f, 2.828427125f, 2.f, 1.414213562f, | |||
| 1.f, 0.7071067812f, 0.5f, 0.3535533906f, | |||
| 0.25f, 0.1767766953f, 0.125f, 0.08838834765f, | |||
| 0.0625f, 0.04419417382f, 0.03125f, 0.02209708691f, | |||
| 0.015625f, 0.01104854346f, 0.0078125f, 0.005524271728f, | |||
| 0.00390625f, 0.002762135864f, 0.001953125f, 0.001381067932f, | |||
| 0.0009765625f, 0.000690533966f, 0.00048828125f, 0.000345266983f, | |||
| 0.000244140625f,0.0001726334915f,0.0001220703125f,8.631674575e-05f, | |||
| 6.103515625e-05f,4.315837288e-05f,3.051757812e-05f,2.157918644e-05f, | |||
| 1.525878906e-05f, | |||
| }; | |||
| #endif | |||
| #define FROMdB_LOOKUP_SZ 35 | |||
| #define FROMdB2_LOOKUP_SZ 32 | |||
| #define FROMdB_SHIFT 5 | |||
| #define FROMdB2_SHIFT 3 | |||
| #define FROMdB2_MASK 31 | |||
| #ifdef FLOAT_LOOKUP | |||
| static const float FROMdB_LOOKUP[FROMdB_LOOKUP_SZ]={ | |||
| 1.f, 0.6309573445f, 0.3981071706f, 0.2511886432f, | |||
| 0.1584893192f, 0.1f, 0.06309573445f, 0.03981071706f, | |||
| 0.02511886432f, 0.01584893192f, 0.01f, 0.006309573445f, | |||
| 0.003981071706f, 0.002511886432f, 0.001584893192f, 0.001f, | |||
| 0.0006309573445f,0.0003981071706f,0.0002511886432f,0.0001584893192f, | |||
| 0.0001f,6.309573445e-05f,3.981071706e-05f,2.511886432e-05f, | |||
| 1.584893192e-05f, 1e-05f,6.309573445e-06f,3.981071706e-06f, | |||
| 2.511886432e-06f,1.584893192e-06f, 1e-06f,6.309573445e-07f, | |||
| 3.981071706e-07f,2.511886432e-07f,1.584893192e-07f, | |||
| }; | |||
| static const float FROMdB2_LOOKUP[FROMdB2_LOOKUP_SZ]={ | |||
| 0.9928302478f, 0.9786445908f, 0.9646616199f, 0.9508784391f, | |||
| 0.9372921937f, 0.92390007f, 0.9106992942f, 0.8976871324f, | |||
| 0.8848608897f, 0.8722179097f, 0.8597555737f, 0.8474713009f, | |||
| 0.835362547f, 0.8234268041f, 0.8116616003f, 0.8000644989f, | |||
| 0.7886330981f, 0.7773650302f, 0.7662579617f, 0.755309592f, | |||
| 0.7445176537f, 0.7338799116f, 0.7233941627f, 0.7130582353f, | |||
| 0.7028699885f, 0.6928273125f, 0.6829281272f, 0.6731703824f, | |||
| 0.6635520573f, 0.6540711597f, 0.6447257262f, 0.6355138211f, | |||
| }; | |||
| #endif | |||
| #ifdef INT_LOOKUP | |||
| #define INVSQ_LOOKUP_I_SHIFT 10 | |||
| #define INVSQ_LOOKUP_I_MASK 1023 | |||
| static const long INVSQ_LOOKUP_I[64+1]={ | |||
| 92682l, 91966l, 91267l, 90583l, | |||
| 89915l, 89261l, 88621l, 87995l, | |||
| 87381l, 86781l, 86192l, 85616l, | |||
| 85051l, 84497l, 83953l, 83420l, | |||
| 82897l, 82384l, 81880l, 81385l, | |||
| 80899l, 80422l, 79953l, 79492l, | |||
| 79039l, 78594l, 78156l, 77726l, | |||
| 77302l, 76885l, 76475l, 76072l, | |||
| 75674l, 75283l, 74898l, 74519l, | |||
| 74146l, 73778l, 73415l, 73058l, | |||
| 72706l, 72359l, 72016l, 71679l, | |||
| 71347l, 71019l, 70695l, 70376l, | |||
| 70061l, 69750l, 69444l, 69141l, | |||
| 68842l, 68548l, 68256l, 67969l, | |||
| 67685l, 67405l, 67128l, 66855l, | |||
| 66585l, 66318l, 66054l, 65794l, | |||
| 65536l, | |||
| }; | |||
| #define COS_LOOKUP_I_SHIFT 9 | |||
| #define COS_LOOKUP_I_MASK 511 | |||
| #define COS_LOOKUP_I_SZ 128 | |||
| static const long COS_LOOKUP_I[COS_LOOKUP_I_SZ+1]={ | |||
| 16384l, 16379l, 16364l, 16340l, | |||
| 16305l, 16261l, 16207l, 16143l, | |||
| 16069l, 15986l, 15893l, 15791l, | |||
| 15679l, 15557l, 15426l, 15286l, | |||
| 15137l, 14978l, 14811l, 14635l, | |||
| 14449l, 14256l, 14053l, 13842l, | |||
| 13623l, 13395l, 13160l, 12916l, | |||
| 12665l, 12406l, 12140l, 11866l, | |||
| 11585l, 11297l, 11003l, 10702l, | |||
| 10394l, 10080l, 9760l, 9434l, | |||
| 9102l, 8765l, 8423l, 8076l, | |||
| 7723l, 7366l, 7005l, 6639l, | |||
| 6270l, 5897l, 5520l, 5139l, | |||
| 4756l, 4370l, 3981l, 3590l, | |||
| 3196l, 2801l, 2404l, 2006l, | |||
| 1606l, 1205l, 804l, 402l, | |||
| 0l, -401l, -803l, -1204l, | |||
| -1605l, -2005l, -2403l, -2800l, | |||
| -3195l, -3589l, -3980l, -4369l, | |||
| -4755l, -5138l, -5519l, -5896l, | |||
| -6269l, -6638l, -7004l, -7365l, | |||
| -7722l, -8075l, -8422l, -8764l, | |||
| -9101l, -9433l, -9759l, -10079l, | |||
| -10393l, -10701l, -11002l, -11296l, | |||
| -11584l, -11865l, -12139l, -12405l, | |||
| -12664l, -12915l, -13159l, -13394l, | |||
| -13622l, -13841l, -14052l, -14255l, | |||
| -14448l, -14634l, -14810l, -14977l, | |||
| -15136l, -15285l, -15425l, -15556l, | |||
| -15678l, -15790l, -15892l, -15985l, | |||
| -16068l, -16142l, -16206l, -16260l, | |||
| -16304l, -16339l, -16363l, -16378l, | |||
| -16383l, | |||
| }; | |||
| #endif | |||
| #endif | |||
| @@ -1,160 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: LPC low level routines | |||
| last mod: $Id: lpc.c 16227 2009-07-08 06:58:46Z xiphmont $ | |||
| ********************************************************************/ | |||
| /* Some of these routines (autocorrelator, LPC coefficient estimator) | |||
| are derived from code written by Jutta Degener and Carsten Bormann; | |||
| thus we include their copyright below. The entirety of this file | |||
| is freely redistributable on the condition that both of these | |||
| copyright notices are preserved without modification. */ | |||
| /* Preserved Copyright: *********************************************/ | |||
| /* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, | |||
| Technische Universita"t Berlin | |||
| Any use of this software is permitted provided that this notice is not | |||
| removed and that neither the authors nor the Technische Universita"t | |||
| Berlin are deemed to have made any representations as to the | |||
| suitability of this software for any purpose nor are held responsible | |||
| for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR | |||
| THIS SOFTWARE. | |||
| As a matter of courtesy, the authors request to be informed about uses | |||
| this software has found, about bugs in this software, and about any | |||
| improvements that may be of general interest. | |||
| Berlin, 28.11.1994 | |||
| Jutta Degener | |||
| Carsten Bormann | |||
| *********************************************************************/ | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <math.h> | |||
| #include "os.h" | |||
| #include "smallft.h" | |||
| #include "lpc.h" | |||
| #include "scales.h" | |||
| #include "misc.h" | |||
| /* Autocorrelation LPC coeff generation algorithm invented by | |||
| N. Levinson in 1947, modified by J. Durbin in 1959. */ | |||
| /* Input : n elements of time doamin data | |||
| Output: m lpc coefficients, excitation energy */ | |||
| float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){ | |||
| double *aut=(double*)alloca(sizeof(*aut)*(m+1)); | |||
| double *lpc=(double*)alloca(sizeof(*lpc)*(m)); | |||
| double error; | |||
| double epsilon; | |||
| int i,j; | |||
| /* autocorrelation, p+1 lag coefficients */ | |||
| j=m+1; | |||
| while(j--){ | |||
| double d=0; /* double needed for accumulator depth */ | |||
| for(i=j;i<n;i++)d+=(double)data[i]*data[i-j]; | |||
| aut[j]=d; | |||
| } | |||
| /* Generate lpc coefficients from autocorr values */ | |||
| /* set our noise floor to about -100dB */ | |||
| error=aut[0] * (1. + 1e-10); | |||
| epsilon=1e-9*aut[0]+1e-10; | |||
| for(i=0;i<m;i++){ | |||
| double r= -aut[i+1]; | |||
| if(error<epsilon){ | |||
| memset(lpc+i,0,(m-i)*sizeof(*lpc)); | |||
| goto done; | |||
| } | |||
| /* Sum up this iteration's reflection coefficient; note that in | |||
| Vorbis we don't save it. If anyone wants to recycle this code | |||
| and needs reflection coefficients, save the results of 'r' from | |||
| each iteration. */ | |||
| for(j=0;j<i;j++)r-=lpc[j]*aut[i-j]; | |||
| r/=error; | |||
| /* Update LPC coefficients and total error */ | |||
| lpc[i]=r; | |||
| for(j=0;j<i/2;j++){ | |||
| double tmp=lpc[j]; | |||
| lpc[j]+=r*lpc[i-1-j]; | |||
| lpc[i-1-j]+=r*tmp; | |||
| } | |||
| if(i&1)lpc[j]+=lpc[j]*r; | |||
| error*=1.-r*r; | |||
| } | |||
| done: | |||
| /* slightly damp the filter */ | |||
| { | |||
| double g = .99; | |||
| double damp = g; | |||
| for(j=0;j<m;j++){ | |||
| lpc[j]*=damp; | |||
| damp*=g; | |||
| } | |||
| } | |||
| for(j=0;j<m;j++)lpci[j]=(float)lpc[j]; | |||
| /* we need the error value to know how big an impulse to hit the | |||
| filter with later */ | |||
| return error; | |||
| } | |||
| void vorbis_lpc_predict(float *coeff,float *prime,int m, | |||
| float *data,long n){ | |||
| /* in: coeff[0...m-1] LPC coefficients | |||
| prime[0...m-1] initial values (allocated size of n+m-1) | |||
| out: data[0...n-1] data samples */ | |||
| long i,j,o,p; | |||
| float y; | |||
| float *work=(float*)alloca(sizeof(*work)*(m+n)); | |||
| if(!prime) | |||
| for(i=0;i<m;i++) | |||
| work[i]=0.f; | |||
| else | |||
| for(i=0;i<m;i++) | |||
| work[i]=prime[i]; | |||
| for(i=0;i<n;i++){ | |||
| y=0; | |||
| o=i; | |||
| p=m; | |||
| for(j=0;j<m;j++) | |||
| y-=work[o++]*coeff[--p]; | |||
| data[i]=work[o]=y; | |||
| } | |||
| } | |||
| @@ -1,29 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: LPC low level routines | |||
| last mod: $Id: lpc.h 16037 2009-05-26 21:10:58Z xiphmont $ | |||
| ********************************************************************/ | |||
| #ifndef _V_LPC_H_ | |||
| #define _V_LPC_H_ | |||
| #include "../../codec.h" | |||
| /* simple linear scale LPC code */ | |||
| extern float vorbis_lpc_from_data(float *data,float *lpc,int n,int m); | |||
| extern void vorbis_lpc_predict(float *coeff,float *prime,int m, | |||
| float *data,long n); | |||
| #endif | |||
| @@ -1,454 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: LSP (also called LSF) conversion routines | |||
| last mod: $Id: lsp.c 17538 2010-10-15 02:52:29Z tterribe $ | |||
| The LSP generation code is taken (with minimal modification and a | |||
| few bugfixes) from "On the Computation of the LSP Frequencies" by | |||
| Joseph Rothweiler (see http://www.rothweiler.us for contact info). | |||
| The paper is available at: | |||
| http://www.myown1.com/joe/lsf | |||
| ********************************************************************/ | |||
| /* Note that the lpc-lsp conversion finds the roots of polynomial with | |||
| an iterative root polisher (CACM algorithm 283). It *is* possible | |||
| to confuse this algorithm into not converging; that should only | |||
| happen with absurdly closely spaced roots (very sharp peaks in the | |||
| LPC f response) which in turn should be impossible in our use of | |||
| the code. If this *does* happen anyway, it's a bug in the floor | |||
| finder; find the cause of the confusion (probably a single bin | |||
| spike or accidental near-float-limit resolution problems) and | |||
| correct it. */ | |||
| #include <math.h> | |||
| #include <string.h> | |||
| #include <stdlib.h> | |||
| #include "lsp.h" | |||
| #include "os.h" | |||
| #include "misc.h" | |||
| #include "lookup.h" | |||
| #include "scales.h" | |||
| /* three possible LSP to f curve functions; the exact computation | |||
| (float), a lookup based float implementation, and an integer | |||
| implementation. The float lookup is likely the optimal choice on | |||
| any machine with an FPU. The integer implementation is *not* fixed | |||
| point (due to the need for a large dynamic range and thus a | |||
| separately tracked exponent) and thus much more complex than the | |||
| relatively simple float implementations. It's mostly for future | |||
| work on a fully fixed point implementation for processors like the | |||
| ARM family. */ | |||
| /* define either of these (preferably FLOAT_LOOKUP) to have faster | |||
| but less precise implementation. */ | |||
| #undef FLOAT_LOOKUP | |||
| #undef INT_LOOKUP | |||
| #ifdef FLOAT_LOOKUP | |||
| #include "lookup.c" /* catch this in the build system; we #include for | |||
| compilers (like gcc) that can't inline across | |||
| modules */ | |||
| /* side effect: changes *lsp to cosines of lsp */ | |||
| void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, | |||
| float amp,float ampoffset){ | |||
| int i; | |||
| float wdel=M_PI/ln; | |||
| vorbis_fpu_control fpu; | |||
| vorbis_fpu_setround(&fpu); | |||
| for(i=0;i<m;i++)lsp[i]=vorbis_coslook(lsp[i]); | |||
| i=0; | |||
| while(i<n){ | |||
| int k=map[i]; | |||
| int qexp; | |||
| float p=.7071067812f; | |||
| float q=.7071067812f; | |||
| float w=vorbis_coslook(wdel*k); | |||
| float *ftmp=lsp; | |||
| int c=m>>1; | |||
| while(c--){ | |||
| q*=ftmp[0]-w; | |||
| p*=ftmp[1]-w; | |||
| ftmp+=2; | |||
| } | |||
| if(m&1){ | |||
| /* odd order filter; slightly assymetric */ | |||
| /* the last coefficient */ | |||
| q*=ftmp[0]-w; | |||
| q*=q; | |||
| p*=p*(1.f-w*w); | |||
| }else{ | |||
| /* even order filter; still symmetric */ | |||
| q*=q*(1.f+w); | |||
| p*=p*(1.f-w); | |||
| } | |||
| q=frexp(p+q,&qexp); | |||
| q=vorbis_fromdBlook(amp* | |||
| vorbis_invsqlook(q)* | |||
| vorbis_invsq2explook(qexp+m)- | |||
| ampoffset); | |||
| do{ | |||
| curve[i++]*=q; | |||
| }while(map[i]==k); | |||
| } | |||
| vorbis_fpu_restore(fpu); | |||
| } | |||
| #else | |||
| #ifdef INT_LOOKUP | |||
| #include "lookup.c" /* catch this in the build system; we #include for | |||
| compilers (like gcc) that can't inline across | |||
| modules */ | |||
| static const int MLOOP_1[64]={ | |||
| 0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13, | |||
| 14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14, | |||
| 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, | |||
| 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15, | |||
| }; | |||
| static const int MLOOP_2[64]={ | |||
| 0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7, | |||
| 8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8, | |||
| 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9, | |||
| 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9, | |||
| }; | |||
| static const int MLOOP_3[8]={0,1,2,2,3,3,3,3}; | |||
| /* side effect: changes *lsp to cosines of lsp */ | |||
| void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, | |||
| float amp,float ampoffset){ | |||
| /* 0 <= m < 256 */ | |||
| /* set up for using all int later */ | |||
| int i; | |||
| int ampoffseti=rint(ampoffset*4096.f); | |||
| int ampi=rint(amp*16.f); | |||
| long *ilsp=(long*)alloca(m*sizeof(*ilsp)); | |||
| for(i=0;i<m;i++)ilsp[i]=vorbis_coslook_i(lsp[i]/M_PI*65536.f+.5f); | |||
| i=0; | |||
| while(i<n){ | |||
| int j,k=map[i]; | |||
| unsigned long pi=46341; /* 2**-.5 in 0.16 */ | |||
| unsigned long qi=46341; | |||
| int qexp=0,shift; | |||
| long wi=vorbis_coslook_i(k*65536/ln); | |||
| qi*=labs(ilsp[0]-wi); | |||
| pi*=labs(ilsp[1]-wi); | |||
| for(j=3;j<m;j+=2){ | |||
| if(!(shift=MLOOP_1[(pi|qi)>>25])) | |||
| if(!(shift=MLOOP_2[(pi|qi)>>19])) | |||
| shift=MLOOP_3[(pi|qi)>>16]; | |||
| qi=(qi>>shift)*labs(ilsp[j-1]-wi); | |||
| pi=(pi>>shift)*labs(ilsp[j]-wi); | |||
| qexp+=shift; | |||
| } | |||
| if(!(shift=MLOOP_1[(pi|qi)>>25])) | |||
| if(!(shift=MLOOP_2[(pi|qi)>>19])) | |||
| shift=MLOOP_3[(pi|qi)>>16]; | |||
| /* pi,qi normalized collectively, both tracked using qexp */ | |||
| if(m&1){ | |||
| /* odd order filter; slightly assymetric */ | |||
| /* the last coefficient */ | |||
| qi=(qi>>shift)*labs(ilsp[j-1]-wi); | |||
| pi=(pi>>shift)<<14; | |||
| qexp+=shift; | |||
| if(!(shift=MLOOP_1[(pi|qi)>>25])) | |||
| if(!(shift=MLOOP_2[(pi|qi)>>19])) | |||
| shift=MLOOP_3[(pi|qi)>>16]; | |||
| pi>>=shift; | |||
| qi>>=shift; | |||
| qexp+=shift-14*((m+1)>>1); | |||
| pi=((pi*pi)>>16); | |||
| qi=((qi*qi)>>16); | |||
| qexp=qexp*2+m; | |||
| pi*=(1<<14)-((wi*wi)>>14); | |||
| qi+=pi>>14; | |||
| }else{ | |||
| /* even order filter; still symmetric */ | |||
| /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't | |||
| worth tracking step by step */ | |||
| pi>>=shift; | |||
| qi>>=shift; | |||
| qexp+=shift-7*m; | |||
| pi=((pi*pi)>>16); | |||
| qi=((qi*qi)>>16); | |||
| qexp=qexp*2+m; | |||
| pi*=(1<<14)-wi; | |||
| qi*=(1<<14)+wi; | |||
| qi=(qi+pi)>>14; | |||
| } | |||
| /* we've let the normalization drift because it wasn't important; | |||
| however, for the lookup, things must be normalized again. We | |||
| need at most one right shift or a number of left shifts */ | |||
| if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */ | |||
| qi>>=1; qexp++; | |||
| }else | |||
| while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/ | |||
| qi<<=1; qexp--; | |||
| } | |||
| amp=vorbis_fromdBlook_i(ampi* /* n.4 */ | |||
| vorbis_invsqlook_i(qi,qexp)- | |||
| /* m.8, m+n<=8 */ | |||
| ampoffseti); /* 8.12[0] */ | |||
| curve[i]*=amp; | |||
| while(map[++i]==k)curve[i]*=amp; | |||
| } | |||
| } | |||
| #else | |||
| /* old, nonoptimized but simple version for any poor sap who needs to | |||
| figure out what the hell this code does, or wants the other | |||
| fraction of a dB precision */ | |||
| /* side effect: changes *lsp to cosines of lsp */ | |||
| void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m, | |||
| float amp,float ampoffset){ | |||
| int i; | |||
| float wdel=M_PI/ln; | |||
| for(i=0;i<m;i++)lsp[i]=2.f*cos(lsp[i]); | |||
| i=0; | |||
| while(i<n){ | |||
| int j,k=map[i]; | |||
| float p=.5f; | |||
| float q=.5f; | |||
| float w=2.f*cos(wdel*k); | |||
| for(j=1;j<m;j+=2){ | |||
| q *= w-lsp[j-1]; | |||
| p *= w-lsp[j]; | |||
| } | |||
| if(j==m){ | |||
| /* odd order filter; slightly assymetric */ | |||
| /* the last coefficient */ | |||
| q*=w-lsp[j-1]; | |||
| p*=p*(4.f-w*w); | |||
| q*=q; | |||
| }else{ | |||
| /* even order filter; still symmetric */ | |||
| p*=p*(2.f-w); | |||
| q*=q*(2.f+w); | |||
| } | |||
| q=fromdB(amp/sqrt(p+q)-ampoffset); | |||
| curve[i]*=q; | |||
| while(map[++i]==k)curve[i]*=q; | |||
| } | |||
| } | |||
| #endif | |||
| #endif | |||
| static void cheby(float *g, int ord) { | |||
| int i, j; | |||
| g[0] *= .5f; | |||
| for(i=2; i<= ord; i++) { | |||
| for(j=ord; j >= i; j--) { | |||
| g[j-2] -= g[j]; | |||
| g[j] += g[j]; | |||
| } | |||
| } | |||
| } | |||
| static int JUCE_CDECL comp(const void *a,const void *b){ | |||
| return (*(float *)a<*(float *)b)-(*(float *)a>*(float *)b); | |||
| } | |||
| /* Newton-Raphson-Maehly actually functioned as a decent root finder, | |||
| but there are root sets for which it gets into limit cycles | |||
| (exacerbated by zero suppression) and fails. We can't afford to | |||
| fail, even if the failure is 1 in 100,000,000, so we now use | |||
| Laguerre and later polish with Newton-Raphson (which can then | |||
| afford to fail) */ | |||
| #define EPSILON 10e-7 | |||
| static int Laguerre_With_Deflation(float *a,int ord,float *r){ | |||
| int i,m; | |||
| double *defl=(double*)alloca(sizeof(*defl)*(ord+1)); | |||
| for(i=0;i<=ord;i++)defl[i]=a[i]; | |||
| for(m=ord;m>0;m--){ | |||
| double newx=0.f,delta; | |||
| /* iterate a root */ | |||
| while(1){ | |||
| double p=defl[m],pp=0.f,ppp=0.f,denom; | |||
| /* eval the polynomial and its first two derivatives */ | |||
| for(i=m;i>0;i--){ | |||
| ppp = newx*ppp + pp; | |||
| pp = newx*pp + p; | |||
| p = newx*p + defl[i-1]; | |||
| } | |||
| /* Laguerre's method */ | |||
| denom=(m-1) * ((m-1)*pp*pp - m*p*ppp); | |||
| if(denom<0) | |||
| return(-1); /* complex root! The LPC generator handed us a bad filter */ | |||
| if(pp>0){ | |||
| denom = pp + sqrt(denom); | |||
| if(denom<EPSILON)denom=EPSILON; | |||
| }else{ | |||
| denom = pp - sqrt(denom); | |||
| if(denom>-(EPSILON))denom=-(EPSILON); | |||
| } | |||
| delta = m*p/denom; | |||
| newx -= delta; | |||
| if(delta<0.f)delta*=-1; | |||
| if(fabs(delta/newx)<10e-12)break; | |||
| } | |||
| r[m-1]=newx; | |||
| /* forward deflation */ | |||
| for(i=m;i>0;i--) | |||
| defl[i-1]+=newx*defl[i]; | |||
| defl++; | |||
| } | |||
| return(0); | |||
| } | |||
| /* for spit-and-polish only */ | |||
| static int Newton_Raphson(float *a,int ord,float *r){ | |||
| int i, k, count=0; | |||
| double error=1.f; | |||
| double *root=(double*)alloca(ord*sizeof(*root)); | |||
| for(i=0; i<ord;i++) root[i] = r[i]; | |||
| while(error>1e-20){ | |||
| error=0; | |||
| for(i=0; i<ord; i++) { /* Update each point. */ | |||
| double pp=0.,delta; | |||
| double rooti=root[i]; | |||
| double p=a[ord]; | |||
| for(k=ord-1; k>= 0; k--) { | |||
| pp= pp* rooti + p; | |||
| p = p * rooti + a[k]; | |||
| } | |||
| delta = p/pp; | |||
| root[i] -= delta; | |||
| error+= delta*delta; | |||
| } | |||
| if(count>40)return(-1); | |||
| count++; | |||
| } | |||
| /* Replaced the original bubble sort with a real sort. With your | |||
| help, we can eliminate the bubble sort in our lifetime. --Monty */ | |||
| for(i=0; i<ord;i++) r[i] = root[i]; | |||
| return(0); | |||
| } | |||
| /* Convert lpc coefficients to lsp coefficients */ | |||
| int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m){ | |||
| int order2=(m+1)>>1; | |||
| int g1_order,g2_order; | |||
| float *g1=(float*)alloca(sizeof(*g1)*(order2+1)); | |||
| float *g2=(float*)alloca(sizeof(*g2)*(order2+1)); | |||
| float *g1r=(float*)alloca(sizeof(*g1r)*(order2+1)); | |||
| float *g2r=(float*)alloca(sizeof(*g2r)*(order2+1)); | |||
| int i; | |||
| /* even and odd are slightly different base cases */ | |||
| g1_order=(m+1)>>1; | |||
| g2_order=(m) >>1; | |||
| /* Compute the lengths of the x polynomials. */ | |||
| /* Compute the first half of K & R F1 & F2 polynomials. */ | |||
| /* Compute half of the symmetric and antisymmetric polynomials. */ | |||
| /* Remove the roots at +1 and -1. */ | |||
| g1[g1_order] = 1.f; | |||
| for(i=1;i<=g1_order;i++) g1[g1_order-i] = lpc[i-1]+lpc[m-i]; | |||
| g2[g2_order] = 1.f; | |||
| for(i=1;i<=g2_order;i++) g2[g2_order-i] = lpc[i-1]-lpc[m-i]; | |||
| if(g1_order>g2_order){ | |||
| for(i=2; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+2]; | |||
| }else{ | |||
| for(i=1; i<=g1_order;i++) g1[g1_order-i] -= g1[g1_order-i+1]; | |||
| for(i=1; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+1]; | |||
| } | |||
| /* Convert into polynomials in cos(alpha) */ | |||
| cheby(g1,g1_order); | |||
| cheby(g2,g2_order); | |||
| /* Find the roots of the 2 even polynomials.*/ | |||
| if(Laguerre_With_Deflation(g1,g1_order,g1r) || | |||
| Laguerre_With_Deflation(g2,g2_order,g2r)) | |||
| return(-1); | |||
| Newton_Raphson(g1,g1_order,g1r); /* if it fails, it leaves g1r alone */ | |||
| Newton_Raphson(g2,g2_order,g2r); /* if it fails, it leaves g2r alone */ | |||
| qsort(g1r,g1_order,sizeof(*g1r),comp); | |||
| qsort(g2r,g2_order,sizeof(*g2r),comp); | |||
| for(i=0;i<g1_order;i++) | |||
| lsp[i*2] = acos(g1r[i]); | |||
| for(i=0;i<g2_order;i++) | |||
| lsp[i*2+1] = acos(g2r[i]); | |||
| return(0); | |||
| } | |||
| @@ -1,28 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: LSP (also called LSF) conversion routines | |||
| last mod: $Id: lsp.h 16227 2009-07-08 06:58:46Z xiphmont $ | |||
| ********************************************************************/ | |||
| #ifndef _V_LSP_H_ | |||
| #define _V_LSP_H_ | |||
| extern int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m); | |||
| extern void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln, | |||
| float *lsp,int m, | |||
| float amp,float ampoffset); | |||
| #endif | |||
| @@ -1,816 +0,0 @@ | |||
| /******************************************************************** | |||
| * * | |||
| * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * | |||
| * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * | |||
| * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * | |||
| * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * | |||
| * * | |||
| * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * | |||
| * by the Xiph.Org Foundation http://www.xiph.org/ * | |||
| * * | |||
| ******************************************************************** | |||
| function: channel mapping 0 implementation | |||
| last mod: $Id: mapping0.c 17022 2010-03-25 03:45:42Z xiphmont $ | |||
| ********************************************************************/ | |||
| #include <stdlib.h> | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <math.h> | |||
| #include "../../ogg.h" | |||
| #include "../../codec.h" | |||
| #include "codec_internal.h" | |||
| #include "codebook.h" | |||
| #include "window.h" | |||
| #include "registry.h" | |||
| #include "psy.h" | |||
| #include "misc.h" | |||
| /* simplistic, wasteful way of doing this (unique lookup for each | |||
| mode/submapping); there should be a central repository for | |||
| identical lookups. That will require minor work, so I'm putting it | |||
| off as low priority. | |||
| Why a lookup for each backend in a given mode? Because the | |||
| blocksize is set by the mode, and low backend lookups may require | |||
| parameters from other areas of the mode/mapping */ | |||
| static void mapping0_free_info(vorbis_info_mapping *i){ | |||
| vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)i; | |||
| if(info){ | |||
| memset(info,0,sizeof(*info)); | |||
| _ogg_free(info); | |||
| } | |||
| } | |||
| static int ilog3(unsigned int v){ | |||
| int ret=0; | |||
| if(v)--v; | |||
| while(v){ | |||
| ret++; | |||
| v>>=1; | |||
| } | |||
| return(ret); | |||
| } | |||
| static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm, | |||
| oggpack_buffer *opb){ | |||
| int i; | |||
| vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)vm; | |||
| /* another 'we meant to do it this way' hack... up to beta 4, we | |||
| packed 4 binary zeros here to signify one submapping in use. We | |||
| now redefine that to mean four bitflags that indicate use of | |||
| deeper features; bit0:submappings, bit1:coupling, | |||
| bit2,3:reserved. This is backward compatable with all actual uses | |||
| of the beta code. */ | |||
| if(info->submaps>1){ | |||
| oggpack_write(opb,1,1); | |||
| oggpack_write(opb,info->submaps-1,4); | |||
| }else | |||
| oggpack_write(opb,0,1); | |||
| if(info->coupling_steps>0){ | |||
| oggpack_write(opb,1,1); | |||
| oggpack_write(opb,info->coupling_steps-1,8); | |||
| for(i=0;i<info->coupling_steps;i++){ | |||
| oggpack_write(opb,info->coupling_mag[i],ilog3(vi->channels)); | |||
| oggpack_write(opb,info->coupling_ang[i],ilog3(vi->channels)); | |||
| } | |||
| }else | |||
| oggpack_write(opb,0,1); | |||
| oggpack_write(opb,0,2); /* 2,3:reserved */ | |||
| /* we don't write the channel submappings if we only have one... */ | |||
| if(info->submaps>1){ | |||
| for(i=0;i<vi->channels;i++) | |||
| oggpack_write(opb,info->chmuxlist[i],4); | |||
| } | |||
| for(i=0;i<info->submaps;i++){ | |||
| oggpack_write(opb,0,8); /* time submap unused */ | |||
| oggpack_write(opb,info->floorsubmap[i],8); | |||
| oggpack_write(opb,info->residuesubmap[i],8); | |||
| } | |||
| } | |||
| /* also responsible for range checking */ | |||
| static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb){ | |||
| int i,b; | |||
| vorbis_info_mapping0 *info=(vorbis_info_mapping0*)_ogg_calloc(1,sizeof(*info)); | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| memset(info,0,sizeof(*info)); | |||
| b=oggpack_read(opb,1); | |||
| if(b<0)goto err_out; | |||
| if(b){ | |||
| info->submaps=oggpack_read(opb,4)+1; | |||
| if(info->submaps<=0)goto err_out; | |||
| }else | |||
| info->submaps=1; | |||
| b=oggpack_read(opb,1); | |||
| if(b<0)goto err_out; | |||
| if(b){ | |||
| info->coupling_steps=oggpack_read(opb,8)+1; | |||
| if(info->coupling_steps<=0)goto err_out; | |||
| for(i=0;i<info->coupling_steps;i++){ | |||
| int testM=info->coupling_mag[i]=oggpack_read(opb,ilog3(vi->channels)); | |||
| int testA=info->coupling_ang[i]=oggpack_read(opb,ilog3(vi->channels)); | |||
| if(testM<0 || | |||
| testA<0 || | |||
| testM==testA || | |||
| testM>=vi->channels || | |||
| testA>=vi->channels) goto err_out; | |||
| } | |||
| } | |||
| if(oggpack_read(opb,2)!=0)goto err_out; /* 2,3:reserved */ | |||
| if(info->submaps>1){ | |||
| for(i=0;i<vi->channels;i++){ | |||
| info->chmuxlist[i]=oggpack_read(opb,4); | |||
| if(info->chmuxlist[i]>=info->submaps || info->chmuxlist[i]<0)goto err_out; | |||
| } | |||
| } | |||
| for(i=0;i<info->submaps;i++){ | |||
| oggpack_read(opb,8); /* time submap unused */ | |||
| info->floorsubmap[i]=oggpack_read(opb,8); | |||
| if(info->floorsubmap[i]>=ci->floors || info->floorsubmap[i]<0)goto err_out; | |||
| info->residuesubmap[i]=oggpack_read(opb,8); | |||
| if(info->residuesubmap[i]>=ci->residues || info->residuesubmap[i]<0)goto err_out; | |||
| } | |||
| return info; | |||
| err_out: | |||
| mapping0_free_info(info); | |||
| return(NULL); | |||
| } | |||
| #include "os.h" | |||
| #include "lpc.h" | |||
| #include "lsp.h" | |||
| #include "envelope.h" | |||
| #include "mdct.h" | |||
| #include "psy.h" | |||
| #include "scales.h" | |||
| #if 0 | |||
| static long seq=0; | |||
| static ogg_int64_t total=0; | |||
| static float FLOOR1_fromdB_LOOKUP[256]={ | |||
| 1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F, | |||
| 1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F, | |||
| 1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F, | |||
| 2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F, | |||
| 2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F, | |||
| 3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F, | |||
| 4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F, | |||
| 6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F, | |||
| 7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F, | |||
| 1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F, | |||
| 1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F, | |||
| 1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F, | |||
| 2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F, | |||
| 2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F, | |||
| 3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F, | |||
| 4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F, | |||
| 5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F, | |||
| 7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F, | |||
| 9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F, | |||
| 1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F, | |||
| 1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F, | |||
| 2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F, | |||
| 2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F, | |||
| 3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F, | |||
| 4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F, | |||
| 5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F, | |||
| 7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F, | |||
| 9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F, | |||
| 0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F, | |||
| 0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F, | |||
| 0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F, | |||
| 0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F, | |||
| 0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F, | |||
| 0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F, | |||
| 0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F, | |||
| 0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F, | |||
| 0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F, | |||
| 0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F, | |||
| 0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F, | |||
| 0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F, | |||
| 0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F, | |||
| 0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F, | |||
| 0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F, | |||
| 0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F, | |||
| 0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F, | |||
| 0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F, | |||
| 0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F, | |||
| 0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F, | |||
| 0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F, | |||
| 0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F, | |||
| 0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F, | |||
| 0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F, | |||
| 0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F, | |||
| 0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F, | |||
| 0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F, | |||
| 0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F, | |||
| 0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F, | |||
| 0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F, | |||
| 0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F, | |||
| 0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F, | |||
| 0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F, | |||
| 0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F, | |||
| 0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F, | |||
| 0.82788260F, 0.88168307F, 0.9389798F, 1.F, | |||
| }; | |||
| #endif | |||
| static int mapping0_forward(vorbis_block *vb){ | |||
| vorbis_dsp_state *vd=vb->vd; | |||
| vorbis_info *vi=vd->vi; | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| private_state *b=(private_state*)vb->vd->backend_state; | |||
| vorbis_block_internal *vbi=(vorbis_block_internal *)vb->internal; | |||
| int n=vb->pcmend; | |||
| int i,j,k; | |||
| int *nonzero = (int*)alloca(sizeof(*nonzero)*vi->channels); | |||
| float **gmdct = (float**)_vorbis_block_alloc(vb,vi->channels*sizeof(*gmdct)); | |||
| int **iwork = (int**)_vorbis_block_alloc(vb,vi->channels*sizeof(*iwork)); | |||
| int ***floor_posts = (int***)_vorbis_block_alloc(vb,vi->channels*sizeof(*floor_posts)); | |||
| float global_ampmax=vbi->ampmax; | |||
| float *local_ampmax=(float*)alloca(sizeof(*local_ampmax)*vi->channels); | |||
| int blocktype=vbi->blocktype; | |||
| int modenumber=vb->W; | |||
| vorbis_info_mapping0 *info=(vorbis_info_mapping0*)ci->map_param[modenumber]; | |||
| vorbis_look_psy *psy_look=b->psy+blocktype+(vb->W?2:0); | |||
| vb->mode=modenumber; | |||
| for(i=0;i<vi->channels;i++){ | |||
| float scale=4.f/n; | |||
| float scale_dB; | |||
| float *pcm =vb->pcm[i]; | |||
| float *logfft =pcm; | |||
| iwork[i]=(int*)_vorbis_block_alloc(vb,n/2*sizeof(**iwork)); | |||
| gmdct[i]=(float*)_vorbis_block_alloc(vb,n/2*sizeof(**gmdct)); | |||
| scale_dB=todB(&scale) + .345; /* + .345 is a hack; the original | |||
| todB estimation used on IEEE 754 | |||
| compliant machines had a bug that | |||
| returned dB values about a third | |||
| of a decibel too high. The bug | |||
| was harmless because tunings | |||
| implicitly took that into | |||
| account. However, fixing the bug | |||
| in the estimator requires | |||
| changing all the tunings as well. | |||
| For now, it's easier to sync | |||
| things back up here, and | |||
| recalibrate the tunings in the | |||
| next major model upgrade. */ | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0) | |||
| _analysis_output("pcmL",seq,pcm,n,0,0,total-n/2); | |||
| else | |||
| _analysis_output("pcmR",seq,pcm,n,0,0,total-n/2); | |||
| }else{ | |||
| _analysis_output("pcm",seq,pcm,n,0,0,total-n/2); | |||
| } | |||
| #endif | |||
| /* window the PCM data */ | |||
| _vorbis_apply_window(pcm,b->window,ci->blocksizes,vb->lW,vb->W,vb->nW); | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0) | |||
| _analysis_output("windowedL",seq,pcm,n,0,0,total-n/2); | |||
| else | |||
| _analysis_output("windowedR",seq,pcm,n,0,0,total-n/2); | |||
| }else{ | |||
| _analysis_output("windowed",seq,pcm,n,0,0,total-n/2); | |||
| } | |||
| #endif | |||
| /* transform the PCM data */ | |||
| /* only MDCT right now.... */ | |||
| mdct_forward((mdct_lookup*) b->transform[vb->W][0],pcm,gmdct[i]); | |||
| /* FFT yields more accurate tonal estimation (not phase sensitive) */ | |||
| drft_forward(&b->fft_look[vb->W],pcm); | |||
| logfft[0]=scale_dB+todB(pcm) + .345; /* + .345 is a hack; the | |||
| original todB estimation used on | |||
| IEEE 754 compliant machines had a | |||
| bug that returned dB values about | |||
| a third of a decibel too high. | |||
| The bug was harmless because | |||
| tunings implicitly took that into | |||
| account. However, fixing the bug | |||
| in the estimator requires | |||
| changing all the tunings as well. | |||
| For now, it's easier to sync | |||
| things back up here, and | |||
| recalibrate the tunings in the | |||
| next major model upgrade. */ | |||
| local_ampmax[i]=logfft[0]; | |||
| for(j=1;j<n-1;j+=2){ | |||
| float temp=pcm[j]*pcm[j]+pcm[j+1]*pcm[j+1]; | |||
| temp=logfft[(j+1)>>1]=scale_dB+.5f*todB(&temp) + .345; /* + | |||
| .345 is a hack; the original todB | |||
| estimation used on IEEE 754 | |||
| compliant machines had a bug that | |||
| returned dB values about a third | |||
| of a decibel too high. The bug | |||
| was harmless because tunings | |||
| implicitly took that into | |||
| account. However, fixing the bug | |||
| in the estimator requires | |||
| changing all the tunings as well. | |||
| For now, it's easier to sync | |||
| things back up here, and | |||
| recalibrate the tunings in the | |||
| next major model upgrade. */ | |||
| if(temp>local_ampmax[i])local_ampmax[i]=temp; | |||
| } | |||
| if(local_ampmax[i]>0.f)local_ampmax[i]=0.f; | |||
| if(local_ampmax[i]>global_ampmax)global_ampmax=local_ampmax[i]; | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0){ | |||
| _analysis_output("fftL",seq,logfft,n/2,1,0,0); | |||
| }else{ | |||
| _analysis_output("fftR",seq,logfft,n/2,1,0,0); | |||
| } | |||
| }else{ | |||
| _analysis_output("fft",seq,logfft,n/2,1,0,0); | |||
| } | |||
| #endif | |||
| } | |||
| { | |||
| float *noise = (float*)_vorbis_block_alloc(vb,n/2*sizeof(*noise)); | |||
| float *tone = (float*)_vorbis_block_alloc(vb,n/2*sizeof(*tone)); | |||
| for(i=0;i<vi->channels;i++){ | |||
| /* the encoder setup assumes that all the modes used by any | |||
| specific bitrate tweaking use the same floor */ | |||
| int submap=info->chmuxlist[i]; | |||
| /* the following makes things clearer to *me* anyway */ | |||
| float *mdct =gmdct[i]; | |||
| float *logfft =vb->pcm[i]; | |||
| float *logmdct =logfft+n/2; | |||
| float *logmask =logfft; | |||
| vb->mode=modenumber; | |||
| floor_posts[i]=(int**)_vorbis_block_alloc(vb,PACKETBLOBS*sizeof(**floor_posts)); | |||
| memset(floor_posts[i],0,sizeof(**floor_posts)*PACKETBLOBS); | |||
| for(j=0;j<n/2;j++) | |||
| logmdct[j]=todB(mdct+j) + .345; /* + .345 is a hack; the original | |||
| todB estimation used on IEEE 754 | |||
| compliant machines had a bug that | |||
| returned dB values about a third | |||
| of a decibel too high. The bug | |||
| was harmless because tunings | |||
| implicitly took that into | |||
| account. However, fixing the bug | |||
| in the estimator requires | |||
| changing all the tunings as well. | |||
| For now, it's easier to sync | |||
| things back up here, and | |||
| recalibrate the tunings in the | |||
| next major model upgrade. */ | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0) | |||
| _analysis_output("mdctL",seq,logmdct,n/2,1,0,0); | |||
| else | |||
| _analysis_output("mdctR",seq,logmdct,n/2,1,0,0); | |||
| }else{ | |||
| _analysis_output("mdct",seq,logmdct,n/2,1,0,0); | |||
| } | |||
| #endif | |||
| /* first step; noise masking. Not only does 'noise masking' | |||
| give us curves from which we can decide how much resolution | |||
| to give noise parts of the spectrum, it also implicitly hands | |||
| us a tonality estimate (the larger the value in the | |||
| 'noise_depth' vector, the more tonal that area is) */ | |||
| _vp_noisemask(psy_look, | |||
| logmdct, | |||
| noise); /* noise does not have by-frequency offset | |||
| bias applied yet */ | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0) | |||
| _analysis_output("noiseL",seq,noise,n/2,1,0,0); | |||
| else | |||
| _analysis_output("noiseR",seq,noise,n/2,1,0,0); | |||
| }else{ | |||
| _analysis_output("noise",seq,noise,n/2,1,0,0); | |||
| } | |||
| #endif | |||
| /* second step: 'all the other crap'; all the stuff that isn't | |||
| computed/fit for bitrate management goes in the second psy | |||
| vector. This includes tone masking, peak limiting and ATH */ | |||
| _vp_tonemask(psy_look, | |||
| logfft, | |||
| tone, | |||
| global_ampmax, | |||
| local_ampmax[i]); | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0) | |||
| _analysis_output("toneL",seq,tone,n/2,1,0,0); | |||
| else | |||
| _analysis_output("toneR",seq,tone,n/2,1,0,0); | |||
| }else{ | |||
| _analysis_output("tone",seq,tone,n/2,1,0,0); | |||
| } | |||
| #endif | |||
| /* third step; we offset the noise vectors, overlay tone | |||
| masking. We then do a floor1-specific line fit. If we're | |||
| performing bitrate management, the line fit is performed | |||
| multiple times for up/down tweakage on demand. */ | |||
| #if 0 | |||
| { | |||
| float aotuv[psy_look->n]; | |||
| #endif | |||
| _vp_offset_and_mix(psy_look, | |||
| noise, | |||
| tone, | |||
| 1, | |||
| logmask, | |||
| mdct, | |||
| logmdct); | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0) | |||
| _analysis_output("aotuvM1_L",seq,aotuv,psy_look->n,1,1,0); | |||
| else | |||
| _analysis_output("aotuvM1_R",seq,aotuv,psy_look->n,1,1,0); | |||
| }else{ | |||
| _analysis_output("aotuvM1",seq,aotuv,psy_look->n,1,1,0); | |||
| } | |||
| } | |||
| #endif | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0) | |||
| _analysis_output("mask1L",seq,logmask,n/2,1,0,0); | |||
| else | |||
| _analysis_output("mask1R",seq,logmask,n/2,1,0,0); | |||
| }else{ | |||
| _analysis_output("mask1",seq,logmask,n/2,1,0,0); | |||
| } | |||
| #endif | |||
| /* this algorithm is hardwired to floor 1 for now; abort out if | |||
| we're *not* floor1. This won't happen unless someone has | |||
| broken the encode setup lib. Guard it anyway. */ | |||
| if(ci->floor_type[info->floorsubmap[submap]]!=1)return(-1); | |||
| floor_posts[i][PACKETBLOBS/2]= | |||
| floor1_fit(vb,(vorbis_look_floor1*)(b->flr[info->floorsubmap[submap]]), | |||
| logmdct, | |||
| logmask); | |||
| /* are we managing bitrate? If so, perform two more fits for | |||
| later rate tweaking (fits represent hi/lo) */ | |||
| if(vorbis_bitrate_managed(vb) && floor_posts[i][PACKETBLOBS/2]){ | |||
| /* higher rate by way of lower noise curve */ | |||
| _vp_offset_and_mix(psy_look, | |||
| noise, | |||
| tone, | |||
| 2, | |||
| logmask, | |||
| mdct, | |||
| logmdct); | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0) | |||
| _analysis_output("mask2L",seq,logmask,n/2,1,0,0); | |||
| else | |||
| _analysis_output("mask2R",seq,logmask,n/2,1,0,0); | |||
| }else{ | |||
| _analysis_output("mask2",seq,logmask,n/2,1,0,0); | |||
| } | |||
| #endif | |||
| floor_posts[i][PACKETBLOBS-1]= | |||
| floor1_fit(vb,(vorbis_look_floor1*)(b->flr[info->floorsubmap[submap]]), | |||
| logmdct, | |||
| logmask); | |||
| /* lower rate by way of higher noise curve */ | |||
| _vp_offset_and_mix(psy_look, | |||
| noise, | |||
| tone, | |||
| 0, | |||
| logmask, | |||
| mdct, | |||
| logmdct); | |||
| #if 0 | |||
| if(vi->channels==2){ | |||
| if(i==0) | |||
| _analysis_output("mask0L",seq,logmask,n/2,1,0,0); | |||
| else | |||
| _analysis_output("mask0R",seq,logmask,n/2,1,0,0); | |||
| }else{ | |||
| _analysis_output("mask0",seq,logmask,n/2,1,0,0); | |||
| } | |||
| #endif | |||
| floor_posts[i][0]= | |||
| floor1_fit(vb,(vorbis_look_floor1*)(b->flr[info->floorsubmap[submap]]), | |||
| logmdct, | |||
| logmask); | |||
| /* we also interpolate a range of intermediate curves for | |||
| intermediate rates */ | |||
| for(k=1;k<PACKETBLOBS/2;k++) | |||
| floor_posts[i][k]= | |||
| floor1_interpolate_fit(vb,(vorbis_look_floor1*)(b->flr[info->floorsubmap[submap]]), | |||
| floor_posts[i][0], | |||
| floor_posts[i][PACKETBLOBS/2], | |||
| k*65536/(PACKETBLOBS/2)); | |||
| for(k=PACKETBLOBS/2+1;k<PACKETBLOBS-1;k++) | |||
| floor_posts[i][k]= | |||
| floor1_interpolate_fit(vb,(vorbis_look_floor1*)(b->flr[info->floorsubmap[submap]]), | |||
| floor_posts[i][PACKETBLOBS/2], | |||
| floor_posts[i][PACKETBLOBS-1], | |||
| (k-PACKETBLOBS/2)*65536/(PACKETBLOBS/2)); | |||
| } | |||
| } | |||
| } | |||
| vbi->ampmax=global_ampmax; | |||
| /* | |||
| the next phases are performed once for vbr-only and PACKETBLOB | |||
| times for bitrate managed modes. | |||
| 1) encode actual mode being used | |||
| 2) encode the floor for each channel, compute coded mask curve/res | |||
| 3) normalize and couple. | |||
| 4) encode residue | |||
| 5) save packet bytes to the packetblob vector | |||
| */ | |||
| /* iterate over the many masking curve fits we've created */ | |||
| { | |||
| int **couple_bundle=(int**)alloca(sizeof(*couple_bundle)*vi->channels); | |||
| int *zerobundle=(int*)alloca(sizeof(*zerobundle)*vi->channels); | |||
| for(k=(vorbis_bitrate_managed(vb)?0:PACKETBLOBS/2); | |||
| k<=(vorbis_bitrate_managed(vb)?PACKETBLOBS-1:PACKETBLOBS/2); | |||
| k++){ | |||
| oggpack_buffer *opb=vbi->packetblob[k]; | |||
| /* start out our new packet blob with packet type and mode */ | |||
| /* Encode the packet type */ | |||
| oggpack_write(opb,0,1); | |||
| /* Encode the modenumber */ | |||
| /* Encode frame mode, pre,post windowsize, then dispatch */ | |||
| oggpack_write(opb,modenumber,b->modebits); | |||
| if(vb->W){ | |||
| oggpack_write(opb,vb->lW,1); | |||
| oggpack_write(opb,vb->nW,1); | |||
| } | |||
| /* encode floor, compute masking curve, sep out residue */ | |||
| for(i=0;i<vi->channels;i++){ | |||
| int submap=info->chmuxlist[i]; | |||
| int *ilogmask=iwork[i]; | |||
| nonzero[i]=floor1_encode(opb,vb,(vorbis_look_floor1*)(b->flr[info->floorsubmap[submap]]), | |||
| floor_posts[i][k], | |||
| ilogmask); | |||
| #if 0 | |||
| { | |||
| char buf[80]; | |||
| sprintf(buf,"maskI%c%d",i?'R':'L',k); | |||
| float work[n/2]; | |||
| for(j=0;j<n/2;j++) | |||
| work[j]=FLOOR1_fromdB_LOOKUP[iwork[i][j]]; | |||
| _analysis_output(buf,seq,work,n/2,1,1,0); | |||
| } | |||
| #endif | |||
| } | |||
| /* our iteration is now based on masking curve, not prequant and | |||
| coupling. Only one prequant/coupling step */ | |||
| /* quantize/couple */ | |||
| /* incomplete implementation that assumes the tree is all depth | |||
| one, or no tree at all */ | |||
| _vp_couple_quantize_normalize(k, | |||
| &ci->psy_g_param, | |||
| psy_look, | |||
| info, | |||
| gmdct, | |||
| iwork, | |||
| nonzero, | |||
| ci->psy_g_param.sliding_lowpass[vb->W][k], | |||
| vi->channels); | |||
| #if 0 | |||
| for(i=0;i<vi->channels;i++){ | |||
| char buf[80]; | |||
| sprintf(buf,"res%c%d",i?'R':'L',k); | |||
| float work[n/2]; | |||
| for(j=0;j<n/2;j++) | |||
| work[j]=iwork[i][j]; | |||
| _analysis_output(buf,seq,work,n/2,1,0,0); | |||
| } | |||
| #endif | |||
| /* classify and encode by submap */ | |||
| for(i=0;i<info->submaps;i++){ | |||
| int ch_in_bundle=0; | |||
| long **classifications; | |||
| int resnum=info->residuesubmap[i]; | |||
| for(j=0;j<vi->channels;j++){ | |||
| if(info->chmuxlist[j]==i){ | |||
| zerobundle[ch_in_bundle]=0; | |||
| if(nonzero[j])zerobundle[ch_in_bundle]=1; | |||
| couple_bundle[ch_in_bundle++]=iwork[j]; | |||
| } | |||
| } | |||
| classifications=_residue_P[ci->residue_type[resnum]]-> | |||
| classx(vb,b->residue[resnum],couple_bundle,zerobundle,ch_in_bundle); | |||
| ch_in_bundle=0; | |||
| for(j=0;j<vi->channels;j++) | |||
| if(info->chmuxlist[j]==i) | |||
| couple_bundle[ch_in_bundle++]=iwork[j]; | |||
| _residue_P[ci->residue_type[resnum]]-> | |||
| forward(opb,vb,b->residue[resnum], | |||
| couple_bundle,zerobundle,ch_in_bundle,classifications,i); | |||
| } | |||
| /* ok, done encoding. Next protopacket. */ | |||
| } | |||
| } | |||
| #if 0 | |||
| seq++; | |||
| total+=ci->blocksizes[vb->W]/4+ci->blocksizes[vb->nW]/4; | |||
| #endif | |||
| return(0); | |||
| } | |||
| static int mapping0_inverse(vorbis_block *vb,vorbis_info_mapping *l){ | |||
| vorbis_dsp_state *vd=vb->vd; | |||
| vorbis_info *vi=vd->vi; | |||
| codec_setup_info *ci=(codec_setup_info*)vi->codec_setup; | |||
| private_state *b=(private_state*)vd->backend_state; | |||
| vorbis_info_mapping0 *info=(vorbis_info_mapping0 *)l; | |||
| int i,j; | |||
| long n=vb->pcmend=ci->blocksizes[vb->W]; | |||
| float **pcmbundle=(float**) alloca(sizeof(*pcmbundle)*vi->channels); | |||
| int *zerobundle=(int*) alloca(sizeof(*zerobundle)*vi->channels); | |||
| int *nonzero =(int*) alloca(sizeof(*nonzero)*vi->channels); | |||
| void **floormemo=(void**) alloca(sizeof(*floormemo)*vi->channels); | |||
| /* recover the spectral envelope; store it in the PCM vector for now */ | |||
| for(i=0;i<vi->channels;i++){ | |||
| int submap=info->chmuxlist[i]; | |||
| floormemo[i]=_floor_P[ci->floor_type[info->floorsubmap[submap]]]-> | |||
| inverse1(vb,b->flr[info->floorsubmap[submap]]); | |||
| if(floormemo[i]) | |||
| nonzero[i]=1; | |||
| else | |||
| nonzero[i]=0; | |||
| memset(vb->pcm[i],0,sizeof(*vb->pcm[i])*n/2); | |||
| } | |||
| /* channel coupling can 'dirty' the nonzero listing */ | |||
| for(i=0;i<info->coupling_steps;i++){ | |||
| if(nonzero[info->coupling_mag[i]] || | |||
| nonzero[info->coupling_ang[i]]){ | |||
| nonzero[info->coupling_mag[i]]=1; | |||
| nonzero[info->coupling_ang[i]]=1; | |||
| } | |||
| } | |||
| /* recover the residue into our working vectors */ | |||
| for(i=0;i<info->submaps;i++){ | |||
| int ch_in_bundle=0; | |||
| for(j=0;j<vi->channels;j++){ | |||
| if(info->chmuxlist[j]==i){ | |||
| if(nonzero[j]) | |||
| zerobundle[ch_in_bundle]=1; | |||
| else | |||
| zerobundle[ch_in_bundle]=0; | |||
| pcmbundle[ch_in_bundle++]=vb->pcm[j]; | |||
| } | |||
| } | |||
| _residue_P[ci->residue_type[info->residuesubmap[i]]]-> | |||
| inverse(vb,b->residue[info->residuesubmap[i]], | |||
| pcmbundle,zerobundle,ch_in_bundle); | |||
| } | |||
| /* channel coupling */ | |||
| for(i=info->coupling_steps-1;i>=0;i--){ | |||
| float *pcmM=vb->pcm[info->coupling_mag[i]]; | |||
| float *pcmA=vb->pcm[info->coupling_ang[i]]; | |||
| for(j=0;j<n/2;j++){ | |||
| float mag=pcmM[j]; | |||
| float ang=pcmA[j]; | |||
| if(mag>0) | |||
| if(ang>0){ | |||
| pcmM[j]=mag; | |||
| pcmA[j]=mag-ang; | |||
| }else{ | |||
| pcmA[j]=mag; | |||
| pcmM[j]=mag+ang; | |||
| } | |||
| else | |||
| if(ang>0){ | |||
| pcmM[j]=mag; | |||
| pcmA[j]=mag+ang; | |||
| }else{ | |||
| pcmA[j]=mag; | |||
| pcmM[j]=mag-ang; | |||
| } | |||
| } | |||
| } | |||
| /* compute and apply spectral envelope */ | |||
| for(i=0;i<vi->channels;i++){ | |||
| float *pcm=vb->pcm[i]; | |||
| int submap=info->chmuxlist[i]; | |||
| _floor_P[ci->floor_type[info->floorsubmap[submap]]]-> | |||
| inverse2(vb,b->flr[info->floorsubmap[submap]], | |||
| floormemo[i],pcm); | |||
| } | |||
| /* transform the PCM data; takes PCM vector, vb; modifies PCM vector */ | |||
| /* only MDCT right now.... */ | |||
| for(i=0;i<vi->channels;i++){ | |||
| float *pcm=vb->pcm[i]; | |||
| mdct_backward((mdct_lookup*) b->transform[vb->W][0],pcm,pcm); | |||
| } | |||
| /* all done! */ | |||
| return(0); | |||
| } | |||
| /* export hooks */ | |||
| const vorbis_func_mapping mapping0_exportbundle={ | |||
| &mapping0_pack, | |||
| &mapping0_unpack, | |||
| &mapping0_free_info, | |||
| &mapping0_forward, | |||
| &mapping0_inverse | |||
| }; | |||