The MAD decoder will not decode the final frame in an mp3 stream unless
it has a small amount of padding afterwards (MAD_BUFFER_GUARD bytes,
actually 8). Without this, it loses sync before returning any decoded
data from the final frame. The result is that the imported audio is
truncated by up to 1152 samples.
This commit addresses that by using a final round of input callback
calls to provide the last MAD_BUFFER_GUARD bytes after the underlying
file has reached eof. The logic is based on madplay.
... whenever they really describe the size of a buffer that fits in memory, or
of a block file (which is never now more than a megabyte and so could be fit in
memory all at once), or a part thereof.
... A non-narrowing conversion out to long long is a necessity, but the
conversions to float and double are simply conveniences.
Conversion from floating is explicit, to avoid unintended consequences with
arithmetic operators, when later sampleCount ceases to be an alias for an
integral type.
Some conversions are not made explicit, where I expect to change the type of
the variable later to have mere size_t width.
... Define lots of operators for disambiguation, but they will go away after
all conversions from sampleCount to built-in numerical types are forced
to be explicit.
... And in some places where a library uses signed types, assert that
the reported number is not negative.
What led me to this, is that there are many places where a size_t value for
an allocation is the product of a number of channels and some other number.
... This makes much code agnostic about how other things (functions and
arguments) are typed.
Many of these neeed to become size_t instead of sampleCount.
... This includes failure paths in the initialization if import. Those
resources would have been reclaimed before program exit, but not as soon as
they should have been.
... This also includes certain leaks that would happen every time a file is
successfully imported or exported. We never used avformat_free_context or
av_dict_free as we should have!
... There were also AVPacket objects repeatedly reinitialized without proper
cleanups in between. That might have leaked memory too.