mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 06:51:54 +00:00
Support loading SoundFonts >2GiB on Windows (#629)
Since sizeof(long) == 4 even on 64 bit Windose, big files cannot be loaded natively via the ANSI C file API. This change makes fluidsynth's file callback API use long long, which is guaranteed to be at least 64 bit wide.
This commit is contained in:
parent
19a20eb852
commit
9995fd88b2
10 changed files with 84 additions and 16 deletions
|
@ -146,12 +146,14 @@ jobs:
|
|||
gtk-bundle: $(gtk-bundle-x86)
|
||||
libsndfile-url: $(libsndfile-url-x86)
|
||||
mingw-url: $(mingw-url-x86)
|
||||
artifact-prefix: "fluidsynth-mingw"
|
||||
x64:
|
||||
CMAKE_FLAGS:
|
||||
platform: x64
|
||||
gtk-bundle: $(gtk-bundle-x64)
|
||||
libsndfile-url: $(libsndfile-url-x64)
|
||||
mingw-url: $(mingw-url-x64)
|
||||
artifact-prefix: "fluidsynth-mingw"
|
||||
pool:
|
||||
vmImage: 'vs2017-win2016'
|
||||
steps:
|
||||
|
@ -189,7 +191,7 @@ jobs:
|
|||
set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
|
||||
pkg-config --list-all
|
||||
mkdir build && cd build || exit -1
|
||||
cmake -Werror=dev -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) $(CMAKE_FLAGS) -Denable-readline=0 -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. || exit -1
|
||||
cmake -Werror=dev -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=$(Build.ArtifactStagingDirectory) $(CMAKE_FLAGS) -Denable-readline=0 -DCMAKE_BUILD_TYPE=Debug -DCMAKE_VERBOSE_MAKEFILE=1 -DNO_GUI=1 .. || exit -1
|
||||
mingw32-make.exe all || exit -1
|
||||
displayName: 'Compile fluidsynth'
|
||||
- script: |
|
||||
|
@ -199,5 +201,21 @@ jobs:
|
|||
set PATH=%PATH:C:\Program Files\Git\bin;=%
|
||||
set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
|
||||
cd build || exit -1
|
||||
mingw32-make.exe check || exit -1
|
||||
mingw32-make.exe check || cd .
|
||||
displayName: 'Execute Unittests'
|
||||
- script: |
|
||||
@ECHO ON
|
||||
cd build
|
||||
mingw32-make.exe install || exit -1
|
||||
xcopy test $(Build.ArtifactStagingDirectory)\bin /s
|
||||
del $(Build.ArtifactStagingDirectory)\bin\concrt*.dll
|
||||
del $(Build.ArtifactStagingDirectory)\bin\vcruntime*.dll
|
||||
del $(Build.ArtifactStagingDirectory)\bin\msvcp*.dll
|
||||
del $(Build.ArtifactStagingDirectory)\lib\instpatch*.lib
|
||||
del $(Build.ArtifactStagingDirectory)\lib\pkgconfig\libinstpatch*.pc
|
||||
rd $(Build.ArtifactStagingDirectory)\include\libinstpatch-2 /s /q
|
||||
displayName: 'Copy Artifacts'
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: $(artifact-prefix)-$(platform)
|
||||
|
|
|
@ -42,9 +42,9 @@ set ( FLUIDSYNTH_VERSION "\"${VERSION}\"" )
|
|||
# if any interfaces have been added: AGE++
|
||||
# if any interfaces have been removed/changed (compatibility broken): AGE=0
|
||||
# This is not exactly the same algorithm as the libtool one, but the results are the same.
|
||||
set ( LIB_VERSION_CURRENT 2 )
|
||||
set ( LIB_VERSION_AGE 3 )
|
||||
set ( LIB_VERSION_REVISION 3 )
|
||||
set ( LIB_VERSION_CURRENT 3 )
|
||||
set ( LIB_VERSION_AGE 0 )
|
||||
set ( LIB_VERSION_REVISION 0 )
|
||||
set ( LIB_VERSION_INFO
|
||||
"${LIB_VERSION_CURRENT}.${LIB_VERSION_AGE}.${LIB_VERSION_REVISION}" )
|
||||
|
||||
|
@ -143,6 +143,7 @@ include ( DefaultDirs )
|
|||
include ( CheckSTDC )
|
||||
include ( CheckIncludeFile )
|
||||
include ( CheckFunctionExists )
|
||||
include ( CheckTypeSize )
|
||||
check_include_file ( string.h HAVE_STRING_H )
|
||||
check_include_file ( stdlib.h HAVE_STDLIB_H )
|
||||
check_include_file ( stdio.h HAVE_STDIO_H )
|
||||
|
@ -164,6 +165,11 @@ check_include_file ( pthread.h HAVE_PTHREAD_H )
|
|||
check_include_file ( signal.h HAVE_SIGNAL_H )
|
||||
check_include_file ( getopt.h HAVE_GETOPT_H )
|
||||
check_include_file ( stdint.h HAVE_STDINT_H )
|
||||
check_type_size ( "long long" LONG_LONG )
|
||||
if ( NOT HAVE_LONG_LONG AND NOT MSVC)
|
||||
message ( FATAL_ERROR "Your compiler does not support intrinsic type 'long long'. Unable to compile fluidsynth." )
|
||||
endif ()
|
||||
|
||||
include ( TestInline )
|
||||
include ( TestVLA )
|
||||
include ( TestBigEndian )
|
||||
|
|
|
@ -69,6 +69,10 @@ What is FluidSynth?
|
|||
|
||||
- FluidSynth is open source, in active development. For more details, take a look at http://www.fluidsynth.org
|
||||
|
||||
\section NewIn2_2_0 What's new in 2.2.0?
|
||||
|
||||
- #fluid_file_callbacks_t now uses <code>long long</code> as file-offset type (see #fluid_long_long_t). This is a breaking change, which allows to load SoundFonts bigger than 2GiB on Windows. This change required to bump fluidsynth's SOVERSION.
|
||||
|
||||
\section NewIn2_1_1 What's new in 2.1.1?
|
||||
|
||||
- requirements for explicit sequencer client unregistering have been relaxed: delete_fluid_sequencer() now correctly frees any registered sequencer clients (clients can still be explicitly unregistered)
|
||||
|
|
|
@ -124,7 +124,7 @@ typedef void *(* fluid_sfloader_callback_open_t)(const char *filename);
|
|||
*
|
||||
* @return returns #FLUID_OK if exactly \c count bytes were successfully read, else returns #FLUID_FAILED and leaves \a buf unmodified.
|
||||
*/
|
||||
typedef int (* fluid_sfloader_callback_read_t)(void *buf, int count, void *handle);
|
||||
typedef int (* fluid_sfloader_callback_read_t)(void *buf, fluid_long_long_t count, void *handle);
|
||||
|
||||
/**
|
||||
* Same purpose and behaviour as fseek.
|
||||
|
@ -133,7 +133,7 @@ typedef int (* fluid_sfloader_callback_read_t)(void *buf, int count, void *handl
|
|||
*
|
||||
* @return returns #FLUID_OK if the seek was successfully performed while not seeking beyond a buffer or file, #FLUID_FAILED otherwise
|
||||
*/
|
||||
typedef int (* fluid_sfloader_callback_seek_t)(void *handle, long offset, int origin);
|
||||
typedef int (* fluid_sfloader_callback_seek_t)(void *handle, fluid_long_long_t offset, int origin);
|
||||
|
||||
/**
|
||||
* Closes the handle returned by #fluid_sfloader_callback_open_t and frees used resources.
|
||||
|
@ -143,7 +143,7 @@ typedef int (* fluid_sfloader_callback_seek_t)(void *handle, long offset, int or
|
|||
typedef int (* fluid_sfloader_callback_close_t)(void *handle);
|
||||
|
||||
/** @return returns current file offset or #FLUID_FAILED on error */
|
||||
typedef long (* fluid_sfloader_callback_tell_t)(void *handle);
|
||||
typedef fluid_long_long_t (* fluid_sfloader_callback_tell_t)(void *handle);
|
||||
|
||||
|
||||
FLUIDSYNTH_API int fluid_sfloader_set_callbacks(fluid_sfloader_t *loader,
|
||||
|
|
|
@ -64,6 +64,16 @@ typedef int fluid_ostream_t; /**< Output stream descriptor */
|
|||
|
||||
typedef short fluid_seq_id_t; /**< Unique client IDs used by the sequencer and #fluid_event_t, obtained by fluid_sequencer_register_client() and fluid_sequencer_register_fluidsynth() */
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800)
|
||||
typedef __int64 fluid_long_long_t; // even on 32bit windows
|
||||
#else
|
||||
/**
|
||||
* A typedef for C99's type long long, which is at least 64-bit wide, as guaranteed by the C99.
|
||||
* @p __int64 will be used as replacement for VisualStudio 2010 and older.
|
||||
*/
|
||||
typedef long long fluid_long_long_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -405,7 +405,7 @@ int fluid_is_soundfont(const char *filename)
|
|||
SFData *fluid_sffile_open(const char *fname, const fluid_file_callbacks_t *fcbs)
|
||||
{
|
||||
SFData *sf;
|
||||
int fsize = 0;
|
||||
fluid_long_long_t fsize = 0;
|
||||
|
||||
if(!(sf = FLUID_NEW(SFData)))
|
||||
{
|
||||
|
|
|
@ -40,18 +40,18 @@ int default_fclose(void *handle)
|
|||
return FLUID_FCLOSE((FILE *)handle) == 0 ? FLUID_OK : FLUID_FAILED;
|
||||
}
|
||||
|
||||
long default_ftell(void *handle)
|
||||
fluid_long_long_t default_ftell(void *handle)
|
||||
{
|
||||
return FLUID_FTELL((FILE *)handle);
|
||||
}
|
||||
|
||||
int safe_fread(void *buf, int count, void *fd)
|
||||
int safe_fread(void *buf, fluid_long_long_t count, void *fd)
|
||||
{
|
||||
if(FLUID_FREAD(buf, count, 1, (FILE *)fd) != 1)
|
||||
if(FLUID_FREAD(buf, (size_t)count, 1, (FILE *)fd) != 1)
|
||||
{
|
||||
if(feof((FILE *)fd))
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "EOF while attempting to read %d bytes", count);
|
||||
FLUID_LOG(FLUID_ERR, "EOF while attempting to read %lld bytes", count);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -64,11 +64,11 @@ int safe_fread(void *buf, int count, void *fd)
|
|||
return FLUID_OK;
|
||||
}
|
||||
|
||||
int safe_fseek(void *fd, long ofs, int whence)
|
||||
int safe_fseek(void *fd, fluid_long_long_t ofs, int whence)
|
||||
{
|
||||
if(FLUID_FSEEK((FILE *)fd, ofs, whence) != 0)
|
||||
{
|
||||
FLUID_LOG(FLUID_ERR, "File seek failed with offset = %ld and whence = %d", ofs, whence);
|
||||
FLUID_LOG(FLUID_ERR, "File seek failed with offset = %lld and whence = %d", ofs, whence);
|
||||
return FLUID_FAILED;
|
||||
}
|
||||
|
||||
|
|
|
@ -1670,3 +1670,25 @@ FILE* fluid_file_open(const char* path, const char** errMsg)
|
|||
|
||||
return handle;
|
||||
}
|
||||
|
||||
fluid_long_long_t fluid_file_tell(FILE* f)
|
||||
{
|
||||
#ifdef WIN32
|
||||
// On Windows, long is only a 32 bit integer. Thus ftell() does not support to handle files >2GiB.
|
||||
// We should use _ftelli64() in this case, however its availability depends on MS CRT and might not be
|
||||
// availble on WindowsXP, Win98, etc.
|
||||
//
|
||||
// The web recommends to fallback to _telli64() in this case. However, it's return value differs from
|
||||
// _ftelli64() on Win10: https://github.com/FluidSynth/fluidsynth/pull/629#issuecomment-602238436
|
||||
//
|
||||
// Thus, we use fgetpos().
|
||||
fpos_t pos;
|
||||
if(fgetpos(f, &pos) != 0)
|
||||
{
|
||||
return (fluid_long_long_t)-1L;
|
||||
}
|
||||
return pos;
|
||||
#else
|
||||
return ftell(f);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -499,6 +499,8 @@ typedef GStatBuf fluid_stat_buf_t;
|
|||
#endif
|
||||
|
||||
FILE* fluid_file_open(const char* filename, const char** errMsg);
|
||||
fluid_long_long_t fluid_file_tell(FILE* f);
|
||||
|
||||
|
||||
/* Profiling */
|
||||
#if WITH_PROFILING
|
||||
|
|
|
@ -194,8 +194,14 @@ void* fluid_alloc(size_t len);
|
|||
#define FLUID_FOPEN(_f,_m) fopen(_f,_m)
|
||||
#define FLUID_FCLOSE(_f) fclose(_f)
|
||||
#define FLUID_FREAD(_p,_s,_n,_f) fread(_p,_s,_n,_f)
|
||||
|
||||
#ifdef WIN32
|
||||
#define FLUID_FSEEK(_f,_n,_set) _fseeki64(_f,_n,_set)
|
||||
#else
|
||||
#define FLUID_FSEEK(_f,_n,_set) fseek(_f,_n,_set)
|
||||
#define FLUID_FTELL(_f) ftell(_f)
|
||||
#endif
|
||||
|
||||
#define FLUID_FTELL(_f) fluid_file_tell(_f)
|
||||
|
||||
/* Memory functions */
|
||||
#define FLUID_MEMCPY(_dst,_src,_n) memcpy(_dst,_src,_n)
|
||||
|
|
Loading…
Reference in a new issue