audio decoder dependencies

adpcm
Dimitri Diakopoulos 11 years ago
parent 9b11afbfa1
commit ca58cd0531

File diff suppressed because it is too large Load Diff

@ -0,0 +1,371 @@
/* 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

@ -0,0 +1,46 @@
/* 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
#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

@ -0,0 +1,185 @@
/* 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"
#include <stdlib.h> /* for size_t */
/** \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

@ -0,0 +1,97 @@
/* 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,86 @@
/* 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

@ -0,0 +1,109 @@
/* 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 "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;
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,843 @@
/* 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 "private/bitwriter.h"
#include "private/crc.h"
#include "private/macros.h"
#include "FLAC/assert.h"
#include "share/alloc.h"
#include "share/compat.h"
#include "share/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 32
#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 = 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 = 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 = 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)
{
register 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);

@ -0,0 +1,487 @@
/* 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 "private/cpu.h"
#include <stdlib.h>
#include <memory.h>
#ifdef DEBUG
# 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;
__sigemptyset(&sigill_sse.sa_mask);
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)
{
#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 */

@ -0,0 +1,143 @@
/* 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 "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;
}

@ -0,0 +1,419 @@
/* 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 "share/compat.h"
#include "private/bitmath.h"
#include "private/fixed.h"
#include "private/macros.h"
#include "FLAC/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);
}
}

@ -0,0 +1,253 @@
/* 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
#ifndef FLAC__INTEGER_ONLY_LIBRARY
#ifndef FLAC__NO_ASM
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#include "private/fixed.h"
#ifdef FLAC__SSE2_SUPPORTED
#include <emmintrin.h> /* SSE2 */
#include <math.h>
#include "private/macros.h"
#include "share/compat.h"
#include "FLAC/assert.h"
#ifdef FLAC__CPU_IA32
#define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src)
#else
#define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src)
#endif
FLAC__SSE_TARGET("sse2")
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])
{
FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
unsigned i, order;
__m128i total_err0, total_err1, total_err2;
{
FLAC__int32 itmp;
__m128i last_error;
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
itmp = data[-2];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
itmp -= data[-3];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
itmp -= data[-3] - data[-4];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
total_err0 = total_err1 = _mm_setzero_si128();
for(i = 0; i < data_len; i++) {
__m128i err0, err1, tmp;
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
#if 1 /* OPT_SSE */
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
#else
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
#endif
tmp = _mm_slli_si128(err0, 12); // e0 0 0 0
last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3
last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3
tmp = _mm_srai_epi32(err0, 31);
err0 = _mm_xor_si128(err0, tmp);
err0 = _mm_sub_epi32(err0, tmp);
tmp = _mm_srai_epi32(err1, 31);
err1 = _mm_xor_si128(err1, tmp);
err1 = _mm_sub_epi32(err1, tmp);
total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0
total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4
}
}
total_error_0 = _mm_cvtsi128_si32(total_err0);
total_err2 = total_err1; // te1 te2 te3 te4
total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2
total_error_4 = _mm_cvtsi128_si32(total_err2);
total_error_2 = _mm_cvtsi128_si32(total_err1);
total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3
total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1
total_error_3 = _mm_cvtsi128_si32(total_err2);
total_error_1 = _mm_cvtsi128_si32(total_err1);
/* prefer higher order */
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);
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);
return order;
}
FLAC__SSE_TARGET("sse2")
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])
{
FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
unsigned i, order;
__m128i total_err0, total_err1, total_err3;
{
FLAC__int32 itmp;
__m128i last_error, zero = _mm_setzero_si128();
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
itmp = data[-2];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
itmp -= data[-3];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
itmp -= data[-3] - data[-4];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
total_err0 = total_err1 = total_err3 = _mm_setzero_si128();
for(i = 0; i < data_len; i++) {
__m128i err0, err1, tmp;
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
#if 1 /* OPT_SSE */
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
#else
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
#endif
tmp = _mm_slli_si128(err0, 12); // e0 0 0 0
last_error = _mm_srli_si128(err1, 4); // 0 e1 e2 e3
last_error = _mm_or_si128(last_error, tmp); // e0 e1 e2 e3
tmp = _mm_srai_epi32(err0, 31);
err0 = _mm_xor_si128(err0, tmp);
err0 = _mm_sub_epi32(err0, tmp);
tmp = _mm_srai_epi32(err1, 31);
err1 = _mm_xor_si128(err1, tmp);
err1 = _mm_sub_epi32(err1, tmp);
total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0
err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4|
err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2|
total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4
total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2
}
}
m128i_to_i64(total_error_0, total_err0);
m128i_to_i64(total_error_4, total_err3);
m128i_to_i64(total_error_2, total_err1);
total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3
total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1
m128i_to_i64(total_error_3, total_err3);
m128i_to_i64(total_error_1, total_err1);
/* prefer higher order */
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);
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);
return order;
}
#endif /* FLAC__SSE2_SUPPORTED */
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
#endif /* FLAC__NO_ASM */
#endif /* FLAC__INTEGER_ONLY_LIBRARY */

@ -0,0 +1,241 @@
/* 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
#ifndef FLAC__INTEGER_ONLY_LIBRARY
#ifndef FLAC__NO_ASM
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#include "private/fixed.h"
#ifdef FLAC__SSSE3_SUPPORTED
#include <tmmintrin.h> /* SSSE3 */
#include <math.h>
#include "private/macros.h"
#include "share/compat.h"
#include "FLAC/assert.h"
#ifdef FLAC__CPU_IA32
#define m128i_to_i64(dest, src) _mm_storel_epi64((__m128i*)&dest, src)
#else
#define m128i_to_i64(dest, src) dest = _mm_cvtsi128_si64(src)
#endif
FLAC__SSE_TARGET("ssse3")
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])
{
FLAC__uint32 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
unsigned i, order;
__m128i total_err0, total_err1, total_err2;
{
FLAC__int32 itmp;
__m128i last_error;
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
itmp = data[-2];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
itmp -= data[-3];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
itmp -= data[-3] - data[-4];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
total_err0 = total_err1 = _mm_setzero_si128();
for(i = 0; i < data_len; i++) {
__m128i err0, err1;
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
#if 1 /* OPT_SSE */
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
#else
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
#endif
last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3
err0 = _mm_abs_epi32(err0);
err1 = _mm_abs_epi32(err1);
total_err0 = _mm_add_epi32(total_err0, err0); // 0 0 0 te0
total_err1 = _mm_add_epi32(total_err1, err1); // te1 te2 te3 te4
}
}
total_error_0 = _mm_cvtsi128_si32(total_err0);
total_err2 = total_err1; // te1 te2 te3 te4
total_err1 = _mm_srli_si128(total_err1, 8); // 0 0 te1 te2
total_error_4 = _mm_cvtsi128_si32(total_err2);
total_error_2 = _mm_cvtsi128_si32(total_err1);
total_err2 = _mm_srli_si128(total_err2, 4); // 0 te1 te2 te3
total_err1 = _mm_srli_si128(total_err1, 4); // 0 0 0 te1
total_error_3 = _mm_cvtsi128_si32(total_err2);
total_error_1 = _mm_cvtsi128_si32(total_err1);
/* prefer higher order */
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);
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);
return order;
}
FLAC__SSE_TARGET("ssse3")
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])
{
FLAC__uint64 total_error_0, total_error_1, total_error_2, total_error_3, total_error_4;
unsigned i, order;
__m128i total_err0, total_err1, total_err3;
{
FLAC__int32 itmp;
__m128i last_error, zero = _mm_setzero_si128();
last_error = _mm_cvtsi32_si128(data[-1]); // 0 0 0 le0
itmp = data[-2];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 0 le0 le1
itmp -= data[-3];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // 0 le0 le1 le2
itmp -= data[-3] - data[-4];
last_error = _mm_shuffle_epi32(last_error, _MM_SHUFFLE(2,1,0,0));
last_error = _mm_sub_epi32(last_error, _mm_cvtsi32_si128(itmp)); // le0 le1 le2 le3
total_err0 = total_err1 = total_err3 = _mm_setzero_si128();
for(i = 0; i < data_len; i++) {
__m128i err0, err1;
err0 = _mm_cvtsi32_si128(data[i]); // 0 0 0 e0
err1 = _mm_shuffle_epi32(err0, _MM_SHUFFLE(0,0,0,0)); // e0 e0 e0 e0
#if 1 /* OPT_SSE */
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 le0 le1 le2
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 0 le0 le1
err1 = _mm_sub_epi32(err1, last_error);
last_error = _mm_srli_si128(last_error, 4); // 0 0 0 le0
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
#else
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 8)); // le0 le1 le2+le0 le3+le1
last_error = _mm_add_epi32(last_error, _mm_srli_si128(last_error, 4)); // le0 le1+le0 le2+le0+le1 le3+le1+le2+le0
err1 = _mm_sub_epi32(err1, last_error); // e1 e2 e3 e4
#endif
last_error = _mm_alignr_epi8(err0, err1, 4); // e0 e1 e2 e3
err0 = _mm_abs_epi32(err0);
err1 = _mm_abs_epi32(err1); // |e1| |e2| |e3| |e4|
total_err0 = _mm_add_epi64(total_err0, err0); // 0 te0
err0 = _mm_unpacklo_epi32(err1, zero); // 0 |e3| 0 |e4|
err1 = _mm_unpackhi_epi32(err1, zero); // 0 |e1| 0 |e2|
total_err3 = _mm_add_epi64(total_err3, err0); // te3 te4
total_err1 = _mm_add_epi64(total_err1, err1); // te1 te2
}
}
m128i_to_i64(total_error_0, total_err0);
m128i_to_i64(total_error_4, total_err3);
m128i_to_i64(total_error_2, total_err1);
total_err3 = _mm_srli_si128(total_err3, 8); // 0 te3
total_err1 = _mm_srli_si128(total_err1, 8); // 0 te1
m128i_to_i64(total_error_3, total_err3);
m128i_to_i64(total_error_1, total_err1);
/* prefer higher order */
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);
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);
return order;
}
#endif /* FLAC__SSSE3_SUPPORTED */
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
#endif /* FLAC__NO_ASM */
#endif /* FLAC__INTEGER_ONLY_LIBRARY */

@ -0,0 +1,302 @@
/* 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 "FLAC/assert.h"
#include "share/compat.h"
#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 */

@ -0,0 +1,585 @@
/* 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 "FLAC/assert.h"
#include "FLAC/format.h"
#include "share/compat.h"
#include "private/format.h"
#include "private/macros.h"
/* VERSION should come from configure */
FLAC_API const char *FLAC__VERSION_STRING = "1.3.1";
FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.3.1 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 = realloc(object->parameters, sizeof(unsigned)*(1 << max_partition_order))))
return false;
if(0 == (object->raw_bits = 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;
}

@ -0,0 +1,98 @@
; vim:filetype=nasm ts=8
; 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.
%include "nasm.h"
data_section
cglobal FLAC__cpu_have_cpuid_asm_ia32
cglobal FLAC__cpu_info_asm_ia32
code_section
; **********************************************************************
;
; FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32()
;
cident FLAC__cpu_have_cpuid_asm_ia32
pushfd
pop eax
mov edx, eax
xor eax, 0x00200000
push eax
popfd
pushfd
pop eax
xor eax, edx
and eax, 0x00200000
shr eax, 0x15
push edx
popfd
ret
; **********************************************************************
;
; void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx)
;
cident FLAC__cpu_info_asm_ia32
;[esp + 8] == flags_edx
;[esp + 12] == flags_ecx
push ebx
call FLAC__cpu_have_cpuid_asm_ia32
test eax, eax
jz .no_cpuid
mov eax, 0
cpuid
cmp eax, 1
jb .no_cpuid
mov eax, 1
cpuid
mov ebx, [esp + 8]
mov [ebx], edx
mov ebx, [esp + 12]
mov [ebx], ecx
jmp .end
.no_cpuid:
xor eax, eax
mov ebx, [esp + 8]
mov [ebx], eax
mov ebx, [esp + 12]
mov [ebx], eax
.end:
pop ebx
ret
; end

