diff --git a/CMakeLists.txt b/CMakeLists.txt index e80bc3171..80d794a05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,7 +241,7 @@ if( MSVC ) # Most of these need to be cleaned out. The source is currently infested with far too much conditional compilation which is a constant source of problems. - set( ALL_C_FLAGS "${ALL_C_FLAGS} /DRENDERTYPESDL=1 /DMIXERTYPEWIN=1 /DSDL_USEFOLDER /DSDL_TARGET=2 /DUSE_OPENGL=1 /DSTARTUP_WINDOW /DUSE_LIBVPX /DHAVE_VORBIS /DHAVE_XMP /DNOASM=1 /DWIN32 /DLIBXMP_CORE_PLAYER" ) + set( ALL_C_FLAGS "${ALL_C_FLAGS} /DRENDERTYPESDL=1 /DMIXERTYPEWIN=1 /DSDL_USEFOLDER /DSDL_TARGET=2 /DUSE_OPENGL=1 /DSTARTUP_WINDOW /DUSE_LIBVPX /DNOASM=1 /DWIN32" ) # The CMake configurations set /GR and /MD by default, which conflict with our settings. string(REPLACE "/MD " " " CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} ) diff --git a/platform/Windows/include/FLAC/all.h b/platform/Windows/include/FLAC/all.h deleted file mode 100644 index 9e288528b..000000000 --- a/platform/Windows/include/FLAC/all.h +++ /dev/null @@ -1,371 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 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 - * here. - * - * \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 Xiph's BSD license. - * 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 - * Xiph's BSD license. - * - * \section getting_started Getting Started - * - * A good starting point for learning the API is to browse through - * the modules. 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 - * example code. - * - * \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' - * libtool version numbers, - * 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 diff --git a/platform/Windows/include/FLAC/assert.h b/platform/Windows/include/FLAC/assert.h deleted file mode 100644 index 787cea913..000000000 --- a/platform/Windows/include/FLAC/assert.h +++ /dev/null @@ -1,46 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 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 -#define FLAC__ASSERT(x) assert(x) -#define FLAC__ASSERT_DECLARATION(x) x -#else -#define FLAC__ASSERT(x) -#define FLAC__ASSERT_DECLARATION(x) -#endif - -#endif diff --git a/platform/Windows/include/FLAC/callback.h b/platform/Windows/include/FLAC/callback.h deleted file mode 100644 index 71bbaec6d..000000000 --- a/platform/Windows/include/FLAC/callback.h +++ /dev/null @@ -1,185 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2013 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 /* 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 diff --git a/platform/Windows/include/FLAC/export.h b/platform/Windows/include/FLAC/export.h deleted file mode 100644 index 2232b410b..000000000 --- a/platform/Windows/include/FLAC/export.h +++ /dev/null @@ -1,97 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 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 diff --git a/platform/Windows/include/FLAC/format.h b/platform/Windows/include/FLAC/format.h deleted file mode 100644 index e4c1c1a61..000000000 --- a/platform/Windows/include/FLAC/format.h +++ /dev/null @@ -1,1023 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 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__FORMAT_H -#define FLAC__FORMAT_H - -#include "export.h" -#include "ordinals.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** \file include/FLAC/format.h - * - * \brief - * This module contains structure definitions for the representation - * of FLAC format components in memory. These are the basic - * structures used by the rest of the interfaces. - * - * See the detailed documentation in the - * \link flac_format format \endlink module. - */ - -/** \defgroup flac_format FLAC/format.h: format components - * \ingroup flac - * - * \brief - * This module contains structure definitions for the representation - * of FLAC format components in memory. These are the basic - * structures used by the rest of the interfaces. - * - * First, you should be familiar with the - * FLAC format. Many of the values here - * follow directly from the specification. As a user of libFLAC, the - * interesting parts really are the structures that describe the frame - * header and metadata blocks. - * - * The format structures here are very primitive, designed to store - * information in an efficient way. Reading information from the - * structures is easy but creating or modifying them directly is - * more complex. For the most part, as a user of a library, editing - * is not necessary; however, for metadata blocks it is, so there are - * convenience functions provided in the \link flac_metadata metadata - * module \endlink to simplify the manipulation of metadata blocks. - * - * \note - * It's not the best convention, but symbols ending in _LEN are in bits - * and _LENGTH are in bytes. _LENGTH symbols are \#defines instead of - * global variables because they are usually used when declaring byte - * arrays and some compilers require compile-time knowledge of array - * sizes when declared on the stack. - * - * \{ - */ - - -/* - Most of the values described in this file are defined by the FLAC - format specification. There is nothing to tune here. -*/ - -/** The largest legal metadata type code. */ -#define FLAC__MAX_METADATA_TYPE_CODE (126u) - -/** The minimum block size, in samples, permitted by the format. */ -#define FLAC__MIN_BLOCK_SIZE (16u) - -/** The maximum block size, in samples, permitted by the format. */ -#define FLAC__MAX_BLOCK_SIZE (65535u) - -/** The maximum block size, in samples, permitted by the FLAC subset for - * sample rates up to 48kHz. */ -#define FLAC__SUBSET_MAX_BLOCK_SIZE_48000HZ (4608u) - -/** The maximum number of channels permitted by the format. */ -#define FLAC__MAX_CHANNELS (8u) - -/** The minimum sample resolution permitted by the format. */ -#define FLAC__MIN_BITS_PER_SAMPLE (4u) - -/** The maximum sample resolution permitted by the format. */ -#define FLAC__MAX_BITS_PER_SAMPLE (32u) - -/** The maximum sample resolution permitted by libFLAC. - * - * \warning - * FLAC__MAX_BITS_PER_SAMPLE is the limit of the FLAC format. However, - * the reference encoder/decoder is currently limited to 24 bits because - * of prevalent 32-bit math, so make sure and use this value when - * appropriate. - */ -#define FLAC__REFERENCE_CODEC_MAX_BITS_PER_SAMPLE (24u) - -/** The maximum sample rate permitted by the format. The value is - * ((2 ^ 16) - 1) * 10; see FLAC format - * as to why. - */ -#define FLAC__MAX_SAMPLE_RATE (655350u) - -/** The maximum LPC order permitted by the format. */ -#define FLAC__MAX_LPC_ORDER (32u) - -/** The maximum LPC order permitted by the FLAC subset for sample rates - * up to 48kHz. */ -#define FLAC__SUBSET_MAX_LPC_ORDER_48000HZ (12u) - -/** The minimum quantized linear predictor coefficient precision - * permitted by the format. - */ -#define FLAC__MIN_QLP_COEFF_PRECISION (5u) - -/** The maximum quantized linear predictor coefficient precision - * permitted by the format. - */ -#define FLAC__MAX_QLP_COEFF_PRECISION (15u) - -/** The maximum order of the fixed predictors permitted by the format. */ -#define FLAC__MAX_FIXED_ORDER (4u) - -/** The maximum Rice partition order permitted by the format. */ -#define FLAC__MAX_RICE_PARTITION_ORDER (15u) - -/** The maximum Rice partition order permitted by the FLAC Subset. */ -#define FLAC__SUBSET_MAX_RICE_PARTITION_ORDER (8u) - -/** The version string of the release, stamped onto the libraries and binaries. - * - * \note - * This does not correspond to the shared library version number, which - * is used to determine binary compatibility. - */ -extern FLAC_API const char *FLAC__VERSION_STRING; - -/** The vendor string inserted by the encoder into the VORBIS_COMMENT block. - * This is a NUL-terminated ASCII string; when inserted into the - * VORBIS_COMMENT the trailing null is stripped. - */ -extern FLAC_API const char *FLAC__VENDOR_STRING; - -/** The byte string representation of the beginning of a FLAC stream. */ -extern FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4]; /* = "fLaC" */ - -/** The 32-bit integer big-endian representation of the beginning of - * a FLAC stream. - */ -extern FLAC_API const unsigned FLAC__STREAM_SYNC; /* = 0x664C6143 */ - -/** The length of the FLAC signature in bits. */ -extern FLAC_API const unsigned FLAC__STREAM_SYNC_LEN; /* = 32 bits */ - -/** The length of the FLAC signature in bytes. */ -#define FLAC__STREAM_SYNC_LENGTH (4u) - - -/***************************************************************************** - * - * Subframe structures - * - *****************************************************************************/ - -/*****************************************************************************/ - -/** An enumeration of the available entropy coding methods. */ -typedef enum { - FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE = 0, - /**< Residual is coded by partitioning into contexts, each with it's own - * 4-bit Rice parameter. */ - - FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2 = 1 - /**< Residual is coded by partitioning into contexts, each with it's own - * 5-bit Rice parameter. */ -} FLAC__EntropyCodingMethodType; - -/** Maps a FLAC__EntropyCodingMethodType to a C string. - * - * Using a FLAC__EntropyCodingMethodType as the index to this array will - * give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__EntropyCodingMethodTypeString[]; - - -/** Contents of a Rice partitioned residual - */ -typedef struct { - - unsigned *parameters; - /**< The Rice parameters for each context. */ - - unsigned *raw_bits; - /**< Widths for escape-coded partitions. Will be non-zero for escaped - * partitions and zero for unescaped partitions. - */ - - unsigned capacity_by_order; - /**< The capacity of the \a parameters and \a raw_bits arrays - * specified as an order, i.e. the number of array elements - * allocated is 2 ^ \a capacity_by_order. - */ -} FLAC__EntropyCodingMethod_PartitionedRiceContents; - -/** Header for a Rice partitioned residual. (c.f. format specification) - */ -typedef struct { - - unsigned order; - /**< The partition order, i.e. # of contexts = 2 ^ \a order. */ - - const FLAC__EntropyCodingMethod_PartitionedRiceContents *contents; - /**< The context's Rice parameters and/or raw bits. */ - -} FLAC__EntropyCodingMethod_PartitionedRice; - -extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ORDER_LEN; /**< == 4 (bits) */ -extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_PARAMETER_LEN; /**< == 4 (bits) */ -extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE2_PARAMETER_LEN; /**< == 5 (bits) */ -extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_RAW_LEN; /**< == 5 (bits) */ - -extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_PARTITIONED_RICE_ESCAPE_PARAMETER; -/**< == (1<format specification) - */ -typedef struct { - FLAC__EntropyCodingMethodType type; - union { - FLAC__EntropyCodingMethod_PartitionedRice partitioned_rice; - } data; -} FLAC__EntropyCodingMethod; - -extern FLAC_API const unsigned FLAC__ENTROPY_CODING_METHOD_TYPE_LEN; /**< == 2 (bits) */ - -/*****************************************************************************/ - -/** An enumeration of the available subframe types. */ -typedef enum { - FLAC__SUBFRAME_TYPE_CONSTANT = 0, /**< constant signal */ - FLAC__SUBFRAME_TYPE_VERBATIM = 1, /**< uncompressed signal */ - FLAC__SUBFRAME_TYPE_FIXED = 2, /**< fixed polynomial prediction */ - FLAC__SUBFRAME_TYPE_LPC = 3 /**< linear prediction */ -} FLAC__SubframeType; - -/** Maps a FLAC__SubframeType to a C string. - * - * Using a FLAC__SubframeType as the index to this array will - * give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__SubframeTypeString[]; - - -/** CONSTANT subframe. (c.f. format specification) - */ -typedef struct { - FLAC__int32 value; /**< The constant signal value. */ -} FLAC__Subframe_Constant; - - -/** VERBATIM subframe. (c.f. format specification) - */ -typedef struct { - const FLAC__int32 *data; /**< A pointer to verbatim signal. */ -} FLAC__Subframe_Verbatim; - - -/** FIXED subframe. (c.f. format specification) - */ -typedef struct { - FLAC__EntropyCodingMethod entropy_coding_method; - /**< The residual coding method. */ - - unsigned order; - /**< The polynomial order. */ - - FLAC__int32 warmup[FLAC__MAX_FIXED_ORDER]; - /**< Warmup samples to prime the predictor, length == order. */ - - const FLAC__int32 *residual; - /**< The residual signal, length == (blocksize minus order) samples. */ -} FLAC__Subframe_Fixed; - - -/** LPC subframe. (c.f. format specification) - */ -typedef struct { - FLAC__EntropyCodingMethod entropy_coding_method; - /**< The residual coding method. */ - - unsigned order; - /**< The FIR order. */ - - unsigned qlp_coeff_precision; - /**< Quantized FIR filter coefficient precision in bits. */ - - int quantization_level; - /**< The qlp coeff shift needed. */ - - FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; - /**< FIR filter coefficients. */ - - FLAC__int32 warmup[FLAC__MAX_LPC_ORDER]; - /**< Warmup samples to prime the predictor, length == order. */ - - const FLAC__int32 *residual; - /**< The residual signal, length == (blocksize minus order) samples. */ -} FLAC__Subframe_LPC; - -extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_COEFF_PRECISION_LEN; /**< == 4 (bits) */ -extern FLAC_API const unsigned FLAC__SUBFRAME_LPC_QLP_SHIFT_LEN; /**< == 5 (bits) */ - - -/** FLAC subframe structure. (c.f. format specification) - */ -typedef struct { - FLAC__SubframeType type; - union { - FLAC__Subframe_Constant constant; - FLAC__Subframe_Fixed fixed; - FLAC__Subframe_LPC lpc; - FLAC__Subframe_Verbatim verbatim; - } data; - unsigned wasted_bits; -} FLAC__Subframe; - -/** == 1 (bit) - * - * This used to be a zero-padding bit (hence the name - * FLAC__SUBFRAME_ZERO_PAD_LEN) but is now a reserved bit. It still has a - * mandatory value of \c 0 but in the future may take on the value \c 0 or \c 1 - * to mean something else. - */ -extern FLAC_API const unsigned FLAC__SUBFRAME_ZERO_PAD_LEN; -extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LEN; /**< == 6 (bits) */ -extern FLAC_API const unsigned FLAC__SUBFRAME_WASTED_BITS_FLAG_LEN; /**< == 1 (bit) */ - -extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_CONSTANT_BYTE_ALIGNED_MASK; /**< = 0x00 */ -extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_VERBATIM_BYTE_ALIGNED_MASK; /**< = 0x02 */ -extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_FIXED_BYTE_ALIGNED_MASK; /**< = 0x10 */ -extern FLAC_API const unsigned FLAC__SUBFRAME_TYPE_LPC_BYTE_ALIGNED_MASK; /**< = 0x40 */ - -/*****************************************************************************/ - - -/***************************************************************************** - * - * Frame structures - * - *****************************************************************************/ - -/** An enumeration of the available channel assignments. */ -typedef enum { - FLAC__CHANNEL_ASSIGNMENT_INDEPENDENT = 0, /**< independent channels */ - FLAC__CHANNEL_ASSIGNMENT_LEFT_SIDE = 1, /**< left+side stereo */ - FLAC__CHANNEL_ASSIGNMENT_RIGHT_SIDE = 2, /**< right+side stereo */ - FLAC__CHANNEL_ASSIGNMENT_MID_SIDE = 3 /**< mid+side stereo */ -} FLAC__ChannelAssignment; - -/** Maps a FLAC__ChannelAssignment to a C string. - * - * Using a FLAC__ChannelAssignment as the index to this array will - * give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__ChannelAssignmentString[]; - -/** An enumeration of the possible frame numbering methods. */ -typedef enum { - FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER, /**< number contains the frame number */ - FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER /**< number contains the sample number of first sample in frame */ -} FLAC__FrameNumberType; - -/** Maps a FLAC__FrameNumberType to a C string. - * - * Using a FLAC__FrameNumberType as the index to this array will - * give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__FrameNumberTypeString[]; - - -/** FLAC frame header structure. (c.f. format specification) - */ -typedef struct { - unsigned blocksize; - /**< The number of samples per subframe. */ - - unsigned sample_rate; - /**< The sample rate in Hz. */ - - unsigned channels; - /**< The number of channels (== number of subframes). */ - - FLAC__ChannelAssignment channel_assignment; - /**< The channel assignment for the frame. */ - - unsigned bits_per_sample; - /**< The sample resolution. */ - - FLAC__FrameNumberType number_type; - /**< The numbering scheme used for the frame. As a convenience, the - * decoder will always convert a frame number to a sample number because - * the rules are complex. */ - - union { - FLAC__uint32 frame_number; - FLAC__uint64 sample_number; - } number; - /**< The frame number or sample number of first sample in frame; - * use the \a number_type value to determine which to use. */ - - FLAC__uint8 crc; - /**< CRC-8 (polynomial = x^8 + x^2 + x^1 + x^0, initialized with 0) - * of the raw frame header bytes, meaning everything before the CRC byte - * including the sync code. - */ -} FLAC__FrameHeader; - -extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC; /**< == 0x3ffe; the frame header sync code */ -extern FLAC_API const unsigned FLAC__FRAME_HEADER_SYNC_LEN; /**< == 14 (bits) */ -extern FLAC_API const unsigned FLAC__FRAME_HEADER_RESERVED_LEN; /**< == 1 (bits) */ -extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCKING_STRATEGY_LEN; /**< == 1 (bits) */ -extern FLAC_API const unsigned FLAC__FRAME_HEADER_BLOCK_SIZE_LEN; /**< == 4 (bits) */ -extern FLAC_API const unsigned FLAC__FRAME_HEADER_SAMPLE_RATE_LEN; /**< == 4 (bits) */ -extern FLAC_API const unsigned FLAC__FRAME_HEADER_CHANNEL_ASSIGNMENT_LEN; /**< == 4 (bits) */ -extern FLAC_API const unsigned FLAC__FRAME_HEADER_BITS_PER_SAMPLE_LEN; /**< == 3 (bits) */ -extern FLAC_API const unsigned FLAC__FRAME_HEADER_ZERO_PAD_LEN; /**< == 1 (bit) */ -extern FLAC_API const unsigned FLAC__FRAME_HEADER_CRC_LEN; /**< == 8 (bits) */ - - -/** FLAC frame footer structure. (c.f. format specification) - */ -typedef struct { - FLAC__uint16 crc; - /**< CRC-16 (polynomial = x^16 + x^15 + x^2 + x^0, initialized with - * 0) of the bytes before the crc, back to and including the frame header - * sync code. - */ -} FLAC__FrameFooter; - -extern FLAC_API const unsigned FLAC__FRAME_FOOTER_CRC_LEN; /**< == 16 (bits) */ - - -/** FLAC frame structure. (c.f. format specification) - */ -typedef struct { - FLAC__FrameHeader header; - FLAC__Subframe subframes[FLAC__MAX_CHANNELS]; - FLAC__FrameFooter footer; -} FLAC__Frame; - -/*****************************************************************************/ - - -/***************************************************************************** - * - * Meta-data structures - * - *****************************************************************************/ - -/** An enumeration of the available metadata block types. */ -typedef enum { - - FLAC__METADATA_TYPE_STREAMINFO = 0, - /**< STREAMINFO block */ - - FLAC__METADATA_TYPE_PADDING = 1, - /**< PADDING block */ - - FLAC__METADATA_TYPE_APPLICATION = 2, - /**< APPLICATION block */ - - FLAC__METADATA_TYPE_SEEKTABLE = 3, - /**< SEEKTABLE block */ - - FLAC__METADATA_TYPE_VORBIS_COMMENT = 4, - /**< VORBISCOMMENT block (a.k.a. FLAC tags) */ - - FLAC__METADATA_TYPE_CUESHEET = 5, - /**< CUESHEET block */ - - FLAC__METADATA_TYPE_PICTURE = 6, - /**< PICTURE block */ - - FLAC__METADATA_TYPE_UNDEFINED = 7 - /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ - -} FLAC__MetadataType; - -/** Maps a FLAC__MetadataType to a C string. - * - * Using a FLAC__MetadataType as the index to this array will - * give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__MetadataTypeString[]; - - -/** FLAC STREAMINFO structure. (c.f. format specification) - */ -typedef struct { - unsigned min_blocksize, max_blocksize; - unsigned min_framesize, max_framesize; - unsigned sample_rate; - unsigned channels; - unsigned bits_per_sample; - FLAC__uint64 total_samples; - FLAC__byte md5sum[16]; -} FLAC__StreamMetadata_StreamInfo; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN; /**< == 16 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN; /**< == 16 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN; /**< == 24 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN; /**< == 24 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN; /**< == 20 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN; /**< == 3 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN; /**< == 5 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN; /**< == 36 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_STREAMINFO_MD5SUM_LEN; /**< == 128 (bits) */ - -/** The total stream length of the STREAMINFO block in bytes. */ -#define FLAC__STREAM_METADATA_STREAMINFO_LENGTH (34u) - -/** FLAC PADDING structure. (c.f. format specification) - */ -typedef struct { - int dummy; - /**< Conceptually this is an empty struct since we don't store the - * padding bytes. Empty structs are not allowed by some C compilers, - * hence the dummy. - */ -} FLAC__StreamMetadata_Padding; - - -/** FLAC APPLICATION structure. (c.f. format specification) - */ -typedef struct { - FLAC__byte id[4]; - FLAC__byte *data; -} FLAC__StreamMetadata_Application; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_APPLICATION_ID_LEN; /**< == 32 (bits) */ - -/** SeekPoint structure used in SEEKTABLE blocks. (c.f. format specification) - */ -typedef struct { - FLAC__uint64 sample_number; - /**< The sample number of the target frame. */ - - FLAC__uint64 stream_offset; - /**< The offset, in bytes, of the target frame with respect to - * beginning of the first frame. */ - - unsigned frame_samples; - /**< The number of samples in the target frame. */ -} FLAC__StreamMetadata_SeekPoint; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN; /**< == 64 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN; /**< == 64 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN; /**< == 16 (bits) */ - -/** The total stream length of a seek point in bytes. */ -#define FLAC__STREAM_METADATA_SEEKPOINT_LENGTH (18u) - -/** The value used in the \a sample_number field of - * FLAC__StreamMetadataSeekPoint used to indicate a placeholder - * point (== 0xffffffffffffffff). - */ -extern FLAC_API const FLAC__uint64 FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER; - - -/** FLAC SEEKTABLE structure. (c.f. format specification) - * - * \note From the format specification: - * - The seek points must be sorted by ascending sample number. - * - Each seek point's sample number must be the first sample of the - * target frame. - * - Each seek point's sample number must be unique within the table. - * - Existence of a SEEKTABLE block implies a correct setting of - * total_samples in the stream_info block. - * - Behavior is undefined when more than one SEEKTABLE block is - * present in a stream. - */ -typedef struct { - unsigned num_points; - FLAC__StreamMetadata_SeekPoint *points; -} FLAC__StreamMetadata_SeekTable; - - -/** Vorbis comment entry structure used in VORBIS_COMMENT blocks. (c.f. format specification) - * - * For convenience, the APIs maintain a trailing NUL character at the end of - * \a entry which is not counted toward \a length, i.e. - * \code strlen(entry) == length \endcode - */ -typedef struct { - FLAC__uint32 length; - FLAC__byte *entry; -} FLAC__StreamMetadata_VorbisComment_Entry; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN; /**< == 32 (bits) */ - - -/** FLAC VORBIS_COMMENT structure. (c.f. format specification) - */ -typedef struct { - FLAC__StreamMetadata_VorbisComment_Entry vendor_string; - FLAC__uint32 num_comments; - FLAC__StreamMetadata_VorbisComment_Entry *comments; -} FLAC__StreamMetadata_VorbisComment; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN; /**< == 32 (bits) */ - - -/** FLAC CUESHEET track index structure. (See the - * format specification for - * the full description of each field.) - */ -typedef struct { - FLAC__uint64 offset; - /**< Offset in samples, relative to the track offset, of the index - * point. - */ - - FLAC__byte number; - /**< The index point number. */ -} FLAC__StreamMetadata_CueSheet_Index; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_OFFSET_LEN; /**< == 64 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_NUMBER_LEN; /**< == 8 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_INDEX_RESERVED_LEN; /**< == 3*8 (bits) */ - - -/** FLAC CUESHEET track structure. (See the - * format specification for - * the full description of each field.) - */ -typedef struct { - FLAC__uint64 offset; - /**< Track offset in samples, relative to the beginning of the FLAC audio stream. */ - - FLAC__byte number; - /**< The track number. */ - - char isrc[13]; - /**< Track ISRC. This is a 12-digit alphanumeric code plus a trailing \c NUL byte */ - - unsigned type:1; - /**< The track type: 0 for audio, 1 for non-audio. */ - - unsigned pre_emphasis:1; - /**< The pre-emphasis flag: 0 for no pre-emphasis, 1 for pre-emphasis. */ - - FLAC__byte num_indices; - /**< The number of track index points. */ - - FLAC__StreamMetadata_CueSheet_Index *indices; - /**< NULL if num_indices == 0, else pointer to array of index points. */ - -} FLAC__StreamMetadata_CueSheet_Track; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_OFFSET_LEN; /**< == 64 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUMBER_LEN; /**< == 8 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_ISRC_LEN; /**< == 12*8 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_TYPE_LEN; /**< == 1 (bit) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_PRE_EMPHASIS_LEN; /**< == 1 (bit) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_RESERVED_LEN; /**< == 6+13*8 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_TRACK_NUM_INDICES_LEN; /**< == 8 (bits) */ - - -/** FLAC CUESHEET structure. (See the - * format specification - * for the full description of each field.) - */ -typedef struct { - char media_catalog_number[129]; - /**< Media catalog number, in ASCII printable characters 0x20-0x7e. In - * general, the media catalog number may be 0 to 128 bytes long; any - * unused characters should be right-padded with NUL characters. - */ - - FLAC__uint64 lead_in; - /**< The number of lead-in samples. */ - - FLAC__bool is_cd; - /**< \c true if CUESHEET corresponds to a Compact Disc, else \c false. */ - - unsigned num_tracks; - /**< The number of tracks. */ - - FLAC__StreamMetadata_CueSheet_Track *tracks; - /**< NULL if num_tracks == 0, else pointer to array of tracks. */ - -} FLAC__StreamMetadata_CueSheet; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_MEDIA_CATALOG_NUMBER_LEN; /**< == 128*8 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_LEAD_IN_LEN; /**< == 64 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_IS_CD_LEN; /**< == 1 (bit) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_RESERVED_LEN; /**< == 7+258*8 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_CUESHEET_NUM_TRACKS_LEN; /**< == 8 (bits) */ - - -/** An enumeration of the PICTURE types (see FLAC__StreamMetadataPicture and id3 v2.4 APIC tag). */ -typedef enum { - FLAC__STREAM_METADATA_PICTURE_TYPE_OTHER = 0, /**< Other */ - FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON_STANDARD = 1, /**< 32x32 pixels 'file icon' (PNG only) */ - FLAC__STREAM_METADATA_PICTURE_TYPE_FILE_ICON = 2, /**< Other file icon */ - FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER = 3, /**< Cover (front) */ - FLAC__STREAM_METADATA_PICTURE_TYPE_BACK_COVER = 4, /**< Cover (back) */ - FLAC__STREAM_METADATA_PICTURE_TYPE_LEAFLET_PAGE = 5, /**< Leaflet page */ - FLAC__STREAM_METADATA_PICTURE_TYPE_MEDIA = 6, /**< Media (e.g. label side of CD) */ - FLAC__STREAM_METADATA_PICTURE_TYPE_LEAD_ARTIST = 7, /**< Lead artist/lead performer/soloist */ - FLAC__STREAM_METADATA_PICTURE_TYPE_ARTIST = 8, /**< Artist/performer */ - FLAC__STREAM_METADATA_PICTURE_TYPE_CONDUCTOR = 9, /**< Conductor */ - FLAC__STREAM_METADATA_PICTURE_TYPE_BAND = 10, /**< Band/Orchestra */ - FLAC__STREAM_METADATA_PICTURE_TYPE_COMPOSER = 11, /**< Composer */ - FLAC__STREAM_METADATA_PICTURE_TYPE_LYRICIST = 12, /**< Lyricist/text writer */ - FLAC__STREAM_METADATA_PICTURE_TYPE_RECORDING_LOCATION = 13, /**< Recording Location */ - FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_RECORDING = 14, /**< During recording */ - FLAC__STREAM_METADATA_PICTURE_TYPE_DURING_PERFORMANCE = 15, /**< During performance */ - FLAC__STREAM_METADATA_PICTURE_TYPE_VIDEO_SCREEN_CAPTURE = 16, /**< Movie/video screen capture */ - FLAC__STREAM_METADATA_PICTURE_TYPE_FISH = 17, /**< A bright coloured fish */ - FLAC__STREAM_METADATA_PICTURE_TYPE_ILLUSTRATION = 18, /**< Illustration */ - FLAC__STREAM_METADATA_PICTURE_TYPE_BAND_LOGOTYPE = 19, /**< Band/artist logotype */ - FLAC__STREAM_METADATA_PICTURE_TYPE_PUBLISHER_LOGOTYPE = 20, /**< Publisher/Studio logotype */ - FLAC__STREAM_METADATA_PICTURE_TYPE_UNDEFINED -} FLAC__StreamMetadata_Picture_Type; - -/** Maps a FLAC__StreamMetadata_Picture_Type to a C string. - * - * Using a FLAC__StreamMetadata_Picture_Type as the index to this array - * will give the string equivalent. The contents should not be - * modified. - */ -extern FLAC_API const char * const FLAC__StreamMetadata_Picture_TypeString[]; - -/** FLAC PICTURE structure. (See the - * format specification - * for the full description of each field.) - */ -typedef struct { - FLAC__StreamMetadata_Picture_Type type; - /**< The kind of picture stored. */ - - char *mime_type; - /**< Picture data's MIME type, in ASCII printable characters - * 0x20-0x7e, NUL terminated. For best compatibility with players, - * use picture data of MIME type \c image/jpeg or \c image/png. A - * MIME type of '-->' is also allowed, in which case the picture - * data should be a complete URL. In file storage, the MIME type is - * stored as a 32-bit length followed by the ASCII string with no NUL - * terminator, but is converted to a plain C string in this structure - * for convenience. - */ - - FLAC__byte *description; - /**< Picture's description in UTF-8, NUL terminated. In file storage, - * the description is stored as a 32-bit length followed by the UTF-8 - * string with no NUL terminator, but is converted to a plain C string - * in this structure for convenience. - */ - - FLAC__uint32 width; - /**< Picture's width in pixels. */ - - FLAC__uint32 height; - /**< Picture's height in pixels. */ - - FLAC__uint32 depth; - /**< Picture's color depth in bits-per-pixel. */ - - FLAC__uint32 colors; - /**< For indexed palettes (like GIF), picture's number of colors (the - * number of palette entries), or \c 0 for non-indexed (i.e. 2^depth). - */ - - FLAC__uint32 data_length; - /**< Length of binary picture data in bytes. */ - - FLAC__byte *data; - /**< Binary picture data. */ - -} FLAC__StreamMetadata_Picture; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_TYPE_LEN; /**< == 32 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN; /**< == 32 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN; /**< == 32 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN; /**< == 32 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN; /**< == 32 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN; /**< == 32 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_COLORS_LEN; /**< == 32 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN; /**< == 32 (bits) */ - - -/** Structure that is used when a metadata block of unknown type is loaded. - * The contents are opaque. The structure is used only internally to - * correctly handle unknown metadata. - */ -typedef struct { - FLAC__byte *data; -} FLAC__StreamMetadata_Unknown; - - -/** FLAC metadata block structure. (c.f. format specification) - */ -typedef struct { - FLAC__MetadataType type; - /**< The type of the metadata block; used determine which member of the - * \a data union to dereference. If type >= FLAC__METADATA_TYPE_UNDEFINED - * then \a data.unknown must be used. */ - - FLAC__bool is_last; - /**< \c true if this metadata block is the last, else \a false */ - - unsigned length; - /**< Length, in bytes, of the block data as it appears in the stream. */ - - union { - FLAC__StreamMetadata_StreamInfo stream_info; - FLAC__StreamMetadata_Padding padding; - FLAC__StreamMetadata_Application application; - FLAC__StreamMetadata_SeekTable seek_table; - FLAC__StreamMetadata_VorbisComment vorbis_comment; - FLAC__StreamMetadata_CueSheet cue_sheet; - FLAC__StreamMetadata_Picture picture; - FLAC__StreamMetadata_Unknown unknown; - } data; - /**< Polymorphic block data; use the \a type value to determine which - * to use. */ -} FLAC__StreamMetadata; - -extern FLAC_API const unsigned FLAC__STREAM_METADATA_IS_LAST_LEN; /**< == 1 (bit) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_TYPE_LEN; /**< == 7 (bits) */ -extern FLAC_API const unsigned FLAC__STREAM_METADATA_LENGTH_LEN; /**< == 24 (bits) */ - -/** The total stream length of a metadata block header in bytes. */ -#define FLAC__STREAM_METADATA_HEADER_LENGTH (4u) - -/*****************************************************************************/ - - -/***************************************************************************** - * - * Utility functions - * - *****************************************************************************/ - -/** Tests that a sample rate is valid for FLAC. - * - * \param sample_rate The sample rate to test for compliance. - * \retval FLAC__bool - * \c true if the given sample rate conforms to the specification, else - * \c false. - */ -FLAC_API FLAC__bool FLAC__format_sample_rate_is_valid(unsigned sample_rate); - -/** Tests that a blocksize at the given sample rate is valid for the FLAC - * subset. - * - * \param blocksize The blocksize to test for compliance. - * \param sample_rate The sample rate is needed, since the valid subset - * blocksize depends on the sample rate. - * \retval FLAC__bool - * \c true if the given blocksize conforms to the specification for the - * subset at the given sample rate, else \c false. - */ -FLAC_API FLAC__bool FLAC__format_blocksize_is_subset(unsigned blocksize, unsigned sample_rate); - -/** Tests that a sample rate is valid for the FLAC subset. The subset rules - * for valid sample rates are slightly more complex since the rate has to - * be expressible completely in the frame header. - * - * \param sample_rate The sample rate to test for compliance. - * \retval FLAC__bool - * \c true if the given sample rate conforms to the specification for the - * subset, else \c false. - */ -FLAC_API FLAC__bool FLAC__format_sample_rate_is_subset(unsigned sample_rate); - -/** Check a Vorbis comment entry name to see if it conforms to the Vorbis - * comment specification. - * - * Vorbis comment names must be composed only of characters from - * [0x20-0x3C,0x3E-0x7D]. - * - * \param name A NUL-terminated string to be checked. - * \assert - * \code name != NULL \endcode - * \retval FLAC__bool - * \c false if entry name is illegal, else \c true. - */ -FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_name_is_legal(const char *name); - -/** Check a Vorbis comment entry value to see if it conforms to the Vorbis - * comment specification. - * - * Vorbis comment values must be valid UTF-8 sequences. - * - * \param value A string to be checked. - * \param length A the length of \a value in bytes. May be - * \c (unsigned)(-1) to indicate that \a value is a plain - * UTF-8 NUL-terminated string. - * \assert - * \code value != NULL \endcode - * \retval FLAC__bool - * \c false if entry name is illegal, else \c true. - */ -FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_value_is_legal(const FLAC__byte *value, unsigned length); - -/** Check a Vorbis comment entry to see if it conforms to the Vorbis - * comment specification. - * - * Vorbis comment entries must be of the form 'name=value', and 'name' and - * 'value' must be legal according to - * FLAC__format_vorbiscomment_entry_name_is_legal() and - * FLAC__format_vorbiscomment_entry_value_is_legal() respectively. - * - * \param entry An entry to be checked. - * \param length The length of \a entry in bytes. - * \assert - * \code value != NULL \endcode - * \retval FLAC__bool - * \c false if entry name is illegal, else \c true. - */ -FLAC_API FLAC__bool FLAC__format_vorbiscomment_entry_is_legal(const FLAC__byte *entry, unsigned length); - -/** Check a seek table to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * seek table. - * - * \param seek_table A pointer to a seek table to be checked. - * \assert - * \code seek_table != NULL \endcode - * \retval FLAC__bool - * \c false if seek table is illegal, else \c true. - */ -FLAC_API FLAC__bool FLAC__format_seektable_is_legal(const FLAC__StreamMetadata_SeekTable *seek_table); - -/** Sort a seek table's seek points according to the format specification. - * This includes a "unique-ification" step to remove duplicates, i.e. - * seek points with identical \a sample_number values. Duplicate seek - * points are converted into placeholder points and sorted to the end of - * the table. - * - * \param seek_table A pointer to a seek table to be sorted. - * \assert - * \code seek_table != NULL \endcode - * \retval unsigned - * The number of duplicate seek points converted into placeholders. - */ -FLAC_API unsigned FLAC__format_seektable_sort(FLAC__StreamMetadata_SeekTable *seek_table); - -/** Check a cue sheet to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * cue sheet. - * - * \param cue_sheet A pointer to an existing cue sheet to be checked. - * \param check_cd_da_subset If \c true, check CUESHEET against more - * stringent requirements for a CD-DA (audio) disc. - * \param violation Address of a pointer to a string. If there is a - * violation, a pointer to a string explanation of the - * violation will be returned here. \a violation may be - * \c NULL if you don't need the returned string. Do not - * free the returned string; it will always point to static - * data. - * \assert - * \code cue_sheet != NULL \endcode - * \retval FLAC__bool - * \c false if cue sheet is illegal, else \c true. - */ -FLAC_API FLAC__bool FLAC__format_cuesheet_is_legal(const FLAC__StreamMetadata_CueSheet *cue_sheet, FLAC__bool check_cd_da_subset, const char **violation); - -/** Check picture data to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * PICTURE block. - * - * \param picture A pointer to existing picture data to be checked. - * \param violation Address of a pointer to a string. If there is a - * violation, a pointer to a string explanation of the - * violation will be returned here. \a violation may be - * \c NULL if you don't need the returned string. Do not - * free the returned string; it will always point to static - * data. - * \assert - * \code picture != NULL \endcode - * \retval FLAC__bool - * \c false if picture data is illegal, else \c true. - */ -FLAC_API FLAC__bool FLAC__format_picture_is_legal(const FLAC__StreamMetadata_Picture *picture, const char **violation); - -/* \} */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/Windows/include/FLAC/metadata.h b/platform/Windows/include/FLAC/metadata.h deleted file mode 100644 index fcc8ed95c..000000000 --- a/platform/Windows/include/FLAC/metadata.h +++ /dev/null @@ -1,2182 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 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__METADATA_H -#define FLAC__METADATA_H - -#include /* for off_t */ -#include "export.h" -#include "callback.h" -#include "format.h" - -/* -------------------------------------------------------------------- - (For an example of how all these routines are used, see the source - code for the unit tests in src/test_libFLAC/metadata_*.c, or - metaflac in src/metaflac/) - ------------------------------------------------------------------*/ - -/** \file include/FLAC/metadata.h - * - * \brief - * This module provides functions for creating and manipulating FLAC - * metadata blocks in memory, and three progressively more powerful - * interfaces for traversing and editing metadata in FLAC files. - * - * See the detailed documentation for each interface in the - * \link flac_metadata metadata \endlink module. - */ - -/** \defgroup flac_metadata FLAC/metadata.h: metadata interfaces - * \ingroup flac - * - * \brief - * This module provides functions for creating and manipulating FLAC - * metadata blocks in memory, and three progressively more powerful - * interfaces for traversing and editing metadata in native FLAC files. - * Note that currently only the Chain interface (level 2) supports Ogg - * FLAC files, and it is read-only i.e. no writing back changed - * metadata to file. - * - * There are three metadata interfaces of increasing complexity: - * - * Level 0: - * Read-only access to the STREAMINFO, VORBIS_COMMENT, CUESHEET, and - * PICTURE blocks. - * - * Level 1: - * Read-write access to all metadata blocks. This level is write- - * efficient in most cases (more on this below), and uses less memory - * than level 2. - * - * Level 2: - * Read-write access to all metadata blocks. This level is write- - * efficient in all cases, but uses more memory since all metadata for - * the whole file is read into memory and manipulated before writing - * out again. - * - * What do we mean by efficient? Since FLAC metadata appears at the - * beginning of the file, when writing metadata back to a FLAC file - * it is possible to grow or shrink the metadata such that the entire - * file must be rewritten. However, if the size remains the same during - * changes or PADDING blocks are utilized, only the metadata needs to be - * overwritten, which is much faster. - * - * Efficient means the whole file is rewritten at most one time, and only - * when necessary. Level 1 is not efficient only in the case that you - * cause more than one metadata block to grow or shrink beyond what can - * be accomodated by padding. In this case you should probably use level - * 2, which allows you to edit all the metadata for a file in memory and - * write it out all at once. - * - * All levels know how to skip over and not disturb an ID3v2 tag at the - * front of the file. - * - * All levels access files via their filenames. In addition, level 2 - * has additional alternative read and write functions that take an I/O - * handle and callbacks, for situations where access by filename is not - * possible. - * - * In addition to the three interfaces, this module defines functions for - * creating and manipulating various metadata objects in memory. As we see - * from the Format module, FLAC metadata blocks in memory are very primitive - * structures for storing information in an efficient way. Reading - * information from the structures is easy but creating or modifying them - * directly is more complex. The metadata object routines here facilitate - * this by taking care of the consistency and memory management drudgery. - * - * Unless you will be using the level 1 or 2 interfaces to modify existing - * metadata however, you will not probably not need these. - * - * From a dependency standpoint, none of the encoders or decoders require - * the metadata module. This is so that embedded users can strip out the - * metadata module from libFLAC to reduce the size and complexity. - */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/** \defgroup flac_metadata_level0 FLAC/metadata.h: metadata level 0 interface - * \ingroup flac_metadata - * - * \brief - * The level 0 interface consists of individual routines to read the - * STREAMINFO, VORBIS_COMMENT, CUESHEET, and PICTURE blocks, requiring - * only a filename. - * - * They try to skip any ID3v2 tag at the head of the file. - * - * \{ - */ - -/** Read the STREAMINFO metadata block of the given FLAC file. This function - * will try to skip any ID3v2 tag at the head of the file. - * - * \param filename The path to the FLAC file to read. - * \param streaminfo A pointer to space for the STREAMINFO block. Since - * FLAC__StreamMetadata is a simple structure with no - * memory allocation involved, you pass the address of - * an existing structure. It need not be initialized. - * \assert - * \code filename != NULL \endcode - * \code streaminfo != NULL \endcode - * \retval FLAC__bool - * \c true if a valid STREAMINFO block was read from \a filename. Returns - * \c false if there was a memory allocation error, a file decoder error, - * or the file contained no STREAMINFO block. (A memory allocation error - * is possible because this function must set up a file decoder.) - */ -FLAC_API FLAC__bool FLAC__metadata_get_streaminfo(const char *filename, FLAC__StreamMetadata *streaminfo); - -/** Read the VORBIS_COMMENT metadata block of the given FLAC file. This - * function will try to skip any ID3v2 tag at the head of the file. - * - * \param filename The path to the FLAC file to read. - * \param tags The address where the returned pointer will be - * stored. The \a tags object must be deleted by - * the caller using FLAC__metadata_object_delete(). - * \assert - * \code filename != NULL \endcode - * \code tags != NULL \endcode - * \retval FLAC__bool - * \c true if a valid VORBIS_COMMENT block was read from \a filename, - * and \a *tags will be set to the address of the metadata structure. - * Returns \c false if there was a memory allocation error, a file - * decoder error, or the file contained no VORBIS_COMMENT block, and - * \a *tags will be set to \c NULL. - */ -FLAC_API FLAC__bool FLAC__metadata_get_tags(const char *filename, FLAC__StreamMetadata **tags); - -/** Read the CUESHEET metadata block of the given FLAC file. This - * function will try to skip any ID3v2 tag at the head of the file. - * - * \param filename The path to the FLAC file to read. - * \param cuesheet The address where the returned pointer will be - * stored. The \a cuesheet object must be deleted by - * the caller using FLAC__metadata_object_delete(). - * \assert - * \code filename != NULL \endcode - * \code cuesheet != NULL \endcode - * \retval FLAC__bool - * \c true if a valid CUESHEET block was read from \a filename, - * and \a *cuesheet will be set to the address of the metadata - * structure. Returns \c false if there was a memory allocation - * error, a file decoder error, or the file contained no CUESHEET - * block, and \a *cuesheet will be set to \c NULL. - */ -FLAC_API FLAC__bool FLAC__metadata_get_cuesheet(const char *filename, FLAC__StreamMetadata **cuesheet); - -/** Read a PICTURE metadata block of the given FLAC file. This - * function will try to skip any ID3v2 tag at the head of the file. - * Since there can be more than one PICTURE block in a file, this - * function takes a number of parameters that act as constraints to - * the search. The PICTURE block with the largest area matching all - * the constraints will be returned, or \a *picture will be set to - * \c NULL if there was no such block. - * - * \param filename The path to the FLAC file to read. - * \param picture The address where the returned pointer will be - * stored. The \a picture object must be deleted by - * the caller using FLAC__metadata_object_delete(). - * \param type The desired picture type. Use \c -1 to mean - * "any type". - * \param mime_type The desired MIME type, e.g. "image/jpeg". The - * string will be matched exactly. Use \c NULL to - * mean "any MIME type". - * \param description The desired description. The string will be - * matched exactly. Use \c NULL to mean "any - * description". - * \param max_width The maximum width in pixels desired. Use - * \c (unsigned)(-1) to mean "any width". - * \param max_height The maximum height in pixels desired. Use - * \c (unsigned)(-1) to mean "any height". - * \param max_depth The maximum color depth in bits-per-pixel desired. - * Use \c (unsigned)(-1) to mean "any depth". - * \param max_colors The maximum number of colors desired. Use - * \c (unsigned)(-1) to mean "any number of colors". - * \assert - * \code filename != NULL \endcode - * \code picture != NULL \endcode - * \retval FLAC__bool - * \c true if a valid PICTURE block was read from \a filename, - * and \a *picture will be set to the address of the metadata - * structure. Returns \c false if there was a memory allocation - * error, a file decoder error, or the file contained no PICTURE - * block, and \a *picture will be set to \c NULL. - */ -FLAC_API FLAC__bool FLAC__metadata_get_picture(const char *filename, FLAC__StreamMetadata **picture, FLAC__StreamMetadata_Picture_Type type, const char *mime_type, const FLAC__byte *description, unsigned max_width, unsigned max_height, unsigned max_depth, unsigned max_colors); - -/* \} */ - - -/** \defgroup flac_metadata_level1 FLAC/metadata.h: metadata level 1 interface - * \ingroup flac_metadata - * - * \brief - * The level 1 interface provides read-write access to FLAC file metadata and - * operates directly on the FLAC file. - * - * The general usage of this interface is: - * - * - Create an iterator using FLAC__metadata_simple_iterator_new() - * - Attach it to a file using FLAC__metadata_simple_iterator_init() and check - * the exit code. Call FLAC__metadata_simple_iterator_is_writable() to - * see if the file is writable, or only read access is allowed. - * - Use FLAC__metadata_simple_iterator_next() and - * FLAC__metadata_simple_iterator_prev() to traverse the blocks. - * This is does not read the actual blocks themselves. - * FLAC__metadata_simple_iterator_next() is relatively fast. - * FLAC__metadata_simple_iterator_prev() is slower since it needs to search - * forward from the front of the file. - * - Use FLAC__metadata_simple_iterator_get_block_type() or - * FLAC__metadata_simple_iterator_get_block() to access the actual data at - * the current iterator position. The returned object is yours to modify - * and free. - * - Use FLAC__metadata_simple_iterator_set_block() to write a modified block - * back. You must have write permission to the original file. Make sure to - * read the whole comment to FLAC__metadata_simple_iterator_set_block() - * below. - * - Use FLAC__metadata_simple_iterator_insert_block_after() to add new blocks. - * Use the object creation functions from - * \link flac_metadata_object here \endlink to generate new objects. - * - Use FLAC__metadata_simple_iterator_delete_block() to remove the block - * currently referred to by the iterator, or replace it with padding. - * - Destroy the iterator with FLAC__metadata_simple_iterator_delete() when - * finished. - * - * \note - * The FLAC file remains open the whole time between - * FLAC__metadata_simple_iterator_init() and - * FLAC__metadata_simple_iterator_delete(), so make sure you are not altering - * the file during this time. - * - * \note - * Do not modify the \a is_last, \a length, or \a type fields of returned - * FLAC__StreamMetadata objects. These are managed automatically. - * - * \note - * If any of the modification functions - * (FLAC__metadata_simple_iterator_set_block(), - * FLAC__metadata_simple_iterator_delete_block(), - * FLAC__metadata_simple_iterator_insert_block_after(), etc.) return \c false, - * you should delete the iterator as it may no longer be valid. - * - * \{ - */ - -struct FLAC__Metadata_SimpleIterator; -/** The opaque structure definition for the level 1 iterator type. - * See the - * \link flac_metadata_level1 metadata level 1 module \endlink - * for a detailed description. - */ -typedef struct FLAC__Metadata_SimpleIterator FLAC__Metadata_SimpleIterator; - -/** Status type for FLAC__Metadata_SimpleIterator. - * - * The iterator's current status can be obtained by calling FLAC__metadata_simple_iterator_status(). - */ -typedef enum { - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK = 0, - /**< The iterator is in the normal OK state */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, - /**< The data passed into a function violated the function's usage criteria */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ERROR_OPENING_FILE, - /**< The iterator could not open the target file */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_A_FLAC_FILE, - /**< The iterator could not find the FLAC signature at the start of the file */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_NOT_WRITABLE, - /**< The iterator tried to write to a file that was not writable */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_BAD_METADATA, - /**< The iterator encountered input that does not conform to the FLAC metadata specification */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR, - /**< The iterator encountered an error while reading the FLAC file */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, - /**< The iterator encountered an error while seeking in the FLAC file */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_WRITE_ERROR, - /**< The iterator encountered an error while writing the FLAC file */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_RENAME_ERROR, - /**< The iterator encountered an error renaming the FLAC file */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_UNLINK_ERROR, - /**< The iterator encountered an error removing the temporary file */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_MEMORY_ALLOCATION_ERROR, - /**< Memory allocation failed */ - - FLAC__METADATA_SIMPLE_ITERATOR_STATUS_INTERNAL_ERROR - /**< The caller violated an assertion or an unexpected error occurred */ - -} FLAC__Metadata_SimpleIteratorStatus; - -/** Maps a FLAC__Metadata_SimpleIteratorStatus to a C string. - * - * Using a FLAC__Metadata_SimpleIteratorStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__Metadata_SimpleIteratorStatusString[]; - - -/** Create a new iterator instance. - * - * \retval FLAC__Metadata_SimpleIterator* - * \c NULL if there was an error allocating memory, else the new instance. - */ -FLAC_API FLAC__Metadata_SimpleIterator *FLAC__metadata_simple_iterator_new(void); - -/** Free an iterator instance. Deletes the object pointed to by \a iterator. - * - * \param iterator A pointer to an existing iterator. - * \assert - * \code iterator != NULL \endcode - */ -FLAC_API void FLAC__metadata_simple_iterator_delete(FLAC__Metadata_SimpleIterator *iterator); - -/** Get the current status of the iterator. Call this after a function - * returns \c false to get the reason for the error. Also resets the status - * to FLAC__METADATA_SIMPLE_ITERATOR_STATUS_OK. - * - * \param iterator A pointer to an existing iterator. - * \assert - * \code iterator != NULL \endcode - * \retval FLAC__Metadata_SimpleIteratorStatus - * The current status of the iterator. - */ -FLAC_API FLAC__Metadata_SimpleIteratorStatus FLAC__metadata_simple_iterator_status(FLAC__Metadata_SimpleIterator *iterator); - -/** Initialize the iterator to point to the first metadata block in the - * given FLAC file. - * - * \param iterator A pointer to an existing iterator. - * \param filename The path to the FLAC file. - * \param read_only If \c true, the FLAC file will be opened - * in read-only mode; if \c false, the FLAC - * file will be opened for edit even if no - * edits are performed. - * \param preserve_file_stats If \c true, the owner and modification - * time will be preserved even if the FLAC - * file is written to. - * \assert - * \code iterator != NULL \endcode - * \code filename != NULL \endcode - * \retval FLAC__bool - * \c false if a memory allocation error occurs, the file can't be - * opened, or another error occurs, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_simple_iterator_init(FLAC__Metadata_SimpleIterator *iterator, const char *filename, FLAC__bool read_only, FLAC__bool preserve_file_stats); - -/** Returns \c true if the FLAC file is writable. If \c false, calls to - * FLAC__metadata_simple_iterator_set_block() and - * FLAC__metadata_simple_iterator_insert_block_after() will fail. - * - * \param iterator A pointer to an existing iterator. - * \assert - * \code iterator != NULL \endcode - * \retval FLAC__bool - * See above. - */ -FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_writable(const FLAC__Metadata_SimpleIterator *iterator); - -/** Moves the iterator forward one metadata block, returning \c false if - * already at the end. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c false if already at the last metadata block of the chain, else - * \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_simple_iterator_next(FLAC__Metadata_SimpleIterator *iterator); - -/** Moves the iterator backward one metadata block, returning \c false if - * already at the beginning. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c false if already at the first metadata block of the chain, else - * \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_simple_iterator_prev(FLAC__Metadata_SimpleIterator *iterator); - -/** Returns a flag telling if the current metadata block is the last. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c true if the current metadata block is the last in the file, - * else \c false. - */ -FLAC_API FLAC__bool FLAC__metadata_simple_iterator_is_last(const FLAC__Metadata_SimpleIterator *iterator); - -/** Get the offset of the metadata block at the current position. This - * avoids reading the actual block data which can save time for large - * blocks. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval off_t - * The offset of the metadata block at the current iterator position. - * This is the byte offset relative to the beginning of the file of - * the current metadata block's header. - */ -FLAC_API off_t FLAC__metadata_simple_iterator_get_block_offset(const FLAC__Metadata_SimpleIterator *iterator); - -/** Get the type of the metadata block at the current position. This - * avoids reading the actual block data which can save time for large - * blocks. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__MetadataType - * The type of the metadata block at the current iterator position. - */ -FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const FLAC__Metadata_SimpleIterator *iterator); - -/** Get the length of the metadata block at the current position. This - * avoids reading the actual block data which can save time for large - * blocks. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval unsigned - * The length of the metadata block at the current iterator position. - * The is same length as that in the - * metadata block header, - * i.e. the length of the metadata body that follows the header. - */ -FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator); - -/** Get the application ID of the \c APPLICATION block at the current - * position. This avoids reading the actual block data which can save - * time for large blocks. - * - * \param iterator A pointer to an existing initialized iterator. - * \param id A pointer to a buffer of at least \c 4 bytes where - * the ID will be stored. - * \assert - * \code iterator != NULL \endcode - * \code id != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c true if the ID was successfully read, else \c false, in which - * case you should check FLAC__metadata_simple_iterator_status() to - * find out why. If the status is - * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_ILLEGAL_INPUT, then the - * current metadata block is not an \c APPLICATION block. Otherwise - * if the status is - * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_READ_ERROR or - * \c FLAC__METADATA_SIMPLE_ITERATOR_STATUS_SEEK_ERROR, an I/O error - * occurred and the iterator can no longer be used. - */ -FLAC_API FLAC__bool FLAC__metadata_simple_iterator_get_application_id(FLAC__Metadata_SimpleIterator *iterator, FLAC__byte *id); - -/** Get the metadata block at the current position. You can modify the - * block but must use FLAC__metadata_simple_iterator_set_block() to - * write it back to the FLAC file. - * - * You must call FLAC__metadata_object_delete() on the returned object - * when you are finished with it. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__StreamMetadata* - * The current metadata block, or \c NULL if there was a memory - * allocation error. - */ -FLAC_API FLAC__StreamMetadata *FLAC__metadata_simple_iterator_get_block(FLAC__Metadata_SimpleIterator *iterator); - -/** Write a block back to the FLAC file. This function tries to be - * as efficient as possible; how the block is actually written is - * shown by the following: - * - * Existing block is a STREAMINFO block and the new block is a - * STREAMINFO block: the new block is written in place. Make sure - * you know what you're doing when changing the values of a - * STREAMINFO block. - * - * Existing block is a STREAMINFO block and the new block is a - * not a STREAMINFO block: this is an error since the first block - * must be a STREAMINFO block. Returns \c false without altering the - * file. - * - * Existing block is not a STREAMINFO block and the new block is a - * STREAMINFO block: this is an error since there may be only one - * STREAMINFO block. Returns \c false without altering the file. - * - * Existing block and new block are the same length: the existing - * block will be replaced by the new block, written in place. - * - * Existing block is longer than new block: if use_padding is \c true, - * the existing block will be overwritten in place with the new - * block followed by a PADDING block, if possible, to make the total - * size the same as the existing block. Remember that a padding - * block requires at least four bytes so if the difference in size - * between the new block and existing block is less than that, the - * entire file will have to be rewritten, using the new block's - * exact size. If use_padding is \c false, the entire file will be - * rewritten, replacing the existing block by the new block. - * - * Existing block is shorter than new block: if use_padding is \c true, - * the function will try and expand the new block into the following - * PADDING block, if it exists and doing so won't shrink the PADDING - * block to less than 4 bytes. If there is no following PADDING - * block, or it will shrink to less than 4 bytes, or use_padding is - * \c false, the entire file is rewritten, replacing the existing block - * with the new block. Note that in this case any following PADDING - * block is preserved as is. - * - * After writing the block, the iterator will remain in the same - * place, i.e. pointing to the new block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block The block to set. - * \param use_padding See above. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \code block != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false. - */ -FLAC_API FLAC__bool FLAC__metadata_simple_iterator_set_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); - -/** This is similar to FLAC__metadata_simple_iterator_set_block() - * except that instead of writing over an existing block, it appends - * a block after the existing block. \a use_padding is again used to - * tell the function to try an expand into following padding in an - * attempt to avoid rewriting the entire file. - * - * This function will fail and return \c false if given a STREAMINFO - * block. - * - * After writing the block, the iterator will be pointing to the - * new block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block The block to set. - * \param use_padding See above. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \code block != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false. - */ -FLAC_API FLAC__bool FLAC__metadata_simple_iterator_insert_block_after(FLAC__Metadata_SimpleIterator *iterator, FLAC__StreamMetadata *block, FLAC__bool use_padding); - -/** Deletes the block at the current position. This will cause the - * entire FLAC file to be rewritten, unless \a use_padding is \c true, - * in which case the block will be replaced by an equal-sized PADDING - * block. The iterator will be left pointing to the block before the - * one just deleted. - * - * You may not delete the STREAMINFO block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param use_padding See above. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_simple_iterator_init() - * \retval FLAC__bool - * \c true if successful, else \c false. - */ -FLAC_API FLAC__bool FLAC__metadata_simple_iterator_delete_block(FLAC__Metadata_SimpleIterator *iterator, FLAC__bool use_padding); - -/* \} */ - - -/** \defgroup flac_metadata_level2 FLAC/metadata.h: metadata level 2 interface - * \ingroup flac_metadata - * - * \brief - * The level 2 interface provides read-write access to FLAC file metadata; - * all metadata is read into memory, operated on in memory, and then written - * to file, which is more efficient than level 1 when editing multiple blocks. - * - * Currently Ogg FLAC is supported for read only, via - * FLAC__metadata_chain_read_ogg() but a subsequent - * FLAC__metadata_chain_write() will fail. - * - * The general usage of this interface is: - * - * - Create a new chain using FLAC__metadata_chain_new(). A chain is a - * linked list of FLAC metadata blocks. - * - Read all metadata into the the chain from a FLAC file using - * FLAC__metadata_chain_read() or FLAC__metadata_chain_read_ogg() and - * check the status. - * - Optionally, consolidate the padding using - * FLAC__metadata_chain_merge_padding() or - * FLAC__metadata_chain_sort_padding(). - * - Create a new iterator using FLAC__metadata_iterator_new() - * - Initialize the iterator to point to the first element in the chain - * using FLAC__metadata_iterator_init() - * - Traverse the chain using FLAC__metadata_iterator_next and - * FLAC__metadata_iterator_prev(). - * - Get a block for reading or modification using - * FLAC__metadata_iterator_get_block(). The pointer to the object - * inside the chain is returned, so the block is yours to modify. - * Changes will be reflected in the FLAC file when you write the - * chain. You can also add and delete blocks (see functions below). - * - When done, write out the chain using FLAC__metadata_chain_write(). - * Make sure to read the whole comment to the function below. - * - Delete the chain using FLAC__metadata_chain_delete(). - * - * \note - * Even though the FLAC file is not open while the chain is being - * manipulated, you must not alter the file externally during - * this time. The chain assumes the FLAC file will not change - * between the time of FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg() - * and FLAC__metadata_chain_write(). - * - * \note - * Do not modify the is_last, length, or type fields of returned - * FLAC__StreamMetadata objects. These are managed automatically. - * - * \note - * The metadata objects returned by FLAC__metadata_iterator_get_block() - * are owned by the chain; do not FLAC__metadata_object_delete() them. - * In the same way, blocks passed to FLAC__metadata_iterator_set_block() - * become owned by the chain and they will be deleted when the chain is - * deleted. - * - * \{ - */ - -struct FLAC__Metadata_Chain; -/** The opaque structure definition for the level 2 chain type. - */ -typedef struct FLAC__Metadata_Chain FLAC__Metadata_Chain; - -struct FLAC__Metadata_Iterator; -/** The opaque structure definition for the level 2 iterator type. - */ -typedef struct FLAC__Metadata_Iterator FLAC__Metadata_Iterator; - -typedef enum { - FLAC__METADATA_CHAIN_STATUS_OK = 0, - /**< The chain is in the normal OK state */ - - FLAC__METADATA_CHAIN_STATUS_ILLEGAL_INPUT, - /**< The data passed into a function violated the function's usage criteria */ - - FLAC__METADATA_CHAIN_STATUS_ERROR_OPENING_FILE, - /**< The chain could not open the target file */ - - FLAC__METADATA_CHAIN_STATUS_NOT_A_FLAC_FILE, - /**< The chain could not find the FLAC signature at the start of the file */ - - FLAC__METADATA_CHAIN_STATUS_NOT_WRITABLE, - /**< The chain tried to write to a file that was not writable */ - - FLAC__METADATA_CHAIN_STATUS_BAD_METADATA, - /**< The chain encountered input that does not conform to the FLAC metadata specification */ - - FLAC__METADATA_CHAIN_STATUS_READ_ERROR, - /**< The chain encountered an error while reading the FLAC file */ - - FLAC__METADATA_CHAIN_STATUS_SEEK_ERROR, - /**< The chain encountered an error while seeking in the FLAC file */ - - FLAC__METADATA_CHAIN_STATUS_WRITE_ERROR, - /**< The chain encountered an error while writing the FLAC file */ - - FLAC__METADATA_CHAIN_STATUS_RENAME_ERROR, - /**< The chain encountered an error renaming the FLAC file */ - - FLAC__METADATA_CHAIN_STATUS_UNLINK_ERROR, - /**< The chain encountered an error removing the temporary file */ - - FLAC__METADATA_CHAIN_STATUS_MEMORY_ALLOCATION_ERROR, - /**< Memory allocation failed */ - - FLAC__METADATA_CHAIN_STATUS_INTERNAL_ERROR, - /**< The caller violated an assertion or an unexpected error occurred */ - - FLAC__METADATA_CHAIN_STATUS_INVALID_CALLBACKS, - /**< One or more of the required callbacks was NULL */ - - FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH, - /**< FLAC__metadata_chain_write() was called on a chain read by - * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), - * or - * FLAC__metadata_chain_write_with_callbacks()/FLAC__metadata_chain_write_with_callbacks_and_tempfile() - * was called on a chain read by - * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). - * Matching read/write methods must always be used. */ - - FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL - /**< FLAC__metadata_chain_write_with_callbacks() was called when the - * chain write requires a tempfile; use - * FLAC__metadata_chain_write_with_callbacks_and_tempfile() instead. - * Or, FLAC__metadata_chain_write_with_callbacks_and_tempfile() was - * called when the chain write does not require a tempfile; use - * FLAC__metadata_chain_write_with_callbacks() instead. - * Always check FLAC__metadata_chain_check_if_tempfile_needed() - * before writing via callbacks. */ - -} FLAC__Metadata_ChainStatus; - -/** Maps a FLAC__Metadata_ChainStatus to a C string. - * - * Using a FLAC__Metadata_ChainStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__Metadata_ChainStatusString[]; - -/*********** FLAC__Metadata_Chain ***********/ - -/** Create a new chain instance. - * - * \retval FLAC__Metadata_Chain* - * \c NULL if there was an error allocating memory, else the new instance. - */ -FLAC_API FLAC__Metadata_Chain *FLAC__metadata_chain_new(void); - -/** Free a chain instance. Deletes the object pointed to by \a chain. - * - * \param chain A pointer to an existing chain. - * \assert - * \code chain != NULL \endcode - */ -FLAC_API void FLAC__metadata_chain_delete(FLAC__Metadata_Chain *chain); - -/** Get the current status of the chain. Call this after a function - * returns \c false to get the reason for the error. Also resets the - * status to FLAC__METADATA_CHAIN_STATUS_OK. - * - * \param chain A pointer to an existing chain. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__Metadata_ChainStatus - * The current status of the chain. - */ -FLAC_API FLAC__Metadata_ChainStatus FLAC__metadata_chain_status(FLAC__Metadata_Chain *chain); - -/** Read all metadata from a FLAC file into the chain. - * - * \param chain A pointer to an existing chain. - * \param filename The path to the FLAC file to read. - * \assert - * \code chain != NULL \endcode - * \code filename != NULL \endcode - * \retval FLAC__bool - * \c true if a valid list of metadata blocks was read from - * \a filename, else \c false. On failure, check the status with - * FLAC__metadata_chain_status(). - */ -FLAC_API FLAC__bool FLAC__metadata_chain_read(FLAC__Metadata_Chain *chain, const char *filename); - -/** Read all metadata from an Ogg FLAC file into the chain. - * - * \note Ogg FLAC metadata data writing is not supported yet and - * FLAC__metadata_chain_write() will fail. - * - * \param chain A pointer to an existing chain. - * \param filename The path to the Ogg FLAC file to read. - * \assert - * \code chain != NULL \endcode - * \code filename != NULL \endcode - * \retval FLAC__bool - * \c true if a valid list of metadata blocks was read from - * \a filename, else \c false. On failure, check the status with - * FLAC__metadata_chain_status(). - */ -FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg(FLAC__Metadata_Chain *chain, const char *filename); - -/** Read all metadata from a FLAC stream into the chain via I/O callbacks. - * - * The \a handle need only be open for reading, but must be seekable. - * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" - * for Windows). - * - * \param chain A pointer to an existing chain. - * \param handle The I/O handle of the FLAC stream to read. The - * handle will NOT be closed after the metadata is read; - * that is the duty of the caller. - * \param callbacks - * A set of callbacks to use for I/O. The mandatory - * callbacks are \a read, \a seek, and \a tell. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if a valid list of metadata blocks was read from - * \a handle, else \c false. On failure, check the status with - * FLAC__metadata_chain_status(). - */ -FLAC_API FLAC__bool FLAC__metadata_chain_read_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); - -/** Read all metadata from an Ogg FLAC stream into the chain via I/O callbacks. - * - * The \a handle need only be open for reading, but must be seekable. - * The equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" - * for Windows). - * - * \note Ogg FLAC metadata data writing is not supported yet and - * FLAC__metadata_chain_write() will fail. - * - * \param chain A pointer to an existing chain. - * \param handle The I/O handle of the Ogg FLAC stream to read. The - * handle will NOT be closed after the metadata is read; - * that is the duty of the caller. - * \param callbacks - * A set of callbacks to use for I/O. The mandatory - * callbacks are \a read, \a seek, and \a tell. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if a valid list of metadata blocks was read from - * \a handle, else \c false. On failure, check the status with - * FLAC__metadata_chain_status(). - */ -FLAC_API FLAC__bool FLAC__metadata_chain_read_ogg_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); - -/** Checks if writing the given chain would require the use of a - * temporary file, or if it could be written in place. - * - * Under certain conditions, padding can be utilized so that writing - * edited metadata back to the FLAC file does not require rewriting the - * entire file. If rewriting is required, then a temporary workfile is - * required. When writing metadata using callbacks, you must check - * this function to know whether to call - * FLAC__metadata_chain_write_with_callbacks() or - * FLAC__metadata_chain_write_with_callbacks_and_tempfile(). When - * writing with FLAC__metadata_chain_write(), the temporary file is - * handled internally. - * - * \param chain A pointer to an existing chain. - * \param use_padding - * Whether or not padding will be allowed to be used - * during the write. The value of \a use_padding given - * here must match the value later passed to - * FLAC__metadata_chain_write_with_callbacks() or - * FLAC__metadata_chain_write_with_callbacks_with_tempfile(). - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if writing the current chain would require a tempfile, or - * \c false if metadata can be written in place. - */ -FLAC_API FLAC__bool FLAC__metadata_chain_check_if_tempfile_needed(FLAC__Metadata_Chain *chain, FLAC__bool use_padding); - -/** Write all metadata out to the FLAC file. This function tries to be as - * efficient as possible; how the metadata is actually written is shown by - * the following: - * - * If the current chain is the same size as the existing metadata, the new - * data is written in place. - * - * If the current chain is longer than the existing metadata, and - * \a use_padding is \c true, and the last block is a PADDING block of - * sufficient length, the function will truncate the final padding block - * so that the overall size of the metadata is the same as the existing - * metadata, and then just rewrite the metadata. Otherwise, if not all of - * the above conditions are met, the entire FLAC file must be rewritten. - * If you want to use padding this way it is a good idea to call - * FLAC__metadata_chain_sort_padding() first so that you have the maximum - * amount of padding to work with, unless you need to preserve ordering - * of the PADDING blocks for some reason. - * - * If the current chain is shorter than the existing metadata, and - * \a use_padding is \c true, and the final block is a PADDING block, the padding - * is extended to make the overall size the same as the existing data. If - * \a use_padding is \c true and the last block is not a PADDING block, a new - * PADDING block is added to the end of the new data to make it the same - * size as the existing data (if possible, see the note to - * FLAC__metadata_simple_iterator_set_block() about the four byte limit) - * and the new data is written in place. If none of the above apply or - * \a use_padding is \c false, the entire FLAC file is rewritten. - * - * If \a preserve_file_stats is \c true, the owner and modification time will - * be preserved even if the FLAC file is written. - * - * For this write function to be used, the chain must have been read with - * FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(), not - * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(). - * - * \param chain A pointer to an existing chain. - * \param use_padding See above. - * \param preserve_file_stats See above. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if the write succeeded, else \c false. On failure, - * check the status with FLAC__metadata_chain_status(). - */ -FLAC_API FLAC__bool FLAC__metadata_chain_write(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats); - -/** Write all metadata out to a FLAC stream via callbacks. - * - * (See FLAC__metadata_chain_write() for the details on how padding is - * used to write metadata in place if possible.) - * - * The \a handle must be open for updating and be seekable. The - * equivalent minimum stdio fopen() file mode is \c "r+" (or \c "r+b" - * for Windows). - * - * For this write function to be used, the chain must have been read with - * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), - * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). - * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned - * \c false. - * - * \param chain A pointer to an existing chain. - * \param use_padding See FLAC__metadata_chain_write() - * \param handle The I/O handle of the FLAC stream to write. The - * handle will NOT be closed after the metadata is - * written; that is the duty of the caller. - * \param callbacks A set of callbacks to use for I/O. The mandatory - * callbacks are \a write and \a seek. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if the write succeeded, else \c false. On failure, - * check the status with FLAC__metadata_chain_status(). - */ -FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks); - -/** Write all metadata out to a FLAC stream via callbacks. - * - * (See FLAC__metadata_chain_write() for the details on how padding is - * used to write metadata in place if possible.) - * - * This version of the write-with-callbacks function must be used when - * FLAC__metadata_chain_check_if_tempfile_needed() returns true. In - * this function, you must supply an I/O handle corresponding to the - * FLAC file to edit, and a temporary handle to which the new FLAC - * file will be written. It is the caller's job to move this temporary - * FLAC file on top of the original FLAC file to complete the metadata - * edit. - * - * The \a handle must be open for reading and be seekable. The - * equivalent minimum stdio fopen() file mode is \c "r" (or \c "rb" - * for Windows). - * - * The \a temp_handle must be open for writing. The - * equivalent minimum stdio fopen() file mode is \c "w" (or \c "wb" - * for Windows). It should be an empty stream, or at least positioned - * at the start-of-file (in which case it is the caller's duty to - * truncate it on return). - * - * For this write function to be used, the chain must have been read with - * FLAC__metadata_chain_read_with_callbacks()/FLAC__metadata_chain_read_ogg_with_callbacks(), - * not FLAC__metadata_chain_read()/FLAC__metadata_chain_read_ogg(). - * Also, FLAC__metadata_chain_check_if_tempfile_needed() must have returned - * \c true. - * - * \param chain A pointer to an existing chain. - * \param use_padding See FLAC__metadata_chain_write() - * \param handle The I/O handle of the original FLAC stream to read. - * The handle will NOT be closed after the metadata is - * written; that is the duty of the caller. - * \param callbacks A set of callbacks to use for I/O on \a handle. - * The mandatory callbacks are \a read, \a seek, and - * \a eof. - * \param temp_handle The I/O handle of the FLAC stream to write. The - * handle will NOT be closed after the metadata is - * written; that is the duty of the caller. - * \param temp_callbacks - * A set of callbacks to use for I/O on temp_handle. - * The only mandatory callback is \a write. - * \assert - * \code chain != NULL \endcode - * \retval FLAC__bool - * \c true if the write succeeded, else \c false. On failure, - * check the status with FLAC__metadata_chain_status(). - */ -FLAC_API FLAC__bool FLAC__metadata_chain_write_with_callbacks_and_tempfile(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__IOHandle handle, FLAC__IOCallbacks callbacks, FLAC__IOHandle temp_handle, FLAC__IOCallbacks temp_callbacks); - -/** Merge adjacent PADDING blocks into a single block. - * - * \note This function does not write to the FLAC file, it only - * modifies the chain. - * - * \warning Any iterator on the current chain will become invalid after this - * call. You should delete the iterator and get a new one. - * - * \param chain A pointer to an existing chain. - * \assert - * \code chain != NULL \endcode - */ -FLAC_API void FLAC__metadata_chain_merge_padding(FLAC__Metadata_Chain *chain); - -/** This function will move all PADDING blocks to the end on the metadata, - * then merge them into a single block. - * - * \note This function does not write to the FLAC file, it only - * modifies the chain. - * - * \warning Any iterator on the current chain will become invalid after this - * call. You should delete the iterator and get a new one. - * - * \param chain A pointer to an existing chain. - * \assert - * \code chain != NULL \endcode - */ -FLAC_API void FLAC__metadata_chain_sort_padding(FLAC__Metadata_Chain *chain); - - -/*********** FLAC__Metadata_Iterator ***********/ - -/** Create a new iterator instance. - * - * \retval FLAC__Metadata_Iterator* - * \c NULL if there was an error allocating memory, else the new instance. - */ -FLAC_API FLAC__Metadata_Iterator *FLAC__metadata_iterator_new(void); - -/** Free an iterator instance. Deletes the object pointed to by \a iterator. - * - * \param iterator A pointer to an existing iterator. - * \assert - * \code iterator != NULL \endcode - */ -FLAC_API void FLAC__metadata_iterator_delete(FLAC__Metadata_Iterator *iterator); - -/** Initialize the iterator to point to the first metadata block in the - * given chain. - * - * \param iterator A pointer to an existing iterator. - * \param chain A pointer to an existing and initialized (read) chain. - * \assert - * \code iterator != NULL \endcode - * \code chain != NULL \endcode - */ -FLAC_API void FLAC__metadata_iterator_init(FLAC__Metadata_Iterator *iterator, FLAC__Metadata_Chain *chain); - -/** Moves the iterator forward one metadata block, returning \c false if - * already at the end. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if already at the last metadata block of the chain, else - * \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_iterator_next(FLAC__Metadata_Iterator *iterator); - -/** Moves the iterator backward one metadata block, returning \c false if - * already at the beginning. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if already at the first metadata block of the chain, else - * \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_iterator_prev(FLAC__Metadata_Iterator *iterator); - -/** Get the type of the metadata block at the current position. - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__MetadataType - * The type of the metadata block at the current iterator position. - */ -FLAC_API FLAC__MetadataType FLAC__metadata_iterator_get_block_type(const FLAC__Metadata_Iterator *iterator); - -/** Get the metadata block at the current position. You can modify - * the block in place but must write the chain before the changes - * are reflected to the FLAC file. You do not need to call - * FLAC__metadata_iterator_set_block() to reflect the changes; - * the pointer returned by FLAC__metadata_iterator_get_block() - * points directly into the chain. - * - * \warning - * Do not call FLAC__metadata_object_delete() on the returned object; - * to delete a block use FLAC__metadata_iterator_delete_block(). - * - * \param iterator A pointer to an existing initialized iterator. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__StreamMetadata* - * The current metadata block. - */ -FLAC_API FLAC__StreamMetadata *FLAC__metadata_iterator_get_block(FLAC__Metadata_Iterator *iterator); - -/** Set the metadata block at the current position, replacing the existing - * block. The new block passed in becomes owned by the chain and it will be - * deleted when the chain is deleted. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block A pointer to a metadata block. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \code block != NULL \endcode - * \retval FLAC__bool - * \c false if the conditions in the above description are not met, or - * a memory allocation error occurs, otherwise \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_iterator_set_block(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); - -/** Removes the current block from the chain. If \a replace_with_padding is - * \c true, the block will instead be replaced with a padding block of equal - * size. You can not delete the STREAMINFO block. The iterator will be - * left pointing to the block before the one just "deleted", even if - * \a replace_with_padding is \c true. - * - * \param iterator A pointer to an existing initialized iterator. - * \param replace_with_padding See above. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if the conditions in the above description are not met, - * otherwise \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_iterator_delete_block(FLAC__Metadata_Iterator *iterator, FLAC__bool replace_with_padding); - -/** Insert a new block before the current block. You cannot insert a block - * before the first STREAMINFO block. You cannot insert a STREAMINFO block - * as there can be only one, the one that already exists at the head when you - * read in a chain. The chain takes ownership of the new block and it will be - * deleted when the chain is deleted. The iterator will be left pointing to - * the new block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block A pointer to a metadata block to insert. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if the conditions in the above description are not met, or - * a memory allocation error occurs, otherwise \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_before(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); - -/** Insert a new block after the current block. You cannot insert a STREAMINFO - * block as there can be only one, the one that already exists at the head when - * you read in a chain. The chain takes ownership of the new block and it will - * be deleted when the chain is deleted. The iterator will be left pointing to - * the new block. - * - * \param iterator A pointer to an existing initialized iterator. - * \param block A pointer to a metadata block to insert. - * \assert - * \code iterator != NULL \endcode - * \a iterator has been successfully initialized with - * FLAC__metadata_iterator_init() - * \retval FLAC__bool - * \c false if the conditions in the above description are not met, or - * a memory allocation error occurs, otherwise \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_iterator_insert_block_after(FLAC__Metadata_Iterator *iterator, FLAC__StreamMetadata *block); - -/* \} */ - - -/** \defgroup flac_metadata_object FLAC/metadata.h: metadata object methods - * \ingroup flac_metadata - * - * \brief - * This module contains methods for manipulating FLAC metadata objects. - * - * Since many are variable length we have to be careful about the memory - * management. We decree that all pointers to data in the object are - * owned by the object and memory-managed by the object. - * - * Use the FLAC__metadata_object_new() and FLAC__metadata_object_delete() - * functions to create all instances. When using the - * FLAC__metadata_object_set_*() functions to set pointers to data, set - * \a copy to \c true to have the function make it's own copy of the data, or - * to \c false to give the object ownership of your data. In the latter case - * your pointer must be freeable by free() and will be free()d when the object - * is FLAC__metadata_object_delete()d. It is legal to pass a null pointer as - * the data pointer to a FLAC__metadata_object_set_*() function as long as - * the length argument is 0 and the \a copy argument is \c false. - * - * The FLAC__metadata_object_new() and FLAC__metadata_object_clone() function - * will return \c NULL in the case of a memory allocation error, otherwise a new - * object. The FLAC__metadata_object_set_*() functions return \c false in the - * case of a memory allocation error. - * - * We don't have the convenience of C++ here, so note that the library relies - * on you to keep the types straight. In other words, if you pass, for - * example, a FLAC__StreamMetadata* that represents a STREAMINFO block to - * FLAC__metadata_object_application_set_data(), you will get an assertion - * failure. - * - * For convenience the FLAC__metadata_object_vorbiscomment_*() functions - * maintain a trailing NUL on each Vorbis comment entry. This is not counted - * toward the length or stored in the stream, but it can make working with plain - * comments (those that don't contain embedded-NULs in the value) easier. - * Entries passed into these functions have trailing NULs added if missing, and - * returned entries are guaranteed to have a trailing NUL. - * - * The FLAC__metadata_object_vorbiscomment_*() functions that take a Vorbis - * comment entry/name/value will first validate that it complies with the Vorbis - * comment specification and return false if it does not. - * - * There is no need to recalculate the length field on metadata blocks you - * have modified. They will be calculated automatically before they are - * written back to a file. - * - * \{ - */ - - -/** Create a new metadata object instance of the given type. - * - * The object will be "empty"; i.e. values and data pointers will be \c 0, - * with the exception of FLAC__METADATA_TYPE_VORBIS_COMMENT, which will have - * the vendor string set (but zero comments). - * - * Do not pass in a value greater than or equal to - * \a FLAC__METADATA_TYPE_UNDEFINED unless you really know what you're - * doing. - * - * \param type Type of object to create - * \retval FLAC__StreamMetadata* - * \c NULL if there was an error allocating memory or the type code is - * greater than FLAC__MAX_METADATA_TYPE_CODE, else the new instance. - */ -FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_new(FLAC__MetadataType type); - -/** Create a copy of an existing metadata object. - * - * The copy is a "deep" copy, i.e. dynamically allocated data within the - * object is also copied. The caller takes ownership of the new block and - * is responsible for freeing it with FLAC__metadata_object_delete(). - * - * \param object Pointer to object to copy. - * \assert - * \code object != NULL \endcode - * \retval FLAC__StreamMetadata* - * \c NULL if there was an error allocating memory, else the new instance. - */ -FLAC_API FLAC__StreamMetadata *FLAC__metadata_object_clone(const FLAC__StreamMetadata *object); - -/** Free a metadata object. Deletes the object pointed to by \a object. - * - * The delete is a "deep" delete, i.e. dynamically allocated data within the - * object is also deleted. - * - * \param object A pointer to an existing object. - * \assert - * \code object != NULL \endcode - */ -FLAC_API void FLAC__metadata_object_delete(FLAC__StreamMetadata *object); - -/** Compares two metadata objects. - * - * The compare is "deep", i.e. dynamically allocated data within the - * object is also compared. - * - * \param block1 A pointer to an existing object. - * \param block2 A pointer to an existing object. - * \assert - * \code block1 != NULL \endcode - * \code block2 != NULL \endcode - * \retval FLAC__bool - * \c true if objects are identical, else \c false. - */ -FLAC_API FLAC__bool FLAC__metadata_object_is_equal(const FLAC__StreamMetadata *block1, const FLAC__StreamMetadata *block2); - -/** Sets the application data of an APPLICATION block. - * - * If \a copy is \c true, a copy of the data is stored; otherwise, the object - * takes ownership of the pointer. The existing data will be freed if this - * function is successful, otherwise the original data will remain if \a copy - * is \c true and malloc() fails. - * - * \note It is safe to pass a const pointer to \a data if \a copy is \c true. - * - * \param object A pointer to an existing APPLICATION object. - * \param data A pointer to the data to set. - * \param length The length of \a data in bytes. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_APPLICATION \endcode - * \code (data != NULL && length > 0) || - * (data == NULL && length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_application_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, unsigned length, FLAC__bool copy); - -/** Resize the seekpoint array. - * - * If the size shrinks, elements will truncated; if it grows, new placeholder - * points will be added to the end. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param new_num_points The desired length of the array; may be \c 0. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code (object->data.seek_table.points == NULL && object->data.seek_table.num_points == 0) || - * (object->data.seek_table.points != NULL && object->data.seek_table.num_points > 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_resize_points(FLAC__StreamMetadata *object, unsigned new_num_points); - -/** Set a seekpoint in a seektable. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param point_num Index into seekpoint array to set. - * \param point The point to set. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code object->data.seek_table.num_points > point_num \endcode - */ -FLAC_API void FLAC__metadata_object_seektable_set_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); - -/** Insert a seekpoint into a seektable. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param point_num Index into seekpoint array to set. - * \param point The point to set. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code object->data.seek_table.num_points >= point_num \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_insert_point(FLAC__StreamMetadata *object, unsigned point_num, FLAC__StreamMetadata_SeekPoint point); - -/** Delete a seekpoint from a seektable. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param point_num Index into seekpoint array to set. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code object->data.seek_table.num_points > point_num \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_delete_point(FLAC__StreamMetadata *object, unsigned point_num); - -/** Check a seektable to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * seektable. - * - * \param object A pointer to an existing SEEKTABLE object. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if seek table is illegal, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_is_legal(const FLAC__StreamMetadata *object); - -/** Append a number of placeholder points to the end of a seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param num The number of placeholder points to append. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_placeholders(FLAC__StreamMetadata *object, unsigned num); - -/** Append a specific seek point template to the end of a seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param sample_number The sample number of the seek point template. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_point(FLAC__StreamMetadata *object, FLAC__uint64 sample_number); - -/** Append specific seek point templates to the end of a seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param sample_numbers An array of sample numbers for the seek points. - * \param num The number of seek point templates to append. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_points(FLAC__StreamMetadata *object, FLAC__uint64 sample_numbers[], unsigned num); - -/** Append a set of evenly-spaced seek point templates to the end of a - * seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param num The number of placeholder points to append. - * \param total_samples The total number of samples to be encoded; - * the seekpoints will be spaced approximately - * \a total_samples / \a num samples apart. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code total_samples > 0 \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points(FLAC__StreamMetadata *object, unsigned num, FLAC__uint64 total_samples); - -/** Append a set of evenly-spaced seek point templates to the end of a - * seek table. - * - * \note - * As with the other ..._seektable_template_... functions, you should - * call FLAC__metadata_object_seektable_template_sort() when finished - * to make the seek table legal. - * - * \param object A pointer to an existing SEEKTABLE object. - * \param samples The number of samples apart to space the placeholder - * points. The first point will be at sample \c 0, the - * second at sample \a samples, then 2*\a samples, and - * so on. As long as \a samples and \a total_samples - * are greater than \c 0, there will always be at least - * one seekpoint at sample \c 0. - * \param total_samples The total number of samples to be encoded; - * the seekpoints will be spaced - * \a samples samples apart. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \code samples > 0 \endcode - * \code total_samples > 0 \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(FLAC__StreamMetadata *object, unsigned samples, FLAC__uint64 total_samples); - -/** Sort a seek table's seek points according to the format specification, - * removing duplicates. - * - * \param object A pointer to a seek table to be sorted. - * \param compact If \c false, behaves like FLAC__format_seektable_sort(). - * If \c true, duplicates are deleted and the seek table is - * shrunk appropriately; the number of placeholder points - * present in the seek table will be the same after the call - * as before. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_SEEKTABLE \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_seektable_template_sort(FLAC__StreamMetadata *object, FLAC__bool compact); - -/** Sets the vendor string in a VORBIS_COMMENT block. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param entry The entry to set the vendor string to. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_vendor_string(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); - -/** Resize the comment array. - * - * If the size shrinks, elements will truncated; if it grows, new empty - * fields will be added to the end. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param new_num_comments The desired length of the array; may be \c 0. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code (object->data.vorbis_comment.comments == NULL && object->data.vorbis_comment.num_comments == 0) || - * (object->data.vorbis_comment.comments != NULL && object->data.vorbis_comment.num_comments > 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_resize_comments(FLAC__StreamMetadata *object, unsigned new_num_comments); - -/** Sets a comment in a VORBIS_COMMENT block. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param comment_num Index into comment array to set. - * \param entry The entry to set the comment to. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code comment_num < object->data.vorbis_comment.num_comments \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_set_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); - -/** Insert a comment in a VORBIS_COMMENT block at the given index. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param comment_num The index at which to insert the comment. The comments - * at and after \a comment_num move right one position. - * To append a comment to the end, set \a comment_num to - * \c object->data.vorbis_comment.num_comments . - * \param entry The comment to insert. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code object->data.vorbis_comment.num_comments >= comment_num \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_insert_comment(FLAC__StreamMetadata *object, unsigned comment_num, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); - -/** Appends a comment to a VORBIS_COMMENT block. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param entry The comment to insert. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_append_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool copy); - -/** Replaces comments in a VORBIS_COMMENT block with a new one. - * - * For convenience, a trailing NUL is added to the entry if it doesn't have - * one already. - * - * Depending on the the value of \a all, either all or just the first comment - * whose field name(s) match the given entry's name will be replaced by the - * given entry. If no comments match, \a entry will simply be appended. - * - * If \a copy is \c true, a copy of the entry is stored; otherwise, the object - * takes ownership of the \c entry.entry pointer. - * - * \note If this function returns \c false, the caller still owns the - * pointer. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param entry The comment to insert. - * \param all If \c true, all comments whose field name matches - * \a entry's field name will be removed, and \a entry will - * be inserted at the position of the first matching - * comment. If \c false, only the first comment whose - * field name matches \a entry's field name will be - * replaced with \a entry. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code (entry.entry != NULL && entry.length > 0) || - * (entry.entry == NULL && entry.length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_replace_comment(FLAC__StreamMetadata *object, FLAC__StreamMetadata_VorbisComment_Entry entry, FLAC__bool all, FLAC__bool copy); - -/** Delete a comment in a VORBIS_COMMENT block at the given index. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param comment_num The index of the comment to delete. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code object->data.vorbis_comment.num_comments > comment_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_delete_comment(FLAC__StreamMetadata *object, unsigned comment_num); - -/** Creates a Vorbis comment entry from NUL-terminated name and value strings. - * - * On return, the filled-in \a entry->entry pointer will point to malloc()ed - * memory and shall be owned by the caller. For convenience the entry will - * have a terminating NUL. - * - * \param entry A pointer to a Vorbis comment entry. The entry's - * \c entry pointer should not point to allocated - * memory as it will be overwritten. - * \param field_name The field name in ASCII, \c NUL terminated. - * \param field_value The field value in UTF-8, \c NUL terminated. - * \assert - * \code entry != NULL \endcode - * \code field_name != NULL \endcode - * \code field_value != NULL \endcode - * \retval FLAC__bool - * \c false if malloc() fails, or if \a field_name or \a field_value does - * not comply with the Vorbis comment specification, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(FLAC__StreamMetadata_VorbisComment_Entry *entry, const char *field_name, const char *field_value); - -/** Splits a Vorbis comment entry into NUL-terminated name and value strings. - * - * The returned pointers to name and value will be allocated by malloc() - * and shall be owned by the caller. - * - * \param entry An existing Vorbis comment entry. - * \param field_name The address of where the returned pointer to the - * field name will be stored. - * \param field_value The address of where the returned pointer to the - * field value will be stored. - * \assert - * \code (entry.entry != NULL && entry.length > 0) \endcode - * \code memchr(entry.entry, '=', entry.length) != NULL \endcode - * \code field_name != NULL \endcode - * \code field_value != NULL \endcode - * \retval FLAC__bool - * \c false if memory allocation fails or \a entry does not comply with the - * Vorbis comment specification, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_to_name_value_pair(const FLAC__StreamMetadata_VorbisComment_Entry entry, char **field_name, char **field_value); - -/** Check if the given Vorbis comment entry's field name matches the given - * field name. - * - * \param entry An existing Vorbis comment entry. - * \param field_name The field name to check. - * \param field_name_length The length of \a field_name, not including the - * terminating \c NUL. - * \assert - * \code (entry.entry != NULL && entry.length > 0) \endcode - * \retval FLAC__bool - * \c true if the field names match, else \c false - */ -FLAC_API FLAC__bool FLAC__metadata_object_vorbiscomment_entry_matches(const FLAC__StreamMetadata_VorbisComment_Entry entry, const char *field_name, unsigned field_name_length); - -/** Find a Vorbis comment with the given field name. - * - * The search begins at entry number \a offset; use an offset of 0 to - * search from the beginning of the comment array. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param offset The offset into the comment array from where to start - * the search. - * \param field_name The field name of the comment to find. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \code field_name != NULL \endcode - * \retval int - * The offset in the comment array of the first comment whose field - * name matches \a field_name, or \c -1 if no match was found. - */ -FLAC_API int FLAC__metadata_object_vorbiscomment_find_entry_from(const FLAC__StreamMetadata *object, unsigned offset, const char *field_name); - -/** Remove first Vorbis comment matching the given field name. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param field_name The field name of comment to delete. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \retval int - * \c -1 for memory allocation error, \c 0 for no matching entries, - * \c 1 for one matching entry deleted. - */ -FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entry_matching(FLAC__StreamMetadata *object, const char *field_name); - -/** Remove all Vorbis comments matching the given field name. - * - * \param object A pointer to an existing VORBIS_COMMENT object. - * \param field_name The field name of comments to delete. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_VORBIS_COMMENT \endcode - * \retval int - * \c -1 for memory allocation error, \c 0 for no matching entries, - * else the number of matching entries deleted. - */ -FLAC_API int FLAC__metadata_object_vorbiscomment_remove_entries_matching(FLAC__StreamMetadata *object, const char *field_name); - -/** Create a new CUESHEET track instance. - * - * The object will be "empty"; i.e. values and data pointers will be \c 0. - * - * \retval FLAC__StreamMetadata_CueSheet_Track* - * \c NULL if there was an error allocating memory, else the new instance. - */ -FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_new(void); - -/** Create a copy of an existing CUESHEET track object. - * - * The copy is a "deep" copy, i.e. dynamically allocated data within the - * object is also copied. The caller takes ownership of the new object and - * is responsible for freeing it with - * FLAC__metadata_object_cuesheet_track_delete(). - * - * \param object Pointer to object to copy. - * \assert - * \code object != NULL \endcode - * \retval FLAC__StreamMetadata_CueSheet_Track* - * \c NULL if there was an error allocating memory, else the new instance. - */ -FLAC_API FLAC__StreamMetadata_CueSheet_Track *FLAC__metadata_object_cuesheet_track_clone(const FLAC__StreamMetadata_CueSheet_Track *object); - -/** Delete a CUESHEET track object - * - * \param object A pointer to an existing CUESHEET track object. - * \assert - * \code object != NULL \endcode - */ -FLAC_API void FLAC__metadata_object_cuesheet_track_delete(FLAC__StreamMetadata_CueSheet_Track *object); - -/** Resize a track's index point array. - * - * If the size shrinks, elements will truncated; if it grows, new blank - * indices will be added to the end. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index of the track to modify. NOTE: this is not - * necessarily the same as the track's \a number field. - * \param new_num_indices The desired length of the array; may be \c 0. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \code (object->data.cue_sheet.tracks[track_num].indices == NULL && object->data.cue_sheet.tracks[track_num].num_indices == 0) || - * (object->data.cue_sheet.tracks[track_num].indices != NULL && object->data.cue_sheet.tracks[track_num].num_indices > 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_resize_indices(FLAC__StreamMetadata *object, unsigned track_num, unsigned new_num_indices); - -/** Insert an index point in a CUESHEET track at the given index. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index of the track to modify. NOTE: this is not - * necessarily the same as the track's \a number field. - * \param index_num The index into the track's index array at which to - * insert the index point. NOTE: this is not necessarily - * the same as the index point's \a number field. The - * indices at and after \a index_num move right one - * position. To append an index point to the end, set - * \a index_num to - * \c object->data.cue_sheet.tracks[track_num].num_indices . - * \param index The index point to insert. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num, FLAC__StreamMetadata_CueSheet_Index index); - -/** Insert a blank index point in a CUESHEET track at the given index. - * - * A blank index point is one in which all field values are zero. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index of the track to modify. NOTE: this is not - * necessarily the same as the track's \a number field. - * \param index_num The index into the track's index array at which to - * insert the index point. NOTE: this is not necessarily - * the same as the index point's \a number field. The - * indices at and after \a index_num move right one - * position. To append an index point to the end, set - * \a index_num to - * \c object->data.cue_sheet.tracks[track_num].num_indices . - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \code object->data.cue_sheet.tracks[track_num].num_indices >= index_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_insert_blank_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); - -/** Delete an index point in a CUESHEET track at the given index. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index into the track array of the track to - * modify. NOTE: this is not necessarily the same - * as the track's \a number field. - * \param index_num The index into the track's index array of the index - * to delete. NOTE: this is not necessarily the same - * as the index's \a number field. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \code object->data.cue_sheet.tracks[track_num].num_indices > index_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_track_delete_index(FLAC__StreamMetadata *object, unsigned track_num, unsigned index_num); - -/** Resize the track array. - * - * If the size shrinks, elements will truncated; if it grows, new blank - * tracks will be added to the end. - * - * \param object A pointer to an existing CUESHEET object. - * \param new_num_tracks The desired length of the array; may be \c 0. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code (object->data.cue_sheet.tracks == NULL && object->data.cue_sheet.num_tracks == 0) || - * (object->data.cue_sheet.tracks != NULL && object->data.cue_sheet.num_tracks > 0) \endcode - * \retval FLAC__bool - * \c false if memory allocation error, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_resize_tracks(FLAC__StreamMetadata *object, unsigned new_num_tracks); - -/** Sets a track in a CUESHEET block. - * - * If \a copy is \c true, a copy of the track is stored; otherwise, the object - * takes ownership of the \a track pointer. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num Index into track array to set. NOTE: this is not - * necessarily the same as the track's \a number field. - * \param track The track to set the track to. You may safely pass in - * a const pointer if \a copy is \c true. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code track_num < object->data.cue_sheet.num_tracks \endcode - * \code (track->indices != NULL && track->num_indices > 0) || - * (track->indices == NULL && track->num_indices == 0) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_set_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); - -/** Insert a track in a CUESHEET block at the given index. - * - * If \a copy is \c true, a copy of the track is stored; otherwise, the object - * takes ownership of the \a track pointer. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index at which to insert the track. NOTE: this - * is not necessarily the same as the track's \a number - * field. The tracks at and after \a track_num move right - * one position. To append a track to the end, set - * \a track_num to \c object->data.cue_sheet.num_tracks . - * \param track The track to insert. You may safely pass in a const - * pointer if \a copy is \c true. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks >= track_num \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_track(FLAC__StreamMetadata *object, unsigned track_num, FLAC__StreamMetadata_CueSheet_Track *track, FLAC__bool copy); - -/** Insert a blank track in a CUESHEET block at the given index. - * - * A blank track is one in which all field values are zero. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index at which to insert the track. NOTE: this - * is not necessarily the same as the track's \a number - * field. The tracks at and after \a track_num move right - * one position. To append a track to the end, set - * \a track_num to \c object->data.cue_sheet.num_tracks . - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks >= track_num \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_insert_blank_track(FLAC__StreamMetadata *object, unsigned track_num); - -/** Delete a track in a CUESHEET block at the given index. - * - * \param object A pointer to an existing CUESHEET object. - * \param track_num The index into the track array of the track to - * delete. NOTE: this is not necessarily the same - * as the track's \a number field. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \code object->data.cue_sheet.num_tracks > track_num \endcode - * \retval FLAC__bool - * \c false if realloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_delete_track(FLAC__StreamMetadata *object, unsigned track_num); - -/** Check a cue sheet to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * cue sheet. - * - * \param object A pointer to an existing CUESHEET object. - * \param check_cd_da_subset If \c true, check CUESHEET against more - * stringent requirements for a CD-DA (audio) disc. - * \param violation Address of a pointer to a string. If there is a - * violation, a pointer to a string explanation of the - * violation will be returned here. \a violation may be - * \c NULL if you don't need the returned string. Do not - * free the returned string; it will always point to static - * data. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \retval FLAC__bool - * \c false if cue sheet is illegal, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_cuesheet_is_legal(const FLAC__StreamMetadata *object, FLAC__bool check_cd_da_subset, const char **violation); - -/** Calculate and return the CDDB/freedb ID for a cue sheet. The function - * assumes the cue sheet corresponds to a CD; the result is undefined - * if the cuesheet's is_cd bit is not set. - * - * \param object A pointer to an existing CUESHEET object. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_CUESHEET \endcode - * \retval FLAC__uint32 - * The unsigned integer representation of the CDDB/freedb ID - */ -FLAC_API FLAC__uint32 FLAC__metadata_object_cuesheet_calculate_cddb_id(const FLAC__StreamMetadata *object); - -/** Sets the MIME type of a PICTURE block. - * - * If \a copy is \c true, a copy of the string is stored; otherwise, the object - * takes ownership of the pointer. The existing string will be freed if this - * function is successful, otherwise the original string will remain if \a copy - * is \c true and malloc() fails. - * - * \note It is safe to pass a const pointer to \a mime_type if \a copy is \c true. - * - * \param object A pointer to an existing PICTURE object. - * \param mime_type A pointer to the MIME type string. The string must be - * ASCII characters 0x20-0x7e, NUL-terminated. No validation - * is done. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode - * \code (mime_type != NULL) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_picture_set_mime_type(FLAC__StreamMetadata *object, char *mime_type, FLAC__bool copy); - -/** Sets the description of a PICTURE block. - * - * If \a copy is \c true, a copy of the string is stored; otherwise, the object - * takes ownership of the pointer. The existing string will be freed if this - * function is successful, otherwise the original string will remain if \a copy - * is \c true and malloc() fails. - * - * \note It is safe to pass a const pointer to \a description if \a copy is \c true. - * - * \param object A pointer to an existing PICTURE object. - * \param description A pointer to the description string. The string must be - * valid UTF-8, NUL-terminated. No validation is done. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode - * \code (description != NULL) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_picture_set_description(FLAC__StreamMetadata *object, FLAC__byte *description, FLAC__bool copy); - -/** Sets the picture data of a PICTURE block. - * - * If \a copy is \c true, a copy of the data is stored; otherwise, the object - * takes ownership of the pointer. Also sets the \a data_length field of the - * metadata object to what is passed in as the \a length parameter. The - * existing data will be freed if this function is successful, otherwise the - * original data and data_length will remain if \a copy is \c true and - * malloc() fails. - * - * \note It is safe to pass a const pointer to \a data if \a copy is \c true. - * - * \param object A pointer to an existing PICTURE object. - * \param data A pointer to the data to set. - * \param length The length of \a data in bytes. - * \param copy See above. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode - * \code (data != NULL && length > 0) || - * (data == NULL && length == 0 && copy == false) \endcode - * \retval FLAC__bool - * \c false if \a copy is \c true and malloc() fails, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_picture_set_data(FLAC__StreamMetadata *object, FLAC__byte *data, FLAC__uint32 length, FLAC__bool copy); - -/** Check a PICTURE block to see if it conforms to the FLAC specification. - * See the format specification for limits on the contents of the - * PICTURE block. - * - * \param object A pointer to existing PICTURE block to be checked. - * \param violation Address of a pointer to a string. If there is a - * violation, a pointer to a string explanation of the - * violation will be returned here. \a violation may be - * \c NULL if you don't need the returned string. Do not - * free the returned string; it will always point to static - * data. - * \assert - * \code object != NULL \endcode - * \code object->type == FLAC__METADATA_TYPE_PICTURE \endcode - * \retval FLAC__bool - * \c false if PICTURE block is illegal, else \c true. - */ -FLAC_API FLAC__bool FLAC__metadata_object_picture_is_legal(const FLAC__StreamMetadata *object, const char **violation); - -/* \} */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/Windows/include/FLAC/ordinals.h b/platform/Windows/include/FLAC/ordinals.h deleted file mode 100644 index a05729973..000000000 --- a/platform/Windows/include/FLAC/ordinals.h +++ /dev/null @@ -1,86 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 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 . - */ - -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 . */ - -#include - -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 diff --git a/platform/Windows/include/FLAC/stream_decoder.h b/platform/Windows/include/FLAC/stream_decoder.h deleted file mode 100644 index 152643fcb..000000000 --- a/platform/Windows/include/FLAC/stream_decoder.h +++ /dev/null @@ -1,1560 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 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__STREAM_DECODER_H -#define FLAC__STREAM_DECODER_H - -#include /* for FILE */ -#include "export.h" -#include "format.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** \file include/FLAC/stream_decoder.h - * - * \brief - * This module contains the functions which implement the stream - * decoder. - * - * See the detailed documentation in the - * \link flac_stream_decoder stream decoder \endlink module. - */ - -/** \defgroup flac_decoder FLAC/ \*_decoder.h: decoder interfaces - * \ingroup flac - * - * \brief - * This module describes the decoder layers provided by libFLAC. - * - * The stream decoder can be used to decode complete streams either from - * the client via callbacks, or directly from a file, depending on how - * it is initialized. When decoding via callbacks, the client provides - * callbacks for reading FLAC data and writing decoded samples, and - * handling metadata and errors. If the client also supplies seek-related - * callback, the decoder function for sample-accurate seeking within the - * FLAC input is also available. When decoding from a file, the client - * needs only supply a filename or open \c FILE* and write/metadata/error - * callbacks; the rest of the callbacks are supplied internally. For more - * info see the \link flac_stream_decoder stream decoder \endlink module. - */ - -/** \defgroup flac_stream_decoder FLAC/stream_decoder.h: stream decoder interface - * \ingroup flac_decoder - * - * \brief - * This module contains the functions which implement the stream - * decoder. - * - * The stream decoder can decode native FLAC, and optionally Ogg FLAC - * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. - * - * The basic usage of this decoder is as follows: - * - The program creates an instance of a decoder using - * FLAC__stream_decoder_new(). - * - The program overrides the default settings using - * FLAC__stream_decoder_set_*() functions. - * - The program initializes the instance to validate the settings and - * prepare for decoding using - * - FLAC__stream_decoder_init_stream() or FLAC__stream_decoder_init_FILE() - * or FLAC__stream_decoder_init_file() for native FLAC, - * - FLAC__stream_decoder_init_ogg_stream() or FLAC__stream_decoder_init_ogg_FILE() - * or FLAC__stream_decoder_init_ogg_file() for Ogg FLAC - * - The program calls the FLAC__stream_decoder_process_*() functions - * to decode data, which subsequently calls the callbacks. - * - The program finishes the decoding with FLAC__stream_decoder_finish(), - * which flushes the input and output and resets the decoder to the - * uninitialized state. - * - The instance may be used again or deleted with - * FLAC__stream_decoder_delete(). - * - * In more detail, the program will create a new instance by calling - * FLAC__stream_decoder_new(), then call FLAC__stream_decoder_set_*() - * functions to override the default decoder options, and call - * one of the FLAC__stream_decoder_init_*() functions. - * - * There are three initialization functions for native FLAC, one for - * setting up the decoder to decode FLAC data from the client via - * callbacks, and two for decoding directly from a FLAC file. - * - * For decoding via callbacks, use FLAC__stream_decoder_init_stream(). - * You must also supply several callbacks for handling I/O. Some (like - * seeking) are optional, depending on the capabilities of the input. - * - * For decoding directly from a file, use FLAC__stream_decoder_init_FILE() - * or FLAC__stream_decoder_init_file(). Then you must only supply an open - * \c FILE* or filename and fewer callbacks; the decoder will handle - * the other callbacks internally. - * - * There are three similarly-named init functions for decoding from Ogg - * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the - * library has been built with Ogg support. - * - * Once the decoder is initialized, your program will call one of several - * functions to start the decoding process: - * - * - FLAC__stream_decoder_process_single() - Tells the decoder to process at - * most one metadata block or audio frame and return, calling either the - * metadata callback or write callback, respectively, once. If the decoder - * loses sync it will return with only the error callback being called. - * - FLAC__stream_decoder_process_until_end_of_metadata() - Tells the decoder - * to process the stream from the current location and stop upon reaching - * the first audio frame. The client will get one metadata, write, or error - * callback per metadata block, audio frame, or sync error, respectively. - * - FLAC__stream_decoder_process_until_end_of_stream() - Tells the decoder - * to process the stream from the current location until the read callback - * returns FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM or - * FLAC__STREAM_DECODER_READ_STATUS_ABORT. The client will get one metadata, - * write, or error callback per metadata block, audio frame, or sync error, - * respectively. - * - * When the decoder has finished decoding (normally or through an abort), - * the instance is finished by calling FLAC__stream_decoder_finish(), which - * ensures the decoder is in the correct state and frees memory. Then the - * instance may be deleted with FLAC__stream_decoder_delete() or initialized - * again to decode another stream. - * - * Seeking is exposed through the FLAC__stream_decoder_seek_absolute() method. - * At any point after the stream decoder has been initialized, the client can - * call this function to seek to an exact sample within the stream. - * Subsequently, the first time the write callback is called it will be - * passed a (possibly partial) block starting at that sample. - * - * If the client cannot seek via the callback interface provided, but still - * has another way of seeking, it can flush the decoder using - * FLAC__stream_decoder_flush() and start feeding data from the new position - * through the read callback. - * - * The stream decoder also provides MD5 signature checking. If this is - * turned on before initialization, FLAC__stream_decoder_finish() will - * report when the decoded MD5 signature does not match the one stored - * in the STREAMINFO block. MD5 checking is automatically turned off - * (until the next FLAC__stream_decoder_reset()) if there is no signature - * in the STREAMINFO block or when a seek is attempted. - * - * The FLAC__stream_decoder_set_metadata_*() functions deserve special - * attention. By default, the decoder only calls the metadata_callback for - * the STREAMINFO block. These functions allow you to tell the decoder - * explicitly which blocks to parse and return via the metadata_callback - * and/or which to skip. Use a FLAC__stream_decoder_set_metadata_respond_all(), - * FLAC__stream_decoder_set_metadata_ignore() ... or FLAC__stream_decoder_set_metadata_ignore_all(), - * FLAC__stream_decoder_set_metadata_respond() ... sequence to exactly specify - * which blocks to return. Remember that metadata blocks can potentially - * be big (for example, cover art) so filtering out the ones you don't - * use can reduce the memory requirements of the decoder. Also note the - * special forms FLAC__stream_decoder_set_metadata_respond_application(id) - * and FLAC__stream_decoder_set_metadata_ignore_application(id) for - * filtering APPLICATION blocks based on the application ID. - * - * STREAMINFO and SEEKTABLE blocks are always parsed and used internally, but - * they still can legally be filtered from the metadata_callback. - * - * \note - * The "set" functions may only be called when the decoder is in the - * state FLAC__STREAM_DECODER_UNINITIALIZED, i.e. after - * FLAC__stream_decoder_new() or FLAC__stream_decoder_finish(), but - * before FLAC__stream_decoder_init_*(). If this is the case they will - * return \c true, otherwise \c false. - * - * \note - * FLAC__stream_decoder_finish() resets all settings to the constructor - * defaults, including the callbacks. - * - * \{ - */ - - -/** State values for a FLAC__StreamDecoder - * - * The decoder's state can be obtained by calling FLAC__stream_decoder_get_state(). - */ -typedef enum { - - FLAC__STREAM_DECODER_SEARCH_FOR_METADATA = 0, - /**< The decoder is ready to search for metadata. */ - - FLAC__STREAM_DECODER_READ_METADATA, - /**< The decoder is ready to or is in the process of reading metadata. */ - - FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC, - /**< The decoder is ready to or is in the process of searching for the - * frame sync code. - */ - - FLAC__STREAM_DECODER_READ_FRAME, - /**< The decoder is ready to or is in the process of reading a frame. */ - - FLAC__STREAM_DECODER_END_OF_STREAM, - /**< The decoder has reached the end of the stream. */ - - FLAC__STREAM_DECODER_OGG_ERROR, - /**< An error occurred in the underlying Ogg layer. */ - - FLAC__STREAM_DECODER_SEEK_ERROR, - /**< An error occurred while seeking. The decoder must be flushed - * with FLAC__stream_decoder_flush() or reset with - * FLAC__stream_decoder_reset() before decoding can continue. - */ - - FLAC__STREAM_DECODER_ABORTED, - /**< The decoder was aborted by the read callback. */ - - FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR, - /**< An error occurred allocating memory. The decoder is in an invalid - * state and can no longer be used. - */ - - FLAC__STREAM_DECODER_UNINITIALIZED - /**< The decoder is in the uninitialized state; one of the - * FLAC__stream_decoder_init_*() functions must be called before samples - * can be processed. - */ - -} FLAC__StreamDecoderState; - -/** Maps a FLAC__StreamDecoderState to a C string. - * - * Using a FLAC__StreamDecoderState as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamDecoderStateString[]; - - -/** Possible return values for the FLAC__stream_decoder_init_*() functions. - */ -typedef enum { - - FLAC__STREAM_DECODER_INIT_STATUS_OK = 0, - /**< Initialization was successful. */ - - FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER, - /**< The library was not compiled with support for the given container - * format. - */ - - FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS, - /**< A required callback was not supplied. */ - - FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR, - /**< An error occurred allocating memory. */ - - FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE, - /**< fopen() failed in FLAC__stream_decoder_init_file() or - * FLAC__stream_decoder_init_ogg_file(). */ - - FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED - /**< FLAC__stream_decoder_init_*() was called when the decoder was - * already initialized, usually because - * FLAC__stream_decoder_finish() was not called. - */ - -} FLAC__StreamDecoderInitStatus; - -/** Maps a FLAC__StreamDecoderInitStatus to a C string. - * - * Using a FLAC__StreamDecoderInitStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamDecoderInitStatusString[]; - - -/** Return values for the FLAC__StreamDecoder read callback. - */ -typedef enum { - - FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, - /**< The read was OK and decoding can continue. */ - - FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM, - /**< The read was attempted while at the end of the stream. Note that - * the client must only return this value when the read callback was - * called when already at the end of the stream. Otherwise, if the read - * itself moves to the end of the stream, the client should still return - * the data and \c FLAC__STREAM_DECODER_READ_STATUS_CONTINUE, and then on - * the next read callback it should return - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM with a byte count - * of \c 0. - */ - - FLAC__STREAM_DECODER_READ_STATUS_ABORT - /**< An unrecoverable error occurred. The decoder will return from the process call. */ - -} FLAC__StreamDecoderReadStatus; - -/** Maps a FLAC__StreamDecoderReadStatus to a C string. - * - * Using a FLAC__StreamDecoderReadStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamDecoderReadStatusString[]; - - -/** Return values for the FLAC__StreamDecoder seek callback. - */ -typedef enum { - - FLAC__STREAM_DECODER_SEEK_STATUS_OK, - /**< The seek was OK and decoding can continue. */ - - FLAC__STREAM_DECODER_SEEK_STATUS_ERROR, - /**< An unrecoverable error occurred. The decoder will return from the process call. */ - - FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED - /**< Client does not support seeking. */ - -} FLAC__StreamDecoderSeekStatus; - -/** Maps a FLAC__StreamDecoderSeekStatus to a C string. - * - * Using a FLAC__StreamDecoderSeekStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamDecoderSeekStatusString[]; - - -/** Return values for the FLAC__StreamDecoder tell callback. - */ -typedef enum { - - FLAC__STREAM_DECODER_TELL_STATUS_OK, - /**< The tell was OK and decoding can continue. */ - - FLAC__STREAM_DECODER_TELL_STATUS_ERROR, - /**< An unrecoverable error occurred. The decoder will return from the process call. */ - - FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED - /**< Client does not support telling the position. */ - -} FLAC__StreamDecoderTellStatus; - -/** Maps a FLAC__StreamDecoderTellStatus to a C string. - * - * Using a FLAC__StreamDecoderTellStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamDecoderTellStatusString[]; - - -/** Return values for the FLAC__StreamDecoder length callback. - */ -typedef enum { - - FLAC__STREAM_DECODER_LENGTH_STATUS_OK, - /**< The length call was OK and decoding can continue. */ - - FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR, - /**< An unrecoverable error occurred. The decoder will return from the process call. */ - - FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED - /**< Client does not support reporting the length. */ - -} FLAC__StreamDecoderLengthStatus; - -/** Maps a FLAC__StreamDecoderLengthStatus to a C string. - * - * Using a FLAC__StreamDecoderLengthStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamDecoderLengthStatusString[]; - - -/** Return values for the FLAC__StreamDecoder write callback. - */ -typedef enum { - - FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE, - /**< The write was OK and decoding can continue. */ - - FLAC__STREAM_DECODER_WRITE_STATUS_ABORT - /**< An unrecoverable error occurred. The decoder will return from the process call. */ - -} FLAC__StreamDecoderWriteStatus; - -/** Maps a FLAC__StreamDecoderWriteStatus to a C string. - * - * Using a FLAC__StreamDecoderWriteStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamDecoderWriteStatusString[]; - - -/** Possible values passed back to the FLAC__StreamDecoder error callback. - * \c FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC is the generic catch- - * all. The rest could be caused by bad sync (false synchronization on - * data that is not the start of a frame) or corrupted data. The error - * itself is the decoder's best guess at what happened assuming a correct - * sync. For example \c FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER - * could be caused by a correct sync on the start of a frame, but some - * data in the frame header was corrupted. Or it could be the result of - * syncing on a point the stream that looked like the starting of a frame - * but was not. \c FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM - * could be because the decoder encountered a valid frame made by a future - * version of the encoder which it cannot parse, or because of a false - * sync making it appear as though an encountered frame was generated by - * a future encoder. - */ -typedef enum { - - FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC, - /**< An error in the stream caused the decoder to lose synchronization. */ - - FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER, - /**< The decoder encountered a corrupted frame header. */ - - FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH, - /**< The frame's data did not match the CRC in the footer. */ - - FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM - /**< The decoder encountered reserved fields in use in the stream. */ - -} FLAC__StreamDecoderErrorStatus; - -/** Maps a FLAC__StreamDecoderErrorStatus to a C string. - * - * Using a FLAC__StreamDecoderErrorStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamDecoderErrorStatusString[]; - - -/*********************************************************************** - * - * class FLAC__StreamDecoder - * - ***********************************************************************/ - -struct FLAC__StreamDecoderProtected; -struct FLAC__StreamDecoderPrivate; -/** The opaque structure definition for the stream decoder type. - * See the \link flac_stream_decoder stream decoder module \endlink - * for a detailed description. - */ -typedef struct { - struct FLAC__StreamDecoderProtected *protected_; /* avoid the C++ keyword 'protected' */ - struct FLAC__StreamDecoderPrivate *private_; /* avoid the C++ keyword 'private' */ -} FLAC__StreamDecoder; - -/** Signature for the read callback. - * - * A function pointer matching this signature must be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder needs more input data. The address of the - * buffer to be filled is supplied, along with the number of bytes the - * buffer can hold. The callback may choose to supply less data and - * modify the byte count but must be careful not to overflow the buffer. - * The callback then returns a status code chosen from - * FLAC__StreamDecoderReadStatus. - * - * Here is an example of a read callback for stdio streams: - * \code - * FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * if(*bytes > 0) { - * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); - * if(ferror(file)) - * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; - * else if(*bytes == 0) - * return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; - * else - * return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; - * } - * else - * return FLAC__STREAM_DECODER_READ_STATUS_ABORT; - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param buffer A pointer to a location for the callee to store - * data to be decoded. - * \param bytes A pointer to the size of the buffer. On entry - * to the callback, it contains the maximum number - * of bytes that may be stored in \a buffer. The - * callee must set it to the actual number of bytes - * stored (0 in case of error or end-of-stream) before - * returning. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderReadStatus - * The callee's return status. Note that the callback should return - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM if and only if - * zero bytes were read and there is no more data to be read. - */ -typedef FLAC__StreamDecoderReadStatus (*FLAC__StreamDecoderReadCallback)(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data); - -/** Signature for the seek callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder needs to seek the input stream. The decoder - * will pass the absolute byte offset to seek to, 0 meaning the - * beginning of the stream. - * - * Here is an example of a seek callback for stdio streams: - * \code - * FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * if(file == stdin) - * return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; - * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) - * return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; - * else - * return FLAC__STREAM_DECODER_SEEK_STATUS_OK; - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param absolute_byte_offset The offset from the beginning of the stream - * to seek to. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderSeekStatus - * The callee's return status. - */ -typedef FLAC__StreamDecoderSeekStatus (*FLAC__StreamDecoderSeekCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data); - -/** Signature for the tell callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder wants to know the current position of the - * stream. The callback should return the byte offset from the - * beginning of the stream. - * - * Here is an example of a tell callback for stdio streams: - * \code - * FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * off_t pos; - * if(file == stdin) - * return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; - * else if((pos = ftello(file)) < 0) - * return FLAC__STREAM_DECODER_TELL_STATUS_ERROR; - * else { - * *absolute_byte_offset = (FLAC__uint64)pos; - * return FLAC__STREAM_DECODER_TELL_STATUS_OK; - * } - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param absolute_byte_offset A pointer to storage for the current offset - * from the beginning of the stream. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderTellStatus - * The callee's return status. - */ -typedef FLAC__StreamDecoderTellStatus (*FLAC__StreamDecoderTellCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data); - -/** Signature for the length callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder wants to know the total length of the stream - * in bytes. - * - * Here is an example of a length callback for stdio streams: - * \code - * FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * struct stat filestats; - * - * if(file == stdin) - * return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; - * else if(fstat(fileno(file), &filestats) != 0) - * return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; - * else { - * *stream_length = (FLAC__uint64)filestats.st_size; - * return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; - * } - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param stream_length A pointer to storage for the length of the stream - * in bytes. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderLengthStatus - * The callee's return status. - */ -typedef FLAC__StreamDecoderLengthStatus (*FLAC__StreamDecoderLengthCallback)(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data); - -/** Signature for the EOF callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_decoder_init*_stream(). The supplied function will be - * called when the decoder needs to know if the end of the stream has - * been reached. - * - * Here is an example of a EOF callback for stdio streams: - * FLAC__bool eof_cb(const FLAC__StreamDecoder *decoder, void *client_data) - * \code - * { - * FILE *file = ((MyClientData*)client_data)->file; - * return feof(file)? true : false; - * } - * \endcode - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__bool - * \c true if the currently at the end of the stream, else \c false. - */ -typedef FLAC__bool (*FLAC__StreamDecoderEofCallback)(const FLAC__StreamDecoder *decoder, void *client_data); - -/** Signature for the write callback. - * - * A function pointer matching this signature must be passed to one of - * the FLAC__stream_decoder_init_*() functions. - * The supplied function will be called when the decoder has decoded a - * single audio frame. The decoder will pass the frame metadata as well - * as an array of pointers (one for each channel) pointing to the - * decoded audio. - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param frame The description of the decoded frame. See - * FLAC__Frame. - * \param buffer An array of pointers to decoded channels of data. - * Each pointer will point to an array of signed - * samples of length \a frame->header.blocksize. - * Channels will be ordered according to the FLAC - * specification; see the documentation for the - * frame header. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - * \retval FLAC__StreamDecoderWriteStatus - * The callee's return status. - */ -typedef FLAC__StreamDecoderWriteStatus (*FLAC__StreamDecoderWriteCallback)(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data); - -/** Signature for the metadata callback. - * - * A function pointer matching this signature must be passed to one of - * the FLAC__stream_decoder_init_*() functions. - * The supplied function will be called when the decoder has decoded a - * metadata block. In a valid FLAC file there will always be one - * \c STREAMINFO block, followed by zero or more other metadata blocks. - * These will be supplied by the decoder in the same order as they - * appear in the stream and always before the first audio frame (i.e. - * write callback). The metadata block that is passed in must not be - * modified, and it doesn't live beyond the callback, so you should make - * a copy of it with FLAC__metadata_object_clone() if you will need it - * elsewhere. Since metadata blocks can potentially be large, by - * default the decoder only calls the metadata callback for the - * \c STREAMINFO block; you can instruct the decoder to pass or filter - * other blocks with FLAC__stream_decoder_set_metadata_*() calls. - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param metadata The decoded metadata block. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - */ -typedef void (*FLAC__StreamDecoderMetadataCallback)(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data); - -/** Signature for the error callback. - * - * A function pointer matching this signature must be passed to one of - * the FLAC__stream_decoder_init_*() functions. - * The supplied function will be called whenever an error occurs during - * decoding. - * - * \note In general, FLAC__StreamDecoder functions which change the - * state should not be called on the \a decoder while in the callback. - * - * \param decoder The decoder instance calling the callback. - * \param status The error encountered by the decoder. - * \param client_data The callee's client data set through - * FLAC__stream_decoder_init_*(). - */ -typedef void (*FLAC__StreamDecoderErrorCallback)(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data); - - -/*********************************************************************** - * - * Class constructor/destructor - * - ***********************************************************************/ - -/** Create a new stream decoder instance. The instance is created with - * default settings; see the individual FLAC__stream_decoder_set_*() - * functions for each setting's default. - * - * \retval FLAC__StreamDecoder* - * \c NULL if there was an error allocating memory, else the new instance. - */ -FLAC_API FLAC__StreamDecoder *FLAC__stream_decoder_new(void); - -/** Free a decoder instance. Deletes the object pointed to by \a decoder. - * - * \param decoder A pointer to an existing decoder. - * \assert - * \code decoder != NULL \endcode - */ -FLAC_API void FLAC__stream_decoder_delete(FLAC__StreamDecoder *decoder); - - -/*********************************************************************** - * - * Public class method prototypes - * - ***********************************************************************/ - -/** Set the serial number for the FLAC stream within the Ogg container. - * The default behavior is to use the serial number of the first Ogg - * page. Setting a serial number here will explicitly specify which - * stream is to be decoded. - * - * \note - * This does not need to be set for native FLAC decoding. - * - * \default \c use serial number of first page - * \param decoder A decoder instance to set. - * \param serial_number See above. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_ogg_serial_number(FLAC__StreamDecoder *decoder, long serial_number); - -/** Set the "MD5 signature checking" flag. If \c true, the decoder will - * compute the MD5 signature of the unencoded audio data while decoding - * and compare it to the signature from the STREAMINFO block, if it - * exists, during FLAC__stream_decoder_finish(). - * - * MD5 signature checking will be turned off (until the next - * FLAC__stream_decoder_reset()) if there is no signature in the - * STREAMINFO block or when a seek is attempted. - * - * Clients that do not use the MD5 check should leave this off to speed - * up decoding. - * - * \default \c false - * \param decoder A decoder instance to set. - * \param value Flag value (see above). - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_md5_checking(FLAC__StreamDecoder *decoder, FLAC__bool value); - -/** Direct the decoder to pass on all metadata blocks of type \a type. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \param type See above. - * \assert - * \code decoder != NULL \endcode - * \a type is valid - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); - -/** Direct the decoder to pass on all APPLICATION metadata blocks of the - * given \a id. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \param id See above. - * \assert - * \code decoder != NULL \endcode - * \code id != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); - -/** Direct the decoder to pass on all metadata blocks of any type. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_respond_all(FLAC__StreamDecoder *decoder); - -/** Direct the decoder to filter out all metadata blocks of type \a type. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \param type See above. - * \assert - * \code decoder != NULL \endcode - * \a type is valid - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore(FLAC__StreamDecoder *decoder, FLAC__MetadataType type); - -/** Direct the decoder to filter out all APPLICATION metadata blocks of - * the given \a id. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \param id See above. - * \assert - * \code decoder != NULL \endcode - * \code id != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_application(FLAC__StreamDecoder *decoder, const FLAC__byte id[4]); - -/** Direct the decoder to filter out all metadata blocks of any type. - * - * \default By default, only the \c STREAMINFO block is returned via the - * metadata callback. - * \param decoder A decoder instance to set. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if the decoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_set_metadata_ignore_all(FLAC__StreamDecoder *decoder); - -/** Get the current decoder state. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderState - * The current decoder state. - */ -FLAC_API FLAC__StreamDecoderState FLAC__stream_decoder_get_state(const FLAC__StreamDecoder *decoder); - -/** Get the current decoder state as a C string. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval const char * - * The decoder state as a C string. Do not modify the contents. - */ -FLAC_API const char *FLAC__stream_decoder_get_resolved_state_string(const FLAC__StreamDecoder *decoder); - -/** Get the "MD5 signature checking" flag. - * This is the value of the setting, not whether or not the decoder is - * currently checking the MD5 (remember, it can be turned off automatically - * by a seek). When the decoder is reset the flag will be restored to the - * value returned by this function. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * See above. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_get_md5_checking(const FLAC__StreamDecoder *decoder); - -/** Get the total number of samples in the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the \c STREAMINFO block. A value of \c 0 means "unknown". - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval unsigned - * See above. - */ -FLAC_API FLAC__uint64 FLAC__stream_decoder_get_total_samples(const FLAC__StreamDecoder *decoder); - -/** Get the current number of channels in the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval unsigned - * See above. - */ -FLAC_API unsigned FLAC__stream_decoder_get_channels(const FLAC__StreamDecoder *decoder); - -/** Get the current channel assignment in the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__ChannelAssignment - * See above. - */ -FLAC_API FLAC__ChannelAssignment FLAC__stream_decoder_get_channel_assignment(const FLAC__StreamDecoder *decoder); - -/** Get the current sample resolution in the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval unsigned - * See above. - */ -FLAC_API unsigned FLAC__stream_decoder_get_bits_per_sample(const FLAC__StreamDecoder *decoder); - -/** Get the current sample rate in Hz of the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval unsigned - * See above. - */ -FLAC_API unsigned FLAC__stream_decoder_get_sample_rate(const FLAC__StreamDecoder *decoder); - -/** Get the current blocksize of the stream being decoded. - * Will only be valid after decoding has started and will contain the - * value from the most recently decoded frame header. - * - * \param decoder A decoder instance to query. - * \assert - * \code decoder != NULL \endcode - * \retval unsigned - * See above. - */ -FLAC_API unsigned FLAC__stream_decoder_get_blocksize(const FLAC__StreamDecoder *decoder); - -/** Returns the decoder's current read position within the stream. - * The position is the byte offset from the start of the stream. - * Bytes before this position have been fully decoded. Note that - * there may still be undecoded bytes in the decoder's read FIFO. - * The returned position is correct even after a seek. - * - * \warning This function currently only works for native FLAC, - * not Ogg FLAC streams. - * - * \param decoder A decoder instance to query. - * \param position Address at which to return the desired position. - * \assert - * \code decoder != NULL \endcode - * \code position != NULL \endcode - * \retval FLAC__bool - * \c true if successful, \c false if the stream is not native FLAC, - * or there was an error from the 'tell' callback or it returned - * \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_get_decode_position(const FLAC__StreamDecoder *decoder, FLAC__uint64 *position); - -/** Initialize the decoder instance to decode native FLAC streams. - * - * This flavor of initialization sets up the decoder to decode from a - * native FLAC stream. I/O is performed via callbacks to the client. - * For decoding from a plain file via filename or open FILE*, - * FLAC__stream_decoder_init_file() and FLAC__stream_decoder_init_FILE() - * provide a simpler interface. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \param decoder An uninitialized decoder instance. - * \param read_callback See FLAC__StreamDecoderReadCallback. This - * pointer must not be \c NULL. - * \param seek_callback See FLAC__StreamDecoderSeekCallback. This - * pointer may be \c NULL if seeking is not - * supported. If \a seek_callback is not \c NULL then a - * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. - * Alternatively, a dummy seek callback that just - * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param tell_callback See FLAC__StreamDecoderTellCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a tell_callback must also be supplied. - * Alternatively, a dummy tell callback that just - * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param length_callback See FLAC__StreamDecoderLengthCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a length_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param eof_callback See FLAC__StreamDecoderEofCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a eof_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c false - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ -FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_stream( - FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderReadCallback read_callback, - FLAC__StreamDecoderSeekCallback seek_callback, - FLAC__StreamDecoderTellCallback tell_callback, - FLAC__StreamDecoderLengthCallback length_callback, - FLAC__StreamDecoderEofCallback eof_callback, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); - -/** Initialize the decoder instance to decode Ogg FLAC streams. - * - * This flavor of initialization sets up the decoder to decode from a - * FLAC stream in an Ogg container. I/O is performed via callbacks to the - * client. For decoding from a plain file via filename or open FILE*, - * FLAC__stream_decoder_init_ogg_file() and FLAC__stream_decoder_init_ogg_FILE() - * provide a simpler interface. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \note Support for Ogg FLAC in the library is optional. If this - * library has been built without support for Ogg FLAC, this function - * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. - * - * \param decoder An uninitialized decoder instance. - * \param read_callback See FLAC__StreamDecoderReadCallback. This - * pointer must not be \c NULL. - * \param seek_callback See FLAC__StreamDecoderSeekCallback. This - * pointer may be \c NULL if seeking is not - * supported. If \a seek_callback is not \c NULL then a - * \a tell_callback, \a length_callback, and \a eof_callback must also be supplied. - * Alternatively, a dummy seek callback that just - * returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param tell_callback See FLAC__StreamDecoderTellCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a tell_callback must also be supplied. - * Alternatively, a dummy tell callback that just - * returns \c FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param length_callback See FLAC__StreamDecoderLengthCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a length_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param eof_callback See FLAC__StreamDecoderEofCallback. This - * pointer may be \c NULL if not supported by the client. If - * \a seek_callback is not \c NULL then a - * \a eof_callback must also be supplied. - * Alternatively, a dummy length callback that just - * returns \c false - * may also be supplied, all though this is slightly - * less efficient for the decoder. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ -FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_stream( - FLAC__StreamDecoder *decoder, - FLAC__StreamDecoderReadCallback read_callback, - FLAC__StreamDecoderSeekCallback seek_callback, - FLAC__StreamDecoderTellCallback tell_callback, - FLAC__StreamDecoderLengthCallback length_callback, - FLAC__StreamDecoderEofCallback eof_callback, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); - -/** Initialize the decoder instance to decode native FLAC files. - * - * This flavor of initialization sets up the decoder to decode from a - * plain native FLAC file. For non-stdio streams, you must use - * FLAC__stream_decoder_init_stream() and provide callbacks for the I/O. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \param decoder An uninitialized decoder instance. - * \param file An open FLAC file. The file should have been - * opened with mode \c "rb" and rewound. The file - * becomes owned by the decoder and should not be - * manipulated by the client while decoding. - * Unless \a file is \c stdin, it will be closed - * when FLAC__stream_decoder_finish() is called. - * Note however that seeking will not work when - * decoding from \c stdout since it is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \code file != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ -FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_FILE( - FLAC__StreamDecoder *decoder, - FILE *file, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); - -/** Initialize the decoder instance to decode Ogg FLAC files. - * - * This flavor of initialization sets up the decoder to decode from a - * plain Ogg FLAC file. For non-stdio streams, you must use - * FLAC__stream_decoder_init_ogg_stream() and provide callbacks for the I/O. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \note Support for Ogg FLAC in the library is optional. If this - * library has been built without support for Ogg FLAC, this function - * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. - * - * \param decoder An uninitialized decoder instance. - * \param file An open FLAC file. The file should have been - * opened with mode \c "rb" and rewound. The file - * becomes owned by the decoder and should not be - * manipulated by the client while decoding. - * Unless \a file is \c stdin, it will be closed - * when FLAC__stream_decoder_finish() is called. - * Note however that seeking will not work when - * decoding from \c stdout since it is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \code file != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ -FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_FILE( - FLAC__StreamDecoder *decoder, - FILE *file, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); - -/** Initialize the decoder instance to decode native FLAC files. - * - * This flavor of initialization sets up the decoder to decode from a plain - * native FLAC file. If POSIX fopen() semantics are not sufficient, (for - * example, with Unicode filenames on Windows), you must use - * FLAC__stream_decoder_init_FILE(), or FLAC__stream_decoder_init_stream() - * and provide callbacks for the I/O. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \param decoder An uninitialized decoder instance. - * \param filename The name of the file to decode from. The file will - * be opened with fopen(). Use \c NULL to decode from - * \c stdin. Note that \c stdin is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ -FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_file( - FLAC__StreamDecoder *decoder, - const char *filename, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); - -/** Initialize the decoder instance to decode Ogg FLAC files. - * - * This flavor of initialization sets up the decoder to decode from a plain - * Ogg FLAC file. If POSIX fopen() semantics are not sufficient, (for - * example, with Unicode filenames on Windows), you must use - * FLAC__stream_decoder_init_ogg_FILE(), or FLAC__stream_decoder_init_ogg_stream() - * and provide callbacks for the I/O. - * - * This function should be called after FLAC__stream_decoder_new() and - * FLAC__stream_decoder_set_*() but before any of the - * FLAC__stream_decoder_process_*() functions. Will set and return the - * decoder state, which will be FLAC__STREAM_DECODER_SEARCH_FOR_METADATA - * if initialization succeeded. - * - * \note Support for Ogg FLAC in the library is optional. If this - * library has been built without support for Ogg FLAC, this function - * will return \c FLAC__STREAM_DECODER_INIT_STATUS_UNSUPPORTED_CONTAINER. - * - * \param decoder An uninitialized decoder instance. - * \param filename The name of the file to decode from. The file will - * be opened with fopen(). Use \c NULL to decode from - * \c stdin. Note that \c stdin is not seekable. - * \param write_callback See FLAC__StreamDecoderWriteCallback. This - * pointer must not be \c NULL. - * \param metadata_callback See FLAC__StreamDecoderMetadataCallback. This - * pointer may be \c NULL if the callback is not - * desired. - * \param error_callback See FLAC__StreamDecoderErrorCallback. This - * pointer must not be \c NULL. - * \param client_data This value will be supplied to callbacks in their - * \a client_data argument. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__StreamDecoderInitStatus - * \c FLAC__STREAM_DECODER_INIT_STATUS_OK if initialization was successful; - * see FLAC__StreamDecoderInitStatus for the meanings of other return values. - */ -FLAC_API FLAC__StreamDecoderInitStatus FLAC__stream_decoder_init_ogg_file( - FLAC__StreamDecoder *decoder, - const char *filename, - FLAC__StreamDecoderWriteCallback write_callback, - FLAC__StreamDecoderMetadataCallback metadata_callback, - FLAC__StreamDecoderErrorCallback error_callback, - void *client_data -); - -/** Finish the decoding process. - * Flushes the decoding buffer, releases resources, resets the decoder - * settings to their defaults, and returns the decoder state to - * FLAC__STREAM_DECODER_UNINITIALIZED. - * - * In the event of a prematurely-terminated decode, it is not strictly - * necessary to call this immediately before FLAC__stream_decoder_delete() - * but it is good practice to match every FLAC__stream_decoder_init_*() - * with a FLAC__stream_decoder_finish(). - * - * \param decoder An uninitialized decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if MD5 checking is on AND a STREAMINFO block was available - * AND the MD5 signature in the STREAMINFO block was non-zero AND the - * signature does not match the one computed by the decoder; else - * \c true. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder); - -/** Flush the stream input. - * The decoder's input buffer will be cleared and the state set to - * \c FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC. This will also turn - * off MD5 checking. - * - * \param decoder A decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false if a memory allocation - * error occurs (in which case the state will be set to - * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR). - */ -FLAC_API FLAC__bool FLAC__stream_decoder_flush(FLAC__StreamDecoder *decoder); - -/** Reset the decoding process. - * The decoder's input buffer will be cleared and the state set to - * \c FLAC__STREAM_DECODER_SEARCH_FOR_METADATA. This is similar to - * FLAC__stream_decoder_finish() except that the settings are - * preserved; there is no need to call FLAC__stream_decoder_init_*() - * before decoding again. MD5 checking will be restored to its original - * setting. - * - * If the decoder is seekable, or was initialized with - * FLAC__stream_decoder_init*_FILE() or FLAC__stream_decoder_init*_file(), - * the decoder will also attempt to seek to the beginning of the file. - * If this rewind fails, this function will return \c false. It follows - * that FLAC__stream_decoder_reset() cannot be used when decoding from - * \c stdin. - * - * If the decoder was initialized with FLAC__stream_encoder_init*_stream() - * and is not seekable (i.e. no seek callback was provided or the seek - * callback returns \c FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED), it - * is the duty of the client to start feeding data from the beginning of - * the stream on the next FLAC__stream_decoder_process() or - * FLAC__stream_decoder_process_interleaved() call. - * - * \param decoder A decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false if a memory allocation occurs - * (in which case the state will be set to - * \c FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR) or a seek error - * occurs (the state will be unchanged). - */ -FLAC_API FLAC__bool FLAC__stream_decoder_reset(FLAC__StreamDecoder *decoder); - -/** Decode one metadata block or audio frame. - * This version instructs the decoder to decode a either a single metadata - * block or a single frame and stop, unless the callbacks return a fatal - * error or the read callback returns - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. - * - * As the decoder needs more input it will call the read callback. - * Depending on what was decoded, the metadata or write callback will be - * called with the decoded metadata block or audio frame. - * - * Unless there is a fatal read error or end of stream, this function - * will return once one whole frame is decoded. In other words, if the - * stream is not synchronized or points to a corrupt frame header, the - * decoder will continue to try and resync until it gets to a valid - * frame, then decode one frame, then return. If the decoder points to - * a frame whose frame CRC in the frame footer does not match the - * computed frame CRC, this function will issue a - * FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH error to the - * error callback, and return, having decoded one complete, although - * corrupt, frame. (Such corrupted frames are sent as silence of the - * correct length to the write callback.) - * - * \param decoder An initialized decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if any fatal read, write, or memory allocation error - * occurred (meaning decoding must stop), else \c true; for more - * information about the decoder, check the decoder state with - * FLAC__stream_decoder_get_state(). - */ -FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *decoder); - -/** Decode until the end of the metadata. - * This version instructs the decoder to decode from the current position - * and continue until all the metadata has been read, or until the - * callbacks return a fatal error or the read callback returns - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. - * - * As the decoder needs more input it will call the read callback. - * As each metadata block is decoded, the metadata callback will be called - * with the decoded metadata. - * - * \param decoder An initialized decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if any fatal read, write, or memory allocation error - * occurred (meaning decoding must stop), else \c true; for more - * information about the decoder, check the decoder state with - * FLAC__stream_decoder_get_state(). - */ -FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_metadata(FLAC__StreamDecoder *decoder); - -/** Decode until the end of the stream. - * This version instructs the decoder to decode from the current position - * and continue until the end of stream (the read callback returns - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM), or until the - * callbacks return a fatal error. - * - * As the decoder needs more input it will call the read callback. - * As each metadata block and frame is decoded, the metadata or write - * callback will be called with the decoded metadata or frame. - * - * \param decoder An initialized decoder instance. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if any fatal read, write, or memory allocation error - * occurred (meaning decoding must stop), else \c true; for more - * information about the decoder, check the decoder state with - * FLAC__stream_decoder_get_state(). - */ -FLAC_API FLAC__bool FLAC__stream_decoder_process_until_end_of_stream(FLAC__StreamDecoder *decoder); - -/** Skip one audio frame. - * This version instructs the decoder to 'skip' a single frame and stop, - * unless the callbacks return a fatal error or the read callback returns - * \c FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM. - * - * The decoding flow is the same as what occurs when - * FLAC__stream_decoder_process_single() is called to process an audio - * frame, except that this function does not decode the parsed data into - * PCM or call the write callback. The integrity of the frame is still - * checked the same way as in the other process functions. - * - * This function will return once one whole frame is skipped, in the - * same way that FLAC__stream_decoder_process_single() will return once - * one whole frame is decoded. - * - * This function can be used in more quickly determining FLAC frame - * boundaries when decoding of the actual data is not needed, for - * example when an application is separating a FLAC stream into frames - * for editing or storing in a container. To do this, the application - * can use FLAC__stream_decoder_skip_single_frame() to quickly advance - * to the next frame, then use - * FLAC__stream_decoder_get_decode_position() to find the new frame - * boundary. - * - * This function should only be called when the stream has advanced - * past all the metadata, otherwise it will return \c false. - * - * \param decoder An initialized decoder instance not in a metadata - * state. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c false if any fatal read, write, or memory allocation error - * occurred (meaning decoding must stop), or if the decoder - * is in the FLAC__STREAM_DECODER_SEARCH_FOR_METADATA or - * FLAC__STREAM_DECODER_READ_METADATA state, else \c true; for more - * information about the decoder, check the decoder state with - * FLAC__stream_decoder_get_state(). - */ -FLAC_API FLAC__bool FLAC__stream_decoder_skip_single_frame(FLAC__StreamDecoder *decoder); - -/** Flush the input and seek to an absolute sample. - * Decoding will resume at the given sample. Note that because of - * this, the next write callback may contain a partial block. The - * client must support seeking the input or this function will fail - * and return \c false. Furthermore, if the decoder state is - * \c FLAC__STREAM_DECODER_SEEK_ERROR, then the decoder must be flushed - * with FLAC__stream_decoder_flush() or reset with - * FLAC__stream_decoder_reset() before decoding can continue. - * - * \param decoder A decoder instance. - * \param sample The target sample number to seek to. - * \assert - * \code decoder != NULL \endcode - * \retval FLAC__bool - * \c true if successful, else \c false. - */ -FLAC_API FLAC__bool FLAC__stream_decoder_seek_absolute(FLAC__StreamDecoder *decoder, FLAC__uint64 sample); - -/* \} */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/Windows/include/FLAC/stream_encoder.h b/platform/Windows/include/FLAC/stream_encoder.h deleted file mode 100644 index 6f7796bb3..000000000 --- a/platform/Windows/include/FLAC/stream_encoder.h +++ /dev/null @@ -1,1769 +0,0 @@ -/* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 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__STREAM_ENCODER_H -#define FLAC__STREAM_ENCODER_H - -#include /* for FILE */ -#include "export.h" -#include "format.h" -#include "stream_decoder.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -/** \file include/FLAC/stream_encoder.h - * - * \brief - * This module contains the functions which implement the stream - * encoder. - * - * See the detailed documentation in the - * \link flac_stream_encoder stream encoder \endlink module. - */ - -/** \defgroup flac_encoder FLAC/ \*_encoder.h: encoder interfaces - * \ingroup flac - * - * \brief - * This module describes the encoder layers provided by libFLAC. - * - * The stream encoder can be used to encode complete streams either to the - * client via callbacks, or directly to a file, depending on how it is - * initialized. When encoding via callbacks, the client provides a write - * callback which will be called whenever FLAC data is ready to be written. - * If the client also supplies a seek callback, the encoder will also - * automatically handle the writing back of metadata discovered while - * encoding, like stream info, seek points offsets, etc. When encoding to - * a file, the client needs only supply a filename or open \c FILE* and an - * optional progress callback for periodic notification of progress; the - * write and seek callbacks are supplied internally. For more info see the - * \link flac_stream_encoder stream encoder \endlink module. - */ - -/** \defgroup flac_stream_encoder FLAC/stream_encoder.h: stream encoder interface - * \ingroup flac_encoder - * - * \brief - * This module contains the functions which implement the stream - * encoder. - * - * The stream encoder can encode to native FLAC, and optionally Ogg FLAC - * (check FLAC_API_SUPPORTS_OGG_FLAC) streams and files. - * - * The basic usage of this encoder is as follows: - * - The program creates an instance of an encoder using - * FLAC__stream_encoder_new(). - * - The program overrides the default settings using - * FLAC__stream_encoder_set_*() functions. At a minimum, the following - * functions should be called: - * - FLAC__stream_encoder_set_channels() - * - FLAC__stream_encoder_set_bits_per_sample() - * - FLAC__stream_encoder_set_sample_rate() - * - FLAC__stream_encoder_set_ogg_serial_number() (if encoding to Ogg FLAC) - * - FLAC__stream_encoder_set_total_samples_estimate() (if known) - * - If the application wants to control the compression level or set its own - * metadata, then the following should also be called: - * - FLAC__stream_encoder_set_compression_level() - * - FLAC__stream_encoder_set_verify() - * - FLAC__stream_encoder_set_metadata() - * - The rest of the set functions should only be called if the client needs - * exact control over how the audio is compressed; thorough understanding - * of the FLAC format is necessary to achieve good results. - * - The program initializes the instance to validate the settings and - * prepare for encoding using - * - FLAC__stream_encoder_init_stream() or FLAC__stream_encoder_init_FILE() - * or FLAC__stream_encoder_init_file() for native FLAC - * - FLAC__stream_encoder_init_ogg_stream() or FLAC__stream_encoder_init_ogg_FILE() - * or FLAC__stream_encoder_init_ogg_file() for Ogg FLAC - * - The program calls FLAC__stream_encoder_process() or - * FLAC__stream_encoder_process_interleaved() to encode data, which - * subsequently calls the callbacks when there is encoder data ready - * to be written. - * - The program finishes the encoding with FLAC__stream_encoder_finish(), - * which causes the encoder to encode any data still in its input pipe, - * update the metadata with the final encoding statistics if output - * seeking is possible, and finally reset the encoder to the - * uninitialized state. - * - The instance may be used again or deleted with - * FLAC__stream_encoder_delete(). - * - * In more detail, the stream encoder functions similarly to the - * \link flac_stream_decoder stream decoder \endlink, but has fewer - * callbacks and more options. Typically the client will create a new - * instance by calling FLAC__stream_encoder_new(), then set the necessary - * parameters with FLAC__stream_encoder_set_*(), and initialize it by - * calling one of the FLAC__stream_encoder_init_*() functions. - * - * Unlike the decoders, the stream encoder has many options that can - * affect the speed and compression ratio. When setting these parameters - * you should have some basic knowledge of the format (see the - * user-level documentation - * or the formal description). The - * FLAC__stream_encoder_set_*() functions themselves do not validate the - * values as many are interdependent. The FLAC__stream_encoder_init_*() - * functions will do this, so make sure to pay attention to the state - * returned by FLAC__stream_encoder_init_*() to make sure that it is - * FLAC__STREAM_ENCODER_INIT_STATUS_OK. Any parameters that are not set - * before FLAC__stream_encoder_init_*() will take on the defaults from - * the constructor. - * - * There are three initialization functions for native FLAC, one for - * setting up the encoder to encode FLAC data to the client via - * callbacks, and two for encoding directly to a file. - * - * For encoding via callbacks, use FLAC__stream_encoder_init_stream(). - * You must also supply a write callback which will be called anytime - * there is raw encoded data to write. If the client can seek the output - * it is best to also supply seek and tell callbacks, as this allows the - * encoder to go back after encoding is finished to write back - * information that was collected while encoding, like seek point offsets, - * frame sizes, etc. - * - * For encoding directly to a file, use FLAC__stream_encoder_init_FILE() - * or FLAC__stream_encoder_init_file(). Then you must only supply a - * filename or open \c FILE*; the encoder will handle all the callbacks - * internally. You may also supply a progress callback for periodic - * notification of the encoding progress. - * - * There are three similarly-named init functions for encoding to Ogg - * FLAC streams. Check \c FLAC_API_SUPPORTS_OGG_FLAC to find out if the - * library has been built with Ogg support. - * - * The call to FLAC__stream_encoder_init_*() currently will also immediately - * call the write callback several times, once with the \c fLaC signature, - * and once for each encoded metadata block. Note that for Ogg FLAC - * encoding you will usually get at least twice the number of callbacks than - * with native FLAC, one for the Ogg page header and one for the page body. - * - * After initializing the instance, the client may feed audio data to the - * encoder in one of two ways: - * - * - Channel separate, through FLAC__stream_encoder_process() - The client - * will pass an array of pointers to buffers, one for each channel, to - * the encoder, each of the same length. The samples need not be - * block-aligned, but each channel should have the same number of samples. - * - Channel interleaved, through - * FLAC__stream_encoder_process_interleaved() - The client will pass a single - * pointer to data that is channel-interleaved (i.e. channel0_sample0, - * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). - * Again, the samples need not be block-aligned but they must be - * sample-aligned, i.e. the first value should be channel0_sample0 and - * the last value channelN_sampleM. - * - * Note that for either process call, each sample in the buffers should be a - * signed integer, right-justified to the resolution set by - * FLAC__stream_encoder_set_bits_per_sample(). For example, if the resolution - * is 16 bits per sample, the samples should all be in the range [-32768,32767]. - * - * When the client is finished encoding data, it calls - * FLAC__stream_encoder_finish(), which causes the encoder to encode any - * data still in its input pipe, and call the metadata callback with the - * final encoding statistics. Then the instance may be deleted with - * FLAC__stream_encoder_delete() or initialized again to encode another - * stream. - * - * For programs that write their own metadata, but that do not know the - * actual metadata until after encoding, it is advantageous to instruct - * the encoder to write a PADDING block of the correct size, so that - * instead of rewriting the whole stream after encoding, the program can - * just overwrite the PADDING block. If only the maximum size of the - * metadata is known, the program can write a slightly larger padding - * block, then split it after encoding. - * - * Make sure you understand how lengths are calculated. All FLAC metadata - * blocks have a 4 byte header which contains the type and length. This - * length does not include the 4 bytes of the header. See the format page - * for the specification of metadata blocks and their lengths. - * - * \note - * If you are writing the FLAC data to a file via callbacks, make sure it - * is open for update (e.g. mode "w+" for stdio streams). This is because - * after the first encoding pass, the encoder will try to seek back to the - * beginning of the stream, to the STREAMINFO block, to write some data - * there. (If using FLAC__stream_encoder_init*_file() or - * FLAC__stream_encoder_init*_FILE(), the file is managed internally.) - * - * \note - * The "set" functions may only be called when the encoder is in the - * state FLAC__STREAM_ENCODER_UNINITIALIZED, i.e. after - * FLAC__stream_encoder_new() or FLAC__stream_encoder_finish(), but - * before FLAC__stream_encoder_init_*(). If this is the case they will - * return \c true, otherwise \c false. - * - * \note - * FLAC__stream_encoder_finish() resets all settings to the constructor - * defaults. - * - * \{ - */ - - -/** State values for a FLAC__StreamEncoder. - * - * The encoder's state can be obtained by calling FLAC__stream_encoder_get_state(). - * - * If the encoder gets into any other state besides \c FLAC__STREAM_ENCODER_OK - * or \c FLAC__STREAM_ENCODER_UNINITIALIZED, it becomes invalid for encoding and - * must be deleted with FLAC__stream_encoder_delete(). - */ -typedef enum { - - FLAC__STREAM_ENCODER_OK = 0, - /**< The encoder is in the normal OK state and samples can be processed. */ - - FLAC__STREAM_ENCODER_UNINITIALIZED, - /**< The encoder is in the uninitialized state; one of the - * FLAC__stream_encoder_init_*() functions must be called before samples - * can be processed. - */ - - FLAC__STREAM_ENCODER_OGG_ERROR, - /**< An error occurred in the underlying Ogg layer. */ - - FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR, - /**< An error occurred in the underlying verify stream decoder; - * check FLAC__stream_encoder_get_verify_decoder_state(). - */ - - FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA, - /**< The verify decoder detected a mismatch between the original - * audio signal and the decoded audio signal. - */ - - FLAC__STREAM_ENCODER_CLIENT_ERROR, - /**< One of the callbacks returned a fatal error. */ - - FLAC__STREAM_ENCODER_IO_ERROR, - /**< An I/O error occurred while opening/reading/writing a file. - * Check \c errno. - */ - - FLAC__STREAM_ENCODER_FRAMING_ERROR, - /**< An error occurred while writing the stream; usually, the - * write_callback returned an error. - */ - - FLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR - /**< Memory allocation failed. */ - -} FLAC__StreamEncoderState; - -/** Maps a FLAC__StreamEncoderState to a C string. - * - * Using a FLAC__StreamEncoderState as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamEncoderStateString[]; - - -/** Possible return values for the FLAC__stream_encoder_init_*() functions. - */ -typedef enum { - - FLAC__STREAM_ENCODER_INIT_STATUS_OK = 0, - /**< Initialization was successful. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_ENCODER_ERROR, - /**< General failure to set up encoder; call FLAC__stream_encoder_get_state() for cause. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_UNSUPPORTED_CONTAINER, - /**< The library was not compiled with support for the given container - * format. - */ - - FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS, - /**< A required callback was not supplied. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_NUMBER_OF_CHANNELS, - /**< The encoder has an invalid setting for number of channels. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BITS_PER_SAMPLE, - /**< The encoder has an invalid setting for bits-per-sample. - * FLAC supports 4-32 bps but the reference encoder currently supports - * only up to 24 bps. - */ - - FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_SAMPLE_RATE, - /**< The encoder has an invalid setting for the input sample rate. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_BLOCK_SIZE, - /**< The encoder has an invalid setting for the block size. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_MAX_LPC_ORDER, - /**< The encoder has an invalid setting for the maximum LPC order. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_QLP_COEFF_PRECISION, - /**< The encoder has an invalid setting for the precision of the quantized linear predictor coefficients. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER, - /**< The specified block size is less than the maximum LPC order. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_NOT_STREAMABLE, - /**< The encoder is bound to the Subset but other settings violate it. */ - - FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_METADATA, - /**< The metadata input to the encoder is invalid, in one of the following ways: - * - FLAC__stream_encoder_set_metadata() was called with a null pointer but a block count > 0 - * - One of the metadata blocks contains an undefined type - * - It contains an illegal CUESHEET as checked by FLAC__format_cuesheet_is_legal() - * - It contains an illegal SEEKTABLE as checked by FLAC__format_seektable_is_legal() - * - It contains more than one SEEKTABLE block or more than one VORBIS_COMMENT block - */ - - FLAC__STREAM_ENCODER_INIT_STATUS_ALREADY_INITIALIZED - /**< FLAC__stream_encoder_init_*() was called when the encoder was - * already initialized, usually because - * FLAC__stream_encoder_finish() was not called. - */ - -} FLAC__StreamEncoderInitStatus; - -/** Maps a FLAC__StreamEncoderInitStatus to a C string. - * - * Using a FLAC__StreamEncoderInitStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamEncoderInitStatusString[]; - - -/** Return values for the FLAC__StreamEncoder read callback. - */ -typedef enum { - - FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE, - /**< The read was OK and decoding can continue. */ - - FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM, - /**< The read was attempted at the end of the stream. */ - - FLAC__STREAM_ENCODER_READ_STATUS_ABORT, - /**< An unrecoverable error occurred. */ - - FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED - /**< Client does not support reading back from the output. */ - -} FLAC__StreamEncoderReadStatus; - -/** Maps a FLAC__StreamEncoderReadStatus to a C string. - * - * Using a FLAC__StreamEncoderReadStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamEncoderReadStatusString[]; - - -/** Return values for the FLAC__StreamEncoder write callback. - */ -typedef enum { - - FLAC__STREAM_ENCODER_WRITE_STATUS_OK = 0, - /**< The write was OK and encoding can continue. */ - - FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR - /**< An unrecoverable error occurred. The encoder will return from the process call. */ - -} FLAC__StreamEncoderWriteStatus; - -/** Maps a FLAC__StreamEncoderWriteStatus to a C string. - * - * Using a FLAC__StreamEncoderWriteStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamEncoderWriteStatusString[]; - - -/** Return values for the FLAC__StreamEncoder seek callback. - */ -typedef enum { - - FLAC__STREAM_ENCODER_SEEK_STATUS_OK, - /**< The seek was OK and encoding can continue. */ - - FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR, - /**< An unrecoverable error occurred. */ - - FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED - /**< Client does not support seeking. */ - -} FLAC__StreamEncoderSeekStatus; - -/** Maps a FLAC__StreamEncoderSeekStatus to a C string. - * - * Using a FLAC__StreamEncoderSeekStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamEncoderSeekStatusString[]; - - -/** Return values for the FLAC__StreamEncoder tell callback. - */ -typedef enum { - - FLAC__STREAM_ENCODER_TELL_STATUS_OK, - /**< The tell was OK and encoding can continue. */ - - FLAC__STREAM_ENCODER_TELL_STATUS_ERROR, - /**< An unrecoverable error occurred. */ - - FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED - /**< Client does not support seeking. */ - -} FLAC__StreamEncoderTellStatus; - -/** Maps a FLAC__StreamEncoderTellStatus to a C string. - * - * Using a FLAC__StreamEncoderTellStatus as the index to this array - * will give the string equivalent. The contents should not be modified. - */ -extern FLAC_API const char * const FLAC__StreamEncoderTellStatusString[]; - - -/*********************************************************************** - * - * class FLAC__StreamEncoder - * - ***********************************************************************/ - -struct FLAC__StreamEncoderProtected; -struct FLAC__StreamEncoderPrivate; -/** The opaque structure definition for the stream encoder type. - * See the \link flac_stream_encoder stream encoder module \endlink - * for a detailed description. - */ -typedef struct { - struct FLAC__StreamEncoderProtected *protected_; /* avoid the C++ keyword 'protected' */ - struct FLAC__StreamEncoderPrivate *private_; /* avoid the C++ keyword 'private' */ -} FLAC__StreamEncoder; - -/** Signature for the read callback. - * - * A function pointer matching this signature must be passed to - * FLAC__stream_encoder_init_ogg_stream() if seeking is supported. - * The supplied function will be called when the encoder needs to read back - * encoded data. This happens during the metadata callback, when the encoder - * has to read, modify, and rewrite the metadata (e.g. seekpoints) gathered - * while encoding. The address of the buffer to be filled is supplied, along - * with the number of bytes the buffer can hold. The callback may choose to - * supply less data and modify the byte count but must be careful not to - * overflow the buffer. The callback then returns a status code chosen from - * FLAC__StreamEncoderReadStatus. - * - * Here is an example of a read callback for stdio streams: - * \code - * FLAC__StreamEncoderReadStatus read_cb(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * if(*bytes > 0) { - * *bytes = fread(buffer, sizeof(FLAC__byte), *bytes, file); - * if(ferror(file)) - * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; - * else if(*bytes == 0) - * return FLAC__STREAM_ENCODER_READ_STATUS_END_OF_STREAM; - * else - * return FLAC__STREAM_ENCODER_READ_STATUS_CONTINUE; - * } - * else - * return FLAC__STREAM_ENCODER_READ_STATUS_ABORT; - * } - * \endcode - * - * \note In general, FLAC__StreamEncoder functions which change the - * state should not be called on the \a encoder while in the callback. - * - * \param encoder The encoder instance calling the callback. - * \param buffer A pointer to a location for the callee to store - * data to be encoded. - * \param bytes A pointer to the size of the buffer. On entry - * to the callback, it contains the maximum number - * of bytes that may be stored in \a buffer. The - * callee must set it to the actual number of bytes - * stored (0 in case of error or end-of-stream) before - * returning. - * \param client_data The callee's client data set through - * FLAC__stream_encoder_set_client_data(). - * \retval FLAC__StreamEncoderReadStatus - * The callee's return status. - */ -typedef FLAC__StreamEncoderReadStatus (*FLAC__StreamEncoderReadCallback)(const FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data); - -/** Signature for the write callback. - * - * A function pointer matching this signature must be passed to - * FLAC__stream_encoder_init*_stream(). The supplied function will be called - * by the encoder anytime there is raw encoded data ready to write. It may - * include metadata mixed with encoded audio frames and the data is not - * guaranteed to be aligned on frame or metadata block boundaries. - * - * The only duty of the callback is to write out the \a bytes worth of data - * in \a buffer to the current position in the output stream. The arguments - * \a samples and \a current_frame are purely informational. If \a samples - * is greater than \c 0, then \a current_frame will hold the current frame - * number that is being written; otherwise it indicates that the write - * callback is being called to write metadata. - * - * \note - * Unlike when writing to native FLAC, when writing to Ogg FLAC the - * write callback will be called twice when writing each audio - * frame; once for the page header, and once for the page body. - * When writing the page header, the \a samples argument to the - * write callback will be \c 0. - * - * \note In general, FLAC__StreamEncoder functions which change the - * state should not be called on the \a encoder while in the callback. - * - * \param encoder The encoder instance calling the callback. - * \param buffer An array of encoded data of length \a bytes. - * \param bytes The byte length of \a buffer. - * \param samples The number of samples encoded by \a buffer. - * \c 0 has a special meaning; see above. - * \param current_frame The number of the current frame being encoded. - * \param client_data The callee's client data set through - * FLAC__stream_encoder_init_*(). - * \retval FLAC__StreamEncoderWriteStatus - * The callee's return status. - */ -typedef FLAC__StreamEncoderWriteStatus (*FLAC__StreamEncoderWriteCallback)(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data); - -/** Signature for the seek callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_encoder_init*_stream(). The supplied function will be called - * when the encoder needs to seek the output stream. The encoder will pass - * the absolute byte offset to seek to, 0 meaning the beginning of the stream. - * - * Here is an example of a seek callback for stdio streams: - * \code - * FLAC__StreamEncoderSeekStatus seek_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * if(file == stdin) - * return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED; - * else if(fseeko(file, (off_t)absolute_byte_offset, SEEK_SET) < 0) - * return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR; - * else - * return FLAC__STREAM_ENCODER_SEEK_STATUS_OK; - * } - * \endcode - * - * \note In general, FLAC__StreamEncoder functions which change the - * state should not be called on the \a encoder while in the callback. - * - * \param encoder The encoder instance calling the callback. - * \param absolute_byte_offset The offset from the beginning of the stream - * to seek to. - * \param client_data The callee's client data set through - * FLAC__stream_encoder_init_*(). - * \retval FLAC__StreamEncoderSeekStatus - * The callee's return status. - */ -typedef FLAC__StreamEncoderSeekStatus (*FLAC__StreamEncoderSeekCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); - -/** Signature for the tell callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_encoder_init*_stream(). The supplied function will be called - * when the encoder needs to know the current position of the output stream. - * - * \warning - * The callback must return the true current byte offset of the output to - * which the encoder is writing. If you are buffering the output, make - * sure and take this into account. If you are writing directly to a - * FILE* from your write callback, ftell() is sufficient. If you are - * writing directly to a file descriptor from your write callback, you - * can use lseek(fd, SEEK_CUR, 0). The encoder may later seek back to - * these points to rewrite metadata after encoding. - * - * Here is an example of a tell callback for stdio streams: - * \code - * FLAC__StreamEncoderTellStatus tell_cb(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) - * { - * FILE *file = ((MyClientData*)client_data)->file; - * off_t pos; - * if(file == stdin) - * return FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED; - * else if((pos = ftello(file)) < 0) - * return FLAC__STREAM_ENCODER_TELL_STATUS_ERROR; - * else { - * *absolute_byte_offset = (FLAC__uint64)pos; - * return FLAC__STREAM_ENCODER_TELL_STATUS_OK; - * } - * } - * \endcode - * - * \note In general, FLAC__StreamEncoder functions which change the - * state should not be called on the \a encoder while in the callback. - * - * \param encoder The encoder instance calling the callback. - * \param absolute_byte_offset The address at which to store the current - * position of the output. - * \param client_data The callee's client data set through - * FLAC__stream_encoder_init_*(). - * \retval FLAC__StreamEncoderTellStatus - * The callee's return status. - */ -typedef FLAC__StreamEncoderTellStatus (*FLAC__StreamEncoderTellCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); - -/** Signature for the metadata callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_encoder_init*_stream(). The supplied function will be called - * once at the end of encoding with the populated STREAMINFO structure. This - * is so the client can seek back to the beginning of the file and write the - * STREAMINFO block with the correct statistics after encoding (like - * minimum/maximum frame size and total samples). - * - * \note In general, FLAC__StreamEncoder functions which change the - * state should not be called on the \a encoder while in the callback. - * - * \param encoder The encoder instance calling the callback. - * \param metadata The final populated STREAMINFO block. - * \param client_data The callee's client data set through - * FLAC__stream_encoder_init_*(). - */ -typedef void (*FLAC__StreamEncoderMetadataCallback)(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data); - -/** Signature for the progress callback. - * - * A function pointer matching this signature may be passed to - * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE(). - * The supplied function will be called when the encoder has finished - * writing a frame. The \c total_frames_estimate argument to the - * callback will be based on the value from - * FLAC__stream_encoder_set_total_samples_estimate(). - * - * \note In general, FLAC__StreamEncoder functions which change the - * state should not be called on the \a encoder while in the callback. - * - * \param encoder The encoder instance calling the callback. - * \param bytes_written Bytes written so far. - * \param samples_written Samples written so far. - * \param frames_written Frames written so far. - * \param total_frames_estimate The estimate of the total number of - * frames to be written. - * \param client_data The callee's client data set through - * FLAC__stream_encoder_init_*(). - */ -typedef void (*FLAC__StreamEncoderProgressCallback)(const FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data); - - -/*********************************************************************** - * - * Class constructor/destructor - * - ***********************************************************************/ - -/** Create a new stream encoder instance. The instance is created with - * default settings; see the individual FLAC__stream_encoder_set_*() - * functions for each setting's default. - * - * \retval FLAC__StreamEncoder* - * \c NULL if there was an error allocating memory, else the new instance. - */ -FLAC_API FLAC__StreamEncoder *FLAC__stream_encoder_new(void); - -/** Free an encoder instance. Deletes the object pointed to by \a encoder. - * - * \param encoder A pointer to an existing encoder. - * \assert - * \code encoder != NULL \endcode - */ -FLAC_API void FLAC__stream_encoder_delete(FLAC__StreamEncoder *encoder); - - -/*********************************************************************** - * - * Public class method prototypes - * - ***********************************************************************/ - -/** Set the serial number for the FLAC stream to use in the Ogg container. - * - * \note - * This does not need to be set for native FLAC encoding. - * - * \note - * It is recommended to set a serial number explicitly as the default of '0' - * may collide with other streams. - * - * \default \c 0 - * \param encoder An encoder instance to set. - * \param serial_number See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_ogg_serial_number(FLAC__StreamEncoder *encoder, long serial_number); - -/** Set the "verify" flag. If \c true, the encoder will verify it's own - * encoded output by feeding it through an internal decoder and comparing - * the original signal against the decoded signal. If a mismatch occurs, - * the process call will return \c false. Note that this will slow the - * encoding process by the extra time required for decoding and comparison. - * - * \default \c false - * \param encoder An encoder instance to set. - * \param value Flag value (see above). - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value); - -/** Set the Subset flag. If \c true, - * the encoder will comply with the Subset and will check the - * settings during FLAC__stream_encoder_init_*() to see if all settings - * comply. If \c false, the settings may take advantage of the full - * range that the format allows. - * - * Make sure you know what it entails before setting this to \c false. - * - * \default \c true - * \param encoder An encoder instance to set. - * \param value Flag value (see above). - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_streamable_subset(FLAC__StreamEncoder *encoder, FLAC__bool value); - -/** Set the number of channels to be encoded. - * - * \default \c 2 - * \param encoder An encoder instance to set. - * \param value See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_channels(FLAC__StreamEncoder *encoder, unsigned value); - -/** Set the sample resolution of the input to be encoded. - * - * \warning - * Do not feed the encoder data that is wider than the value you - * set here or you will generate an invalid stream. - * - * \default \c 16 - * \param encoder An encoder instance to set. - * \param value See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_bits_per_sample(FLAC__StreamEncoder *encoder, unsigned value); - -/** Set the sample rate (in Hz) of the input to be encoded. - * - * \default \c 44100 - * \param encoder An encoder instance to set. - * \param value See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *encoder, unsigned value); - -/** Set the compression level - * - * The compression level is roughly proportional to the amount of effort - * the encoder expends to compress the file. A higher level usually - * means more computation but higher compression. The default level is - * suitable for most applications. - * - * Currently the levels range from \c 0 (fastest, least compression) to - * \c 8 (slowest, most compression). A value larger than \c 8 will be - * treated as \c 8. - * - * This function automatically calls the following other \c _set_ - * functions with appropriate values, so the client does not need to - * unless it specifically wants to override them: - * - FLAC__stream_encoder_set_do_mid_side_stereo() - * - FLAC__stream_encoder_set_loose_mid_side_stereo() - * - FLAC__stream_encoder_set_apodization() - * - FLAC__stream_encoder_set_max_lpc_order() - * - FLAC__stream_encoder_set_qlp_coeff_precision() - * - FLAC__stream_encoder_set_do_qlp_coeff_prec_search() - * - FLAC__stream_encoder_set_do_escape_coding() - * - FLAC__stream_encoder_set_do_exhaustive_model_search() - * - FLAC__stream_encoder_set_min_residual_partition_order() - * - FLAC__stream_encoder_set_max_residual_partition_order() - * - FLAC__stream_encoder_set_rice_parameter_search_dist() - * - * The actual values set for each level are: - * - * - * - * - * - * - * - * - * - * - * - * - *
level - * do mid-side stereo - * loose mid-side stereo - * apodization - * max lpc order - * qlp coeff precision - * qlp coeff prec search - * escape coding - * exhaustive model search - * min residual partition order - * max residual partition order - * rice parameter search dist - *
0 false false tukey(0.5) 0 0 false false false 0 3 0
1 true true tukey(0.5) 0 0 false false false 0 3 0
2 true false tukey(0.5) 0 0 false false false 0 3 0
3 false false tukey(0.5) 6 0 false false false 0 4 0
4 true true tukey(0.5) 8 0 false false false 0 4 0
5 true false tukey(0.5) 8 0 false false false 0 5 0
6 true false tukey(0.5) 8 0 false false false 0 6 0
7 true false tukey(0.5) 8 0 false false true 0 6 0
8 true false tukey(0.5) 12 0 false false true 0 6 0
- * - * \default \c 5 - * \param encoder An encoder instance to set. - * \param value See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncoder *encoder, unsigned value); - -/** Set the blocksize to use while encoding. - * - * The number of samples to use per frame. Use \c 0 to let the encoder - * estimate a blocksize; this is usually best. - * - * \default \c 0 - * \param encoder An encoder instance to set. - * \param value See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_blocksize(FLAC__StreamEncoder *encoder, unsigned value); - -/** Set to \c true to enable mid-side encoding on stereo input. The - * number of channels must be 2 for this to have any effect. Set to - * \c false to use only independent channel coding. - * - * \default \c false - * \param encoder An encoder instance to set. - * \param value Flag value (see above). - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_do_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); - -/** Set to \c true to enable adaptive switching between mid-side and - * left-right encoding on stereo input. Set to \c false to use - * exhaustive searching. Setting this to \c true requires - * FLAC__stream_encoder_set_do_mid_side_stereo() to also be set to - * \c true in order to have any effect. - * - * \default \c false - * \param encoder An encoder instance to set. - * \param value Flag value (see above). - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamEncoder *encoder, FLAC__bool value); - -/** Sets the apodization function(s) the encoder will use when windowing - * audio data for LPC analysis. - * - * The \a specification is a plain ASCII string which specifies exactly - * which functions to use. There may be more than one (up to 32), - * separated by \c ';' characters. Some functions take one or more - * comma-separated arguments in parentheses. - * - * The available functions are \c bartlett, \c bartlett_hann, - * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop, - * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall, - * \c rectangle, \c triangle, \c tukey(P), \c welch. - * - * For \c gauss(STDDEV), STDDEV specifies the standard deviation - * (0blocksize / (2 ^ order). - * - * Set both min and max values to \c 0 to force a single context, - * whose Rice parameter is based on the residual signal variance. - * Otherwise, set a min and max order, and the encoder will search - * all orders, using the mean of each context for its Rice parameter, - * and use the best. - * - * \default \c 0 - * \param encoder An encoder instance to set. - * \param value See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_min_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); - -/** Set the maximum partition order to search when coding the residual. - * This is used in tandem with - * FLAC__stream_encoder_set_min_residual_partition_order(). - * - * The partition order determines the context size in the residual. - * The context size will be approximately blocksize / (2 ^ order). - * - * Set both min and max values to \c 0 to force a single context, - * whose Rice parameter is based on the residual signal variance. - * Otherwise, set a min and max order, and the encoder will search - * all orders, using the mean of each context for its Rice parameter, - * and use the best. - * - * \default \c 0 - * \param encoder An encoder instance to set. - * \param value See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_max_residual_partition_order(FLAC__StreamEncoder *encoder, unsigned value); - -/** Deprecated. Setting this value has no effect. - * - * \default \c 0 - * \param encoder An encoder instance to set. - * \param value See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_rice_parameter_search_dist(FLAC__StreamEncoder *encoder, unsigned value); - -/** Set an estimate of the total samples that will be encoded. - * This is merely an estimate and may be set to \c 0 if unknown. - * This value will be written to the STREAMINFO block before encoding, - * and can remove the need for the caller to rewrite the value later - * if the value is known before encoding. - * - * \default \c 0 - * \param encoder An encoder instance to set. - * \param value See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_total_samples_estimate(FLAC__StreamEncoder *encoder, FLAC__uint64 value); - -/** Set the metadata blocks to be emitted to the stream before encoding. - * A value of \c NULL, \c 0 implies no metadata; otherwise, supply an - * array of pointers to metadata blocks. The array is non-const since - * the encoder may need to change the \a is_last flag inside them, and - * in some cases update seek point offsets. Otherwise, the encoder will - * not modify or free the blocks. It is up to the caller to free the - * metadata blocks after encoding finishes. - * - * \note - * The encoder stores only copies of the pointers in the \a metadata array; - * the metadata blocks themselves must survive at least until after - * FLAC__stream_encoder_finish() returns. Do not free the blocks until then. - * - * \note - * The STREAMINFO block is always written and no STREAMINFO block may - * occur in the supplied array. - * - * \note - * By default the encoder does not create a SEEKTABLE. If one is supplied - * in the \a metadata array, but the client has specified that it does not - * support seeking, then the SEEKTABLE will be written verbatim. However - * by itself this is not very useful as the client will not know the stream - * offsets for the seekpoints ahead of time. In order to get a proper - * seektable the client must support seeking. See next note. - * - * \note - * SEEKTABLE blocks are handled specially. Since you will not know - * the values for the seek point stream offsets, you should pass in - * a SEEKTABLE 'template', that is, a SEEKTABLE object with the - * required sample numbers (or placeholder points), with \c 0 for the - * \a frame_samples and \a stream_offset fields for each point. If the - * client has specified that it supports seeking by providing a seek - * callback to FLAC__stream_encoder_init_stream() or both seek AND read - * callback to FLAC__stream_encoder_init_ogg_stream() (or by using - * FLAC__stream_encoder_init*_file() or FLAC__stream_encoder_init*_FILE()), - * then while it is encoding the encoder will fill the stream offsets in - * for you and when encoding is finished, it will seek back and write the - * real values into the SEEKTABLE block in the stream. There are helper - * routines for manipulating seektable template blocks; see metadata.h: - * FLAC__metadata_object_seektable_template_*(). If the client does - * not support seeking, the SEEKTABLE will have inaccurate offsets which - * will slow down or remove the ability to seek in the FLAC stream. - * - * \note - * The encoder instance \b will modify the first \c SEEKTABLE block - * as it transforms the template to a valid seektable while encoding, - * but it is still up to the caller to free all metadata blocks after - * encoding. - * - * \note - * A VORBIS_COMMENT block may be supplied. The vendor string in it - * will be ignored. libFLAC will use it's own vendor string. libFLAC - * will not modify the passed-in VORBIS_COMMENT's vendor string, it - * will simply write it's own into the stream. If no VORBIS_COMMENT - * block is present in the \a metadata array, libFLAC will write an - * empty one, containing only the vendor string. - * - * \note The Ogg FLAC mapping requires that the VORBIS_COMMENT block be - * the second metadata block of the stream. The encoder already supplies - * the STREAMINFO block automatically. If \a metadata does not contain a - * VORBIS_COMMENT block, the encoder will supply that too. Otherwise, if - * \a metadata does contain a VORBIS_COMMENT block and it is not the - * first, the init function will reorder \a metadata by moving the - * VORBIS_COMMENT block to the front; the relative ordering of the other - * blocks will remain as they were. - * - * \note The Ogg FLAC mapping limits the number of metadata blocks per - * stream to \c 65535. If \a num_blocks exceeds this the function will - * return \c false. - * - * \default \c NULL, 0 - * \param encoder An encoder instance to set. - * \param metadata See above. - * \param num_blocks See above. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * \c false if the encoder is already initialized, else \c true. - * \c false if the encoder is already initialized, or if - * \a num_blocks > 65535 if encoding to Ogg FLAC, else \c true. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_set_metadata(FLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks); - -/** Get the current encoder state. - * - * \param encoder An encoder instance to query. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__StreamEncoderState - * The current encoder state. - */ -FLAC_API FLAC__StreamEncoderState FLAC__stream_encoder_get_state(const FLAC__StreamEncoder *encoder); - -/** Get the state of the verify stream decoder. - * Useful when the stream encoder state is - * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. - * - * \param encoder An encoder instance to query. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__StreamDecoderState - * The verify stream decoder state. - */ -FLAC_API FLAC__StreamDecoderState FLAC__stream_encoder_get_verify_decoder_state(const FLAC__StreamEncoder *encoder); - -/** Get the current encoder state as a C string. - * This version automatically resolves - * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR by getting the - * verify decoder's state. - * - * \param encoder A encoder instance to query. - * \assert - * \code encoder != NULL \endcode - * \retval const char * - * The encoder state as a C string. Do not modify the contents. - */ -FLAC_API const char *FLAC__stream_encoder_get_resolved_state_string(const FLAC__StreamEncoder *encoder); - -/** Get relevant values about the nature of a verify decoder error. - * Useful when the stream encoder state is - * \c FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR. The arguments should - * be addresses in which the stats will be returned, or NULL if value - * is not desired. - * - * \param encoder An encoder instance to query. - * \param absolute_sample The absolute sample number of the mismatch. - * \param frame_number The number of the frame in which the mismatch occurred. - * \param channel The channel in which the mismatch occurred. - * \param sample The number of the sample (relative to the frame) in - * which the mismatch occurred. - * \param expected The expected value for the sample in question. - * \param got The actual value returned by the decoder. - * \assert - * \code encoder != NULL \endcode - */ -FLAC_API void FLAC__stream_encoder_get_verify_decoder_error_stats(const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got); - -/** Get the "verify" flag. - * - * \param encoder An encoder instance to query. - * \assert - * \code encoder != NULL \endcode - * \retval FLAC__bool - * See FLAC__stream_encoder_set_verify(). - */ -FLAC_API FLAC__bool FLAC__stream_encoder_get_verify(const FLAC__StreamEncoder *encoder); - -/** Get the frame header. - * - * \param encoder An initialized encoder instance in the OK state. - * \param buffer An array of pointers to each channel's signal. - * \param samples The number of samples in one channel. - * \assert - * \code encoder != NULL \endcode - * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode - * \retval FLAC__bool - * \c true if successful, else \c false; in this case, check the - * encoder state with FLAC__stream_encoder_get_state() to see what - * went wrong. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples); - -/** Submit data for encoding. - * This version allows you to supply the input data where the channels - * are interleaved into a single array (i.e. channel0_sample0, - * channel1_sample0, ... , channelN_sample0, channel0_sample1, ...). - * The samples need not be block-aligned but they must be - * sample-aligned, i.e. the first value should be channel0_sample0 - * and the last value channelN_sampleM. Each sample should be a signed - * integer, right-justified to the resolution set by - * FLAC__stream_encoder_set_bits_per_sample(). For example, if the - * resolution is 16 bits per sample, the samples should all be in the - * range [-32768,32767]. - * - * For applications where channel order is important, channels must - * follow the order as described in the - * frame header. - * - * \param encoder An initialized encoder instance in the OK state. - * \param buffer An array of channel-interleaved data (see above). - * \param samples The number of samples in one channel, the same as for - * FLAC__stream_encoder_process(). For example, if - * encoding two channels, \c 1000 \a samples corresponds - * to a \a buffer of 2000 values. - * \assert - * \code encoder != NULL \endcode - * \code FLAC__stream_encoder_get_state(encoder) == FLAC__STREAM_ENCODER_OK \endcode - * \retval FLAC__bool - * \c true if successful, else \c false; in this case, check the - * encoder state with FLAC__stream_encoder_get_state() to see what - * went wrong. - */ -FLAC_API FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples); - -/* \} */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/platform/Windows/include/ogg/config_types.h b/platform/Windows/include/ogg/config_types.h deleted file mode 100644 index 4b00047a0..000000000 --- a/platform/Windows/include/ogg/config_types.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __CONFIG_TYPES_H__ -#define __CONFIG_TYPES_H__ - -/* these are filled in by configure */ -#define INCLUDE_INTTYPES_H 1 -#define INCLUDE_STDINT_H 1 -#define INCLUDE_SYS_TYPES_H 1 - -#if INCLUDE_INTTYPES_H -# include -#endif -#if INCLUDE_STDINT_H -# include -#endif -#if INCLUDE_SYS_TYPES_H -# include -#endif - -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; - -#endif diff --git a/platform/Windows/include/ogg/ogg.h b/platform/Windows/include/ogg/ogg.h deleted file mode 100644 index cea4ebed7..000000000 --- a/platform/Windows/include/ogg/ogg.h +++ /dev/null @@ -1,210 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: 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 -#include - -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 */ diff --git a/platform/Windows/include/ogg/os_types.h b/platform/Windows/include/ogg/os_types.h deleted file mode 100644 index 8bf82107e..000000000 --- a/platform/Windows/include/ogg/os_types.h +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: #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 - 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 - 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 - 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 - 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 - 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 - 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 - -#endif - -#endif /* _OS_TYPES_H */ diff --git a/platform/Windows/include/vorbis/codec.h b/platform/Windows/include/vorbis/codec.h deleted file mode 100644 index 999aa3351..000000000 --- a/platform/Windows/include/vorbis/codec.h +++ /dev/null @@ -1,243 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - - ******************************************************************** - - function: libvorbis codec headers - last mod: $Id: codec.h 17021 2010-03-24 09:29:41Z xiphmont $ - - ********************************************************************/ - -#ifndef _vorbis_codec_h_ -#define _vorbis_codec_h_ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#include - -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 - diff --git a/platform/Windows/include/vorbis/vorbisfile.h b/platform/Windows/include/vorbis/vorbisfile.h deleted file mode 100644 index 9271331e7..000000000 --- a/platform/Windows/include/vorbis/vorbisfile.h +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************** - * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * - * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * - * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * - * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * - * by the Xiph.Org Foundation http://www.xiph.org/ * - * * - ******************************************************************** - - function: 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 -#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 - diff --git a/platform/Windows/lib/32/libogg.lib b/platform/Windows/lib/32/libogg.lib deleted file mode 100644 index efd959cbe..000000000 Binary files a/platform/Windows/lib/32/libogg.lib and /dev/null differ diff --git a/platform/Windows/lib/32/libvorbis.lib b/platform/Windows/lib/32/libvorbis.lib deleted file mode 100644 index ccf4c002d..000000000 Binary files a/platform/Windows/lib/32/libvorbis.lib and /dev/null differ diff --git a/platform/Windows/lib/32/libvorbisfile.lib b/platform/Windows/lib/32/libvorbisfile.lib deleted file mode 100644 index 7fe2e0c13..000000000 Binary files a/platform/Windows/lib/32/libvorbisfile.lib and /dev/null differ diff --git a/platform/Windows/lib/64/libogg.lib b/platform/Windows/lib/64/libogg.lib deleted file mode 100644 index d6cad22a4..000000000 Binary files a/platform/Windows/lib/64/libogg.lib and /dev/null differ diff --git a/platform/Windows/lib/64/libvorbis.lib b/platform/Windows/lib/64/libvorbis.lib deleted file mode 100644 index e25f02831..000000000 Binary files a/platform/Windows/lib/64/libvorbis.lib and /dev/null differ diff --git a/platform/Windows/lib/64/libvorbisfile.lib b/platform/Windows/lib/64/libvorbisfile.lib deleted file mode 100644 index 6ddacdfad..000000000 Binary files a/platform/Windows/lib/64/libvorbisfile.lib and /dev/null differ diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 0a0b9de86..d39073e49 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -104,10 +104,7 @@ if( WIN32 ) libSDL2main libSDL2 - # this local library crap needs to go away. The Ogg/Vorbis libraries are easy to replace with libsndfile but there doesn't seem to be anything to get a working libvpx that doesn't force linking with MinGW dependencies. - libogg - libvorbis - libvorbisfile + # this local library crap needs to go away. Sadly there doesn't seem to be anything to get a working libvpx that doesn't force linking with MinGW dependencies. libvpx libcompat-to-msvc diff --git a/source/audiolib/gpl-2.0.txt b/source/audiolib/gpl-2.0.txt deleted file mode 100644 index d159169d1..000000000 --- a/source/audiolib/gpl-2.0.txt +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/source/audiolib/include/al_midi.h b/source/audiolib/include/al_midi.h deleted file mode 100644 index 1dbb1608a..000000000 --- a/source/audiolib/include/al_midi.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef __AL_MIDI_H -#define __AL_MIDI_H - -#include "opl3.h" - -#include - -typedef struct -{ - uint8_t SAVEK[2]; - uint8_t Level[2]; - uint8_t Env1[2]; - uint8_t Env2[2]; - uint8_t Wave[2]; - uint8_t Feedback; - int8_t Transpose; - int8_t Velocity; -} AdLibTimbre; - -extern AdLibTimbre ADLIB_TimbreBank[256]; - -opl3_chip *AL_GetChip(void); -void AL_RegisterTimbreBank(uint8_t const *timbres); -void AL_SetStereo(int const stereo); - -#endif diff --git a/source/audiolib/include/drivers.h b/source/audiolib/include/drivers.h deleted file mode 100644 index 1026e8175..000000000 --- a/source/audiolib/include/drivers.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -#ifndef DRIVERS_H -#define DRIVERS_H - -#include "sndcards.h" -#include "midifuncs.h" - -extern int ASS_PCMSoundDriver; -extern int ASS_MIDISoundDriver; -extern int ASS_EMIDICard; - -int SoundDriver_IsPCMSupported(int driver); -int SoundDriver_IsMIDISupported(int driver); - -const char *SoundDriver_GetName(int driver); - -int SoundDriver_PCM_GetError(void); -const char *SoundDriver_PCM_ErrorString(int ErrorNumber); -int SoundDriver_MIDI_GetError(void); -const char *SoundDriver_MIDI_ErrorString(int ErrorNumber); - -int SoundDriver_PCM_Init(int *mixrate, int *numchannels, void *initdata); -void SoundDriver_PCM_Shutdown(void); -int SoundDriver_PCM_BeginPlayback(char *BufferStart, int BufferSize, int NumDivisions, void (*CallBackFunc)(void)); -void SoundDriver_PCM_StopPlayback(void); -void SoundDriver_PCM_Lock(void); -void SoundDriver_PCM_Unlock(void); - -int SoundDriver_MIDI_Init(midifuncs *); -void SoundDriver_MIDI_Shutdown(void); -int SoundDriver_MIDI_StartPlayback(void (*service)(void)); -void SoundDriver_MIDI_HaltPlayback(void); -void SoundDriver_MIDI_SetTempo(int tempo, int division); -void SoundDriver_MIDI_Lock(void); -void SoundDriver_MIDI_Unlock(void); - -#endif diff --git a/source/audiolib/include/fx_man.h b/source/audiolib/include/fx_man.h deleted file mode 100644 index 9187db937..000000000 --- a/source/audiolib/include/fx_man.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -/********************************************************************** - module: FX_MAN.H - - author: James R. Dose - date: March 17, 1994 - - Public header for FX_MAN.C - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#ifndef FX_MAN_H_ -#define FX_MAN_H_ - -#include "drivers.h" -#include -#include "limits.h" -#include "multivoc.h" - -enum FX_ERRORS -{ - FX_Warning = -2, - FX_Error = -1, - FX_Ok = 0, - FX_InvalidCard, - FX_MultiVocError, -}; - -enum FX_LOOP_HOW -{ - FX_ONESHOT = -1, - FX_LOOP = 0, -}; - -#define FX_MUSIC_PRIORITY INT_MAX - -const char *FX_ErrorString(int ErrorNumber); -int FX_Init(int numvoices, int numchannels, int mixrate, void *initdata); -int FX_Shutdown(void); -int FX_GetDevice(void); - - - -int FX_Play(char *ptr, uint32_t ptrlength, int loopstart, int loopend, int pitchoffset, - int vol, int left, int right, int priority, float volume, intptr_t callbackval); -int FX_Play3D(char *ptr, uint32_t ptrlength, int loophow, int pitchoffset, int angle, - int distance, int priority, float volume, intptr_t callbackval); -int FX_PlayRaw(char *ptr, uint32_t ptrlength, int rate, int pitchoffset, int vol, - int left, int right, int priority, float volume, intptr_t callbackval); -int FX_PlayLoopedRaw(char *ptr, uint32_t ptrlength, char *loopstart, char *loopend, int rate, - int pitchoffset, int vol, int left, int right, int priority, float volume, intptr_t callbackval); - - -int FX_SetPrintf(void(*function)(const char *, ...)); - -extern int FX_ErrorCode; -#define FX_SetErrorCode(status) FX_ErrorCode = (status); - -static FORCE_INLINE int FX_CheckMVErr(int status) -{ - if (status != MV_Ok) - { - FX_SetErrorCode(FX_MultiVocError); - status = FX_Warning; - } - - return status; -} - -static FORCE_INLINE void FX_SetCallBack(void(*function)(intptr_t)) { MV_SetCallBack(function); } -static FORCE_INLINE void FX_SetVolume(int volume) { MV_SetVolume(volume); } -static FORCE_INLINE int FX_GetVolume(void) { return MV_GetVolume(); } -static FORCE_INLINE void FX_SetReverseStereo(int setting) { MV_SetReverseStereo(setting); } -static FORCE_INLINE int FX_GetReverseStereo(void) { return MV_GetReverseStereo(); } -static FORCE_INLINE void FX_SetReverb_(int reverb) { MV_SetReverb(reverb); } -static FORCE_INLINE int FX_GetMaxReverbDelay(void) { return MV_GetMaxReverbDelay(); } -static FORCE_INLINE int FX_GetReverbDelay(void) { return MV_GetReverbDelay(); } -static FORCE_INLINE int FX_VoiceAvailable(int priority) { return MV_VoiceAvailable(priority); } -static FORCE_INLINE int FX_PauseVoice(int handle, int pause) { return FX_CheckMVErr(MV_PauseVoice(handle, pause)); } -static FORCE_INLINE int FX_EndLooping(int handle) { return FX_CheckMVErr(MV_EndLooping(handle)); } -static FORCE_INLINE int FX_SetPan(int handle, int vol, int left, int right) -{ - return FX_CheckMVErr(MV_SetPan(handle, vol, left, right)); -} -static FORCE_INLINE int FX_SetPitch(int handle, int pitchoffset) { return FX_CheckMVErr(MV_SetPitch(handle, pitchoffset)); } -static FORCE_INLINE int FX_SetFrequency(int handle, int frequency) { return FX_CheckMVErr(MV_SetFrequency(handle, frequency)); } -static FORCE_INLINE int FX_Pan3D(int handle, int angle, int distance) -{ - return FX_CheckMVErr(MV_Pan3D(handle, angle, distance)); -} -static FORCE_INLINE int FX_SoundActive(int handle) { return MV_VoicePlaying(handle); } -static FORCE_INLINE int FX_SoundValidAndActive(int handle) { return handle > 0 && MV_VoicePlaying(handle); } -static FORCE_INLINE int FX_SoundsPlaying(void) { return MV_VoicesPlaying(); } -static FORCE_INLINE int FX_StopSound(int handle) { return FX_CheckMVErr(MV_Kill(handle)); } -static FORCE_INLINE int FX_StopAllSounds_(void) { return FX_CheckMVErr(MV_KillAllVoices()); } - -#endif diff --git a/source/audiolib/include/midifuncs.h b/source/audiolib/include/midifuncs.h deleted file mode 100644 index 7b85a49b7..000000000 --- a/source/audiolib/include/midifuncs.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef __MIDIFUNCS_H -#define __MIDIFUNCS_H - -typedef struct - { - void ( *NoteOff )( int channel, int key, int velocity ); - void ( *NoteOn )( int channel, int key, int velocity ); - void ( *PolyAftertouch )( int channel, int key, int pressure ); - void ( *ControlChange )( int channel, int number, int value ); - void ( *ProgramChange )( int channel, int program ); - void ( *ChannelAftertouch )( int channel, int pressure ); - void ( *PitchBend )( int channel, int lsb, int msb ); - void ( *ReleasePatches )( void ); - void ( *LoadPatch )( int number ); - void ( *SetVolume )( int volume ); - int ( *GetVolume )( void ); - void ( *SysEx )( const unsigned char * data, int length ); - } midifuncs; - -#endif diff --git a/source/audiolib/include/multivoc.h b/source/audiolib/include/multivoc.h deleted file mode 100644 index c4e93c8f6..000000000 --- a/source/audiolib/include/multivoc.h +++ /dev/null @@ -1,138 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -/********************************************************************** - file: MULTIVOC.H - - author: James R. Dose - date: December 20, 1993 - - Public header for MULTIVOC.C - - (c) Copyright 1993 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#ifndef MULTIVOC_H_ -#define MULTIVOC_H_ - -#include "compat.h" -#include "drivers.h" - -typedef enum : char -{ - FMT_UNKNOWN, - FMT_RAW, - FMT_VOC, - FMT_WAV, - FMT_SNDFILE, - FMT_ZMUSIC, - // soon to be obsolete. - FMT_VORBIS, - FMT_FLAC, - FMT_MAX -} wavefmt_t; - -#define MV_MINVOICEHANDLE 1 - -extern int MV_ErrorCode; - -enum MV_Errors -{ - MV_Error = -1, - MV_Ok = 0, - MV_NotInstalled, - MV_DriverError, - MV_NoVoices, - MV_NoMem, - MV_VoiceNotFound, - MV_InvalidFile, -}; - -extern void (*MV_Printf)(const char *fmt, ...); -extern int MV_Locked; - -static inline void MV_Lock(void) -{ - if (!MV_Locked++) - SoundDriver_PCM_Lock(); -} - -static inline void MV_Unlock(void) -{ - if (!--MV_Locked) - SoundDriver_PCM_Unlock(); - else if (MV_Locked < 0) - MV_Printf("MV_Unlock(): lockdepth < 0!\n"); -} - -const char *MV_ErrorString(int ErrorNumber); - -int MV_VoicePlaying(int handle); -int MV_KillAllVoices(void); -int MV_Kill(int handle); -int MV_VoicesPlaying(void); -int MV_VoiceAvailable(int priority); -int MV_SetPitch(int handle, int pitchoffset); -int MV_SetFrequency(int handle, int frequency); -int MV_PauseVoice(int handle, int pause); -int MV_EndLooping(int handle); -int MV_SetPan(int handle, int vol, int left, int right); -int MV_Pan3D(int handle, int angle, int distance); -void MV_SetReverb(int reverb); -int MV_GetMaxReverbDelay(void); -int MV_GetReverbDelay(void); -void MV_SetReverbDelay(int delay); - -int MV_PlayVOC3D(char *ptr, uint32_t length, int loophow, int pitchoffset, int angle, int distance, - int priority, float volume, intptr_t callbackval); -int MV_PlayVOC(char *ptr, uint32_t length, int loopstart, int loopend, int pitchoffset, int vol, - int left, int right, int priority, float volume, intptr_t callbackval); - -decltype(MV_PlayVOC3D) MV_PlayWAV3D; -decltype(MV_PlayVOC) MV_PlayWAV; -decltype(MV_PlayVOC3D) MV_PlayVorbis3D; -decltype(MV_PlayVOC) MV_PlayVorbis; -decltype(MV_PlayVOC3D) MV_PlayFLAC3D; -decltype(MV_PlayVOC) MV_PlayFLAC; - -int MV_PlayRAW(char *ptr, uint32_t length, int rate, char *loopstart, char *loopend, int pitchoffset, int vol, - int left, int right, int priority, float volume, intptr_t callbackval); - -int MV_GetPosition(int handle, int *position); -int MV_SetPosition(int handle, int position); -void MV_SetVolume(int volume); -int MV_GetVolume(void); -void MV_SetCallBack(void (*function)(intptr_t)); -void MV_SetReverseStereo(int setting); -int MV_GetReverseStereo(void); -int MV_Init(int soundcard, int MixRate, int Voices, int numchannels, void *initdata); -int MV_Shutdown(void); -void MV_HookMusicRoutine(void (*callback)(void)); -void MV_UnhookMusicRoutine(void); - -struct MV_MusicRoutineBuffer -{ - char * buffer; - int32_t size; -}; -struct MV_MusicRoutineBuffer MV_GetMusicRoutineBuffer(void); - -static inline void MV_SetPrintf(void (*function)(const char *, ...)) { if (function) MV_Printf = function; } - -#endif diff --git a/source/audiolib/include/music.h b/source/audiolib/include/music.h deleted file mode 100644 index 1613431be..000000000 --- a/source/audiolib/include/music.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) -*/ -/********************************************************************** - module: MUSIC.H - - author: James R. Dose - date: March 25, 1994 - - Public header for MUSIC.C - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#ifndef __MUSIC_H -#define __MUSIC_H - -#include "compat.h" - -extern int MUSIC_ErrorCode; - -enum MUSIC_ERRORS -{ - MUSIC_Warning = -2, - MUSIC_Error = -1, - MUSIC_Ok = 0, - MUSIC_MidiError, -}; - -typedef struct -{ - uint32_t tickposition; - uint32_t milliseconds; - uint32_t measure; - uint32_t beat; - uint32_t tick; -} songposition; - -#define MUSIC_LoopSong ( 1 == 1 ) -#define MUSIC_PlayOnce ( !MUSIC_LoopSong ) - -#define MUSIC_SetErrorCode(status) MUSIC_ErrorCode = (status); - -extern const char *MUSIC_ErrorString(int ErrorNumber); - -int MUSIC_Init(int SoundCard); -int MUSIC_Shutdown(void); -int MIDI_GetDevice(void); -void MUSIC_SetVolume(int volume); -int MUSIC_GetVolume(void); -void MUSIC_SetLoopFlag(int loopflag); -void MUSIC_Continue(void); -void MUSIC_Pause(void); -int MUSIC_StopSong(void); -int MUSIC_PlaySong(char *song, int songsize, int loopflag, const char *fn = nullptr); -void MUSIC_Update(void); - -#endif diff --git a/source/audiolib/include/opl3.h b/source/audiolib/include/opl3.h deleted file mode 100644 index cc476c1f7..000000000 --- a/source/audiolib/include/opl3.h +++ /dev/null @@ -1,160 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2013-2019 Nuke.YKT - -This file is part of NBlood. - -NBlood is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- -// -// Nuked OPL3 emulator. -// Thanks: -// MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): -// Feedback and Rhythm part calculation information. -// forums.submarine.org.uk(carbon14, opl3): -// Tremolo and phase generator calculation information. -// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): -// OPL2 ROMs. -// siliconpr0n.org(John McMaster, digshadow): -// YMF262 and VRC VII decaps and die shots. -// -// version: 1.8 -// - -#ifndef OPL_OPL3_H -#define OPL_OPL3_H - -#include - -#define OPL_WRITEBUF_SIZE 1024 -#define OPL_WRITEBUF_DELAY 2 - -typedef uintptr_t Bitu; -typedef intptr_t Bits; -typedef uint64_t Bit64u; -typedef int64_t Bit64s; -typedef uint32_t Bit32u; -typedef int32_t Bit32s; -typedef uint16_t Bit16u; -typedef int16_t Bit16s; -typedef uint8_t Bit8u; -typedef int8_t Bit8s; - -typedef struct _opl3_slot opl3_slot; -typedef struct _opl3_channel opl3_channel; -typedef struct _opl3_chip opl3_chip; - -struct _opl3_slot { - opl3_channel *channel; - opl3_chip *chip; - Bit16s out; - Bit16s fbmod; - Bit16s *mod; - Bit16s prout; - Bit16s eg_rout; - Bit16s eg_out; - Bit8u eg_inc; - Bit8u eg_gen; - Bit8u eg_rate; - Bit8u eg_ksl; - Bit8u *trem; - Bit8u reg_vib; - Bit8u reg_type; - Bit8u reg_ksr; - Bit8u reg_mult; - Bit8u reg_ksl; - Bit8u reg_tl; - Bit8u reg_ar; - Bit8u reg_dr; - Bit8u reg_sl; - Bit8u reg_rr; - Bit8u reg_wf; - Bit8u key; - Bit32u pg_reset; - Bit32u pg_phase; - Bit16u pg_phase_out; - Bit8u slot_num; -}; - -struct _opl3_channel { - opl3_slot *slots[2]; - opl3_channel *pair; - opl3_chip *chip; - Bit16s *out[4]; - Bit8u chtype; - Bit16u f_num; - Bit8u block; - Bit8u fb; - Bit8u con; - Bit8u alg; - Bit8u ksv; - Bit16u cha, chb; - Bit32s leftpan; - Bit32s rightpan; - Bit8u ch_num; -}; - -typedef struct _opl3_writebuf { - Bit64u time; - Bit16u reg; - Bit8u data; -} opl3_writebuf; - -struct _opl3_chip { - opl3_channel channel[18]; - opl3_slot slot[36]; - Bit16u timer; - Bit64u eg_timer; - Bit8u eg_timerrem; - Bit8u eg_state; - Bit8u eg_add; - Bit8u newm; - Bit8u nts; - Bit8u rhy; - Bit8u vibpos; - Bit8u vibshift; - Bit8u tremolo; - Bit8u tremolopos; - Bit8u tremoloshift; - Bit32u noise; - Bit16s zeromod; - Bit32s mixbuff[2]; - Bit8u rm_hh_bit2; - Bit8u rm_hh_bit3; - Bit8u rm_hh_bit7; - Bit8u rm_hh_bit8; - Bit8u rm_tc_bit3; - Bit8u rm_tc_bit5; - Bit8u stereoext; - Bit32s rateratio; - Bit32s samplecnt; - Bit16s oldsamples[2]; - Bit16s samples[2]; - - Bit64u writebuf_samplecnt; - Bit32u writebuf_cur; - Bit32u writebuf_last; - Bit64u writebuf_lasttime; - opl3_writebuf writebuf[OPL_WRITEBUF_SIZE]; -}; - -void OPL3_Generate(opl3_chip *chip, Bit16s *buf); -void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf); -void OPL3_Reset(opl3_chip *chip, Bit32u samplerate); -void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v); -void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v); -void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples); -#endif diff --git a/source/audiolib/include/opl3_reg.h b/source/audiolib/include/opl3_reg.h deleted file mode 100644 index 2396706d6..000000000 --- a/source/audiolib/include/opl3_reg.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright by Hannu Savolainen 1993-1996 - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - */ - -// heavily modified for audiolib -// original definitions found at http://www.cs.albany.edu/~sdc/Linux/linux-2.0/drivers/sound/opl3.h -// it's from old Linux source but the license is pretty clearly 2-clause BSD. - -#ifndef opl3_reg_h__ -#define OPL3_opl3_reg_h__ - -#define OPL3_TEST_REGISTER 0x01 -#define OPL3_ENABLE_WAVE_SELECT 0x20 - -#define OPL3_TIMER1_REGISTER 0x02 -#define OPL3_TIMER2_REGISTER 0x03 -#define OPL3_TIMER_CONTROL_REGISTER 0x04 /* Left side */ -#define OPL3_IRQ_RESET 0x80 -#define OPL3_TIMER1_MASK 0x40 -#define OPL3_TIMER2_MASK 0x20 -#define OPL3_TIMER1_START 0x01 -#define OPL3_TIMER2_START 0x02 - -#define OPL3_CONNECTION_SELECT_REGISTER 0x04 /* Right side */ -#define OPL3_RIGHT_4OP_0 0x01 -#define OPL3_RIGHT_4OP_1 0x02 -#define OPL3_RIGHT_4OP_2 0x04 -#define OPL3_LEFT_4OP_0 0x08 -#define OPL3_LEFT_4OP_1 0x10 -#define OPL3_LEFT_4OP_2 0x20 - -#define OPL3_MODE_REGISTER 0x05 /* Right side */ -#define OPL3_ENABLE 0x01 -#define OPL3_OPL4_ENABLE 0x02 - -#define OPL3_KBD_SPLIT_REGISTER 0x08 /* Left side */ -#define OPL3_COMPOSITE_SINE_WAVE_MODE 0x80 /* Don't use with OPL-3? */ -#define OPL3_KEYBOARD_SPLIT 0x40 - -#define OPL3_PERCUSSION_REGISTER 0xbd /* Left side only */ -#define OPL3_TREMOLO_DEPTH 0x80 -#define OPL3_VIBRATO_DEPTH 0x40 -#define OPL3_PERCUSSION_ENABLE 0x20 -#define OPL3_BASSDRUM_ON 0x10 -#define OPL3_SNAREDRUM_ON 0x08 -#define OPL3_TOMTOM_ON 0x04 -#define OPL3_CYMBAL_ON 0x02 -#define OPL3_HIHAT_ON 0x01 - -/* - * Offsets to the register banks for operators. To get the - * register number just add the operator offset to the bank offset - * - * AM/VIB/EG/KSR/Multiple (0x20 to 0x35) - */ -#define OPL3_AM_VIB 0x20 -#define OPL3_TREMOLO_ON 0x80 -#define OPL3_VIBRATO_ON 0x40 -#define OPL3_SUSTAIN_ON 0x20 -#define OPL3_KSR 0x10 /* Key scaling rate */ -#define OPL3_MULTIPLE_MASK 0x0f /* Frequency multiplier */ - -/* - * KSL/Total level (0x40 to 0x55) - */ -#define OPL3_KSL_LEVEL 0x40 -#define OPL3_KSL_MASK 0xc0 /* Envelope scaling bits */ -#define OPL3_TOTAL_LEVEL_MASK 0x3f /* Strength (volume) of OP */ - -/* - * Attack / Decay rate (0x60 to 0x75) - */ -#define OPL3_ATTACK_DECAY 0x60 -#define OPL3_ATTACK_MASK 0xf0 -#define OPL3_DECAY_MASK 0x0f - -/* - * Sustain level / Release rate (0x80 to 0x95) - */ -#define OPL3_SUSTAIN_RELEASE 0x80 -#define OPL3_SUSTAIN_MASK 0xf0 -#define OPL3_RELEASE_MASK 0x0f - -/* - * Wave select (0xE0 to 0xF5) - */ -#define OPL3_WAVE_SELECT 0xe0 - -/* - * Offsets to the register banks for voices. Just add to the - * voice number to get the register number. - * - * F-Number low bits (0xA0 to 0xA8). - */ -#define OPL3_FNUM_LOW 0xa0 - -/* - * F-number high bits / Key on / Block (octave) (0xB0 to 0xB8) - */ -#define OPL3_KEYON_BLOCK 0xb0 -#define OPL3_KEYON_BIT 0x20 -#define OPL3_BLOCKNUM_MASK 0x1c -#define OPL3_FNUM_HIGH_MASK 0x03 - -/* - * Feedback / Connection (0xc0 to 0xc8) - * - * These registers have two new bits when the OPL-3 mode - * is selected. These bits controls connecting the voice - * to the stereo channels. For 4 OP voices this bit is - * defined in the second half of the voice (add 3 to the - * register offset). - * - * For 4 OP voices the connection bit is used in the - * both halfs (gives 4 ways to connect the operators). - */ -#define OPL3_FEEDBACK_CONNECTION 0xc0 -#define OPL3_FEEDBACK_MASK 0x0e /* Valid just for 1st OP of a voice */ -#define OPL3_CONNECTION_BIT 0x01 -#define OPL3_STEREO_BITS 0x30 /* OPL-3 only */ -#define OPL3_VOICE_TO_LEFT 0x10 -#define OPL3_VOICE_TO_RIGHT 0x20 - -#endif // opl3_reg_h__ diff --git a/source/audiolib/include/sndcards.h b/source/audiolib/include/sndcards.h deleted file mode 100644 index b272480c7..000000000 --- a/source/audiolib/include/sndcards.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -/********************************************************************** - module: SNDCARDS.H - - author: James R. Dose - date: March 31, 1994 - - Contains enumerated type definitions for sound cards. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#ifndef __SNDCARDS_H -#define __SNDCARDS_H - -typedef enum -{ - ASS_SDL, - ASS_DirectSound, - ASS_OPL3, - ASS_WinMM, - ASS_NumSoundCards, - ASS_AutoDetect = -2 -} soundcardnames; - -#endif diff --git a/source/audiolib/src/_al_midi.h b/source/audiolib/src/_al_midi.h deleted file mode 100644 index 4de5c5f5a..000000000 --- a/source/audiolib/src/_al_midi.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef ___AL_MIDI_H -#define ___AL_MIDI_H - -#include - -#define STEREO_DETUNE 5 - -#define lobyte(num) ((uint32_t)*((char *)&(num))) -#define hibyte(num) ((uint32_t)*(((char *)&(num)) + 1)) - -#define AL_MaxVolume 127 -#define AL_DefaultChannelVolume 90 -#define AL_DefaultPitchBendRange 200 -#define AL_VoiceNotFound -1 - -#define ADLIB_PORT 0x388 - -/* Number of slots for the voices on the chip */ -#define AL_NumChipSlots 18 - -#define NUMADLIBVOICES 9 -#define NUMADLIBCHANNELS 16 - -#define NOTE_ON 0x2000 /* Used to turn note on or toggle note */ -#define NOTE_OFF 0x0000 - -#define MAX_VELOCITY 0x7f -#define MAX_OCTAVE 7 -#define MAX_NOTE (MAX_OCTAVE * 12 + 11) -#define FINETUNE_MAX 31 -#define FINETUNE_RANGE (FINETUNE_MAX + 1) - -#define PITCHBEND_CENTER 1638400 - -#define MIDI_VOLUME 7 -#define MIDI_PAN 10 -#define MIDI_DETUNE 94 -#define MIDI_ALL_NOTES_OFF 0x7B -#define MIDI_RESET_ALL_CONTROLLERS 0x79 -#define MIDI_RPN_MSB 100 -#define MIDI_RPN_LSB 101 -#define MIDI_DATAENTRY_MSB 6 -#define MIDI_DATAENTRY_LSB 38 -#define MIDI_PITCHBEND_RPN 0 - -/* Definition of octave information to be ORed onto F-Number */ - -enum octaves -{ - OCTAVE_0 = 0x0000, - OCTAVE_1 = 0x0400, - OCTAVE_2 = 0x0800, - OCTAVE_3 = 0x0C00, - OCTAVE_4 = 0x1000, - OCTAVE_5 = 0x1400, - OCTAVE_6 = 0x1800, - OCTAVE_7 = 0x1C00 -}; - -typedef struct AdLibVoice -{ - struct AdLibVoice *next; - struct AdLibVoice *prev; - - uint32_t num; - uint32_t key; - uint32_t velocity; - uint32_t channel; - uint32_t pitchleft; - uint32_t pitchright; - int timbre; - int port; - uint32_t status; -} AdLibVoice; - -typedef struct -{ - AdLibVoice *start; - AdLibVoice *end; -} AdLibVoiceList; - -typedef struct -{ - AdLibVoiceList Voices; - - int Timbre; - int Pitchbend; - int KeyOffset; - uint32_t KeyDetune; - uint32_t Volume; - uint32_t EffectiveVolume; - int Pan; - int Detune; - uint32_t RPN; - int16_t PitchBendRange; - int16_t PitchBendSemiTones; - int16_t PitchBendHundreds; -} AdLibChannel; - -static int AL_Init(int rate); -static void AL_NoteOff(int channel, int key, int velocity); -static void AL_NoteOn(int channel, int key, int vel); -static void AL_ControlChange(int channel, int type, int data); -static void AL_ProgramChange(int channel, int patch); -static void AL_SetPitchBend(int channel, int lsb, int msb); - -#endif diff --git a/source/audiolib/src/_midi.h b/source/audiolib/src/_midi.h deleted file mode 100644 index 160bdd812..000000000 --- a/source/audiolib/src/_midi.h +++ /dev/null @@ -1,156 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010-2019 EDuke32 developers and contributors -Copyright (C) 2019 Nuke.YKT - -This file is part of NBlood. - -NBlood is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#ifndef ___MIDI_H -#define ___MIDI_H -#include "compat.h" - -#define RELATIVE_BEAT(measure, beat, tick) ((tick) + ((beat) << 9) + ((measure) << 16)) - -//Bobby Prince thinks this may be 100 -//#define GENMIDI_DefaultVolume 100 -#define GENMIDI_DefaultVolume 90 - -#define MAX_FORMAT 1 - -#define NUM_MIDI_CHANNELS 16 - -#define TIME_PRECISION 16 - -#define MIDI_HEADER_SIGNATURE 0x6468544d // "MThd" -#define MIDI_TRACK_SIGNATURE 0x6b72544d // "MTrk" - -#define MIDI_VOLUME 7 -#define MIDI_PAN 10 -#define MIDI_DETUNE 94 -#define MIDI_RHYTHM_CHANNEL 9 -#define MIDI_BANK_SELECT_MSB 0 -#define MIDI_BANK_SELECT_LSB 32 -#define MIDI_RPN_MSB 100 -#define MIDI_RPN_LSB 101 -#define MIDI_DATAENTRY_MSB 6 -#define MIDI_DATAENTRY_LSB 38 -#define MIDI_PITCHBEND_MSB 0 -#define MIDI_PITCHBEND_LSB 0 -#define MIDI_RUNNING_STATUS 0x80 -#define MIDI_NOTE_OFF 0x8 -#define MIDI_NOTE_ON 0x9 -#define MIDI_POLY_AFTER_TCH 0xA -#define MIDI_CONTROL_CHANGE 0xB -#define MIDI_PROGRAM_CHANGE 0xC -#define MIDI_AFTER_TOUCH 0xD -#define MIDI_PITCH_BEND 0xE -#define MIDI_SPECIAL 0xF -#define MIDI_SYSEX 0xF0 -#define MIDI_SYSEX_CONTINUE 0xF7 -#define MIDI_META_EVENT 0xFF -#define MIDI_END_OF_TRACK 0x2F -#define MIDI_HOLD1 0x40 -#define MIDI_SOSTENUTO 0x42 -#define MIDI_TEMPO_CHANGE 0x51 -#define MIDI_TIME_SIGNATURE 0x58 -#define MIDI_REVERB 0x5b -#define MIDI_CHORUS 0x5d -#define MIDI_ALL_SOUNDS_OFF 0x78 -#define MIDI_RESET_ALL_CONTROLLERS 0x79 -#define MIDI_ALL_NOTES_OFF 0x7b -#define MIDI_MONO_MODE_ON 0x7E -#define MIDI_SYSTEM_RESET 0xFF - -#define GET_NEXT_EVENT( track, data ) do { \ - ( data ) = *( track )->pos; \ - ( track )->pos += 1; \ -} while (0) - -#define GET_MIDI_CHANNEL( event ) ( ( event ) & 0xf ) -#define GET_MIDI_COMMAND( event ) ( ( event ) >> 4 ) - -#define EMIDI_INFINITE -1 -#define EMIDI_END_LOOP_VALUE 127 -#define EMIDI_ALL_CARDS 127 -#define EMIDI_INCLUDE_TRACK 110 -#define EMIDI_EXCLUDE_TRACK 111 -#define EMIDI_PROGRAM_CHANGE 112 -#define EMIDI_VOLUME_CHANGE 113 -#define EMIDI_CONTEXT_START 114 -#define EMIDI_CONTEXT_END 115 -#define EMIDI_LOOP_START 116 -#define EMIDI_LOOP_END 117 -#define EMIDI_SONG_LOOP_START 118 -#define EMIDI_SONG_LOOP_END 119 - -#define EMIDI_GeneralMIDI 0 -#define EMIDI_SoundBlaster 4 -#define EMIDI_AdLib 7 - -#define EMIDI_AffectsCurrentCard(c, type) (((c) == EMIDI_ALL_CARDS) || ((c) == (type))) -#define EMIDI_NUM_CONTEXTS 7 - -typedef struct -{ - char *pos; - char *loopstart; - int16_t loopcount; - int16_t RunningStatus; - unsigned time; - int FPSecondsPerTick; - int16_t tick; - int16_t beat; - int16_t measure; - int16_t BeatsPerMeasure; - int16_t TicksPerBeat; - int16_t TimeBase; - int delay; - int16_t active; -} songcontext; - -typedef struct -{ - char *start; - char *pos; - - int delay; - int16_t active; - int16_t RunningStatus; - - int16_t currentcontext; - songcontext context[EMIDI_NUM_CONTEXTS]; - - char EMIDI_IncludeTrack; - char EMIDI_ProgramChange; - char EMIDI_VolumeChange; -} track; - -static int _MIDI_ReadNumber(void *from, size_t size); -static int _MIDI_ReadDelta(track *ptr); -static void _MIDI_ResetTracks(void); -static void _MIDI_AdvanceTick(void); -static void _MIDI_MetaEvent(track *Track); -static void _MIDI_SysEx(track *Track); -static int _MIDI_InterpretControllerInfo(track *Track, int TimeSet, int channel, int c1, int c2); -static int _MIDI_SendControlChange(int channel, int c1, int c2); -static void _MIDI_SetChannelVolume(int channel, int volume); -static void _MIDI_SendChannelVolumes(void); -static void _MIDI_InitEMIDI(void); - -#endif diff --git a/source/audiolib/src/_multivc.h b/source/audiolib/src/_multivc.h deleted file mode 100644 index 0cbf8ed7a..000000000 --- a/source/audiolib/src/_multivc.h +++ /dev/null @@ -1,293 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -/********************************************************************** - file: _MULTIVC.H - - author: James R. Dose - date: December 20, 1993 - - Private header for MULTIVOC.C - - (c) Copyright 1993 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#ifndef MULTIVC_H_ -#define MULTIVC_H_ - -#include "multivoc.h" - -#define VOC_8BIT 0x0 -#define VOC_16BIT 0x4 - -#define T_SIXTEENBIT_STEREO 0 -#define T_MONO 1 -#define T_16BITSOURCE 2 -#define T_STEREOSOURCE 4 -#define T_DEFAULT T_SIXTEENBIT_STEREO - -#define MV_MAXPANPOSITION 127 /* formerly 31 */ -#define MV_NUMPANPOSITIONS ( MV_MAXPANPOSITION + 1 ) -#define MV_MAXTOTALVOLUME 255 -#define MV_MAXVOLUME 127 /* formerly 63 */ - -// mirrors FX_MUSIC_PRIORITY from fx_man.h -#define MV_MUSIC_PRIORITY INT_MAX - -#define MIX_VOLUME(volume) ((max(0, min((volume), 255)) * (MV_MAXVOLUME + 1)) >> 8) - -extern float MV_GlobalVolume; -extern float MV_VolumeSmooth; - -static FORCE_INLINE float SMOOTH_VOLUME(float const volume, float const dest) -{ - return volume + (dest - volume) * MV_VolumeSmooth; -} - -template -static inline conditional_t< is_signed::value, make_unsigned_t, make_signed_t > FLIP_SIGN(T src) -{ - static constexpr make_unsigned_t msb = ((make_unsigned_t)1) << (sizeof(T) * CHAR_BIT - 1u); - return src ^ msb; -} - -template -static inline enable_if_t::value, T> SCALE_SAMPLE(T src, float volume) -{ - return (T)Blrintf((float)src * volume); -} - -template -static inline T CONVERT_SAMPLE_FROM_SIGNED(int src); - -template<> -inline int16_t CONVERT_SAMPLE_FROM_SIGNED(int src) -{ - return src; -} - -template -static inline int CONVERT_SAMPLE_TO_SIGNED(T src); - -template<> -inline int CONVERT_SAMPLE_TO_SIGNED(int16_t src) -{ - return src; -} - -template -static inline int CONVERT_LE_SAMPLE_TO_SIGNED(S src); - -template<> -inline int CONVERT_LE_SAMPLE_TO_SIGNED(uint8_t src) -{ - return FLIP_SIGN(src) << 8; -} - -template<> -inline int CONVERT_LE_SAMPLE_TO_SIGNED(int16_t src) -{ - return B_LITTLE16(src); -} - -template -static int CLAMP_SAMPLE(int src); - -template<> -inline int CLAMP_SAMPLE(int src) -{ - return clamp(src, INT16_MIN, INT16_MAX); -} - -template -static T MIX_SAMPLES(int signed_sample, T untouched_sample) -{ - return CONVERT_SAMPLE_FROM_SIGNED(CLAMP_SAMPLE(signed_sample + CONVERT_SAMPLE_TO_SIGNED(untouched_sample))); -} - -struct split16_t -{ - explicit split16_t(uint16_t x) : v{x} {} - - uint8_t l() const - { - return (v & 0x00FFu); - } - uint8_t h() const - { - return (v & 0xFF00u) >> CHAR_BIT; - } - -private: - uint16_t v; -}; - -#define MV_MIXBUFFERSIZE 256 -#define MV_NUMBEROFBUFFERS 32 -#define MV_TOTALBUFFERSIZE ( MV_MIXBUFFERSIZE * MV_NUMBEROFBUFFERS ) - -typedef enum : bool -{ - NoMoreData, - KeepPlaying -} playbackstatus; - - -typedef struct VoiceNode -{ - struct VoiceNode *next; - struct VoiceNode *prev; - - playbackstatus (*GetSound)(struct VoiceNode *); - - uint32_t (*mix)(struct VoiceNode *, uint32_t); - - const char *sound; - - float LeftVolume, LeftVolumeDest; - float RightVolume, RightVolumeDest; - - void *rawdataptr; - - const char *NextBlock; - const char *LoopStart; - const char *LoopEnd; - - wavefmt_t wavetype; - char bits; - char channels; - - float volume; - - int LoopCount; - uint32_t LoopSize; - uint32_t BlockLength; - - int ptrlength; // ptrlength-1 is the max permissible index for rawdataptr - - uint32_t PitchScale; - uint32_t FixedPointBufferSize; - - uint32_t length; - uint32_t SamplingRate; - uint32_t RateScale; - uint32_t position; - int Paused; - - int handle; - int priority; - - intptr_t callbackval; -} VoiceNode; - -typedef struct -{ - uint8_t left; - uint8_t right; -} Pan; - -typedef struct -{ - char RIFF[4]; - uint32_t file_size; - char WAVE[4]; - char fmt[4]; - uint32_t format_size; -} riff_header; - -typedef struct -{ - uint16_t wFormatTag; - uint16_t nChannels; - uint32_t nSamplesPerSec; - uint32_t nAvgBytesPerSec; - uint16_t nBlockAlign; - uint16_t nBitsPerSample; -} format_header; - -typedef struct -{ - uint8_t DATA[4]; - uint32_t size; -} data_header; - -extern Pan MV_PanTable[ MV_NUMPANPOSITIONS ][ MV_MAXVOLUME + 1 ]; -extern int MV_ErrorCode; -extern int MV_Installed; -extern int MV_MixRate; -extern char *MV_MusicBuffer; -extern int MV_BufferSize; - -extern int MV_MIDIRenderTempo; -extern int MV_MIDIRenderTimer; - -static FORCE_INLINE int MV_SetErrorCode(int status) -{ - MV_ErrorCode = status; - return MV_Error; -} - -void MV_PlayVoice(VoiceNode *voice); - -VoiceNode *MV_AllocVoice(int priority); - -void MV_SetVoiceMixMode(VoiceNode *voice); -void MV_SetVoiceVolume(VoiceNode *voice, int vol, int left, int right, float volume); -void MV_SetVoicePitch(VoiceNode *voice, uint32_t rate, int pitchoffset); - -int MV_GetVorbisPosition(VoiceNode *voice); -void MV_SetVorbisPosition(VoiceNode *voice, int position); -int MV_GetFLACPosition(VoiceNode *voice); -void MV_SetFLACPosition(VoiceNode *voice, int position); -int MV_GetXAPosition(VoiceNode *voice); -void MV_SetXAPosition(VoiceNode *voice, int position); -int MV_GetXMPPosition(VoiceNode *voice); -void MV_SetXMPPosition(VoiceNode *voice, int position); - -void MV_ReleaseVorbisVoice(VoiceNode *voice); -void MV_ReleaseZMusicVoice(VoiceNode* voice); -void MV_ReleaseFLACVoice(VoiceNode *voice); -void MV_ReleaseXAVoice(VoiceNode *voice); -void MV_ReleaseXMPVoice(VoiceNode *voice); - -// implemented in mix.c -template uint32_t MV_MixMono(struct VoiceNode * const voice, uint32_t length); -template uint32_t MV_MixStereo(struct VoiceNode * const voice, uint32_t length); -template void MV_Reverb(char const *src, char * const dest, const float volume, int count); - -// implemented in mixst.c -template uint32_t MV_MixMonoStereo(struct VoiceNode * const voice, uint32_t length); -template uint32_t MV_MixStereoStereo(struct VoiceNode * const voice, uint32_t length); - -extern char *MV_MixDestination; // pointer to the next output sample -extern int MV_SampleSize; -extern int MV_RightChannelOffset; - -#define loopStartTagCount 3 -extern const char *loopStartTags[loopStartTagCount]; -#define loopEndTagCount 2 -extern const char *loopEndTags[loopEndTagCount]; -#define loopLengthTagCount 2 -extern const char *loopLengthTags[loopLengthTagCount]; - -#if defined __POWERPC__ || defined GEKKO -# define BIGENDIAN -#endif - -#endif diff --git a/source/audiolib/src/driver_adlib.cpp b/source/audiolib/src/driver_adlib.cpp deleted file mode 100644 index aefb10bc5..000000000 --- a/source/audiolib/src/driver_adlib.cpp +++ /dev/null @@ -1,776 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -/********************************************************************** - module: AL_MIDI.C - - author: James R. Dose - date: April 1, 1994 - - Low level routines to support General MIDI music on AdLib compatible - cards. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#include "driver_adlib.h" - -#include "_al_midi.h" -#include "_multivc.h" -#include "compat.h" -#include "midi.h" -#include "midifuncs.h" -#include "opl3.h" -#include "opl3_reg.h" -#include "c_cvars.h" - -CUSTOM_CVARD(Bool, mus_al_stereo, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG, "enable/disable OPL3 stereo mode") -{ - AL_Stereo = self; - AL_SetStereo(AL_Stereo); -} - -CVARD(Bool, mus_al_additivemode, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enable/disable alternate additive AdLib timbre mode") - - -enum -{ - AdLibErr_Warning = -2, - AdLibErr_Error = -1, - AdLibErr_Ok = 0, -}; - -static void AL_Shutdown(void); -static int ErrorCode; - -int AdLibDrv_GetError(void) { return ErrorCode; } - -const char *AdLibDrv_ErrorString(int const ErrorNumber) -{ - const char *ErrorString; - - switch( ErrorNumber ) - { - case AdLibErr_Warning : - case AdLibErr_Error : - ErrorString = AdLibDrv_ErrorString( ErrorCode ); - break; - - case AdLibErr_Ok : - ErrorString = "AdLib ok."; - break; - - default: - ErrorString = "Unknown AdLib error."; - break; - } - - return ErrorString; -} - -int AdLibDrv_MIDI_Init(midifuncs * const funcs) -{ - AdLibDrv_MIDI_Shutdown(); - Bmemset(funcs, 0, sizeof(midifuncs)); - - funcs->NoteOff = AL_NoteOff; - funcs->NoteOn = AL_NoteOn; - funcs->PolyAftertouch = nullptr; - funcs->ControlChange = AL_ControlChange; - funcs->ProgramChange = AL_ProgramChange; - funcs->ChannelAftertouch = nullptr; - funcs->PitchBend = AL_SetPitchBend; - - return AdLibErr_Ok; -} - -void AdLibDrv_MIDI_HaltPlayback(void) { MV_UnhookMusicRoutine(); } - -void AdLibDrv_MIDI_Shutdown(void) -{ - AdLibDrv_MIDI_HaltPlayback(); - AL_Shutdown(); -} - -int AdLibDrv_MIDI_StartPlayback(void (*service)(void)) -{ - AdLibDrv_MIDI_HaltPlayback(); - - AL_Init(MV_MixRate); - MV_HookMusicRoutine(service); - - return MIDI_Ok; -} - -void AdLibDrv_MIDI_SetTempo(int const tempo, int const division) -{ - MV_MIDIRenderTempo = tempo * division / 60; - MV_MIDIRenderTimer = 0; -} - -static opl3_chip chip; - -opl3_chip *AL_GetChip(void) { return &chip; } - -static uint32_t constexpr OctavePitch[MAX_OCTAVE+1] = { - OCTAVE_0, OCTAVE_1, OCTAVE_2, OCTAVE_3, OCTAVE_4, OCTAVE_5, OCTAVE_6, OCTAVE_7, -}; - -static uint32_t NoteMod12[MAX_NOTE+1]; -static uint32_t NoteDiv12[MAX_NOTE+1]; - -// Pitch table - -//static unsigned NotePitch[ FINETUNE_MAX+1 ][ 12 ] = -// { -// { C, C_SHARP, D, D_SHARP, E, F, F_SHARP, G, G_SHARP, A, A_SHARP, B }, -// }; - -static uint32_t constexpr NotePitch[FINETUNE_MAX+1][12] = { - { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263, 0x287 }, - { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x242, 0x264, 0x288 }, - { 0x158, 0x16c, 0x182, 0x199, 0x1b1, 0x1cb, 0x1e6, 0x203, 0x221, 0x243, 0x265, 0x289 }, - { 0x158, 0x16c, 0x183, 0x19a, 0x1b2, 0x1cc, 0x1e7, 0x204, 0x222, 0x244, 0x266, 0x28a }, - { 0x159, 0x16d, 0x183, 0x19a, 0x1b3, 0x1cd, 0x1e8, 0x205, 0x223, 0x245, 0x267, 0x28b }, - { 0x15a, 0x16e, 0x184, 0x19b, 0x1b3, 0x1ce, 0x1e9, 0x206, 0x224, 0x246, 0x268, 0x28c }, - { 0x15a, 0x16e, 0x185, 0x19c, 0x1b4, 0x1ce, 0x1ea, 0x207, 0x225, 0x247, 0x269, 0x28e }, - { 0x15b, 0x16f, 0x185, 0x19d, 0x1b5, 0x1cf, 0x1eb, 0x208, 0x226, 0x248, 0x26a, 0x28f }, - { 0x15b, 0x170, 0x186, 0x19d, 0x1b6, 0x1d0, 0x1ec, 0x209, 0x227, 0x249, 0x26b, 0x290 }, - { 0x15c, 0x170, 0x187, 0x19e, 0x1b7, 0x1d1, 0x1ec, 0x20a, 0x228, 0x24a, 0x26d, 0x291 }, - { 0x15d, 0x171, 0x188, 0x19f, 0x1b7, 0x1d2, 0x1ed, 0x20b, 0x229, 0x24b, 0x26e, 0x292 }, - { 0x15d, 0x172, 0x188, 0x1a0, 0x1b8, 0x1d3, 0x1ee, 0x20c, 0x22a, 0x24c, 0x26f, 0x293 }, - { 0x15e, 0x172, 0x189, 0x1a0, 0x1b9, 0x1d4, 0x1ef, 0x20d, 0x22b, 0x24d, 0x270, 0x295 }, - { 0x15f, 0x173, 0x18a, 0x1a1, 0x1ba, 0x1d4, 0x1f0, 0x20e, 0x22c, 0x24e, 0x271, 0x296 }, - { 0x15f, 0x174, 0x18a, 0x1a2, 0x1bb, 0x1d5, 0x1f1, 0x20f, 0x22d, 0x24f, 0x272, 0x297 }, - { 0x160, 0x174, 0x18b, 0x1a3, 0x1bb, 0x1d6, 0x1f2, 0x210, 0x22e, 0x250, 0x273, 0x298 }, - { 0x161, 0x175, 0x18c, 0x1a3, 0x1bc, 0x1d7, 0x1f3, 0x211, 0x22f, 0x251, 0x274, 0x299 }, - { 0x161, 0x176, 0x18c, 0x1a4, 0x1bd, 0x1d8, 0x1f4, 0x212, 0x230, 0x252, 0x276, 0x29b }, - { 0x162, 0x176, 0x18d, 0x1a5, 0x1be, 0x1d9, 0x1f5, 0x212, 0x231, 0x254, 0x277, 0x29c }, - { 0x162, 0x177, 0x18e, 0x1a6, 0x1bf, 0x1d9, 0x1f5, 0x213, 0x232, 0x255, 0x278, 0x29d }, - { 0x163, 0x178, 0x18f, 0x1a6, 0x1bf, 0x1da, 0x1f6, 0x214, 0x233, 0x256, 0x279, 0x29e }, - { 0x164, 0x179, 0x18f, 0x1a7, 0x1c0, 0x1db, 0x1f7, 0x215, 0x235, 0x257, 0x27a, 0x29f }, - { 0x164, 0x179, 0x190, 0x1a8, 0x1c1, 0x1dc, 0x1f8, 0x216, 0x236, 0x258, 0x27b, 0x2a1 }, - { 0x165, 0x17a, 0x191, 0x1a9, 0x1c2, 0x1dd, 0x1f9, 0x217, 0x237, 0x259, 0x27c, 0x2a2 }, - { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1de, 0x1fa, 0x218, 0x238, 0x25a, 0x27e, 0x2a3 }, - { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1df, 0x1fb, 0x219, 0x239, 0x25b, 0x27f, 0x2a4 }, - { 0x167, 0x17c, 0x193, 0x1ab, 0x1c4, 0x1e0, 0x1fc, 0x21a, 0x23a, 0x25c, 0x280, 0x2a6 }, - { 0x168, 0x17d, 0x194, 0x1ac, 0x1c5, 0x1e0, 0x1fd, 0x21b, 0x23b, 0x25d, 0x281, 0x2a7 }, - { 0x168, 0x17d, 0x194, 0x1ad, 0x1c6, 0x1e1, 0x1fe, 0x21c, 0x23c, 0x25e, 0x282, 0x2a8 }, - { 0x169, 0x17e, 0x195, 0x1ad, 0x1c7, 0x1e2, 0x1ff, 0x21d, 0x23d, 0x260, 0x283, 0x2a9 }, - { 0x16a, 0x17f, 0x196, 0x1ae, 0x1c8, 0x1e3, 0x1ff, 0x21e, 0x23e, 0x261, 0x284, 0x2ab }, - { 0x16a, 0x17f, 0x197, 0x1af, 0x1c8, 0x1e4, 0x200, 0x21f, 0x23f, 0x262, 0x286, 0x2ac } -}; - -// Slot numbers as a function of the voice and the operator. -// ( melodic only) - -static int constexpr slotVoice[NUMADLIBVOICES][2] = { - { 0, 3 }, // voice 0 - { 1, 4 }, // 1 - { 2, 5 }, // 2 - { 6, 9 }, // 3 - { 7, 10 }, // 4 - { 8, 11 }, // 5 - { 12, 15 }, // 6 - { 13, 16 }, // 7 - { 14, 17 }, // 8 -}; - -static int VoiceLevel[AL_NumChipSlots][2]; -static int VoiceKsl[AL_NumChipSlots][2]; - -// This table gives the offset of each slot within the chip. -// offset = fn( slot) - -static int8_t constexpr offsetSlot[AL_NumChipSlots] = { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21 }; - -static int VoiceReserved[NUMADLIBVOICES * 2]; - -static AdLibVoice Voice[NUMADLIBVOICES * 2]; -static AdLibVoiceList Voice_Pool; - -static AdLibChannel Channel[NUMADLIBCHANNELS]; - -static int constexpr AL_LeftPort = ADLIB_PORT; -static int constexpr AL_RightPort = ADLIB_PORT + 2; - -static int constexpr AL_MaxMidiChannel = ARRAY_SIZE(Channel); - -int AL_Stereo = TRUE; - -int AL_PostAmp = 3; - -// TODO: clean up this shit... -#define OFFSET(structure, offset) (*((char **)&(structure)[offset])) - -#define LL_AddToTail(type, listhead, node) \ - LL_AddNode((char *)(node), (char **)&((listhead)->end), (char **)&((listhead)->start), (intptr_t) & ((type *)0)->prev, \ - (intptr_t) & ((type *)0)->next) - -#define LL_Remove(type, listhead, node) \ - LL_RemoveNode((char *)(node), (char **)&((listhead)->start), (char **)&((listhead)->end), (intptr_t) & ((type *)0)->next, \ - (intptr_t) & ((type *)0)->prev) - -static void LL_RemoveNode(char *item, char **head, char **tail, intptr_t next, intptr_t prev) -{ - if (OFFSET(item, prev) == nullptr) - *head = OFFSET(item, next); - else - OFFSET(OFFSET(item, prev), next) = OFFSET(item, next); - - if (OFFSET(item, next) == nullptr) - *tail = OFFSET(item, prev); - else - OFFSET(OFFSET(item, next), prev) = OFFSET(item, prev); - - OFFSET(item, next) = nullptr; - OFFSET(item, prev) = nullptr; -} - -static void LL_AddNode(char *item, char **head, char **tail, intptr_t next, intptr_t prev) -{ - OFFSET(item, prev) = nullptr; - OFFSET(item, next) = *head; - - if (*head) - OFFSET(*head, prev) = item; - else - *tail = item; - - *head = item; -} - - -static void AL_SendOutputToPort(int const port, int const reg, int const data) -{ - OPL3_WriteRegBuffered(&chip, (Bit16u)(reg + ((port & 2) << 7)), (Bit8u)data); -} - - -static void AL_SendOutput(int const voice, int const reg, int const data) -{ - AL_SendOutputToPort(voice ? AL_LeftPort : AL_RightPort, reg, data); -} - - -static void AL_SetVoiceTimbre(int const voice) -{ - int const channel = Voice[voice].channel; - int const patch = (channel == 9) ? Voice[voice].key + 128 : Channel[channel].Timbre; - - if (Voice[voice].timbre == patch) - return; - - Voice[voice].timbre = patch; - - auto const timbre = &ADLIB_TimbreBank[patch]; - - int const port = Voice[voice].port; - int const voc = (voice >= NUMADLIBVOICES) ? voice - NUMADLIBVOICES : voice; - int slot = slotVoice[voc][0]; - int off = offsetSlot[slot]; - - VoiceLevel[slot][port] = OPL3_TOTAL_LEVEL_MASK - (timbre->Level[0] & OPL3_TOTAL_LEVEL_MASK); - VoiceKsl[slot][port] = timbre->Level[0] & OPL3_KSL_MASK; - - AL_SendOutput(port, OPL3_FNUM_LOW + voc, 0); - AL_SendOutput(port, OPL3_KEYON_BLOCK + voc, 0); - - // Let voice clear the release - AL_SendOutput(port, OPL3_SUSTAIN_RELEASE + off, 0xff); - - AL_SendOutput(port, OPL3_ATTACK_DECAY + off, timbre->Env1[0]); - AL_SendOutput(port, OPL3_SUSTAIN_RELEASE + off, timbre->Env2[0]); - AL_SendOutput(port, OPL3_ENABLE_WAVE_SELECT + off, timbre->SAVEK[0]); - AL_SendOutput(port, OPL3_WAVE_SELECT + off, timbre->Wave[0]); - - AL_SendOutput(port, OPL3_KSL_LEVEL + off, timbre->Level[0]); - slot = slotVoice[voc][1]; - - AL_SendOutput(port, OPL3_FEEDBACK_CONNECTION + voc, (timbre->Feedback & OPL3_FEEDBACK_MASK) | OPL3_STEREO_BITS); - - off = offsetSlot[slot]; - - VoiceLevel[slot][port] = OPL3_TOTAL_LEVEL_MASK - (timbre->Level[1] & OPL3_TOTAL_LEVEL_MASK); - VoiceKsl[slot][port] = timbre->Level[1] & OPL3_KSL_MASK; - - AL_SendOutput(port, OPL3_KSL_LEVEL + off, OPL3_TOTAL_LEVEL_MASK); - - // Let voice clear the release - AL_SendOutput(port, OPL3_SUSTAIN_RELEASE + off, 0xff); - - AL_SendOutput(port, OPL3_ATTACK_DECAY + off, timbre->Env1[1]); - AL_SendOutput(port, OPL3_SUSTAIN_RELEASE + off, timbre->Env2[1]); - AL_SendOutput(port, OPL3_ENABLE_WAVE_SELECT + off, timbre->SAVEK[1]); - AL_SendOutput(port, OPL3_WAVE_SELECT + off, timbre->Wave[1]); -} - - -static void AL_SetVoiceVolume(int const voice) -{ - int const channel = Voice[voice].channel; - auto const timbre = &ADLIB_TimbreBank[Voice[voice].timbre]; - int const velocity = min(Voice[voice].velocity + timbre->Velocity, MAX_VELOCITY); - - int const voc = (voice >= NUMADLIBVOICES) ? voice - NUMADLIBVOICES : voice; - int const slot = slotVoice[voc][1]; - int const port = Voice[voice].port; - - // amplitude - auto t1 = (uint32_t)VoiceLevel[slot][port] * (velocity + 0x80); - t1 = (Channel[channel].Volume * t1) >> 15; - - uint32_t volume = t1 ^ OPL3_TOTAL_LEVEL_MASK; - volume |= (uint32_t)VoiceKsl[slot][port]; - - AL_SendOutput(port, OPL3_KSL_LEVEL + offsetSlot[slot], volume); - - // Check if this timbre is Additive - if (timbre->Feedback & 0x01) - { - int const slot = slotVoice[voc][0]; - uint32_t t2; - - // amplitude - if (mus_al_additivemode) - t1 = (uint32_t)VoiceLevel[slot][port] * (velocity + 0x80); - - t2 = (Channel[channel].Volume * t1) >> 15; - - volume = t2 ^ OPL3_TOTAL_LEVEL_MASK; - volume |= (uint32_t)VoiceKsl[slot][port]; - - AL_SendOutput(port, OPL3_KSL_LEVEL + offsetSlot[slot], volume); - } -} - - -static int AL_AllocVoice(void) -{ - if (!Voice_Pool.start) - return AL_VoiceNotFound; - - int const voice = Voice_Pool.start->num; - LL_Remove(AdLibVoice, &Voice_Pool, &Voice[voice]); - return voice; -} - - -static int AL_GetVoice(int const channel, int const key) -{ - auto const *voice = Channel[channel].Voices.start; - - while (voice != nullptr) - { - if (voice->key == (uint32_t)key) - return voice->num; - voice = voice->next; - } - - return AL_VoiceNotFound; -} - - -static void AL_SetVoicePitch(int const voice) -{ - int const port = Voice[voice].port; - int const voc = (voice >= NUMADLIBVOICES) ? voice - NUMADLIBVOICES : voice; - int const channel = Voice[voice].channel; - - int patch, note; - - if (channel == 9) - { - patch = Voice[voice].key + 128; - note = ADLIB_TimbreBank[patch].Transpose; - } - else - { - patch = Channel[channel].Timbre; - note = Voice[voice].key + ADLIB_TimbreBank[patch].Transpose; - } - - note += Channel[channel].KeyOffset - 12; - note = clamp(note, 0, MAX_NOTE); - - int detune = Channel[channel].KeyDetune; - - int ScaleNote = NoteMod12[note]; - int Octave = NoteDiv12[note]; - - int pitch = OctavePitch[Octave] | NotePitch[detune][ScaleNote]; - - Voice[voice].pitchleft = pitch; - - pitch |= Voice[voice].status; - - AL_SendOutput(port, OPL3_FNUM_LOW + voc, pitch); - AL_SendOutput(port, OPL3_KEYON_BLOCK + voc, pitch >> 8); -} - -static void AL_SetVoicePan(int const voice) -{ - int const port = Voice[voice].port; - int const voc = (voice >= NUMADLIBVOICES) ? voice - NUMADLIBVOICES : voice; - int const channel = Voice[voice].channel; - - if (AL_Stereo) - AL_SendOutput(port, 0xD0 + voc, Channel[channel].Pan << 1); -} - - -static void AL_SetChannelVolume(int const channel, int const volume) -{ - Channel[channel].Volume = clamp(volume, 0, AL_MaxVolume); - - auto voice = Channel[channel].Voices.start; - - while (voice != nullptr) - { - AL_SetVoiceVolume(voice->num); - voice = voice->next; - } -} - - -static void AL_SetChannelPan(int const channel, int const pan) -{ - // Don't pan drum sounds - if (channel != 9) - Channel[channel].Pan = pan; - - auto voice = Channel[channel].Voices.start; - while (voice != nullptr) - { - AL_SetVoicePan(voice->num); - voice = voice->next; - } -} - - -static void AL_SetChannelDetune(int const channel, int const detune) { Channel[channel].Detune = detune; } - - -static void AL_ResetVoices(void) -{ - Voice_Pool.start = nullptr; - Voice_Pool.end = nullptr; - - int const numvoices = NUMADLIBVOICES * 2; - - for (int index = 0; index < numvoices; index++) - { - if (VoiceReserved[index] == FALSE) - { - Voice[index].num = index; - Voice[index].key = 0; - Voice[index].velocity = 0; - Voice[index].channel = -1; - Voice[index].timbre = -1; - Voice[index].port = (index < NUMADLIBVOICES) ? 0 : 1; - Voice[index].status = NOTE_OFF; - LL_AddToTail(AdLibVoice, &Voice_Pool, &Voice[index]); - } - } - - for (int index = 0; index < NUMADLIBCHANNELS; index++) - { - Channel[index] = {}; - Channel[index].Volume = AL_DefaultChannelVolume; - Channel[index].Pan = 64; - Channel[index].PitchBendRange = AL_DefaultPitchBendRange; - Channel[index].PitchBendSemiTones = AL_DefaultPitchBendRange / 100; - Channel[index].PitchBendHundreds = AL_DefaultPitchBendRange % 100; - } -} - - -static void AL_CalcPitchInfo(void) -{ - // int finetune; - // double detune; - - for (int note = 0; note <= MAX_NOTE; note++) - { - NoteMod12[note] = note % 12; - NoteDiv12[note] = note / 12; - } - - // for( finetune = 1; finetune <= FINETUNE_MAX; finetune++ ) - // { - // detune = pow( 2, ( double )finetune / ( 12.0 * FINETUNE_RANGE ) ); - // for( note = 0; note < 12; note++ ) - // { - // NotePitch[ finetune ][ note ] = ( ( double )NotePitch[ 0 ][ note ] * detune ); - // } - // } -} - - -static void AL_FlushCard(int const port) -{ - for (int i = 0; i < NUMADLIBVOICES; i++) - { - if (VoiceReserved[i]) - continue; - - auto slot1 = offsetSlot[slotVoice[i][0]]; - auto slot2 = offsetSlot[slotVoice[i][1]]; - - AL_SendOutputToPort(port, OPL3_FNUM_LOW + i, 0); - AL_SendOutputToPort(port, OPL3_KEYON_BLOCK + i, 0); - - AL_SendOutputToPort(port, OPL3_WAVE_SELECT + slot1, 0); - AL_SendOutputToPort(port, OPL3_WAVE_SELECT + slot2, 0); - - // Set the envelope to be fast and quiet - AL_SendOutputToPort(port, OPL3_ATTACK_DECAY + slot1, 0xff); - AL_SendOutputToPort(port, OPL3_ATTACK_DECAY + slot2, 0xff); - AL_SendOutputToPort(port, OPL3_SUSTAIN_RELEASE + slot1, 0xff); - AL_SendOutputToPort(port, OPL3_SUSTAIN_RELEASE + slot2, 0xff); - - // Maximum attenuation - AL_SendOutputToPort(port, OPL3_KSL_LEVEL + slot1, 0xff); - AL_SendOutputToPort(port, OPL3_KSL_LEVEL + slot2, 0xff); - } -} - - -static void AL_Reset(void) -{ - AL_SendOutputToPort(ADLIB_PORT, 1, OPL3_ENABLE_WAVE_SELECT); - AL_SendOutputToPort(ADLIB_PORT, OPL3_KBD_SPLIT_REGISTER, 0); - - // Set the values: AM Depth, VIB depth & Rhythm - AL_SendOutputToPort(ADLIB_PORT, OPL3_PERCUSSION_REGISTER, 0); - - AL_SetStereo(AL_Stereo); - - AL_FlushCard(AL_LeftPort); - AL_FlushCard(AL_RightPort); -} - - -void AL_SetStereo(int const stereo) { AL_SendOutputToPort(AL_RightPort, OPL3_MODE_REGISTER, (stereo << 1) + 1); } - - -static void AL_NoteOff(int const channel, int const key, int velocity) -{ - UNREFERENCED_PARAMETER(velocity); - - // We only play channels 1 through 10 - if (channel > AL_MaxMidiChannel) - return; - - int const voice = AL_GetVoice(channel, key); - - if (voice == AL_VoiceNotFound) - return; - - Voice[voice].status = NOTE_OFF; - - int const port = Voice[voice].port; - int const voc = (voice >= NUMADLIBVOICES) ? voice - NUMADLIBVOICES : voice; - - AL_SendOutput(port, OPL3_KEYON_BLOCK + voc, hibyte(Voice[voice].pitchleft)); - - LL_Remove(AdLibVoice, &Channel[channel].Voices, &Voice[voice]); - LL_AddToTail(AdLibVoice, &Voice_Pool, &Voice[voice]); -} - - -static void AL_NoteOn(int const channel, int const key, int const velocity) -{ - // We only play channels 1 through 10 - if (channel > AL_MaxMidiChannel) - return; - - if (velocity == 0) - { - AL_NoteOff(channel, key, velocity); - return; - } - - int voice = AL_AllocVoice(); - - if (voice == AL_VoiceNotFound) - { - if (Channel[9].Voices.start) - { - AL_NoteOff(9, Channel[9].Voices.start->key, 0); - voice = AL_AllocVoice(); - } - - if (voice == AL_VoiceNotFound) - return; - } - - Voice[voice].key = key; - Voice[voice].channel = channel; - Voice[voice].velocity = velocity; - Voice[voice].status = NOTE_ON; - - LL_AddToTail(AdLibVoice, &Channel[channel].Voices, &Voice[voice]); - - AL_SetVoiceTimbre(voice); - AL_SetVoiceVolume(voice); - AL_SetVoicePitch(voice); - AL_SetVoicePan(voice); -} - - -static inline void AL_AllNotesOff(int const channel) -{ - while (Channel[channel].Voices.start != nullptr) - AL_NoteOff(channel, Channel[channel].Voices.start->key, 0); -} - - -static void AL_ControlChange(int const channel, int const type, int const data) -{ - // We only play channels 1 through 10 - if (channel > AL_MaxMidiChannel) - return; - - switch (type) - { - case MIDI_VOLUME: - AL_SetChannelVolume(channel, data); - break; - - case MIDI_PAN: - AL_SetChannelPan(channel, data); - break; - - case MIDI_DETUNE: - AL_SetChannelDetune(channel, data); - break; - - case MIDI_ALL_NOTES_OFF: - AL_AllNotesOff(channel); - break; - - case MIDI_RESET_ALL_CONTROLLERS: - AL_ResetVoices(); - AL_SetChannelVolume(channel, AL_DefaultChannelVolume); - AL_SetChannelPan(channel, 64); - AL_SetChannelDetune(channel, 0); - break; - - case MIDI_RPN_MSB: - Channel[channel].RPN &= 0x00FF; - Channel[channel].RPN |= (data & 0xFF) << 8; - break; - - case MIDI_RPN_LSB: - Channel[channel].RPN &= 0xFF00; - Channel[channel].RPN |= data & 0xFF; - break; - - case MIDI_DATAENTRY_MSB: - if (Channel[channel].RPN == MIDI_PITCHBEND_RPN) - { - Channel[channel].PitchBendSemiTones = data; - Channel[channel].PitchBendRange = Channel[channel].PitchBendSemiTones * 100 + Channel[channel].PitchBendHundreds; - } - break; - - case MIDI_DATAENTRY_LSB: - if (Channel[channel].RPN == MIDI_PITCHBEND_RPN) - { - Channel[channel].PitchBendHundreds = data; - Channel[channel].PitchBendRange = Channel[channel].PitchBendSemiTones * 100 + Channel[channel].PitchBendHundreds; - } - break; - } -} - - -static void AL_ProgramChange(int const channel, int const patch) -{ - // We only play channels 1 through 10 - if (channel > AL_MaxMidiChannel) - return; - - Channel[channel].Timbre = patch; -} - - -static void AL_SetPitchBend(int const channel, int const lsb, int const msb) -{ - // We only play channels 1 through 10 - if (channel > AL_MaxMidiChannel) - return; - - int const pitchbend = lsb + (msb << 8); - int const TotalBend = pitchbend * Channel[channel].PitchBendRange / (PITCHBEND_CENTER / FINETUNE_RANGE); - - Channel[channel].Pitchbend = pitchbend; - Channel[channel].KeyOffset = (int)(TotalBend / FINETUNE_RANGE); - Channel[channel].KeyOffset -= Channel[channel].PitchBendSemiTones; - - Channel[channel].KeyDetune = (uint32_t)(TotalBend % FINETUNE_RANGE); - - auto voice = Channel[channel].Voices.start; - while (voice != nullptr) - { - AL_SetVoicePitch(voice->num); - voice = voice->next; - } -} - - -static void AL_Shutdown(void) -{ - AL_ResetVoices(); - AL_Reset(); -} - - -static int AL_Init(int const rate) -{ - OPL3_Reset(&chip, rate); - - AL_CalcPitchInfo(); - AL_Reset(); - AL_ResetVoices(); - - return AdLibErr_Ok; -} - - -void AL_RegisterTimbreBank(uint8_t const *timbres) -{ - for (int i = 0; i < 256; i++) - { - ADLIB_TimbreBank[i].SAVEK[0] = *(timbres++); - ADLIB_TimbreBank[i].SAVEK[1] = *(timbres++); - ADLIB_TimbreBank[i].Level[0] = *(timbres++); - ADLIB_TimbreBank[i].Level[1] = *(timbres++); - ADLIB_TimbreBank[i].Env1[0] = *(timbres++); - ADLIB_TimbreBank[i].Env1[1] = *(timbres++); - ADLIB_TimbreBank[i].Env2[0] = *(timbres++); - ADLIB_TimbreBank[i].Env2[1] = *(timbres++); - ADLIB_TimbreBank[i].Wave[0] = *(timbres++); - ADLIB_TimbreBank[i].Wave[1] = *(timbres++); - ADLIB_TimbreBank[i].Feedback = *(timbres++); - ADLIB_TimbreBank[i].Transpose = *(int8_t *)(timbres++); - ADLIB_TimbreBank[i].Velocity = *(int8_t *)(timbres++); - } -} diff --git a/source/audiolib/src/driver_adlib.h b/source/audiolib/src/driver_adlib.h deleted file mode 100644 index 198d84ae8..000000000 --- a/source/audiolib/src/driver_adlib.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ - -#include "al_midi.h" -#include "midifuncs.h" -#include "opl3.h" - -extern int AL_Stereo; -extern int AL_PostAmp; - -int AdLibDrv_GetError(void); -const char *AdLibDrv_ErrorString(int ErrorNumber); - -int AdLibDrv_MIDI_Init(midifuncs *); -void AdLibDrv_MIDI_Shutdown(void); -int AdLibDrv_MIDI_StartPlayback(void (*service)(void)); -void AdLibDrv_MIDI_HaltPlayback(void); -void AdLibDrv_MIDI_SetTempo(int tempo, int division); - diff --git a/source/audiolib/src/driver_directsound.cpp b/source/audiolib/src/driver_directsound.cpp deleted file mode 100644 index c82891353..000000000 --- a/source/audiolib/src/driver_directsound.cpp +++ /dev/null @@ -1,422 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -/** - * DirectSound output driver for MultiVoc - */ - -#define NEED_MMSYSTEM_H -#define NEED_DSOUND_H - -#include "driver_directsound.h" - -#include "compat.h" -#include "multivoc.h" -#include "mutex.h" -#include "windows_inc.h" - -#define MIXBUFFERPOSITIONS 8 - -static int ErrorCode; -static int Initialised; -static int Playing; - -static char * MixBuffer; -static int MixBufferSize; -static int MixBufferCount; -static int MixBufferCurrent; -static int MixBufferUsed; - -static void (*MixCallBack)(void); - -static LPDIRECTSOUND lpds; -static LPDIRECTSOUNDBUFFER lpdsbprimary, lpdsbsec; -static LPDIRECTSOUNDNOTIFY lpdsnotify; - -static HANDLE mixThread; -static mutex_t mutex; - -static DSBPOSITIONNOTIFY notifyPositions[MIXBUFFERPOSITIONS + 1] = {}; - -static void FillBufferPosition(char * ptr, int remaining) -{ - int len = 0; - - do - { - if (MixBufferUsed == MixBufferSize) - { - MixCallBack(); - MixBufferUsed = 0; - - if (++MixBufferCurrent >= MixBufferCount) - MixBufferCurrent -= MixBufferCount; - } - - do - { - char *sptr = MixBuffer + (MixBufferCurrent * MixBufferSize) + MixBufferUsed; - - len = MixBufferSize - MixBufferUsed; - - if (remaining < len) - len = remaining; - - memcpy(ptr, sptr, len); - - ptr += len; - MixBufferUsed += len; - remaining -= len; - } - while (remaining >= len && MixBufferUsed < MixBufferSize); - } - while (remaining >= len); -} - -static void FillBuffer(int bufnum) -{ - LPVOID ptr, ptr2; - DWORD remaining, remaining2; - int retries = 1; - - do - { - HRESULT err = IDirectSoundBuffer_Lock(lpdsbsec, notifyPositions[bufnum].dwOffset, notifyPositions[1].dwOffset, - &ptr, &remaining, &ptr2, &remaining2, 0); - - if (EDUKE32_PREDICT_FALSE(FAILED(err))) - { - if (err == DSERR_BUFFERLOST) - { - if (FAILED(err = IDirectSoundBuffer_Restore(lpdsbsec))) - goto fail; - - if (retries-- > 0) - continue; - } -fail: - MV_Printf("DirectSound FillBuffer: err %x\n", (uint32_t)err); - - return; - } - break; - } - while (1); - - if (ptr && remaining) - FillBufferPosition((char *)ptr, remaining); - - if (ptr2 && remaining2) - FillBufferPosition((char *)ptr2, remaining2); - - IDirectSoundBuffer_Unlock(lpdsbsec, ptr, remaining, ptr2, remaining2); -} - -static DWORD WINAPI fillDataThread(LPVOID lpParameter) -{ - UNREFERENCED_PARAMETER(lpParameter); - - HANDLE handles[MIXBUFFERPOSITIONS+1]; - - for (int i = 0; i < ARRAY_SSIZE(handles); i++) - handles[i] = notifyPositions[i].hEventNotify; - - do - { - DWORD const waitret = WaitForMultipleObjects(MIXBUFFERPOSITIONS, handles, FALSE, INFINITE); - - if (waitret >= WAIT_OBJECT_0 && waitret < WAIT_OBJECT_0+MIXBUFFERPOSITIONS) - { - mutex_lock(&mutex); - FillBuffer((waitret + MIXBUFFERPOSITIONS - 1 - WAIT_OBJECT_0) % MIXBUFFERPOSITIONS); - mutex_unlock(&mutex); - } - else - { - switch (waitret) - { - case WAIT_OBJECT_0 + MIXBUFFERPOSITIONS: - ExitThread(0); - break; - - default: - MV_Printf("DirectSound fillDataThread: wfmo err %d\n", (int)waitret); - break; - } - } - } - while (1); - - return 0; -} - -static void TeardownDSound(HRESULT err) -{ - if (FAILED(err)) - MV_Printf("Dying error: %x\n", (uint32_t)err); - - if (lpdsnotify) - IDirectSoundNotify_Release(lpdsnotify), lpdsnotify = nullptr; - - for (int i = 0; i < MIXBUFFERPOSITIONS + 1; i++) - { - if (notifyPositions[i].hEventNotify) - CloseHandle(notifyPositions[i].hEventNotify); - notifyPositions[i].hEventNotify = 0; - } - -#ifdef RENDERTYPEWIN - if (mutex) - CloseHandle(mutex), mutex = nullptr; -#endif - - if (lpdsbsec) - IDirectSoundBuffer_Release(lpdsbsec), lpdsbsec = nullptr; - - if (lpdsbprimary) - IDirectSoundBuffer_Release(lpdsbprimary), lpdsbprimary = nullptr; - - if (lpds) - IDirectSound_Release(lpds), lpds = nullptr; -} - -static int DirectSound_Error(HRESULT err, int code) -{ - TeardownDSound(err); - ErrorCode = code; - return DSErr_Error; -} - -int DirectSoundDrv_PCM_Init(int *mixrate, int *numchannels, void * initdata) -{ - HRESULT err; - DSBUFFERDESC bufdesc = {}; - WAVEFORMATEX wfex = {}; - - if (Initialised) - DirectSoundDrv_PCM_Shutdown(); - - if (FAILED(err = DirectSoundCreate(0, &lpds, 0))) - return DirectSound_Error(err, DSErr_DirectSoundCreate); - - if (FAILED(err = IDirectSound_SetCooperativeLevel(lpds, (HWND) initdata, DSSCL_PRIORITY))) - return DirectSound_Error(err, DSErr_SetCooperativeLevel); - - bufdesc.dwSize = sizeof(DSBUFFERDESC); - bufdesc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; - - if (FAILED(err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbprimary, 0))) - return DirectSound_Error(err, DSErr_CreateSoundBuffer); - - wfex.wFormatTag = WAVE_FORMAT_PCM; - wfex.nChannels = *numchannels; - wfex.nSamplesPerSec = *mixrate; - wfex.wBitsPerSample = 16; - wfex.nBlockAlign = wfex.nChannels * wfex.wBitsPerSample / 8; - wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; - - if (FAILED(err = IDirectSoundBuffer_SetFormat(lpdsbprimary, &wfex))) - return DirectSound_Error(err, DSErr_SetFormat); - - bufdesc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; - - bufdesc.dwBufferBytes = wfex.nBlockAlign * 2048 * 2; - bufdesc.lpwfxFormat = &wfex; - - if (FAILED(err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbsec, 0))) - return DirectSound_Error(err, DSErr_CreateSoundBufferSecondary); - - if (FAILED(err = IDirectSoundBuffer_QueryInterface(lpdsbsec, IID_IDirectSoundNotify, (LPVOID *)&lpdsnotify))) - return DirectSound_Error(err, DSErr_Notify); - - for (int i = 0; i < MIXBUFFERPOSITIONS; i++) - { - notifyPositions[i].dwOffset = (bufdesc.dwBufferBytes/MIXBUFFERPOSITIONS)*i; - notifyPositions[i].hEventNotify = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (!notifyPositions[i].hEventNotify) - return DirectSound_Error(DS_OK, DSErr_NotifyEvents); - } - - notifyPositions[MIXBUFFERPOSITIONS].dwOffset = DSBPN_OFFSETSTOP; - notifyPositions[MIXBUFFERPOSITIONS].hEventNotify = CreateEvent(nullptr, FALSE, FALSE, nullptr); - - if (FAILED(err = IDirectSoundNotify_SetNotificationPositions(lpdsnotify, MIXBUFFERPOSITIONS+1, notifyPositions))) - return DirectSound_Error(err, DSErr_SetNotificationPositions); - - if (FAILED(err = IDirectSoundBuffer_Play(lpdsbprimary, 0, 0, DSBPLAY_LOOPING))) - return DirectSound_Error(err, DSErr_Play); - - Initialised = 1; - - return DSErr_Ok; -} - -void DirectSoundDrv_PCM_Shutdown(void) -{ - if (!Initialised) - return; - - DirectSoundDrv_PCM_StopPlayback(); - TeardownDSound(DS_OK); - - Initialised = 0; -} - -int DirectSoundDrv_PCM_BeginPlayback(char *BufferStart, int BufferSize, int NumDivisions, void (*CallBackFunc)(void)) -{ - if (!Initialised) - { - ErrorCode = DSErr_Uninitialised; - return DSErr_Error; - } - - DirectSoundDrv_PCM_StopPlayback(); - - MixBuffer = BufferStart; - MixBufferSize = BufferSize; - MixBufferCount = NumDivisions; - MixBufferCurrent = 0; - MixBufferUsed = 0; - MixCallBack = CallBackFunc; - - // prime the buffer - FillBuffer(0); - - if ((mixThread = CreateThread(nullptr, 0, fillDataThread, 0, 0, 0)) == nullptr) - { - ErrorCode = DSErr_CreateThread; - return DSErr_Error; - } - - SetThreadPriority(mixThread, THREAD_PRIORITY_ABOVE_NORMAL); - - HRESULT err = IDirectSoundBuffer_Play(lpdsbsec, 0, 0, DSBPLAY_LOOPING); - - if (FAILED(err)) - { - ErrorCode = DSErr_PlaySecondary; - return DSErr_Error; - } - - Playing = 1; - - return DSErr_Ok; -} - -void DirectSoundDrv_PCM_StopPlayback(void) -{ - if (!Playing) - return; - - IDirectSoundBuffer_Stop(lpdsbsec); - IDirectSoundBuffer_SetCurrentPosition(lpdsbsec, 0); - - Playing = 0; -} - -void DirectSoundDrv_PCM_Lock(void) -{ - mutex_lock(&mutex); -} - -void DirectSoundDrv_PCM_Unlock(void) -{ - mutex_unlock(&mutex); -} - -int DirectSoundDrv_GetError(void) -{ - return ErrorCode; -} - -const char *DirectSoundDrv_ErrorString(int ErrorNumber) -{ - const char *ErrorString; - - switch (ErrorNumber) - { - case DSErr_Warning: - case DSErr_Error: - ErrorString = DirectSoundDrv_ErrorString(ErrorCode); - break; - - case DSErr_Ok: - ErrorString = "DirectSound ok."; - break; - - case DSErr_Uninitialised: - ErrorString = "DirectSound uninitialised."; - break; - - case DSErr_DirectSoundCreate: - ErrorString = "DirectSound error: DirectSoundCreate failed."; - break; - - case DSErr_SetCooperativeLevel: - ErrorString = "DirectSound error: SetCooperativeLevel failed."; - break; - - case DSErr_CreateSoundBuffer: - ErrorString = "DirectSound error: primary CreateSoundBuffer failed."; - break; - - case DSErr_CreateSoundBufferSecondary: - ErrorString = "DirectSound error: secondary CreateSoundBuffer failed."; - break; - - case DSErr_SetFormat: - ErrorString = "DirectSound error: primary buffer SetFormat failed."; - break; - - case DSErr_SetFormatSecondary: - ErrorString = "DirectSound error: secondary buffer SetFormat failed."; - break; - - case DSErr_Notify: - ErrorString = "DirectSound error: failed querying secondary buffer for notify interface."; - break; - - case DSErr_NotifyEvents: - ErrorString = "DirectSound error: failed creating notify events."; - break; - - case DSErr_SetNotificationPositions: - ErrorString = "DirectSound error: failed setting notification positions."; - break; - - case DSErr_Play: - ErrorString = "DirectSound error: primary buffer Play failed."; - break; - - case DSErr_PlaySecondary: - ErrorString = "DirectSound error: secondary buffer Play failed."; - break; - - case DSErr_CreateThread: - ErrorString = "DirectSound error: failed creating mix thread."; - break; - - default: - ErrorString = "Unknown DirectSound error code."; - break; - } - - return ErrorString; -} diff --git a/source/audiolib/src/driver_directsound.h b/source/audiolib/src/driver_directsound.h deleted file mode 100644 index 68874707d..000000000 --- a/source/audiolib/src/driver_directsound.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -#include - -enum -{ - DSErr_Warning = -2, - DSErr_Error = -1, - DSErr_Ok = 0, - DSErr_Uninitialised, - DSErr_DirectSoundCreate, - DSErr_SetCooperativeLevel, - DSErr_CreateSoundBuffer, - DSErr_CreateSoundBufferSecondary, - DSErr_SetFormat, - DSErr_SetFormatSecondary, - DSErr_Notify, - DSErr_NotifyEvents, - DSErr_SetNotificationPositions, - DSErr_Play, - DSErr_PlaySecondary, - DSErr_CreateThread, -}; - -int DirectSoundDrv_GetError(void); -const char *DirectSoundDrv_ErrorString(int ErrorNumber); - -int DirectSoundDrv_PCM_Init(int *mixrate, int *numchannels, void *initdata); -void DirectSoundDrv_PCM_Shutdown(void); -int DirectSoundDrv_PCM_BeginPlayback(char *BufferStart, int BufferSize, int NumDivisions, void (*CallBackFunc)(void)); -void DirectSoundDrv_PCM_StopPlayback(void); -void DirectSoundDrv_PCM_Lock(void); -void DirectSoundDrv_PCM_Unlock(void); diff --git a/source/audiolib/src/driver_sdl.cpp b/source/audiolib/src/driver_sdl.cpp deleted file mode 100644 index 9e8b9d5b3..000000000 --- a/source/audiolib/src/driver_sdl.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -/** - * libSDL output driver for MultiVoc - */ - -#include "driver_sdl.h" - -#include "compat.h" -#include "multivoc.h" -#include "mutex.h" -#include "sdl_inc.h" - -enum { - SDLErr_Warning = -2, - SDLErr_Error = -1, - SDLErr_Ok = 0, - SDLErr_Uninitialised, - SDLErr_InitSubSystem, - SDLErr_OpenAudio -}; - -static int ErrorCode = SDLErr_Ok; -static int Initialised; -static int Playing; -static uint32_t StartedSDL; - -static char *MixBuffer; -static int MixBufferSize; -static int MixBufferCount; -static int MixBufferCurrent; -static int MixBufferUsed; -static void (*MixCallBack)(void); - -#if (SDL_MAJOR_VERSION == 2) -static SDL_AudioDeviceID audio_dev; -#endif - -static void fillData(void * userdata, Uint8 * ptr, int remaining) -{ - if (!MixBuffer || !MixCallBack) - return; - - UNREFERENCED_PARAMETER(userdata); - - int len; - char *sptr; - - while (remaining > 0) { - if (MixBufferUsed == MixBufferSize) { - MixCallBack(); - - MixBufferUsed = 0; - MixBufferCurrent++; - if (MixBufferCurrent >= MixBufferCount) { - MixBufferCurrent -= MixBufferCount; - } - } - - while (remaining > 0 && MixBufferUsed < MixBufferSize) { - sptr = MixBuffer + (MixBufferCurrent * MixBufferSize) + MixBufferUsed; - - len = MixBufferSize - MixBufferUsed; - if (remaining < len) { - len = remaining; - } - - memcpy(ptr, sptr, len); - - ptr += len; - MixBufferUsed += len; - remaining -= len; - } - } -} - -int SDLDrv_GetError(void) -{ - return ErrorCode; -} - -const char *SDLDrv_ErrorString(int ErrorNumber) -{ - const char *ErrorString; - - switch( ErrorNumber ) { - case SDLErr_Warning : - case SDLErr_Error : - ErrorString = SDLDrv_ErrorString( ErrorCode ); - break; - - case SDLErr_Ok : - ErrorString = "SDL Audio ok."; - break; - - case SDLErr_Uninitialised: - ErrorString = "SDL Audio uninitialised."; - break; - - case SDLErr_InitSubSystem: - ErrorString = "SDL Audio: error in Init or InitSubSystem."; - break; - - case SDLErr_OpenAudio: - ErrorString = "SDL Audio: error in OpenAudio."; - break; - - default: - ErrorString = "Unknown SDL Audio error code."; - break; - } - - return ErrorString; -} - -int SDLDrv_PCM_Init(int *mixrate, int *numchannels, void * initdata) -{ - UNREFERENCED_PARAMETER(initdata); - - Uint32 inited; - int err = 0; - SDL_AudioSpec spec, actual; - - if (Initialised) { - SDLDrv_PCM_Shutdown(); - } - - inited = SDL_WasInit(SDL_INIT_AUDIO); - - if (!(inited & SDL_INIT_AUDIO)) { - err = SDL_InitSubSystem(SDL_INIT_AUDIO); - StartedSDL = SDL_WasInit(SDL_INIT_AUDIO); - } - - if (err < 0) { - ErrorCode = SDLErr_InitSubSystem; - return SDLErr_Error; - } - - int chunksize = 512; -#ifdef __ANDROID__ - chunksize = droidinfo.audio_buffer_size; -#endif - - spec.freq = *mixrate; - spec.format = AUDIO_S16SYS; - spec.channels = *numchannels; - spec.samples = chunksize; - spec.callback = fillData; - spec.userdata = nullptr; - - Bmemset(&actual, 0, sizeof(actual)); - -#if (SDL_MAJOR_VERSION == 1) - err = !SDL_OpenAudio(&spec, &actual); -#else - audio_dev = err = SDL_OpenAudioDevice(nullptr, 0, &spec, &actual, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); -#endif - - if (err == 0) { - ErrorCode = SDLErr_OpenAudio; - return SDLErr_Error; - } - -#if (SDL_MAJOR_VERSION == 1) - char drivername[64] = "(error)"; - SDL_AudioDriverName(drivername, sizeof(drivername)); - MV_Printf("SDL %s driver\n", drivername); -#else - auto drivername = Xstrdup(SDL_GetCurrentAudioDriver()); - - for (int i=0;drivername[i] != 0;++i) - drivername[i] = toupper(drivername[i]); - - auto devname = Xstrdup(SDL_GetAudioDeviceName(0, 0)); - auto pdevname = Bstrchr(devname, '('); - - if (pdevname) - { - auto rt = Bstrchr(pdevname++, ')'); - if (rt != nullptr) *rt = '\0'; - } - else - pdevname = devname; - - MV_Printf("SDL %s driver on %s\n", drivername, pdevname); - - Xfree(devname); - Xfree(drivername); -#endif - -#if (SDL_MAJOR_VERSION == 1) - if (actual.freq == 0 || actual.channels == 0) { - // hack for when SDL said it opened the audio, but clearly didn't - SDL_CloseAudio(); - ErrorCode = SDLErr_OpenAudio; - return SDLErr_Error; - } -#endif - err = 0; - - *mixrate = actual.freq; - if (actual.format == AUDIO_U8 || actual.format == AUDIO_S8) - { - ErrorCode = SDLErr_OpenAudio; - err = 1; - } - - *numchannels = actual.channels; - if (actual.channels != 1 && actual.channels != 2) - { - ErrorCode = SDLErr_OpenAudio; - err = 1; - } - - if (err) - { - SDL_CloseAudio(); - return SDLErr_Error; - } - - Initialised = 1; - return SDLErr_Ok; -} - -void SDLDrv_PCM_Shutdown(void) -{ - if (!Initialised) - return; - - if (StartedSDL) - SDL_QuitSubSystem(StartedSDL); - - StartedSDL = 0; - Initialised = 0; -} - -int SDLDrv_PCM_BeginPlayback(char *BufferStart, int BufferSize, - int NumDivisions, void ( *CallBackFunc )( void ) ) -{ - if (!Initialised) { - ErrorCode = SDLErr_Uninitialised; - return SDLErr_Error; - } - - if (Playing) { - SDLDrv_PCM_StopPlayback(); - } - - MixBuffer = BufferStart; - MixBufferSize = BufferSize; - MixBufferCount = NumDivisions; - MixBufferCurrent = 0; - MixBufferUsed = 0; - MixCallBack = CallBackFunc; - - // prime the buffer - MixCallBack(); - -#if (SDL_MAJOR_VERSION == 2) - SDL_PauseAudioDevice(audio_dev, 0); -#else - SDL_PauseAudio(0); -#endif - Playing = 1; - - return SDLErr_Ok; -} - -void SDLDrv_PCM_StopPlayback(void) -{ - if (!Initialised || !Playing) { - return; - } - -#if (SDL_MAJOR_VERSION == 2) - SDL_PauseAudioDevice(audio_dev, 1); -#else - SDL_PauseAudio(1); -#endif - - Playing = 0; -} - -void SDLDrv_PCM_Lock(void) -{ -#if (SDL_MAJOR_VERSION == 2) - SDL_LockAudioDevice(audio_dev); -#else - SDL_LockAudio(); -#endif -} - -void SDLDrv_PCM_Unlock(void) -{ -#if (SDL_MAJOR_VERSION == 2) - SDL_UnlockAudioDevice(audio_dev); -#else - SDL_UnlockAudio(); -#endif -} diff --git a/source/audiolib/src/driver_sdl.h b/source/audiolib/src/driver_sdl.h deleted file mode 100644 index f3737a87b..000000000 --- a/source/audiolib/src/driver_sdl.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -#ifndef driver_sdl_h__ -#define driver_sdl_h__ - -#include "compat.h" - -int SDLDrv_GetError(void); -const char *SDLDrv_ErrorString( int ErrorNumber ); -int SDLDrv_PCM_Init(int *mixrate, int *numchannels, void * initdata); -void SDLDrv_PCM_Shutdown(void); -int SDLDrv_PCM_BeginPlayback(char *BufferStart, int BufferSize, - int NumDivisions, void ( *CallBackFunc )( void ) ); -void SDLDrv_PCM_StopPlayback(void); -void SDLDrv_PCM_Lock(void); -void SDLDrv_PCM_Unlock(void); -#endif // driver_sdl_h__ diff --git a/source/audiolib/src/driver_winmm.cpp b/source/audiolib/src/driver_winmm.cpp deleted file mode 100644 index 87a93b948..000000000 --- a/source/audiolib/src/driver_winmm.cpp +++ /dev/null @@ -1,838 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ - -/** - * WinMM MIDI output driver - */ - -#include "driver_winmm.h" - -#include "compat.h" -#include "ll.h" -#include "midifuncs.h" -#include "multivoc.h" - -#include - -#ifdef _MSC_VER -#define inline _inline -#endif - -enum -{ - WinMMErr_Warning = -2, - WinMMErr_Error = -1, - WinMMErr_Ok = 0, - WinMMErr_Uninitialised, - WinMMErr_NotifyWindow, - WinMMErr_MIDIStreamOpen, - WinMMErr_MIDIStreamRestart, - WinMMErr_MIDICreateEvent, - WinMMErr_MIDIPlayThread, - WinMMErr_MIDICreateMutex -}; - -static int ErrorCode = WinMMErr_Ok; - -static BOOL midiInstalled; -static HMIDISTRM midiStream; -static UINT midiDeviceID = MIDI_MAPPER; -static void (*midiThreadService)(void); -static uint32_t midiThreadTimer; -static uint32_t midiLastEventTime; -static uint32_t midiThreadQueueTimer; -static uint32_t midiThreadQueueTicks; -static HANDLE midiThread; -static HANDLE midiThreadQuitEvent; -static HANDLE midiMutex; -static BOOL midiStreamRunning; -static int midiLastDivision; -#define THREAD_QUEUE_INTERVAL 10 // 1/10 sec -#define MIDI_BUFFER_SPACE (12*128u) // 128 note-on events - -typedef struct MidiBuffer { - struct MidiBuffer *next; - struct MidiBuffer *prev; - - BOOL prepared; - MIDIHDR hdr; -} MidiBuffer; - -static volatile MidiBuffer activeMidiBuffers; -static volatile MidiBuffer spareMidiBuffers; -static MidiBuffer *currentMidiBuffer; - -#define MIDI_NOTE_OFF 0x80 -#define MIDI_NOTE_ON 0x90 -#define MIDI_POLY_AFTER_TCH 0xA0 -#define MIDI_CONTROL_CHANGE 0xB0 -#define MIDI_PROGRAM_CHANGE 0xC0 -#define MIDI_AFTER_TOUCH 0xD0 -#define MIDI_PITCH_BEND 0xE0 -#define MIDI_META_EVENT 0xFF -#define MIDI_END_OF_TRACK 0x2F -#define MIDI_TEMPO_CHANGE 0x51 -#define MIDI_MONO_MODE_ON 0x7E -#define MIDI_ALL_NOTES_OFF 0x7B - - -int WinMMDrv_GetError(void) -{ - return ErrorCode; -} - -const char *WinMMDrv_ErrorString( int ErrorNumber ) -{ - const char *ErrorString; - - switch( ErrorNumber ) - { - case WinMMErr_Warning : - case WinMMErr_Error : - ErrorString = WinMMDrv_ErrorString( ErrorCode ); - break; - - case WinMMErr_Ok : - ErrorString = "WinMM ok."; - break; - - case WinMMErr_Uninitialised: - ErrorString = "WinMM uninitialised."; - break; - - case WinMMErr_MIDIStreamOpen: - ErrorString = "MIDI error: failed opening stream."; - break; - - case WinMMErr_MIDIStreamRestart: - ErrorString = "MIDI error: failed starting stream."; - break; - - case WinMMErr_MIDICreateEvent: - ErrorString = "MIDI error: failed creating play thread quit event."; - break; - - case WinMMErr_MIDIPlayThread: - ErrorString = "MIDI error: failed creating play thread."; - break; - - case WinMMErr_MIDICreateMutex: - ErrorString = "MIDI error: failed creating play mutex."; - break; - - default: - ErrorString = "Unknown WinMM error code."; - break; - } - - return ErrorString; - -} - - -// will append "err nnn (ssss)\n" to the end of the string it emits -static void midi_error(MMRESULT rv, const char * fmt, ...) -{ - va_list va; - const char * errtxt = "?"; - - switch (rv) { - case MMSYSERR_NOERROR: errtxt = "MMSYSERR_NOERROR"; break; - case MMSYSERR_BADDEVICEID: errtxt = "MMSYSERR_BADDEVICEID"; break; - case MMSYSERR_NOTENABLED: errtxt = "MMSYSERR_NOTENABLED"; break; - case MMSYSERR_ALLOCATED: errtxt = "MMSYSERR_ALLOCATED"; break; - case MMSYSERR_INVALHANDLE: errtxt = "MMSYSERR_INVALHANDLE"; break; - case MMSYSERR_NODRIVER: errtxt = "MMSYSERR_NODRIVER"; break; - case MMSYSERR_NOMEM: errtxt = "MMSYSERR_NOMEM"; break; - case MMSYSERR_NOTSUPPORTED: errtxt = "MMSYSERR_NOTSUPPORTED"; break; - case MMSYSERR_BADERRNUM: errtxt = "MMSYSERR_BADERRNUM"; break; - case MMSYSERR_INVALFLAG: errtxt = "MMSYSERR_INVALFLAG"; break; - case MMSYSERR_INVALPARAM: errtxt = "MMSYSERR_INVALPARAM"; break; - case MMSYSERR_HANDLEBUSY: errtxt = "MMSYSERR_HANDLEBUSY"; break; - case MMSYSERR_INVALIDALIAS: errtxt = "MMSYSERR_INVALIDALIAS"; break; - case MMSYSERR_BADDB: errtxt = "MMSYSERR_BADDB"; break; - case MMSYSERR_KEYNOTFOUND: errtxt = "MMSYSERR_KEYNOTFOUND"; break; - case MMSYSERR_READERROR: errtxt = "MMSYSERR_READERROR"; break; - case MMSYSERR_WRITEERROR: errtxt = "MMSYSERR_WRITEERROR"; break; - case MMSYSERR_DELETEERROR: errtxt = "MMSYSERR_DELETEERROR"; break; - case MMSYSERR_VALNOTFOUND: errtxt = "MMSYSERR_VALNOTFOUND"; break; - case MMSYSERR_NODRIVERCB: errtxt = "MMSYSERR_NODRIVERCB"; break; - default: break; - } - - va_start(va, fmt); - MV_Printf(fmt, va); - va_end(va); - - MV_Printf(" err %d (%s)\n", (int)rv, errtxt); -} - -static void midi_dispose_buffer(MidiBuffer * node, const char * caller) -{ - MMRESULT rv; - - if (node->prepared) { - rv = midiOutUnprepareHeader( (HMIDIOUT) midiStream, &node->hdr, sizeof(MIDIHDR) ); - if (rv != MMSYSERR_NOERROR) { - midi_error(rv, "WinMM %s/midi_dispose_buffer midiOutUnprepareHeader", caller); - } - node->prepared = FALSE; - } - - if (midiThread) { - // remove the node from the activeMidiBuffers list - LL_Remove( node, next, prev ); - - // when playing, we keep the buffers - LL_Add( (MidiBuffer*) &spareMidiBuffers, node, next, prev ); - //MV_Printf("WinMM %s/midi_dispose_buffer recycling buffer %p\n", caller, node); - } else { - // when not, we throw them away - free(node); - //MV_Printf("WinMM %s/midi_dispose_buffer freeing buffer %p\n", caller, node); - } -} - -static void midi_gc_buffers(void) -{ - MidiBuffer *node, *next; - - for ( node = activeMidiBuffers.next; node != &activeMidiBuffers; node = next ) { - next = node->next; - - if (node->hdr.dwFlags & MHDR_DONE) { - midi_dispose_buffer(node, "midi_gc_buffers"); - } - } -} - -static void midi_free_buffers(void) -{ - MidiBuffer *node, *next; - - //MV_Printf("waiting for active buffers to return\n"); - while (!LL_ListEmpty(&activeMidiBuffers, next, prev)) { - // wait for Windows to finish with all the buffers queued - midi_gc_buffers(); - //MV_Printf("waiting...\n"); - Sleep(10); - } - //MV_Printf("waiting over\n"); - - for ( node = spareMidiBuffers.next; node != &spareMidiBuffers; node = next ) { - next = node->next; - LL_Remove( node, next, prev ); - free(node); - //MV_Printf("WinMM midi_free_buffers freeing buffer %p\n", node); - } - - assert(currentMidiBuffer == 0); -} - -static void midi_flush_current_buffer(void) -{ - MMRESULT rv; - MIDIEVENT * evt; - BOOL needsPrepare = FALSE; - - if (!currentMidiBuffer) { - return; - } - - evt = (MIDIEVENT *) currentMidiBuffer->hdr.lpData; - - if (!midiThread) { - // immediate messages don't use a MIDIEVENT header so strip it off and - // make some adjustments - - currentMidiBuffer->hdr.dwBufferLength = currentMidiBuffer->hdr.dwBytesRecorded - 12; - currentMidiBuffer->hdr.dwBytesRecorded = 0; - currentMidiBuffer->hdr.lpData = (LPSTR) &evt->dwParms[0]; - - if (currentMidiBuffer->hdr.dwBufferLength > 0) { - needsPrepare = TRUE; - } - } else { - needsPrepare = TRUE; - } - - if (needsPrepare) { - // playing a file, or sending a sysex when not playing means - // we need to prepare the buffer - rv = midiOutPrepareHeader( (HMIDIOUT) midiStream, ¤tMidiBuffer->hdr, sizeof(MIDIHDR) ); - if (rv != MMSYSERR_NOERROR) { - midi_error(rv, "WinMM midi_flush_current_buffer midiOutPrepareHeader"); - return; - } - - currentMidiBuffer->prepared = TRUE; - } - - if (midiThread) { - // midi file playing, so send events to the stream - - LL_Add( (MidiBuffer*) &activeMidiBuffers, currentMidiBuffer, next, prev ); - - rv = midiStreamOut(midiStream, ¤tMidiBuffer->hdr, sizeof(MIDIHDR)); - if (rv != MMSYSERR_NOERROR) { - midi_error(rv, "WinMM midi_flush_current_buffer midiStreamOut"); - midi_dispose_buffer(currentMidiBuffer, "midi_flush_current_buffer"); - return; - } - - //MV_Printf("WinMM midi_flush_current_buffer queued buffer %p\n", currentMidiBuffer); - } else { - // midi file not playing, so send immediately - - if (currentMidiBuffer->hdr.dwBufferLength > 0) { - rv = midiOutLongMsg( (HMIDIOUT) midiStream, ¤tMidiBuffer->hdr, sizeof(MIDIHDR) ); - if (rv == MMSYSERR_NOERROR) { - // busy-wait for Windows to be done with it - while (!(currentMidiBuffer->hdr.dwFlags & MHDR_DONE)) ; - - //MV_Printf("WinMM midi_flush_current_buffer sent immediate long\n"); - } else { - midi_error(rv, "WinMM midi_flush_current_buffer midiOutLongMsg"); - } - } else { - rv = midiOutShortMsg( (HMIDIOUT) midiStream, evt->dwEvent ); - if (rv == MMSYSERR_NOERROR) { - //MV_Printf("WinMM midi_flush_current_buffer sent immediate short\n"); - } else { - midi_error(rv, "WinMM midi_flush_current_buffer midiOutShortMsg"); - } - } - - midi_dispose_buffer(currentMidiBuffer, "midi_flush_current_buffer"); - } - - currentMidiBuffer = 0; -} - -static void midi_setup_event(int length, unsigned char ** data) -{ - MIDIEVENT * evt; - - evt = (MIDIEVENT *) ((intptr_t) currentMidiBuffer->hdr.lpData + - currentMidiBuffer->hdr.dwBytesRecorded); - - evt->dwDeltaTime = midiThread ? (midiThreadTimer - midiLastEventTime) : 0; - evt->dwStreamID = 0; - - if (length <= 3) { - evt->dwEvent = (DWORD)MEVT_SHORTMSG << 24; - *data = (unsigned char *) &evt->dwEvent; - } else { - evt->dwEvent = ((DWORD)MEVT_LONGMSG << 24) | (length & 0x00ffffff); - *data = (unsigned char *) &evt->dwParms[0]; - } -} - -/* Gets space in the buffer presently being filled. - If insufficient space can be found in the buffer, - what is there is flushed to the stream and a new - buffer large enough is allocated. - - Returns a pointer to starting writing at in 'data'. - */ -static BOOL midi_get_buffer(int length, unsigned char ** data) -{ - uint32_t datalen; - MidiBuffer * node; - - // determine the space to alloc. - // the size of a MIDIEVENT is 3*sizeof(DWORD) = 12. - // short messages need only that amount of space. - // long messages need additional space equal to the length of - // the message, padded to 4 bytes - - if (length <= 3) { - datalen = 12; - } else { - datalen = 12 + length; - if ((datalen & 3) > 0) { - datalen += 4 - (datalen & 3); - } - } - - if (!midiThread) { - assert(currentMidiBuffer == 0); - } - - if (currentMidiBuffer && (currentMidiBuffer->hdr.dwBufferLength - - currentMidiBuffer->hdr.dwBytesRecorded) >= datalen) { - // there was enough space in the current buffer, so hand that back - midi_setup_event(length, data); - - currentMidiBuffer->hdr.dwBytesRecorded += datalen; - - return TRUE; - } - - if (currentMidiBuffer) { - // not enough space in the current buffer to accommodate the - // new data, so flush it to the stream - midi_flush_current_buffer(); - currentMidiBuffer = 0; - } - - // check if there's a spare buffer big enough to hold the message - if (midiThread) { - for ( node = spareMidiBuffers.next; node != &spareMidiBuffers; node = node->next ) { - if (node->hdr.dwBufferLength >= datalen) { - // yes! - LL_Remove( node, next, prev ); - - node->hdr.dwBytesRecorded = 0; - memset(node->hdr.lpData, 0, node->hdr.dwBufferLength); - - currentMidiBuffer = node; - - //MV_Printf("WinMM midi_get_buffer fetched buffer %p\n", node); - break; - } - } - } - - if (!currentMidiBuffer) { - // there were no spare buffers, or none were big enough, so - // allocate a new one - int size; - - if (midiThread) { - // playing a file, so allocate a buffer for more than - // one event - size = max(MIDI_BUFFER_SPACE, datalen); - } else { - // not playing a file, so allocate just a buffer for - // the event we'll be sending immediately - size = datalen; - } - - node = (MidiBuffer *) malloc( sizeof(MidiBuffer) + size ); - if (node == 0) { - return FALSE; - } - - memset(node, 0, sizeof(MidiBuffer) + datalen); - node->hdr.dwUser = (DWORD_PTR) node; - node->hdr.lpData = (LPSTR) ((intptr_t)node + sizeof(MidiBuffer)); - node->hdr.dwBufferLength = size; - node->hdr.dwBytesRecorded = 0; - - currentMidiBuffer = node; - - //MV_Printf("WinMM midi_get_buffer allocated buffer %p\n", node); - } - - midi_setup_event(length, data); - - currentMidiBuffer->hdr.dwBytesRecorded += datalen; - - return TRUE; -} - -static inline void midi_sequence_event(void) -{ - if (!midiThread) { - // a midi event being sent out of playback (streaming) mode - midi_flush_current_buffer(); - return; - } - - //MV_Printf("WinMM midi_sequence_event buffered\n"); - - // update the delta time counter - midiLastEventTime = midiThreadTimer; -} - -static void Func_NoteOff( int channel, int key, int velocity ) -{ - unsigned char * data; - - if (midi_get_buffer(3, &data)) { - data[0] = MIDI_NOTE_OFF | channel; - data[1] = key; - data[2] = velocity; - midi_sequence_event(); - } else MV_Printf("WinMM Func_NoteOff error\n"); -} - -static void Func_NoteOn( int channel, int key, int velocity ) -{ - unsigned char * data; - - if (midi_get_buffer(3, &data)) { - data[0] = MIDI_NOTE_ON | channel; - data[1] = key; - data[2] = velocity; - midi_sequence_event(); - } else MV_Printf("WinMM Func_NoteOn error\n"); -} - -static void Func_PolyAftertouch( int channel, int key, int pressure ) -{ - unsigned char * data; - - if (midi_get_buffer(3, &data)) { - data[0] = MIDI_POLY_AFTER_TCH | channel; - data[1] = key; - data[2] = pressure; - midi_sequence_event(); - } else MV_Printf("WinMM Func_PolyAftertouch error\n"); -} - -static void Func_ControlChange( int channel, int number, int value ) -{ - unsigned char * data; - - if (midi_get_buffer(3, &data)) { - data[0] = MIDI_CONTROL_CHANGE | channel; - data[1] = number; - data[2] = value; - midi_sequence_event(); - } else MV_Printf("WinMM Func_ControlChange error\n"); -} - -static void Func_ProgramChange( int channel, int program ) -{ - unsigned char * data; - - if (midi_get_buffer(2, &data)) { - data[0] = MIDI_PROGRAM_CHANGE | channel; - data[1] = program; - midi_sequence_event(); - } else MV_Printf("WinMM Func_ProgramChange error\n"); -} - -static void Func_ChannelAftertouch( int channel, int pressure ) -{ - unsigned char * data; - - if (midi_get_buffer(2, &data)) { - data[0] = MIDI_AFTER_TOUCH | channel; - data[1] = pressure; - midi_sequence_event(); - } else MV_Printf("WinMM Func_ChannelAftertouch error\n"); -} - -static void Func_PitchBend( int channel, int lsb, int msb ) -{ - unsigned char * data; - - if (midi_get_buffer(3, &data)) { - data[0] = MIDI_PITCH_BEND | channel; - data[1] = lsb; - data[2] = msb; - midi_sequence_event(); - } else MV_Printf("WinMM Func_PitchBend error\n"); -} - -static void Func_SysEx( const unsigned char * data, int length ) -{ - unsigned char * wdata; - - if (midi_get_buffer(length, &wdata)) { - memcpy(wdata, data, length); - midi_sequence_event(); - } else MV_Printf("WinMM Func_SysEx error\n"); -} - -int WinMMDrv_MIDI_Init(midifuncs * funcs) -{ - MMRESULT rv; - - if (midiInstalled) { - WinMMDrv_MIDI_Shutdown(); - } - - memset(funcs, 0, sizeof(midifuncs)); - - LL_Reset( (MidiBuffer*) &activeMidiBuffers, next, prev ); - LL_Reset( (MidiBuffer*) &spareMidiBuffers, next, prev ); - - midiMutex = CreateMutex(0, FALSE, 0); - if (!midiMutex) { - ErrorCode = WinMMErr_MIDICreateMutex; - return WinMMErr_Error; - } - - rv = midiStreamOpen(&midiStream, &midiDeviceID, 1, (DWORD_PTR) 0, (DWORD_PTR) 0, CALLBACK_NULL); - if (rv != MMSYSERR_NOERROR) { - CloseHandle(midiMutex); - midiMutex = 0; - - midi_error(rv, "WinMM MIDI_Init midiStreamOpen"); - ErrorCode = WinMMErr_MIDIStreamOpen; - return WinMMErr_Error; - } - - funcs->NoteOff = Func_NoteOff; - funcs->NoteOn = Func_NoteOn; - funcs->PolyAftertouch = Func_PolyAftertouch; - funcs->ControlChange = Func_ControlChange; - funcs->ProgramChange = Func_ProgramChange; - funcs->ChannelAftertouch = Func_ChannelAftertouch; - funcs->PitchBend = Func_PitchBend; - funcs->SysEx = Func_SysEx; - - midiInstalled = TRUE; - - return WinMMErr_Ok; -} - -void WinMMDrv_MIDI_Shutdown(void) -{ - MMRESULT rv; - - if (!midiInstalled) { - return; - } - - WinMMDrv_MIDI_HaltPlayback(); - - if (midiStream) { - rv = midiStreamClose(midiStream); - if (rv != MMSYSERR_NOERROR) { - midi_error(rv, "WinMM MIDI_Shutdown midiStreamClose"); - } - } - - if (midiMutex) { - CloseHandle(midiMutex); - } - - midiStream = 0; - midiMutex = 0; - - midiInstalled = FALSE; -} - -static DWORD midi_get_tick(void) -{ - MMRESULT rv; - MMTIME mmtime; - - mmtime.wType = TIME_TICKS; - - rv = midiStreamPosition(midiStream, &mmtime, sizeof(MMTIME)); - if (rv != MMSYSERR_NOERROR) { - midi_error(rv, "WinMM midi_get_tick midiStreamPosition"); - return 0; - } - - return mmtime.u.ticks; -} - -static DWORD WINAPI midiDataThread(LPVOID lpParameter) -{ - UNREFERENCED_PARAMETER(lpParameter); - - DWORD waitret; - DWORD sequenceTime; - DWORD sleepAmount = 100 / THREAD_QUEUE_INTERVAL; - - // MV_Printf("WinMM midiDataThread: started\n"); - - midiThreadTimer = midi_get_tick(); - midiLastEventTime = midiThreadTimer; - midiThreadQueueTimer = midiThreadTimer + midiThreadQueueTicks; - - WinMMDrv_MIDI_Lock(); - midi_gc_buffers(); - while (midiThreadTimer < midiThreadQueueTimer) { - if (midiThreadService) { - midiThreadService(); - } - midiThreadTimer++; - } - midi_flush_current_buffer(); - WinMMDrv_MIDI_Unlock(); - - do { - waitret = WaitForSingleObject(midiThreadQuitEvent, sleepAmount); - if (waitret == WAIT_OBJECT_0) { - // MV_Printf("WinMM midiDataThread: exiting\n"); - break; - } else if (waitret == WAIT_TIMEOUT) { - // queue a tick - sequenceTime = midi_get_tick(); - - sleepAmount = 100 / THREAD_QUEUE_INTERVAL; - if ((midiThreadTimer - sequenceTime) > midiThreadQueueTicks) { - // we're running ahead, so sleep for half the usual - // amount and try again - sleepAmount /= 2; - continue; - } - - midiThreadQueueTimer = sequenceTime + midiThreadQueueTicks; - - WinMMDrv_MIDI_Lock(); - midi_gc_buffers(); - while (midiThreadTimer < midiThreadQueueTimer) { - if (midiThreadService) { - midiThreadService(); - } - midiThreadTimer++; - } - midi_flush_current_buffer(); - WinMMDrv_MIDI_Unlock(); - - } else { - MV_Printf("WinMM midiDataThread: wfmo err %d\n", (int) waitret); - } - } while (1); - - return 0; -} - -int WinMMDrv_MIDI_StartPlayback(void (*service)(void)) -{ - MMRESULT rv; - - WinMMDrv_MIDI_HaltPlayback(); - - midiThreadService = service; - - midiThreadQuitEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); - if (!midiThreadQuitEvent) { - ErrorCode = WinMMErr_MIDICreateEvent; - return WinMMErr_Error; - } - - if (!midiStreamRunning) { - rv = midiStreamRestart(midiStream); - if (rv != MMSYSERR_NOERROR) { - midi_error(rv, "MIDI_StartPlayback midiStreamRestart"); - WinMMDrv_MIDI_HaltPlayback(); - ErrorCode = WinMMErr_MIDIStreamRestart; - return WinMMErr_Error; - } - - midiStreamRunning = TRUE; - } - - midiThread = CreateThread(nullptr, 0, midiDataThread, 0, 0, 0); - if (!midiThread) { - WinMMDrv_MIDI_HaltPlayback(); - ErrorCode = WinMMErr_MIDIPlayThread; - return WinMMErr_Error; - } - - midiLastDivision = 0; - - return WinMMErr_Ok; -} - -void WinMMDrv_MIDI_HaltPlayback(void) -{ - MMRESULT rv; - - if (midiThread) { - SetEvent(midiThreadQuitEvent); - - WaitForSingleObject(midiThread, INFINITE); - // MV_Printf("WinMM MIDI_HaltPlayback synched\n"); - - CloseHandle(midiThread); - } - - if (midiThreadQuitEvent) { - CloseHandle(midiThreadQuitEvent); - } - - if (midiStreamRunning) { - // MV_Printf("stopping stream\n"); - rv = midiStreamStop(midiStream); - if (rv != MMSYSERR_NOERROR) { - midi_error(rv, "WinMM MIDI_HaltPlayback midiStreamStop"); - } - // MV_Printf("stream stopped\n"); - - midiStreamRunning = FALSE; - } - - midi_free_buffers(); - - midiThread = 0; - midiThreadQuitEvent = 0; -} - -void WinMMDrv_MIDI_SetTempo(int tempo, int division) -{ - MMRESULT rv; - MIDIPROPTEMPO propTempo; - MIDIPROPTIMEDIV propTimediv; - BOOL running = midiStreamRunning; - - //MV_Printf("MIDI_SetTempo %d/%d\n", tempo, division); - - propTempo.cbStruct = sizeof(MIDIPROPTEMPO); - propTempo.dwTempo = 60000000l / tempo; - propTimediv.cbStruct = sizeof(MIDIPROPTIMEDIV); - propTimediv.dwTimeDiv = division; - - if (midiLastDivision != division) { - // changing the division means halting the stream - WinMMDrv_MIDI_HaltPlayback(); - - rv = midiStreamProperty(midiStream, (LPBYTE) &propTimediv, MIDIPROP_SET | MIDIPROP_TIMEDIV); - if (rv != MMSYSERR_NOERROR) { - midi_error(rv, "WinMM MIDI_SetTempo midiStreamProperty timediv"); - } - } - - rv = midiStreamProperty(midiStream, (LPBYTE) &propTempo, MIDIPROP_SET | MIDIPROP_TEMPO); - if (rv != MMSYSERR_NOERROR) { - midi_error(rv, "WinMM MIDI_SetTempo midiStreamProperty tempo"); - } - - if (midiLastDivision != division) { - if (running && WinMMDrv_MIDI_StartPlayback(midiThreadService) != WinMMErr_Ok) { - return; - } - - midiLastDivision = division; - } - - midiThreadQueueTicks = (int) ceil( ( ( (double) tempo * (double) division ) / 60.0 ) / - (double) THREAD_QUEUE_INTERVAL ); - if (midiThreadQueueTicks <= 0) { - midiThreadQueueTicks = 1; - } -} - -void WinMMDrv_MIDI_Lock(void) -{ - DWORD err; - - err = WaitForSingleObject(midiMutex, INFINITE); - if (err != WAIT_OBJECT_0) { - MV_Printf("WinMM midiMutex lock: wfso %d\n", (int) err); - } -} - -void WinMMDrv_MIDI_Unlock(void) -{ - ReleaseMutex(midiMutex); -} - -// vim:ts=4:sw=4:expandtab: diff --git a/source/audiolib/src/driver_winmm.h b/source/audiolib/src/driver_winmm.h deleted file mode 100644 index 51c71d2b6..000000000 --- a/source/audiolib/src/driver_winmm.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ - -#include "midifuncs.h" - -int WinMMDrv_GetError(void); -const char *WinMMDrv_ErrorString( int ErrorNumber ); - -int WinMMDrv_MIDI_Init(midifuncs *); -void WinMMDrv_MIDI_Shutdown(void); -int WinMMDrv_MIDI_StartPlayback(void (*service)(void)); -void WinMMDrv_MIDI_HaltPlayback(void); -void WinMMDrv_MIDI_SetTempo(int tempo, int division); -void WinMMDrv_MIDI_Lock(void); -void WinMMDrv_MIDI_Unlock(void); - diff --git a/source/audiolib/src/drivers.cpp b/source/audiolib/src/drivers.cpp deleted file mode 100644 index 57d90f12b..000000000 --- a/source/audiolib/src/drivers.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ - -/** - * Abstraction layer for hiding the various supported sound devices - * behind a common and opaque interface called on by MultiVoc. - */ - -#include "drivers.h" - -#include "driver_adlib.h" - -#ifdef RENDERTYPESDL -# include "driver_sdl.h" -#endif - -#ifdef _WIN32 -# include "driver_directsound.h" -# include "driver_winmm.h" -#endif - -int ASS_PCMSoundDriver = ASS_AutoDetect; -int ASS_MIDISoundDriver = ASS_AutoDetect; -int ASS_EMIDICard = -1; - -#define UNSUPPORTED_PCM nullptr,nullptr,nullptr,nullptr,nullptr,nullptr -#define UNSUPPORTED_MIDI nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr -#define UNSUPPORTED_COMPLETELY nullptr, nullptr, UNSUPPORTED_PCM, UNSUPPORTED_MIDI - -static struct { - const char * DriverName; - - int (*GetError)(void); - const char *(*ErrorString)(int); - - int (*PCM_Init)(int *, int *, void *); - void (*PCM_Shutdown)(void); - int (*PCM_BeginPlayback)(char *, int, int, void (*)(void)); - void (*PCM_StopPlayback)(void); - void (*PCM_Lock)(void); - void (*PCM_Unlock)(void); - - int (*MIDI_Init)(midifuncs *); - void (*MIDI_Shutdown)(void); - int (*MIDI_StartPlayback)(void (*service)(void)); - void (*MIDI_HaltPlayback)(void); - void (*MIDI_SetTempo)(int tempo, int division); - void (*MIDI_Lock)(void); - void (*MIDI_Unlock)(void); -} SoundDrivers[ASS_NumSoundCards] = { - - - // Simple DirectMedia Layer - { - "SDL", - #ifdef RENDERTYPESDL - SDLDrv_GetError, - SDLDrv_ErrorString, - SDLDrv_PCM_Init, - SDLDrv_PCM_Shutdown, - SDLDrv_PCM_BeginPlayback, - SDLDrv_PCM_StopPlayback, - SDLDrv_PCM_Lock, - SDLDrv_PCM_Unlock, - UNSUPPORTED_MIDI, - #else - UNSUPPORTED_COMPLETELY - #endif - }, - - // Windows DirectSound - { - "DirectSound", - #ifdef RENDERTYPEWIN - DirectSoundDrv_GetError, - DirectSoundDrv_ErrorString, - DirectSoundDrv_PCM_Init, - DirectSoundDrv_PCM_Shutdown, - DirectSoundDrv_PCM_BeginPlayback, - DirectSoundDrv_PCM_StopPlayback, - DirectSoundDrv_PCM_Lock, - DirectSoundDrv_PCM_Unlock, - UNSUPPORTED_MIDI, - #else - UNSUPPORTED_COMPLETELY - #endif - }, - - // OPL3 emulation - { - "Nuked OPL3 AdLib emulator", - AdLibDrv_GetError, - AdLibDrv_ErrorString, - - UNSUPPORTED_PCM, - - AdLibDrv_MIDI_Init, - AdLibDrv_MIDI_Shutdown, - AdLibDrv_MIDI_StartPlayback, - AdLibDrv_MIDI_HaltPlayback, - AdLibDrv_MIDI_SetTempo, - nullptr, - nullptr, - }, - - // Windows MultiMedia system - { - "WinMM", - #ifdef _WIN32 - WinMMDrv_GetError, - WinMMDrv_ErrorString, - - UNSUPPORTED_PCM, - - WinMMDrv_MIDI_Init, - WinMMDrv_MIDI_Shutdown, - WinMMDrv_MIDI_StartPlayback, - WinMMDrv_MIDI_HaltPlayback, - WinMMDrv_MIDI_SetTempo, - WinMMDrv_MIDI_Lock, - WinMMDrv_MIDI_Unlock, - #else - UNSUPPORTED_COMPLETELY - #endif - }, -}; - - -int SoundDriver_IsPCMSupported(int driver) { return (SoundDrivers[driver].PCM_Init != 0); } -int SoundDriver_IsMIDISupported(int driver) { return (SoundDrivers[driver].MIDI_Init != 0); } -const char *SoundDriver_GetName(int driver) { return SoundDrivers[driver].DriverName; } - -int SoundDriver_PCM_GetError(void) -{ - if (!SoundDriver_IsPCMSupported(ASS_PCMSoundDriver)) - return -1; - - return SoundDrivers[ASS_PCMSoundDriver].GetError(); -} - -const char * SoundDriver_PCM_ErrorString( int ErrorNumber ) -{ - if (ASS_PCMSoundDriver < 0 || ASS_PCMSoundDriver >= ASS_NumSoundCards) - return "No sound driver selected."; - - if (!SoundDriver_IsPCMSupported(ASS_PCMSoundDriver)) - return "Unsupported sound driver selected."; - - return SoundDrivers[ASS_PCMSoundDriver].ErrorString(ErrorNumber); -} - -int SoundDriver_MIDI_GetError(void) -{ - if (!SoundDriver_IsMIDISupported(ASS_MIDISoundDriver)) - return -1; - - return SoundDrivers[ASS_MIDISoundDriver].GetError(); -} - -const char * SoundDriver_MIDI_ErrorString( int ErrorNumber ) -{ - if (ASS_MIDISoundDriver < 0 || ASS_MIDISoundDriver >= ASS_NumSoundCards) - return "No sound driver selected."; - - if (!SoundDriver_IsMIDISupported(ASS_MIDISoundDriver)) - return "Unsupported sound driver selected."; - - return SoundDrivers[ASS_MIDISoundDriver].ErrorString(ErrorNumber); -} - -int SoundDriver_PCM_Init(int *mixrate, int *numchannels, void *initdata) -{ - return SoundDrivers[ASS_PCMSoundDriver].PCM_Init(mixrate, numchannels, initdata); -} - -int SoundDriver_PCM_BeginPlayback(char *BufferStart, int BufferSize, int NumDivisions, void (*CallBackFunc)(void)) -{ - return SoundDrivers[ASS_PCMSoundDriver].PCM_BeginPlayback(BufferStart, BufferSize, NumDivisions, CallBackFunc); -} - -void SoundDriver_PCM_Shutdown(void) { SoundDrivers[ASS_PCMSoundDriver].PCM_Shutdown(); } -void SoundDriver_PCM_StopPlayback(void) { SoundDrivers[ASS_PCMSoundDriver].PCM_StopPlayback(); } -void SoundDriver_PCM_Lock(void) { SoundDrivers[ASS_PCMSoundDriver].PCM_Lock(); } -void SoundDriver_PCM_Unlock(void) { SoundDrivers[ASS_PCMSoundDriver].PCM_Unlock(); } -int SoundDriver_MIDI_Init(midifuncs *funcs) { return SoundDrivers[ASS_MIDISoundDriver].MIDI_Init(funcs); } -int SoundDriver_MIDI_StartPlayback(void (*service)(void)) { return SoundDrivers[ASS_MIDISoundDriver].MIDI_StartPlayback(service); } -void SoundDriver_MIDI_Shutdown(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_Shutdown(); } -void SoundDriver_MIDI_HaltPlayback(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_HaltPlayback(); } -void SoundDriver_MIDI_SetTempo(int tempo, int division) { SoundDrivers[ASS_MIDISoundDriver].MIDI_SetTempo(tempo, division); } -void SoundDriver_MIDI_Lock(void) { if (SoundDrivers[ASS_MIDISoundDriver].MIDI_Lock) SoundDrivers[ASS_MIDISoundDriver].MIDI_Lock(); } -void SoundDriver_MIDI_Unlock(void) { if (SoundDrivers[ASS_MIDISoundDriver].MIDI_Unlock) SoundDrivers[ASS_MIDISoundDriver].MIDI_Unlock(); } - -// vim:ts=4:sw=4:expandtab: diff --git a/source/audiolib/src/formats.cpp b/source/audiolib/src/formats.cpp deleted file mode 100644 index 5fcfedf56..000000000 --- a/source/audiolib/src/formats.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - Copyright (C) 2015 EDuke32 developers - Copyright (C) 2015 Voidpoint, LLC - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -/** - * Raw, WAV, and VOC source support for MultiVoc - */ - -#include "_multivc.h" -#include "compat.h" -#include "multivoc.h" -#include "pitch.h" -#include "pragmas.h" - -static playbackstatus MV_GetNextWAVBlock(VoiceNode *voice) -{ - if (voice->BlockLength == 0) - { - if (voice->LoopStart == nullptr) - return NoMoreData; - - voice->BlockLength = voice->LoopSize; - voice->NextBlock = voice->LoopStart; - voice->length = 0; - voice->position = 0; - } - - voice->sound = voice->NextBlock; - voice->position -= voice->length; - voice->length = min(voice->BlockLength, 0x8000u); - voice->NextBlock += voice->length * ((voice->channels * voice->bits) >> 3); - voice->BlockLength -= voice->length; - voice->length <<= 16; - - return KeepPlaying; -} - -static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice) -{ - size_t blocklength = 0; - uint32_t samplespeed = 0; // XXX: compiler-happy on synthesis - uint32_t tc = 0; - unsigned BitsPerSample; - unsigned Channels; - unsigned Format; - - if (voice->BlockLength > 0) - { - voice->position -= voice->length; - voice->sound += (voice->length >> 16) * ((voice->channels * voice->bits) >> 3); - voice->length = min(voice->BlockLength, 0x8000u); - voice->BlockLength -= voice->length; - voice->length <<= 16; - return KeepPlaying; - } - - auto ptr = (uint8_t const *)voice->NextBlock; - - voice->Paused = FALSE; - - int voicemode = 0; - int blocktype = 0; - int lastblocktype = 0; - int packtype = 0; - - int done = FALSE; - - do - { - // Stop playing if we get a null pointer - if (ptr == nullptr) - { - done = 2; - break; - } - - // terminator is not mandatory according to - // http://wiki.multimedia.cx/index.php?title=Creative_Voice - - if (ptr - (uint8_t *)voice->rawdataptr >= voice->ptrlength) - blocktype = 0; // fake a terminator - else - blocktype = *ptr; - - if (blocktype != 0) - blocklength = ptr[1]|(ptr[2]<<8)|(ptr[3]<<16); - else - blocklength = 0; - // would need one byte pad at end of alloc'd region: -// blocklength = B_LITTLE32(*(uint32_t *)(ptr + 1)) & 0x00ffffff; - - ptr += 4; - - switch (blocktype) - { - case 0 : -end_of_data: - // End of data - if ((voice->LoopStart == nullptr) || - ((intptr_t) voice->LoopStart >= ((intptr_t) ptr - 4))) - { - done = 2; - } - else - { - voice->NextBlock = voice->LoopStart; - voice->BlockLength = 0; - voice->position = 0; - return MV_GetNextVOCBlock(voice); - } - break; - - case 1 : - // Sound data block - voice->bits = 8; - voice->channels = voicemode + 1; - if (lastblocktype != 8) - { - tc = (uint32_t)*ptr << 8; - packtype = *(ptr + 1); - } - - ptr += 2; - blocklength -= 2; - - samplespeed = 256000000L / (voice->channels * (65536 - tc)); - - // Skip packed or stereo data - if ((packtype != 0) || (voicemode != 0 && voicemode != 1)) - ptr += blocklength; - else - done = TRUE; - - if (ptr - (uint8_t *)voice->rawdataptr >= voice->ptrlength) - goto end_of_data; - - voicemode = 0; - break; - - case 2 : - // Sound continuation block - samplespeed = voice->SamplingRate; - done = TRUE; - break; - - case 3 : - // Silence - case 4 : - // Marker - case 5 : - // ASCII string - // All not implemented. - ptr += blocklength; - break; - - case 6 : - // Repeat begin - if (voice->LoopEnd == nullptr) - { - voice->LoopCount = B_LITTLE16(*(uint16_t const *)ptr); - voice->LoopStart = (char *)((intptr_t) ptr + blocklength); - } - ptr += blocklength; - break; - - case 7 : - // Repeat end - ptr += blocklength; - if (lastblocktype == 6) - voice->LoopCount = 0; - else - { - if ((voice->LoopCount > 0) && (voice->LoopStart != nullptr)) - { - ptr = (uint8_t const *) voice->LoopStart; - - if (voice->LoopCount < 0xffff) - { - if (--voice->LoopCount == 0) - voice->LoopStart = nullptr; - } - } - } - break; - - case 8 : - // Extended block - voice->bits = 8; - voice->channels = 1; - tc = B_LITTLE16(*(uint16_t const *)ptr); - packtype = *(ptr + 2); - voicemode = *(ptr + 3); - ptr += blocklength; - break; - - case 9 : - // New sound data block - samplespeed = B_LITTLE32(*(uint32_t const *)ptr); - BitsPerSample = (unsigned)*(ptr + 4); - Channels = (unsigned)*(ptr + 5); - Format = (unsigned)B_LITTLE16(*(uint16_t const *)(ptr + 6)); - - if ((BitsPerSample == 8) && (Channels == 1 || Channels == 2) && (Format == VOC_8BIT)) - { - ptr += 12; - blocklength -= 12; - voice->bits = 8; - voice->channels = Channels; - done = TRUE; - } - else if ((BitsPerSample == 16) && (Channels == 1 || Channels == 2) && (Format == VOC_16BIT)) - { - ptr += 12; - blocklength -= 12; - voice->bits = 16; - voice->channels = Channels; - done = TRUE; - } - else - { - ptr += blocklength; - } - - // CAUTION: - // SNAKRM.VOC is corrupt! blocklength gets us beyond the - // end of the file. - if (ptr - (uint8_t *)voice->rawdataptr >= voice->ptrlength) - goto end_of_data; - - break; - - default : - // Unknown data. Probably not a VOC file. - done = 2; - break; - } - - lastblocktype = blocktype; - } - while (!done); - - if (done != 2) - { - voice->NextBlock = (char const *)ptr + blocklength; - voice->sound = (char const *)ptr; - - // CODEDUP multivoc.c MV_SetVoicePitch - voice->SamplingRate = samplespeed; - voice->RateScale = divideu32(voice->SamplingRate * voice->PitchScale, MV_MixRate); - - // Multiply by MV_MIXBUFFERSIZE - 1 - voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - - voice->RateScale; - - if (voice->LoopEnd != nullptr) - { - if (blocklength > (uintptr_t)voice->LoopEnd) - blocklength = (uintptr_t)voice->LoopEnd; - else - voice->LoopEnd = (char *)blocklength; - - voice->LoopStart = voice->sound + (uintptr_t)voice->LoopStart; - voice->LoopEnd = voice->sound + (uintptr_t)voice->LoopEnd; - voice->LoopSize = voice->LoopEnd - voice->LoopStart; - } - - if (voice->bits == 16) - blocklength /= 2; - - if (voice->channels == 2) - blocklength /= 2; - - voice->position = 0; - voice->length = min(blocklength, 0x8000u); - voice->BlockLength = blocklength - voice->length; - voice->length <<= 16; - - MV_SetVoiceMixMode(voice); - - return KeepPlaying; - } - - return NoMoreData; -} - -static playbackstatus MV_GetNextRAWBlock(VoiceNode *voice) -{ - if (voice->BlockLength == 0) - { - if (voice->LoopStart == NULL) - return NoMoreData; - - voice->BlockLength = voice->LoopSize; - voice->NextBlock = voice->LoopStart; - voice->length = 0; - voice->position = 0; - } - - voice->sound = voice->NextBlock; - voice->position -= voice->length; - voice->length = min(voice->BlockLength, 0x8000u); - voice->NextBlock += voice->length * (voice->channels * voice->bits / 8); - voice->BlockLength -= voice->length; - voice->length <<= 16; - - return KeepPlaying; -} - -int MV_PlayWAV3D(char *ptr, uint32_t length, int loophow, int pitchoffset, int angle, int distance, - int priority, float volume, intptr_t callbackval) -{ - if (!MV_Installed) - return MV_Error; - - if (distance < 0) - { - distance = -distance; - angle += MV_NUMPANPOSITIONS / 2; - } - - int const vol = MIX_VOLUME(distance); - - // Ensure angle is within 0 - 127 - angle &= MV_MAXPANPOSITION; - - return MV_PlayWAV(ptr, length, loophow, -1, pitchoffset, max(0, 255 - distance), - MV_PanTable[ angle ][ vol ].left, MV_PanTable[ angle ][ vol ].right, priority, volume, callbackval); -} - -int MV_PlayWAV(char *ptr, uint32_t length, int loopstart, int loopend, int pitchoffset, int vol, - int left, int right, int priority, float volume, intptr_t callbackval) -{ - if (!MV_Installed) - return MV_Error; - - riff_header riff; - memcpy(&riff, ptr, sizeof(riff_header)); - riff.file_size = B_LITTLE32(riff.file_size); - riff.format_size = B_LITTLE32(riff.format_size); - - if ((memcmp(riff.RIFF, "RIFF", 4) != 0) || (memcmp(riff.WAVE, "WAVE", 4) != 0) || (memcmp(riff.fmt, "fmt ", 4) != 0)) - return MV_SetErrorCode(MV_InvalidFile); - - format_header format; - memcpy(&format, ptr + sizeof(riff_header), sizeof(format_header)); - format.wFormatTag = B_LITTLE16(format.wFormatTag); - format.nChannels = B_LITTLE16(format.nChannels); - format.nSamplesPerSec = B_LITTLE32(format.nSamplesPerSec); - format.nAvgBytesPerSec = B_LITTLE32(format.nAvgBytesPerSec); - format.nBlockAlign = B_LITTLE16(format.nBlockAlign); - format.nBitsPerSample = B_LITTLE16(format.nBitsPerSample); - - data_header data; - memcpy(&data, ptr + sizeof(riff_header) + riff.format_size, sizeof(data_header)); - data.size = B_LITTLE32(data.size); - - // Check if it's PCM data. - if (format.wFormatTag != 1 || (format.nChannels != 1 && format.nChannels != 2) || - ((format.nBitsPerSample != 8) && (format.nBitsPerSample != 16)) || memcmp(data.DATA, "data", 4) != 0) - return MV_SetErrorCode(MV_InvalidFile); - - // Request a voice from the voice pool - - VoiceNode *voice = MV_AllocVoice(priority); - - if (voice == nullptr) - return MV_SetErrorCode(MV_NoVoices); - - voice->wavetype = FMT_WAV; - voice->bits = format.nBitsPerSample; - voice->channels = format.nChannels; - voice->GetSound = MV_GetNextWAVBlock; - - int blocklen = data.size; - - if (voice->bits == 16) - { - data.size &= ~1; - blocklen /= 2; - } - - if (voice->channels == 2) - { - data.size &= ~1; - blocklen /= 2; - } - - voice->rawdataptr = (uint8_t *)ptr; - voice->ptrlength = length; - voice->Paused = FALSE; - voice->LoopCount = 0; - voice->position = 0; - voice->length = 0; - voice->BlockLength = blocklen; - voice->NextBlock = (char *)((intptr_t) ptr + sizeof(riff_header) + riff.format_size + sizeof(data_header)); - voice->next = nullptr; - voice->prev = nullptr; - voice->priority = priority; - voice->callbackval = callbackval; - voice->LoopStart = loopstart >= 0 ? voice->NextBlock : nullptr; - voice->LoopEnd = nullptr; - voice->LoopSize = loopend > 0 ? loopend - loopstart + 1 : blocklen; - - MV_SetVoicePitch(voice, format.nSamplesPerSec, pitchoffset); - MV_SetVoiceVolume(voice, vol, left, right, volume); - MV_PlayVoice(voice); - - return voice->handle; -} - -int MV_PlayVOC3D(char *ptr, uint32_t length, int loophow, int pitchoffset, int angle, - int distance, int priority, float volume, intptr_t callbackval) -{ - if (!MV_Installed) - return MV_Error; - - if (distance < 0) - { - distance = -distance; - angle += MV_NUMPANPOSITIONS / 2; - } - - int const vol = MIX_VOLUME(distance); - - // Ensure angle is within 0 - 127 - angle &= MV_MAXPANPOSITION; - - return MV_PlayVOC(ptr, length, loophow, -1, pitchoffset, max(0, 255 - distance), - MV_PanTable[ angle ][ vol ].left, MV_PanTable[ angle ][ vol ].right, priority, volume, callbackval); -} - -int MV_PlayVOC(char *ptr, uint32_t length, int loopstart, int loopend, int pitchoffset, int vol, - int left, int right, int priority, float volume, intptr_t callbackval) -{ - if (!MV_Installed) - return MV_Error; - - // Make sure it looks like a valid VOC file. - if (memcmp(ptr, "Creative Voice File", 19) != 0) - return MV_SetErrorCode(MV_InvalidFile); - - // Request a voice from the voice pool - VoiceNode *voice = MV_AllocVoice(priority); - - if (voice == nullptr) - return MV_SetErrorCode(MV_NoVoices); - - voice->rawdataptr = (uint8_t *)ptr; - voice->ptrlength = length; - voice->Paused = FALSE; - voice->wavetype = FMT_VOC; - voice->bits = 8; - voice->channels = 1; - voice->GetSound = MV_GetNextVOCBlock; - voice->NextBlock = ptr + B_LITTLE16(*(uint16_t *)(ptr + 0x14)); - voice->LoopCount = 0; - voice->BlockLength = 0; - voice->PitchScale = PITCH_GetScale(pitchoffset); - voice->length = 0; - voice->next = nullptr; - voice->prev = nullptr; - voice->priority = priority; - voice->callbackval = callbackval; - voice->LoopStart = loopstart >= 0 ? voice->NextBlock : nullptr; - voice->LoopEnd = nullptr; - voice->LoopSize = loopend - loopstart + 1; - - voice->volume = volume; - - MV_SetVoiceVolume(voice, vol, left, right, volume); - MV_PlayVoice(voice); - - return voice->handle; -} - -int MV_PlayRAW(char *ptr, uint32_t length, int rate, char *loopstart, char *loopend, int pitchoffset, int vol, - int left, int right, int priority, float volume, intptr_t callbackval) -{ - if (!MV_Installed) - return MV_Error; - - // Request a voice from the voice pool - VoiceNode *voice = MV_AllocVoice(priority); - - if (voice == NULL) - { - MV_SetErrorCode(MV_NoVoices); - return MV_Error; - } - - voice->rawdataptr = (uint8_t *)ptr; - voice->ptrlength = length; - voice->Paused = FALSE; - voice->wavetype = FMT_RAW; - voice->bits = 8; - voice->channels = 1; - voice->GetSound = MV_GetNextRAWBlock; - voice->NextBlock = ptr; - voice->LoopCount = 0; - voice->position = 0; - voice->BlockLength = length; - voice->PitchScale = PITCH_GetScale(pitchoffset); - voice->length = 0; - voice->next = NULL; - voice->prev = NULL; - voice->priority = priority; - voice->callbackval = callbackval; - voice->LoopStart = loopstart; - voice->LoopEnd = loopend; - voice->LoopSize = loopend - loopstart + 1; - - voice->volume = volume; - - MV_SetVoicePitch(voice, rate, pitchoffset); - MV_SetVoiceVolume(voice, vol, left, right, volume); - MV_PlayVoice(voice); - - return voice->handle; -} diff --git a/source/audiolib/src/fx_man.cpp b/source/audiolib/src/fx_man.cpp deleted file mode 100644 index 28154ee31..000000000 --- a/source/audiolib/src/fx_man.cpp +++ /dev/null @@ -1,225 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2016 EDuke32 developers and contributors - -This file is part of EDuke32. - -EDuke32 is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#include "fx_man.h" - -#include "compat.h" -#include "drivers.h" -#include "driver_adlib.h" -#include "midi.h" -#include "multivoc.h" -#include "osd.h" - -int FX_ErrorCode = FX_Ok; -int FX_Installed; - -const char *FX_ErrorString(int const ErrorNumber) -{ - const char *ErrorString; - - switch (ErrorNumber) - { - case FX_Warning: - case FX_Error: ErrorString = FX_ErrorString(FX_ErrorCode); break; - case FX_Ok: ErrorString = "Fx ok."; break; - case FX_MultiVocError: ErrorString = MV_ErrorString(MV_Error); break; - default: ErrorString = "Unknown Fx error code."; break; - } - - return ErrorString; -} - - -int FX_Init(int numvoices, int numchannels, int mixrate, void *initdata) -{ - if (FX_Installed) - FX_Shutdown(); - - int SoundCard = ASS_AutoDetect; - - if (SoundCard == ASS_AutoDetect) - { -#if defined RENDERTYPESDL - SoundCard = ASS_SDL; -#elif defined RENDERTYPEWIN - SoundCard = ASS_DirectSound; -#endif - } - - if (SoundCard < 0 || SoundCard >= ASS_NumSoundCards) - { - FX_SetErrorCode(FX_InvalidCard); - return FX_Error; - } - - if (SoundDriver_IsPCMSupported(SoundCard) == 0) - { - // unsupported cards fall back to no sound - FX_SetErrorCode(FX_InvalidCard); - return FX_Error; - } - - int status = FX_Ok; - - if (MV_Init(SoundCard, mixrate, numvoices, numchannels, initdata) != MV_Ok) - { - FX_SetErrorCode(FX_MultiVocError); - status = FX_Error; - } - - if (status == FX_Ok) - FX_Installed = TRUE; - - return status; -} - -int FX_Shutdown(void) -{ - if (!FX_Installed) - return FX_Ok; - - int status = MV_Shutdown(); - - if (status != MV_Ok) - { - FX_SetErrorCode(FX_MultiVocError); - status = FX_Error; - } - - FX_Installed = FALSE; - - return status; -} - -int FX_GetDevice() -{ - return ASS_PCMSoundDriver; -} - -static wavefmt_t FX_DetectFormat(char const * const ptr, uint32_t length) -{ - if (length < 12) - return FMT_UNKNOWN; - - wavefmt_t fmt = FMT_UNKNOWN; - - switch (B_LITTLE32(*(int const *)ptr)) - { - case 'C' + ('r' << 8) + ('e' << 16) + ('a' << 24): // Crea - fmt = FMT_VOC; - break; - case 'O' + ('g' << 8) + ('g' << 16) + ('S' << 24): // OggS - fmt = FMT_VORBIS; - break; - case 'R' + ('I' << 8) + ('F' << 16) + ('F' << 24): // RIFF - switch (B_LITTLE32(*(int const *)(ptr + 8))) - { - case 'W' + ('A' << 8) + ('V' << 16) + ('E' << 24): // WAVE - fmt = FMT_WAV; - break; - } - break; - default: - break; - } - - return fmt; -} - -int FX_Play(char *ptr, uint32_t ptrlength, int loopstart, int loopend, int pitchoffset, - int vol, int left, int right, int priority, float volume, intptr_t callbackval) -{ - static constexpr decltype(MV_PlayVOC) *func[] = - { nullptr, nullptr, MV_PlayVOC, MV_PlayWAV, nullptr, nullptr, MV_PlayVorbis, nullptr, nullptr, nullptr }; - - //EDUKE32_STATIC_ASSERT(FMT_MAX == ARRAY_SIZE(func)); - - wavefmt_t const fmt = FX_DetectFormat(ptr, ptrlength); - - int handle = - (func[fmt]) ? func[fmt](ptr, ptrlength, loopstart, loopend, pitchoffset, vol, left, right, priority, volume, callbackval) : -1; - - if (handle <= MV_Ok) - { - FX_SetErrorCode(FX_MultiVocError); - handle = FX_Warning; - } - - return handle; -} - -int FX_Play3D(char *ptr, uint32_t ptrlength, int loophow, int pitchoffset, int angle, int distance, - int priority, float volume, intptr_t callbackval) -{ - static constexpr decltype(MV_PlayVOC3D) *func[] = - { nullptr, nullptr, MV_PlayVOC3D, MV_PlayWAV3D, nullptr, nullptr, MV_PlayVorbis3D, nullptr, nullptr, nullptr }; - - //EDUKE32_STATIC_ASSERT(FMT_MAX == ARRAY_SIZE(func)); - - wavefmt_t const fmt = FX_DetectFormat(ptr, ptrlength); - - int handle = - (func[fmt]) ? func[fmt](ptr, ptrlength, loophow, pitchoffset, angle, distance, priority, volume, callbackval) : -1; - - if (handle <= MV_Ok) - { - FX_SetErrorCode(FX_MultiVocError); - handle = FX_Warning; - } - - return handle; -} - -int FX_PlayRaw(char *ptr, uint32_t ptrlength, int rate, int pitchoffset, int vol, - int left, int right, int priority, float volume, intptr_t callbackval) -{ - int handle = MV_PlayRAW(ptr, ptrlength, rate, NULL, NULL, pitchoffset, vol, left, right, priority, volume, callbackval); - - if (handle <= MV_Ok) - { - FX_SetErrorCode(FX_MultiVocError); - handle = FX_Warning; - } - - return handle; -} - -int FX_PlayLoopedRaw(char *ptr, uint32_t ptrlength, char *loopstart, char *loopend, int rate, - int pitchoffset, int vol, int left, int right, int priority, float volume, intptr_t callbackval) -{ - int handle = MV_PlayRAW(ptr, ptrlength, rate, loopstart, loopend, pitchoffset, vol, left, right, priority, volume, callbackval); - - if (handle <= MV_Ok) - { - FX_SetErrorCode(FX_MultiVocError); - handle = FX_Warning; - } - - return handle; -} - -int FX_SetPrintf(void (*function)(const char *, ...)) -{ - MV_SetPrintf(function); - - return FX_Ok; -} diff --git a/source/audiolib/src/gmtimbre.cpp b/source/audiolib/src/gmtimbre.cpp deleted file mode 100644 index a363e75e7..000000000 --- a/source/audiolib/src/gmtimbre.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include -#include "al_midi.h" - -AdLibTimbre ADLIB_TimbreBank[256] = - { - { { 33, 33 }, { 143, 6 }, { 242, 242 }, { 69, 118 }, { 0, 0 }, 8, 0, 0 }, - { { 49, 33 }, { 75, 0 }, { 242, 242 }, { 84, 86 }, { 0, 0 }, 8, 0, 0 }, - { { 49, 33 }, { 73, 0 }, { 242, 242 }, { 85, 118 }, { 0, 0 }, 8, 0, 0 }, - { { 177, 97 }, { 14, 0 }, { 242, 243 }, { 59, 11 }, { 0, 0 }, 6, 0, 0 }, - { { 1, 33 }, { 87, 0 }, { 241, 241 }, { 56, 40 }, { 0, 0 }, 0, 0, 0 }, - { { 1, 33 }, { 147, 0 }, { 241, 241 }, { 56, 40 }, { 0, 0 }, 0, 0, 0 }, - { { 33, 54 }, { 128, 14 }, { 162, 241 }, { 1, 213 }, { 0, 0 }, 8, 0, 0 }, - { { 1, 1 }, { 146, 0 }, { 194, 194 }, { 168, 88 }, { 0, 0 }, 10, 0, 0 }, - { { 12, 129 }, { 92, 0 }, { 246, 243 }, { 84, 181 }, { 0, 0 }, 0, 0, 0 }, - { { 7, 17 }, { 151, 128 }, { 246, 245 }, { 50, 17 }, { 0, 0 }, 2, 0, 0 }, - { { 23, 1 }, { 33, 0 }, { 86, 246 }, { 4, 4 }, { 0, 0 }, 2, 0, 0 }, - { { 24, 129 }, { 98, 0 }, { 243, 242 }, { 230, 246 }, { 0, 0 }, 0, 0, 0 }, - { { 24, 33 }, { 35, 0 }, { 247, 229 }, { 85, 216 }, { 0, 0 }, 0, 0, 0 }, - { { 21, 1 }, { 145, 0 }, { 246, 246 }, { 166, 230 }, { 0, 0 }, 4, 0, 0 }, - { { 69, 129 }, { 89, 128 }, { 211, 163 }, { 130, 227 }, { 0, 0 }, 12, 0, 0 }, - { { 3, 129 }, { 73, 128 }, { 116, 179 }, { 85, 5 }, { 1, 0 }, 4, 0, 0 }, - { { 113, 49 }, { 146, 0 }, { 246, 241 }, { 20, 7 }, { 0, 0 }, 2, 0, 0 }, - { { 114, 48 }, { 20, 0 }, { 199, 199 }, { 88, 8 }, { 0, 0 }, 2, 0, 0 }, - { { 112, 177 }, { 68, 0 }, { 170, 138 }, { 24, 8 }, { 0, 0 }, 4, 0, 0 }, - { { 35, 177 }, { 147, 0 }, { 151, 85 }, { 35, 20 }, { 1, 0 }, 4, 0, 0 }, - { { 97, 177 }, { 19, 128 }, { 151, 85 }, { 4, 4 }, { 1, 0 }, 0, 0, 0 }, - { { 36, 177 }, { 72, 0 }, { 152, 70 }, { 42, 26 }, { 1, 0 }, 12, 0, 0 }, - { { 97, 33 }, { 19, 0 }, { 145, 97 }, { 6, 7 }, { 1, 0 }, 10, 0, 0 }, - { { 33, 161 }, { 19, 137 }, { 113, 97 }, { 6, 7 }, { 0, 0 }, 6, 0, 0 }, - { { 2, 65 }, { 156, 128 }, { 243, 243 }, { 148, 200 }, { 1, 0 }, 12, 0, 0 }, - { { 3, 17 }, { 84, 0 }, { 243, 241 }, { 154, 231 }, { 1, 0 }, 12, 0, 0 }, - { { 35, 33 }, { 95, 0 }, { 241, 242 }, { 58, 248 }, { 0, 0 }, 0, 0, 0 }, - { { 3, 33 }, { 135, 128 }, { 246, 243 }, { 34, 243 }, { 1, 0 }, 6, 0, 0 }, - { { 3, 33 }, { 71, 0 }, { 249, 246 }, { 84, 58 }, { 0, 0 }, 0, 0, 0 }, - { { 35, 33 }, { 72, 0 }, { 149, 132 }, { 25, 25 }, { 1, 0 }, 8, 0, 0 }, - { { 35, 33 }, { 74, 0 }, { 149, 148 }, { 25, 25 }, { 1, 0 }, 8, 0, 0 }, - { { 9, 132 }, { 161, 128 }, { 32, 209 }, { 79, 248 }, { 0, 0 }, 8, 0, 0 }, - { { 33, 162 }, { 30, 0 }, { 148, 195 }, { 6, 166 }, { 0, 0 }, 2, 0, 0 }, - { { 49, 49 }, { 18, 0 }, { 241, 241 }, { 40, 24 }, { 0, 0 }, 10, 0, 0 }, - { { 49, 49 }, { 141, 0 }, { 241, 241 }, { 232, 120 }, { 0, 0 }, 10, 0, 0 }, - { { 49, 50 }, { 91, 0 }, { 81, 113 }, { 40, 72 }, { 0, 0 }, 12, 0, 0 }, - { { 1, 33 }, { 139, 64 }, { 161, 242 }, { 154, 223 }, { 0, 0 }, 8, 0, 0 }, - { { 1, 33 }, { 137, 64 }, { 161, 242 }, { 154, 223 }, { 0, 0 }, 8, 0, 0 }, - { { 49, 49 }, { 139, 0 }, { 244, 241 }, { 232, 120 }, { 0, 0 }, 10, 0, 0 }, - { { 49, 49 }, { 18, 0 }, { 241, 241 }, { 40, 24 }, { 0, 0 }, 10, 0, 0 }, - { { 49, 33 }, { 21, 0 }, { 221, 86 }, { 19, 38 }, { 1, 0 }, 8, 0, 0 }, - { { 49, 33 }, { 22, 0 }, { 221, 102 }, { 19, 6 }, { 1, 0 }, 8, 0, 0 }, - { { 113, 49 }, { 73, 0 }, { 209, 97 }, { 28, 12 }, { 1, 0 }, 8, 0, 0 }, - { { 33, 35 }, { 77, 128 }, { 113, 114 }, { 18, 6 }, { 1, 0 }, 2, 0, 0 }, - { { 241, 225 }, { 64, 0 }, { 241, 111 }, { 33, 22 }, { 1, 0 }, 2, 0, 0 }, - { { 2, 1 }, { 26, 128 }, { 245, 133 }, { 117, 53 }, { 1, 0 }, 0, 0, 0 }, - { { 2, 1 }, { 29, 128 }, { 245, 243 }, { 117, 244 }, { 1, 0 }, 0, 0, 0 }, - { { 16, 17 }, { 65, 0 }, { 245, 242 }, { 5, 195 }, { 1, 0 }, 2, 0, 0 }, - { { 33, 162 }, { 155, 1 }, { 177, 114 }, { 37, 8 }, { 1, 0 }, 14, 0, 0 }, - { { 161, 33 }, { 152, 0 }, { 127, 63 }, { 3, 7 }, { 1, 1 }, 0, 0, 0 }, - { { 161, 97 }, { 147, 0 }, { 193, 79 }, { 18, 5 }, { 0, 0 }, 10, 0, 0 }, - { { 33, 97 }, { 24, 0 }, { 193, 79 }, { 34, 5 }, { 0, 0 }, 12, 0, 0 }, - { { 49, 114 }, { 91, 131 }, { 244, 138 }, { 21, 5 }, { 0, 0 }, 0, 0, 0 }, - { { 161, 97 }, { 144, 0 }, { 116, 113 }, { 57, 103 }, { 0, 0 }, 0, 0, 0 }, - { { 113, 114 }, { 87, 0 }, { 84, 122 }, { 5, 5 }, { 0, 0 }, 12, 0, 0 }, - { { 144, 65 }, { 0, 0 }, { 84, 165 }, { 99, 69 }, { 0, 0 }, 8, 0, 0 }, - { { 33, 33 }, { 146, 1 }, { 133, 143 }, { 23, 9 }, { 0, 0 }, 12, 0, 0 }, - { { 33, 33 }, { 148, 5 }, { 117, 143 }, { 23, 9 }, { 0, 0 }, 12, 0, 0 }, - { { 33, 97 }, { 148, 0 }, { 118, 130 }, { 21, 55 }, { 0, 0 }, 12, 0, 0 }, - { { 49, 33 }, { 67, 0 }, { 158, 98 }, { 23, 44 }, { 1, 1 }, 2, 0, 0 }, - { { 33, 33 }, { 155, 0 }, { 97, 127 }, { 106, 10 }, { 0, 0 }, 2, 0, 0 }, - { { 97, 34 }, { 138, 6 }, { 117, 116 }, { 31, 15 }, { 0, 0 }, 8, 0, 0 }, - { { 161, 33 }, { 134, 13 }, { 114, 113 }, { 85, 24 }, { 1, 0 }, 0, 0, 0 }, - { { 33, 33 }, { 77, 0 }, { 84, 166 }, { 60, 28 }, { 0, 0 }, 8, 0, 0 }, - { { 49, 97 }, { 143, 0 }, { 147, 114 }, { 2, 11 }, { 1, 0 }, 8, 0, 0 }, - { { 49, 97 }, { 142, 0 }, { 147, 114 }, { 3, 9 }, { 1, 0 }, 8, 0, 0 }, - { { 49, 97 }, { 145, 0 }, { 147, 130 }, { 3, 9 }, { 1, 0 }, 10, 0, 0 }, - { { 49, 97 }, { 142, 0 }, { 147, 114 }, { 15, 15 }, { 1, 0 }, 10, 0, 0 }, - { { 33, 33 }, { 75, 0 }, { 170, 143 }, { 22, 10 }, { 1, 0 }, 8, 0, 0 }, - { { 49, 33 }, { 144, 0 }, { 126, 139 }, { 23, 12 }, { 1, 1 }, 6, 0, 0 }, - { { 49, 50 }, { 129, 0 }, { 117, 97 }, { 25, 25 }, { 1, 0 }, 0, 0, 0 }, - { { 50, 33 }, { 144, 0 }, { 155, 114 }, { 33, 23 }, { 0, 0 }, 4, 0, 0 }, - { { 225, 225 }, { 31, 0 }, { 133, 101 }, { 95, 26 }, { 0, 0 }, 0, 0, 0 }, - { { 225, 225 }, { 70, 0 }, { 136, 101 }, { 95, 26 }, { 0, 0 }, 0, 0, 0 }, - { { 161, 33 }, { 156, 0 }, { 117, 117 }, { 31, 10 }, { 0, 0 }, 2, 0, 0 }, - { { 49, 33 }, { 139, 0 }, { 132, 101 }, { 88, 26 }, { 0, 0 }, 0, 0, 0 }, - { { 225, 161 }, { 76, 0 }, { 102, 101 }, { 86, 38 }, { 0, 0 }, 0, 0, 0 }, - { { 98, 161 }, { 203, 0 }, { 118, 85 }, { 70, 54 }, { 0, 0 }, 0, 0, 0 }, - { { 98, 161 }, { 153, 0 }, { 87, 86 }, { 7, 7 }, { 0, 0 }, 11, 0, 0 }, - { { 98, 161 }, { 147, 0 }, { 119, 118 }, { 7, 7 }, { 0, 0 }, 11, 0, 0 }, - { { 34, 33 }, { 89, 0 }, { 255, 255 }, { 3, 15 }, { 2, 0 }, 0, 0, 0 }, - { { 33, 33 }, { 14, 0 }, { 255, 255 }, { 15, 15 }, { 1, 1 }, 0, 0, 0 }, - { { 34, 33 }, { 70, 128 }, { 134, 100 }, { 85, 24 }, { 0, 0 }, 0, 0, 0 }, - { { 33, 161 }, { 69, 0 }, { 102, 150 }, { 18, 10 }, { 0, 0 }, 0, 0, 0 }, - { { 33, 34 }, { 139, 0 }, { 146, 145 }, { 42, 42 }, { 1, 0 }, 0, 0, 0 }, - { { 162, 97 }, { 158, 64 }, { 223, 111 }, { 5, 7 }, { 0, 0 }, 2, 0, 0 }, - { { 32, 96 }, { 26, 0 }, { 239, 143 }, { 1, 6 }, { 0, 2 }, 0, 0, 0 }, - { { 33, 33 }, { 143, 128 }, { 241, 244 }, { 41, 9 }, { 0, 0 }, 10, 0, 0 }, - { { 119, 161 }, { 165, 0 }, { 83, 160 }, { 148, 5 }, { 0, 0 }, 2, 0, 0 }, - { { 97, 177 }, { 31, 128 }, { 168, 37 }, { 17, 3 }, { 0, 0 }, 10, 0, 0 }, - { { 97, 97 }, { 23, 0 }, { 145, 85 }, { 52, 22 }, { 0, 0 }, 12, 0, 0 }, - { { 113, 114 }, { 93, 0 }, { 84, 106 }, { 1, 3 }, { 0, 0 }, 0, 0, 0 }, - { { 33, 162 }, { 151, 0 }, { 33, 66 }, { 67, 53 }, { 0, 0 }, 8, 0, 0 }, - { { 161, 33 }, { 28, 0 }, { 161, 49 }, { 119, 71 }, { 1, 1 }, 0, 0, 0 }, - { { 33, 97 }, { 137, 3 }, { 17, 66 }, { 51, 37 }, { 0, 0 }, 10, 0, 0 }, - { { 161, 33 }, { 21, 0 }, { 17, 207 }, { 71, 7 }, { 1, 0 }, 0, 0, 0 }, - { { 58, 81 }, { 206, 0 }, { 248, 134 }, { 246, 2 }, { 0, 0 }, 2, 0, 0 }, - { { 33, 33 }, { 21, 0 }, { 33, 65 }, { 35, 19 }, { 1, 0 }, 0, 0, 0 }, - { { 6, 1 }, { 91, 0 }, { 116, 165 }, { 149, 114 }, { 0, 0 }, 0, 0, 0 }, - { { 34, 97 }, { 146, 131 }, { 177, 242 }, { 129, 38 }, { 0, 0 }, 12, 0, 0 }, - { { 65, 66 }, { 77, 0 }, { 241, 242 }, { 81, 245 }, { 1, 0 }, 0, 0, 0 }, - { { 97, 163 }, { 148, 128 }, { 17, 17 }, { 81, 19 }, { 1, 0 }, 6, 0, 0 }, - { { 97, 161 }, { 140, 128 }, { 17, 29 }, { 49, 3 }, { 0, 0 }, 6, 0, 0 }, - { { 164, 97 }, { 76, 0 }, { 243, 129 }, { 115, 35 }, { 1, 0 }, 4, 0, 0 }, - { { 2, 7 }, { 133, 3 }, { 210, 242 }, { 83, 246 }, { 0, 1 }, 0, 0, 0 }, - { { 17, 19 }, { 12, 128 }, { 163, 162 }, { 17, 229 }, { 1, 0 }, 0, 0, 0 }, - { { 17, 17 }, { 6, 0 }, { 246, 242 }, { 65, 230 }, { 1, 2 }, 4, 0, 0 }, - { { 147, 145 }, { 145, 0 }, { 212, 235 }, { 50, 17 }, { 0, 1 }, 8, 0, 0 }, - { { 4, 1 }, { 79, 0 }, { 250, 194 }, { 86, 5 }, { 0, 0 }, 12, 0, 0 }, - { { 33, 34 }, { 73, 0 }, { 124, 111 }, { 32, 12 }, { 0, 1 }, 6, 0, 0 }, - { { 49, 33 }, { 133, 0 }, { 221, 86 }, { 51, 22 }, { 1, 0 }, 10, 0, 0 }, - { { 32, 33 }, { 4, 129 }, { 218, 143 }, { 5, 11 }, { 2, 0 }, 6, 0, 0 }, - { { 5, 3 }, { 106, 128 }, { 241, 195 }, { 229, 229 }, { 0, 0 }, 6, 0, 0 }, - { { 7, 2 }, { 21, 0 }, { 236, 248 }, { 38, 22 }, { 0, 0 }, 10, 0, 0 }, - { { 5, 1 }, { 157, 0 }, { 103, 223 }, { 53, 5 }, { 0, 0 }, 8, 0, 0 }, - { { 24, 18 }, { 150, 0 }, { 250, 248 }, { 40, 229 }, { 0, 0 }, 10, 0, 0 }, - { { 16, 0 }, { 134, 3 }, { 168, 250 }, { 7, 3 }, { 0, 0 }, 6, 0, 0 }, - { { 17, 16 }, { 65, 3 }, { 248, 243 }, { 71, 3 }, { 2, 0 }, 4, 0, 0 }, - { { 1, 16 }, { 142, 0 }, { 241, 243 }, { 6, 2 }, { 2, 0 }, 14, 0, 0 }, - { { 14, 192 }, { 0, 0 }, { 31, 31 }, { 0, 255 }, { 0, 3 }, 14, 0, 0 }, - { { 6, 3 }, { 128, 136 }, { 248, 86 }, { 36, 132 }, { 0, 2 }, 14, 0, 0 }, - { { 14, 208 }, { 0, 5 }, { 248, 52 }, { 0, 4 }, { 0, 3 }, 14, 0, 0 }, - { { 14, 192 }, { 0, 0 }, { 246, 31 }, { 0, 2 }, { 0, 3 }, 14, 0, 0 }, - { { 213, 218 }, { 149, 64 }, { 55, 86 }, { 163, 55 }, { 0, 0 }, 0, 0, 0 }, - { { 53, 20 }, { 92, 8 }, { 178, 244 }, { 97, 21 }, { 2, 0 }, 10, 0, 0 }, - { { 14, 208 }, { 0, 0 }, { 246, 79 }, { 0, 245 }, { 0, 3 }, 14, 0, 0 }, - { { 38, 228 }, { 0, 0 }, { 255, 18 }, { 1, 22 }, { 0, 1 }, 14, 0, 0 }, - { { 0, 0 }, { 0, 0 }, { 243, 246 }, { 240, 201 }, { 0, 2 }, 14, 0, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 0, 0 }, { 0, 0 }, { 252, 250 }, { 5, 23 }, { 2, 0 }, 14, 52, 0 }, - { { 0, 1 }, { 2, 0 }, { 255, 255 }, { 7, 8 }, { 0, 0 }, 0, 48, 0 }, - { { 0, 0 }, { 0, 0 }, { 252, 250 }, { 5, 23 }, { 2, 0 }, 14, 58, 0 }, - { { 0, 0 }, { 0, 0 }, { 246, 246 }, { 12, 6 }, { 0, 0 }, 4, 60, 0 }, - { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 47, 0 }, - { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43, 0 }, - { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 49, 0 }, - { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43, 0 }, - { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 51, 0 }, - { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43, 0 }, - { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 54, 0 }, - { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 57, 0 }, - { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 72, 0 }, - { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 60, 0 }, - { { 14, 208 }, { 0, 10 }, { 245, 159 }, { 48, 2 }, { 0, 0 }, 14, 76, 0 }, - { { 14, 7 }, { 10, 93 }, { 228, 245 }, { 228, 229 }, { 3, 1 }, 6, 84, 0 }, - { { 2, 5 }, { 3, 10 }, { 180, 151 }, { 4, 247 }, { 0, 0 }, 14, 36, 0 }, - { { 78, 158 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 14, 76, 0 }, - { { 17, 16 }, { 69, 8 }, { 248, 243 }, { 55, 5 }, { 2, 0 }, 8, 84, 0 }, - { { 14, 208 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 14, 83, 0 }, - { { 128, 16 }, { 0, 13 }, { 255, 255 }, { 3, 20 }, { 3, 0 }, 12, 84, 0 }, - { { 14, 7 }, { 8, 81 }, { 248, 244 }, { 66, 228 }, { 0, 3 }, 14, 24, 0 }, - { { 14, 208 }, { 0, 10 }, { 245, 159 }, { 48, 2 }, { 0, 0 }, 14, 77, 0 }, - { { 1, 2 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 7, 60, 0 }, - { { 1, 1 }, { 81, 0 }, { 250, 250 }, { 135, 183 }, { 0, 0 }, 6, 65, 0 }, - { { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 59, 0 }, - { { 1, 2 }, { 89, 0 }, { 250, 248 }, { 136, 182 }, { 0, 0 }, 6, 51, 0 }, - { { 1, 0 }, { 0, 0 }, { 249, 250 }, { 10, 6 }, { 3, 0 }, 14, 45, 0 }, - { { 0, 0 }, { 128, 0 }, { 249, 246 }, { 137, 108 }, { 3, 0 }, 14, 71, 0 }, - { { 3, 12 }, { 128, 8 }, { 248, 246 }, { 136, 182 }, { 3, 0 }, 15, 60, 0 }, - { { 3, 12 }, { 133, 0 }, { 248, 246 }, { 136, 182 }, { 3, 0 }, 15, 58, 0 }, - { { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 53, 0 }, - { { 14, 3 }, { 64, 0 }, { 200, 155 }, { 73, 105 }, { 0, 2 }, 14, 64, 0 }, - { { 215, 199 }, { 220, 0 }, { 173, 141 }, { 5, 5 }, { 3, 0 }, 14, 71, 0 }, - { { 215, 199 }, { 220, 0 }, { 168, 136 }, { 4, 4 }, { 3, 0 }, 14, 61, 0 }, - { { 128, 17 }, { 0, 0 }, { 246, 103 }, { 6, 23 }, { 3, 3 }, 14, 61, 0 }, - { { 128, 17 }, { 0, 9 }, { 245, 70 }, { 5, 22 }, { 2, 3 }, 14, 48, 0 }, - { { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 48, 0 }, - { { 6, 18 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 3, 0 }, 0, 69, 0 }, - { { 6, 18 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 68, 0 }, - { { 1, 2 }, { 88, 0 }, { 103, 117 }, { 231, 7 }, { 0, 0 }, 0, 63, 0 }, - { { 65, 66 }, { 69, 8 }, { 248, 117 }, { 72, 5 }, { 0, 0 }, 0, 74, 0 }, - { { 10, 30 }, { 64, 78 }, { 224, 255 }, { 240, 5 }, { 3, 0 }, 8, 60, 0 }, - { { 10, 30 }, { 124, 82 }, { 224, 255 }, { 240, 2 }, { 3, 0 }, 8, 80, 0 }, - { { 14, 0 }, { 64, 8 }, { 122, 123 }, { 74, 27 }, { 0, 2 }, 14, 64, 0 }, - { { 14, 7 }, { 10, 64 }, { 228, 85 }, { 228, 57 }, { 3, 1 }, 6, 69, 0 }, - { { 5, 4 }, { 5, 64 }, { 249, 214 }, { 50, 165 }, { 3, 0 }, 14, 73, 0 }, - { { 2, 21 }, { 63, 0 }, { 0, 247 }, { 243, 245 }, { 3, 0 }, 8, 75, 0 }, - { { 1, 2 }, { 79, 0 }, { 250, 248 }, { 141, 181 }, { 0, 0 }, 7, 68, 0 }, - { { 0, 0 }, { 0, 0 }, { 246, 246 }, { 12, 6 }, { 0, 0 }, 4, 48, 0 }, - { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 53, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 }, - { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35, 0 } - }; diff --git a/source/audiolib/src/ll.h b/source/audiolib/src/ll.h deleted file mode 100644 index a0a581ffe..000000000 --- a/source/audiolib/src/ll.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#ifndef __linklist_h -#define __linklist_h -#ifdef __cplusplus -extern "C" { -#endif - - -#define NewNode(type) ((type*)SafeMalloc(sizeof(type))) - - -#define LL_CreateNewLinkedList(rootnode,type,next,prev) \ - { \ - (rootnode) = NewNode(type); \ - (rootnode)->prev = (rootnode); \ - (rootnode)->next = (rootnode); \ - } - - - -#define LL_AddNode(rootnode, newnode, next, prev) \ - { \ - (newnode)->next = (rootnode); \ - (newnode)->prev = (rootnode)->prev; \ - (rootnode)->prev->next = (newnode); \ - (rootnode)->prev = (newnode); \ - } - -#define LL_TransferList(oldroot,newroot,next,prev) \ - { \ - if ((oldroot)->prev != (oldroot)) \ - { \ - (oldroot)->prev->next = (newroot); \ - (oldroot)->next->prev = (newroot)->prev; \ - (newroot)->prev->next = (oldroot)->next; \ - (newroot)->prev = (oldroot)->prev; \ - (oldroot)->next = (oldroot); \ - (oldroot)->prev = (oldroot); \ - } \ - } - -#define LL_ReverseList(root,type,next,prev) \ - { \ - type *newend,*trav,*tprev; \ - \ - newend = (root)->next; \ - for(trav = (root)->prev; trav != newend; trav = tprev) \ - { \ - tprev = trav->prev; \ - LL_MoveNode(trav,newend,next,prev); \ - } \ - } - - -#define LL_RemoveNode(node,next,prev) \ - { \ - (node)->prev->next = (node)->next; \ - (node)->next->prev = (node)->prev; \ - (node)->next = (node); \ - (node)->prev = (node); \ - } - - -#define LL_SortedInsertion(rootnode,insertnode,next,prev,type,sortparm) \ - { \ - type *hoya; \ - \ - hoya = (rootnode)->next; \ - while((hoya != (rootnode)) && ((insertnode)->sortparm > hoya->sortparm)) \ - { \ - hoya = hoya->next; \ - } \ - LL_AddNode(hoya,(insertnode),next,prev); \ - } - -#define LL_MoveNode(node,newroot,next,prev) \ - { \ - LL_RemoveNode((node),next,prev); \ - LL_AddNode((newroot),(node),next,prev); \ - } - -#define LL_ListEmpty(list,next,prev) \ - ( \ - ((list)->next == (list)) && \ - ((list)->prev == (list)) \ - ) - -#define LL_Free(list) SafeFree(list) -#define LL_Reset(list,next,prev) (list)->next = (list)->prev = (list) -#define LL_New LL_CreateNewLinkedList -#define LL_Remove LL_RemoveNode -#define LL_Add LL_AddNode -#define LL_Empty LL_ListEmpty -#define LL_Move LL_MoveNode - - -#ifdef __cplusplus -}; -#endif -#endif diff --git a/source/audiolib/src/midi.cpp b/source/audiolib/src/midi.cpp deleted file mode 100644 index cef907974..000000000 --- a/source/audiolib/src/midi.cpp +++ /dev/null @@ -1,1023 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010-2019 EDuke32 developers and contributors -Copyright (C) 2019 Nuke.YKT - -This file is part of NBlood. - -NBlood is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -/********************************************************************** - module: MIDI.C - - author: James R. Dose - date: May 25, 1994 - - Midi song file playback routines. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#include "midi.h" - -#include "_midi.h" -#include "_multivc.h" -#include "compat.h" -#include "multivoc.h" -#include "music.h" -#include "pragmas.h" -#include "sndcards.h" -#include "driver_adlib.h" -#include "c_cvars.h" - -CUSTOM_CVARD(Int, mus_emidicard, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "force a specific EMIDI instrument set") -{ - ASS_EMIDICard = clamp(*self, -1, 10); -} - - -extern int MV_MixRate; -extern int ASS_MIDISoundDriver; - -int MIDI_GetDevice() -{ - return ASS_MIDISoundDriver; -} - -static const int _MIDI_CommandLengths[NUM_MIDI_CHANNELS] = { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0 }; - -static track * _MIDI_TrackPtr; -static int _MIDI_TrackMemSize; -static int _MIDI_NumTracks; - -static int _MIDI_SongActive; -static int _MIDI_SongLoaded; -static int _MIDI_Loop; - -static int _MIDI_Division; -static int _MIDI_Tick; -static int _MIDI_Beat = 1; -static int _MIDI_Measure = 1; -static uint32_t _MIDI_Time; -static int _MIDI_BeatsPerMeasure; -static int _MIDI_TicksPerBeat; -static int _MIDI_TimeBase; -static int _MIDI_FPSecondsPerTick; -static uint32_t _MIDI_TotalTime; -static int _MIDI_TotalTicks; -static int _MIDI_TotalBeats; -static int _MIDI_TotalMeasures; - -uint32_t _MIDI_PositionInTicks; -uint32_t _MIDI_GlobalPositionInTicks; - -static int _MIDI_Context; - -static int _MIDI_ActiveTracks; -static int _MIDI_TotalVolume = MIDI_MaxVolume; - -static int _MIDI_ChannelVolume[ NUM_MIDI_CHANNELS ]; - -static midifuncs *_MIDI_Funcs; - -static int _MIDI_Reset; - -int MV_MIDIRenderTempo = -1; -int MV_MIDIRenderTimer; - -static char *_MIDI_SongPtr; - -void MIDI_Restart(void) -{ - MIDI_PlaySong(_MIDI_SongPtr, _MIDI_Loop); -} - -static int _MIDI_ReadNumber(void *from, size_t size) -{ - if (size > 4) - size = 4; - - char *FromPtr = (char *)from; - int value = 0; - - while (size--) - { - value <<= 8; - value += *FromPtr++; - } - - return value; -} - -static int _MIDI_ReadDelta(track *ptr) -{ - int value; - - GET_NEXT_EVENT(ptr, value); - - if (value & 0x80) - { - value &= 0x7f; - char c; - - do - { - GET_NEXT_EVENT(ptr, c); - value = (value << 7) + (c & 0x7f); - } - while (c & 0x80); - } - - return value; -} - -static void _MIDI_ResetTracks(void) -{ - _MIDI_Tick = 0; - _MIDI_Beat = 1; - _MIDI_Measure = 1; - _MIDI_Time = 0; - _MIDI_BeatsPerMeasure = 4; - _MIDI_TicksPerBeat = _MIDI_Division; - _MIDI_TimeBase = 4; - _MIDI_PositionInTicks = 0; - _MIDI_ActiveTracks = 0; - _MIDI_Context = 0; - - track *ptr = _MIDI_TrackPtr; - for (bssize_t i = 0; i < _MIDI_NumTracks; ++i) - { - ptr->pos = ptr->start; - ptr->delay = _MIDI_ReadDelta(ptr); - ptr->active = ptr->EMIDI_IncludeTrack; - ptr->RunningStatus = 0; - ptr->currentcontext = 0; - ptr->context[ 0 ].loopstart = ptr->start; - ptr->context[ 0 ].loopcount = 0; - - if (ptr->active) - _MIDI_ActiveTracks++; - - ptr++; - } -} - -static void _MIDI_AdvanceTick(void) -{ - _MIDI_PositionInTicks++; - _MIDI_Time += _MIDI_FPSecondsPerTick; - - _MIDI_Tick++; - while (_MIDI_Tick > _MIDI_TicksPerBeat) - { - _MIDI_Tick -= _MIDI_TicksPerBeat; - _MIDI_Beat++; - } - while (_MIDI_Beat > _MIDI_BeatsPerMeasure) - { - _MIDI_Beat -= _MIDI_BeatsPerMeasure; - _MIDI_Measure++; - } -} - -static void _MIDI_SysEx(track *Track) -{ - int length = _MIDI_ReadDelta(Track); - Track->pos += length; -} - - -static void _MIDI_MetaEvent(track *Track) -{ - int command; - int length; - - GET_NEXT_EVENT(Track, command); - GET_NEXT_EVENT(Track, length); - - switch (command) - { - case MIDI_END_OF_TRACK: - Track->active = FALSE; - - _MIDI_ActiveTracks--; - break; - - case MIDI_TEMPO_CHANGE: - { - int tempo = tabledivide32_noinline(60000000L, _MIDI_ReadNumber(Track->pos, 3)); - MIDI_SetTempo(tempo); - break; - } - - case MIDI_TIME_SIGNATURE: - { - if ((_MIDI_Tick > 0) || (_MIDI_Beat > 1)) - _MIDI_Measure++; - - _MIDI_Tick = 0; - _MIDI_Beat = 1; - _MIDI_TimeBase = 1; - _MIDI_BeatsPerMeasure = (int)*Track->pos; - int denominator = (int) * (Track->pos + 1); - - while (denominator > 0) - { - _MIDI_TimeBase += _MIDI_TimeBase; - denominator--; - } - - _MIDI_TicksPerBeat = tabledivide32_noinline(_MIDI_Division * 4, _MIDI_TimeBase); - break; - } - } - - Track->pos += length; -} - -static int _MIDI_InterpretControllerInfo(track *Track, int TimeSet, int channel, int c1, int c2) -{ - track *trackptr; - int tracknum; - int loopcount; - - switch (c1) - { - case MIDI_MONO_MODE_ON : - Track->pos++; - break; - - case MIDI_VOLUME : - if (!Track->EMIDI_VolumeChange) - _MIDI_SetChannelVolume(channel, c2); - break; - - case EMIDI_INCLUDE_TRACK : - case EMIDI_EXCLUDE_TRACK : - break; - - case EMIDI_PROGRAM_CHANGE : - if (Track->EMIDI_ProgramChange) - _MIDI_Funcs->ProgramChange(channel, c2 & 0x7f); - break; - - case EMIDI_VOLUME_CHANGE : - if (Track->EMIDI_VolumeChange) - _MIDI_SetChannelVolume(channel, c2); - break; - - case EMIDI_CONTEXT_START : - break; - - case EMIDI_CONTEXT_END : - if ((Track->currentcontext == _MIDI_Context) || (_MIDI_Context < 0) || - (Track->context[_MIDI_Context].pos == nullptr)) - break; - - Track->currentcontext = _MIDI_Context; - Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart; - Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount; - Track->pos = Track->context[ _MIDI_Context ].pos; - Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus; - - if (TimeSet) - { - break; - } - - _MIDI_Time = Track->context[ _MIDI_Context ].time; - _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick; - _MIDI_Tick = Track->context[ _MIDI_Context ].tick; - _MIDI_Beat = Track->context[ _MIDI_Context ].beat; - _MIDI_Measure = Track->context[ _MIDI_Context ].measure; - _MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure; - _MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat; - _MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase; - TimeSet = TRUE; - break; - - case EMIDI_LOOP_START : - case EMIDI_SONG_LOOP_START : - loopcount = (c2 == 0) ? EMIDI_INFINITE : c2; - - if (c1 == EMIDI_SONG_LOOP_START) - { - trackptr = _MIDI_TrackPtr; - tracknum = _MIDI_NumTracks; - } - else - { - trackptr = Track; - tracknum = 1; - } - - while (tracknum > 0) - { - trackptr->context[ 0 ].loopcount = loopcount; - trackptr->context[ 0 ].pos = trackptr->pos; - trackptr->context[ 0 ].loopstart = trackptr->pos; - trackptr->context[ 0 ].RunningStatus = trackptr->RunningStatus; - trackptr->context[ 0 ].active = trackptr->active; - trackptr->context[ 0 ].delay = trackptr->delay; - trackptr->context[ 0 ].time = _MIDI_Time; - trackptr->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; - trackptr->context[ 0 ].tick = _MIDI_Tick; - trackptr->context[ 0 ].beat = _MIDI_Beat; - trackptr->context[ 0 ].measure = _MIDI_Measure; - trackptr->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; - trackptr->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat; - trackptr->context[ 0 ].TimeBase = _MIDI_TimeBase; - trackptr++; - tracknum--; - } - break; - - case EMIDI_LOOP_END : - case EMIDI_SONG_LOOP_END : - if ((c2 != EMIDI_END_LOOP_VALUE) || (Track->context[0].loopstart == nullptr) || (Track->context[0].loopcount == 0)) - break; - - if (c1 == EMIDI_SONG_LOOP_END) - { - trackptr = _MIDI_TrackPtr; - tracknum = _MIDI_NumTracks; - _MIDI_ActiveTracks = 0; - } - else - { - trackptr = Track; - tracknum = 1; - _MIDI_ActiveTracks--; - } - - while (tracknum > 0) - { - if (trackptr->context[ 0 ].loopcount != EMIDI_INFINITE) - { - trackptr->context[ 0 ].loopcount--; - } - - trackptr->pos = trackptr->context[ 0 ].loopstart; - trackptr->RunningStatus = trackptr->context[ 0 ].RunningStatus; - trackptr->delay = trackptr->context[ 0 ].delay; - trackptr->active = trackptr->context[ 0 ].active; - if (trackptr->active) - { - _MIDI_ActiveTracks++; - } - - if (!TimeSet) - { - _MIDI_Time = trackptr->context[ 0 ].time; - _MIDI_FPSecondsPerTick = trackptr->context[ 0 ].FPSecondsPerTick; - _MIDI_Tick = trackptr->context[ 0 ].tick; - _MIDI_Beat = trackptr->context[ 0 ].beat; - _MIDI_Measure = trackptr->context[ 0 ].measure; - _MIDI_BeatsPerMeasure = trackptr->context[ 0 ].BeatsPerMeasure; - _MIDI_TicksPerBeat = trackptr->context[ 0 ].TicksPerBeat; - _MIDI_TimeBase = trackptr->context[ 0 ].TimeBase; - TimeSet = TRUE; - } - - trackptr++; - tracknum--; - } - break; - - default : - if (_MIDI_Funcs->ControlChange) - _MIDI_Funcs->ControlChange(channel, c1, c2); - } - - return TimeSet; -} - -static void _MIDI_ServiceRoutine(void) -{ - if (!_MIDI_SongActive) - return; - - track *Track = _MIDI_TrackPtr; - int tracknum = 0; - int TimeSet = FALSE; - int c1 = 0; - int c2 = 0; - - while (tracknum < _MIDI_NumTracks) - { - while ((Track->active) && (Track->delay == 0)) - { - int event; - GET_NEXT_EVENT(Track, event); - - if (GET_MIDI_COMMAND(event) == MIDI_SPECIAL) - { - switch (event) - { - case MIDI_SYSEX: - case MIDI_SYSEX_CONTINUE: _MIDI_SysEx(Track); break; - case MIDI_META_EVENT: _MIDI_MetaEvent(Track); break; - } - - if (Track->active) - Track->delay = _MIDI_ReadDelta(Track); - continue; - } - - if (event & MIDI_RUNNING_STATUS) - Track->RunningStatus = event; - else - { - event = Track->RunningStatus; - Track->pos--; - } - - int const channel = GET_MIDI_CHANNEL(event); - int const command = GET_MIDI_COMMAND(event); - - if (_MIDI_CommandLengths[ command ] > 0) - { - GET_NEXT_EVENT(Track, c1); - if (_MIDI_CommandLengths[ command ] > 1) - GET_NEXT_EVENT(Track, c2); - } - - switch (command) - { - case MIDI_NOTE_OFF: - if (_MIDI_Funcs->NoteOff) - _MIDI_Funcs->NoteOff(channel, c1, c2); - break; - - case MIDI_NOTE_ON: - if (_MIDI_Funcs->NoteOn) - _MIDI_Funcs->NoteOn(channel, c1, c2); - break; - - case MIDI_POLY_AFTER_TCH: - if (_MIDI_Funcs->PolyAftertouch) - _MIDI_Funcs->PolyAftertouch(channel, c1, c2); - break; - - case MIDI_CONTROL_CHANGE: - TimeSet = _MIDI_InterpretControllerInfo(Track, TimeSet, channel, c1, c2); - break; - - case MIDI_PROGRAM_CHANGE: - if ((_MIDI_Funcs->ProgramChange) && (!Track->EMIDI_ProgramChange)) - _MIDI_Funcs->ProgramChange(channel, c1 & 0x7f); - break; - - case MIDI_AFTER_TOUCH: - if (_MIDI_Funcs->ChannelAftertouch) - _MIDI_Funcs->ChannelAftertouch(channel, c1); - break; - - case MIDI_PITCH_BEND: - if (_MIDI_Funcs->PitchBend) - _MIDI_Funcs->PitchBend(channel, c1, c2); - break; - - default: break; - } - - Track->delay = _MIDI_ReadDelta(Track); - } - - Track->delay--; - Track++; - tracknum++; - - if (_MIDI_ActiveTracks == 0) - { - _MIDI_ResetTracks(); - if (_MIDI_Loop) - { - tracknum = 0; - Track = _MIDI_TrackPtr; - } - else - { - _MIDI_SongActive = FALSE; - break; - } - } - } - - _MIDI_AdvanceTick(); - _MIDI_GlobalPositionInTicks++; -} - -static void _MIDI_ServiceMultivoc(void) -{ - int16_t * buffer16 = (int16_t *)MV_MusicBuffer; - int const samples = MV_BufferSize >> 2; - - for (int i = 0; i < samples; i++) - { - Bit16s buf[2]; - while (MV_MIDIRenderTimer >= MV_MixRate) - { - if (MV_MIDIRenderTempo >= 0) - _MIDI_ServiceRoutine(); - MV_MIDIRenderTimer -= MV_MixRate; - } - if (MV_MIDIRenderTempo >= 0) MV_MIDIRenderTimer += MV_MIDIRenderTempo; - OPL3_GenerateResampled(AL_GetChip(), buf); - *buffer16++ = clamp(buf[0]<ControlChange == nullptr) - return MIDI_Error; - - _MIDI_Funcs->ControlChange(channel, c1, c2); - - return MIDI_Ok; -} - -static int _MIDI_SendProgramChange(int channel, int c1) -{ - if (_MIDI_Funcs == nullptr || _MIDI_Funcs->ProgramChange == nullptr) - return MIDI_Error; - - _MIDI_Funcs->ProgramChange(channel, c1); - - return MIDI_Ok; -} - -int MIDI_AllNotesOff(void) -{ - SoundDriver_MIDI_Lock(); - - for (bssize_t channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - { - _MIDI_SendControlChange(channel, MIDI_HOLD1, 0); - _MIDI_SendControlChange(channel, MIDI_SOSTENUTO, 0); - _MIDI_SendControlChange(channel, MIDI_ALL_NOTES_OFF, 0); - _MIDI_SendControlChange(channel, MIDI_ALL_SOUNDS_OFF, 0); - } - - SoundDriver_MIDI_Unlock(); - - return MIDI_Ok; -} - -static void _MIDI_SetChannelVolume(int channel, int volume) -{ - _MIDI_ChannelVolume[channel] = volume; - - if (_MIDI_Funcs == nullptr || _MIDI_Funcs->ControlChange == nullptr) - return; - - volume *= _MIDI_TotalVolume; - volume = tabledivide32_noinline(volume, MIDI_MaxVolume); - - _MIDI_Funcs->ControlChange(channel, MIDI_VOLUME, volume); -} - -static void _MIDI_SendChannelVolumes(void) -{ - for (bssize_t channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - _MIDI_SetChannelVolume(channel, _MIDI_ChannelVolume[channel]); -} - -int MIDI_Reset(void) -{ - MIDI_AllNotesOff(); - - SoundDriver_MIDI_Lock(); - - for (bssize_t channel = 0; channel < NUM_MIDI_CHANNELS; channel++) - { - _MIDI_SendControlChange(channel, MIDI_RESET_ALL_CONTROLLERS, 0); - _MIDI_SendControlChange(channel, MIDI_RPN_MSB, MIDI_PITCHBEND_MSB); - _MIDI_SendControlChange(channel, MIDI_RPN_LSB, MIDI_PITCHBEND_LSB); - _MIDI_SendControlChange(channel, MIDI_DATAENTRY_MSB, 2); /* Pitch Bend Sensitivity MSB */ - _MIDI_SendControlChange(channel, MIDI_DATAENTRY_LSB, 0); /* Pitch Bend Sensitivity LSB */ - _MIDI_ChannelVolume[channel] = GENMIDI_DefaultVolume; - _MIDI_SendControlChange(channel, MIDI_PAN, 64); // begin TURRICAN's recommendation - _MIDI_SendControlChange(channel, MIDI_REVERB, 40); - _MIDI_SendControlChange(channel, MIDI_CHORUS, 0); - _MIDI_SendControlChange(channel, MIDI_BANK_SELECT_MSB, 0); - _MIDI_SendControlChange(channel, MIDI_BANK_SELECT_LSB, 0); - _MIDI_SendProgramChange(channel, 0); // end TURRICAN's recommendation - } - - _MIDI_SendChannelVolumes(); - - SoundDriver_MIDI_Unlock(); - - _MIDI_Reset = TRUE; - - return MIDI_Ok; -} - - -int MIDI_SetVolume(int volume) -{ - if (_MIDI_Funcs == nullptr) - return MIDI_NullMidiModule; - - volume = min(MIDI_MaxVolume, volume); - volume = max(0, volume); - - _MIDI_TotalVolume = volume; - - SoundDriver_MIDI_Lock(); - - if (_MIDI_Funcs->SetVolume) - _MIDI_Funcs->SetVolume(volume); - else - _MIDI_SendChannelVolumes(); - - SoundDriver_MIDI_Unlock(); - - return MIDI_Ok; -} - - -int MIDI_GetVolume(void) -{ - if (_MIDI_Funcs == nullptr) - return MIDI_NullMidiModule; - - SoundDriver_MIDI_Lock(); - int volume = (_MIDI_Funcs->GetVolume) ? _MIDI_Funcs->GetVolume() : _MIDI_TotalVolume; - SoundDriver_MIDI_Unlock(); - - return volume; -} - -void MIDI_SetLoopFlag(int loopflag) { _MIDI_Loop = loopflag; } - -void MIDI_ContinueSong(void) -{ - if (!_MIDI_SongLoaded) - return; - - _MIDI_SongActive = TRUE; -} - -void MIDI_PauseSong(void) -{ - if (!_MIDI_SongLoaded) - return; - - _MIDI_SongActive = FALSE; - MIDI_AllNotesOff(); -} - -void MIDI_SetMidiFuncs(midifuncs *funcs) { _MIDI_Funcs = funcs; } - -void MIDI_StopSong(void) -{ - if (!_MIDI_SongLoaded) - return; - - SoundDriver_MIDI_HaltPlayback(); - - _MIDI_SongActive = FALSE; - _MIDI_SongLoaded = FALSE; - - MIDI_Reset(); - _MIDI_ResetTracks(); - - DO_FREE_AND_NULL(_MIDI_TrackPtr); - - _MIDI_NumTracks = 0; - _MIDI_TrackMemSize = 0; - - _MIDI_TotalTime = 0; - _MIDI_TotalTicks = 0; - _MIDI_TotalBeats = 0; - _MIDI_TotalMeasures = 0; -} - -int MIDI_PlaySong(char *song, int loopflag) -{ - if (_MIDI_Funcs == nullptr) - return MIDI_NullMidiModule; - - if (B_UNBUF32(song) != MIDI_HEADER_SIGNATURE) - return MIDI_InvalidMidiFile; - - _MIDI_SongPtr = song; - - song += 4; - int const headersize = _MIDI_ReadNumber(song, 4); - song += 4; - int const format = _MIDI_ReadNumber(song, 2); - - int My_MIDI_NumTracks = _MIDI_ReadNumber(song + 2, 2); - int My_MIDI_Division = _MIDI_ReadNumber(song + 4, 2); - - if (My_MIDI_Division < 0) - { - // If a SMPTE time division is given, just set to 96 so no errors occur - My_MIDI_Division = 96; - } - - if (format > MAX_FORMAT) - return MIDI_UnknownMidiFormat; - - char *ptr = song + headersize; - - if (My_MIDI_NumTracks == 0) - return MIDI_NoTracks; - - int My_MIDI_TrackMemSize = My_MIDI_NumTracks * sizeof(track); - track * My_MIDI_TrackPtr = (track *)Xmalloc(My_MIDI_TrackMemSize); - - auto CurrentTrack = My_MIDI_TrackPtr; - int numtracks = My_MIDI_NumTracks; - - while (numtracks--) - { - if (B_UNBUF32(ptr) != MIDI_TRACK_SIGNATURE) - { - DO_FREE_AND_NULL(My_MIDI_TrackPtr); - - My_MIDI_TrackMemSize = 0; - - return MIDI_InvalidTrack; - } - - int tracklength = _MIDI_ReadNumber(ptr + 4, 4); - ptr += 8; - CurrentTrack->start = ptr; - ptr += tracklength; - CurrentTrack++; - } - - // at this point we know song load is successful - - if (_MIDI_SongLoaded) - MIDI_StopSong(); - - _MIDI_Loop = loopflag; - _MIDI_NumTracks = My_MIDI_NumTracks; - _MIDI_Division = My_MIDI_Division; - _MIDI_TrackMemSize = My_MIDI_TrackMemSize; - _MIDI_TrackPtr = My_MIDI_TrackPtr; - - _MIDI_InitEMIDI(); - _MIDI_ResetTracks(); - - if (!_MIDI_Reset) - MIDI_Reset(); - - _MIDI_Reset = FALSE; - - // this can either stay like this, or I can add another field to the MIDI driver spec that holds the service callback - if (SoundDriver_MIDI_StartPlayback(ASS_MIDISoundDriver == ASS_OPL3 ? _MIDI_ServiceMultivoc : _MIDI_ServiceRoutine) != MIDI_Ok) - return MIDI_DriverError; - - MIDI_SetTempo(120); - - _MIDI_SongLoaded = TRUE; - _MIDI_SongActive = TRUE; - - return MIDI_Ok; -} - -void MIDI_SetTempo(int tempo) -{ - SoundDriver_MIDI_SetTempo(tempo, _MIDI_Division); - int const tickspersecond = tempo * _MIDI_Division / 60; - _MIDI_FPSecondsPerTick = tabledivide32_noinline(1 << TIME_PRECISION, tickspersecond); -} - -static void _MIDI_InitEMIDI(void) -{ - int type = EMIDI_GeneralMIDI; - - switch (ASS_MIDISoundDriver) - { - case ASS_OPL3: - type = EMIDI_SoundBlaster; - break; - } - - if (ASS_EMIDICard != -1) - type = ASS_EMIDICard; - - _MIDI_ResetTracks(); - - _MIDI_TotalTime = 0; - _MIDI_TotalTicks = 0; - _MIDI_TotalBeats = 0; - _MIDI_TotalMeasures = 0; - - track *Track = _MIDI_TrackPtr; - int tracknum = 0; - - while ((tracknum < _MIDI_NumTracks) && (Track != nullptr)) - { - _MIDI_Tick = 0; - _MIDI_Beat = 1; - _MIDI_Measure = 1; - _MIDI_Time = 0; - _MIDI_BeatsPerMeasure = 4; - _MIDI_TicksPerBeat = _MIDI_Division; - _MIDI_TimeBase = 4; - - _MIDI_PositionInTicks = 0; - _MIDI_ActiveTracks = 0; - _MIDI_Context = -1; - - Track->RunningStatus = 0; - Track->active = TRUE; - - Track->EMIDI_ProgramChange = FALSE; - Track->EMIDI_VolumeChange = FALSE; - Track->EMIDI_IncludeTrack = TRUE; - - memset(Track->context, 0, sizeof(Track->context)); - - while (Track->delay > 0) - { - _MIDI_AdvanceTick(); - Track->delay--; - } - - int IncludeFound = FALSE; - - while (Track->active) - { - int event; - - GET_NEXT_EVENT(Track, event); - - if (GET_MIDI_COMMAND(event) == MIDI_SPECIAL) - { - switch (event) - { - case MIDI_SYSEX: - case MIDI_SYSEX_CONTINUE: _MIDI_SysEx(Track); break; - case MIDI_META_EVENT: _MIDI_MetaEvent(Track); break; - } - - if (Track->active) - { - Track->delay = _MIDI_ReadDelta(Track); - while (Track->delay > 0) - { - _MIDI_AdvanceTick(); - Track->delay--; - } - } - - continue; - } - - if (event & MIDI_RUNNING_STATUS) - Track->RunningStatus = event; - else - { - event = Track->RunningStatus; - Track->pos--; - } - -// channel = GET_MIDI_CHANNEL(event); - int const command = GET_MIDI_COMMAND(event); - int length = _MIDI_CommandLengths[ command ]; - - if (command == MIDI_CONTROL_CHANGE) - { - if (*Track->pos == MIDI_MONO_MODE_ON) - length++; - - int c1, c2; - GET_NEXT_EVENT(Track, c1); - GET_NEXT_EVENT(Track, c2); - length -= 2; - - switch (c1) - { - case EMIDI_LOOP_START : - case EMIDI_SONG_LOOP_START : - Track->context[ 0 ].loopcount = (c2 == 0) ? EMIDI_INFINITE : c2; - Track->context[ 0 ].pos = Track->pos; - Track->context[ 0 ].loopstart = Track->pos; - Track->context[ 0 ].RunningStatus = Track->RunningStatus; - Track->context[ 0 ].time = _MIDI_Time; - Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; - Track->context[ 0 ].tick = _MIDI_Tick; - Track->context[ 0 ].beat = _MIDI_Beat; - Track->context[ 0 ].measure = _MIDI_Measure; - Track->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; - Track->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat; - Track->context[ 0 ].TimeBase = _MIDI_TimeBase; - break; - - case EMIDI_LOOP_END : - case EMIDI_SONG_LOOP_END : - if (c2 == EMIDI_END_LOOP_VALUE) - { - Track->context[ 0 ].loopstart = nullptr; - Track->context[ 0 ].loopcount = 0; - } - break; - - case EMIDI_INCLUDE_TRACK : - if (EMIDI_AffectsCurrentCard(c2, type)) - { - //printf( "Include track %d on card %d\n", tracknum, c2 ); - IncludeFound = TRUE; - Track->EMIDI_IncludeTrack = TRUE; - } - else if (!IncludeFound) - { - //printf( "Track excluded %d on card %d\n", tracknum, c2 ); - IncludeFound = TRUE; - Track->EMIDI_IncludeTrack = FALSE; - } - break; - - case EMIDI_EXCLUDE_TRACK : - if (EMIDI_AffectsCurrentCard(c2, type)) - { - //printf( "Exclude track %d on card %d\n", tracknum, c2 ); - Track->EMIDI_IncludeTrack = FALSE; - } - break; - - case EMIDI_PROGRAM_CHANGE : - if (!Track->EMIDI_ProgramChange) - //printf( "Program change on track %d\n", tracknum ); - Track->EMIDI_ProgramChange = TRUE; - break; - - case EMIDI_VOLUME_CHANGE : - if (!Track->EMIDI_VolumeChange) - //printf( "Volume change on track %d\n", tracknum ); - Track->EMIDI_VolumeChange = TRUE; - break; - - case EMIDI_CONTEXT_START : - if ((c2 > 0) && (c2 < EMIDI_NUM_CONTEXTS)) - { - Track->context[ c2 ].pos = Track->pos; - Track->context[ c2 ].loopstart = Track->context[ 0 ].loopstart; - Track->context[ c2 ].loopcount = Track->context[ 0 ].loopcount; - Track->context[ c2 ].RunningStatus = Track->RunningStatus; - Track->context[ c2 ].time = _MIDI_Time; - Track->context[ c2 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick; - Track->context[ c2 ].tick = _MIDI_Tick; - Track->context[ c2 ].beat = _MIDI_Beat; - Track->context[ c2 ].measure = _MIDI_Measure; - Track->context[ c2 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure; - Track->context[ c2 ].TicksPerBeat = _MIDI_TicksPerBeat; - Track->context[ c2 ].TimeBase = _MIDI_TimeBase; - } - break; - - case EMIDI_CONTEXT_END : - break; - } - } - - Track->pos += length; - Track->delay = _MIDI_ReadDelta(Track); - - while (Track->delay > 0) - { - _MIDI_AdvanceTick(); - Track->delay--; - } - } - - _MIDI_TotalTime = max(_MIDI_TotalTime, _MIDI_Time); - if (RELATIVE_BEAT(_MIDI_Measure, _MIDI_Beat, _MIDI_Tick) > - RELATIVE_BEAT(_MIDI_TotalMeasures, _MIDI_TotalBeats, _MIDI_TotalTicks)) - { - _MIDI_TotalTicks = _MIDI_Tick; - _MIDI_TotalBeats = _MIDI_Beat; - _MIDI_TotalMeasures = _MIDI_Measure; - } - - Track++; - tracknum++; - } - - _MIDI_ResetTracks(); -} - diff --git a/source/audiolib/src/midi.h b/source/audiolib/src/midi.h deleted file mode 100644 index fee2257f5..000000000 --- a/source/audiolib/src/midi.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -/********************************************************************** - module: MIDI.H - - author: James R. Dose - date: May 25, 1994 - - Public header for MIDI.C. Midi song file playback routines. - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#ifndef __MIDI_H -#define __MIDI_H - -#include "compat.h" -#include "midifuncs.h" - -enum MIDI_Errors -{ - MIDI_Warning = -2, - MIDI_Error = -1, - MIDI_Ok = 0, - MIDI_NullMidiModule, - MIDI_InvalidMidiFile, - MIDI_UnknownMidiFormat, - MIDI_NoTracks, - MIDI_InvalidTrack, - MIDI_NoMemory, - MIDI_DriverError -}; - - -#define MIDI_PASS_THROUGH 1 -#define MIDI_DONT_PLAY 0 - -#define MIDI_MaxVolume 255 - -int MIDI_AllNotesOff(void); -int MIDI_Reset(void); -int MIDI_SetVolume(int volume); -int MIDI_GetVolume(void); -void MIDI_SetMidiFuncs(midifuncs *funcs); -void MIDI_SetLoopFlag(int loopflag); -void MIDI_ContinueSong(void); -void MIDI_PauseSong(void); -void MIDI_StopSong(void); -int MIDI_PlaySong(char *song, int loopflag); -void MIDI_SetTempo(int tempo); -void MIDI_Restart(void); - -#endif diff --git a/source/audiolib/src/mix.cpp b/source/audiolib/src/mix.cpp deleted file mode 100644 index 331d5cd58..000000000 --- a/source/audiolib/src/mix.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -#include "_multivc.h" - -template uint32_t MV_MixMono(struct VoiceNode * const voice, uint32_t length); -template uint32_t MV_MixStereo(struct VoiceNode * const voice, uint32_t length); -template uint32_t MV_MixMono(struct VoiceNode * const voice, uint32_t length); -template uint32_t MV_MixStereo(struct VoiceNode * const voice, uint32_t length); -template void MV_Reverb(char const *src, char * const dest, const float volume, int count); - -/* - length = count of samples to mix - position = offset of starting sample in source - rate = resampling increment - volume = direct volume adjustment, 1.0 = no change - */ - -// mono source, mono output -template -uint32_t MV_MixMono(struct VoiceNode * const voice, uint32_t length) -{ - auto const source = (S const *)voice->sound; - auto dest = (D *)MV_MixDestination; - - uint32_t position = voice->position; - uint32_t const rate = voice->RateScale; - float const volume = voice->volume*MV_GlobalVolume; - - do - { - auto const isample0 = CONVERT_LE_SAMPLE_TO_SIGNED(source[position >> 16]); - - position += rate; - - *dest = MIX_SAMPLES(SCALE_SAMPLE(isample0, volume*voice->LeftVolume), *dest); - dest++; - - voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); - } - while (--length); - - MV_MixDestination = (char *)dest; - - return position; -} - -// mono source, stereo output -template -uint32_t MV_MixStereo(struct VoiceNode * const voice, uint32_t length) -{ - auto const source = (S const *)voice->sound; - auto dest = (D *)MV_MixDestination; - - uint32_t position = voice->position; - uint32_t const rate = voice->RateScale; - float const volume = voice->volume*MV_GlobalVolume; - - do - { - auto const isample0 = CONVERT_LE_SAMPLE_TO_SIGNED(source[position >> 16]); - - position += rate; - - *dest = MIX_SAMPLES(SCALE_SAMPLE(isample0, volume*voice->LeftVolume), *dest); - *(dest + (MV_RightChannelOffset / sizeof(*dest))) - = MIX_SAMPLES(SCALE_SAMPLE(isample0, volume*voice->RightVolume), *(dest + (MV_RightChannelOffset / sizeof(*dest)))); - dest += 2; - - voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); - voice->RightVolume = SMOOTH_VOLUME(voice->RightVolume, voice->RightVolumeDest); - } - while (--length); - - MV_MixDestination = (char *)dest; - - return position; -} - -template -void MV_Reverb(char const *src, char * const dest, const float volume, int count) -{ - auto input = (T const *)src; - auto output = (T *)dest; - - do - { - auto const isample0 = CONVERT_SAMPLE_TO_SIGNED(*input++); - *output++ = CONVERT_SAMPLE_FROM_SIGNED(SCALE_SAMPLE(isample0, volume)); - } - while (--count > 0); -} diff --git a/source/audiolib/src/mixst.cpp b/source/audiolib/src/mixst.cpp deleted file mode 100644 index 198989667..000000000 --- a/source/audiolib/src/mixst.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -#include "_multivc.h" - -template uint32_t MV_MixMonoStereo(struct VoiceNode * const voice, uint32_t length); -template uint32_t MV_MixStereoStereo(struct VoiceNode * const voice, uint32_t length); -template uint32_t MV_MixMonoStereo(struct VoiceNode * const voice, uint32_t length); -template uint32_t MV_MixStereoStereo(struct VoiceNode * const voice, uint32_t length); - -/* - length = count of samples to mix - position = offset of starting sample in source - rate = resampling increment - volume = direct volume adjustment, 1.0 = no change - */ - -// stereo source, mono output -template -uint32_t MV_MixMonoStereo(struct VoiceNode * const voice, uint32_t length) -{ - auto const source = (S const *)voice->sound; - auto dest = (D *)MV_MixDestination; - - uint32_t position = voice->position; - uint32_t const rate = voice->RateScale; - float const volume = voice->volume*MV_GlobalVolume; - - do - { - auto const isample0 = CONVERT_LE_SAMPLE_TO_SIGNED(source[(position >> 16) << 1]); - auto const isample1 = CONVERT_LE_SAMPLE_TO_SIGNED(source[((position >> 16) << 1) + 1]); - - position += rate; - - *dest = MIX_SAMPLES((SCALE_SAMPLE((isample0 + isample1) >> 1, volume*voice->LeftVolume)), *dest); - dest++; - - voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); - } - while (--length); - - MV_MixDestination = (char *)dest; - - return position; -} - -// stereo source, stereo output -template -uint32_t MV_MixStereoStereo(struct VoiceNode * const voice, uint32_t length) -{ - auto const source = (S const *)voice->sound; - auto dest = (D *)MV_MixDestination; - - uint32_t position = voice->position; - uint32_t const rate = voice->RateScale; - float const volume = voice->volume*MV_GlobalVolume; - - do - { - auto const isample0 = CONVERT_LE_SAMPLE_TO_SIGNED(source[(position >> 16) << 1]); - auto const isample1 = CONVERT_LE_SAMPLE_TO_SIGNED(source[((position >> 16) << 1) + 1]); - - position += rate; - - *dest = MIX_SAMPLES(SCALE_SAMPLE(isample0, volume*voice->LeftVolume), *dest); - *(dest + (MV_RightChannelOffset / sizeof(*dest))) - = MIX_SAMPLES(SCALE_SAMPLE(isample1, volume*voice->RightVolume), *(dest + (MV_RightChannelOffset / sizeof(*dest)))); - dest += 2; - - voice->LeftVolume = SMOOTH_VOLUME(voice->LeftVolume, voice->LeftVolumeDest); - voice->RightVolume = SMOOTH_VOLUME(voice->RightVolume, voice->RightVolumeDest); - } - while (--length); - - MV_MixDestination = (char *)dest; - - return position; -} diff --git a/source/audiolib/src/multivoc.cpp b/source/audiolib/src/multivoc.cpp deleted file mode 100644 index 7144d38ed..000000000 --- a/source/audiolib/src/multivoc.cpp +++ /dev/null @@ -1,885 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. -Copyright (C) 2015 EDuke32 developers -Copyright (C) 2015 Voidpoint, LLC - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -/********************************************************************** - module: MULTIVOC.C - - author: James R. Dose - date: December 20, 1993 - - Routines to provide multichannel digitized sound playback for - Sound Blaster compatible sound cards. - - (c) Copyright 1993 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#include "multivoc.h" - -#include "_multivc.h" -#include "baselayer.h" -#include "compat.h" -#include "drivers.h" -#include "fx_man.h" -#include "linklist.h" -#include "osd.h" -#include "pitch.h" -#include "pragmas.h" - -static void MV_StopVoice(VoiceNode *voice); -static void MV_ServiceVoc(void); - -static VoiceNode *MV_GetVoice(int handle); - -static int MV_ReverbLevel; -static int MV_ReverbDelay; -static float MV_ReverbVolume; - -Pan MV_PanTable[MV_NUMPANPOSITIONS][MV_MAXVOLUME + 1]; - -int MV_Installed; -static int MV_TotalVolume = MV_MAXTOTALVOLUME; -static int MV_MaxVoices = 1; - -int MV_BufferSize = MV_MIXBUFFERSIZE; -static int MV_BufferLength; - -static int MV_NumberOfBuffers = MV_NUMBEROFBUFFERS; - -static int MV_Channels = 1; - -static int MV_ReverseStereo; - -int MV_MixRate; - -static int MV_BufferEmpty[MV_NUMBEROFBUFFERS]; -char *MV_MixBuffer[(MV_NUMBEROFBUFFERS << 1) + 1]; - -static VoiceNode *MV_Voices; -static VoiceNode VoiceList; -static VoiceNode VoicePool; - -static int MV_MixPage; - -void (*MV_Printf)(const char *fmt, ...) = OSD_Printf; -static void (*MV_CallBackFunc)(intptr_t); - -char *MV_MixDestination; -int MV_SampleSize = 1; -int MV_RightChannelOffset; - -int MV_ErrorCode = MV_NotInstalled; - -float MV_GlobalVolume = 1.f; -float MV_VolumeSmooth = 1.f; - -int MV_Locked; - -char *MV_MusicBuffer; -static void (*MV_MusicCallback)(void); -static int MV_MixMusic = FALSE; - -static bool MV_Mix(VoiceNode * const voice, int const buffer) -{ - if (voice->length == 0 && voice->GetSound(voice) != KeepPlaying) - return false; - - float const gv = MV_GlobalVolume; - - if (voice->priority == FX_MUSIC_PRIORITY) - MV_GlobalVolume = 1.f; - - int length = MV_MIXBUFFERSIZE; - uint32_t bufsiz = voice->FixedPointBufferSize; - uint32_t const rate = voice->RateScale; - - MV_MixDestination = MV_MixBuffer[buffer]; - - // Add this voice to the mix - do - { - int mixlen = length; - uint32_t const position = voice->position; - uint32_t const voclen = voice->length; - - // Check if the last sample in this buffer would be - // beyond the length of the sample block - if ((position + bufsiz) >= voclen) - { - if (position >= voclen) - { - voice->GetSound(voice); - break; - } - - mixlen = (voclen - position + rate - voice->channels) / rate; - } - - voice->position = voice->mix(voice, mixlen); - length -= mixlen; - - if (voice->position >= voclen) - { - // Get the next block of sound - if (voice->GetSound(voice) == NoMoreData) - { - MV_GlobalVolume = gv; - return false; - } - - // Get the position of the last sample in the buffer - if (length > (voice->channels - 1)) - bufsiz = voice->RateScale * (length - voice->channels); - } - } while (length > 0); - - MV_GlobalVolume = gv; - return true; -} - -void MV_PlayVoice(VoiceNode *voice) -{ - MV_Lock(); - LL::SortedInsert(&VoiceList, voice, &VoiceNode::priority); - voice->LeftVolume = voice->LeftVolumeDest; - voice->RightVolume = voice->RightVolumeDest; - MV_Unlock(); -} - -static void MV_CleanupVoice(VoiceNode *voice) -{ - if (MV_CallBackFunc) - MV_CallBackFunc(voice->callbackval); - - switch (voice->wavetype) - { - case FMT_VORBIS: MV_ReleaseVorbisVoice(voice); break; - //case FMT_ZMUSIC: MV_ReleaseZMusicVoice(voice); break; - default: break; - } - - voice->handle = 0; -} - -static void MV_StopVoice(VoiceNode *voice) -{ - MV_CleanupVoice(voice); - MV_Lock(); - // move the voice from the play list to the free list - LL::Move(voice, &VoicePool); - MV_Unlock(); -} - -/*--------------------------------------------------------------------- - JBF: no synchronisation happens inside MV_ServiceVoc nor the - supporting functions it calls. This would cause a deadlock - between the mixer thread in the driver vs the nested - locking in the user-space functions of MultiVoc. The call - to MV_ServiceVoc is synchronised in the driver. ----------------------------------------------------------------------*/ -static void MV_ServiceVoc(void) -{ - // Toggle which buffer we'll mix next - ++MV_MixPage &= MV_NumberOfBuffers-1; - - if (MV_ReverbLevel == 0) - { - if (!MV_BufferEmpty[MV_MixPage]) - { - Bmemset(MV_MixBuffer[MV_MixPage], 0, MV_BufferSize); - MV_BufferEmpty[ MV_MixPage ] = TRUE; - } - } - else - { - char const *const end = MV_MixBuffer[0] + MV_BufferLength; - char * dest = MV_MixBuffer[MV_MixPage]; - char const * source = MV_MixBuffer[MV_MixPage] - MV_ReverbDelay; - - if (source < MV_MixBuffer[ 0 ]) - source += MV_BufferLength; - - int length = MV_BufferSize; - - do - { - int const count = (source + length > end) ? (end - source) : length; - - MV_Reverb(source, dest, MV_ReverbVolume, count >> 1); - - // if we go through the loop again, it means that we've wrapped around the buffer - source = MV_MixBuffer[ 0 ]; - dest += count; - length -= count; - } while (length > 0); - } - - if (VoiceList.next && VoiceList.next != &VoiceList) - { - VoiceNode *voice = VoiceList.next; - VoiceNode *next; - - do - { - next = voice->next; - - if (voice->Paused) - continue; - - MV_BufferEmpty[ MV_MixPage ] = FALSE; - - // Is this voice done? - if (!MV_Mix(voice, MV_MixPage)) - { - MV_CleanupVoice(voice); - LL::Move(voice, &VoicePool); - } - } - while ((voice = next) != &VoiceList); - } - - Bmemcpy(MV_MixBuffer[MV_MixPage+MV_NumberOfBuffers], MV_MixBuffer[MV_MixPage], MV_BufferSize); - - if (MV_MixMusic) - { - MV_MusicCallback(); - int16_t *source = (int16_t*)MV_MusicBuffer; - int16_t *dest = (int16_t*)MV_MixBuffer[MV_MixPage+MV_NumberOfBuffers]; - for (int32_t i = 0; i < MV_BufferSize>>2; i++) - { - int32_t sl = *source++; - int32_t sr = *source++; - *dest = clamp(*dest+sl,INT16_MIN, INT16_MAX); - dest++; - *dest = clamp(*dest+sr,INT16_MIN, INT16_MAX); - dest++; - } - } -} - -static VoiceNode *MV_GetVoice(int handle) -{ - if (handle < MV_MINVOICEHANDLE || handle > MV_MaxVoices) - { - //MV_Printf("MV_GetVoice(): bad handle (%d)!\n", handle); - return nullptr; - } - - MV_Lock(); - - for (VoiceNode *voice = VoiceList.next; voice != &VoiceList; voice = voice->next) - { - if (handle == voice->handle) - { - MV_Unlock(); - return voice; - } - } - - MV_Unlock(); - MV_SetErrorCode(MV_VoiceNotFound); - return nullptr; -} - -VoiceNode *MV_BeginService(int handle) -{ - if (!MV_Installed) - return nullptr; - - VoiceNode *voice = MV_GetVoice(handle); - - if (voice == nullptr) - { - MV_SetErrorCode(MV_VoiceNotFound); - return nullptr; - } - - MV_Lock(); - - return voice; -} - -static inline void MV_EndService(void) { MV_Unlock(); } - -int MV_VoicePlaying(int handle) -{ - return (MV_Installed && MV_GetVoice(handle)) ? TRUE : FALSE; -} - -int MV_KillAllVoices(void) -{ - if (!MV_Installed) - return MV_Error; - - MV_Lock(); - - if (&VoiceList == VoiceList.next) - { - MV_Unlock(); - return MV_Ok; - } - - VoiceNode * voice = VoiceList.prev; - - // Remove all the voices from the list - while (voice != &VoiceList) - { - if (voice->priority == MV_MUSIC_PRIORITY) - { - voice = voice->prev; - continue; - } - - MV_Kill(voice->handle); - voice = VoiceList.prev; - } - - MV_Unlock(); - - return MV_Ok; -} - -int MV_Kill(int handle) -{ - VoiceNode *voice = MV_BeginService(handle); - - if (voice == nullptr) - return MV_Error; - - MV_StopVoice(voice); - MV_EndService(); - - return MV_Ok; -} - -int MV_VoicesPlaying(void) -{ - if (!MV_Installed) - return 0; - - MV_Lock(); - - int NumVoices = 0; - - for (VoiceNode *voice = VoiceList.next; voice != &VoiceList; voice = voice->next) - NumVoices++; - - MV_Unlock(); - - return NumVoices; -} - -VoiceNode *MV_AllocVoice(int priority) -{ - VoiceNode *voice; - - MV_Lock(); - - // Check if we have any free voices - if (LL::Empty(&VoicePool)) - { - // check if we have a higher priority than a voice that is playing. - for (auto node = voice = VoiceList.next; node != &VoiceList; node = node->next) - { - if (node->priority < voice->priority) - voice = node; - } - - if (priority >= voice->priority && voice != &VoiceList && voice->handle >= MV_MINVOICEHANDLE) - MV_Kill(voice->handle); - - if (LL::Empty(&VoicePool)) - { - // No free voices - MV_Unlock(); - return nullptr; - } - } - - voice = VoicePool.next; - LL::Remove(voice); - MV_Unlock(); - - int vhan = MV_MINVOICEHANDLE; - - // Find a free voice handle - do - { - if (++vhan < MV_MINVOICEHANDLE || vhan > MV_MaxVoices) - vhan = MV_MINVOICEHANDLE; - } while (MV_VoicePlaying(vhan)); - - voice->handle = vhan; - - return voice; -} - -int MV_VoiceAvailable(int priority) -{ - // Check if we have any free voices - if (!LL::Empty(&VoicePool)) - return TRUE; - - MV_Lock(); - - VoiceNode *voice; - - // check if we have a higher priority than a voice that is playing. - for (auto node = voice = VoiceList.next; node != &VoiceList; node = node->next) - { - if (node->priority < voice->priority) - voice = node; - } - - if ((voice == &VoiceList) || (priority < voice->priority)) - { - MV_Unlock(); - return FALSE; - } - - MV_Unlock(); - return TRUE; -} - -void MV_SetVoicePitch(VoiceNode *voice, uint32_t rate, int pitchoffset) -{ - voice->SamplingRate = rate; - voice->PitchScale = PITCH_GetScale(pitchoffset); - voice->RateScale = divideu32(rate * voice->PitchScale, MV_MixRate); - - // Multiply by MV_MIXBUFFERSIZE - 1 - voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - - voice->RateScale; -} - -int MV_SetPitch(int handle, int pitchoffset) -{ - VoiceNode *voice = MV_BeginService(handle); - - if (voice == nullptr) - return MV_Error; - - MV_SetVoicePitch(voice, voice->SamplingRate, pitchoffset); - MV_EndService(); - - return MV_Ok; -} - -int MV_SetFrequency(int handle, int frequency) -{ - VoiceNode *voice = MV_BeginService(handle); - - if (voice == nullptr) - return MV_Error; - - MV_SetVoicePitch(voice, frequency, 0); - MV_EndService(); - - return MV_Ok; -} - -/*--------------------------------------------------------------------- - Function: MV_SetVoiceMixMode - - Selects which method should be used to mix the voice. - - 16Bit 16Bit | 8Bit 16Bit 8Bit 16Bit | - Mono Ster | Mono Mono Ster Ster | Mixer - Out Out | In In In In | -----------------------+---------------------------+------------- - X | X | MixMono - X | X | MixMono - X | X | MixStereo - X | X | MixStereo -----------------------+---------------------------+------------- - X | X | MixStereoStereo - X | X | MixStereoStereo - X | X | MixMonoStereo - X | X | MixMonoStereo ----------------------------------------------------------------------*/ - -void MV_SetVoiceMixMode(VoiceNode *voice) -{ - int type = T_DEFAULT; - - if (MV_Channels == 1) - type |= T_MONO; - - if (voice->bits == 16) - type |= T_16BITSOURCE; - - if (voice->channels == 2) - type |= T_STEREOSOURCE; - - // stereo look-up table - static constexpr decltype(voice->mix) mixslut[] - = { MV_MixStereo, MV_MixMono, MV_MixStereo, MV_MixMono, - MV_MixStereoStereo, MV_MixMonoStereo, MV_MixStereoStereo, MV_MixMonoStereo }; - - voice->mix = mixslut[type]; -} - -void MV_SetVoiceVolume(VoiceNode *voice, int vol, int left, int right, float volume) -{ - if (MV_Channels == 1) - left = right = vol; - else if (MV_ReverseStereo) - swap(&left, &right); - - voice->LeftVolumeDest = float(left)*(1.f/MV_MAXTOTALVOLUME); - voice->RightVolumeDest = float(right)*(1.f/MV_MAXTOTALVOLUME); - voice->volume = volume; - - MV_SetVoiceMixMode(voice); -} - -int MV_PauseVoice(int handle, int pause) -{ - VoiceNode *voice = MV_BeginService(handle); - - if (voice == nullptr) - return MV_Error; - - voice->Paused = pause; - MV_EndService(); - - return MV_Ok; -} - -int MV_EndLooping(int handle) -{ - VoiceNode *voice = MV_BeginService(handle); - - if (voice == nullptr) - return MV_Error; - - voice->LoopCount = 0; - voice->LoopStart = nullptr; - voice->LoopEnd = nullptr; - - MV_EndService(); - - return MV_Ok; -} - -int MV_SetPan(int handle, int vol, int left, int right) -{ - VoiceNode *voice = MV_BeginService(handle); - - if (voice == nullptr) - return MV_Error; - - MV_SetVoiceVolume(voice, vol, left, right, voice->volume); - MV_EndService(); - return MV_Ok; -} - -int MV_Pan3D(int handle, int angle, int distance) -{ - if (distance < 0) - { - distance = -distance; - angle += MV_NUMPANPOSITIONS / 2; - } - - int const volume = MIX_VOLUME(distance); - - angle &= MV_MAXPANPOSITION; - - return MV_SetPan(handle, max(0, 255 - distance), - MV_PanTable[ angle ][ volume ].left, - MV_PanTable[ angle ][ volume ].right); -} - -void MV_SetReverb(int reverb) -{ - MV_ReverbLevel = MIX_VOLUME(reverb); - MV_ReverbVolume = float(MV_ReverbLevel)*(1.f/MV_MAXVOLUME); -} - -int MV_GetMaxReverbDelay(void) { return MV_MIXBUFFERSIZE * MV_NumberOfBuffers; } -int MV_GetReverbDelay(void) { return tabledivide32(MV_ReverbDelay, MV_SampleSize); } - -void MV_SetReverbDelay(int delay) -{ - MV_ReverbDelay = max(MV_MIXBUFFERSIZE, min(delay, MV_GetMaxReverbDelay())) * MV_SampleSize; -} - -static int MV_SetMixMode(int numchannels) -{ - if (!MV_Installed) - return MV_Error; - - MV_Channels = 1 + (numchannels == 2); - MV_SampleSize = sizeof(int8_t) * MV_Channels * 2; - - MV_BufferSize = MV_MIXBUFFERSIZE * MV_SampleSize; - MV_NumberOfBuffers = tabledivide32(MV_TOTALBUFFERSIZE, MV_BufferSize); - Bassert(isPow2(MV_NumberOfBuffers)); - MV_BufferLength = MV_TOTALBUFFERSIZE; - - MV_RightChannelOffset = MV_SampleSize >> 1; - - return MV_Ok; -} - -static int MV_StartPlayback(void) -{ - // Initialize the buffers - Bmemset(MV_MixBuffer[0], 0, MV_TOTALBUFFERSIZE << 1); - - for (int buffer = 0; buffer < MV_NumberOfBuffers; buffer++) - MV_BufferEmpty[buffer] = TRUE; - - MV_MixPage = 1; - - if (SoundDriver_PCM_BeginPlayback(MV_MixBuffer[MV_NumberOfBuffers], MV_BufferSize, MV_NumberOfBuffers, MV_ServiceVoc) != MV_Ok) - return MV_SetErrorCode(MV_DriverError); - - return MV_Ok; -} - -static void MV_StopPlayback(void) -{ - SoundDriver_PCM_StopPlayback(); - - // Make sure all callbacks are done. - MV_Lock(); - - for (VoiceNode *voice = VoiceList.next, *next; voice != &VoiceList; voice = next) - { - next = voice->next; - MV_StopVoice(voice); - } - - MV_Unlock(); -} - -static void MV_CalcPanTable(void) -{ - const int HalfAngle = MV_NUMPANPOSITIONS / 2; - const int QuarterAngle = HalfAngle / 2; - - for (int distance = 0; distance <= MV_MAXVOLUME; distance++) - { - const int level = (255 * (MV_MAXVOLUME - distance)) / MV_MAXVOLUME; - - for (int angle = 0; angle <= QuarterAngle; angle++) - { - const int ramp = level - (level * angle) / QuarterAngle; - - MV_PanTable[angle][distance].left = ramp; - MV_PanTable[angle][distance].right = level; - - MV_PanTable[HalfAngle - angle][distance].left = ramp; - MV_PanTable[HalfAngle - angle][distance].right = level; - - MV_PanTable[HalfAngle + angle][distance].left = level; - MV_PanTable[HalfAngle + angle][distance].right = ramp; - - MV_PanTable[MV_MAXPANPOSITION - angle][distance].left = level; - MV_PanTable[MV_MAXPANPOSITION - angle][distance].right = ramp; - } - } -} - -void MV_SetVolume(int volume) -{ - MV_TotalVolume = min(max(0, volume), MV_MAXTOTALVOLUME); - MV_GlobalVolume = (float)volume / 255.f; - // MV_CalcVolume(MV_TotalVolume); -} - -int MV_GetVolume(void) { return MV_TotalVolume; } - -void MV_SetCallBack(void (*function)(intptr_t)) { MV_CallBackFunc = function; } - -void MV_SetReverseStereo(int setting) { MV_ReverseStereo = setting; } - -int MV_GetReverseStereo(void) { return MV_ReverseStereo; } - -int MV_Init(int soundcard, int MixRate, int Voices, int numchannels, void *initdata) -{ - if (MV_Installed) - MV_Shutdown(); - - MV_SetErrorCode(MV_Ok); - - // MV_TotalMemory + 2: FIXME, see valgrind_errors.log - int const totalmem = Voices * sizeof(VoiceNode) + (MV_TOTALBUFFERSIZE<<1) + (MV_MIXBUFFERSIZE<<2) + 2; - - char *ptr = (char *) Xaligned_alloc(16, totalmem); - - if (!ptr) - return MV_SetErrorCode(MV_NoMem); - - Bmemset(ptr, 0, totalmem); - - MV_Voices = (VoiceNode *)ptr; - ptr += Voices * sizeof(VoiceNode); - - MV_MaxVoices = Voices; - - LL::Reset((VoiceNode*) &VoiceList); - LL::Reset((VoiceNode*) &VoicePool); - - for (int index = 0; index < Voices; index++) - LL::Insert(&VoicePool, &MV_Voices[index]); - - MV_SetReverseStereo(FALSE); - - ASS_PCMSoundDriver = soundcard; - - // Initialize the sound card - - if (SoundDriver_PCM_Init(&MixRate, &numchannels, initdata) != MV_Ok) - MV_SetErrorCode(MV_DriverError); - - if (MV_ErrorCode != MV_Ok) - { - ALIGNED_FREE_AND_NULL(MV_Voices); - - return MV_Error; - } - - MV_Installed = TRUE; - MV_CallBackFunc = nullptr; - MV_ReverbLevel = 0; - MV_ReverbVolume = 0.f; - - // Set the sampling rate - MV_MixRate = MixRate; - - // Set Mixer to play stereo digitized sound - MV_SetMixMode(numchannels); - MV_ReverbDelay = MV_BufferSize * 3; - - // Make sure we don't cross a physical page - MV_MixBuffer[ MV_NumberOfBuffers<<1 ] = ptr; - for (int buffer = 0; buffer < MV_NumberOfBuffers<<1; buffer++) - { - MV_MixBuffer[ buffer ] = ptr; - ptr += MV_BufferSize; - } - - MV_MusicBuffer = ptr; - - // Calculate pan table - MV_CalcPanTable(); - - MV_VolumeSmooth = 1.f-powf(0.1f, 30.f/MixRate); - - // Start the playback engine - if (MV_StartPlayback() != MV_Ok) - { - // Preserve error code while we shutdown. - int status = MV_ErrorCode; - MV_Shutdown(); - return MV_SetErrorCode(status); - } - - return MV_Ok; -} - -int MV_Shutdown(void) -{ - if (!MV_Installed) - return MV_Ok; - - MV_KillAllVoices(); - - MV_Installed = FALSE; - - // Stop the sound playback engine - MV_StopPlayback(); - - // Shutdown the sound card - SoundDriver_PCM_Shutdown(); - - // Free any voices we allocated - ALIGNED_FREE_AND_NULL(MV_Voices); - - LL::Reset((VoiceNode*) &VoiceList); - LL::Reset((VoiceNode*) &VoicePool); - - MV_MaxVoices = 1; - - // Release the descriptor from our mix buffer - for (int buffer = 0; buffer < MV_NUMBEROFBUFFERS<<1; buffer++) - MV_MixBuffer[ buffer ] = nullptr; - - MV_SetErrorCode(MV_NotInstalled); - - return MV_Ok; -} - -void MV_HookMusicRoutine(void(*callback)(void)) -{ - MV_Lock(); - MV_MusicCallback = callback; - MV_MixMusic = TRUE; - MV_Unlock(); -} - -void MV_UnhookMusicRoutine(void) -{ - if (MV_MusicCallback) - { - MV_Lock(); - MV_MusicCallback = nullptr; - MV_MixMusic = FALSE; - MV_Unlock(); - } -} - -MV_MusicRoutineBuffer MV_GetMusicRoutineBuffer() -{ - return MV_MusicRoutineBuffer{ MV_MusicBuffer, MV_BufferSize }; -} - -const char *loopStartTags[loopStartTagCount] = { "LOOP_START", "LOOPSTART", "LOOP" }; -const char *loopEndTags[loopEndTagCount] = { "LOOP_END", "LOOPEND" }; -const char *loopLengthTags[loopLengthTagCount] = { "LOOP_LENGTH", "LOOPLENGTH" }; - -const char *MV_ErrorString(int ErrorNumber) -{ - switch (ErrorNumber) - { - case MV_Error: - return MV_ErrorString(MV_ErrorCode); - case MV_Ok: - return "Multivoc ok."; - case MV_NotInstalled: - return "Multivoc not installed."; - case MV_DriverError: - return SoundDriver_PCM_ErrorString(SoundDriver_PCM_GetError()); - case MV_NoVoices: - return "No free voices available to Multivoc."; - case MV_NoMem: - return "Out of memory in Multivoc."; - case MV_VoiceNotFound: - return "No voice with matching handle found."; - case MV_InvalidFile: - return "Invalid file passed in to Multivoc."; - default: - return "Unknown Multivoc error code."; - } -} - diff --git a/source/audiolib/src/music.cpp b/source/audiolib/src/music.cpp deleted file mode 100644 index c0c4f03f2..000000000 --- a/source/audiolib/src/music.cpp +++ /dev/null @@ -1,147 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2010-2019 EDuke32 developers and contributors -Copyright (C) 2019 Nuke.YKT - -This file is part of NBlood. - -NBlood is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- - -#include "music.h" - -#include "compat.h" -#include "drivers.h" -#include "midi.h" -#include "multivoc.h" -#include "sndcards.h" - -int MUSIC_ErrorCode = MUSIC_Ok; - -static midifuncs MUSIC_MidiFunctions; - -#define MUSIC_SetErrorCode(status) MUSIC_ErrorCode = (status); - -const char *MUSIC_ErrorString(int ErrorNumber) -{ - const char *ErrorString; - - switch (ErrorNumber) - { - case MUSIC_Warning: - case MUSIC_Error: ErrorString = MUSIC_ErrorString(MUSIC_ErrorCode); break; - case MUSIC_Ok: ErrorString = "Music ok."; break; - case MUSIC_MidiError: ErrorString = "Error playing MIDI file."; break; - default: ErrorString = "Unknown Music error code."; break; - } - - return ErrorString; -} - - -int MUSIC_Init(int SoundCard) -{ - int detected = 0; - - if (SoundCard == ASS_AutoDetect) - { -redetect: - detected++; - SoundCard = ASS_OPL3; - } - - if (SoundCard < 0 || SoundCard >= ASS_NumSoundCards) - { -failed: - MV_Printf("failed!\n"); - MUSIC_ErrorCode = MUSIC_MidiError; - return MUSIC_Error; - } - - if (!SoundDriver_IsMIDISupported(SoundCard)) - { - MV_Printf("Couldn't init %s\n", SoundDriver_GetName(SoundCard)); - - if (detected < 2) - goto redetect; - - goto failed; - } - - ASS_MIDISoundDriver = SoundCard; - - int status = SoundDriver_MIDI_Init(&MUSIC_MidiFunctions); - - if (status != MUSIC_Ok) - { - if (detected < 2) - goto redetect; - - goto failed; - } - - MV_Printf("%s\n", SoundDriver_GetName(SoundCard)); - - MIDI_SetMidiFuncs(&MUSIC_MidiFunctions); - - return MUSIC_Ok; -} - - -int MUSIC_Shutdown(void) -{ - MIDI_StopSong(); - - return MUSIC_Ok; -} - - -void MUSIC_SetVolume(int volume) { MIDI_SetVolume(min(max(0, volume), 255)); } - - -int MUSIC_GetVolume(void) { return MIDI_GetVolume(); } -void MUSIC_SetLoopFlag(int loopflag) { MIDI_SetLoopFlag(loopflag); } -void MUSIC_Continue(void) { MIDI_ContinueSong(); } -void MUSIC_Pause(void) { MIDI_PauseSong(); } - -int MUSIC_StopSong(void) -{ - MIDI_StopSong(); - MUSIC_SetErrorCode(MUSIC_Ok); - return MUSIC_Ok; -} - - -int MUSIC_PlaySong(char *song, int songsize, int loopflag, const char *fn /*= nullptr*/) -{ - UNREFERENCED_PARAMETER(songsize); - UNREFERENCED_PARAMETER(fn); - - MUSIC_SetErrorCode(MUSIC_Ok) - - if (MIDI_PlaySong(song, loopflag) != MIDI_Ok) - { - MUSIC_SetErrorCode(MUSIC_MidiError); - return MUSIC_Warning; - } - - return MUSIC_Ok; -} - - -void MUSIC_Update(void) -{ -} diff --git a/source/audiolib/src/opl3.cpp b/source/audiolib/src/opl3.cpp deleted file mode 100644 index 0efea236c..000000000 --- a/source/audiolib/src/opl3.cpp +++ /dev/null @@ -1,1398 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 2013-2019 Nuke.YKT - -This file is part of NBlood. - -NBlood is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 2 -as published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ -//------------------------------------------------------------------------- -// -// Nuked OPL3 emulator. -// Thanks: -// MAME Development Team(Jarek Burczynski, Tatsuyuki Satoh): -// Feedback and Rhythm part calculation information. -// forums.submarine.org.uk(carbon14, opl3): -// Tremolo and phase generator calculation information. -// OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): -// OPL2 ROMs. -// siliconpr0n.org(John McMaster, digshadow): -// YMF262 and VRC VII decaps and die shots. -// -// version: 1.8, with stereo extension -// - -#include -#include -#include -#define _USE_MATH_DEFINES -#include -#include "opl3.h" - -#define RSM_FRAC 10 - -// Channel types - -enum { - ch_2op = 0, - ch_4op = 1, - ch_4op2 = 2, - ch_drum = 3 -}; - -// Envelope key types - -enum { - egk_norm = 0x01, - egk_drum = 0x02 -}; - - -// -// logsin table -// - -static const Bit16u logsinrom[256] = { - 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, - 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365, - 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, - 0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261, - 0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f, - 0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd, - 0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195, - 0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166, - 0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c, - 0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118, - 0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8, - 0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db, - 0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1, - 0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9, - 0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094, - 0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081, - 0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070, - 0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060, - 0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052, - 0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045, - 0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039, - 0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f, - 0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026, - 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e, - 0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017, - 0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011, - 0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c, - 0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007, - 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004, - 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002, - 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 -}; - -// -// exp table -// - -static const Bit16u exprom[256] = { - 0x7fa, 0x7f5, 0x7ef, 0x7ea, 0x7e4, 0x7df, 0x7da, 0x7d4, - 0x7cf, 0x7c9, 0x7c4, 0x7bf, 0x7b9, 0x7b4, 0x7ae, 0x7a9, - 0x7a4, 0x79f, 0x799, 0x794, 0x78f, 0x78a, 0x784, 0x77f, - 0x77a, 0x775, 0x770, 0x76a, 0x765, 0x760, 0x75b, 0x756, - 0x751, 0x74c, 0x747, 0x742, 0x73d, 0x738, 0x733, 0x72e, - 0x729, 0x724, 0x71f, 0x71a, 0x715, 0x710, 0x70b, 0x706, - 0x702, 0x6fd, 0x6f8, 0x6f3, 0x6ee, 0x6e9, 0x6e5, 0x6e0, - 0x6db, 0x6d6, 0x6d2, 0x6cd, 0x6c8, 0x6c4, 0x6bf, 0x6ba, - 0x6b5, 0x6b1, 0x6ac, 0x6a8, 0x6a3, 0x69e, 0x69a, 0x695, - 0x691, 0x68c, 0x688, 0x683, 0x67f, 0x67a, 0x676, 0x671, - 0x66d, 0x668, 0x664, 0x65f, 0x65b, 0x657, 0x652, 0x64e, - 0x649, 0x645, 0x641, 0x63c, 0x638, 0x634, 0x630, 0x62b, - 0x627, 0x623, 0x61e, 0x61a, 0x616, 0x612, 0x60e, 0x609, - 0x605, 0x601, 0x5fd, 0x5f9, 0x5f5, 0x5f0, 0x5ec, 0x5e8, - 0x5e4, 0x5e0, 0x5dc, 0x5d8, 0x5d4, 0x5d0, 0x5cc, 0x5c8, - 0x5c4, 0x5c0, 0x5bc, 0x5b8, 0x5b4, 0x5b0, 0x5ac, 0x5a8, - 0x5a4, 0x5a0, 0x59c, 0x599, 0x595, 0x591, 0x58d, 0x589, - 0x585, 0x581, 0x57e, 0x57a, 0x576, 0x572, 0x56f, 0x56b, - 0x567, 0x563, 0x560, 0x55c, 0x558, 0x554, 0x551, 0x54d, - 0x549, 0x546, 0x542, 0x53e, 0x53b, 0x537, 0x534, 0x530, - 0x52c, 0x529, 0x525, 0x522, 0x51e, 0x51b, 0x517, 0x514, - 0x510, 0x50c, 0x509, 0x506, 0x502, 0x4ff, 0x4fb, 0x4f8, - 0x4f4, 0x4f1, 0x4ed, 0x4ea, 0x4e7, 0x4e3, 0x4e0, 0x4dc, - 0x4d9, 0x4d6, 0x4d2, 0x4cf, 0x4cc, 0x4c8, 0x4c5, 0x4c2, - 0x4be, 0x4bb, 0x4b8, 0x4b5, 0x4b1, 0x4ae, 0x4ab, 0x4a8, - 0x4a4, 0x4a1, 0x49e, 0x49b, 0x498, 0x494, 0x491, 0x48e, - 0x48b, 0x488, 0x485, 0x482, 0x47e, 0x47b, 0x478, 0x475, - 0x472, 0x46f, 0x46c, 0x469, 0x466, 0x463, 0x460, 0x45d, - 0x45a, 0x457, 0x454, 0x451, 0x44e, 0x44b, 0x448, 0x445, - 0x442, 0x43f, 0x43c, 0x439, 0x436, 0x433, 0x430, 0x42d, - 0x42a, 0x428, 0x425, 0x422, 0x41f, 0x41c, 0x419, 0x416, - 0x414, 0x411, 0x40e, 0x40b, 0x408, 0x406, 0x403, 0x400 -}; - -// -// freq mult table multiplied by 2 -// -// 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15 -// - -static const Bit8u mt[16] = { - 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 -}; - -// -// ksl table -// - -static const Bit8u kslrom[16] = { - 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 -}; - -static const Bit8u kslshift[4] = { - 8, 1, 2, 0 -}; - -// -// envelope generator constants -// - -static const Bit8u eg_incstep[4][4] = { - { 0, 0, 0, 0 }, - { 1, 0, 0, 0 }, - { 1, 0, 1, 0 }, - { 1, 1, 1, 0 } -}; - -// -// address decoding -// - -static const Bit8s ad_slot[0x20] = { - 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, - 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -}; - -static const Bit8u ch_slot[18] = { - 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32 -}; - -static Bit32s panpot_lut[256]; -static Bit8u panpot_lut_build = 0; - -// -// Envelope generator -// - -typedef Bit16s(*envelope_sinfunc)(Bit16u phase, Bit16u envelope); -typedef void(*envelope_genfunc)(opl3_slot *slott); - -static Bit16s OPL3_EnvelopeCalcExp(Bit32u level) -{ - if (level > 0x1fff) - { - level = 0x1fff; - } - return (exprom[level & 0xff] << 1) >> (level >> 8); -} - -static Bit16s OPL3_EnvelopeCalcSin0(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - Bit16u neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = 0xffff; - } - if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; -} - -static Bit16s OPL3_EnvelopeCalcSin1(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static Bit16s OPL3_EnvelopeCalcSin2(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static Bit16s OPL3_EnvelopeCalcSin3(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x100) - { - out = 0x1000; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static Bit16s OPL3_EnvelopeCalcSin4(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - Bit16u neg = 0; - phase &= 0x3ff; - if ((phase & 0x300) == 0x100) - { - neg = 0xffff; - } - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x80) - { - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; - } - else - { - out = logsinrom[(phase << 1) & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; -} - -static Bit16s OPL3_EnvelopeCalcSin5(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x80) - { - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; - } - else - { - out = logsinrom[(phase << 1) & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); -} - -static Bit16s OPL3_EnvelopeCalcSin6(Bit16u phase, Bit16u envelope) -{ - Bit16u neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = 0xffff; - } - return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg; -} - -static Bit16s OPL3_EnvelopeCalcSin7(Bit16u phase, Bit16u envelope) -{ - Bit16u out = 0; - Bit16u neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = 0xffff; - phase = (phase & 0x1ff) ^ 0x1ff; - } - out = phase << 3; - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; -} - -static const envelope_sinfunc envelope_sin[8] = { - OPL3_EnvelopeCalcSin0, - OPL3_EnvelopeCalcSin1, - OPL3_EnvelopeCalcSin2, - OPL3_EnvelopeCalcSin3, - OPL3_EnvelopeCalcSin4, - OPL3_EnvelopeCalcSin5, - OPL3_EnvelopeCalcSin6, - OPL3_EnvelopeCalcSin7 -}; - -enum envelope_gen_num -{ - envelope_gen_num_attack = 0, - envelope_gen_num_decay = 1, - envelope_gen_num_sustain = 2, - envelope_gen_num_release = 3 -}; - -static void OPL3_EnvelopeUpdateKSL(opl3_slot *slot) -{ - Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 2) - - ((0x08 - slot->channel->block) << 5); - if (ksl < 0) - { - ksl = 0; - } - slot->eg_ksl = (Bit8u)ksl; -} - -static void OPL3_EnvelopeCalc(opl3_slot *slot) -{ - Bit8u nonzero; - Bit8u rate; - Bit8u rate_hi; - Bit8u rate_lo; - Bit8u reg_rate = 0; - Bit8u ks; - Bit8u eg_shift, shift; - Bit16u eg_rout; - Bit16s eg_inc; - Bit8u eg_off; - Bit8u reset = 0; - slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) - + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; - if (slot->key && slot->eg_gen == envelope_gen_num_release) - { - reset = 1; - reg_rate = slot->reg_ar; - } - else - { - switch (slot->eg_gen) - { - case envelope_gen_num_attack: - reg_rate = slot->reg_ar; - break; - case envelope_gen_num_decay: - reg_rate = slot->reg_dr; - break; - case envelope_gen_num_sustain: - if (!slot->reg_type) - { - reg_rate = slot->reg_rr; - } - break; - case envelope_gen_num_release: - reg_rate = slot->reg_rr; - break; - } - } - slot->pg_reset = reset; - ks = slot->channel->ksv >> ((slot->reg_ksr ^ 1) << 1); - nonzero = (reg_rate != 0); - rate = ks + (reg_rate << 2); - rate_hi = rate >> 2; - rate_lo = rate & 0x03; - if (rate_hi & 0x10) - { - rate_hi = 0x0f; - } - eg_shift = rate_hi + slot->chip->eg_add; - shift = 0; - if (nonzero) - { - if (rate_hi < 12) - { - if (slot->chip->eg_state) - { - switch (eg_shift) - { - case 12: - shift = 1; - break; - case 13: - shift = (rate_lo >> 1) & 0x01; - break; - case 14: - shift = rate_lo & 0x01; - break; - default: - break; - } - } - } - else - { - shift = (rate_hi & 0x03) + eg_incstep[rate_lo][slot->chip->timer & 0x03]; - if (shift & 0x04) - { - shift = 0x03; - } - if (!shift) - { - shift = slot->chip->eg_state; - } - } - } - eg_rout = slot->eg_rout; - eg_inc = 0; - eg_off = 0; - // Instant attack - if (reset && rate_hi == 0x0f) - { - eg_rout = 0x00; - } - // Envelope off - if ((slot->eg_rout & 0x1f8) == 0x1f8) - { - eg_off = 1; - } - if (slot->eg_gen != envelope_gen_num_attack && !reset && eg_off) - { - eg_rout = 0x1ff; - } - switch (slot->eg_gen) - { - case envelope_gen_num_attack: - if (!slot->eg_rout) - { - slot->eg_gen = envelope_gen_num_decay; - } - else if (slot->key && shift > 0 && rate_hi != 0x0f) - { - eg_inc = ((~slot->eg_rout) << shift) >> 4; - } - break; - case envelope_gen_num_decay: - if ((slot->eg_rout >> 4) == slot->reg_sl) - { - slot->eg_gen = envelope_gen_num_sustain; - } - else if (!eg_off && !reset && shift > 0) - { - eg_inc = 1 << (shift - 1); - } - break; - case envelope_gen_num_sustain: - case envelope_gen_num_release: - if (!eg_off && !reset && shift > 0) - { - eg_inc = 1 << (shift - 1); - } - break; - } - slot->eg_rout = (eg_rout + eg_inc) & 0x1ff; - // Key off - if (reset) - { - slot->eg_gen = envelope_gen_num_attack; - } - if (!slot->key) - { - slot->eg_gen = envelope_gen_num_release; - } -} - -static void OPL3_EnvelopeKeyOn(opl3_slot *slot, Bit8u type) -{ - slot->key |= type; -} - -static void OPL3_EnvelopeKeyOff(opl3_slot *slot, Bit8u type) -{ - slot->key &= ~type; -} - -// -// Phase Generator -// - -static void OPL3_PhaseGenerate(opl3_slot *slot) -{ - opl3_chip *chip; - Bit16u f_num; - Bit32u basefreq; - Bit8u rm_xor, n_bit; - Bit32u noise; - Bit16u phase; - - chip = slot->chip; - f_num = slot->channel->f_num; - if (slot->reg_vib) - { - Bit8s range; - Bit8u vibpos; - - range = (f_num >> 7) & 7; - vibpos = slot->chip->vibpos; - - if (!(vibpos & 3)) - { - range = 0; - } - else if (vibpos & 1) - { - range >>= 1; - } - range >>= slot->chip->vibshift; - - if (vibpos & 4) - { - range = -range; - } - f_num += range; - } - basefreq = (f_num << slot->channel->block) >> 1; - phase = (Bit16u)(slot->pg_phase >> 9); - if (slot->pg_reset) - { - slot->pg_phase = 0; - } - slot->pg_phase += (basefreq * mt[slot->reg_mult]) >> 1; - // Rhythm mode - noise = chip->noise; - slot->pg_phase_out = phase; - if (slot->slot_num == 13) // hh - { - chip->rm_hh_bit2 = (phase >> 2) & 1; - chip->rm_hh_bit3 = (phase >> 3) & 1; - chip->rm_hh_bit7 = (phase >> 7) & 1; - chip->rm_hh_bit8 = (phase >> 8) & 1; - } - if (slot->slot_num == 17 && (chip->rhy & 0x20)) // tc - { - chip->rm_tc_bit3 = (phase >> 3) & 1; - chip->rm_tc_bit5 = (phase >> 5) & 1; - } - if (chip->rhy & 0x20) - { - rm_xor = (chip->rm_hh_bit2 ^ chip->rm_hh_bit7) - | (chip->rm_hh_bit3 ^ chip->rm_tc_bit5) - | (chip->rm_tc_bit3 ^ chip->rm_tc_bit5); - switch (slot->slot_num) - { - case 13: // hh - slot->pg_phase_out = rm_xor << 9; - if (rm_xor ^ (noise & 1)) - { - slot->pg_phase_out |= 0xd0; - } - else - { - slot->pg_phase_out |= 0x34; - } - break; - case 16: // sd - slot->pg_phase_out = (chip->rm_hh_bit8 << 9) - | ((chip->rm_hh_bit8 ^ (noise & 1)) << 8); - break; - case 17: // tc - slot->pg_phase_out = (rm_xor << 9) | 0x80; - break; - default: - break; - } - } - n_bit = ((noise >> 14) ^ noise) & 0x01; - chip->noise = (noise >> 1) | (n_bit << 22); -} - -// -// Slot -// - -static void OPL3_SlotWrite20(opl3_slot *slot, Bit8u data) -{ - if ((data >> 7) & 0x01) - { - slot->trem = &slot->chip->tremolo; - } - else - { - slot->trem = (Bit8u*)&slot->chip->zeromod; - } - slot->reg_vib = (data >> 6) & 0x01; - slot->reg_type = (data >> 5) & 0x01; - slot->reg_ksr = (data >> 4) & 0x01; - slot->reg_mult = data & 0x0f; -} - -static void OPL3_SlotWrite40(opl3_slot *slot, Bit8u data) -{ - slot->reg_ksl = (data >> 6) & 0x03; - slot->reg_tl = data & 0x3f; - OPL3_EnvelopeUpdateKSL(slot); -} - -static void OPL3_SlotWrite60(opl3_slot *slot, Bit8u data) -{ - slot->reg_ar = (data >> 4) & 0x0f; - slot->reg_dr = data & 0x0f; -} - -static void OPL3_SlotWrite80(opl3_slot *slot, Bit8u data) -{ - slot->reg_sl = (data >> 4) & 0x0f; - if (slot->reg_sl == 0x0f) - { - slot->reg_sl = 0x1f; - } - slot->reg_rr = data & 0x0f; -} - -static void OPL3_SlotWriteE0(opl3_slot *slot, Bit8u data) -{ - slot->reg_wf = data & 0x07; - if (slot->chip->newm == 0x00) - { - slot->reg_wf &= 0x03; - } -} - -static void OPL3_SlotGenerate(opl3_slot *slot) -{ - slot->out = envelope_sin[slot->reg_wf](slot->pg_phase_out + *slot->mod, slot->eg_out); -} - -static void OPL3_SlotCalcFB(opl3_slot *slot) -{ - if (slot->channel->fb != 0x00) - { - slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb); - } - else - { - slot->fbmod = 0; - } - slot->prout = slot->out; -} - -// -// Channel -// - -static void OPL3_ChannelSetupAlg(opl3_channel *channel); - -static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) -{ - opl3_channel *channel6; - opl3_channel *channel7; - opl3_channel *channel8; - Bit8u chnum; - - chip->rhy = data & 0x3f; - if (chip->rhy & 0x20) - { - channel6 = &chip->channel[6]; - channel7 = &chip->channel[7]; - channel8 = &chip->channel[8]; - channel6->out[0] = &channel6->slots[1]->out; - channel6->out[1] = &channel6->slots[1]->out; - channel6->out[2] = &chip->zeromod; - channel6->out[3] = &chip->zeromod; - channel7->out[0] = &channel7->slots[0]->out; - channel7->out[1] = &channel7->slots[0]->out; - channel7->out[2] = &channel7->slots[1]->out; - channel7->out[3] = &channel7->slots[1]->out; - channel8->out[0] = &channel8->slots[0]->out; - channel8->out[1] = &channel8->slots[0]->out; - channel8->out[2] = &channel8->slots[1]->out; - channel8->out[3] = &channel8->slots[1]->out; - for (chnum = 6; chnum < 9; chnum++) - { - chip->channel[chnum].chtype = ch_drum; - } - OPL3_ChannelSetupAlg(channel6); - OPL3_ChannelSetupAlg(channel7); - OPL3_ChannelSetupAlg(channel8); - //hh - if (chip->rhy & 0x01) - { - OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum); - } - //tc - if (chip->rhy & 0x02) - { - OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum); - } - //tom - if (chip->rhy & 0x04) - { - OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum); - } - //sd - if (chip->rhy & 0x08) - { - OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum); - } - //bd - if (chip->rhy & 0x10) - { - OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum); - OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum); - } - else - { - OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum); - OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum); - } - } - else - { - for (chnum = 6; chnum < 9; chnum++) - { - chip->channel[chnum].chtype = ch_2op; - OPL3_ChannelSetupAlg(&chip->channel[chnum]); - OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[0], egk_drum); - OPL3_EnvelopeKeyOff(chip->channel[chnum].slots[1], egk_drum); - } - } -} - -static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data) -{ - if (channel->chip->newm && channel->chtype == ch_4op2) - { - return; - } - channel->f_num = (channel->f_num & 0x300) | data; - channel->ksv = (channel->block << 1) - | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->slots[1]); - if (channel->chip->newm && channel->chtype == ch_4op) - { - channel->pair->f_num = channel->f_num; - channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); - } -} - -static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data) -{ - if (channel->chip->newm && channel->chtype == ch_4op2) - { - return; - } - channel->f_num = (channel->f_num & 0xff) | ((data & 0x03) << 8); - channel->block = (data >> 2) & 0x07; - channel->ksv = (channel->block << 1) - | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->slots[1]); - if (channel->chip->newm && channel->chtype == ch_4op) - { - channel->pair->f_num = channel->f_num; - channel->pair->block = channel->block; - channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); - } -} - -static void OPL3_ChannelSetupAlg(opl3_channel *channel) -{ - if (channel->chtype == ch_drum) - { - if (channel->ch_num == 7 || channel->ch_num == 8) - { - channel->slots[0]->mod = &channel->chip->zeromod; - channel->slots[1]->mod = &channel->chip->zeromod; - return; - } - switch (channel->alg & 0x01) - { - case 0x00: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->slots[0]->out; - break; - case 0x01: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->chip->zeromod; - break; - } - return; - } - if (channel->alg & 0x08) - { - return; - } - if (channel->alg & 0x04) - { - channel->pair->out[0] = &channel->chip->zeromod; - channel->pair->out[1] = &channel->chip->zeromod; - channel->pair->out[2] = &channel->chip->zeromod; - channel->pair->out[3] = &channel->chip->zeromod; - switch (channel->alg & 0x03) - { - case 0x00: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; - channel->out[1] = &channel->chip->zeromod; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x01: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->chip->zeromod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[1]->out; - channel->out[1] = &channel->slots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x02: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x03: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[0]->out; - channel->out[2] = &channel->slots[1]->out; - channel->out[3] = &channel->chip->zeromod; - break; - } - } - else - { - switch (channel->alg & 0x01) - { - case 0x00: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; - channel->out[1] = &channel->chip->zeromod; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x01: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - } - } -} - -static void OPL3_ChannelWriteC0(opl3_channel *channel, Bit8u data) -{ - channel->fb = (data & 0x0e) >> 1; - channel->con = data & 0x01; - channel->alg = channel->con; - if (channel->chip->newm) - { - if (channel->chtype == ch_4op) - { - channel->pair->alg = 0x04 | (channel->con << 1) | (channel->pair->con); - channel->alg = 0x08; - OPL3_ChannelSetupAlg(channel->pair); - } - else if (channel->chtype == ch_4op2) - { - channel->alg = 0x04 | (channel->pair->con << 1) | (channel->con); - channel->pair->alg = 0x08; - OPL3_ChannelSetupAlg(channel); - } - else - { - OPL3_ChannelSetupAlg(channel); - } - } - else - { - OPL3_ChannelSetupAlg(channel); - } - if (channel->chip->newm) - { - channel->cha = ((data >> 4) & 0x01) ? ~0 : 0; - channel->chb = ((data >> 5) & 0x01) ? ~0 : 0; - } - else - { - channel->cha = channel->chb = (Bit16u)~0; - } - if (!channel->chip->stereoext) - { - channel->leftpan = channel->cha << 16; - channel->rightpan = channel->chb << 16; - } -} - -static void OPL3_ChannelWriteD0(opl3_channel* channel, Bit8u data) -{ - if (channel->chip->stereoext) - { - channel->leftpan = panpot_lut[data ^ 0xff]; - channel->rightpan = panpot_lut[data]; - } -} - -static void OPL3_ChannelKeyOn(opl3_channel *channel) -{ - if (channel->chip->newm) - { - if (channel->chtype == ch_4op) - { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm); - } - else if (channel->chtype == ch_2op || channel->chtype == ch_drum) - { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); - } - } - else - { - OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); - } -} - -static void OPL3_ChannelKeyOff(opl3_channel *channel) -{ - if (channel->chip->newm) - { - if (channel->chtype == ch_4op) - { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm); - } - else if (channel->chtype == ch_2op || channel->chtype == ch_drum) - { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); - } - } - else - { - OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); - OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); - } -} - -static void OPL3_ChannelSet4Op(opl3_chip *chip, Bit8u data) -{ - Bit8u bit; - Bit8u chnum; - for (bit = 0; bit < 6; bit++) - { - chnum = bit; - if (bit >= 3) - { - chnum += 9 - 3; - } - if ((data >> bit) & 0x01) - { - chip->channel[chnum].chtype = ch_4op; - chip->channel[chnum + 3].chtype = ch_4op2; - } - else - { - chip->channel[chnum].chtype = ch_2op; - chip->channel[chnum + 3].chtype = ch_2op; - } - } -} - -static Bit16s OPL3_ClipSample(Bit32s sample) -{ - if (sample > 32767) - { - sample = 32767; - } - else if (sample < -32768) - { - sample = -32768; - } - return (Bit16s)sample; -} - -void OPL3_Generate(opl3_chip *chip, Bit16s *buf) -{ - Bit8u ii; - Bit8u jj; - Bit16s accm; - Bit8u shift = 0; - - buf[1] = OPL3_ClipSample(chip->mixbuff[1]); - - for (ii = 0; ii < 36; ii++) - { - OPL3_SlotCalcFB(&chip->slot[ii]); - OPL3_EnvelopeCalc(&chip->slot[ii]); - OPL3_PhaseGenerate(&chip->slot[ii]); - OPL3_SlotGenerate(&chip->slot[ii]); - } - - chip->mixbuff[0] = 0; - for (ii = 0; ii < 18; ii++) - { - accm = 0; - for (jj = 0; jj < 4; jj++) - { - accm += *chip->channel[ii].out[jj]; - } - chip->mixbuff[0] += (Bit16s)((accm * chip->channel[ii].leftpan) >> 16); - } - - buf[0] = OPL3_ClipSample(chip->mixbuff[0]); - - chip->mixbuff[1] = 0; - for (ii = 0; ii < 18; ii++) - { - accm = 0; - for (jj = 0; jj < 4; jj++) - { - accm += *chip->channel[ii].out[jj]; - } - chip->mixbuff[1] += (Bit16s)((accm * chip->channel[ii].rightpan) >> 16); - } - - if ((chip->timer & 0x3f) == 0x3f) - { - chip->tremolopos = (chip->tremolopos + 1) % 210; - } - if (chip->tremolopos < 105) - { - chip->tremolo = chip->tremolopos >> chip->tremoloshift; - } - else - { - chip->tremolo = (210 - chip->tremolopos) >> chip->tremoloshift; - } - - if ((chip->timer & 0x3ff) == 0x3ff) - { - chip->vibpos = (chip->vibpos + 1) & 7; - } - - chip->timer++; - - chip->eg_add = 0; - if (chip->eg_timer) - { - while (shift < 36 && ((chip->eg_timer >> shift) & 1) == 0) - { - shift++; - } - if (shift > 12) - { - chip->eg_add = 0; - } - else - { - chip->eg_add = shift + 1; - } - } - - if (chip->eg_timerrem || chip->eg_state) - { - if (chip->eg_timer == 0xfffffffff) - { - chip->eg_timer = 0; - chip->eg_timerrem = 1; - } - else - { - chip->eg_timer++; - chip->eg_timerrem = 0; - } - } - - chip->eg_state ^= 1; - - while (chip->writebuf[chip->writebuf_cur].time <= chip->writebuf_samplecnt) - { - if (!(chip->writebuf[chip->writebuf_cur].reg & 0x200)) - { - break; - } - chip->writebuf[chip->writebuf_cur].reg &= 0x1ff; - OPL3_WriteReg(chip, chip->writebuf[chip->writebuf_cur].reg, - chip->writebuf[chip->writebuf_cur].data); - chip->writebuf_cur = (chip->writebuf_cur + 1) % OPL_WRITEBUF_SIZE; - } - chip->writebuf_samplecnt++; -} - -void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf) -{ - while (chip->samplecnt >= chip->rateratio) - { - chip->oldsamples[0] = chip->samples[0]; - chip->oldsamples[1] = chip->samples[1]; - OPL3_Generate(chip, chip->samples); - chip->samplecnt -= chip->rateratio; - } - buf[0] = (Bit16s)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt) - + chip->samples[0] * chip->samplecnt) / chip->rateratio); - buf[1] = (Bit16s)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt) - + chip->samples[1] * chip->samplecnt) / chip->rateratio); - chip->samplecnt += 1 << RSM_FRAC; -} - -void OPL3_Reset(opl3_chip *chip, Bit32u samplerate) -{ - Bit8u slotnum; - Bit8u channum; - - memset(chip, 0, sizeof(opl3_chip)); - for (slotnum = 0; slotnum < 36; slotnum++) - { - chip->slot[slotnum].chip = chip; - chip->slot[slotnum].mod = &chip->zeromod; - chip->slot[slotnum].eg_rout = 0x1ff; - chip->slot[slotnum].eg_out = 0x1ff; - chip->slot[slotnum].eg_gen = envelope_gen_num_release; - chip->slot[slotnum].trem = (Bit8u*)&chip->zeromod; - chip->slot[slotnum].slot_num = slotnum; - } - for (channum = 0; channum < 18; channum++) - { - chip->channel[channum].slots[0] = &chip->slot[ch_slot[channum]]; - chip->channel[channum].slots[1] = &chip->slot[ch_slot[channum] + 3]; - chip->slot[ch_slot[channum]].channel = &chip->channel[channum]; - chip->slot[ch_slot[channum] + 3].channel = &chip->channel[channum]; - if ((channum % 9) < 3) - { - chip->channel[channum].pair = &chip->channel[channum + 3]; - } - else if ((channum % 9) < 6) - { - chip->channel[channum].pair = &chip->channel[channum - 3]; - } - chip->channel[channum].chip = chip; - chip->channel[channum].out[0] = &chip->zeromod; - chip->channel[channum].out[1] = &chip->zeromod; - chip->channel[channum].out[2] = &chip->zeromod; - chip->channel[channum].out[3] = &chip->zeromod; - chip->channel[channum].chtype = ch_2op; - chip->channel[channum].cha = 0xffff; - chip->channel[channum].chb = 0xffff; - chip->channel[channum].leftpan = 0x10000; - chip->channel[channum].rightpan = 0x10000; - chip->channel[channum].ch_num = channum; - OPL3_ChannelSetupAlg(&chip->channel[channum]); - } - chip->noise = 1; - chip->rateratio = (samplerate << RSM_FRAC) / 49716; - chip->tremoloshift = 4; - chip->vibshift = 1; - - if (!panpot_lut_build) - { - for (int i = 0; i < 256; i++) - { - panpot_lut[i] = (Bit32u)(sin(i * M_PI / 512.0) * 0x10000); - } - panpot_lut_build = 1; - } -} - -void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v) -{ - Bit8u high = (reg >> 8) & 0x01; - Bit8u regm = reg & 0xff; - switch (regm & 0xf0) - { - case 0x00: - if (high) - { - switch (regm & 0x0f) - { - case 0x04: - OPL3_ChannelSet4Op(chip, v); - break; - case 0x05: - chip->newm = v & 0x01; - chip->stereoext = (v >> 1) & 0x01; - break; - } - } - else - { - switch (regm & 0x0f) - { - case 0x08: - chip->nts = (v >> 6) & 0x01; - break; - } - } - break; - case 0x20: - case 0x30: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWrite20(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0x40: - case 0x50: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWrite40(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0x60: - case 0x70: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWrite60(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0x80: - case 0x90: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWrite80(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0xe0: - case 0xf0: - if (ad_slot[regm & 0x1f] >= 0) - { - OPL3_SlotWriteE0(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); - } - break; - case 0xa0: - if ((regm & 0x0f) < 9) - { - OPL3_ChannelWriteA0(&chip->channel[9 * high + (regm & 0x0f)], v); - } - break; - case 0xb0: - if (regm == 0xbd && !high) - { - chip->tremoloshift = (((v >> 7) ^ 1) << 1) + 2; - chip->vibshift = ((v >> 6) & 0x01) ^ 1; - OPL3_ChannelUpdateRhythm(chip, v); - } - else if ((regm & 0x0f) < 9) - { - OPL3_ChannelWriteB0(&chip->channel[9 * high + (regm & 0x0f)], v); - if (v & 0x20) - { - OPL3_ChannelKeyOn(&chip->channel[9 * high + (regm & 0x0f)]); - } - else - { - OPL3_ChannelKeyOff(&chip->channel[9 * high + (regm & 0x0f)]); - } - } - break; - case 0xc0: - if ((regm & 0x0f) < 9) - { - OPL3_ChannelWriteC0(&chip->channel[9 * high + (regm & 0x0f)], v); - } - break; - case 0xd0: - if ((regm & 0x0f) < 9) - { - OPL3_ChannelWriteD0(&chip->channel[9 * high + (regm & 0x0f)], v); - } - break; - } -} - -void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v) -{ - Bit64u time1, time2; - - if (chip->writebuf[chip->writebuf_last].reg & 0x200) - { - OPL3_WriteReg(chip, chip->writebuf[chip->writebuf_last].reg & 0x1ff, - chip->writebuf[chip->writebuf_last].data); - - chip->writebuf_cur = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE; - chip->writebuf_samplecnt = chip->writebuf[chip->writebuf_last].time; - } - - chip->writebuf[chip->writebuf_last].reg = reg | 0x200; - chip->writebuf[chip->writebuf_last].data = v; - time1 = chip->writebuf_lasttime + OPL_WRITEBUF_DELAY; - time2 = chip->writebuf_samplecnt; - - if (time1 < time2) - { - time1 = time2; - } - - chip->writebuf[chip->writebuf_last].time = time1; - chip->writebuf_lasttime = time1; - chip->writebuf_last = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE; -} - -void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples) -{ - Bit32u i; - - for(i = 0; i < numsamples; i++) - { - OPL3_GenerateResampled(chip, sndptr); - sndptr += 2; - } -} diff --git a/source/audiolib/src/pitch.cpp b/source/audiolib/src/pitch.cpp deleted file mode 100644 index d4f9e75ab..000000000 --- a/source/audiolib/src/pitch.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -/********************************************************************** - module: PITCH.C - - author: James R. Dose - date: June 14, 1993 - - Routines for pitch scaling. - - (c) Copyright 1993 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#include "compat.h" -#include "pitch.h" - -#define MAXDETUNE 50 - -static uint32_t PitchTable[12][MAXDETUNE]; - - -/*--------------------------------------------------------------------- - Function: PITCH_Init - - Initializes pitch table. ----------------------------------------------------------------------*/ - - -void PITCH_Init(void) -{ - for (int note = 0; note < 12; note++) - for (int detune = 0; detune < MAXDETUNE; detune++) - PitchTable[note][detune] = (uint32_t) (65536.f * powf(2.f, (note * MAXDETUNE + detune) / (12.f * MAXDETUNE))); -} - - -/*--------------------------------------------------------------------- - Function: PITCH_GetScale - - Returns a fixed-point value to scale number the specified amount. ----------------------------------------------------------------------*/ - -uint32_t PITCH_GetScale(int const pitchoffset) -{ - static bool bInitialized; - - if (!bInitialized) - { - PITCH_Init(); - bInitialized = true; - } - - if (pitchoffset == 0) - return PitchTable[0][0]; - - int noteshift = pitchoffset % 1200; - - if (noteshift < 0) - noteshift += 1200; - - int const note = noteshift / 100; - int const detune = (noteshift % 100) / (100 / MAXDETUNE); - int const oshift = (pitchoffset - noteshift) / 1200; - auto const &scale = PitchTable[note][detune]; - - return (oshift < 0) ? (scale >> -oshift) : (scale << oshift); -} diff --git a/source/audiolib/src/pitch.h b/source/audiolib/src/pitch.h deleted file mode 100644 index 9b81e68f2..000000000 --- a/source/audiolib/src/pitch.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (C) 1994-1995 Apogee Software, Ltd. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -*/ -/********************************************************************** - module: PITCH.H - - author: James R. Dose - date: June 14, 1994 - - Public header for PITCH.C - - (c) Copyright 1994 James R. Dose. All Rights Reserved. -**********************************************************************/ - -#ifndef PITCH_H_ -#define PITCH_H_ - -#include - -uint32_t PITCH_GetScale(int pitchoffset); -#endif diff --git a/source/audiolib/src/vorbis.cpp b/source/audiolib/src/vorbis.cpp deleted file mode 100644 index e095b055e..000000000 --- a/source/audiolib/src/vorbis.cpp +++ /dev/null @@ -1,472 +0,0 @@ -/* - Copyright (C) 2009 Jonathon Fowler - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - - See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - */ - -/** - * OggVorbis source support for MultiVoc - */ - -#include "compat.h" -#include "pragmas.h" - -#ifdef HAVE_VORBIS - -#include "pitch.h" -#include "multivoc.h" -#include "_multivc.h" - -#define OV_EXCLUDE_STATIC_CALLBACKS - -#if defined __APPLE__ -# include -#elif defined GEKKO -# define USING_TREMOR -# include -#else -# include "vorbis/vorbisfile.h" -#endif - -#define BLOCKSIZE MV_MIXBUFFERSIZE - - -typedef struct { - void * ptr; - size_t length; - size_t pos; - - OggVorbis_File vf; - - char block[BLOCKSIZE]; - int lastbitstream; -} vorbis_data; - -// designed with multiple calls in mind -static void MV_GetVorbisCommentLoops(VoiceNode *voice, vorbis_comment *vc) -{ - const char *vc_loopstart = nullptr; - const char *vc_loopend = nullptr; - const char *vc_looplength = nullptr; - - for (int comment = 0; comment < vc->comments; ++comment) - { - auto entry = (const char *)vc->user_comments[comment]; - if (entry != nullptr && entry[0] != '\0') - { - const char *value = Bstrchr(entry, '='); - - if (!value) - continue; - - const size_t field = value - entry; - value += 1; - - for (int t = 0; t < loopStartTagCount && vc_loopstart == nullptr; ++t) - { - auto tag = loopStartTags[t]; - if (field == Bstrlen(tag) && Bstrncasecmp(entry, tag, field) == 0) - vc_loopstart = value; - } - - for (int t = 0; t < loopEndTagCount && vc_loopend == nullptr; ++t) - { - auto tag = loopEndTags[t]; - if (field == Bstrlen(tag) && Bstrncasecmp(entry, tag, field) == 0) - vc_loopend = value; - } - - for (int t = 0; t < loopLengthTagCount && vc_looplength == nullptr; ++t) - { - auto tag = loopLengthTags[t]; - if (field == Bstrlen(tag) && Bstrncasecmp(entry, tag, field) == 0) - vc_looplength = value; - } - } - } - - if (vc_loopstart != nullptr) - { - const ogg_int64_t ov_loopstart = Batol(vc_loopstart); - if (ov_loopstart >= 0) // a loop starting at 0 is valid - { - voice->LoopStart = (const char *) (intptr_t) ov_loopstart; - voice->LoopSize = 1; - } - } - if (vc_loopend != nullptr) - { - if (voice->LoopSize > 0) - { - const ogg_int64_t ov_loopend = Batol(vc_loopend); - if (ov_loopend > 0) // a loop ending at 0 is invalid - voice->LoopEnd = (const char *) (intptr_t) ov_loopend; - } - } - if (vc_looplength != nullptr) - { - if (voice->LoopSize > 0 && voice->LoopEnd == 0) - { - const ogg_int64_t ov_looplength = Batol(vc_looplength); - if (ov_looplength > 0) // a loop of length 0 is invalid - voice->LoopEnd = (const char *) ((intptr_t) ov_looplength + (intptr_t) voice->LoopStart); - } - } -} - -// callbacks - -static size_t read_vorbis(void *ptr, size_t size, size_t nmemb, void *datasource) -{ - auto vorb = (vorbis_data *)datasource; - - errno = 0; - - if (vorb->length == vorb->pos) - return 0; - - int nread = 0; - - for (; nmemb > 0; nmemb--, nread++) - { - int bytes = vorb->length - vorb->pos; - - if ((signed)size < bytes) - bytes = (int)size; - - memcpy(ptr, (uint8_t *)vorb->ptr + vorb->pos, bytes); - vorb->pos += bytes; - ptr = (uint8_t *)ptr + bytes; - - if (vorb->length == vorb->pos) - { - nread++; - break; - } - } - - return nread; -} - - -static int seek_vorbis(void *datasource, ogg_int64_t offset, int whence) -{ - auto vorb = (vorbis_data *)datasource; - - switch (whence) - { - case SEEK_SET: vorb->pos = 0; break; - case SEEK_CUR: break; - case SEEK_END: vorb->pos = vorb->length; break; - } - - vorb->pos += offset; - - if (vorb->pos > vorb->length) - vorb->pos = vorb->length; - - return vorb->pos; -} - -static int close_vorbis(void *datasource) -{ - UNREFERENCED_PARAMETER(datasource); - return 0; -} - -static long tell_vorbis(void *datasource) -{ - auto vorb = (vorbis_data *)datasource; - - return vorb->pos; -} - -static ov_callbacks vorbis_callbacks = { read_vorbis, seek_vorbis, close_vorbis, tell_vorbis }; - - -int MV_GetVorbisPosition(VoiceNode *voice) -{ - auto vd = (vorbis_data *) voice->rawdataptr; - - return ov_pcm_tell(&vd->vf); -} - -void MV_SetVorbisPosition(VoiceNode *voice, int position) -{ - auto vd = (vorbis_data *) voice->rawdataptr; - - ov_pcm_seek(&vd->vf, position); -} - -/*--------------------------------------------------------------------- -Function: MV_GetNextVorbisBlock - -Controls playback of OggVorbis data ----------------------------------------------------------------------*/ - -static playbackstatus MV_GetNextVorbisBlock(VoiceNode *voice) -{ - int bitstream; - - int bytesread = 0; - auto vd = (vorbis_data *)voice->rawdataptr; - do - { -#ifdef USING_TREMOR - int bytes = ov_read(&vd->vf, vd->block + bytesread, BLOCKSIZE - bytesread, &bitstream); -#else - int bytes = ov_read(&vd->vf, vd->block + bytesread, BLOCKSIZE - bytesread, 0, 2, 1, &bitstream); -#endif - // fprintf(stderr, "ov_read = %d\n", bytes); - if (bytes > 0) - { - ogg_int64_t currentPosition; - bytesread += bytes; - if ((ogg_int64_t)(intptr_t)voice->LoopEnd > 0 && - (currentPosition = ov_pcm_tell(&vd->vf)) >= (ogg_int64_t)(intptr_t)voice->LoopEnd) - { - bytesread -= - (currentPosition - (ogg_int64_t)(intptr_t)voice->LoopEnd) * voice->channels * 2; // (voice->bits>>3) - - int const err = ov_pcm_seek(&vd->vf, (ogg_int64_t)(intptr_t)voice->LoopStart); - - if (err != 0) - { - MV_Printf("MV_GetNextVorbisBlock ov_pcm_seek: LOOP_START %l, LOOP_END %l, err %d\n", - (ogg_int64_t)(intptr_t)voice->LoopStart, (ogg_int64_t)(intptr_t)voice->LoopEnd, err); - } - } - continue; - } - else if (bytes == OV_HOLE) - continue; - else if (bytes == 0) - { - if (voice->LoopSize > 0) - { - int const err = ov_pcm_seek(&vd->vf, (ogg_int64_t)(intptr_t)voice->LoopStart); - - if (err != 0) - { - MV_Printf("MV_GetNextVorbisBlock ov_pcm_seek: LOOP_START %l, err %d\n", - (ogg_int64_t)(intptr_t)voice->LoopStart, err); - } - else - continue; - } - else - { - break; - } - } - else if (bytes < 0) - { - MV_Printf("MV_GetNextVorbisBlock ov_read: err %d\n", bytes); - return NoMoreData; - } - } while (bytesread < BLOCKSIZE); - - if (bytesread == 0) - return NoMoreData; - - if (bitstream != vd->lastbitstream) - { - vorbis_info *vi = ov_info(&vd->vf, -1); - if (!vi || (vi->channels != 1 && vi->channels != 2)) - return NoMoreData; - - voice->channels = vi->channels; - voice->SamplingRate = vi->rate; - voice->RateScale = divideu32(voice->SamplingRate * voice->PitchScale, MV_MixRate); - - voice->FixedPointBufferSize = (voice->RateScale * MV_MIXBUFFERSIZE) - voice->RateScale; - vd->lastbitstream = bitstream; - MV_SetVoiceMixMode(voice); - } - - uint32_t const samples = divideu32(bytesread, ((voice->bits>>3) * voice->channels)); - - voice->position = 0; - voice->sound = vd->block; - voice->BlockLength = 0; - voice->length = samples << 16; - -#ifdef GEKKO - // If libtremor had the three additional ov_read() parameters that libvorbis has, - // this would be better handled using the endianness parameter. - int16_t *data = (int16_t *)(vd->block); // assumes signed 16-bit - for (bytesread = 0; bytesread < BLOCKSIZE / 2; ++bytesread) - data[bytesread] = (data[bytesread] & 0xff) << 8 | ((data[bytesread] & 0xff00) >> 8); -#endif - - return KeepPlaying; -} - - -/*--------------------------------------------------------------------- -Function: MV_PlayVorbis3D - -Begin playback of sound data at specified angle and distance -from listener. ----------------------------------------------------------------------*/ - -int MV_PlayVorbis3D(char *ptr, uint32_t length, int loophow, int pitchoffset, int angle, int distance, int priority, float volume, intptr_t callbackval) -{ - if (!MV_Installed) - return MV_SetErrorCode(MV_NotInstalled); - - if (distance < 0) - { - distance = -distance; - angle += MV_NUMPANPOSITIONS / 2; - } - - int const vol = MIX_VOLUME(distance); - - // Ensure angle is within 0 - 127 - angle &= MV_MAXPANPOSITION; - - return MV_PlayVorbis(ptr, length, loophow, -1, pitchoffset, max(0, 255 - distance), - MV_PanTable[angle][vol].left, MV_PanTable[angle][vol].right, priority, volume, callbackval); -} - - -/*--------------------------------------------------------------------- -Function: MV_PlayVorbis - -Begin playback of sound data with the given sound levels and -priority. ----------------------------------------------------------------------*/ - -int MV_PlayVorbis(char *ptr, uint32_t length, int loopstart, int loopend, int pitchoffset, int vol, int left, int right, int priority, float volume, intptr_t callbackval) -{ - UNREFERENCED_PARAMETER(loopend); - - if (!MV_Installed) - return MV_SetErrorCode(MV_NotInstalled); - - VoiceNode *voice = MV_AllocVoice(priority); - - if (voice == nullptr) - return MV_SetErrorCode(MV_NoVoices); - - - auto vd = (vorbis_data *)Xcalloc(1, sizeof(vorbis_data)); - vd->ptr = ptr; - vd->pos = 0; - vd->length = length; - - vd->lastbitstream = -1; - - int status = ov_open_callbacks((void *)vd, &vd->vf, 0, 0, vorbis_callbacks); - vorbis_info *vi; - - if (status < 0 || ((vi = ov_info(&vd->vf, 0)) == nullptr) || vi->channels < 1 || vi->channels > 2) - { - if (status == 0) - ov_clear(&vd->vf); - else - MV_Printf("MV_PlayVorbis: err %d\n", status); - - Xfree(vd); - return MV_SetErrorCode(MV_InvalidFile); - } - - voice->wavetype = FMT_VORBIS; - voice->bits = 16; - voice->channels = vi->channels; - voice->rawdataptr = (void *)vd; - voice->GetSound = MV_GetNextVorbisBlock; - voice->NextBlock = vd->block; - voice->LoopCount = 0; - voice->BlockLength = 0; - voice->length = 0; - voice->next = nullptr; - voice->prev = nullptr; - voice->priority = priority; - voice->callbackval = callbackval; - - voice->LoopStart = nullptr; - voice->LoopEnd = nullptr; - voice->LoopSize = (loopstart >= 0 ? 1 : 0); - - // load loop tags from metadata - if (auto comment = ov_comment(&vd->vf, 0)) - MV_GetVorbisCommentLoops(voice, comment); - - voice->Paused = FALSE; - - MV_SetVoicePitch(voice, vi->rate, pitchoffset); - MV_SetVoiceMixMode(voice); - - MV_SetVoiceVolume(voice, vol, left, right, volume); - MV_PlayVoice(voice); - - return voice->handle; -} - -void MV_ReleaseVorbisVoice( VoiceNode * voice ) -{ - if (voice->wavetype != FMT_VORBIS) - return; - - auto vd = (vorbis_data *)voice->rawdataptr; - - voice->length = 0; - voice->sound = nullptr; - ov_clear(&vd->vf); - Xfree(vd); -} -#else -#include "_multivc.h" - -int MV_PlayVorbis(char *ptr, uint32_t ptrlength, int loopstart, int loopend, int pitchoffset, - int vol, int left, int right, int priority, float volume, intptr_t callbackval) -{ - UNREFERENCED_PARAMETER(ptr); - UNREFERENCED_PARAMETER(ptrlength); - UNREFERENCED_PARAMETER(loopstart); - UNREFERENCED_PARAMETER(loopend); - UNREFERENCED_PARAMETER(pitchoffset); - UNREFERENCED_PARAMETER(vol); - UNREFERENCED_PARAMETER(left); - UNREFERENCED_PARAMETER(right); - UNREFERENCED_PARAMETER(priority); - UNREFERENCED_PARAMETER(volume); - UNREFERENCED_PARAMETER(callbackval); - - MV_Printf("MV_PlayVorbis: OggVorbis support not included in this binary.\n"); - return -1; -} - -int MV_PlayVorbis3D(char *ptr, uint32_t ptrlength, int loophow, int pitchoffset, int angle, - int distance, int priority, float volume, intptr_t callbackval) -{ - UNREFERENCED_PARAMETER(ptr); - UNREFERENCED_PARAMETER(ptrlength); - UNREFERENCED_PARAMETER(loophow); - UNREFERENCED_PARAMETER(pitchoffset); - UNREFERENCED_PARAMETER(angle); - UNREFERENCED_PARAMETER(distance); - UNREFERENCED_PARAMETER(priority); - UNREFERENCED_PARAMETER(volume); - UNREFERENCED_PARAMETER(callbackval); - - MV_Printf("MV_PlayVorbis: OggVorbis support not included in this binary.\n"); - return -1; -} -#endif //HAVE_VORBIS diff --git a/source/blood/src/config.cpp b/source/blood/src/config.cpp index c37acc228..c4201adb0 100644 --- a/source/blood/src/config.cpp +++ b/source/blood/src/config.cpp @@ -28,7 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "common_game.h" #include "build.h" -#include "sndcards.h" #include "hash.h" #include "renderlayer.h" #include "gamecontrol.h" diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index efee1bb54..11d09d5ed 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -27,7 +27,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "osd.h" #include "compat.h" #include "mmulti.h" -#include "sndcards.h" #include "common_game.h" #include "config.h" #include "blood.h" diff --git a/source/blood/src/sound.cpp b/source/blood/src/sound.cpp index 4a8d9a0c3..26bbfc141 100644 --- a/source/blood/src/sound.cpp +++ b/source/blood/src/sound.cpp @@ -30,7 +30,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "resource.h" #include "sound.h" #include "renderlayer.h" -#include "al_midi.h" #include "openaudio.h" #include "z_music.h" #include "sfx.h"