Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2004-2022, OpenMPT Project Developers and Contributors
|
||||
Copyright (c) 1997-2003, Olivier Lapicque
|
||||
All rights reserved.
|
||||
|
||||
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 OpenMPT project 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 COPYRIGHT HOLDER 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.
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
ACLOCAL_AMFLAGS = -I m4 --install
|
||||
EXTRA_DIST =
|
||||
EXTRA_DIST += LICENSE
|
||||
EXTRA_DIST += libopenmpt_modplug.pc.in
|
||||
EXTRA_DIST += libmodplug.pc.in
|
||||
EXTRA_DIST += test.sh
|
||||
MOSTLYCLEANFILES =
|
||||
|
||||
dist_doc_DATA =
|
||||
dist_doc_DATA += LICENSE
|
||||
nobase_dist_doc_DATA =
|
||||
|
||||
bin_PROGRAMS =
|
||||
check_PROGRAMS =
|
||||
lib_LTLIBRARIES =
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA =
|
||||
nobase_include_HEADERS =
|
||||
|
||||
if ENABLE_LIBOPENMPT_MODPLUG
|
||||
lib_LTLIBRARIES += libopenmpt_modplug.la
|
||||
libopenmpt_modplug_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
||||
libopenmpt_modplug_la_CPPFLAGS = -I$(srcdir)/ $(LIBOPENMPT_CPPFLAGS)
|
||||
libopenmpt_modplug_la_CXXFLAGS = $(LIBOPENMPT_CFLAGS)
|
||||
libopenmpt_modplug_la_CFLAGS = $(LIBOPENMPT_CFLAGS)
|
||||
libopenmpt_modplug_la_LIBADD = $(LIBOPENMPT_LIBS)
|
||||
libopenmpt_modplug_la_SOURCES =
|
||||
libopenmpt_modplug_la_SOURCES += libopenmpt_modplug.c
|
||||
libopenmpt_modplug_la_SOURCES += libopenmpt_modplug_cpp.cpp
|
||||
endif
|
||||
|
||||
if ENABLE_LIBMODPLUG
|
||||
pkgconfig_DATA += libmodplug.pc
|
||||
lib_LTLIBRARIES += libmodplug.la
|
||||
libmodplug_la_LDFLAGS = -version-info 1:0:0 -no-undefined
|
||||
nobase_include_HEADERS += libmodplug/modplug.h libmodplug/sndfile.h libmodplug/stdafx.h
|
||||
libmodplug_la_CPPFLAGS = -I$(srcdir)/ $(LIBOPENMPT_CPPFLAGS)
|
||||
libmodplug_la_CXXFLAGS = $(LIBOPENMPT_CFLAGS)
|
||||
libmodplug_la_CFLAGS = $(LIBOPENMPT_CFLAGS)
|
||||
libmodplug_la_LIBADD = $(LIBOPENMPT_LIBS)
|
||||
libmodplug_la_SOURCES =
|
||||
libmodplug_la_SOURCES += libopenmpt_modplug.c
|
||||
libmodplug_la_SOURCES += libopenmpt_modplug_cpp.cpp
|
||||
endif
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env sh
|
||||
autoreconf -i
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
./autogen.sh
|
||||
./configure
|
||||
make distclean
|
|
@ -0,0 +1,81 @@
|
|||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* define if the compiler supports basic C++11 syntax */
|
||||
#undef HAVE_CXX11
|
||||
|
||||
/* define if the compiler supports basic C++14 syntax */
|
||||
#undef HAVE_CXX14
|
||||
|
||||
/* define if the compiler supports basic C++17 syntax */
|
||||
#undef HAVE_CXX17
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
|
@ -0,0 +1,66 @@
|
|||
AC_INIT([libopenmpt-modplug], [0.8.9.0-openmpt1], [https://bugs.openmpt.org/], [libopenmpt-modplug], [https://lib.openmpt.org/])
|
||||
AC_PREREQ([2.68])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_FILES([Makefile libopenmpt_modplug.pc libmodplug.pc])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.11 -Wall -Werror foreign subdir-objects])
|
||||
|
||||
AM_PROG_AR
|
||||
|
||||
LT_INIT
|
||||
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
PKG_PROG_PKG_CONFIG([0.24])
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CXX
|
||||
AC_PROG_INSTALL
|
||||
|
||||
LIBOPENMPT_REQUIRES_PRIVATE=
|
||||
LIBOPENMPT_LIBS_PRIVATE=
|
||||
|
||||
# We want a modern C compiler
|
||||
AC_PROG_CC_STDC
|
||||
#AC_PROG_CC_C99
|
||||
|
||||
# We need C++11 support
|
||||
AX_CXX_COMPILE_STDCXX(17, [noext], [optional])
|
||||
AS_IF([test "x$HAVE_CXX17" != "x1"],
|
||||
[
|
||||
AX_CXX_COMPILE_STDCXX(14, [noext], [optional])
|
||||
AS_IF([test "x$HAVE_CXX14" != "x1"],
|
||||
[
|
||||
AX_CXX_COMPILE_STDCXX(11, [noext], [mandatory])
|
||||
],[]
|
||||
)
|
||||
],[]
|
||||
)
|
||||
|
||||
AC_LANG_PUSH([C])
|
||||
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden], [CFLAGS="$CFLAGS -fvisibility=hidden -DSYM_VISIBILITY"])
|
||||
AX_CFLAGS_WARN_ALL
|
||||
AC_LANG_POP([C])
|
||||
|
||||
AC_LANG_PUSH([C++])
|
||||
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden], [CXXFLAGS="$CXXFLAGS -fvisibility=hidden -DSYM_VISIBILITY"])
|
||||
AX_CXXFLAGS_WARN_ALL
|
||||
AC_LANG_POP([C++])
|
||||
|
||||
PKG_CHECK_MODULES([LIBOPENMPT], [libopenmpt])
|
||||
|
||||
# libmodplug emulation
|
||||
AC_ARG_ENABLE([libopenmpt_modplug], AS_HELP_STRING([--disable-libopenmpt_modplug], [Disable the libopenmpt_modplug emulation library of the libmodplug interface.]))
|
||||
AM_CONDITIONAL([ENABLE_LIBOPENMPT_MODPLUG], [test "x$enable_libopenmpt_modplug" != "xno"])
|
||||
|
||||
# libmodplug replacement
|
||||
AC_ARG_ENABLE([libmodplug], AS_HELP_STRING([--enable-libmodplug], [Enable libmodplug replacement library based on libopenmpt.
|
||||
WARNING: This will replace your current libmodplug installation.
|
||||
CAUTION: The emulation of the libmodplug interface is not complete as libmodplug exposes lots of internal implementation details. If any of those is used by an application, the emulation via libopenmpt will fail and/or crash.
|
||||
]))
|
||||
AM_CONDITIONAL([ENABLE_LIBMODPLUG], [test "x$enable_libmodplug" = "xyes"])
|
||||
|
||||
AC_OUTPUT
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
./test.sh
|
||||
|
||||
./autogen.sh
|
||||
./configure
|
||||
make dist
|
|
@ -0,0 +1,13 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libmodplug
|
||||
Description: The ModPlug mod file playing library (emulated via libopenmpt).
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires.private: libopenmpt
|
||||
Libs: -L${libdir} -lmodplug
|
||||
Libs.private:
|
||||
Cflags: -I${includedir}
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* This source code is public domain.
|
||||
*
|
||||
* Authors: Kenton Varda <temporal@gauge3d.org> (C interface wrapper)
|
||||
*/
|
||||
|
||||
#ifndef MODPLUG_MODPLUG_H
|
||||
#define MODPLUG_MODPLUG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# if defined(MODPLUG_BUILD) && defined(DLL_EXPORT) /* building libmodplug as a dll for windows */
|
||||
# define MODPLUG_EXPORT __declspec(dllexport)
|
||||
# elif defined(MODPLUG_BUILD) || defined(MODPLUG_STATIC) /* building or using static libmodplug for windows */
|
||||
# define MODPLUG_EXPORT
|
||||
# else
|
||||
# define MODPLUG_EXPORT __declspec(dllimport) /* using libmodplug dll for windows */
|
||||
# endif
|
||||
#elif defined(MODPLUG_BUILD) && defined(SYM_VISIBILITY)
|
||||
# define MODPLUG_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define MODPLUG_EXPORT
|
||||
#endif
|
||||
|
||||
struct _ModPlugFile;
|
||||
typedef struct _ModPlugFile ModPlugFile;
|
||||
|
||||
struct _ModPlugNote {
|
||||
unsigned char Note;
|
||||
unsigned char Instrument;
|
||||
unsigned char VolumeEffect;
|
||||
unsigned char Effect;
|
||||
unsigned char Volume;
|
||||
unsigned char Parameter;
|
||||
};
|
||||
typedef struct _ModPlugNote ModPlugNote;
|
||||
|
||||
typedef void (*ModPlugMixerProc)(int*, unsigned long, unsigned long);
|
||||
|
||||
/* Load a mod file. [data] should point to a block of memory containing the complete
|
||||
* file, and [size] should be the size of that block.
|
||||
* Return the loaded mod file on success, or NULL on failure. */
|
||||
MODPLUG_EXPORT ModPlugFile* ModPlug_Load(const void* data, int size);
|
||||
/* Unload a mod file. */
|
||||
MODPLUG_EXPORT void ModPlug_Unload(ModPlugFile* file);
|
||||
|
||||
/* Read sample data into the buffer. Returns the number of bytes read. If the end
|
||||
* of the mod has been reached, zero is returned. */
|
||||
MODPLUG_EXPORT int ModPlug_Read(ModPlugFile* file, void* buffer, int size);
|
||||
|
||||
/* Get the name of the mod. The returned buffer is stored within the ModPlugFile
|
||||
* structure and will remain valid until you unload the file. */
|
||||
MODPLUG_EXPORT const char* ModPlug_GetName(ModPlugFile* file);
|
||||
|
||||
/* Get the length of the mod, in milliseconds. Note that this result is not always
|
||||
* accurate, especially in the case of mods with loops. */
|
||||
MODPLUG_EXPORT int ModPlug_GetLength(ModPlugFile* file);
|
||||
|
||||
/* Seek to a particular position in the song. Note that seeking and MODs don't mix very
|
||||
* well. Some mods will be missing instruments for a short time after a seek, as ModPlug
|
||||
* does not scan the sequence backwards to find out which instruments were supposed to be
|
||||
* playing at that time. (Doing so would be difficult and not very reliable.) Also,
|
||||
* note that seeking is not very exact in some mods -- especially those for which
|
||||
* ModPlug_GetLength() does not report the full length. */
|
||||
MODPLUG_EXPORT void ModPlug_Seek(ModPlugFile* file, int millisecond);
|
||||
|
||||
enum _ModPlug_Flags
|
||||
{
|
||||
MODPLUG_ENABLE_OVERSAMPLING = 1 << 0, /* Enable oversampling (*highly* recommended) */
|
||||
MODPLUG_ENABLE_NOISE_REDUCTION = 1 << 1, /* Enable noise reduction */
|
||||
MODPLUG_ENABLE_REVERB = 1 << 2, /* Enable reverb */
|
||||
MODPLUG_ENABLE_MEGABASS = 1 << 3, /* Enable megabass */
|
||||
MODPLUG_ENABLE_SURROUND = 1 << 4 /* Enable surround sound. */
|
||||
};
|
||||
|
||||
enum _ModPlug_ResamplingMode
|
||||
{
|
||||
MODPLUG_RESAMPLE_NEAREST = 0, /* No interpolation (very fast, extremely bad sound quality) */
|
||||
MODPLUG_RESAMPLE_LINEAR = 1, /* Linear interpolation (fast, good quality) */
|
||||
MODPLUG_RESAMPLE_SPLINE = 2, /* Cubic spline interpolation (high quality) */
|
||||
MODPLUG_RESAMPLE_FIR = 3 /* 8-tap fir filter (extremely high quality) */
|
||||
};
|
||||
|
||||
typedef struct _ModPlug_Settings
|
||||
{
|
||||
int mFlags; /* One or more of the MODPLUG_ENABLE_* flags above, bitwise-OR'ed */
|
||||
|
||||
/* Note that ModPlug always decodes sound at 44100kHz, 32 bit, stereo and then
|
||||
* down-mixes to the settings you choose. */
|
||||
int mChannels; /* Number of channels - 1 for mono or 2 for stereo */
|
||||
int mBits; /* Bits per sample - 8, 16, or 32 */
|
||||
int mFrequency; /* Sampling rate - 11025, 22050, or 44100 */
|
||||
int mResamplingMode; /* One of MODPLUG_RESAMPLE_*, above */
|
||||
|
||||
int mStereoSeparation; /* Stereo separation, 1 - 256 */
|
||||
int mMaxMixChannels; /* Maximum number of mixing channels (polyphony), 32 - 256 */
|
||||
|
||||
int mReverbDepth; /* Reverb level 0(quiet)-100(loud) */
|
||||
int mReverbDelay; /* Reverb delay in ms, usually 40-200ms */
|
||||
int mBassAmount; /* XBass level 0(quiet)-100(loud) */
|
||||
int mBassRange; /* XBass cutoff in Hz 10-100 */
|
||||
int mSurroundDepth; /* Surround level 0(quiet)-100(heavy) */
|
||||
int mSurroundDelay; /* Surround delay in ms, usually 5-40ms */
|
||||
int mLoopCount; /* Number of times to loop. Zero prevents looping.
|
||||
* -1 loops forever. */
|
||||
} ModPlug_Settings;
|
||||
|
||||
/* Get and set the mod decoder settings. All options, except for channels, bits-per-sample,
|
||||
* sampling rate, and loop count, will take effect immediately. Those options which don't
|
||||
* take effect immediately will take effect the next time you load a mod. */
|
||||
MODPLUG_EXPORT void ModPlug_GetSettings(ModPlug_Settings* settings);
|
||||
MODPLUG_EXPORT void ModPlug_SetSettings(const ModPlug_Settings* settings);
|
||||
|
||||
/* New ModPlug API Functions */
|
||||
/* NOTE: Master Volume (1-512) */
|
||||
MODPLUG_EXPORT unsigned int ModPlug_GetMasterVolume(ModPlugFile* file) ;
|
||||
MODPLUG_EXPORT void ModPlug_SetMasterVolume(ModPlugFile* file,unsigned int cvol) ;
|
||||
|
||||
MODPLUG_EXPORT int ModPlug_GetCurrentSpeed(ModPlugFile* file);
|
||||
MODPLUG_EXPORT int ModPlug_GetCurrentTempo(ModPlugFile* file);
|
||||
MODPLUG_EXPORT int ModPlug_GetCurrentOrder(ModPlugFile* file);
|
||||
MODPLUG_EXPORT int ModPlug_GetCurrentPattern(ModPlugFile* file);
|
||||
MODPLUG_EXPORT int ModPlug_GetCurrentRow(ModPlugFile* file);
|
||||
MODPLUG_EXPORT int ModPlug_GetPlayingChannels(ModPlugFile* file);
|
||||
|
||||
MODPLUG_EXPORT void ModPlug_SeekOrder(ModPlugFile* file,int order);
|
||||
MODPLUG_EXPORT int ModPlug_GetModuleType(ModPlugFile* file);
|
||||
MODPLUG_EXPORT char* ModPlug_GetMessage(ModPlugFile* file);
|
||||
|
||||
#define MODPLUG_NO_FILESAVE /* experimental yet. must match stdafx.h. */
|
||||
#ifndef MODPLUG_NO_FILESAVE
|
||||
/*
|
||||
* EXPERIMENTAL Export Functions
|
||||
*/
|
||||
/*Export to a Scream Tracker 3 S3M module. EXPERIMENTAL (only works on Little-Endian platforms)*/
|
||||
MODPLUG_EXPORT char ModPlug_ExportS3M(ModPlugFile* file, const char* filepath);
|
||||
|
||||
/*Export to a Extended Module (XM). EXPERIMENTAL (only works on Little-Endian platforms)*/
|
||||
MODPLUG_EXPORT char ModPlug_ExportXM(ModPlugFile* file, const char* filepath);
|
||||
|
||||
/*Export to a Amiga MOD file. EXPERIMENTAL.*/
|
||||
MODPLUG_EXPORT char ModPlug_ExportMOD(ModPlugFile* file, const char* filepath);
|
||||
|
||||
/*Export to a Impulse Tracker IT file. Should work OK in Little-Endian & Big-Endian platforms :-) */
|
||||
MODPLUG_EXPORT char ModPlug_ExportIT(ModPlugFile* file, const char* filepath);
|
||||
#endif /* MODPLUG_NO_FILESAVE */
|
||||
|
||||
MODPLUG_EXPORT unsigned int ModPlug_NumInstruments(ModPlugFile* file);
|
||||
MODPLUG_EXPORT unsigned int ModPlug_NumSamples(ModPlugFile* file);
|
||||
MODPLUG_EXPORT unsigned int ModPlug_NumPatterns(ModPlugFile* file);
|
||||
MODPLUG_EXPORT unsigned int ModPlug_NumChannels(ModPlugFile* file);
|
||||
MODPLUG_EXPORT unsigned int ModPlug_SampleName(ModPlugFile* file, unsigned int qual, char* buff);
|
||||
MODPLUG_EXPORT unsigned int ModPlug_InstrumentName(ModPlugFile* file, unsigned int qual, char* buff);
|
||||
|
||||
/*
|
||||
* Retrieve pattern note-data
|
||||
*/
|
||||
MODPLUG_EXPORT ModPlugNote* ModPlug_GetPattern(ModPlugFile* file, int pattern, unsigned int* numrows);
|
||||
|
||||
/*
|
||||
* =================
|
||||
* Mixer callback
|
||||
* =================
|
||||
*
|
||||
* Use this callback if you want to 'modify' the mixed data of LibModPlug.
|
||||
*
|
||||
* void proc(int* buffer,unsigned long channels,unsigned long nsamples) ;
|
||||
*
|
||||
* 'buffer': A buffer of mixed samples
|
||||
* 'channels': N. of channels in the buffer
|
||||
* 'nsamples': N. of samples in the buffeer (without taking care of n.channels)
|
||||
*
|
||||
* (Samples are signed 32-bit integers)
|
||||
*/
|
||||
MODPLUG_EXPORT void ModPlug_InitMixerCallback(ModPlugFile* file,ModPlugMixerProc proc) ;
|
||||
MODPLUG_EXPORT void ModPlug_UnloadMixerCallback(ModPlugFile* file) ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* This source code is public domain.
|
||||
*
|
||||
* Authors: Rani Assaf <rani@magic.metawire.com>,
|
||||
* Olivier Lapicque <olivierl@jps.net>,
|
||||
* Adam Goode <adam@evdebs.org> (endian and char fixes for PPC)
|
||||
*/
|
||||
|
||||
#ifndef MODPLUG_STDAFX_H
|
||||
#define MODPLUG_STDAFX_H
|
||||
|
||||
/* Autoconf detection of stdint/inttypes */
|
||||
#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED)
|
||||
# include "config.h"
|
||||
# define CONFIG_H_INCLUDED 1
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
/* disable AGC and FILESAVE for all targets for uniformity. */
|
||||
#define NO_AGC
|
||||
#define MODPLUG_NO_FILESAVE
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef MSC_VER
|
||||
#pragma warning (disable:4201)
|
||||
#pragma warning (disable:4514)
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <mmsystem.h>
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define srandom(_seed) srand(_seed)
|
||||
#define random() rand()
|
||||
#define sleep(_ms) Sleep(_ms)
|
||||
|
||||
inline void ProcessPlugins(int n) {}
|
||||
|
||||
#undef strcasecmp
|
||||
#undef strncasecmp
|
||||
#define strcasecmp(a,b) _stricmp(a,b)
|
||||
#define strncasecmp(a,b,c) _strnicmp(a,b,c)
|
||||
|
||||
#define HAVE_SINF 1
|
||||
|
||||
#ifndef isblank
|
||||
#define isblank(c) ((c) == ' ' || (c) == '\t')
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
typedef int8_t CHAR;
|
||||
typedef uint8_t UCHAR;
|
||||
typedef uint8_t* PUCHAR;
|
||||
typedef uint16_t USHORT;
|
||||
typedef uint32_t ULONG;
|
||||
typedef uint32_t UINT;
|
||||
typedef uint32_t DWORD;
|
||||
typedef int32_t LONG;
|
||||
typedef int64_t LONGLONG;
|
||||
typedef int32_t* LPLONG;
|
||||
typedef uint32_t* LPDWORD;
|
||||
typedef uint16_t WORD;
|
||||
typedef uint8_t BYTE;
|
||||
typedef uint8_t* LPBYTE;
|
||||
typedef bool BOOL;
|
||||
typedef char* LPSTR;
|
||||
typedef void* LPVOID;
|
||||
typedef uint16_t* LPWORD;
|
||||
typedef const char* LPCSTR;
|
||||
typedef void* PVOID;
|
||||
typedef void VOID;
|
||||
|
||||
inline LONG MulDiv (long a, long b, long c)
|
||||
{
|
||||
/*if (!c) return 0;*/
|
||||
return ((uint64_t) a * (uint64_t) b ) / c;
|
||||
}
|
||||
|
||||
#define LPCTSTR LPCSTR
|
||||
#define lstrcpyn strncpy
|
||||
#define lstrcpy strcpy
|
||||
#define lstrcmp strcmp
|
||||
#define wsprintf sprintf
|
||||
|
||||
#define WAVE_FORMAT_PCM 1
|
||||
|
||||
#define GHND 0
|
||||
#define GlobalFreePtr(p) free((void *)(p))
|
||||
inline int8_t * GlobalAllocPtr(unsigned int, size_t size)
|
||||
{
|
||||
int8_t * p = (int8_t *) malloc(size);
|
||||
|
||||
if (p != NULL) memset(p, 0, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
inline void ProcessPlugins(int /* n */ ) {}
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE false
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE true
|
||||
#endif
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# if defined(MODPLUG_BUILD) && defined(DLL_EXPORT) /* building libmodplug as a dll for windows */
|
||||
# define MODPLUG_EXPORT __declspec(dllexport)
|
||||
# elif defined(MODPLUG_BUILD) || defined(MODPLUG_STATIC) /* building or using static libmodplug for windows */
|
||||
# define MODPLUG_EXPORT
|
||||
# else
|
||||
# define MODPLUG_EXPORT __declspec(dllimport) /* using libmodplug dll for windows */
|
||||
# endif
|
||||
#elif defined(MODPLUG_BUILD) && defined(SYM_VISIBILITY)
|
||||
# define MODPLUG_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define MODPLUG_EXPORT
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,604 @@
|
|||
/*
|
||||
* libopenmpt_modplug.c
|
||||
* --------------------
|
||||
* Purpose: libopenmpt emulation of the libmodplug interface
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef NO_LIBMODPLUG
|
||||
|
||||
#ifdef LIBOPENMPT_BUILD_DLL
|
||||
#undef LIBOPENMPT_BUILD_DLL
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#include <libopenmpt/libopenmpt.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MODPLUG_BUILD
|
||||
#ifdef _MSC_VER
|
||||
#ifdef MPT_BUILD_MSVC_SHARED
|
||||
#define DLL_EXPORT
|
||||
#endif /* MPT_BUILD_MSVC_SHARED */
|
||||
#ifdef MPT_BUILD_MSVC_STATIC
|
||||
#define MODPLUG_STATIC
|
||||
#endif /* MPT_BUILD_MSVC_STATIC */
|
||||
#endif /* _MSC_VER */
|
||||
#ifdef _MSC_VER
|
||||
#define LIBOPENMPT_MODPLUG_API
|
||||
#else /* !_MSC_VER */
|
||||
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT
|
||||
#endif /* _MSC_VER */
|
||||
#include "libmodplug/modplug.h"
|
||||
|
||||
/* from libmodplug/sndfile.h */
|
||||
/* header is not c clean */
|
||||
#define MIXING_ATTENUATION 4
|
||||
#define MOD_TYPE_NONE 0x0
|
||||
#define MOD_TYPE_MOD 0x1
|
||||
#define MOD_TYPE_S3M 0x2
|
||||
#define MOD_TYPE_XM 0x4
|
||||
#define MOD_TYPE_MED 0x8
|
||||
#define MOD_TYPE_MTM 0x10
|
||||
#define MOD_TYPE_IT 0x20
|
||||
#define MOD_TYPE_669 0x40
|
||||
#define MOD_TYPE_ULT 0x80
|
||||
#define MOD_TYPE_STM 0x100
|
||||
#define MOD_TYPE_FAR 0x200
|
||||
#define MOD_TYPE_WAV 0x400
|
||||
#define MOD_TYPE_AMF 0x800
|
||||
#define MOD_TYPE_AMS 0x1000
|
||||
#define MOD_TYPE_DSM 0x2000
|
||||
#define MOD_TYPE_MDL 0x4000
|
||||
#define MOD_TYPE_OKT 0x8000
|
||||
#define MOD_TYPE_MID 0x10000
|
||||
#define MOD_TYPE_DMF 0x20000
|
||||
#define MOD_TYPE_PTM 0x40000
|
||||
#define MOD_TYPE_DBM 0x80000
|
||||
#define MOD_TYPE_MT2 0x100000
|
||||
#define MOD_TYPE_AMF0 0x200000
|
||||
#define MOD_TYPE_PSM 0x400000
|
||||
#define MOD_TYPE_J2B 0x800000
|
||||
#define MOD_TYPE_ABC 0x1000000
|
||||
#define MOD_TYPE_PAT 0x2000000
|
||||
#define MOD_TYPE_UMX 0x80000000 // Fake type
|
||||
|
||||
#define BUFFER_COUNT 1024
|
||||
|
||||
struct _ModPlugFile {
|
||||
openmpt_module* mod;
|
||||
signed short* buf;
|
||||
signed int* mixerbuf;
|
||||
char* name;
|
||||
char* message;
|
||||
ModPlug_Settings settings;
|
||||
ModPlugMixerProc mixerproc;
|
||||
ModPlugNote** patterns;
|
||||
};
|
||||
|
||||
static ModPlug_Settings globalsettings = {
|
||||
MODPLUG_ENABLE_OVERSAMPLING|MODPLUG_ENABLE_NOISE_REDUCTION,
|
||||
2,
|
||||
16,
|
||||
44100,
|
||||
MODPLUG_RESAMPLE_LINEAR,
|
||||
128,
|
||||
256,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
static int32_t modplugresamplingmode_to_filterlength(int mode)
|
||||
{
|
||||
if(mode<0){
|
||||
return 1;
|
||||
}
|
||||
switch(mode){
|
||||
case MODPLUG_RESAMPLE_NEAREST: return 1; break;
|
||||
case MODPLUG_RESAMPLE_LINEAR: return 2; break;
|
||||
case MODPLUG_RESAMPLE_SPLINE: return 4; break;
|
||||
case MODPLUG_RESAMPLE_FIR: return 8; break;
|
||||
}
|
||||
return 8;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API ModPlugFile* ModPlug_Load(const void* data, int size)
|
||||
{
|
||||
ModPlugFile* file = malloc(sizeof(ModPlugFile));
|
||||
const char* name = NULL;
|
||||
const char* message = NULL;
|
||||
if(!file) return NULL;
|
||||
memset(file,0,sizeof(ModPlugFile));
|
||||
memcpy(&file->settings,&globalsettings,sizeof(ModPlug_Settings));
|
||||
file->mod = openmpt_module_create_from_memory2(data,size,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
if(!file->mod){
|
||||
free(file);
|
||||
return NULL;
|
||||
}
|
||||
file->buf = malloc(BUFFER_COUNT*sizeof(signed short)*4);
|
||||
if(!file->buf){
|
||||
openmpt_module_destroy(file->mod);
|
||||
free(file);
|
||||
return NULL;
|
||||
}
|
||||
openmpt_module_set_repeat_count(file->mod,file->settings.mLoopCount);
|
||||
name = openmpt_module_get_metadata(file->mod,"title");
|
||||
if(name){
|
||||
file->name = malloc(strlen(name)+1);
|
||||
if(file->name){
|
||||
strcpy(file->name,name);
|
||||
}
|
||||
openmpt_free_string(name);
|
||||
name = NULL;
|
||||
}else{
|
||||
file->name = malloc(strlen("")+1);
|
||||
if(file->name){
|
||||
strcpy(file->name,"");
|
||||
}
|
||||
}
|
||||
message = openmpt_module_get_metadata(file->mod,"message");
|
||||
if(message){
|
||||
file->message = malloc(strlen(message)+1);
|
||||
if(file->message){
|
||||
strcpy(file->message,message);
|
||||
}
|
||||
openmpt_free_string(message);
|
||||
message = NULL;
|
||||
}else{
|
||||
file->message = malloc(strlen("")+1);
|
||||
if(file->message){
|
||||
strcpy(file->message,"");
|
||||
}
|
||||
}
|
||||
openmpt_module_set_render_param(file->mod,OPENMPT_MODULE_RENDER_STEREOSEPARATION_PERCENT,file->settings.mStereoSeparation*100/128);
|
||||
openmpt_module_set_render_param(file->mod,OPENMPT_MODULE_RENDER_INTERPOLATIONFILTER_LENGTH,modplugresamplingmode_to_filterlength(file->settings.mResamplingMode));
|
||||
return file;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API void ModPlug_Unload(ModPlugFile* file)
|
||||
{
|
||||
int p;
|
||||
if(!file) return;
|
||||
if(file->patterns){
|
||||
for(p=0;p<openmpt_module_get_num_patterns(file->mod);p++){
|
||||
if(file->patterns[p]){
|
||||
free(file->patterns[p]);
|
||||
file->patterns[p] = NULL;
|
||||
}
|
||||
}
|
||||
free(file->patterns);
|
||||
file->patterns = NULL;
|
||||
}
|
||||
if(file->mixerbuf){
|
||||
free(file->mixerbuf);
|
||||
file->mixerbuf = NULL;
|
||||
}
|
||||
openmpt_module_destroy(file->mod);
|
||||
file->mod = NULL;
|
||||
free(file->name);
|
||||
file->name = NULL;
|
||||
free(file->message);
|
||||
file->message = NULL;
|
||||
free(file->buf);
|
||||
file->buf = NULL;
|
||||
free(file);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API int ModPlug_Read(ModPlugFile* file, void* buffer, int size)
|
||||
{
|
||||
int framesize;
|
||||
int framecount;
|
||||
int frames;
|
||||
int rendered;
|
||||
int frame;
|
||||
int channel;
|
||||
int totalrendered;
|
||||
signed short* in;
|
||||
signed int* mixbuf;
|
||||
unsigned char* buf8;
|
||||
signed short* buf16;
|
||||
signed int* buf32;
|
||||
if(!file) return 0;
|
||||
framesize = file->settings.mBits/8*file->settings.mChannels;
|
||||
framecount = size/framesize;
|
||||
buf8 = buffer;
|
||||
buf16 = buffer;
|
||||
buf32 = buffer;
|
||||
totalrendered = 0;
|
||||
while(framecount>0){
|
||||
frames = framecount;
|
||||
if(frames>BUFFER_COUNT){
|
||||
frames = BUFFER_COUNT;
|
||||
}
|
||||
if(file->settings.mChannels==1){
|
||||
rendered = (int)openmpt_module_read_mono(file->mod,file->settings.mFrequency,frames,&file->buf[frames*0]);
|
||||
}else if(file->settings.mChannels==2){
|
||||
rendered = (int)openmpt_module_read_stereo(file->mod,file->settings.mFrequency,frames,&file->buf[frames*0],&file->buf[frames*1]);
|
||||
}else if(file->settings.mChannels==4){
|
||||
rendered = (int)openmpt_module_read_quad(file->mod,file->settings.mFrequency,frames,&file->buf[frames*0],&file->buf[frames*1],&file->buf[frames*2],&file->buf[frames*3]);
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
in = file->buf;
|
||||
if(file->mixerproc&&file->mixerbuf){
|
||||
mixbuf=file->mixerbuf;
|
||||
for(frame=0;frame<frames;frame++){
|
||||
for(channel=0;channel<file->settings.mChannels;channel++){
|
||||
*mixbuf = in[frames*channel+frame]<<(32-16-1-MIXING_ATTENUATION);
|
||||
mixbuf++;
|
||||
}
|
||||
}
|
||||
file->mixerproc(file->mixerbuf,file->settings.mChannels*frames,file->settings.mChannels);
|
||||
mixbuf=file->mixerbuf;
|
||||
for(frame=0;frame<frames;frame++){
|
||||
for(channel=0;channel<file->settings.mChannels;channel++){
|
||||
in[frames*channel+frame] = *mixbuf>>(32-16-1-MIXING_ATTENUATION);
|
||||
mixbuf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(file->settings.mBits==8){
|
||||
for(frame=0;frame<frames;frame++){
|
||||
for(channel=0;channel<file->settings.mChannels;channel++){
|
||||
*buf8 = in[frames*channel+frame]/256+0x80;
|
||||
buf8++;
|
||||
}
|
||||
}
|
||||
}else if(file->settings.mBits==16){
|
||||
for(frame=0;frame<frames;frame++){
|
||||
for(channel=0;channel<file->settings.mChannels;channel++){
|
||||
*buf16 = in[frames*channel+frame];
|
||||
buf16++;
|
||||
}
|
||||
}
|
||||
}else if(file->settings.mBits==32){
|
||||
for(frame=0;frame<frames;frame++){
|
||||
for(channel=0;channel<file->settings.mChannels;channel++){
|
||||
*buf32 = in[frames*channel+frame] << (32-16-1-MIXING_ATTENUATION);
|
||||
buf32++;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
totalrendered += rendered;
|
||||
framecount -= frames;
|
||||
if(!rendered) break;
|
||||
}
|
||||
memset(((char*)buffer)+totalrendered*framesize,0,size-totalrendered*framesize);
|
||||
return totalrendered*framesize;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API const char* ModPlug_GetName(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return NULL;
|
||||
return file->name;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API int ModPlug_GetLength(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return (int)(openmpt_module_get_duration_seconds(file->mod)*1000.0);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API void ModPlug_Seek(ModPlugFile* file, int millisecond)
|
||||
{
|
||||
if(!file) return;
|
||||
openmpt_module_set_position_seconds(file->mod,(double)millisecond*0.001);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API void ModPlug_GetSettings(ModPlug_Settings* settings)
|
||||
{
|
||||
if(!settings) return;
|
||||
memcpy(settings,&globalsettings,sizeof(ModPlug_Settings));
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API void ModPlug_SetSettings(const ModPlug_Settings* settings)
|
||||
{
|
||||
if(!settings) return;
|
||||
memcpy(&globalsettings,settings,sizeof(ModPlug_Settings));
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API unsigned int ModPlug_GetMasterVolume(ModPlugFile* file)
|
||||
{
|
||||
int32_t val;
|
||||
if(!file) return 0;
|
||||
val = 0;
|
||||
if(!openmpt_module_get_render_param(file->mod,OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL,&val)) return 128;
|
||||
return (unsigned int)(128.0*pow(10.0,val*0.0005));
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API void ModPlug_SetMasterVolume(ModPlugFile* file,unsigned int cvol)
|
||||
{
|
||||
if(!file) return;
|
||||
openmpt_module_set_render_param(file->mod,OPENMPT_MODULE_RENDER_MASTERGAIN_MILLIBEL,(int32_t)(2000.0*log10(cvol/128.0)));
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentSpeed(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_current_speed(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentTempo(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_current_tempo(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentOrder(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_current_order(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentPattern(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_current_pattern(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API int ModPlug_GetCurrentRow(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_current_row(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API int ModPlug_GetPlayingChannels(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_current_playing_channels(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API void ModPlug_SeekOrder(ModPlugFile* file,int order)
|
||||
{
|
||||
if(!file) return;
|
||||
openmpt_module_set_position_order_row(file->mod,order,0);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API int ModPlug_GetModuleType(ModPlugFile* file)
|
||||
{
|
||||
const char* type;
|
||||
int retval;
|
||||
if(!file) return 0;
|
||||
type = openmpt_module_get_metadata(file->mod,"type");
|
||||
retval = MOD_TYPE_NONE;
|
||||
if(!type){
|
||||
return retval;
|
||||
}
|
||||
if(!strcmp(type,"mod")){
|
||||
retval = MOD_TYPE_MOD;
|
||||
}else if(!strcmp(type,"s3m")){
|
||||
retval = MOD_TYPE_S3M;
|
||||
}else if(!strcmp(type,"xm")){
|
||||
retval = MOD_TYPE_XM;
|
||||
}else if(!strcmp(type,"med")){
|
||||
retval = MOD_TYPE_MED;
|
||||
}else if(!strcmp(type,"mtm")){
|
||||
retval = MOD_TYPE_MTM;
|
||||
}else if(!strcmp(type,"it")){
|
||||
retval = MOD_TYPE_IT;
|
||||
}else if(!strcmp(type,"669")){
|
||||
retval = MOD_TYPE_669;
|
||||
}else if(!strcmp(type,"ult")){
|
||||
retval = MOD_TYPE_ULT;
|
||||
}else if(!strcmp(type,"stm")){
|
||||
retval = MOD_TYPE_STM;
|
||||
}else if(!strcmp(type,"far")){
|
||||
retval = MOD_TYPE_FAR;
|
||||
}else if(!strcmp(type,"s3m")){
|
||||
retval = MOD_TYPE_WAV;
|
||||
}else if(!strcmp(type,"amf")){
|
||||
retval = MOD_TYPE_AMF;
|
||||
}else if(!strcmp(type,"ams")){
|
||||
retval = MOD_TYPE_AMS;
|
||||
}else if(!strcmp(type,"dsm")){
|
||||
retval = MOD_TYPE_DSM;
|
||||
}else if(!strcmp(type,"mdl")){
|
||||
retval = MOD_TYPE_MDL;
|
||||
}else if(!strcmp(type,"okt")){
|
||||
retval = MOD_TYPE_OKT;
|
||||
}else if(!strcmp(type,"mid")){
|
||||
retval = MOD_TYPE_MID;
|
||||
}else if(!strcmp(type,"dmf")){
|
||||
retval = MOD_TYPE_DMF;
|
||||
}else if(!strcmp(type,"ptm")){
|
||||
retval = MOD_TYPE_PTM;
|
||||
}else if(!strcmp(type,"dbm")){
|
||||
retval = MOD_TYPE_DBM;
|
||||
}else if(!strcmp(type,"mt2")){
|
||||
retval = MOD_TYPE_MT2;
|
||||
}else if(!strcmp(type,"amf0")){
|
||||
retval = MOD_TYPE_AMF0;
|
||||
}else if(!strcmp(type,"psm")){
|
||||
retval = MOD_TYPE_PSM;
|
||||
}else if(!strcmp(type,"j2b")){
|
||||
retval = MOD_TYPE_J2B;
|
||||
}else if(!strcmp(type,"abc")){
|
||||
retval = MOD_TYPE_ABC;
|
||||
}else if(!strcmp(type,"pat")){
|
||||
retval = MOD_TYPE_PAT;
|
||||
}else if(!strcmp(type,"umx")){
|
||||
retval = MOD_TYPE_UMX;
|
||||
}else{
|
||||
retval = MOD_TYPE_IT; /* fallback, most complex type */
|
||||
}
|
||||
openmpt_free_string(type);
|
||||
return retval;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API char* ModPlug_GetMessage(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return NULL;
|
||||
return file->message;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumInstruments(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_num_instruments(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumSamples(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_num_samples(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumPatterns(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_num_patterns(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API unsigned int ModPlug_NumChannels(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return 0;
|
||||
return openmpt_module_get_num_channels(file->mod);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API unsigned int ModPlug_SampleName(ModPlugFile* file, unsigned int qual, char* buff)
|
||||
{
|
||||
const char* str;
|
||||
char buf[32];
|
||||
if(!file) return 0;
|
||||
str = openmpt_module_get_sample_name(file->mod,qual-1);
|
||||
memset(buf,0,32);
|
||||
if(str){
|
||||
strncpy(buf,str,31);
|
||||
openmpt_free_string(str);
|
||||
}
|
||||
if(buff){
|
||||
strncpy(buff,buf,32);
|
||||
}
|
||||
return (unsigned int)strlen(buf);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API unsigned int ModPlug_InstrumentName(ModPlugFile* file, unsigned int qual, char* buff)
|
||||
{
|
||||
const char* str;
|
||||
char buf[32];
|
||||
if(!file) return 0;
|
||||
str = openmpt_module_get_instrument_name(file->mod,qual-1);
|
||||
memset(buf,0,32);
|
||||
if(str){
|
||||
strncpy(buf,str,31);
|
||||
openmpt_free_string(str);
|
||||
}
|
||||
if(buff){
|
||||
strncpy(buff,buf,32);
|
||||
}
|
||||
return (unsigned int)strlen(buf);
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API ModPlugNote* ModPlug_GetPattern(ModPlugFile* file, int pattern, unsigned int* numrows)
|
||||
{
|
||||
int c;
|
||||
int r;
|
||||
int numr;
|
||||
int numc;
|
||||
ModPlugNote note;
|
||||
if(!file) return NULL;
|
||||
if(numrows){
|
||||
*numrows = openmpt_module_get_pattern_num_rows(file->mod,pattern);
|
||||
}
|
||||
if(pattern<0||pattern>=openmpt_module_get_num_patterns(file->mod)){
|
||||
return NULL;
|
||||
}
|
||||
if(!file->patterns){
|
||||
file->patterns = malloc(sizeof(ModPlugNote*)*openmpt_module_get_pattern_num_rows(file->mod,pattern));
|
||||
if(!file->patterns) return NULL;
|
||||
memset(file->patterns,0,sizeof(ModPlugNote*)*openmpt_module_get_pattern_num_rows(file->mod,pattern));
|
||||
}
|
||||
if(!file->patterns[pattern]){
|
||||
file->patterns[pattern] = malloc(sizeof(ModPlugNote)*openmpt_module_get_pattern_num_rows(file->mod,pattern)*openmpt_module_get_num_channels(file->mod));
|
||||
if(!file->patterns[pattern]) return NULL;
|
||||
memset(file->patterns[pattern],0,sizeof(ModPlugNote)*openmpt_module_get_pattern_num_rows(file->mod,pattern)*openmpt_module_get_num_channels(file->mod));
|
||||
}
|
||||
numr = openmpt_module_get_pattern_num_rows(file->mod,pattern);
|
||||
numc = openmpt_module_get_num_channels(file->mod);
|
||||
for(r=0;r<numr;r++){
|
||||
for(c=0;c<numc;c++){
|
||||
memset(¬e,0,sizeof(ModPlugNote));
|
||||
note.Note = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_NOTE);
|
||||
note.Instrument = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_INSTRUMENT);
|
||||
note.VolumeEffect = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_VOLUMEEFFECT);
|
||||
note.Effect = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_EFFECT);
|
||||
note.Volume = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_VOLUME);
|
||||
note.Parameter = openmpt_module_get_pattern_row_channel_command(file->mod,pattern,r,c,OPENMPT_MODULE_COMMAND_PARAMETER);
|
||||
memcpy(&file->patterns[pattern][r*numc+c],¬e,sizeof(ModPlugNote));
|
||||
}
|
||||
}
|
||||
return file->patterns[pattern];
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API void ModPlug_InitMixerCallback(ModPlugFile* file,ModPlugMixerProc proc)
|
||||
{
|
||||
if(!file) return;
|
||||
if(!file->mixerbuf){
|
||||
file->mixerbuf = malloc(BUFFER_COUNT*sizeof(signed int)*4);
|
||||
}
|
||||
file->mixerproc = proc;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API void ModPlug_UnloadMixerCallback(ModPlugFile* file)
|
||||
{
|
||||
if(!file) return;
|
||||
file->mixerproc = NULL;
|
||||
if(file->mixerbuf){
|
||||
free(file->mixerbuf);
|
||||
file->mixerbuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API char ModPlug_ExportS3M(ModPlugFile* file, const char* filepath)
|
||||
{
|
||||
(void)file;
|
||||
/* not implemented */
|
||||
fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportS3M(%s) not implemented.\n",filepath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API char ModPlug_ExportXM(ModPlugFile* file, const char* filepath)
|
||||
{
|
||||
(void)file;
|
||||
/* not implemented */
|
||||
fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportXM(%s) not implemented.\n",filepath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API char ModPlug_ExportMOD(ModPlugFile* file, const char* filepath)
|
||||
{
|
||||
(void)file;
|
||||
/* not implemented */
|
||||
fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportMOD(%s) not implemented.\n",filepath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBOPENMPT_MODPLUG_API char ModPlug_ExportIT(ModPlugFile* file, const char* filepath)
|
||||
{
|
||||
(void)file;
|
||||
/* not implemented */
|
||||
fprintf(stderr,"libopenmpt-modplug: error: ModPlug_ExportIT(%s) not implemented.\n",filepath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* NO_LIBMODPLUG */
|
|
@ -0,0 +1,12 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libopenmpt_modplug
|
||||
Description: The ModPlug mod file playing library (emulated via libopenmpt).
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires.private: libopenmpt
|
||||
Libs: -L${libdir} -lopenmpt_modplug
|
||||
Libs.private:
|
||||
Cflags: -I${includedir}
|
|
@ -0,0 +1,887 @@
|
|||
/*
|
||||
* libopenmpt_modplug_cpp.cpp
|
||||
* --------------------------
|
||||
* Purpose: libopenmpt emulation of the libmodplug c++ interface
|
||||
* Notes : WARNING! THIS IS A HACK!
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#ifndef NO_LIBMODPLUG
|
||||
|
||||
/*
|
||||
|
||||
***********************************************************************
|
||||
WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||
***********************************************************************
|
||||
|
||||
This is a dirty hack to emulate just so much of the libmodplug c++
|
||||
interface so that the current known users (mainly xmms-modplug itself,
|
||||
gstreamer modplug, audacious, and stuff based on those) work. This is
|
||||
neither a complete nor a correct implementation.
|
||||
Metadata and other state is not provided or updated.
|
||||
|
||||
*/
|
||||
|
||||
#ifdef UNICODE
|
||||
#undef UNICODE
|
||||
#endif
|
||||
#ifdef _UNICODE
|
||||
#undef _UNICODE
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#include <libopenmpt/libopenmpt.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#define MODPLUG_BUILD
|
||||
#ifdef _MSC_VER
|
||||
/* libmodplug C++ header is broken for MSVC DLL builds */
|
||||
#define MODPLUG_STATIC
|
||||
#endif /* _MSC_VER */
|
||||
#ifdef _MSC_VER
|
||||
#define LIBOPENMPT_MODPLUG_API
|
||||
#else /* !_MSC_VER */
|
||||
#define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT
|
||||
#endif /* _MSC_VER */
|
||||
class LIBOPENMPT_MODPLUG_API CSoundFile;
|
||||
#include "libmodplug/stdafx.h"
|
||||
#include "libmodplug/sndfile.h"
|
||||
|
||||
namespace {
|
||||
template <class T>
|
||||
void Clear( T & x )
|
||||
{
|
||||
std::memset( &x, 0, sizeof(T) );
|
||||
}
|
||||
}
|
||||
|
||||
//#define mpcpplog() fprintf(stderr, "%s %i\n", __func__, __LINE__)
|
||||
#define mpcpplog() do{}while(0)
|
||||
|
||||
#define UNUSED(x) (void)((x))
|
||||
|
||||
union self_t {
|
||||
CHAR CompressionTable[16];
|
||||
openmpt::module * self_;
|
||||
};
|
||||
|
||||
static void set_self( CSoundFile * that, openmpt::module * self_ ) {
|
||||
self_t self_union;
|
||||
Clear(self_union);
|
||||
self_union.self_ = self_;
|
||||
std::memcpy( that->CompressionTable, self_union.CompressionTable, sizeof( self_union.CompressionTable ) );
|
||||
}
|
||||
|
||||
static openmpt::module * get_self( const CSoundFile * that ) {
|
||||
self_t self_union;
|
||||
Clear(self_union);
|
||||
std::memcpy( self_union.CompressionTable, that->CompressionTable, sizeof( self_union.CompressionTable ) );
|
||||
return self_union.self_;
|
||||
}
|
||||
|
||||
#define mod ( get_self( this ) )
|
||||
|
||||
#define update_state() \
|
||||
if ( mod ) m_nCurrentPattern = mod->get_current_order(); \
|
||||
if ( mod ) m_nPattern = mod->get_current_pattern(); \
|
||||
if ( mod ) m_nMusicSpeed = mod->get_current_speed(); \
|
||||
if ( mod ) m_nMusicTempo = mod->get_current_tempo(); \
|
||||
/**/
|
||||
|
||||
UINT CSoundFile::m_nXBassDepth = 0;
|
||||
UINT CSoundFile::m_nXBassRange = 0;
|
||||
UINT CSoundFile::m_nReverbDepth = 0;
|
||||
UINT CSoundFile::m_nReverbDelay = 0;
|
||||
UINT CSoundFile::gnReverbType = 0;
|
||||
UINT CSoundFile::m_nProLogicDepth = 0;
|
||||
UINT CSoundFile::m_nProLogicDelay = 0;
|
||||
UINT CSoundFile::m_nStereoSeparation = 128;
|
||||
UINT CSoundFile::m_nMaxMixChannels = 256;
|
||||
LONG CSoundFile::m_nStreamVolume = 0x8000;
|
||||
DWORD CSoundFile::gdwSysInfo = 0;
|
||||
DWORD CSoundFile::gdwSoundSetup = 0;
|
||||
DWORD CSoundFile::gdwMixingFreq = 44100;
|
||||
DWORD CSoundFile::gnBitsPerSample = 16;
|
||||
DWORD CSoundFile::gnChannels = 2;
|
||||
UINT CSoundFile::gnAGC = 0;
|
||||
UINT CSoundFile::gnVolumeRampSamples = 0;
|
||||
UINT CSoundFile::gnVUMeter = 0;
|
||||
UINT CSoundFile::gnCPUUsage = 0;
|
||||
LPSNDMIXHOOKPROC CSoundFile::gpSndMixHook = 0;
|
||||
PMIXPLUGINCREATEPROC CSoundFile::gpMixPluginCreateProc = 0;
|
||||
|
||||
CSoundFile::CSoundFile() {
|
||||
mpcpplog();
|
||||
Clear(Chn);
|
||||
Clear(ChnMix);
|
||||
Clear(Ins);
|
||||
Clear(Headers);
|
||||
Clear(ChnSettings);
|
||||
Clear(Patterns);
|
||||
Clear(PatternSize);
|
||||
Clear(Order);
|
||||
Clear(m_MidiCfg);
|
||||
Clear(m_MixPlugins);
|
||||
Clear(m_nDefaultSpeed);
|
||||
Clear(m_nDefaultTempo);
|
||||
Clear(m_nDefaultGlobalVolume);
|
||||
Clear(m_dwSongFlags);
|
||||
Clear(m_nChannels);
|
||||
Clear(m_nMixChannels);
|
||||
Clear(m_nMixStat);
|
||||
Clear(m_nBufferCount);
|
||||
Clear(m_nType);
|
||||
Clear(m_nSamples);
|
||||
Clear(m_nInstruments);
|
||||
Clear(m_nTickCount);
|
||||
Clear(m_nTotalCount);
|
||||
Clear(m_nPatternDelay);
|
||||
Clear(m_nFrameDelay);
|
||||
Clear(m_nMusicSpeed);
|
||||
Clear(m_nMusicTempo);
|
||||
Clear(m_nNextRow);
|
||||
Clear(m_nRow);
|
||||
Clear(m_nPattern);
|
||||
Clear(m_nCurrentPattern);
|
||||
Clear(m_nNextPattern);
|
||||
Clear(m_nRestartPos);
|
||||
Clear(m_nMasterVolume);
|
||||
Clear(m_nGlobalVolume);
|
||||
Clear(m_nSongPreAmp);
|
||||
Clear(m_nFreqFactor);
|
||||
Clear(m_nTempoFactor);
|
||||
Clear(m_nOldGlbVolSlide);
|
||||
Clear(m_nMinPeriod);
|
||||
Clear(m_nMaxPeriod);
|
||||
Clear(m_nRepeatCount);
|
||||
Clear(m_nInitialRepeatCount);
|
||||
Clear(m_nGlobalFadeSamples);
|
||||
Clear(m_nGlobalFadeMaxSamples);
|
||||
Clear(m_nMaxOrderPosition);
|
||||
Clear(m_nPatternNames);
|
||||
Clear(m_lpszSongComments);
|
||||
Clear(m_lpszPatternNames);
|
||||
Clear(m_szNames);
|
||||
Clear(CompressionTable);
|
||||
}
|
||||
|
||||
CSoundFile::~CSoundFile() {
|
||||
mpcpplog();
|
||||
Destroy();
|
||||
}
|
||||
|
||||
BOOL CSoundFile::Create( LPCBYTE lpStream, DWORD dwMemLength ) {
|
||||
mpcpplog();
|
||||
try {
|
||||
openmpt::module * m = new openmpt::module( lpStream, dwMemLength );
|
||||
set_self( this, m );
|
||||
std::strncpy( m_szNames[0], mod->get_metadata("title").c_str(), sizeof( m_szNames[0] ) - 1 );
|
||||
m_szNames[0][ sizeof( m_szNames[0] ) - 1 ] = '\0';
|
||||
std::string type = mod->get_metadata("type");
|
||||
m_nType = MOD_TYPE_NONE;
|
||||
if ( type == "mod" ) {
|
||||
m_nType = MOD_TYPE_MOD;
|
||||
} else if ( type == "s3m" ) {
|
||||
m_nType = MOD_TYPE_S3M;
|
||||
} else if ( type == "xm" ) {
|
||||
m_nType = MOD_TYPE_XM;
|
||||
} else if ( type == "med" ) {
|
||||
m_nType = MOD_TYPE_MED;
|
||||
} else if ( type == "mtm" ) {
|
||||
m_nType = MOD_TYPE_MTM;
|
||||
} else if ( type == "it" ) {
|
||||
m_nType = MOD_TYPE_IT;
|
||||
} else if ( type == "669" ) {
|
||||
m_nType = MOD_TYPE_669;
|
||||
} else if ( type == "ult" ) {
|
||||
m_nType = MOD_TYPE_ULT;
|
||||
} else if ( type == "stm" ) {
|
||||
m_nType = MOD_TYPE_STM;
|
||||
} else if ( type == "far" ) {
|
||||
m_nType = MOD_TYPE_FAR;
|
||||
} else if ( type == "s3m" ) {
|
||||
m_nType = MOD_TYPE_WAV;
|
||||
} else if ( type == "amf" ) {
|
||||
m_nType = MOD_TYPE_AMF;
|
||||
} else if ( type == "ams" ) {
|
||||
m_nType = MOD_TYPE_AMS;
|
||||
} else if ( type == "dsm" ) {
|
||||
m_nType = MOD_TYPE_DSM;
|
||||
} else if ( type == "mdl" ) {
|
||||
m_nType = MOD_TYPE_MDL;
|
||||
} else if ( type == "okt" ) {
|
||||
m_nType = MOD_TYPE_OKT;
|
||||
} else if ( type == "mid" ) {
|
||||
m_nType = MOD_TYPE_MID;
|
||||
} else if ( type == "dmf" ) {
|
||||
m_nType = MOD_TYPE_DMF;
|
||||
} else if ( type == "ptm" ) {
|
||||
m_nType = MOD_TYPE_PTM;
|
||||
} else if ( type == "dbm" ) {
|
||||
m_nType = MOD_TYPE_DBM;
|
||||
} else if ( type == "mt2" ) {
|
||||
m_nType = MOD_TYPE_MT2;
|
||||
} else if ( type == "amf0" ) {
|
||||
m_nType = MOD_TYPE_AMF0;
|
||||
} else if ( type == "psm" ) {
|
||||
m_nType = MOD_TYPE_PSM;
|
||||
} else if ( type == "j2b" ) {
|
||||
m_nType = MOD_TYPE_J2B;
|
||||
} else if ( type == "abc" ) {
|
||||
m_nType = MOD_TYPE_ABC;
|
||||
} else if ( type == "pat" ) {
|
||||
m_nType = MOD_TYPE_PAT;
|
||||
} else if ( type == "umx" ) {
|
||||
m_nType = MOD_TYPE_UMX;
|
||||
} else {
|
||||
m_nType = MOD_TYPE_IT; // fallback, most complex type
|
||||
}
|
||||
m_nChannels = mod->get_num_channels();
|
||||
m_nMasterVolume = 128;
|
||||
m_nSamples = mod->get_num_samples();
|
||||
update_state();
|
||||
return TRUE;
|
||||
} catch ( ... ) {
|
||||
Destroy();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CSoundFile::Destroy() {
|
||||
mpcpplog();
|
||||
if ( mod ) {
|
||||
delete mod;
|
||||
set_self( this, 0 );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetNumChannels() const {
|
||||
mpcpplog();
|
||||
return mod->get_num_channels();
|
||||
}
|
||||
|
||||
static std::int32_t vol128_To_millibel( unsigned int vol ) {
|
||||
return static_cast<std::int32_t>( 2000.0 * std::log10( static_cast<int>( vol ) / 128.0 ) );
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SetMasterVolume( UINT vol, BOOL bAdjustAGC ) {
|
||||
UNUSED(bAdjustAGC);
|
||||
mpcpplog();
|
||||
m_nMasterVolume = vol;
|
||||
mod->set_render_param( openmpt::module::RENDER_MASTERGAIN_MILLIBEL, vol128_To_millibel( m_nMasterVolume ) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetNumPatterns() const {
|
||||
mpcpplog();
|
||||
return mod->get_num_patterns();
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetNumInstruments() const {
|
||||
mpcpplog();
|
||||
return mod->get_num_instruments();
|
||||
}
|
||||
|
||||
void CSoundFile::SetCurrentOrder( UINT nOrder ) {
|
||||
mpcpplog();
|
||||
mod->set_position_order_row( nOrder, 0 );
|
||||
update_state();
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetSampleName( UINT nSample, LPSTR s ) const {
|
||||
mpcpplog();
|
||||
char buf[32];
|
||||
std::memset( buf, 0, 32 );
|
||||
if ( mod ) {
|
||||
std::vector<std::string> names = mod->get_sample_names();
|
||||
if ( 1 <= nSample && nSample <= names.size() ) {
|
||||
std::strncpy( buf, names[ nSample - 1 ].c_str(), 31 );
|
||||
}
|
||||
}
|
||||
if ( s ) {
|
||||
std::strncpy( s, buf, 32 );
|
||||
}
|
||||
return static_cast<UINT>( std::strlen( buf ) );
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetInstrumentName( UINT nInstr, LPSTR s ) const {
|
||||
mpcpplog();
|
||||
char buf[32];
|
||||
std::memset( buf, 0, 32 );
|
||||
if ( mod ) {
|
||||
std::vector<std::string> names = mod->get_instrument_names();
|
||||
if ( 1 <= nInstr && nInstr <= names.size() ) {
|
||||
std::strncpy( buf, names[ nInstr - 1 ].c_str(), 31 );
|
||||
}
|
||||
}
|
||||
if ( s ) {
|
||||
std::strncpy( s, buf, 32 );
|
||||
}
|
||||
return static_cast<UINT>( std::strlen( buf ) );
|
||||
}
|
||||
|
||||
void CSoundFile::LoopPattern( int nPat, int nRow ) {
|
||||
UNUSED(nPat);
|
||||
UNUSED(nRow);
|
||||
mpcpplog();
|
||||
// todo
|
||||
}
|
||||
|
||||
void CSoundFile::CheckCPUUsage( UINT nCPU ) {
|
||||
UNUSED(nCPU);
|
||||
mpcpplog();
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SetPatternName( UINT nPat, LPCSTR lpszName ) {
|
||||
UNUSED(nPat);
|
||||
mpcpplog();
|
||||
if ( !lpszName ) {
|
||||
return FALSE;
|
||||
}
|
||||
// todo
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::GetPatternName( UINT nPat, LPSTR lpszName, UINT cbSize ) const {
|
||||
UNUSED(nPat);
|
||||
mpcpplog();
|
||||
if ( !lpszName || cbSize <= 0 ) {
|
||||
return FALSE;
|
||||
}
|
||||
std::memset( lpszName, 0, cbSize );
|
||||
// todo
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::ReadXM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadS3M(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadMod(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadMed(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadMTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadSTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadIT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::Read669(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadUlt(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadWav(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadDSM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadFAR(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadMDL(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadOKT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadDMF(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadPTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadDBM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadUMX(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadABC(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::TestABC(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadMID(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::TestMID(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::ReadPAT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
BOOL CSoundFile::TestPAT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
|
||||
|
||||
#ifndef MODPLUG_NO_FILESAVE
|
||||
|
||||
UINT CSoundFile::WriteSample( FILE * f, MODINSTRUMENT * pins, UINT nFlags, UINT nMaxLen ) {
|
||||
UNUSED(f);
|
||||
UNUSED(pins);
|
||||
UNUSED(nFlags);
|
||||
UNUSED(nMaxLen);
|
||||
mpcpplog();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SaveXM( LPCSTR lpszFileName, UINT nPacking ) {
|
||||
UNUSED(lpszFileName);
|
||||
UNUSED(nPacking);
|
||||
mpcpplog();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SaveS3M( LPCSTR lpszFileName, UINT nPacking ) {
|
||||
UNUSED(lpszFileName);
|
||||
UNUSED(nPacking);
|
||||
mpcpplog();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SaveMod( LPCSTR lpszFileName, UINT nPacking ) {
|
||||
UNUSED(lpszFileName);
|
||||
UNUSED(nPacking);
|
||||
mpcpplog();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SaveIT( LPCSTR lpszFileName, UINT nPacking ) {
|
||||
UNUSED(lpszFileName);
|
||||
UNUSED(nPacking);
|
||||
mpcpplog();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
UINT CSoundFile::GetBestSaveFormat() const {
|
||||
mpcpplog();
|
||||
return MOD_TYPE_IT;
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetSaveFormats() const {
|
||||
mpcpplog();
|
||||
return MOD_TYPE_IT;
|
||||
}
|
||||
|
||||
void CSoundFile::ConvertModCommand( MODCOMMAND * ) const {
|
||||
mpcpplog();
|
||||
}
|
||||
|
||||
void CSoundFile::S3MConvert( MODCOMMAND * m, BOOL bIT ) const {
|
||||
UNUSED(m);
|
||||
UNUSED(bIT);
|
||||
mpcpplog();
|
||||
}
|
||||
|
||||
void CSoundFile::S3MSaveConvert( UINT * pcmd, UINT * pprm, BOOL bIT ) const {
|
||||
UNUSED(pcmd);
|
||||
UNUSED(pprm);
|
||||
UNUSED(bIT);
|
||||
mpcpplog();
|
||||
}
|
||||
|
||||
WORD CSoundFile::ModSaveCommand( const MODCOMMAND * m, BOOL bXM ) const {
|
||||
UNUSED(m);
|
||||
UNUSED(bXM);
|
||||
mpcpplog();
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID CSoundFile::ResetChannels() {
|
||||
mpcpplog();
|
||||
}
|
||||
|
||||
UINT CSoundFile::CreateStereoMix( int count ) {
|
||||
UNUSED(count);
|
||||
mpcpplog();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::FadeSong( UINT msec ) {
|
||||
UNUSED(msec);
|
||||
mpcpplog();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::GlobalFadeSong( UINT msec ) {
|
||||
UNUSED(msec);
|
||||
mpcpplog();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::InitPlayer( BOOL bReset ) {
|
||||
UNUSED(bReset);
|
||||
mpcpplog();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SetMixConfig( UINT nStereoSeparation, UINT nMaxMixChannels ) {
|
||||
UNUSED(nMaxMixChannels);
|
||||
mpcpplog();
|
||||
m_nStereoSeparation = nStereoSeparation;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD CSoundFile::InitSysInfo() {
|
||||
mpcpplog();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSoundFile::SetAGC( BOOL b ) {
|
||||
UNUSED(b);
|
||||
mpcpplog();
|
||||
}
|
||||
|
||||
void CSoundFile::ResetAGC() {
|
||||
mpcpplog();
|
||||
}
|
||||
|
||||
void CSoundFile::ProcessAGC( int count ) {
|
||||
UNUSED(count);
|
||||
mpcpplog();
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SetWaveConfig( UINT nRate, UINT nBits, UINT nChannels, BOOL bMMX ) {
|
||||
UNUSED(bMMX);
|
||||
mpcpplog();
|
||||
gdwMixingFreq = nRate;
|
||||
gnBitsPerSample = nBits;
|
||||
gnChannels = nChannels;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SetWaveConfigEx( BOOL bSurround, BOOL bNoOverSampling, BOOL bReverb, BOOL hqido, BOOL bMegaBass, BOOL bNR, BOOL bEQ ) {
|
||||
UNUSED(bSurround);
|
||||
UNUSED(bReverb);
|
||||
UNUSED(hqido);
|
||||
UNUSED(bMegaBass);
|
||||
UNUSED(bEQ);
|
||||
mpcpplog();
|
||||
DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
|
||||
if ( bNoOverSampling ) {
|
||||
d |= SNDMIX_NORESAMPLING;
|
||||
} else if ( !hqido ) {
|
||||
d |= 0;
|
||||
} else if ( !bNR ) {
|
||||
d |= SNDMIX_HQRESAMPLER;
|
||||
} else {
|
||||
d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
|
||||
}
|
||||
gdwSoundSetup = d;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SetResamplingMode( UINT nMode ) {
|
||||
mpcpplog();
|
||||
DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
|
||||
switch ( nMode ) {
|
||||
case SRCMODE_NEAREST:
|
||||
d |= SNDMIX_NORESAMPLING;
|
||||
break;
|
||||
case SRCMODE_LINEAR:
|
||||
break;
|
||||
case SRCMODE_SPLINE:
|
||||
d |= SNDMIX_HQRESAMPLER;
|
||||
break;
|
||||
case SRCMODE_POLYPHASE:
|
||||
d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
gdwSoundSetup = d;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SetReverbParameters( UINT nDepth, UINT nDelay ) {
|
||||
UNUSED(nDepth);
|
||||
UNUSED(nDelay);
|
||||
mpcpplog();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SetXBassParameters( UINT nDepth, UINT nRange ) {
|
||||
UNUSED(nDepth);
|
||||
UNUSED(nRange);
|
||||
mpcpplog();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL CSoundFile::SetSurroundParameters( UINT nDepth, UINT nDelay ) {
|
||||
UNUSED(nDepth);
|
||||
UNUSED(nDelay);
|
||||
mpcpplog();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetMaxPosition() const {
|
||||
mpcpplog();
|
||||
// rows in original, just use seconds here
|
||||
if ( mod ) return static_cast<UINT>( mod->get_duration_seconds() + 0.5 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD CSoundFile::GetLength( BOOL bAdjust, BOOL bTotal ) {
|
||||
UNUSED(bAdjust);
|
||||
UNUSED(bTotal);
|
||||
mpcpplog();
|
||||
if ( mod ) return static_cast<DWORD>( mod->get_duration_seconds() + 0.5 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetSongComments( LPSTR s, UINT cbsize, UINT linesize ) {
|
||||
UNUSED(linesize);
|
||||
mpcpplog();
|
||||
if ( !s ) {
|
||||
return 0;
|
||||
}
|
||||
if ( cbsize <= 0 ) {
|
||||
return 0;
|
||||
}
|
||||
if ( !mod ) {
|
||||
s[0] = '\0';
|
||||
return 1;
|
||||
}
|
||||
std::strncpy( s, mod->get_metadata("message").c_str(), cbsize );
|
||||
s[ cbsize - 1 ] = '\0';
|
||||
return static_cast<UINT>( std::strlen( s ) + 1 );
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetRawSongComments( LPSTR s, UINT cbsize, UINT linesize ) {
|
||||
UNUSED(linesize);
|
||||
mpcpplog();
|
||||
if ( !s ) {
|
||||
return 0;
|
||||
}
|
||||
if ( cbsize <= 0 ) {
|
||||
return 0;
|
||||
}
|
||||
if ( !mod ) {
|
||||
s[0] = '\0';
|
||||
return 1;
|
||||
}
|
||||
std::strncpy( s, mod->get_metadata("message_raw").c_str(), cbsize );
|
||||
s[ cbsize - 1 ] = '\0';
|
||||
return static_cast<UINT>( std::strlen( s ) + 1 );
|
||||
}
|
||||
|
||||
void CSoundFile::SetCurrentPos( UINT nPos ) {
|
||||
mpcpplog();
|
||||
if ( mod ) mod->set_position_seconds( nPos );
|
||||
update_state();
|
||||
}
|
||||
|
||||
UINT CSoundFile::GetCurrentPos() const {
|
||||
mpcpplog();
|
||||
if ( mod ) return static_cast<UINT>( mod->get_position_seconds() + 0.5 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_stereo_separation() {
|
||||
mpcpplog();
|
||||
return CSoundFile::m_nStereoSeparation * 100 / 128;
|
||||
}
|
||||
|
||||
static int get_filter_length() {
|
||||
mpcpplog();
|
||||
if ( ( CSoundFile::gdwSoundSetup & (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) ) == (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) ) {
|
||||
return 8;
|
||||
} else if ( ( CSoundFile::gdwSoundSetup & SNDMIX_HQRESAMPLER ) == SNDMIX_HQRESAMPLER ) {
|
||||
return 4;
|
||||
} else if ( ( CSoundFile::gdwSoundSetup & SNDMIX_NORESAMPLING ) == SNDMIX_NORESAMPLING ) {
|
||||
return 1;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
static std::size_t get_sample_size() {
|
||||
return (CSoundFile::gnBitsPerSample/8);
|
||||
}
|
||||
|
||||
static std::size_t get_num_channels() {
|
||||
return CSoundFile::gnChannels;
|
||||
}
|
||||
|
||||
static std::size_t get_frame_size() {
|
||||
return get_sample_size() * get_num_channels();
|
||||
}
|
||||
|
||||
static int get_samplerate() {
|
||||
return CSoundFile::gdwMixingFreq;
|
||||
}
|
||||
|
||||
UINT CSoundFile::Read( LPVOID lpBuffer, UINT cbBuffer ) {
|
||||
mpcpplog();
|
||||
if ( !mod ) {
|
||||
return 0;
|
||||
}
|
||||
mpcpplog();
|
||||
if ( !lpBuffer ) {
|
||||
return 0;
|
||||
}
|
||||
mpcpplog();
|
||||
if ( cbBuffer <= 0 ) {
|
||||
return 0;
|
||||
}
|
||||
mpcpplog();
|
||||
if ( get_samplerate() <= 0 ) {
|
||||
return 0;
|
||||
}
|
||||
mpcpplog();
|
||||
if ( get_sample_size() != 1 && get_sample_size() != 2 && get_sample_size() != 4 ) {
|
||||
return 0;
|
||||
}
|
||||
mpcpplog();
|
||||
if ( get_num_channels() != 1 && get_num_channels() != 2 && get_num_channels() != 4 ) {
|
||||
return 0;
|
||||
}
|
||||
mpcpplog();
|
||||
std::memset( lpBuffer, 0, cbBuffer );
|
||||
const std::size_t frames_torender = cbBuffer / get_frame_size();
|
||||
short * out = reinterpret_cast<short*>( lpBuffer );
|
||||
std::vector<short> tmpbuf;
|
||||
if ( get_sample_size() == 1 || get_sample_size() == 4 ) {
|
||||
tmpbuf.resize( frames_torender * get_num_channels() );
|
||||
out = &tmpbuf[0];
|
||||
}
|
||||
|
||||
mod->set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, get_stereo_separation() );
|
||||
mod->set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, get_filter_length() );
|
||||
std::size_t frames_rendered = 0;
|
||||
if ( get_num_channels() == 1 ) {
|
||||
frames_rendered = mod->read( get_samplerate(), frames_torender, out );
|
||||
} else if ( get_num_channels() == 4 ) {
|
||||
frames_rendered = mod->read_interleaved_quad( get_samplerate(), frames_torender, out );
|
||||
} else {
|
||||
frames_rendered = mod->read_interleaved_stereo( get_samplerate(), frames_torender, out );
|
||||
}
|
||||
|
||||
if ( get_sample_size() == 1 ) {
|
||||
unsigned char * dst = reinterpret_cast<unsigned char*>( lpBuffer );
|
||||
for ( std::size_t sample = 0; sample < frames_rendered * get_num_channels(); ++sample ) {
|
||||
dst[sample] = ( tmpbuf[sample] / 0x100 ) + 0x80;
|
||||
}
|
||||
} else if ( get_sample_size() == 4 ) {
|
||||
int * dst = reinterpret_cast<int*>( lpBuffer );
|
||||
for ( std::size_t sample = 0; sample < frames_rendered * get_num_channels(); ++sample ) {
|
||||
dst[sample] = tmpbuf[sample] << (32-16-1-MIXING_ATTENUATION);
|
||||
}
|
||||
}
|
||||
update_state();
|
||||
return static_cast<UINT>( frames_rendered );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
gstreamer modplug calls:
|
||||
|
||||
mSoundFile->Create
|
||||
mSoundFile->Destroy
|
||||
|
||||
mSoundFile->SetWaveConfig
|
||||
mSoundFile->SetWaveConfigEx
|
||||
mSoundFile->SetResamplingMode
|
||||
mSoundFile->SetSurroundParameters
|
||||
mSoundFile->SetXBassParameters
|
||||
mSoundFile->SetReverbParameters
|
||||
|
||||
mSoundFile->GetMaxPosition (inline, -> GetLength)
|
||||
mSoundFile->GetSongTime
|
||||
|
||||
mSoundFile->GetTitle (inline)
|
||||
mSoundFile->GetSongComments
|
||||
|
||||
mSoundFile->SetCurrentPos
|
||||
mSoundFile->Read
|
||||
|
||||
mSoundFile->GetCurrentPos
|
||||
mSoundFile->GetMusicTempo (inline)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
// really very internal symbols, probably nothing calls these directly
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma clang diagnostic ignored "-Wunused-parameter"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
BOOL CSoundFile::ReadNote() { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::ProcessRow() { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::ProcessEffects() { mpcpplog(); return 0; }
|
||||
UINT CSoundFile::GetNNAChannel(UINT nChn) const { mpcpplog(); return 0; }
|
||||
void CSoundFile::CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut) { mpcpplog(); }
|
||||
void CSoundFile::NoteChange(UINT nChn, int note, BOOL bPorta, BOOL bResetEnv) { mpcpplog(); }
|
||||
void CSoundFile::InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta,BOOL bUpdVol,BOOL bResetEnv) { mpcpplog(); }
|
||||
void CSoundFile::PortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::PortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::FinePortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::FinePortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::ExtraFinePortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::ExtraFinePortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::TonePortamento(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::Vibrato(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::FineVibrato(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::VolumeSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::PanningSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::ChannelVolSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::FineVolumeUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::FineVolumeDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::Tremolo(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::Panbrello(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::RetrigNote(UINT nChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::NoteCut(UINT nChn, UINT nTick) { mpcpplog(); }
|
||||
void CSoundFile::KeyOff(UINT nChn) { mpcpplog(); }
|
||||
int CSoundFile::PatternLoop(MODCHANNEL *, UINT param) { mpcpplog(); return 0; }
|
||||
void CSoundFile::ExtendedMODCommands(UINT nChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::ExtendedS3MCommands(UINT nChn, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::ExtendedChannelEffect(MODCHANNEL *, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param) { mpcpplog(); }
|
||||
void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const { mpcpplog(); }
|
||||
void CSoundFile::DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide) { mpcpplog(); }
|
||||
void CSoundFile::SetTempo(UINT param) { mpcpplog(); }
|
||||
void CSoundFile::SetSpeed(UINT param) { mpcpplog(); }
|
||||
void CSoundFile::GlobalVolSlide(UINT param) { mpcpplog(); }
|
||||
DWORD CSoundFile::IsSongFinished(UINT nOrder, UINT nRow) const { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const { mpcpplog(); return 0; }
|
||||
UINT CSoundFile::PackSample(int &sample, int next) { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result) { mpcpplog(); return 0; }
|
||||
UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR pMemFile, DWORD dwMemLength) { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::DestroySample(UINT nSample) { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::DestroyInstrument(UINT nInstr) { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::IsSampleUsed(UINT nSample) { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::IsInstrumentUsed(UINT nInstr) { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::RemoveInstrumentSamples(UINT nInstr) { mpcpplog(); return 0; }
|
||||
UINT CSoundFile::DetectUnusedSamples(BOOL *) { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::RemoveSelectedSamples(BOOL *) { mpcpplog(); return 0; }
|
||||
void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns) { mpcpplog(); }
|
||||
BOOL CSoundFile::ReadInstrumentFromSong(UINT nInstr, CSoundFile *, UINT nSrcInstrument) { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::ReadSampleFromSong(UINT nSample, CSoundFile *, UINT nSrcSample) { mpcpplog(); return 0; }
|
||||
UINT CSoundFile::GetNoteFromPeriod(UINT period) const { mpcpplog(); return 0; }
|
||||
UINT CSoundFile::GetPeriodFromNote(UINT note, int nFineTune, UINT nC4Speed) const { mpcpplog(); return 0; }
|
||||
UINT CSoundFile::GetFreqFromPeriod(UINT period, UINT nC4Speed, int nPeriodFrac) const { mpcpplog(); return 0; }
|
||||
void CSoundFile::ResetMidiCfg() { mpcpplog(); }
|
||||
UINT CSoundFile::MapMidiInstrument(DWORD dwProgram, UINT nChannel, UINT nNote) { mpcpplog(); return 0; }
|
||||
BOOL CSoundFile::ITInstrToMPT(const void *p, INSTRUMENTHEADER *penv, UINT trkvers) { mpcpplog(); return 0; }
|
||||
UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate) { mpcpplog(); return 0; }
|
||||
UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen) { mpcpplog(); return 0; }
|
||||
#ifndef NO_FILTER
|
||||
DWORD CSoundFile::CutOffToFrequency(UINT nCutOff, int flt_modifier) const { mpcpplog(); return 0; }
|
||||
#endif
|
||||
DWORD CSoundFile::TransposeToFrequency(int transp, int ftune) { mpcpplog(); return 0; }
|
||||
int CSoundFile::FrequencyToTranspose(DWORD freq) { mpcpplog(); return 0; }
|
||||
void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp) { mpcpplog(); }
|
||||
MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns) { mpcpplog(); return 0; }
|
||||
signed char* CSoundFile::AllocateSample(UINT nbytes) { mpcpplog(); return 0; }
|
||||
void CSoundFile::FreePattern(LPVOID pat) { mpcpplog(); }
|
||||
void CSoundFile::FreeSample(LPVOID p) { mpcpplog(); }
|
||||
UINT CSoundFile::Normalize24BitBuffer(LPBYTE pbuffer, UINT cbsizebytes, DWORD lmax24, DWORD dwByteInc) { mpcpplog(); return 0; }
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#elif defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#endif // NO_LIBMODPLUG
|
|
@ -0,0 +1,972 @@
|
|||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Check for baseline language coverage in the compiler for the specified
|
||||
# version of the C++ standard. If necessary, add switches to CXX and
|
||||
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
|
||||
# or '14' (for the C++14 standard).
|
||||
#
|
||||
# The second argument, if specified, indicates whether you insist on an
|
||||
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
|
||||
# -std=c++11). If neither is specified, you get whatever works, with
|
||||
# preference for an extended mode.
|
||||
#
|
||||
# The third argument, if specified 'mandatory' or if left unspecified,
|
||||
# indicates that baseline support for the specified C++ standard is
|
||||
# required and that the macro should error out if no mode with that
|
||||
# support is found. If specified 'optional', then configuration proceeds
|
||||
# regardless, after defining HAVE_CXX${VERSION} if and only if a
|
||||
# supporting mode is found.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
|
||||
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
|
||||
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
|
||||
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
|
||||
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
|
||||
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
|
||||
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 9
|
||||
|
||||
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
|
||||
dnl (serial version number 13).
|
||||
|
||||
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
|
||||
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
|
||||
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
|
||||
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
|
||||
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||
m4_if([$2], [], [],
|
||||
[$2], [ext], [],
|
||||
[$2], [noext], [],
|
||||
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
|
||||
m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
|
||||
[$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
|
||||
[$3], [optional], [ax_cxx_compile_cxx$1_required=false],
|
||||
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
|
||||
AC_LANG_PUSH([C++])dnl
|
||||
ac_success=no
|
||||
|
||||
m4_if([$2], [noext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||
switch="-std=gnu++${alternative}"
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXX="$CXX"
|
||||
CXX="$CXX $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXX="$ac_save_CXX"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXX="$CXX $switch"
|
||||
if test -n "$CXXCPP" ; then
|
||||
CXXCPP="$CXXCPP $switch"
|
||||
fi
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
|
||||
m4_if([$2], [ext], [], [dnl
|
||||
if test x$ac_success = xno; then
|
||||
dnl HP's aCC needs +std=c++11 according to:
|
||||
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
|
||||
dnl Cray's crayCC needs "-h std=c++11"
|
||||
for alternative in ${ax_cxx_compile_alternatives}; do
|
||||
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
|
||||
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
|
||||
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
|
||||
$cachevar,
|
||||
[ac_save_CXX="$CXX"
|
||||
CXX="$CXX $switch"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
|
||||
[eval $cachevar=yes],
|
||||
[eval $cachevar=no])
|
||||
CXX="$ac_save_CXX"])
|
||||
if eval test x\$$cachevar = xyes; then
|
||||
CXX="$CXX $switch"
|
||||
if test -n "$CXXCPP" ; then
|
||||
CXXCPP="$CXXCPP $switch"
|
||||
fi
|
||||
ac_success=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test x$ac_success = xyes; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi])
|
||||
AC_LANG_POP([C++])
|
||||
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
|
||||
if test x$ac_success = xno; then
|
||||
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
|
||||
fi
|
||||
fi
|
||||
if test x$ac_success = xno; then
|
||||
HAVE_CXX$1=0
|
||||
AC_MSG_NOTICE([No compiler with C++$1 support was found])
|
||||
else
|
||||
HAVE_CXX$1=1
|
||||
AC_DEFINE(HAVE_CXX$1,1,
|
||||
[define if the compiler supports basic C++$1 syntax])
|
||||
fi
|
||||
AC_SUBST(HAVE_CXX$1)
|
||||
])
|
||||
|
||||
|
||||
dnl Test body for checking C++11 support
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
)
|
||||
|
||||
|
||||
dnl Test body for checking C++14 support
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
)
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
|
||||
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
|
||||
)
|
||||
|
||||
dnl Tests for new features in C++11
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++11, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus < 201103L
|
||||
|
||||
#error "This is not a C++11 compiler"
|
||||
|
||||
#else
|
||||
|
||||
namespace cxx11
|
||||
{
|
||||
|
||||
namespace test_static_assert
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct check
|
||||
{
|
||||
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_final_override
|
||||
{
|
||||
|
||||
struct Base
|
||||
{
|
||||
virtual void f() {}
|
||||
};
|
||||
|
||||
struct Derived : public Base
|
||||
{
|
||||
virtual void f() override {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_double_right_angle_brackets
|
||||
{
|
||||
|
||||
template < typename T >
|
||||
struct check {};
|
||||
|
||||
typedef check<void> single_type;
|
||||
typedef check<check<void>> double_type;
|
||||
typedef check<check<check<void>>> triple_type;
|
||||
typedef check<check<check<check<void>>>> quadruple_type;
|
||||
|
||||
}
|
||||
|
||||
namespace test_decltype
|
||||
{
|
||||
|
||||
int
|
||||
f()
|
||||
{
|
||||
int a = 1;
|
||||
decltype(a) b = 2;
|
||||
return a + b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_type_deduction
|
||||
{
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
struct is_same
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct is_same<T, T>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
auto
|
||||
add(T1 a1, T2 a2) -> decltype(a1 + a2)
|
||||
{
|
||||
return a1 + a2;
|
||||
}
|
||||
|
||||
int
|
||||
test(const int c, volatile int v)
|
||||
{
|
||||
static_assert(is_same<int, decltype(0)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(c)>::value == false, "");
|
||||
static_assert(is_same<int, decltype(v)>::value == false, "");
|
||||
auto ac = c;
|
||||
auto av = v;
|
||||
auto sumi = ac + av + 'x';
|
||||
auto sumf = ac + av + 1.0;
|
||||
static_assert(is_same<int, decltype(ac)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(av)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(sumi)>::value == true, "");
|
||||
static_assert(is_same<int, decltype(sumf)>::value == false, "");
|
||||
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
|
||||
return (sumf > 0.0) ? sumi : add(c, v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_noexcept
|
||||
{
|
||||
|
||||
int f() { return 0; }
|
||||
int g() noexcept { return 0; }
|
||||
|
||||
static_assert(noexcept(f()) == false, "");
|
||||
static_assert(noexcept(g()) == true, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_constexpr
|
||||
{
|
||||
|
||||
template < typename CharT >
|
||||
unsigned long constexpr
|
||||
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
|
||||
{
|
||||
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
|
||||
}
|
||||
|
||||
template < typename CharT >
|
||||
unsigned long constexpr
|
||||
strlen_c(const CharT *const s) noexcept
|
||||
{
|
||||
return strlen_c_r(s, 0UL);
|
||||
}
|
||||
|
||||
static_assert(strlen_c("") == 0UL, "");
|
||||
static_assert(strlen_c("1") == 1UL, "");
|
||||
static_assert(strlen_c("example") == 7UL, "");
|
||||
static_assert(strlen_c("another\0example") == 7UL, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_rvalue_references
|
||||
{
|
||||
|
||||
template < int N >
|
||||
struct answer
|
||||
{
|
||||
static constexpr int value = N;
|
||||
};
|
||||
|
||||
answer<1> f(int&) { return answer<1>(); }
|
||||
answer<2> f(const int&) { return answer<2>(); }
|
||||
answer<3> f(int&&) { return answer<3>(); }
|
||||
|
||||
void
|
||||
test()
|
||||
{
|
||||
int i = 0;
|
||||
const int c = 0;
|
||||
static_assert(decltype(f(i))::value == 1, "");
|
||||
static_assert(decltype(f(c))::value == 2, "");
|
||||
static_assert(decltype(f(0))::value == 3, "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_uniform_initialization
|
||||
{
|
||||
|
||||
struct test
|
||||
{
|
||||
static const int zero {};
|
||||
static const int one {1};
|
||||
};
|
||||
|
||||
static_assert(test::zero == 0, "");
|
||||
static_assert(test::one == 1, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambdas
|
||||
{
|
||||
|
||||
void
|
||||
test1()
|
||||
{
|
||||
auto lambda1 = [](){};
|
||||
auto lambda2 = lambda1;
|
||||
lambda1();
|
||||
lambda2();
|
||||
}
|
||||
|
||||
int
|
||||
test2()
|
||||
{
|
||||
auto a = [](int i, int j){ return i + j; }(1, 2);
|
||||
auto b = []() -> int { return '0'; }();
|
||||
auto c = [=](){ return a + b; }();
|
||||
auto d = [&](){ return c; }();
|
||||
auto e = [a, &b](int x) mutable {
|
||||
const auto identity = [](int y){ return y; };
|
||||
for (auto i = 0; i < a; ++i)
|
||||
a += b--;
|
||||
return x + identity(a + b);
|
||||
}(0);
|
||||
return a + b + c + d + e;
|
||||
}
|
||||
|
||||
int
|
||||
test3()
|
||||
{
|
||||
const auto nullary = [](){ return 0; };
|
||||
const auto unary = [](int x){ return x; };
|
||||
using nullary_t = decltype(nullary);
|
||||
using unary_t = decltype(unary);
|
||||
const auto higher1st = [](nullary_t f){ return f(); };
|
||||
const auto higher2nd = [unary](nullary_t f1){
|
||||
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
|
||||
};
|
||||
return higher1st(nullary) + higher2nd(nullary)(unary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_variadic_templates
|
||||
{
|
||||
|
||||
template <int...>
|
||||
struct sum;
|
||||
|
||||
template <int N0, int... N1toN>
|
||||
struct sum<N0, N1toN...>
|
||||
{
|
||||
static constexpr auto value = N0 + sum<N1toN...>::value;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct sum<>
|
||||
{
|
||||
static constexpr auto value = 0;
|
||||
};
|
||||
|
||||
static_assert(sum<>::value == 0, "");
|
||||
static_assert(sum<1>::value == 1, "");
|
||||
static_assert(sum<23>::value == 23, "");
|
||||
static_assert(sum<1, 2>::value == 3, "");
|
||||
static_assert(sum<5, 5, 11>::value == 21, "");
|
||||
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
|
||||
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
|
||||
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
|
||||
// because of this.
|
||||
namespace test_template_alias_sfinae
|
||||
{
|
||||
|
||||
struct foo {};
|
||||
|
||||
template<typename T>
|
||||
using member = typename T::member_type;
|
||||
|
||||
template<typename T>
|
||||
void func(...) {}
|
||||
|
||||
template<typename T>
|
||||
void func(member<T>*) {}
|
||||
|
||||
void test();
|
||||
|
||||
void test() { func<foo>(0); }
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx11
|
||||
|
||||
#endif // __cplusplus >= 201103L
|
||||
|
||||
]])
|
||||
|
||||
|
||||
dnl Tests for new features in C++14
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++14, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus < 201402L
|
||||
|
||||
#error "This is not a C++14 compiler"
|
||||
|
||||
#else
|
||||
|
||||
namespace cxx14
|
||||
{
|
||||
|
||||
namespace test_polymorphic_lambdas
|
||||
{
|
||||
|
||||
int
|
||||
test()
|
||||
{
|
||||
const auto lambda = [](auto&&... args){
|
||||
const auto istiny = [](auto x){
|
||||
return (sizeof(x) == 1UL) ? 1 : 0;
|
||||
};
|
||||
const int aretiny[] = { istiny(args)... };
|
||||
return aretiny[0];
|
||||
};
|
||||
return lambda(1, 1L, 1.0f, '1');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_binary_literals
|
||||
{
|
||||
|
||||
constexpr auto ivii = 0b0000000000101010;
|
||||
static_assert(ivii == 42, "wrong value");
|
||||
|
||||
}
|
||||
|
||||
namespace test_generalized_constexpr
|
||||
{
|
||||
|
||||
template < typename CharT >
|
||||
constexpr unsigned long
|
||||
strlen_c(const CharT *const s) noexcept
|
||||
{
|
||||
auto length = 0UL;
|
||||
for (auto p = s; *p; ++p)
|
||||
++length;
|
||||
return length;
|
||||
}
|
||||
|
||||
static_assert(strlen_c("") == 0UL, "");
|
||||
static_assert(strlen_c("x") == 1UL, "");
|
||||
static_assert(strlen_c("test") == 4UL, "");
|
||||
static_assert(strlen_c("another\0test") == 7UL, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambda_init_capture
|
||||
{
|
||||
|
||||
int
|
||||
test()
|
||||
{
|
||||
auto x = 0;
|
||||
const auto lambda1 = [a = x](int b){ return a + b; };
|
||||
const auto lambda2 = [a = lambda1(x)](){ return a; };
|
||||
return lambda2();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_digit_separators
|
||||
{
|
||||
|
||||
constexpr auto ten_million = 100'000'000;
|
||||
static_assert(ten_million == 100000000, "");
|
||||
|
||||
}
|
||||
|
||||
namespace test_return_type_deduction
|
||||
{
|
||||
|
||||
auto f(int& x) { return x; }
|
||||
decltype(auto) g(int& x) { return x; }
|
||||
|
||||
template < typename T1, typename T2 >
|
||||
struct is_same
|
||||
{
|
||||
static constexpr auto value = false;
|
||||
};
|
||||
|
||||
template < typename T >
|
||||
struct is_same<T, T>
|
||||
{
|
||||
static constexpr auto value = true;
|
||||
};
|
||||
|
||||
int
|
||||
test()
|
||||
{
|
||||
auto x = 0;
|
||||
static_assert(is_same<int, decltype(f(x))>::value, "");
|
||||
static_assert(is_same<int&, decltype(g(x))>::value, "");
|
||||
return x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx14
|
||||
|
||||
#endif // __cplusplus >= 201402L
|
||||
|
||||
]])
|
||||
|
||||
|
||||
dnl Tests for new features in C++17
|
||||
|
||||
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
|
||||
|
||||
// If the compiler admits that it is not ready for C++17, why torture it?
|
||||
// Hopefully, this will speed up the test.
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#error "This is not a C++ compiler"
|
||||
|
||||
#elif __cplusplus <= 201402L
|
||||
|
||||
#error "This is not a C++17 compiler"
|
||||
|
||||
#else
|
||||
|
||||
#if defined(__clang__)
|
||||
#define REALLY_CLANG
|
||||
#else
|
||||
#if defined(__GNUC__)
|
||||
#define REALLY_GCC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
namespace cxx17
|
||||
{
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_constexpr_lambdas
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
constexpr int foo = [](){return 42;}();
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
namespace test::nested_namespace::definitions
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
namespace test_fold_expression
|
||||
{
|
||||
|
||||
template<typename... Args>
|
||||
int multiply(Args... args)
|
||||
{
|
||||
return (args * ... * 1);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
bool all(Args... args)
|
||||
{
|
||||
return (args && ...);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_extended_static_assert
|
||||
{
|
||||
|
||||
static_assert (true);
|
||||
|
||||
}
|
||||
|
||||
namespace test_auto_brace_init_list
|
||||
{
|
||||
|
||||
auto foo = {5};
|
||||
auto bar {5};
|
||||
|
||||
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
|
||||
static_assert(std::is_same<int, decltype(bar)>::value);
|
||||
}
|
||||
|
||||
namespace test_typename_in_template_template_parameter
|
||||
{
|
||||
|
||||
template<template<typename> typename X> struct D;
|
||||
|
||||
}
|
||||
|
||||
namespace test_fallthrough_nodiscard_maybe_unused_attributes
|
||||
{
|
||||
|
||||
int f1()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
[[nodiscard]] int f2()
|
||||
{
|
||||
[[maybe_unused]] auto unused = f1();
|
||||
|
||||
switch (f1())
|
||||
{
|
||||
case 17:
|
||||
f1();
|
||||
[[fallthrough]];
|
||||
case 42:
|
||||
f1();
|
||||
}
|
||||
return f1();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_extended_aggregate_initialization
|
||||
{
|
||||
|
||||
struct base1
|
||||
{
|
||||
int b1, b2 = 42;
|
||||
};
|
||||
|
||||
struct base2
|
||||
{
|
||||
base2() {
|
||||
b3 = 42;
|
||||
}
|
||||
int b3;
|
||||
};
|
||||
|
||||
struct derived : base1, base2
|
||||
{
|
||||
int d;
|
||||
};
|
||||
|
||||
derived d1 {{1, 2}, {}, 4}; // full initialization
|
||||
derived d2 {{}, {}, 4}; // value-initialized bases
|
||||
|
||||
}
|
||||
|
||||
namespace test_general_range_based_for_loop
|
||||
{
|
||||
|
||||
struct iter
|
||||
{
|
||||
int i;
|
||||
|
||||
int& operator* ()
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
const int& operator* () const
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
iter& operator++()
|
||||
{
|
||||
++i;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct sentinel
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
bool operator== (const iter& i, const sentinel& s)
|
||||
{
|
||||
return i.i == s.i;
|
||||
}
|
||||
|
||||
bool operator!= (const iter& i, const sentinel& s)
|
||||
{
|
||||
return !(i == s);
|
||||
}
|
||||
|
||||
struct range
|
||||
{
|
||||
iter begin() const
|
||||
{
|
||||
return {0};
|
||||
}
|
||||
|
||||
sentinel end() const
|
||||
{
|
||||
return {5};
|
||||
}
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
range r {};
|
||||
|
||||
for (auto i : r)
|
||||
{
|
||||
[[maybe_unused]] auto v = i;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_lambda_capture_asterisk_this_by_value
|
||||
{
|
||||
|
||||
struct t
|
||||
{
|
||||
int i;
|
||||
int foo()
|
||||
{
|
||||
return [*this]()
|
||||
{
|
||||
return i;
|
||||
}();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace test_enum_class_construction
|
||||
{
|
||||
|
||||
enum class byte : unsigned char
|
||||
{};
|
||||
|
||||
byte foo {42};
|
||||
|
||||
}
|
||||
|
||||
namespace test_constexpr_if
|
||||
{
|
||||
|
||||
template <bool cond>
|
||||
int f ()
|
||||
{
|
||||
if constexpr(cond)
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace test_selection_statement_with_initializer
|
||||
{
|
||||
|
||||
int f()
|
||||
{
|
||||
return 13;
|
||||
}
|
||||
|
||||
int f2()
|
||||
{
|
||||
if (auto i = f(); i > 0)
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
switch (auto i = f(); i + 4)
|
||||
{
|
||||
case 17:
|
||||
return 2;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_template_argument_deduction_for_class_templates
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
template <typename T1, typename T2>
|
||||
struct pair
|
||||
{
|
||||
pair (T1 p1, T2 p2)
|
||||
: m1 {p1},
|
||||
m2 {p2}
|
||||
{}
|
||||
|
||||
T1 m1;
|
||||
T2 m2;
|
||||
};
|
||||
|
||||
void f()
|
||||
{
|
||||
[[maybe_unused]] auto p = pair{13, 42u};
|
||||
}
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
namespace test_non_type_auto_template_parameters
|
||||
{
|
||||
|
||||
template <auto n>
|
||||
struct B
|
||||
{};
|
||||
|
||||
B<5> b1;
|
||||
B<'a'> b2;
|
||||
|
||||
}
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_structured_bindings
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
int arr[2] = { 1, 2 };
|
||||
std::pair<int, int> pr = { 1, 2 };
|
||||
|
||||
auto f1() -> int(&)[2]
|
||||
{
|
||||
return arr;
|
||||
}
|
||||
|
||||
auto f2() -> std::pair<int, int>&
|
||||
{
|
||||
return pr;
|
||||
}
|
||||
|
||||
struct S
|
||||
{
|
||||
int x1 : 2;
|
||||
volatile double y1;
|
||||
};
|
||||
|
||||
S f3()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
auto [ x1, y1 ] = f1();
|
||||
auto& [ xr1, yr1 ] = f1();
|
||||
auto [ x2, y2 ] = f2();
|
||||
auto& [ xr2, yr2 ] = f2();
|
||||
const auto [ x3, y3 ] = f3();
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
#if !defined(REALLY_CLANG)
|
||||
namespace test_exception_spec_type_system
|
||||
{
|
||||
|
||||
// TODO: test it with clang++ from git
|
||||
|
||||
struct Good {};
|
||||
struct Bad {};
|
||||
|
||||
void g1() noexcept;
|
||||
void g2();
|
||||
|
||||
template<typename T>
|
||||
Bad
|
||||
f(T*, T*);
|
||||
|
||||
template<typename T1, typename T2>
|
||||
Good
|
||||
f(T1*, T2*);
|
||||
|
||||
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
|
||||
|
||||
}
|
||||
#endif // !defined(REALLY_CLANG)
|
||||
|
||||
namespace test_inline_variables
|
||||
{
|
||||
|
||||
template<class T> void f(T)
|
||||
{}
|
||||
|
||||
template<class T> inline T g(T)
|
||||
{
|
||||
return T{};
|
||||
}
|
||||
|
||||
template<> inline void f<>(int)
|
||||
{}
|
||||
|
||||
template<> int g<>(int)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // namespace cxx17
|
||||
|
||||
#endif // __cplusplus <= 201402L
|
||||
|
||||
]])
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
./autogen.sh
|
||||
|
||||
./configure
|
||||
make
|
||||
make distcheck
|
||||
make distclean
|
Loading…
Add table
Add a link
Reference in a new issue