@ -0,0 +1,309 @@
; vim:filetype=nasm ts=8
; 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.
%include "nasm.h"
data_section
cglobal FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov
code_section
; **********************************************************************
;
; unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 *data, unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
; {
; 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 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4))
; order = 0;
; else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4))
; order = 1;
; else if(total_error_2 < min(total_error_3, total_error_4))
; order = 2;
; else if(total_error_3 < total_error_4)
; order = 3;
; else
; order = 4;
;
; residual_bits_per_sample[0] = (FLAC__float)((data_len > 0 && 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)((data_len > 0 && 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)((data_len > 0 && 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)((data_len > 0 && 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)((data_len > 0 && total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
;
; return order;
; }
ALIGN 16
cident FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov
; esp + 36 == data[]
; esp + 40 == data_len
; esp + 44 == residual_bits_per_sample[]
push ebp
push ebx
push esi
push edi
sub esp, byte 16
; qword [esp] == temp space for loading FLAC__uint64s to FPU regs
; ebx == &data[i]
; ecx == loop counter (i)
; ebp == order
; mm0 == total_error_1:total_error_0
; mm1 == total_error_2:total_error_3
; mm2 == :total_error_4
; mm3 == last_error_1:last_error_0
; mm4 == last_error_2:last_error_3
mov ecx, [esp + 40] ; ecx = data_len
test ecx, ecx
jz near .data_len_is_0
mov ebx, [esp + 36] ; ebx = data[]
movd mm3, [ebx - 4] ; mm3 = 0:last_error_0
movd mm2, [ebx - 8] ; mm2 = 0:data[-2]
movd mm1, [ebx - 12] ; mm1 = 0:data[-3]
movd mm0, [ebx - 16] ; mm0 = 0:data[-4]
movq mm5, mm3 ; mm5 = 0:last_error_0
psubd mm5, mm2 ; mm5 = 0:last_error_1
punpckldq mm3, mm5 ; mm3 = last_error_1:last_error_0
psubd mm2, mm1 ; mm2 = 0:data[-2] - data[-3]
psubd mm5, mm2 ; mm5 = 0:last_error_2
movq mm4, mm5 ; mm4 = 0:last_error_2
psubd mm4, mm2 ; mm4 = 0:last_error_2 - (data[-2] - data[-3])
paddd mm4, mm1 ; mm4 = 0:last_error_2 - (data[-2] - 2 * data[-3])
psubd mm4, mm0 ; mm4 = 0:last_error_3
punpckldq mm4, mm5 ; mm4 = last_error_2:last_error_3
pxor mm0, mm0 ; mm0 = total_error_1:total_error_0
pxor mm1, mm1 ; mm1 = total_error_2:total_error_3
pxor mm2, mm2 ; mm2 = 0:total_error_4
ALIGN 16
.loop:
movd mm7, [ebx] ; mm7 = 0:error_0
add ebx, byte 4
movq mm6, mm7 ; mm6 = 0:error_0
psubd mm7, mm3 ; mm7 = :error_1
punpckldq mm6, mm7 ; mm6 = error_1:error_0
movq mm5, mm6 ; mm5 = error_1:error_0
movq mm7, mm6 ; mm7 = error_1:error_0
psubd mm5, mm3 ; mm5 = error_2:
movq mm3, mm6 ; mm3 = error_1:error_0
psrad mm6, 31
pxor mm7, mm6
psubd mm7, mm6 ; mm7 = abs(error_1):abs(error_0)
paddd mm0, mm7 ; mm0 = total_error_1:total_error_0
movq mm6, mm5 ; mm6 = error_2:
psubd mm5, mm4 ; mm5 = error_3:
punpckhdq mm5, mm6 ; mm5 = error_2:error_3
movq mm7, mm5 ; mm7 = error_2:error_3
movq mm6, mm5 ; mm6 = error_2:error_3
psubd mm5, mm4 ; mm5 = :error_4
movq mm4, mm6 ; mm4 = error_2:error_3
psrad mm6, 31
pxor mm7, mm6
psubd mm7, mm6 ; mm7 = abs(error_2):abs(error_3)
paddd mm1, mm7 ; mm1 = total_error_2:total_error_3
movq mm6, mm5 ; mm6 = :error_4
psrad mm5, 31
pxor mm6, mm5
psubd mm6, mm5 ; mm6 = :abs(error_4)
paddd mm2, mm6 ; mm2 = :total_error_4
dec ecx
jnz short .loop
; if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4))
; order = 0;
; else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4))
; order = 1;
; else if(total_error_2 < min(total_error_3, total_error_4))
; order = 2;
; else if(total_error_3 < total_error_4)
; order = 3;
; else
; order = 4;
movq mm3, mm0 ; mm3 = total_error_1:total_error_0
movd edi, mm2 ; edi = total_error_4
movd esi, mm1 ; esi = total_error_3
movd eax, mm0 ; eax = total_error_0
punpckhdq mm1, mm1 ; mm1 = total_error_2:total_error_2
punpckhdq mm3, mm3 ; mm3 = total_error_1:total_error_1
movd edx, mm1 ; edx = total_error_2
movd ecx, mm3 ; ecx = total_error_1
xor ebx, ebx
xor ebp, ebp
inc ebx
cmp ecx, eax
cmovb eax, ecx ; eax = min(total_error_0, total_error_1)
cmovbe ebp, ebx
inc ebx
cmp edx, eax
cmovb eax, edx ; eax = min(total_error_0, total_error_1, total_error_2)
cmovbe ebp, ebx
inc ebx
cmp esi, eax
cmovb eax, esi ; eax = min(total_error_0, total_error_1, total_error_2, total_error_3)
cmovbe ebp, ebx
inc ebx
cmp edi, eax
cmovb eax, edi ; eax = min(total_error_0, total_error_1, total_error_2, total_error_3, total_error_4)
cmovbe ebp, ebx
movd ebx, mm0 ; ebx = total_error_0
emms
; residual_bits_per_sample[0] = (FLAC__float)((data_len > 0 && 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)((data_len > 0 && 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)((data_len > 0 && 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)((data_len > 0 && 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)((data_len > 0 && total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
xor eax, eax
fild dword [esp + 40] ; ST = data_len (NOTE: assumes data_len is <2gigs)
.rbps_0:
test ebx, ebx
jz .total_error_0_is_0
fld1 ; ST = 1.0 data_len
mov [esp], ebx
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_0
mov ebx, [esp + 44]
fild qword [esp] ; ST = total_error_0 1.0 data_len
fdiv st2 ; ST = total_error_0/data_len 1.0 data_len
fldln2 ; ST = ln2 total_error_0/data_len 1.0 data_len
fmulp st1 ; ST = ln2*total_error_0/data_len 1.0 data_len
fyl2x ; ST = log2(ln2*total_error_0/data_len) data_len
fstp dword [ebx] ; residual_bits_per_sample[0] = log2(ln2*total_error_0/data_len) ST = data_len
jmp short .rbps_1
.total_error_0_is_0:
mov ebx, [esp + 44]
mov [ebx], eax ; residual_bits_per_sample[0] = 0.0
.rbps_1:
test ecx, ecx
jz .total_error_1_is_0
fld1 ; ST = 1.0 data_len
mov [esp], ecx
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_1
fild qword [esp] ; ST = total_error_1 1.0 data_len
fdiv st2 ; ST = total_error_1/data_len 1.0 data_len
fldln2 ; ST = ln2 total_error_1/data_len 1.0 data_len
fmulp st1 ; ST = ln2*total_error_1/data_len 1.0 data_len
fyl2x ; ST = log2(ln2*total_error_1/data_len) data_len
fstp dword [ebx + 4] ; residual_bits_per_sample[1] = log2(ln2*total_error_1/data_len) ST = data_len
jmp short .rbps_2
.total_error_1_is_0:
mov [ebx + 4], eax ; residual_bits_per_sample[1] = 0.0
.rbps_2:
test edx, edx
jz .total_error_2_is_0
fld1 ; ST = 1.0 data_len
mov [esp], edx
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_2
fild qword [esp] ; ST = total_error_2 1.0 data_len
fdiv st2 ; ST = total_error_2/data_len 1.0 data_len
fldln2 ; ST = ln2 total_error_2/data_len 1.0 data_len
fmulp st1 ; ST = ln2*total_error_2/data_len 1.0 data_len
fyl2x ; ST = log2(ln2*total_error_2/data_len) data_len
fstp dword [ebx + 8] ; residual_bits_per_sample[2] = log2(ln2*total_error_2/data_len) ST = data_len
jmp short .rbps_3
.total_error_2_is_0:
mov [ebx + 8], eax ; residual_bits_per_sample[2] = 0.0
.rbps_3:
test esi, esi
jz .total_error_3_is_0
fld1 ; ST = 1.0 data_len
mov [esp], esi
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_3
fild qword [esp] ; ST = total_error_3 1.0 data_len
fdiv st2 ; ST = total_error_3/data_len 1.0 data_len
fldln2 ; ST = ln2 total_error_3/data_len 1.0 data_len
fmulp st1 ; ST = ln2*total_error_3/data_len 1.0 data_len
fyl2x ; ST = log2(ln2*total_error_3/data_len) data_len
fstp dword [ebx + 12] ; residual_bits_per_sample[3] = log2(ln2*total_error_3/data_len) ST = data_len
jmp short .rbps_4
.total_error_3_is_0:
mov [ebx + 12], eax ; residual_bits_per_sample[3] = 0.0
.rbps_4:
test edi, edi
jz .total_error_4_is_0
fld1 ; ST = 1.0 data_len
mov [esp], edi
mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_4
fild qword [esp] ; ST = total_error_4 1.0 data_len
fdiv st2 ; ST = total_error_4/data_len 1.0 data_len
fldln2 ; ST = ln2 total_error_4/data_len 1.0 data_len
fmulp st1 ; ST = ln2*total_error_4/data_len 1.0 data_len
fyl2x ; ST = log2(ln2*total_error_4/data_len) data_len
fstp dword [ebx + 16] ; residual_bits_per_sample[4] = log2(ln2*total_error_4/data_len) ST = data_len
jmp short .rbps_end
.total_error_4_is_0:
mov [ebx + 16], eax ; residual_bits_per_sample[4] = 0.0
.rbps_end:
fstp st0 ; ST = [empty]
jmp short .end
.data_len_is_0:
; data_len == 0, so residual_bits_per_sample[*] = 0.0
xor ebp, ebp
mov edi, [esp + 44]
mov [edi], ebp
mov [edi + 4], ebp
mov [edi + 8], ebp
mov [edi + 12], ebp
mov [edi + 16], ebp
add ebp, byte 4 ; order = 4
.end:
mov eax, ebp ; return order
add esp, byte 16
pop edi
pop esi
pop ebx
pop ebp
ret
; end

File diff suppressed because it is too large Load Diff

@ -0,0 +1,85 @@
; 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.
bits 32
%ifdef OBJ_FORMAT_win32
%define FLAC__PUBLIC_NEEDS_UNDERSCORE
%idefine code_section section .text align=16 class=CODE use32
%idefine data_section section .data align=32 class=DATA use32
%idefine bss_section section .bss align=32 class=DATA use32
%elifdef OBJ_FORMAT_aout
%define FLAC__PUBLIC_NEEDS_UNDERSCORE
%idefine code_section section .text
%idefine data_section section .data
%idefine bss_section section .bss
%elifdef OBJ_FORMAT_aoutb
%define FLAC__PUBLIC_NEEDS_UNDERSCORE
%idefine code_section section .text
%idefine data_section section .data
%idefine bss_section section .bss
%elifdef OBJ_FORMAT_elf
%idefine code_section section .text align=16
%idefine data_section section .data align=32
%idefine bss_section section .bss align=32
%else
%error unsupported object format!
%endif
%imacro cglobal 1
%ifdef FLAC__PUBLIC_NEEDS_UNDERSCORE
global _%1
%else
%if __NASM_MAJOR__ >= 2
global %1:function hidden
%else
global %1
%endif
%endif
%endmacro
%imacro cextern 1
%ifdef FLAC__PUBLIC_NEEDS_UNDERSCORE
extern _%1
%else
extern %1
%endif
%endmacro
%imacro cident 1
_%1:
%1:
%endmacro
%ifdef OBJ_FORMAT_elf
section .note.GNU-stack progbits noalloc noexec nowrite align=1
%endif

@ -0,0 +1,50 @@
/* 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

@ -0,0 +1,186 @@
/* 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 "FLAC/ordinals.h"
#include "FLAC/assert.h"
/* for CHAR_BIT */
#include <limits.h>
#include "share/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

@ -0,0 +1,91 @@
/* 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 "FLAC/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

@ -0,0 +1,104 @@
/* 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 "FLAC/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

@ -0,0 +1,168 @@
/* 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 "FLAC/ordinals.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if defined FLAC__HAS_X86INTRIN
/* SSE intrinsics support by ICC/MSVC/GCC */
#if defined __INTEL_COMPILER
#define FLAC__SSE_TARGET(x)
#define FLAC__SSE_SUPPORTED 1
#define FLAC__SSE2_SUPPORTED 1
#if (__INTEL_COMPILER >= 1000) /* Intel C++ Compiler 10.0 */
#define FLAC__SSSE3_SUPPORTED 1
#define FLAC__SSE4_1_SUPPORTED 1
#endif
#if (__INTEL_COMPILER >= 1110) /* Intel C++ Compiler 11.1 */
#define FLAC__AVX_SUPPORTED 1
#endif
#if (__INTEL_COMPILER >= 1300) /* Intel C++ Compiler 13.0 */
#define FLAC__AVX2_SUPPORTED 1
#define FLAC__FMA_SUPPORTED 1
#endif
#elif defined _MSC_VER
#define FLAC__SSE_TARGET(x)
#define FLAC__SSE_SUPPORTED 1
#define FLAC__SSE2_SUPPORTED 1
#if (_MSC_VER >= 1500) /* MS Visual Studio 2008 */
#define FLAC__SSSE3_SUPPORTED 1
#define FLAC__SSE4_1_SUPPORTED 1
#endif
#if (_MSC_FULL_VER >= 160040219) /* MS Visual Studio 2010 SP1 */
#define FLAC__AVX_SUPPORTED 1
#endif
#if (_MSC_VER >= 1700) /* MS Visual Studio 2012 */
#define FLAC__AVX2_SUPPORTED 1
#define FLAC__FMA_SUPPORTED 1
#endif
#elif defined __GNUC__
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) /* since GCC 4.9 -msse.. compiler options aren't necessary */
#define FLAC__SSE_TARGET(x) __attribute__ ((__target__ (x)))
#define FLAC__SSE_SUPPORTED 1
#define FLAC__SSE2_SUPPORTED 1
#define FLAC__SSSE3_SUPPORTED 1
#define FLAC__SSE4_1_SUPPORTED 1
#define FLAC__AVX_SUPPORTED 1
#define FLAC__AVX2_SUPPORTED 1
#define FLAC__FMA_SUPPORTED 1
#else /* for GCC older than 4.9 */
#define FLAC__SSE_TARGET(x)
#ifdef __SSE__
#define FLAC__SSE_SUPPORTED 1
#endif
#ifdef __SSE2__
#define FLAC__SSE2_SUPPORTED 1
#endif
#ifdef __SSSE3__
#define FLAC__SSSE3_SUPPORTED 1
#endif
#ifdef __SSE4_1__
#define FLAC__SSE4_1_SUPPORTED 1
#endif
#ifdef __AVX__
#define FLAC__AVX_SUPPORTED 1
#endif
#ifdef __AVX2__
#define FLAC__AVX2_SUPPORTED 1
#endif
#ifdef __FMA__
#define FLAC__FMA_SUPPORTED 1
#endif
#endif /* GCC version */
#endif /* compiler version */
#endif /* intrinsics support */
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

@ -0,0 +1,62 @@
/* 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 "FLAC/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

@ -0,0 +1,107 @@
/* 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 "private/cpu.h"
#include "private/float.h"
#include "FLAC/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

@ -0,0 +1,98 @@
/* 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 "FLAC/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

@ -0,0 +1,45 @@
/* 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 "FLAC/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

@ -0,0 +1,246 @@
/* 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 "private/cpu.h"
#include "private/float.h"
#include "FLAC/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

@ -0,0 +1,72 @@
/* 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.
*/
#ifndef FLAC__PRIVATE__MACROS_H
#define FLAC__PRIVATE__MACROS_H
#if defined(__GNUC__) && (__GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 3))
#define flac_max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
#define MIN_PASTE(A,B) A##B
#define MIN_IMPL(A,B,L) ({ \
__typeof__(A) MIN_PASTE(__a,L) = (A); \
__typeof__(B) MIN_PASTE(__b,L) = (B); \
MIN_PASTE(__a,L) < MIN_PASTE(__b,L) ? MIN_PASTE(__a,L) : MIN_PASTE(__b,L); \
})
#define flac_min(A,B) MIN_IMPL(A,B,__COUNTER__)
/* Whatever other unix that has sys/param.h */
#elif defined(HAVE_SYS_PARAM_H)
#include <sys/param.h>
#define flac_max(a,b) MAX(a,b)
#define flac_min(a,b) MIN(a,b)
/* Windows VS has them in stdlib.h.. XXX:Untested */
#elif defined(_MSC_VER)
#include <stdlib.h>
#define flac_max(a,b) __max(a,b)
#define flac_min(a,b) __min(a,b)
#endif
#ifndef MIN
#define MIN(x,y) ((x) <= (y) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x,y) ((x) >= (y) ? (x) : (y))
#endif
#endif

@ -0,0 +1,50 @@
#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 "FLAC/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

@ -0,0 +1,58 @@
/* 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 "private/float.h"
#include "FLAC/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

@ -0,0 +1,46 @@
/* 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 "FLAC/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

@ -0,0 +1,80 @@
/* libFLAC - Free Lossless Audio Codec
* 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__OGG_DECODER_ASPECT_H
#define FLAC__PRIVATE__OGG_DECODER_ASPECT_H
#include <ogg/ogg.h>
#include "FLAC/ordinals.h"
#include "FLAC/stream_decoder.h" /* for FLAC__StreamDecoderReadStatus */
typedef struct FLAC__OggDecoderAspect {
/* these are storage for values that can be set through the API */
FLAC__bool use_first_serial_number;
long serial_number;
/* these are for internal state related to Ogg decoding */
ogg_stream_state stream_state;
ogg_sync_state sync_state;
unsigned version_major, version_minor;
FLAC__bool need_serial_number;
FLAC__bool end_of_stream;
FLAC__bool have_working_page; /* only if true will the following vars be valid */
ogg_page working_page;
FLAC__bool have_working_packet; /* only if true will the following vars be valid */
ogg_packet working_packet; /* as we work through the packet we will move working_packet.packet forward and working_packet.bytes down */
} FLAC__OggDecoderAspect;
void FLAC__ogg_decoder_aspect_set_serial_number(FLAC__OggDecoderAspect *aspect, long value);
void FLAC__ogg_decoder_aspect_set_defaults(FLAC__OggDecoderAspect *aspect);
FLAC__bool FLAC__ogg_decoder_aspect_init(FLAC__OggDecoderAspect *aspect);
void FLAC__ogg_decoder_aspect_finish(FLAC__OggDecoderAspect *aspect);
void FLAC__ogg_decoder_aspect_flush(FLAC__OggDecoderAspect *aspect);
void FLAC__ogg_decoder_aspect_reset(FLAC__OggDecoderAspect *aspect);
typedef enum {
FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK = 0,
FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM,
FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC,
FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC,
FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION,
FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT,
FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR,
FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR
} FLAC__OggDecoderAspectReadStatus;
typedef FLAC__OggDecoderAspectReadStatus (*FLAC__OggDecoderAspectReadCallbackProxy)(const void *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data);
FLAC__OggDecoderAspectReadStatus FLAC__ogg_decoder_aspect_read_callback_wrapper(FLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], size_t *bytes, FLAC__OggDecoderAspectReadCallbackProxy read_callback, const FLAC__StreamDecoder *decoder, void *client_data);
#endif

@ -0,0 +1,63 @@
/* libFLAC - Free Lossless Audio Codec
* 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__OGG_ENCODER_ASPECT_H
#define FLAC__PRIVATE__OGG_ENCODER_ASPECT_H
#include <ogg/ogg.h>
#include "FLAC/ordinals.h"
#include "FLAC/stream_encoder.h" /* for FLAC__StreamEncoderWriteStatus */
typedef struct FLAC__OggEncoderAspect {
/* these are storage for values that can be set through the API */
long serial_number;
unsigned num_metadata;
/* these are for internal state related to Ogg encoding */
ogg_stream_state stream_state;
ogg_page page;
FLAC__bool seen_magic; /* true if we've seen the fLaC magic in the write callback yet */
FLAC__bool is_first_packet;
FLAC__uint64 samples_written;
} FLAC__OggEncoderAspect;
void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value);
FLAC__bool FLAC__ogg_encoder_aspect_set_num_metadata(FLAC__OggEncoderAspect *aspect, unsigned value);
void FLAC__ogg_encoder_aspect_set_defaults(FLAC__OggEncoderAspect *aspect);
FLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect);
void FLAC__ogg_encoder_aspect_finish(FLAC__OggEncoderAspect *aspect);
typedef FLAC__StreamEncoderWriteStatus (*FLAC__OggEncoderAspectWriteCallbackProxy)(const void *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data);
FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(FLAC__OggEncoderAspect *aspect, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, FLAC__bool is_last_block, FLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data);
#endif

@ -0,0 +1,44 @@
/* libFLAC - Free Lossless Audio Codec
* 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__OGG_HELPER_H
#define FLAC__PRIVATE__OGG_HELPER_H
#include <ogg/ogg.h>
#include "FLAC/stream_encoder.h" /* for FLAC__StreamEncoder */
void simple_ogg_page__init(ogg_page *page);
void simple_ogg_page__clear(ogg_page *page);
FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderReadCallback read_callback, void *client_data);
FLAC__bool simple_ogg_page__set_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data);
#endif

