fluid-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [fluid-dev] About Supporting 2GiB+ Soundfonts on Windows


From: Carlo Bramini
Subject: Re: [fluid-dev] About Supporting 2GiB+ Soundfonts on Windows
Date: Tue, 17 Mar 2020 13:31:30 +0100 (CET)

Hello,

although it is true that you cannot handle files larger than 2GB with current 
code, there is one thing that's strange in that bug report.
If you really have not large file support, the first function to fail should be 
fseek() and not ftell(), so the first message you should read in the console 
should be "Seek to end of file failed" and not "Get end of file position 
failed". And this is what happens on Windows with oldest common runtime, try to 
believe. And when this happens, this means that MSVCRT does not also provide 
functions like _fseeki64/_ftelli64, this is unavoidable. But if the bug report 
says that the function that fails is ftell(), probably it means that the 
program is using a CRT with large file support. In this case, you can bypass 
the limitation of ftell() in this way:

fsize = fcbs->ftell(sf->sffd);
if (fsize == FLUID_FAILED)
{
    FLUID_LOG(FLUID_WARN, "Get end of file position failed");
    /* Try alternative way for large file support */
    fsize = get_large_file_size(sf->sffd);
    if (fsize == FLUID_FAILED)
    {
        FLUID_LOG(FLUID_ERR, "Get large file size failed");
        goto error_exit;
    }
}

and then you can add a function like this one (I used traditional fseek/ftell 
instead of _fluid_file_callbacks_t for simplicity):

int64_t get_large_file_size(FILE *fp)
{
    int     res = fseek(fp, 0L, SEEK_END);
    long    offset = 0x40000000L; /* 1GiB */
    long    rel;
    int64_t size = 0;

    if (res < 0)
        return res;

    for (;;)
    {
        res = fseek(fp, -offset, SEEK_CUR);

        if (res < 0)
            return res;

        size += offset;

        rel = ftell(fp);
        if (rel < 0)
            continue;

        return size + rel;
    }
    return size;
}

and you won't need to change the ABI of the library, at least for now. 
Technically, I don't think that it would be a big problem: "filesize" is 
compared with "chunk.size", which is 32bit so, if I understood correctly, this 
limits the size of a single SF2 file to 4GiB by design and this also means that 
there will be a maximum of 3 calls to fseek/ftell before computing the size of 
the large file. I have not tested on Unix, but if LIBC provides large file 
support, I expect that it will also work on it.
What do you think?

Sincerely.

Carlo Bramini.

> Il 17 marzo 2020 alle 9.44 "Tom M. via fluid-dev" <address@hidden> ha scritto:
> 
> 
> > If you decided to require C99, I would think you would want to use int64_t 
> > and its relatives for portability.
> 
> I actually had "long long" in mind, because int64_t would require
> fluidsynth's header to include stdint.h, and whenever possible I would
> like to avoid polluting our header with any C system header (for the
> sake of portability to C++). Also note that int64_t is an optional
> type and may only be provided if the implementation supports it. (The
> latter doesn't really make sense in practice, because long long is an
> intrinsic type guaranteed to be at least 64 bits wide. And because
> long long must be available, int64_t will also be available.)
> 
> Based on Reinhold's thought, the idea would be to use something like
> 
> #if defined(_MSVC_VER < VisualStudio2015)
> typedef __int64 fluid_long_long_t; // even on 32bit windows
> #else
> typedef long long fluid_long_long_t;
> #endif
> 
> in our public header. Which basically means: Fluidsynth's source code
> stays C89. The public header will be compatible with C99 (or C++11)
> UNLESS it's being compiled with an old VS in which case we provide a
> fallback. This should provide enough portability while still retaining
> ABI compatibility between and MSVC and MinGW compiled fluidsynth.
> 
> Should it really be that simple or am I missing smth.?
> 
> Tom
> 
> _______________________________________________
> fluid-dev mailing list
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/fluid-dev



reply via email to

[Prev in Thread] Current Thread [Next in Thread]