@ -0,0 +1,64 @@
/* libFLAC - Free Lossless Audio Codec
* 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__OGG_MAPPING_H
#define FLAC__PRIVATE__OGG_MAPPING_H
#include "FLAC/ordinals.h"
/** The length of the packet type field in bytes. */
#define FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH (1u)
extern const unsigned FLAC__OGG_MAPPING_PACKET_TYPE_LEN; /* = 8 bits */
extern const FLAC__byte FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE; /* = 0x7f */
/** The length of the 'FLAC' magic in bytes. */
#define FLAC__OGG_MAPPING_MAGIC_LENGTH (4u)
extern const FLAC__byte * const FLAC__OGG_MAPPING_MAGIC; /* = "FLAC" */
extern const unsigned FLAC__OGG_MAPPING_VERSION_MAJOR_LEN; /* = 8 bits */
extern const unsigned FLAC__OGG_MAPPING_VERSION_MINOR_LEN; /* = 8 bits */
/** The length of the Ogg FLAC mapping major version number in bytes. */
#define FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH (1u)
/** The length of the Ogg FLAC mapping minor version number in bytes. */
#define FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH (1u)
extern const unsigned FLAC__OGG_MAPPING_NUM_HEADERS_LEN; /* = 16 bits */
/** The length of the #-of-header-packets number bytes. */
#define FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH (2u)
#endif

@ -0,0 +1,67 @@
/* 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 "private/cpu.h"
#include "FLAC/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

@ -0,0 +1,46 @@
/* 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 "FLAC/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

@ -0,0 +1,74 @@
/* 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 "private/float.h"
#include "FLAC/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

@ -0,0 +1,39 @@
/* 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

@ -0,0 +1,60 @@
/* 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 "FLAC/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

@ -0,0 +1,118 @@
/* 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 "FLAC/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

@ -0,0 +1,209 @@
/* 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
*/
#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 "share/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

@ -0,0 +1,201 @@
/* 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 _WIN32 && !defined __CYGWIN__
/* where MSVC puts unlink() */
# include <io.h>
#else
# include <unistd.h>
#endif
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
#include <sys/types.h> /* for off_t */
#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 HAVE_INTTYPES_H
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#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 || 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
/* Visual Studio 2010 has decent C99 support */
# include <stdint.h>
# define PRIu64 "llu"
# define PRId64 "lld"
# define PRIx64 "llx"
# else
# include <limits.h>
# 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 "share/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.
*/
#include <stdarg.h>
#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 */

@ -0,0 +1,78 @@
/* 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 */
#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

@ -0,0 +1,184 @@
/*
NOTE:
I cannot get the vanilla getopt code to work (i.e. compile only what
is needed and not duplicate symbols found in the standard library)
on all the platforms that FLAC supports. In particular the gating
of code with the ELIDE_CODE #define is not accurate enough on systems
that are POSIX but not glibc. If someone has a patch that works on
GNU/Linux, Darwin, AND Solaris please submit it on the project page:
https://sourceforge.net/p/flac/patches/
In the meantime I have munged the global symbols and removed gates
around code, while at the same time trying to touch the original as
little as possible.
*/
/* Declarations for getopt.
Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#ifndef SHARE__GETOPT_H
#define SHARE__GETOPT_H
/*[JEC] was:#ifndef __need_getopt*/
/*[JEC] was:# define _GETOPT_H 1*/
/*[JEC] was:#endif*/
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `share__getopt' to the caller.
When `share__getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *share__optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `share__getopt'.
On entry to `share__getopt', zero means this is the first call; initialize.
When `share__getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `share__optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int share__optind;
/* Callers store zero here to inhibit the error message `share__getopt' prints
for unrecognized options. */
extern int share__opterr;
/* Set to an option character which was unrecognized. */
extern int share__optopt;
/*[JEC] was:#ifndef __need_getopt */
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to share__getopt_long or share__getopt_long_only is a vector
of `struct share__option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
share__no_argument (or 0) if the option does not take an argument,
share__required_argument (or 1) if the option requires an argument,
share__optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `share__optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `share__getopt'
returns the contents of the `val' field. */
struct share__option
{
# if defined __STDC__ && __STDC__
const char *name;
# else
char *name;
# endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct share__option'. */
# define share__no_argument 0
# define share__required_argument 1
# define share__optional_argument 2
/*[JEC] was:#endif*/ /* need getopt */
/* Get definitions and prototypes for functions to process the
arguments in ARGV (ARGC of them, minus the program name) for
options given in OPTS.
Return the option character from OPTS just read. Return -1 when
there are no more options. For unrecognized options, or options
missing arguments, `share__optopt' is set to the option letter, and '?' is
returned.
The OPTS string is a list of characters which are recognized option
letters, optionally followed by colons, specifying that that letter
takes an argument, to be placed in `share__optarg'.
If a letter in OPTS is followed by two colons, its argument is
optional. This behavior is specific to the GNU `share__getopt'.
The argument `--' causes premature termination of argument
scanning, explicitly telling `share__getopt' that there are no more
options.
If OPTS begins with `--', then non-option arguments are treated as
arguments to the option '\0'. This behavior is specific to the GNU
`share__getopt'. */
/*[JEC] was:#if defined __STDC__ && __STDC__*/
/*[JEC] was:# ifdef __GNU_LIBRARY__*/
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int share__getopt (int argc, char *const *argv, const char *shortopts);
/*[JEC] was:# else*/ /* not __GNU_LIBRARY__ */
/*[JEC] was:extern int getopt ();*/
/*[JEC] was:# endif*/ /* __GNU_LIBRARY__ */
/*[JEC] was:# ifndef __need_getopt*/
extern int share__getopt_long (int argc, char *const *argv, const char *shortopts,
const struct share__option *longopts, int *longind);
extern int share__getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct share__option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int share___getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct share__option *longopts, int *longind,
int long_only);
/*[JEC] was:# endif*/
/*[JEC] was:#else*/ /* not __STDC__ */
/*[JEC] was:extern int getopt ();*/
/*[JEC] was:# ifndef __need_getopt*/
/*[JEC] was:extern int getopt_long ();*/
/*[JEC] was:extern int getopt_long_only ();*/
/*[JEC] was:extern int _getopt_internal ();*/
/*[JEC] was:# endif*/
/*[JEC] was:#endif*/ /* __STDC__ */
#ifdef __cplusplus
}
#endif
/* Make sure we later can get all the definitions and declarations. */
/*[JEC] was:#undef __need_getopt*/
#endif /* getopt.h */

@ -0,0 +1,41 @@
/* 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.
*/
#include <errno.h>
/* FLAC_CHECK_RETURN : Check the return value of of the provided function and
* print and error message if it fails (ie returns a value < 0).
*/
#define FLAC_CHECK_RETURN(x) \
{ if ((x) < 0) \
printf ("%s : %s\n", #x, strerror (errno)) ; \
}

@ -0,0 +1,45 @@
/* 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.
*/
#ifndef FLAC__SHARE__PRIVATE_H
#define FLAC__SHARE__PRIVATE_H
/*
* Unpublished debug routines from libFLAC> This should not be used from any
* client code other than code shipped with the FLAC sources.
*/
FLAC_API FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
FLAC_API FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
FLAC_API FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
FLAC_API FLAC__bool FLAC__stream_encoder_set_do_md5(FLAC__StreamEncoder *encoder, FLAC__bool value);
FLAC_API FLAC__bool FLAC__stream_encoder_get_do_md5(const FLAC__StreamEncoder *encoder);
#endif /* FLAC__SHARE__PRIVATE_H */

@ -0,0 +1,69 @@
/* 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.
*/
/* Safe string handling functions to replace things like strcpy, strncpy,
* strcat, strncat etc.
* All of these functions guarantee a correctly NUL terminated string but
* the string may be truncated if the destination buffer was too short.
*/
#ifndef FLAC__SHARE_SAFE_STR_H
#define FLAC__SHARE_SAFE_STR_H
static inline char *
safe_strncat(char *dest, const char *src, size_t dest_size)
{
char * ret;
if (dest_size < 1)
return dest;
ret = strncat(dest, src, dest_size - strlen (dest));
dest [dest_size - 1] = 0;
return ret;
}
static inline char *
safe_strncpy(char *dest, const char *src, size_t dest_size)
{
char * ret;
if (dest_size < 1)
return dest;
ret = strncpy(dest, src, dest_size);
dest [dest_size - 1] = 0;
return ret;
}
#endif /* FLAC__SHARE_SAFE_STR_H */

@ -0,0 +1,25 @@
#ifndef SHARE__UTF8_H
#define SHARE__UTF8_H
/*
* Convert a string between UTF-8 and the locale's charset.
* Invalid bytes are replaced by '#', and characters that are
* not available in the target encoding are replaced by '?'.
*
* If the locale's charset is not set explicitly then it is
* obtained using nl_langinfo(CODESET), where available, the
* environment variable CHARSET, or assumed to be US-ASCII.
*
* Return value of conversion functions:
*
* -1 : memory allocation failed
* 0 : data was converted exactly
* 1 : valid data was converted approximately (using '?')
* 2 : input was invalid (but still converted, using '#')
* 3 : unknown encoding (but still converted, using '?')
*/
int utf8_encode(const char *from, char **to);
int utf8_decode(const char *from, char **to);
#endif

@ -0,0 +1,69 @@
/* 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
#include <stdio.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <windows.h>
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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,451 @@
/* 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
#ifndef FLAC__INTEGER_ONLY_LIBRARY
#ifndef FLAC__NO_ASM
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#include "private/lpc.h"
#ifdef FLAC__SSE_SUPPORTED
#include "FLAC/assert.h"
#include "FLAC/format.h"
#include <xmmintrin.h> /* SSE */
#if 1
/* Faster on current Intel (starting from Core i aka Nehalem) and all AMD CPUs */
FLAC__SSE_TARGET("sse")
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
{
int i;
int limit = data_len - 4;
__m128 sum0;
(void) lag;
FLAC__ASSERT(lag <= 4);
FLAC__ASSERT(lag <= data_len);
sum0 = _mm_setzero_ps();
for(i = 0; i <= limit; i++) {
__m128 d, d0;
d0 = _mm_loadu_ps(data+i);
d = d0; d = _mm_shuffle_ps(d, d, 0);
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
}
{
__m128 d0 = _mm_setzero_ps();
limit++; if(limit < 0) limit = 0;
for(i = data_len-1; i >= limit; i--) {
__m128 d;
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
d0 = _mm_move_ss(d0, d);
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
}
}
_mm_storeu_ps(autoc, sum0);
}
FLAC__SSE_TARGET("sse")
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
{
int i;
int limit = data_len - 8;
__m128 sum0, sum1;
(void) lag;
FLAC__ASSERT(lag <= 8);
FLAC__ASSERT(lag <= data_len);
sum0 = _mm_setzero_ps();
sum1 = _mm_setzero_ps();
for(i = 0; i <= limit; i++) {
__m128 d, d0, d1;
d0 = _mm_loadu_ps(data+i);
d1 = _mm_loadu_ps(data+i+4);
d = d0; d = _mm_shuffle_ps(d, d, 0);
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d));
}
{
__m128 d0 = _mm_setzero_ps();
__m128 d1 = _mm_setzero_ps();
limit++; if(limit < 0) limit = 0;
for(i = data_len-1; i >= limit; i--) {
__m128 d;
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3));
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
d1 = _mm_move_ss(d1, d0);
d0 = _mm_move_ss(d0, d);
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1));
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
}
}
_mm_storeu_ps(autoc, sum0);
_mm_storeu_ps(autoc+4, sum1);
}
FLAC__SSE_TARGET("sse")
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
{
int i;
int limit = data_len - 12;
__m128 sum0, sum1, sum2;
(void) lag;
FLAC__ASSERT(lag <= 12);
FLAC__ASSERT(lag <= data_len);
sum0 = _mm_setzero_ps();
sum1 = _mm_setzero_ps();
sum2 = _mm_setzero_ps();
for(i = 0; i <= limit; i++) {
__m128 d, d0, d1, d2;
d0 = _mm_loadu_ps(data+i);
d1 = _mm_loadu_ps(data+i+4);
d2 = _mm_loadu_ps(data+i+8);
d = d0; d = _mm_shuffle_ps(d, d, 0);
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d));
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d));
}
{
__m128 d0 = _mm_setzero_ps();
__m128 d1 = _mm_setzero_ps();
__m128 d2 = _mm_setzero_ps();
limit++; if(limit < 0) limit = 0;
for(i = data_len-1; i >= limit; i--) {
__m128 d;
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3));
d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3));
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
d2 = _mm_move_ss(d2, d1);
d1 = _mm_move_ss(d1, d0);
d0 = _mm_move_ss(d0, d);
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2));
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1));
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
}
}
_mm_storeu_ps(autoc, sum0);
_mm_storeu_ps(autoc+4, sum1);
_mm_storeu_ps(autoc+8, sum2);
}
FLAC__SSE_TARGET("sse")
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
{
int i;
int limit = data_len - 16;
__m128 sum0, sum1, sum2, sum3;
(void) lag;
FLAC__ASSERT(lag <= 16);
FLAC__ASSERT(lag <= data_len);
sum0 = _mm_setzero_ps();
sum1 = _mm_setzero_ps();
sum2 = _mm_setzero_ps();
sum3 = _mm_setzero_ps();
for(i = 0; i <= limit; i++) {
__m128 d, d0, d1, d2, d3;
d0 = _mm_loadu_ps(data+i);
d1 = _mm_loadu_ps(data+i+4);
d2 = _mm_loadu_ps(data+i+8);
d3 = _mm_loadu_ps(data+i+12);
d = d0; d = _mm_shuffle_ps(d, d, 0);
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d0, d));
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d1, d));
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d2, d));
sum3 = _mm_add_ps(sum3, _mm_mul_ps(d3, d));
}
{
__m128 d0 = _mm_setzero_ps();
__m128 d1 = _mm_setzero_ps();
__m128 d2 = _mm_setzero_ps();
__m128 d3 = _mm_setzero_ps();
limit++; if(limit < 0) limit = 0;
for(i = data_len-1; i >= limit; i--) {
__m128 d;
d = _mm_load_ss(data+i); d = _mm_shuffle_ps(d, d, 0);
d3 = _mm_shuffle_ps(d3, d3, _MM_SHUFFLE(2,1,0,3));
d2 = _mm_shuffle_ps(d2, d2, _MM_SHUFFLE(2,1,0,3));
d1 = _mm_shuffle_ps(d1, d1, _MM_SHUFFLE(2,1,0,3));
d0 = _mm_shuffle_ps(d0, d0, _MM_SHUFFLE(2,1,0,3));
d3 = _mm_move_ss(d3, d2);
d2 = _mm_move_ss(d2, d1);
d1 = _mm_move_ss(d1, d0);
d0 = _mm_move_ss(d0, d);
sum3 = _mm_add_ps(sum3, _mm_mul_ps(d, d3));
sum2 = _mm_add_ps(sum2, _mm_mul_ps(d, d2));
sum1 = _mm_add_ps(sum1, _mm_mul_ps(d, d1));
sum0 = _mm_add_ps(sum0, _mm_mul_ps(d, d0));
}
}
_mm_storeu_ps(autoc, sum0);
_mm_storeu_ps(autoc+4, sum1);
_mm_storeu_ps(autoc+8, sum2);
_mm_storeu_ps(autoc+12,sum3);
}
#else
/* Faster on older Intel CPUs (up to Core 2) */
FLAC__SSE_TARGET("sse")
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
{
__m128 xmm0, xmm2, xmm5;
(void) lag;
FLAC__ASSERT(lag > 0);
FLAC__ASSERT(lag <= 4);
FLAC__ASSERT(lag <= data_len);
FLAC__ASSERT(data_len > 0);
xmm5 = _mm_setzero_ps();
xmm0 = _mm_load_ss(data++);
xmm2 = xmm0;
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
xmm0 = _mm_mul_ps(xmm0, xmm2);
xmm5 = _mm_add_ps(xmm5, xmm0);
data_len--;
while(data_len)
{
xmm0 = _mm_load1_ps(data++);
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
xmm2 = _mm_move_ss(xmm2, xmm0);
xmm0 = _mm_mul_ps(xmm0, xmm2);
xmm5 = _mm_add_ps(xmm5, xmm0);
data_len--;
}
_mm_storeu_ps(autoc, xmm5);
}
FLAC__SSE_TARGET("sse")
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
{
__m128 xmm0, xmm1, xmm2, xmm3, xmm5, xmm6;
(void) lag;
FLAC__ASSERT(lag > 0);
FLAC__ASSERT(lag <= 8);
FLAC__ASSERT(lag <= data_len);
FLAC__ASSERT(data_len > 0);
xmm5 = _mm_setzero_ps();
xmm6 = _mm_setzero_ps();
xmm0 = _mm_load_ss(data++);
xmm2 = xmm0;
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
xmm3 = _mm_setzero_ps();
xmm0 = _mm_mul_ps(xmm0, xmm2);
xmm5 = _mm_add_ps(xmm5, xmm0);
data_len--;
while(data_len)
{
xmm0 = _mm_load1_ps(data++);
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3));
xmm3 = _mm_move_ss(xmm3, xmm2);
xmm2 = _mm_move_ss(xmm2, xmm0);
xmm1 = xmm0;
xmm1 = _mm_mul_ps(xmm1, xmm3);
xmm0 = _mm_mul_ps(xmm0, xmm2);
xmm6 = _mm_add_ps(xmm6, xmm1);
xmm5 = _mm_add_ps(xmm5, xmm0);
data_len--;
}
_mm_storeu_ps(autoc, xmm5);
_mm_storeu_ps(autoc+4, xmm6);
}
FLAC__SSE_TARGET("sse")
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
{
__m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
(void) lag;
FLAC__ASSERT(lag > 0);
FLAC__ASSERT(lag <= 12);
FLAC__ASSERT(lag <= data_len);
FLAC__ASSERT(data_len > 0);
xmm5 = _mm_setzero_ps();
xmm6 = _mm_setzero_ps();
xmm7 = _mm_setzero_ps();
xmm0 = _mm_load_ss(data++);
xmm2 = xmm0;
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
xmm3 = _mm_setzero_ps();
xmm4 = _mm_setzero_ps();
xmm0 = _mm_mul_ps(xmm0, xmm2);
xmm5 = _mm_add_ps(xmm5, xmm0);
data_len--;
while(data_len)
{
xmm0 = _mm_load1_ps(data++);
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3));
xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3));
xmm4 = _mm_move_ss(xmm4, xmm3);
xmm3 = _mm_move_ss(xmm3, xmm2);
xmm2 = _mm_move_ss(xmm2, xmm0);
xmm1 = xmm0;
xmm1 = _mm_mul_ps(xmm1, xmm2);
xmm5 = _mm_add_ps(xmm5, xmm1);
xmm1 = xmm0;
xmm1 = _mm_mul_ps(xmm1, xmm3);
xmm6 = _mm_add_ps(xmm6, xmm1);
xmm0 = _mm_mul_ps(xmm0, xmm4);
xmm7 = _mm_add_ps(xmm7, xmm0);
data_len--;
}
_mm_storeu_ps(autoc, xmm5);
_mm_storeu_ps(autoc+4, xmm6);
_mm_storeu_ps(autoc+8, xmm7);
}
FLAC__SSE_TARGET("sse")
void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
{
__m128 xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9;
(void) lag;
FLAC__ASSERT(lag > 0);
FLAC__ASSERT(lag <= 16);
FLAC__ASSERT(lag <= data_len);
FLAC__ASSERT(data_len > 0);
xmm6 = _mm_setzero_ps();
xmm7 = _mm_setzero_ps();
xmm8 = _mm_setzero_ps();
xmm9 = _mm_setzero_ps();
xmm0 = _mm_load_ss(data++);
xmm2 = xmm0;
xmm0 = _mm_shuffle_ps(xmm0, xmm0, 0);
xmm3 = _mm_setzero_ps();
xmm4 = _mm_setzero_ps();
xmm5 = _mm_setzero_ps();
xmm0 = _mm_mul_ps(xmm0, xmm2);
xmm6 = _mm_add_ps(xmm6, xmm0);
data_len--;
while(data_len)
{
xmm0 = _mm_load1_ps(data++);
/* shift xmm5:xmm4:xmm3:xmm2 left by one float */
xmm5 = _mm_shuffle_ps(xmm5, xmm5, _MM_SHUFFLE(2,1,0,3));
xmm4 = _mm_shuffle_ps(xmm4, xmm4, _MM_SHUFFLE(2,1,0,3));
xmm3 = _mm_shuffle_ps(xmm3, xmm3, _MM_SHUFFLE(2,1,0,3));
xmm2 = _mm_shuffle_ps(xmm2, xmm2, _MM_SHUFFLE(2,1,0,3));
xmm5 = _mm_move_ss(xmm5, xmm4);
xmm4 = _mm_move_ss(xmm4, xmm3);
xmm3 = _mm_move_ss(xmm3, xmm2);
xmm2 = _mm_move_ss(xmm2, xmm0);
/* xmm9|xmm8|xmm7|xmm6 += xmm0|xmm0|xmm0|xmm0 * xmm5|xmm4|xmm3|xmm2 */
xmm1 = xmm0;
xmm1 = _mm_mul_ps(xmm1, xmm5);
xmm9 = _mm_add_ps(xmm9, xmm1);
xmm1 = xmm0;
xmm1 = _mm_mul_ps(xmm1, xmm4);
xmm8 = _mm_add_ps(xmm8, xmm1);
xmm1 = xmm0;
xmm1 = _mm_mul_ps(xmm1, xmm3);
xmm7 = _mm_add_ps(xmm7, xmm1);
xmm0 = _mm_mul_ps(xmm0, xmm2);
xmm6 = _mm_add_ps(xmm6, xmm0);
data_len--;
}
_mm_storeu_ps(autoc, xmm6);
_mm_storeu_ps(autoc+4, xmm7);
_mm_storeu_ps(autoc+8, xmm8);
_mm_storeu_ps(autoc+12,xmm9);
}
#endif
#endif /* FLAC__SSE_SUPPORTED */
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
#endif /* FLAC__NO_ASM */
#endif /* FLAC__INTEGER_ONLY_LIBRARY */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,518 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h> /* for malloc() */
#include <string.h> /* for memcpy() */
#include "private/md5.h"
#include "share/alloc.h"
#include "share/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])
{
register 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 = realloc(ctx->internal_buf.p8, bytes_needed);
if (0 == tmp) {
free(ctx->internal_buf.p8);
if (0 == (ctx->internal_buf.p8= 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;
}

@ -0,0 +1,218 @@
/* 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 "private/memory.h"
#include "FLAC/assert.h"
#include "share/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__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__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__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 = 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__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);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,251 @@
/* libFLAC - Free Lossless Audio Codec
* 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h> /* for memcpy() */
#include "FLAC/assert.h"
#include "private/ogg_decoder_aspect.h"
#include "private/ogg_mapping.h"
#include "private/macros.h"
/***********************************************************************
*
* Public class methods
*
***********************************************************************/
FLAC__bool FLAC__ogg_decoder_aspect_init(FLAC__OggDecoderAspect *aspect)
{
/* we will determine the serial number later if necessary */
if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0)
return false;
if(ogg_sync_init(&aspect->sync_state) != 0)
return false;
aspect->version_major = ~(0u);
aspect->version_minor = ~(0u);
aspect->need_serial_number = aspect->use_first_serial_number;
aspect->end_of_stream = false;
aspect->have_working_page = false;
return true;
}
void FLAC__ogg_decoder_aspect_finish(FLAC__OggDecoderAspect *aspect)
{
(void)ogg_sync_clear(&aspect->sync_state);
(void)ogg_stream_clear(&aspect->stream_state);
}
void FLAC__ogg_decoder_aspect_set_serial_number(FLAC__OggDecoderAspect *aspect, long value)
{
aspect->use_first_serial_number = false;
aspect->serial_number = value;
}
void FLAC__ogg_decoder_aspect_set_defaults(FLAC__OggDecoderAspect *aspect)
{
aspect->use_first_serial_number = true;
}
void FLAC__ogg_decoder_aspect_flush(FLAC__OggDecoderAspect *aspect)
{
(void)ogg_stream_reset(&aspect->stream_state);
(void)ogg_sync_reset(&aspect->sync_state);
aspect->end_of_stream = false;
aspect->have_working_page = false;
}
void FLAC__ogg_decoder_aspect_reset(FLAC__OggDecoderAspect *aspect)
{
FLAC__ogg_decoder_aspect_flush(aspect);
if(aspect->use_first_serial_number)
aspect->need_serial_number = true;
}
FLAC__OggDecoderAspectReadStatus FLAC__ogg_decoder_aspect_read_callback_wrapper(FLAC__OggDecoderAspect *aspect, FLAC__byte buffer[], size_t *bytes, FLAC__OggDecoderAspectReadCallbackProxy read_callback, const FLAC__StreamDecoder *decoder, void *client_data)
{
static const size_t OGG_BYTES_CHUNK = 8192;
const size_t bytes_requested = *bytes;
/*
* The FLAC decoding API uses pull-based reads, whereas Ogg decoding
* is push-based. In libFLAC, when you ask to decode a frame, the
* decoder will eventually call the read callback to supply some data,
* but how much it asks for depends on how much free space it has in
* its internal buffer. It does not try to grow its internal buffer
* to accomodate a whole frame because then the internal buffer size
* could not be limited, which is necessary in embedded applications.
*
* Ogg however grows its internal buffer until a whole page is present;
* only then can you get decoded data out. So we can't just ask for
* the same number of bytes from Ogg, then pass what's decoded down to
* libFLAC. If what libFLAC is asking for will not contain a whole
* page, then we will get no data from ogg_sync_pageout(), and at the
* same time cannot just read more data from the client for the purpose
* of getting a whole decoded page because the decoded size might be
* larger than libFLAC's internal buffer.
*
* Instead, whenever this read callback wrapper is called, we will
* continually request data from the client until we have at least one
* page, and manage pages internally so that we can send pieces of
* pages down to libFLAC in such a way that we obey its size
* requirement. To limit the amount of callbacks, we will always try
* to read in enough pages to return the full number of bytes
* requested.
*/
*bytes = 0;
while (*bytes < bytes_requested && !aspect->end_of_stream) {
if (aspect->have_working_page) {
if (aspect->have_working_packet) {
size_t n = bytes_requested - *bytes;
if ((size_t)aspect->working_packet.bytes <= n) {
/* the rest of the packet will fit in the buffer */
n = aspect->working_packet.bytes;
memcpy(buffer, aspect->working_packet.packet, n);
*bytes += n;
buffer += n;
aspect->have_working_packet = false;
}
else {
/* only n bytes of the packet will fit in the buffer */
memcpy(buffer, aspect->working_packet.packet, n);
*bytes += n;
buffer += n;
aspect->working_packet.packet += n;
aspect->working_packet.bytes -= n;
}
}
else {
/* try and get another packet */
const int ret = ogg_stream_packetout(&aspect->stream_state, &aspect->working_packet);
if (ret > 0) {
aspect->have_working_packet = true;
/* if it is the first header packet, check for magic and a supported Ogg FLAC mapping version */
if (aspect->working_packet.bytes > 0 && aspect->working_packet.packet[0] == FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE) {
const FLAC__byte *b = aspect->working_packet.packet;
const unsigned header_length =
FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH +
FLAC__OGG_MAPPING_MAGIC_LENGTH +
FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH +
FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH +
FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH;
if (aspect->working_packet.bytes < (long)header_length)
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC;
b += FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH;
if (memcmp(b, FLAC__OGG_MAPPING_MAGIC, FLAC__OGG_MAPPING_MAGIC_LENGTH))
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_NOT_FLAC;
b += FLAC__OGG_MAPPING_MAGIC_LENGTH;
aspect->version_major = (unsigned)(*b);
b += FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH;
aspect->version_minor = (unsigned)(*b);
if (aspect->version_major != 1)
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_UNSUPPORTED_MAPPING_VERSION;
aspect->working_packet.packet += header_length;
aspect->working_packet.bytes -= header_length;
}
}
else if (ret == 0) {
aspect->have_working_page = false;
}
else { /* ret < 0 */
/* lost sync, we'll leave the working page for the next call */
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC;
}
}
}
else {
/* try and get another page */
const int ret = ogg_sync_pageout(&aspect->sync_state, &aspect->working_page);
if (ret > 0) {
/* got a page, grab the serial number if necessary */
if(aspect->need_serial_number) {
aspect->stream_state.serialno = aspect->serial_number = ogg_page_serialno(&aspect->working_page);
aspect->need_serial_number = false;
}
if(ogg_stream_pagein(&aspect->stream_state, &aspect->working_page) == 0) {
aspect->have_working_page = true;
aspect->have_working_packet = false;
}
/* else do nothing, could be a page from another stream */
}
else if (ret == 0) {
/* need more data */
const size_t ogg_bytes_to_read = flac_max(bytes_requested - *bytes, OGG_BYTES_CHUNK);
char *oggbuf = ogg_sync_buffer(&aspect->sync_state, ogg_bytes_to_read);
if(0 == oggbuf) {
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_MEMORY_ALLOCATION_ERROR;
}
else {
size_t ogg_bytes_read = ogg_bytes_to_read;
switch(read_callback(decoder, (FLAC__byte*)oggbuf, &ogg_bytes_read, client_data)) {
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK:
break;
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM:
aspect->end_of_stream = true;
break;
case FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT:
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ABORT;
default:
FLAC__ASSERT(0);
}
if(ogg_sync_wrote(&aspect->sync_state, ogg_bytes_read) < 0) {
/* double protection; this will happen if the read callback returns more bytes than the max requested, which would overflow Ogg's internal buffer */
FLAC__ASSERT(0);
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_ERROR;
}
}
}
else { /* ret < 0 */
/* lost sync, bail out */
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_LOST_SYNC;
}
}
}
if (aspect->end_of_stream && *bytes == 0) {
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_END_OF_STREAM;
}
return FLAC__OGG_DECODER_ASPECT_READ_STATUS_OK;
}

@ -0,0 +1,228 @@
/* libFLAC - Free Lossless Audio Codec
* 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.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h> /* for memset() */
#include "FLAC/assert.h"
#include "private/ogg_encoder_aspect.h"
#include "private/ogg_mapping.h"
static const FLAC__byte FLAC__OGG_MAPPING_VERSION_MAJOR = 1;
static const FLAC__byte FLAC__OGG_MAPPING_VERSION_MINOR = 0;
/***********************************************************************
*
* Public class methods
*
***********************************************************************/
FLAC__bool FLAC__ogg_encoder_aspect_init(FLAC__OggEncoderAspect *aspect)
{
/* we will determine the serial number later if necessary */
if(ogg_stream_init(&aspect->stream_state, aspect->serial_number) != 0)
return false;
aspect->seen_magic = false;
aspect->is_first_packet = true;
aspect->samples_written = 0;
return true;
}
void FLAC__ogg_encoder_aspect_finish(FLAC__OggEncoderAspect *aspect)
{
(void)ogg_stream_clear(&aspect->stream_state);
/*@@@ what about the page? */
}
void FLAC__ogg_encoder_aspect_set_serial_number(FLAC__OggEncoderAspect *aspect, long value)
{
aspect->serial_number = value;
}
FLAC__bool FLAC__ogg_encoder_aspect_set_num_metadata(FLAC__OggEncoderAspect *aspect, unsigned value)
{
if(value < (1u << FLAC__OGG_MAPPING_NUM_HEADERS_LEN)) {
aspect->num_metadata = value;
return true;
}
else
return false;
}
void FLAC__ogg_encoder_aspect_set_defaults(FLAC__OggEncoderAspect *aspect)
{
aspect->serial_number = 0;
aspect->num_metadata = 0;
}
/*
* The basic FLAC -> Ogg mapping goes like this:
*
* - 'fLaC' magic and STREAMINFO block get combined into the first
* packet. The packet is prefixed with
* + the one-byte packet type 0x7F
* + 'FLAC' magic
* + the 2 byte Ogg FLAC mapping version number
* + tne 2 byte big-endian # of header packets
* - The first packet is flushed to the first page.
* - Each subsequent metadata block goes into its own packet.
* - Each metadata packet is flushed to page (this is not required,
* the mapping only requires that a flush must occur after all
* metadata is written).
* - Each subsequent FLAC audio frame goes into its own packet.
*
* WATCHOUT:
* This depends on the behavior of FLAC__StreamEncoder that we get a
* separate write callback for the fLaC magic, and then separate write
* callbacks for each metadata block and audio frame.
*/
FLAC__StreamEncoderWriteStatus FLAC__ogg_encoder_aspect_write_callback_wrapper(FLAC__OggEncoderAspect *aspect, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, FLAC__bool is_last_block, FLAC__OggEncoderAspectWriteCallbackProxy write_callback, void *encoder, void *client_data)
{
/* WATCHOUT:
* This depends on the behavior of FLAC__StreamEncoder that 'samples'
* will be 0 for metadata writes.
*/
const FLAC__bool is_metadata = (samples == 0);
/*
* Treat fLaC magic packet specially. We will note when we see it, then
* wait until we get the STREAMINFO and prepend it in that packet
*/
if(aspect->seen_magic) {
ogg_packet packet;
FLAC__byte synthetic_first_packet_body[
FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH +
FLAC__OGG_MAPPING_MAGIC_LENGTH +
FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH +
FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH +
FLAC__OGG_MAPPING_NUM_HEADERS_LENGTH +
FLAC__STREAM_SYNC_LENGTH +
FLAC__STREAM_METADATA_HEADER_LENGTH +
FLAC__STREAM_METADATA_STREAMINFO_LENGTH
];
memset(&packet, 0, sizeof(packet));
packet.granulepos = aspect->samples_written + samples;
if(aspect->is_first_packet) {
FLAC__byte *b = synthetic_first_packet_body;
if(bytes != FLAC__STREAM_METADATA_HEADER_LENGTH + FLAC__STREAM_METADATA_STREAMINFO_LENGTH) {
/*
* If we get here, our assumption about the way write callbacks happen
* (explained above) is wrong
*/
FLAC__ASSERT(0);
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
}
/* add first header packet type */
*b = FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE;
b += FLAC__OGG_MAPPING_PACKET_TYPE_LENGTH;
/* add 'FLAC' mapping magic */
memcpy(b, FLAC__OGG_MAPPING_MAGIC, FLAC__OGG_MAPPING_MAGIC_LENGTH);
b += FLAC__OGG_MAPPING_MAGIC_LENGTH;
/* add Ogg FLAC mapping major version number */
memcpy(b, &FLAC__OGG_MAPPING_VERSION_MAJOR, FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH);
b += FLAC__OGG_MAPPING_VERSION_MAJOR_LENGTH;
/* add Ogg FLAC mapping minor version number */
memcpy(b, &FLAC__OGG_MAPPING_VERSION_MINOR, FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH);
b += FLAC__OGG_MAPPING_VERSION_MINOR_LENGTH;
/* add number of header packets */
*b = (FLAC__byte)(aspect->num_metadata >> 8);
b++;
*b = (FLAC__byte)(aspect->num_metadata);
b++;
/* add native FLAC 'fLaC' magic */
memcpy(b, FLAC__STREAM_SYNC_STRING, FLAC__STREAM_SYNC_LENGTH);
b += FLAC__STREAM_SYNC_LENGTH;
/* add STREAMINFO */
memcpy(b, buffer, bytes);
FLAC__ASSERT(b + bytes - synthetic_first_packet_body == sizeof(synthetic_first_packet_body));
packet.packet = (unsigned char *)synthetic_first_packet_body;
packet.bytes = sizeof(synthetic_first_packet_body);
packet.b_o_s = 1;
aspect->is_first_packet = false;
}
else {
packet.packet = (unsigned char *)buffer;
packet.bytes = bytes;
}
if(is_last_block) {
/* we used to check:
* FLAC__ASSERT(total_samples_estimate == 0 || total_samples_estimate == aspect->samples_written + samples);
* but it's really not useful since total_samples_estimate is an estimate and can be inexact
*/
packet.e_o_s = 1;
}
if(ogg_stream_packetin(&aspect->stream_state, &packet) != 0)
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
/*@@@ can't figure out a way to pass a useful number for 'samples' to the write_callback, so we'll just pass 0 */
if(is_metadata) {
while(ogg_stream_flush(&aspect->stream_state, &aspect->page) != 0) {
if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
}
}
else {
while(ogg_stream_pageout(&aspect->stream_state, &aspect->page) != 0) {
if(write_callback(encoder, aspect->page.header, aspect->page.header_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
if(write_callback(encoder, aspect->page.body, aspect->page.body_len, 0, current_frame, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
}
}
}
else if(is_metadata && current_frame == 0 && samples == 0 && bytes == 4 && 0 == memcmp(buffer, FLAC__STREAM_SYNC_STRING, sizeof(FLAC__STREAM_SYNC_STRING))) {
aspect->seen_magic = true;
}
else {
/*
* If we get here, our assumption about the way write callbacks happen
* explained above is wrong
*/
FLAC__ASSERT(0);
return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
}
aspect->samples_written += samples;
return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
}

@ -0,0 +1,210 @@
/* libFLAC - Free Lossless Audio Codec
* 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 <stdlib.h> /* for malloc() */
#include <string.h> /* for memcmp(), memcpy() */
#include "FLAC/assert.h"
#include "share/alloc.h"
#include "private/ogg_helper.h"
#include "protected/stream_encoder.h"
static FLAC__bool full_read_(FLAC__StreamEncoder *encoder, FLAC__byte *buffer, size_t bytes, FLAC__StreamEncoderReadCallback read_callback, void *client_data)
{
while(bytes > 0) {
size_t bytes_read = bytes;
switch(read_callback(encoder, buffer, &bytes_read, client_data)) {
case FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE:
bytes -= bytes_read;
buffer += bytes_read;
break;
case FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM:
if(bytes_read == 0) {
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
return false;
}
bytes -= bytes_read;
buffer += bytes_read;
break;
case FLAC__STREAM_ENCODER_READ_STATUS_ABORT:
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
case FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED:
return false;
default:
/* double protection: */
FLAC__ASSERT(0);
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
}
return true;
}
void simple_ogg_page__init(ogg_page *page)
{
page->header = 0;
page->header_len = 0;
page->body = 0;
page->body_len = 0;
}
void simple_ogg_page__clear(ogg_page *page)
{
if(page->header)
free(page->header);
if(page->body)
free(page->body);
simple_ogg_page__init(page);
}
FLAC__bool simple_ogg_page__get_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderReadCallback read_callback, void *client_data)
{
static const unsigned OGG_HEADER_FIXED_PORTION_LEN = 27;
static const unsigned OGG_MAX_HEADER_LEN = 27/*OGG_HEADER_FIXED_PORTION_LEN*/ + 255;
FLAC__byte crc[4];
FLAC__StreamEncoderSeekStatus seek_status;
FLAC__ASSERT(page->header == 0);
FLAC__ASSERT(page->header_len == 0);
FLAC__ASSERT(page->body == 0);
FLAC__ASSERT(page->body_len == 0);
/* move the stream pointer to the supposed beginning of the page */
if(0 == seek_callback)
return false;
if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
/* allocate space for the page header */
if(0 == (page->header = safe_malloc_(OGG_MAX_HEADER_LEN))) {
encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return false;
}
/* read in the fixed part of the page header (up to but not including
* the segment table */
if(!full_read_(encoder, page->header, OGG_HEADER_FIXED_PORTION_LEN, read_callback, client_data))
return false;
page->header_len = OGG_HEADER_FIXED_PORTION_LEN + page->header[26];
/* check to see if it's a correct, "simple" page (one packet only) */
if(
memcmp(page->header, "OggS", 4) || /* doesn't start with OggS */
(page->header[5] & 0x01) || /* continued packet */
memcmp(page->header+6, "\0\0\0\0\0\0\0\0", 8) || /* granulepos is non-zero */
page->header[26] == 0 /* packet is 0-size */
) {
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
return false;
}
/* read in the segment table */
if(!full_read_(encoder, page->header + OGG_HEADER_FIXED_PORTION_LEN, page->header[26], read_callback, client_data))
return false;
{
unsigned i;
/* check to see that it specifies a single packet */
for(i = 0; i < (unsigned)page->header[26] - 1; i++) {
if(page->header[i + OGG_HEADER_FIXED_PORTION_LEN] != 255) {
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
return false;
}
}
page->body_len = 255 * i + page->header[i + OGG_HEADER_FIXED_PORTION_LEN];
}
/* allocate space for the page body */
if(0 == (page->body = safe_malloc_(page->body_len))) {
encoder->protected_->state = FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR;
return false;
}
/* read in the page body */
if(!full_read_(encoder, page->body, page->body_len, read_callback, client_data))
return false;
/* check the CRC */
memcpy(crc, page->header+22, 4);
ogg_page_checksum_set(page);
if(memcmp(crc, page->header+22, 4)) {
encoder->protected_->state = FLAC__STREAM_ENCODER_OGG_ERROR;
return false;
}
return true;
}
FLAC__bool simple_ogg_page__set_at(FLAC__StreamEncoder *encoder, FLAC__uint64 position, ogg_page *page, FLAC__StreamEncoderSeekCallback seek_callback, FLAC__StreamEncoderWriteCallback write_callback, void *client_data)
{
FLAC__StreamEncoderSeekStatus seek_status;
FLAC__ASSERT(page->header != 0);
FLAC__ASSERT(page->header_len != 0);
FLAC__ASSERT(page->body != 0);
FLAC__ASSERT(page->body_len != 0);
/* move the stream pointer to the supposed beginning of the page */
if(0 == seek_callback)
return false;
if((seek_status = seek_callback((FLAC__StreamEncoder*)encoder, position, client_data)) != FLAC__STREAM_ENCODER_SEEK_STATUS_OK) {
if(seek_status == FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR)
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
ogg_page_checksum_set(page);
/* re-write the page */
if(write_callback((FLAC__StreamEncoder*)encoder, page->header, page->header_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
if(write_callback((FLAC__StreamEncoder*)encoder, page->body, page->body_len, 0, 0, client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
encoder->protected_->state = FLAC__STREAM_ENCODER_CLIENT_ERROR;
return false;
}
return true;
}

@ -0,0 +1,48 @@
/* libFLAC - Free Lossless Audio Codec
* 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 "private/ogg_mapping.h"
const unsigned FLAC__OGG_MAPPING_PACKET_TYPE_LEN = 8; /* bits */
const FLAC__byte FLAC__OGG_MAPPING_FIRST_HEADER_PACKET_TYPE = 0x7f;
const FLAC__byte * const FLAC__OGG_MAPPING_MAGIC = (const FLAC__byte * const)"FLAC";
const unsigned FLAC__OGG_MAPPING_VERSION_MAJOR_LEN = 8; /* bits */
const unsigned FLAC__OGG_MAPPING_VERSION_MINOR_LEN = 8; /* bits */
const unsigned FLAC__OGG_MAPPING_NUM_HEADERS_LEN = 16; /* bits */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,549 @@
/* 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 "private/stream_encoder_framing.h"
#include "private/crc.h"
#include "FLAC/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;
}
}

@ -0,0 +1,142 @@
/* 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
#ifndef FLAC__NO_ASM
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#include "private/stream_encoder.h"
#include "private/bitmath.h"
#ifdef FLAC__AVX2_SUPPORTED
#include <stdlib.h> /* for abs() */
#include <immintrin.h> /* AVX2 */
#include "FLAC/assert.h"
FLAC__SSE_TARGET("avx2")
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)
{
const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order;
unsigned partitions = 1u << max_partition_order;
FLAC__ASSERT(default_partition_samples > predictor_order);
/* first do max_partition_order */
{
unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
__m256i res256, sum256;
__m128i res128, sum128;
if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) {
for(partition = residual_sample = 0; partition < partitions; partition++) {
end += default_partition_samples;
sum256 = _mm256_setzero_si256();
for( ; (int)residual_sample < (int)end-7; residual_sample+=8) {
res256 = _mm256_abs_epi32(_mm256_loadu_si256((const __m256i*)(residual+residual_sample)));
sum256 = _mm256_add_epi32(sum256, res256);
}
sum128 = _mm_add_epi32(_mm256_extracti128_si256(sum256, 1), _mm256_castsi256_si128(sum256));
for( ; (int)residual_sample < (int)end-3; residual_sample+=4) {
res128 = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample)));
sum128 = _mm_add_epi32(sum128, res128);
}
for( ; residual_sample < end; residual_sample++) {
res128 = _mm_cvtsi32_si128(residual[residual_sample]);
res128 = _mm_abs_epi32(res128);
sum128 = _mm_add_epi32(sum128, res128);
}
sum128 = _mm_hadd_epi32(sum128, sum128);
sum128 = _mm_hadd_epi32(sum128, sum128);
abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(sum128);
}
}
else { /* have to pessimistically use 64 bits for accumulator */
for(partition = residual_sample = 0; partition < partitions; partition++) {
end += default_partition_samples;
sum256 = _mm256_setzero_si256();
for( ; (int)residual_sample < (int)end-3; residual_sample+=4) {
res128 = _mm_abs_epi32(_mm_loadu_si128((const __m128i*)(residual+residual_sample)));
res256 = _mm256_cvtepu32_epi64(res128);
sum256 = _mm256_add_epi64(sum256, res256);
}
sum128 = _mm_add_epi64(_mm256_extracti128_si256(sum256, 1), _mm256_castsi256_si128(sum256));
for( ; (int)residual_sample < (int)end-1; residual_sample+=2) {
res128 = _mm_loadl_epi64((const __m128i*)(residual+residual_sample));
res128 = _mm_abs_epi32(res128);
res128 = _mm_cvtepu32_epi64(res128);
sum128 = _mm_add_epi64(sum128, res128);
}
for( ; residual_sample < end; residual_sample++) {
res128 = _mm_cvtsi32_si128(residual[residual_sample]);
res128 = _mm_abs_epi32(res128);
sum128 = _mm_add_epi64(sum128, res128);
}
sum128 = _mm_add_epi64(sum128, _mm_srli_si128(sum128, 8));
_mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), sum128);
}
}
}
/* now merge partitions for lower orders */
{
unsigned from_partition = 0, to_partition = partitions;
int partition_order;
for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) {
unsigned i;
partitions >>= 1;
for(i = 0; i < partitions; i++) {
abs_residual_partition_sums[to_partition++] =
abs_residual_partition_sums[from_partition ] +
abs_residual_partition_sums[from_partition+1];
from_partition += 2;
}
}
}
_mm256_zeroupper();
}
#endif /* FLAC__AVX2_SUPPORTED */
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
#endif /* FLAC__NO_ASM */

@ -0,0 +1,159 @@
/* 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
#ifndef FLAC__NO_ASM
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#include "private/stream_encoder.h"
#include "private/bitmath.h"
#ifdef FLAC__SSE2_SUPPORTED
#include <stdlib.h> /* for abs() */
#include <emmintrin.h> /* SSE2 */
#include "FLAC/assert.h"
FLAC__SSE_TARGET("sse2")
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)
{
const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order;
unsigned partitions = 1u << max_partition_order;
FLAC__ASSERT(default_partition_samples > predictor_order);
/* first do max_partition_order */
{
unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
unsigned e1, e3;
__m128i mm_res, mm_sum, mm_mask;
if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) {
for(partition = residual_sample = 0; partition < partitions; partition++) {
end += default_partition_samples;
mm_sum = _mm_setzero_si128();
e1 = (residual_sample + 3) & ~3; e3 = end & ~3;
if(e1 > end)
e1 = end; /* try flac -l 1 -b 16 and you'll be here */
/* assumption: residual[] is properly aligned so (residual + e1) is properly aligned too and _mm_loadu_si128() is fast */
for( ; residual_sample < e1; residual_sample++) {
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
mm_mask = _mm_srai_epi32(mm_res, 31);
mm_res = _mm_xor_si128(mm_res, mm_mask);
mm_res = _mm_sub_epi32(mm_res, mm_mask); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */
mm_sum = _mm_add_epi32(mm_sum, mm_res);
}
for( ; residual_sample < e3; residual_sample+=4) {
mm_res = _mm_loadu_si128((const __m128i*)(residual+residual_sample));
mm_mask = _mm_srai_epi32(mm_res, 31);
mm_res = _mm_xor_si128(mm_res, mm_mask);
mm_res = _mm_sub_epi32(mm_res, mm_mask);
mm_sum = _mm_add_epi32(mm_sum, mm_res);
}
for( ; residual_sample < end; residual_sample++) {
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
mm_mask = _mm_srai_epi32(mm_res, 31);
mm_res = _mm_xor_si128(mm_res, mm_mask);
mm_res = _mm_sub_epi32(mm_res, mm_mask);
mm_sum = _mm_add_epi32(mm_sum, mm_res);
}
mm_sum = _mm_add_epi32(mm_sum, _mm_srli_si128(mm_sum, 8));
mm_sum = _mm_add_epi32(mm_sum, _mm_srli_si128(mm_sum, 4));
abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(mm_sum);
}
}
else { /* have to pessimistically use 64 bits for accumulator */
for(partition = residual_sample = 0; partition < partitions; partition++) {
end += default_partition_samples;
mm_sum = _mm_setzero_si128();
e1 = (residual_sample + 1) & ~1; e3 = end & ~1;
FLAC__ASSERT(e1 <= end);
for( ; residual_sample < e1; residual_sample++) {
mm_res = _mm_cvtsi32_si128(residual[residual_sample]); /* 0 0 0 r0 */
mm_mask = _mm_srai_epi32(mm_res, 31);
mm_res = _mm_xor_si128(mm_res, mm_mask);
mm_res = _mm_sub_epi32(mm_res, mm_mask); /* 0 0 0 |r0| == 00 |r0_64| */
mm_sum = _mm_add_epi64(mm_sum, mm_res);
}
for( ; residual_sample < e3; residual_sample+=2) {
mm_res = _mm_loadl_epi64((const __m128i*)(residual+residual_sample)); /* 0 0 r1 r0 */
mm_mask = _mm_srai_epi32(mm_res, 31);
mm_res = _mm_xor_si128(mm_res, mm_mask);
mm_res = _mm_sub_epi32(mm_res, mm_mask); /* 0 0 |r1| |r0| */
mm_res = _mm_shuffle_epi32(mm_res, _MM_SHUFFLE(3,1,2,0)); /* 0 |r1| 0 |r0| == |r1_64| |r0_64| */
mm_sum = _mm_add_epi64(mm_sum, mm_res);
}
for( ; residual_sample < end; residual_sample++) {
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
mm_mask = _mm_srai_epi32(mm_res, 31);
mm_res = _mm_xor_si128(mm_res, mm_mask);
mm_res = _mm_sub_epi32(mm_res, mm_mask);
mm_sum = _mm_add_epi64(mm_sum, mm_res);
}
mm_sum = _mm_add_epi64(mm_sum, _mm_srli_si128(mm_sum, 8));
_mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), mm_sum);
}
}
}
/* now merge partitions for lower orders */
{
unsigned from_partition = 0, to_partition = partitions;
int partition_order;
for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) {
unsigned i;
partitions >>= 1;
for(i = 0; i < partitions; i++) {
abs_residual_partition_sums[to_partition++] =
abs_residual_partition_sums[from_partition ] +
abs_residual_partition_sums[from_partition+1];
from_partition += 2;
}
}
}
}
#endif /* FLAC__SSE2_SUPPORTED */
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
#endif /* FLAC__NO_ASM */

@ -0,0 +1,147 @@
/* 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
#ifndef FLAC__NO_ASM
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#include "private/stream_encoder.h"
#include "private/bitmath.h"
#ifdef FLAC__SSSE3_SUPPORTED
#include <stdlib.h> /* for abs() */
#include <tmmintrin.h> /* SSSE3 */
#include "FLAC/assert.h"
FLAC__SSE_TARGET("ssse3")
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)
{
const unsigned default_partition_samples = (residual_samples + predictor_order) >> max_partition_order;
unsigned partitions = 1u << max_partition_order;
FLAC__ASSERT(default_partition_samples > predictor_order);
/* first do max_partition_order */
{
unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
unsigned e1, e3;
__m128i mm_res, mm_sum;
if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) {
for(partition = residual_sample = 0; partition < partitions; partition++) {
end += default_partition_samples;
mm_sum = _mm_setzero_si128();
e1 = (residual_sample + 3) & ~3; e3 = end & ~3;
if(e1 > end)
e1 = end; /* try flac -l 1 -b 16 and you'll be here */
/* assumption: residual[] is properly aligned so (residual + e1) is properly aligned too and _mm_loadu_si128() is fast */
for( ; residual_sample < e1; residual_sample++) {
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
mm_res = _mm_abs_epi32(mm_res); /* abs(INT_MIN) is undefined, but if the residual is INT_MIN we have bigger problems */
mm_sum = _mm_add_epi32(mm_sum, mm_res);
}
for( ; residual_sample < e3; residual_sample+=4) {
mm_res = _mm_loadu_si128((const __m128i*)(residual+residual_sample));
mm_res = _mm_abs_epi32(mm_res);
mm_sum = _mm_add_epi32(mm_sum, mm_res);
}
for( ; residual_sample < end; residual_sample++) {
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
mm_res = _mm_abs_epi32(mm_res);
mm_sum = _mm_add_epi32(mm_sum, mm_res);
}
mm_sum = _mm_hadd_epi32(mm_sum, mm_sum);
mm_sum = _mm_hadd_epi32(mm_sum, mm_sum);
abs_residual_partition_sums[partition] = (FLAC__uint32)_mm_cvtsi128_si32(mm_sum);
}
}
else { /* have to pessimistically use 64 bits for accumulator */
for(partition = residual_sample = 0; partition < partitions; partition++) {
end += default_partition_samples;
mm_sum = _mm_setzero_si128();
e1 = (residual_sample + 1) & ~1; e3 = end & ~1;
FLAC__ASSERT(e1 <= end);
for( ; residual_sample < e1; residual_sample++) {
mm_res = _mm_cvtsi32_si128(residual[residual_sample]); /* 0 0 0 r0 */
mm_res = _mm_abs_epi32(mm_res); /* 0 0 0 |r0| == 00 |r0_64| */
mm_sum = _mm_add_epi64(mm_sum, mm_res);
}
for( ; residual_sample < e3; residual_sample+=2) {
mm_res = _mm_loadl_epi64((const __m128i*)(residual+residual_sample)); /* 0 0 r1 r0 */
mm_res = _mm_abs_epi32(mm_res); /* 0 0 |r1| |r0| */
mm_res = _mm_shuffle_epi32(mm_res, _MM_SHUFFLE(3,1,2,0)); /* 0 |r1| 0 |r0| == |r1_64| |r0_64| */
mm_sum = _mm_add_epi64(mm_sum, mm_res);
}
for( ; residual_sample < end; residual_sample++) {
mm_res = _mm_cvtsi32_si128(residual[residual_sample]);
mm_res = _mm_abs_epi32(mm_res);
mm_sum = _mm_add_epi64(mm_sum, mm_res);
}
mm_sum = _mm_add_epi64(mm_sum, _mm_srli_si128(mm_sum, 8));
_mm_storel_epi64((__m128i*)(abs_residual_partition_sums+partition), mm_sum);
}
}
}
/* now merge partitions for lower orders */
{
unsigned from_partition = 0, to_partition = partitions;
int partition_order;
for(partition_order = (int)max_partition_order - 1; partition_order >= (int)min_partition_order; partition_order--) {
unsigned i;
partitions >>= 1;
for(i = 0; i < partitions; i++) {
abs_residual_partition_sums[to_partition++] =
abs_residual_partition_sums[from_partition ] +
abs_residual_partition_sums[from_partition+1];
from_partition += 2;
}
}
}
}
#endif /* FLAC__SSSE3_SUPPORTED */
#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */
#endif /* FLAC__NO_ASM */

@ -0,0 +1,373 @@
/* 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 HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <sys/stat.h>
#include <sys/utime.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h> /* for WideCharToMultiByte and MultiByteToWideChar */
#include "share/win_utf8_io.h"
#define UTF8_BUFFER_SIZE 32768
static
int local_vsnprintf(char *str, size_t size, const char *fmt, va_list va)
{
int rc;
#if defined _MSC_VER
if (size == 0)
return 1024;
rc = vsnprintf_s (str, size, _TRUNCATE, fmt, va);
if (rc < 0)
rc = size - 1;
#elif defined __MINGW32__
rc = __mingw_vsnprintf (str, size, fmt, va);
#else
rc = vsnprintf (str, size, fmt, va);
#endif
return rc;
}
static UINT win_utf8_io_codepage = CP_ACP;
/* convert WCHAR stored Unicode string to UTF-8. Caller is responsible for freeing memory */
static
char *utf8_from_wchar(const wchar_t *wstr)
{
char *utf8str;
int len;
if (!wstr) return NULL;
if ((len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL)) == 0) return NULL;
if ((utf8str = (char *)malloc(++len)) == NULL) return NULL;
if (WideCharToMultiByte(CP_UTF8, 0, wstr, -1, utf8str, len, NULL, NULL) == 0) {
free(utf8str);
utf8str = NULL;
}
return utf8str;
}
/* convert UTF-8 back to WCHAR. Caller is responsible for freeing memory */
static
wchar_t *wchar_from_utf8(const char *str)
{
wchar_t *widestr;
int len;
if (!str) return NULL;
len=(int)strlen(str)+1;
if ((widestr = (wchar_t *)malloc(len*sizeof(wchar_t))) != NULL) {
if (MultiByteToWideChar(win_utf8_io_codepage, 0, str, len, widestr, len) == 0) {
if (MultiByteToWideChar(CP_ACP, 0, str, len, widestr, len) == 0) { /* try conversion from Ansi in case the initial UTF-8 conversion had failed */
free(widestr);
widestr = NULL;
}
}
}
return widestr;
}
/* retrieve WCHAR commandline, expand wildcards and convert everything to UTF-8 */
int get_utf8_argv(int *argc, char ***argv)
{
typedef int (__cdecl *wgetmainargs_t)(int*, wchar_t***, wchar_t***, int, int*);
wgetmainargs_t wgetmainargs;
HMODULE handle;
int wargc;
wchar_t **wargv;
wchar_t **wenv;
char **utf8argv;
int ret, i;
if ((handle = LoadLibrary("msvcrt.dll")) == NULL) return 1;
if ((wgetmainargs = (wgetmainargs_t)GetProcAddress(handle, "__wgetmainargs")) == NULL) return 1;
i = 0;
/* if __wgetmainargs expands wildcards then it also erroneously converts \\?\c:\path\to\file.flac to \\file.flac */
if (wgetmainargs(&wargc, &wargv, &wenv, 1, &i) != 0) return 1;
if ((utf8argv = (char **)calloc(wargc, sizeof(char*))) == NULL) return 1;
ret = 0;
for (i=0; i<wargc; i++) {
if ((utf8argv[i] = utf8_from_wchar(wargv[i])) == NULL) {
ret = 1;
break;
}
}
FreeLibrary(handle);
if (ret == 0) {
win_utf8_io_codepage = CP_UTF8;
*argc = wargc;
*argv = utf8argv;
} else {
for (i=0; i<wargc; i++)
free(utf8argv[i]);
free(utf8argv);
}
return ret;
}
/* return number of characters in the UTF-8 string */
size_t strlen_utf8(const char *str)
{
size_t len;
if ((len = MultiByteToWideChar(win_utf8_io_codepage, 0, str, -1, NULL, 0)) == 0)
len = strlen(str);
return len;
}
/* get the console width in characters */
int win_get_console_width(void)
{
int width = 80;
CONSOLE_SCREEN_BUFFER_INFO csbi;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (GetConsoleScreenBufferInfo(hOut, &csbi) != 0) width = csbi.dwSize.X;
return width;
}
/* print functions */
int print_console(FILE *stream, const wchar_t *text, size_t len)
{
static HANDLE hOut;
static HANDLE hErr;
DWORD out;
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
hErr = GetStdHandle(STD_ERROR_HANDLE);
if (stream == stdout && hOut != INVALID_HANDLE_VALUE && GetFileType(hOut) == FILE_TYPE_CHAR) {
if (WriteConsoleW(hOut, text, len, &out, NULL) == 0) return -1;
return out;
} else if (stream == stderr && hErr != INVALID_HANDLE_VALUE && GetFileType(hErr) == FILE_TYPE_CHAR) {
if (WriteConsoleW(hErr, text, len, &out, NULL) == 0) return -1;
return out;
} else {
int ret = fputws(text, stream);
if (ret < 0) return ret;
return len;
}
}
int printf_utf8(const char *format, ...)
{
char *utmp = NULL;
wchar_t *wout = NULL;
int ret = -1;
while (1) {
va_list argptr;
if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
va_start(argptr, format);
ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr);
va_end(argptr);
if (ret < 0) break;
if (!(wout = wchar_from_utf8(utmp))) {
ret = -1;
break;
}
ret = print_console(stdout, wout, wcslen(wout));
break;
}
if (utmp) free(utmp);
if (wout) free(wout);
return ret;
}
int fprintf_utf8(FILE *stream, const char *format, ...)
{
char *utmp = NULL;
wchar_t *wout = NULL;
int ret = -1;
while (1) {
va_list argptr;
if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
va_start(argptr, format);
ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr);
va_end(argptr);
if (ret < 0) break;
if (!(wout = wchar_from_utf8(utmp))) {
ret = -1;
break;
}
ret = print_console(stream, wout, wcslen(wout));
break;
}
if (utmp) free(utmp);
if (wout) free(wout);
return ret;
}
int vfprintf_utf8(FILE *stream, const char *format, va_list argptr)
{
char *utmp = NULL;
wchar_t *wout = NULL;
int ret = -1;
while (1) {
if (!(utmp = (char *)malloc(UTF8_BUFFER_SIZE*sizeof(char)))) break;
if ((ret = local_vsnprintf(utmp, UTF8_BUFFER_SIZE, format, argptr)) < 0) break;
if (!(wout = wchar_from_utf8(utmp))) {
ret = -1;
break;
}
ret = print_console(stream, wout, wcslen(wout));
break;
}
if (utmp) free(utmp);
if (wout) free(wout);
return ret;
}
/* file functions */
FILE *fopen_utf8(const char *filename, const char *mode)
{
wchar_t *wname = NULL;
wchar_t *wmode = NULL;
FILE *f = NULL;
while (1) {
if (!(wname = wchar_from_utf8(filename))) break;
if (!(wmode = wchar_from_utf8(mode))) break;
f = _wfopen(wname, wmode);
break;
}
if (wname) free(wname);
if (wmode) free(wmode);
return f;
}
int _stat64_utf8(const char *path, struct __stat64 *buffer)
{
wchar_t *wpath;
int ret;
if (!(wpath = wchar_from_utf8(path))) return -1;
ret = _wstat64(wpath, buffer);
free(wpath);
return ret;
}
int chmod_utf8(const char *filename, int pmode)
{
wchar_t *wname;
int ret;
if (!(wname = wchar_from_utf8(filename))) return -1;
ret = _wchmod(wname, pmode);
free(wname);
return ret;
}
int utime_utf8(const char *filename, struct utimbuf *times)
{
wchar_t *wname;
struct __utimbuf64 ut;
int ret;
if (sizeof(*times) == sizeof(ut)) {
memcpy(&ut, times, sizeof(ut));
} else {
ut.actime = times->actime;
ut.modtime = times->modtime;
}
if (!(wname = wchar_from_utf8(filename))) return -1;
ret = _wutime64(wname, &ut);
free(wname);
return ret;
}
int unlink_utf8(const char *filename)
{
wchar_t *wname;
int ret;
if (!(wname = wchar_from_utf8(filename))) return -1;
ret = _wunlink(wname);
free(wname);
return ret;
}
int rename_utf8(const char *oldname, const char *newname)
{
wchar_t *wold = NULL;
wchar_t *wnew = NULL;
int ret = -1;
while (1) {
if (!(wold = wchar_from_utf8(oldname))) break;
if (!(wnew = wchar_from_utf8(newname))) break;
ret = _wrename(wold, wnew);
break;
}
if (wold) free(wold);
if (wnew) free(wnew);
return ret;
}
HANDLE WINAPI CreateFile_utf8(const char *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
wchar_t *wname;
HANDLE handle = INVALID_HANDLE_VALUE;
if ((wname = wchar_from_utf8(lpFileName)) != NULL) {
handle = CreateFileW(wname, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
free(wname);
}
return handle;
}

@ -0,0 +1,282 @@
/* 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 "share/compat.h"
#include "FLAC/assert.h"
#include "FLAC/format.h"
#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 */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,210 @@
/********************************************************************
* *
* 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: toplevel libogg include
last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $
********************************************************************/
#ifndef _OGG_H
#define _OGG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stddef.h>
#include <ogg/os_types.h>
typedef struct {
void *iov_base;
size_t iov_len;
} ogg_iovec_t;
typedef struct {
long endbyte;
int endbit;
unsigned char *buffer;
unsigned char *ptr;
long storage;
} oggpack_buffer;
/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/
typedef struct {
unsigned char *header;
long header_len;
unsigned char *body;
long body_len;
} ogg_page;
/* ogg_stream_state contains the current encode/decode state of a logical
Ogg bitstream **********************************************************/
typedef struct {
unsigned char *body_data; /* bytes from packet bodies */
long body_storage; /* storage elements allocated */
long body_fill; /* elements stored; fill mark */
long body_returned; /* elements of fill returned */
int *lacing_vals; /* The values that will go to the segment table */
ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact
this way, but it is simple coupled to the
lacing fifo */
long lacing_storage;
long lacing_fill;
long lacing_packet;
long lacing_returned;
unsigned char header[282]; /* working space for header encode */
int header_fill;
int e_o_s; /* set when we have buffered the last packet in the
logical bitstream */
int b_o_s; /* set after we've written the initial page
of a logical bitstream */
long serialno;
long pageno;
ogg_int64_t packetno; /* sequence number for decode; the framing
knows where there's a hole in the data,
but we need coupling so that the codec
(which is in a separate abstraction
layer) also knows about the gap */
ogg_int64_t granulepos;
} ogg_stream_state;
/* ogg_packet is used to encapsulate the data and metadata belonging
to a single raw Ogg/Vorbis packet *************************************/
typedef struct {
unsigned char *packet;
long bytes;
long b_o_s;
long e_o_s;
ogg_int64_t granulepos;
ogg_int64_t packetno; /* sequence number for decode; the framing
knows where there's a hole in the data,
but we need coupling so that the codec
(which is in a separate abstraction
layer) also knows about the gap */
} ogg_packet;
typedef struct {
unsigned char *data;
int storage;
int fill;
int returned;
int unsynced;
int headerbytes;
int bodybytes;
} ogg_sync_state;
/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
extern void oggpack_writeinit(oggpack_buffer *b);
extern int oggpack_writecheck(oggpack_buffer *b);
extern void oggpack_writetrunc(oggpack_buffer *b,long bits);
extern void oggpack_writealign(oggpack_buffer *b);
extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits);
extern void oggpack_reset(oggpack_buffer *b);
extern void oggpack_writeclear(oggpack_buffer *b);
extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits);
extern long oggpack_look(oggpack_buffer *b,int bits);
extern long oggpack_look1(oggpack_buffer *b);
extern void oggpack_adv(oggpack_buffer *b,int bits);
extern void oggpack_adv1(oggpack_buffer *b);
extern long oggpack_read(oggpack_buffer *b,int bits);
extern long oggpack_read1(oggpack_buffer *b);
extern long oggpack_bytes(oggpack_buffer *b);
extern long oggpack_bits(oggpack_buffer *b);
extern unsigned char *oggpack_get_buffer(oggpack_buffer *b);
extern void oggpackB_writeinit(oggpack_buffer *b);
extern int oggpackB_writecheck(oggpack_buffer *b);
extern void oggpackB_writetrunc(oggpack_buffer *b,long bits);
extern void oggpackB_writealign(oggpack_buffer *b);
extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits);
extern void oggpackB_reset(oggpack_buffer *b);
extern void oggpackB_writeclear(oggpack_buffer *b);
extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes);
extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits);
extern long oggpackB_look(oggpack_buffer *b,int bits);
extern long oggpackB_look1(oggpack_buffer *b);
extern void oggpackB_adv(oggpack_buffer *b,int bits);
extern void oggpackB_adv1(oggpack_buffer *b);
extern long oggpackB_read(oggpack_buffer *b,int bits);
extern long oggpackB_read1(oggpack_buffer *b);
extern long oggpackB_bytes(oggpack_buffer *b);
extern long oggpackB_bits(oggpack_buffer *b);
extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b);
/* Ogg BITSTREAM PRIMITIVES: encoding **************************/
extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op);
extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov,
int count, long e_o_s, ogg_int64_t granulepos);
extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill);
extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill);
/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
extern int ogg_sync_init(ogg_sync_state *oy);
extern int ogg_sync_clear(ogg_sync_state *oy);
extern int ogg_sync_reset(ogg_sync_state *oy);
extern int ogg_sync_destroy(ogg_sync_state *oy);
extern int ogg_sync_check(ogg_sync_state *oy);
extern char *ogg_sync_buffer(ogg_sync_state *oy, long size);
extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes);
extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og);
extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og);
extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og);
extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op);
extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op);
/* Ogg BITSTREAM PRIMITIVES: general ***************************/
extern int ogg_stream_init(ogg_stream_state *os,int serialno);
extern int ogg_stream_clear(ogg_stream_state *os);
extern int ogg_stream_reset(ogg_stream_state *os);
extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno);
extern int ogg_stream_destroy(ogg_stream_state *os);
extern int ogg_stream_check(ogg_stream_state *os);
extern int ogg_stream_eos(ogg_stream_state *os);
extern void ogg_page_checksum_set(ogg_page *og);
extern int ogg_page_version(const ogg_page *og);
extern int ogg_page_continued(const ogg_page *og);
extern int ogg_page_bos(const ogg_page *og);
extern int ogg_page_eos(const ogg_page *og);
extern ogg_int64_t ogg_page_granulepos(const ogg_page *og);
extern int ogg_page_serialno(const ogg_page *og);
extern long ogg_page_pageno(const ogg_page *og);
extern int ogg_page_packets(const ogg_page *og);
extern void ogg_packet_clear(ogg_packet *op);
#ifdef __cplusplus
}
#endif
#endif /* _OGG_H */

@ -0,0 +1,147 @@
/********************************************************************
* *
* 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: #ifdef jail to whip a few platforms into the UNIX ideal.
last mod: $Id: os_types.h 19098 2014-02-26 19:06:45Z giles $
********************************************************************/
#ifndef _OS_TYPES_H
#define _OS_TYPES_H
/* make it easy on the folks that want to compile the libs with a
different malloc than stdlib */
#define _ogg_malloc malloc
#define _ogg_calloc calloc
#define _ogg_realloc realloc
#define _ogg_free free
#if defined(_WIN32)
# if defined(__CYGWIN__)
# include <stdint.h>
typedef int16_t ogg_int16_t;
typedef uint16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
typedef uint64_t ogg_uint64_t;
# elif defined(__MINGW32__)
# include <sys/types.h>
typedef short ogg_int16_t;
typedef unsigned short ogg_uint16_t;
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long ogg_int64_t;
typedef unsigned long long ogg_uint64_t;
# elif defined(__MWERKS__)
typedef long long ogg_int64_t;
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef short ogg_int16_t;
typedef unsigned short ogg_uint16_t;
# else
/* MSVC/Borland */
typedef __int64 ogg_int64_t;
typedef __int32 ogg_int32_t;
typedef unsigned __int32 ogg_uint32_t;
typedef __int16 ogg_int16_t;
typedef unsigned __int16 ogg_uint16_t;
# endif
#elif defined(__MACOS__)
# include <sys/types.h>
typedef SInt16 ogg_int16_t;
typedef UInt16 ogg_uint16_t;
typedef SInt32 ogg_int32_t;
typedef UInt32 ogg_uint32_t;
typedef SInt64 ogg_int64_t;
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
# include <inttypes.h>
typedef int16_t ogg_int16_t;
typedef uint16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
#elif defined(__HAIKU__)
/* Haiku */
# include <sys/types.h>
typedef short ogg_int16_t;
typedef unsigned short ogg_uint16_t;
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long ogg_int64_t;
#elif defined(__BEOS__)
/* Be */
# include <inttypes.h>
typedef int16_t ogg_int16_t;
typedef uint16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
#elif defined (__EMX__)
/* OS/2 GCC */
typedef short ogg_int16_t;
typedef unsigned short ogg_uint16_t;
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long ogg_int64_t;
#elif defined (DJGPP)
/* DJGPP */
typedef short ogg_int16_t;
typedef int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long ogg_int64_t;
#elif defined(R5900)
/* PS2 EE */
typedef long ogg_int64_t;
typedef int ogg_int32_t;
typedef unsigned ogg_uint32_t;
typedef short ogg_int16_t;
#elif defined(__SYMBIAN32__)
/* Symbian GCC */
typedef signed short ogg_int16_t;
typedef unsigned short ogg_uint16_t;
typedef signed int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long int ogg_int64_t;
#elif defined(__TMS320C6X__)
/* TI C64x compiler */
typedef signed short ogg_int16_t;
typedef unsigned short ogg_uint16_t;
typedef signed int ogg_int32_t;
typedef unsigned int ogg_uint32_t;
typedef long long int ogg_int64_t;
#else
# include <ogg/config_types.h>
#endif
#endif /* _OS_TYPES_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,243 @@
/********************************************************************
* *
* 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/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

@ -0,0 +1,436 @@
/********************************************************************
* *
* 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: vorbis encode-engine setup
last mod: $Id: vorbisenc.h 17021 2010-03-24 09:29:41Z xiphmont $
********************************************************************/
/** \file
* Libvorbisenc is a convenient API for setting up an encoding
* environment using libvorbis. Libvorbisenc encapsulates the
* actions needed to set up the encoder properly.
*/
#ifndef _OV_ENC_H_
#define _OV_ENC_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#include "codec.h"
/**
* This is the primary function within libvorbisenc for setting up managed
* bitrate modes.
*
* Before this function is called, the \ref vorbis_info
* struct should be initialized by using vorbis_info_init() from the libvorbis
* API. After encoding, vorbis_info_clear() should be called.
*
* The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set
* constraints for the encoded file. This function uses these settings to
* select the appropriate encoding mode and set it up.
*
* \param vi Pointer to an initialized \ref vorbis_info struct.
* \param channels The number of channels to be encoded.
* \param rate The sampling rate of the source audio.
* \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset.
* \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset.
* \param min_bitrate Desired minimum bitrate. -1 indicates unset.
*
* \return Zero for success, and negative values for failure.
*
* \retval 0 Success.
* \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
* \retval OV_EINVAL Invalid setup request, eg, out of range argument.
* \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request.
*/
extern int vorbis_encode_init(vorbis_info *vi,
long channels,
long rate,
long max_bitrate,
long nominal_bitrate,
long min_bitrate);
/**
* This function performs step-one of a three-step bitrate-managed encode
* setup. It functions similarly to the one-step setup performed by \ref
* vorbis_encode_init but allows an application to make further encode setup
* tweaks using \ref vorbis_encode_ctl before finally calling \ref
* vorbis_encode_setup_init to complete the setup process.
*
* Before this function is called, the \ref vorbis_info struct should be
* initialized by using vorbis_info_init() from the libvorbis API. After
* encoding, vorbis_info_clear() should be called.
*
* The max_bitrate, nominal_bitrate, and min_bitrate settings are used to set
* constraints for the encoded file. This function uses these settings to
* select the appropriate encoding mode and set it up.
*
* \param vi Pointer to an initialized vorbis_info struct.
* \param channels The number of channels to be encoded.
* \param rate The sampling rate of the source audio.
* \param max_bitrate Desired maximum bitrate (limit). -1 indicates unset.
* \param nominal_bitrate Desired average, or central, bitrate. -1 indicates unset.
* \param min_bitrate Desired minimum bitrate. -1 indicates unset.
*
* \return Zero for success, and negative for failure.
*
* \retval 0 Success
* \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
* \retval OV_EINVAL Invalid setup request, eg, out of range argument.
* \retval OV_EIMPL Unimplemented mode; unable to comply with bitrate request.
*/
extern int vorbis_encode_setup_managed(vorbis_info *vi,
long channels,
long rate,
long max_bitrate,
long nominal_bitrate,
long min_bitrate);
/**
* This function performs step-one of a three-step variable bitrate
* (quality-based) encode setup. It functions similarly to the one-step setup
* performed by \ref vorbis_encode_init_vbr() but allows an application to
* make further encode setup tweaks using \ref vorbis_encode_ctl() before
* finally calling \ref vorbis_encode_setup_init to complete the setup
* process.
*
* Before this function is called, the \ref vorbis_info struct should be
* initialized by using \ref vorbis_info_init() from the libvorbis API. After
* encoding, vorbis_info_clear() should be called.
*
* \param vi Pointer to an initialized vorbis_info struct.
* \param channels The number of channels to be encoded.
* \param rate The sampling rate of the source audio.
* \param quality Desired quality level, currently from -0.1 to 1.0 (lo to hi).
*
* \return Zero for success, and negative values for failure.
*
* \retval 0 Success
* \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
* \retval OV_EINVAL Invalid setup request, eg, out of range argument.
* \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request.
*/
extern int vorbis_encode_setup_vbr(vorbis_info *vi,
long channels,
long rate,
float quality
);
/**
* This is the primary function within libvorbisenc for setting up variable
* bitrate ("quality" based) modes.
*
*
* Before this function is called, the vorbis_info struct should be
* initialized by using vorbis_info_init() from the libvorbis API. After
* encoding, vorbis_info_clear() should be called.
*
* \param vi Pointer to an initialized vorbis_info struct.
* \param channels The number of channels to be encoded.
* \param rate The sampling rate of the source audio.
* \param base_quality Desired quality level, currently from -0.1 to 1.0 (lo to hi).
*
*
* \return Zero for success, or a negative number for failure.
*
* \retval 0 Success
* \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
* \retval OV_EINVAL Invalid setup request, eg, out of range argument.
* \retval OV_EIMPL Unimplemented mode; unable to comply with quality level request.
*/
extern int vorbis_encode_init_vbr(vorbis_info *vi,
long channels,
long rate,
float base_quality
);
/**
* This function performs the last stage of three-step encoding setup, as
* described in the API overview under managed bitrate modes.
*
* Before this function is called, the \ref vorbis_info struct should be
* initialized by using vorbis_info_init() from the libvorbis API, one of
* \ref vorbis_encode_setup_managed() or \ref vorbis_encode_setup_vbr() called to
* initialize the high-level encoding setup, and \ref vorbis_encode_ctl()
* called if necessary to make encoding setup changes.
* vorbis_encode_setup_init() finalizes the highlevel encoding structure into
* a complete encoding setup after which the application may make no further
* setup changes.
*
* After encoding, vorbis_info_clear() should be called.
*
* \param vi Pointer to an initialized \ref vorbis_info struct.
*
* \return Zero for success, and negative values for failure.
*
* \retval 0 Success.
* \retval OV_EFAULT Internal logic fault; indicates a bug or heap/stack corruption.
*
* \retval OV_EINVAL Attempt to use vorbis_encode_setup_init() without first
* calling one of vorbis_encode_setup_managed() or vorbis_encode_setup_vbr() to
* initialize the high-level encoding setup
*
*/
extern int vorbis_encode_setup_init(vorbis_info *vi);
/**
* This function implements a generic interface to miscellaneous encoder
* settings similar to the classic UNIX 'ioctl()' system call. Applications
* may use vorbis_encode_ctl() to query or set bitrate management or quality
* mode details by using one of several \e request arguments detailed below.
* vorbis_encode_ctl() must be called after one of
* vorbis_encode_setup_managed() or vorbis_encode_setup_vbr(). When used
* to modify settings, \ref vorbis_encode_ctl() must be called before \ref
* vorbis_encode_setup_init().
*
* \param vi Pointer to an initialized vorbis_info struct.
*
* \param number Specifies the desired action; See \ref encctlcodes "the list
* of available requests".
*
* \param arg void * pointing to a data structure matching the request
* argument.
*
* \retval 0 Success. Any further return information (such as the result of a
* query) is placed into the storage pointed to by *arg.
*
* \retval OV_EINVAL Invalid argument, or an attempt to modify a setting after
* calling vorbis_encode_setup_init().
*
* \retval OV_EIMPL Unimplemented or unknown request
*/
extern int vorbis_encode_ctl(vorbis_info *vi,int number,void *arg);
/**
* \deprecated This is a deprecated interface. Please use vorbis_encode_ctl()
* with the \ref ovectl_ratemanage2_arg struct and \ref
* OV_ECTL_RATEMANAGE2_GET and \ref OV_ECTL_RATEMANAGE2_SET calls in new code.
*
* The \ref ovectl_ratemanage_arg structure is used with vorbis_encode_ctl()
* and the \ref OV_ECTL_RATEMANAGE_GET, \ref OV_ECTL_RATEMANAGE_SET, \ref
* OV_ECTL_RATEMANAGE_AVG, \ref OV_ECTL_RATEMANAGE_HARD calls in order to
* query and modify specifics of the encoder's bitrate management
* configuration.
*/
struct ovectl_ratemanage_arg {
int management_active; /**< nonzero if bitrate management is active*/
/** hard lower limit (in kilobits per second) below which the stream bitrate
will never be allowed for any given bitrate_hard_window seconds of time.*/
long bitrate_hard_min;
/** hard upper limit (in kilobits per second) above which the stream bitrate
will never be allowed for any given bitrate_hard_window seconds of time.*/
long bitrate_hard_max;
/** the window period (in seconds) used to regulate the hard bitrate minimum
and maximum*/
double bitrate_hard_window;
/** soft lower limit (in kilobits per second) below which the average bitrate
tracker will start nudging the bitrate higher.*/
long bitrate_av_lo;
/** soft upper limit (in kilobits per second) above which the average bitrate
tracker will start nudging the bitrate lower.*/
long bitrate_av_hi;
/** the window period (in seconds) used to regulate the average bitrate
minimum and maximum.*/
double bitrate_av_window;
/** Regulates the relative centering of the average and hard windows; in
libvorbis 1.0 and 1.0.1, the hard window regulation overlapped but
followed the average window regulation. In libvorbis 1.1 a bit-reservoir
interface replaces the old windowing interface; the older windowing
interface is simulated and this field has no effect.*/
double bitrate_av_window_center;
};
/**
* \name struct ovectl_ratemanage2_arg
*
* The ovectl_ratemanage2_arg structure is used with vorbis_encode_ctl() and
* the OV_ECTL_RATEMANAGE2_GET and OV_ECTL_RATEMANAGE2_SET calls in order to
* query and modify specifics of the encoder's bitrate management
* configuration.
*
*/
struct ovectl_ratemanage2_arg {
int management_active; /**< nonzero if bitrate management is active */
/** Lower allowed bitrate limit in kilobits per second */
long bitrate_limit_min_kbps;
/** Upper allowed bitrate limit in kilobits per second */
long bitrate_limit_max_kbps;
long bitrate_limit_reservoir_bits; /**<Size of the bitrate reservoir in bits */
/** Regulates the bitrate reservoir's preferred fill level in a range from 0.0
* to 1.0; 0.0 tries to bank bits to buffer against future bitrate spikes, 1.0
* buffers against future sudden drops in instantaneous bitrate. Default is
* 0.1
*/
double bitrate_limit_reservoir_bias;
/** Average bitrate setting in kilobits per second */
long bitrate_average_kbps;
/** Slew rate limit setting for average bitrate adjustment; sets the minimum
* time in seconds the bitrate tracker may swing from one extreme to the
* other when boosting or damping average bitrate.
*/
double bitrate_average_damping;
};
/**
* \name vorbis_encode_ctl() codes
*
* \anchor encctlcodes
*
* These values are passed as the \c number parameter of vorbis_encode_ctl().
* The type of the referent of that function's \c arg pointer depends on these
* codes.
*/
/*@{*/
/**
* Query the current encoder bitrate management setting.
*
*Argument: <tt>struct ovectl_ratemanage2_arg *</tt>
*
* Used to query the current encoder bitrate management setting. Also used to
* initialize fields of an ovectl_ratemanage2_arg structure for use with
* \ref OV_ECTL_RATEMANAGE2_SET.
*/
#define OV_ECTL_RATEMANAGE2_GET 0x14
/**
* Set the current encoder bitrate management settings.
*
* Argument: <tt>struct ovectl_ratemanage2_arg *</tt>
*
* Used to set the current encoder bitrate management settings to the values
* listed in the ovectl_ratemanage2_arg. Passing a NULL pointer will disable
* bitrate management.
*/
#define OV_ECTL_RATEMANAGE2_SET 0x15
/**
* Returns the current encoder hard-lowpass setting (kHz) in the double
* pointed to by arg.
*
* Argument: <tt>double *</tt>
*/
#define OV_ECTL_LOWPASS_GET 0x20
/**
* Sets the encoder hard-lowpass to the value (kHz) pointed to by arg. Valid
* lowpass settings range from 2 to 99.
*
* Argument: <tt>double *</tt>
*/
#define OV_ECTL_LOWPASS_SET 0x21
/**
* Returns the current encoder impulse block setting in the double pointed
* to by arg.
*
* Argument: <tt>double *</tt>
*/
#define OV_ECTL_IBLOCK_GET 0x30
/**
* Sets the impulse block bias to the the value pointed to by arg.
*
* Argument: <tt>double *</tt>
*
* Valid range is -15.0 to 0.0 [default]. A negative impulse block bias will
* direct to encoder to use more bits when incoding short blocks that contain
* strong impulses, thus improving the accuracy of impulse encoding.
*/
#define OV_ECTL_IBLOCK_SET 0x31
/**
* Returns the current encoder coupling setting in the int pointed
* to by arg.
*
* Argument: <tt>int *</tt>
*/
#define OV_ECTL_COUPLING_GET 0x40
/**
* Enables/disables channel coupling in multichannel encoding according to arg.
*
* Argument: <tt>int *</tt>
*
* Zero disables channel coupling for multichannel inputs, nonzer enables
* channel coupling. Setting has no effect on monophonic encoding or
* multichannel counts that do not offer coupling. At present, coupling is
* available for stereo and 5.1 encoding.
*/
#define OV_ECTL_COUPLING_SET 0x41
/* deprecated rate management supported only for compatibility */
/**
* Old interface to querying bitrate management settings.
*
* Deprecated after move to bit-reservoir style management in 1.1 rendered
* this interface partially obsolete.
* \deprecated Please use \ref OV_ECTL_RATEMANAGE2_GET instead.
*
* Argument: <tt>struct ovectl_ratemanage_arg *</tt>
*/
#define OV_ECTL_RATEMANAGE_GET 0x10
/**
* Old interface to modifying bitrate management settings.
*
* deprecated after move to bit-reservoir style management in 1.1 rendered
* this interface partially obsolete.
*
* \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
*
* Argument: <tt>struct ovectl_ratemanage_arg *</tt>
*/
#define OV_ECTL_RATEMANAGE_SET 0x11
/**
* Old interface to setting average-bitrate encoding mode.
*
* Deprecated after move to bit-reservoir style management in 1.1 rendered
* this interface partially obsolete.
*
* \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
*
* Argument: <tt>struct ovectl_ratemanage_arg *</tt>
*/
#define OV_ECTL_RATEMANAGE_AVG 0x12
/**
* Old interface to setting bounded-bitrate encoding modes.
*
* deprecated after move to bit-reservoir style management in 1.1 rendered
* this interface partially obsolete.
*
* \deprecated Please use \ref OV_ECTL_RATEMANAGE2_SET instead.
*
* Argument: <tt>struct ovectl_ratemanage_arg *</tt>
*/
#define OV_ECTL_RATEMANAGE_HARD 0x13
/*@}*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

@ -0,0 +1,206 @@
/********************************************************************
* *
* 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: stdio-based convenience library for opening/seeking/decoding
last mod: $Id: vorbisfile.h 17182 2010-04-29 03:48:32Z xiphmont $
********************************************************************/
#ifndef _OV_FILE_H_
#define _OV_FILE_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#include <stdio.h>
#include "codec.h"
/* The function prototypes for the callbacks are basically the same as for
* the stdio functions fread, fseek, fclose, ftell.
* The one difference is that the FILE * arguments have been replaced with
* a void * - this is to be used as a pointer to whatever internal data these
* functions might need. In the stdio case, it's just a FILE * cast to a void *
*
* If you use other functions, check the docs for these functions and return
* the right values. For seek_func(), you *MUST* return -1 if the stream is
* unseekable
*/
typedef struct {
size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource);
int (*seek_func) (void *datasource, ogg_int64_t offset, int whence);
int (*close_func) (void *datasource);
long (*tell_func) (void *datasource);
} ov_callbacks;
#ifndef OV_EXCLUDE_STATIC_CALLBACKS
/* a few sets of convenient callbacks, especially for use under
* Windows where ov_open_callbacks() should always be used instead of
* ov_open() to avoid problems with incompatible crt.o version linking
* issues. */
static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){
if(f==NULL)return(-1);
#ifdef __MINGW32__
return fseeko64(f,off,whence);
#elif defined (_WIN32)
return _fseeki64(f,off,whence);
#else
return fseek(f,off,whence);
#endif
}
/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as
* static data. That means that every file which includes this header
* will get its own copy of these structs whether it uses them or
* not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS.
* These static symbols are essential on platforms such as Windows on
* which several different versions of stdio support may be linked to
* by different DLLs, and we need to be certain we know which one
* we're using (the same one as the main application).
*/
static ov_callbacks OV_CALLBACKS_DEFAULT = {
(size_t (*)(void *, size_t, size_t, void *)) fread,
(int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap,
(int (*)(void *)) fclose,
(long (*)(void *)) ftell
};
static ov_callbacks OV_CALLBACKS_NOCLOSE = {
(size_t (*)(void *, size_t, size_t, void *)) fread,
(int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap,
(int (*)(void *)) NULL,
(long (*)(void *)) ftell
};
static ov_callbacks OV_CALLBACKS_STREAMONLY = {
(size_t (*)(void *, size_t, size_t, void *)) fread,
(int (*)(void *, ogg_int64_t, int)) NULL,
(int (*)(void *)) fclose,
(long (*)(void *)) NULL
};
static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = {
(size_t (*)(void *, size_t, size_t, void *)) fread,
(int (*)(void *, ogg_int64_t, int)) NULL,
(int (*)(void *)) NULL,
(long (*)(void *)) NULL
};
#endif
#define NOTOPEN 0
#define PARTOPEN 1
#define OPENED 2
#define STREAMSET 3
#define INITSET 4
typedef struct OggVorbis_File {
void *datasource; /* Pointer to a FILE *, etc. */
int seekable;
ogg_int64_t offset;
ogg_int64_t end;
ogg_sync_state oy;
/* If the FILE handle isn't seekable (eg, a pipe), only the current
stream appears */
int links;
ogg_int64_t *offsets;
ogg_int64_t *dataoffsets;
long *serialnos;
ogg_int64_t *pcmlengths; /* overloaded to maintain binary
compatibility; x2 size, stores both
beginning and end values */
vorbis_info *vi;
vorbis_comment *vc;
/* Decoding working state local storage */
ogg_int64_t pcm_offset;
int ready_state;
long current_serialno;
int current_link;
double bittrack;
double samptrack;
ogg_stream_state os; /* take physical pages, weld into a logical
stream of packets */
vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
vorbis_block vb; /* local working space for packet->PCM decode */
ov_callbacks callbacks;
} OggVorbis_File;
extern int ov_clear(OggVorbis_File *vf);
extern int ov_fopen(const char *path,OggVorbis_File *vf);
extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
const char *initial, long ibytes, ov_callbacks callbacks);
extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
const char *initial, long ibytes, ov_callbacks callbacks);
extern int ov_test_open(OggVorbis_File *vf);
extern long ov_bitrate(OggVorbis_File *vf,int i);
extern long ov_bitrate_instant(OggVorbis_File *vf);
extern long ov_streams(OggVorbis_File *vf);
extern long ov_seekable(OggVorbis_File *vf);
extern long ov_serialnumber(OggVorbis_File *vf,int i);
extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i);
extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i);
extern double ov_time_total(OggVorbis_File *vf,int i);
extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos);
extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos);
extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos);
extern int ov_time_seek(OggVorbis_File *vf,double pos);
extern int ov_time_seek_page(OggVorbis_File *vf,double pos);
extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos);
extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos);
extern int ov_time_seek_lap(OggVorbis_File *vf,double pos);
extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos);
extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf);
extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf);
extern double ov_time_tell(OggVorbis_File *vf);
extern vorbis_info *ov_info(OggVorbis_File *vf,int link);
extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples,
int *bitstream);
extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
int bigendianp,int word,int sgned,int *bitstream,
void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param);
extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
int bigendianp,int word,int sgned,int *bitstream);
extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2);
extern int ov_halfrate(OggVorbis_File *vf,int flag);
extern int ov_halfrate_p(OggVorbis_File *vf);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif

@ -0,0 +1,120 @@
/********************************************************************
* *
* 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/ogg.h>
#include "vorbis/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=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

@ -0,0 +1,144 @@
/********************************************************************
* *
* 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 **(*class) (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

@ -0,0 +1,64 @@
/********************************************************************
* *
* 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: bark scale utility
last mod: $Id: barkmel.c 19454 2015-03-02 22:39:28Z xiphmont $
********************************************************************/
#include <stdio.h>
#include "scales.h"
int main(){
int i;
double rate;
for(i=64;i<32000;i*=2){
rate=48000.f;
fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
rate=44100.f;
fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
rate=32000.f;
fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
rate=22050.f;
fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
rate=16000.f;
fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
rate=11025.f;
fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n",
rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
rate=8000.f;
fprintf(stderr,"rate=%gHz, block=%d, f(1)=%.2gHz bark(1)=%.2g (of %.2g)\n\n",
rate,i,rate/2 / (i/2),toBARK(rate/2 /(i/2)),toBARK(rate/2));
}
{
float i;
int j;
for(i=0.,j=0;i<28;i+=1,j++){
fprintf(stderr,"(%d) bark=%f %gHz (%d of 128)\n",
j,i,fromBARK(i),(int)(fromBARK(i)/22050.*128.));
}
}
return(0);
}

@ -0,0 +1,253 @@
/********************************************************************
* *
* 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/ogg.h>
#include "vorbis/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=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= rint(1.*bi->avg_rate*halfsamples/ratesamples);
bm->min_bitsper= rint(1.*bi->min_rate*halfsamples/ratesamples);
bm->max_bitsper= 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=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=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=vb->internal;
vorbis_dsp_state *vd=vb->vd;
private_state *b=vd->backend_state;
bitrate_manager_state *bm=&b->bms;
vorbis_info *vi=vd->vi;
codec_setup_info *ci=vi->codec_setup;
bitrate_manager_info *bi=&ci->bi;
int choice=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=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=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=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=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);
}

@ -0,0 +1,59 @@
/********************************************************************
* *
* 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 "vorbis/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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,490 @@
/********************************************************************
* *
* 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-2015 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: basic codebook pack/unpack/code/decode operations
last mod: $Id: codebook.c 19457 2015-03-03 00:15:29Z giles $
********************************************************************/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ogg/ogg.h>
#include "vorbis/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++){
char this=c->lengthlist[i];
char last=c->lengthlist[i-1];
if(this>last){
for(j=last;j<this;j++){
oggpack_write(opb,i-count,ov_ilog(c->entries-count));
count=i;
}
}
}
oggpack_write(opb,i-count,ov_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=_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(ov_ilog(s->dim)+ov_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=_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=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
for(i=0;i<s->entries;){
long num=oggpack_read(opb,ov_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=_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;
}
/* Single entry codebooks use a firsttablen of 1 and a
dec_maxlength of 1. If a single-entry codebook gets here (due to
failure to read one bit above), the next look attempt will also
fail and we'll correctly kick out instead of trying to walk the
underformed tree */
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 *************************************/
/* decode vector / dim granularity gaurding is done in the upper layer */
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 = alloca(sizeof(*entry)*step);
float **t = 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);
}
/* decode vector / dim granularity gaurding is done in the upper layer */
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);
}
/* unlike the others, we guard against n not being an integer number
of <dim> internally rather than in the upper layer (called only by
floor0) */
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;i<n && j<book->dim;){
a[i++]=t[j++];
}
}
}else{
int i;
for(i=0;i<n;){
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);
}

@ -0,0 +1,118 @@
/********************************************************************
* *
* 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-2015 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: basic shared codebook operations
last mod: $Id: codebook.h 19457 2015-03-03 00:15:29Z giles $
********************************************************************/
#ifndef _V_CODEBOOK_H_
#define _V_CODEBOOK_H_
#include <ogg/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 */
char *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 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

@ -0,0 +1,167 @@
/********************************************************************
* *
* 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"
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

@ -0,0 +1,375 @@
/********************************************************************
* *
* 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/ogg.h>
#include "vorbis/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=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=_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=_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=_ogg_calloc(VE_BANDS*ch,sizeof(*e->filter));
e->mark=_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=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,this=filters[j].ampptr;
float postmax,postmin,premax=-99999.f,premin=99999.f;
p=this;
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[this]=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=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=_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=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=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;
}

@ -0,0 +1,80 @@
/********************************************************************
* *
* 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;
vbs_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

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save