mirror of https://github.com/odrling/Aegisub
Drop support for non-little-endian platforms
Aegisub doesn't actually currently run on any.
This commit is contained in:
parent
160346df99
commit
b67a0538ff
|
@ -133,7 +133,6 @@
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PreprocessorDefinitions>
|
<PreprocessorDefinitions>
|
||||||
HAVE_LITTLE_ENDIAN;
|
|
||||||
__STDC_FORMAT_MACROS;
|
__STDC_FORMAT_MACROS;
|
||||||
NOMINMAX;
|
NOMINMAX;
|
||||||
%(PreprocessorDefinitions)
|
%(PreprocessorDefinitions)
|
||||||
|
|
|
@ -89,7 +89,6 @@
|
||||||
<!-- Source files -->
|
<!-- Source files -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="$(SrcDir)MatroskaParser.h" />
|
<ClInclude Include="$(SrcDir)MatroskaParser.h" />
|
||||||
<ClInclude Include="$(SrcDir)aegisub_endian.h" />
|
|
||||||
<ClInclude Include="$(SrcDir)aegisublocale.h" />
|
<ClInclude Include="$(SrcDir)aegisublocale.h" />
|
||||||
<ClInclude Include="$(SrcDir)agi_pre.h" />
|
<ClInclude Include="$(SrcDir)agi_pre.h" />
|
||||||
<ClInclude Include="$(SrcDir)ass_attachment.h" />
|
<ClInclude Include="$(SrcDir)ass_attachment.h" />
|
||||||
|
|
|
@ -255,9 +255,6 @@
|
||||||
<ClInclude Include="$(SrcDir)audio_player_portaudio.h">
|
<ClInclude Include="$(SrcDir)audio_player_portaudio.h">
|
||||||
<Filter>Audio\Players</Filter>
|
<Filter>Audio\Players</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="$(SrcDir)aegisub_endian.h">
|
|
||||||
<Filter>Utilities</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="$(SrcDir)block_cache.h">
|
<ClInclude Include="$(SrcDir)block_cache.h">
|
||||||
<Filter>Utilities</Filter>
|
<Filter>Utilities</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -51,14 +51,6 @@ AC_SUBST(build_linux)
|
||||||
AC_SUBST(build_darwin)
|
AC_SUBST(build_darwin)
|
||||||
AC_SUBST(build_default)
|
AC_SUBST(build_default)
|
||||||
|
|
||||||
# Handle endianess.
|
|
||||||
AC_C_BIGENDIAN(
|
|
||||||
AC_DEFINE([HAVE_BIG_ENDIAN], [1], [Big Endian]),
|
|
||||||
AC_DEFINE([HAVE_LITTLE_ENDIAN], [1], [Little Endian]),
|
|
||||||
AC_DEFINE([HAVE_DYNAMIC_ENDIAN], [1], [Unknown endian]),
|
|
||||||
AC_DEFINE([HAVE_UNIVERSAL_ENDIAN], [1], [Universal Endian (MAC Universal PPC/Intel Binaries, uses HAVE_DYNAMIC_ENDIAN)])
|
|
||||||
)
|
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Configurable variables
|
# Configurable variables
|
||||||
########################
|
########################
|
||||||
|
|
|
@ -1,327 +0,0 @@
|
||||||
// Copyright (c) 2008, Niels Martin Hansen
|
|
||||||
//
|
|
||||||
// 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 Aegisub Group 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 OWNER 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.
|
|
||||||
//
|
|
||||||
// Aegisub Project http://www.aegisub.org/
|
|
||||||
|
|
||||||
/// @file aegisub_endian.h
|
|
||||||
/// @brief Convert numbers between various endianness
|
|
||||||
/// @ingroup utility
|
|
||||||
///
|
|
||||||
|
|
||||||
|
|
||||||
// Sanity check
|
|
||||||
#ifndef HAVE_LITTLE_ENDIAN
|
|
||||||
# ifndef HAVE_BIG_ENDIAN
|
|
||||||
// We neither have big nor little endian from configuration
|
|
||||||
# ifdef HAVE_UNIVERSAL_ENDIAN
|
|
||||||
// But this is an OS X system building a universal binary
|
|
||||||
// Apple's GCC defines _BIG_ENDIAN when building for PPC
|
|
||||||
# ifdef _BIG_ENDIAN
|
|
||||||
# define HAVE_BIG_ENDIAN
|
|
||||||
# else
|
|
||||||
# define HAVE_LITTLE_ENDIAN
|
|
||||||
# endif
|
|
||||||
# undef HAVE_DYNAMIC_ENDIAN
|
|
||||||
# else // !HAVE_UNIVERSAL_ENDIAN
|
|
||||||
// We aren't building an OS X universal binary
|
|
||||||
// Use the dynamic endian code
|
|
||||||
# ifndef HAVE_DYNAMIC_ENDIAN
|
|
||||||
# define HAVE_DYNAMIC_ENDIAN
|
|
||||||
# endif
|
|
||||||
# endif //HAVE_UNIVERSAL_ENDIAN
|
|
||||||
# endif // HAVE_BIG_ENDIAN
|
|
||||||
#endif // HAVE_LITTLE_ENDIAN
|
|
||||||
|
|
||||||
#ifdef HAVE_LITTLE_ENDIAN
|
|
||||||
# ifdef HAVE_BIG_ENDIAN
|
|
||||||
# error You cannot have both HAVE_LITTLE_ENDIAN and HAVE_BIG_ENDIAN defined at the same time
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace Endian {
|
|
||||||
// Unconditionally reverse endianness
|
|
||||||
|
|
||||||
// These are only defined for unsigned ints,
|
|
||||||
// Use reinterpret_cast on the values if you need signed values.
|
|
||||||
inline uint16_t Reverse(uint16_t val)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((val & 0x00FF) << 8) |
|
|
||||||
((val & 0xFF00) >> 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t Reverse(uint32_t val)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((val & 0x000000FF) << 24) |
|
|
||||||
((val & 0x0000FF00) << 8) |
|
|
||||||
((val & 0x00FF0000) >> 8) |
|
|
||||||
((val & 0xFF000000) >> 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t Reverse(uint64_t val)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
((val & 0x00000000000000FFULL) << 56) |
|
|
||||||
((val & 0x000000000000FF00ULL) << 40) |
|
|
||||||
((val & 0x0000000000FF0000ULL) << 24) |
|
|
||||||
((val & 0x00000000FF000000ULL) << 8) |
|
|
||||||
((val & 0x000000FF00000000ULL) >> 8) |
|
|
||||||
((val & 0x0000FF0000000000ULL) >> 24) |
|
|
||||||
((val & 0x00FF000000000000ULL) >> 40) |
|
|
||||||
((val & 0xFF00000000000000ULL) >> 56);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HAVE_DYNAMIC_ENDIAN
|
|
||||||
// Regular, fast, templatized conditional reversing
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline T LittleToMachine(T val)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_BIG_ENDIAN
|
|
||||||
// We're on big endian, reverse little to big
|
|
||||||
return Reverse(val);
|
|
||||||
#else
|
|
||||||
// We're on little endian and input is little
|
|
||||||
return val;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline T BigToMachine(T val)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_LITTLE_ENDIAN
|
|
||||||
// We're on little endian, reverse big to little
|
|
||||||
return Reverse(val);
|
|
||||||
#else
|
|
||||||
// We're on big endian and input is big
|
|
||||||
return val;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline T MachineToLittle(T val)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_BIG_ENDIAN
|
|
||||||
// We're on big endian, reverse to little
|
|
||||||
return Reverse(val);
|
|
||||||
#else
|
|
||||||
// Already on little, nothing to be done
|
|
||||||
return val;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline T MachineToBig(T val)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_LITTLE_ENDIAN
|
|
||||||
// We're on little endian, reverse to big
|
|
||||||
return Reverse(val);
|
|
||||||
#else
|
|
||||||
// Already on big, nothing to be done
|
|
||||||
return val;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // HAVE_DYNAMIC_ENDIAN
|
|
||||||
|
|
||||||
// Dynamic endianness handling
|
|
||||||
|
|
||||||
// Exploit that bit-shifting operations always can put bytes into
|
|
||||||
// machine word order, while unions can be used to access bytes
|
|
||||||
// only from an explicitly given byte order.
|
|
||||||
// This is probably slower than when we explicitly know
|
|
||||||
// the endianness of the machine we are on, but it's the same
|
|
||||||
// code for any platform!
|
|
||||||
|
|
||||||
// Unions to pack together ints and get their physical bytes
|
|
||||||
|
|
||||||
union bytes16 {
|
|
||||||
uint8_t byte[2];
|
|
||||||
uint16_t word;
|
|
||||||
};
|
|
||||||
|
|
||||||
union bytes32 {
|
|
||||||
uint8_t byte[4];
|
|
||||||
uint32_t word;
|
|
||||||
};
|
|
||||||
|
|
||||||
union bytes64 {
|
|
||||||
uint8_t byte[8];
|
|
||||||
uint64_t word;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 16 bit words
|
|
||||||
|
|
||||||
inline uint16_t MachineToBig(uint16_t val)
|
|
||||||
{
|
|
||||||
bytes16 pack;
|
|
||||||
// Store the bytes into the correct positions in the word
|
|
||||||
pack.byte[0] = (val & 0xFF00) >> 8;
|
|
||||||
pack.byte[1] = val & 0x00FF;
|
|
||||||
// And return a value now encoded as big endian
|
|
||||||
return pack.word;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint16_t MachineToLittle(uint16_t val)
|
|
||||||
{
|
|
||||||
bytes16 pack;
|
|
||||||
// Store the bytes into the correct positions in the word
|
|
||||||
pack.byte[0] = val & 0x00FF;
|
|
||||||
pack.byte[1] = (val & 0xFF00) >> 8;
|
|
||||||
// And return a value now encoded as little endian
|
|
||||||
return pack.word;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint16_t BigToMachine(uint16_t val)
|
|
||||||
{
|
|
||||||
bytes16 pack;
|
|
||||||
// Put our word into the pack
|
|
||||||
pack.word = val;
|
|
||||||
// And produce a machine endian value of it
|
|
||||||
return uint16_t(pack.byte[1]) | (uint16_t(pack.byte[0]) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint16_t LittleToMachine(uint16_t val)
|
|
||||||
{
|
|
||||||
bytes16 pack;
|
|
||||||
// Put our word into the pack
|
|
||||||
pack.word = val;
|
|
||||||
// And produce a machine endian value of it
|
|
||||||
return uint16_t(pack.byte[0]) | (uint16_t(pack.byte[1]) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 32 bit words
|
|
||||||
|
|
||||||
inline uint32_t MachineToBig(uint32_t val)
|
|
||||||
{
|
|
||||||
bytes32 pack;
|
|
||||||
pack.byte[0] = (val & 0xFF000000) >> 24;
|
|
||||||
pack.byte[1] = (val & 0x00FF0000) >> 16;
|
|
||||||
pack.byte[2] = (val & 0x0000FF00) >> 8;
|
|
||||||
pack.byte[3] = val & 0x000000FF ;
|
|
||||||
return pack.word;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t MachineToLittle(uint32_t val)
|
|
||||||
{
|
|
||||||
bytes32 pack;
|
|
||||||
pack.byte[0] = val & 0x000000FF ;
|
|
||||||
pack.byte[1] = (val & 0x0000FF00) >> 8;
|
|
||||||
pack.byte[2] = (val & 0x00FF0000) >> 16;
|
|
||||||
pack.byte[3] = (val & 0xFF000000) >> 24;
|
|
||||||
return pack.word;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t BigToMachine(uint32_t val)
|
|
||||||
{
|
|
||||||
bytes32 pack;
|
|
||||||
pack.word = val;
|
|
||||||
return
|
|
||||||
(uint32_t(pack.byte[0]) << 24) |
|
|
||||||
(uint32_t(pack.byte[1]) << 16) |
|
|
||||||
(uint32_t(pack.byte[2]) << 8) |
|
|
||||||
uint32_t(pack.byte[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint32_t LittleToMachine(uint32_t val)
|
|
||||||
{
|
|
||||||
bytes32 pack;
|
|
||||||
pack.word = val;
|
|
||||||
return
|
|
||||||
(uint32_t(pack.byte[3]) << 24) |
|
|
||||||
(uint32_t(pack.byte[2]) << 16) |
|
|
||||||
(uint32_t(pack.byte[1]) << 8) |
|
|
||||||
uint32_t(pack.byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 64 bit words
|
|
||||||
|
|
||||||
inline uint64_t MachineToBig(uint64_t val)
|
|
||||||
{
|
|
||||||
bytes64 pack;
|
|
||||||
pack.byte[0] = (val & 0xFF00000000000000ULL) >> 56;
|
|
||||||
pack.byte[1] = (val & 0x00FF000000000000ULL) >> 48;
|
|
||||||
pack.byte[2] = (val & 0x0000FF0000000000ULL) >> 40;
|
|
||||||
pack.byte[3] = (val & 0x000000FF00000000ULL) >> 32;
|
|
||||||
pack.byte[4] = (val & 0x00000000FF000000ULL) >> 24;
|
|
||||||
pack.byte[5] = (val & 0x0000000000FF0000ULL) >> 16;
|
|
||||||
pack.byte[6] = (val & 0x000000000000FF00ULL) >> 8;
|
|
||||||
pack.byte[7] = val & 0x00000000000000FFULL ;
|
|
||||||
return pack.word;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t MachineToLittle(uint64_t val)
|
|
||||||
{
|
|
||||||
bytes64 pack;
|
|
||||||
pack.byte[0] = val & 0x00000000000000FFULL ;
|
|
||||||
pack.byte[1] = (val & 0x000000000000FF00ULL) >> 8;
|
|
||||||
pack.byte[2] = (val & 0x0000000000FF0000ULL) >> 16;
|
|
||||||
pack.byte[3] = (val & 0x00000000FF000000ULL) >> 24;
|
|
||||||
pack.byte[4] = (val & 0x000000FF00000000ULL) >> 32;
|
|
||||||
pack.byte[5] = (val & 0x0000FF0000000000ULL) >> 40;
|
|
||||||
pack.byte[6] = (val & 0x00FF000000000000ULL) >> 48;
|
|
||||||
pack.byte[7] = (val & 0xFF00000000000000ULL) >> 56;
|
|
||||||
return pack.word;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t BigToMachine(uint64_t val)
|
|
||||||
{
|
|
||||||
bytes64 pack;
|
|
||||||
pack.word = val;
|
|
||||||
return
|
|
||||||
(uint64_t(pack.byte[0]) << 56) |
|
|
||||||
(uint64_t(pack.byte[1]) << 48) |
|
|
||||||
(uint64_t(pack.byte[2]) << 40) |
|
|
||||||
(uint64_t(pack.byte[3]) << 32) |
|
|
||||||
(uint64_t(pack.byte[4]) << 24) |
|
|
||||||
(uint64_t(pack.byte[5]) << 16) |
|
|
||||||
(uint64_t(pack.byte[6]) << 8) |
|
|
||||||
uint64_t(pack.byte[7]);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t LittleToMachine(uint64_t val)
|
|
||||||
{
|
|
||||||
bytes64 pack;
|
|
||||||
pack.word = val;
|
|
||||||
return
|
|
||||||
(uint64_t(pack.byte[7]) << 56) |
|
|
||||||
(uint64_t(pack.byte[6]) << 48) |
|
|
||||||
(uint64_t(pack.byte[5]) << 40) |
|
|
||||||
(uint64_t(pack.byte[4]) << 32) |
|
|
||||||
(uint64_t(pack.byte[3]) << 24) |
|
|
||||||
(uint64_t(pack.byte[2]) << 16) |
|
|
||||||
(uint64_t(pack.byte[1]) << 8) |
|
|
||||||
uint64_t(pack.byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -48,7 +48,6 @@ class AvisynthAudioProvider : public AudioProvider {
|
||||||
public:
|
public:
|
||||||
AvisynthAudioProvider(agi::fs::path const& filename);
|
AvisynthAudioProvider(agi::fs::path const& filename);
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
|
||||||
bool NeedsCache() const { return true; }
|
bool NeedsCache() const { return true; }
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
|
|
||||||
#include "audio_provider_convert.h"
|
#include "audio_provider_convert.h"
|
||||||
|
|
||||||
#include "aegisub_endian.h"
|
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
#include "include/aegisub/audio_provider.h"
|
#include "include/aegisub/audio_provider.h"
|
||||||
|
|
||||||
|
@ -47,7 +46,6 @@ public:
|
||||||
float_samples = source->AreSamplesFloat();
|
float_samples = source->AreSamplesFloat();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
|
||||||
agi::fs::path GetFilename() const { return source->GetFilename(); }
|
agi::fs::path GetFilename() const { return source->GetFilename(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,13 +53,11 @@ public:
|
||||||
template<class Target>
|
template<class Target>
|
||||||
class BitdepthConvertAudioProvider : public AudioProviderConverter {
|
class BitdepthConvertAudioProvider : public AudioProviderConverter {
|
||||||
int src_bytes_per_sample;
|
int src_bytes_per_sample;
|
||||||
bool src_is_native_endian;
|
|
||||||
public:
|
public:
|
||||||
BitdepthConvertAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
|
BitdepthConvertAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
|
||||||
if (bytes_per_sample > 8)
|
if (bytes_per_sample > 8)
|
||||||
throw agi::AudioProviderOpenError("Audio format converter: audio with bitdepths greater than 64 bits/sample is currently unsupported", 0);
|
throw agi::AudioProviderOpenError("Audio format converter: audio with bitdepths greater than 64 bits/sample is currently unsupported", 0);
|
||||||
|
|
||||||
src_is_native_endian = source->AreSamplesNativeEndian();
|
|
||||||
src_bytes_per_sample = bytes_per_sample;
|
src_bytes_per_sample = bytes_per_sample;
|
||||||
bytes_per_sample = sizeof(Target);
|
bytes_per_sample = sizeof(Target);
|
||||||
}
|
}
|
||||||
|
@ -81,22 +77,8 @@ public:
|
||||||
// while everything else is assumed to be signed with zero bias
|
// while everything else is assumed to be signed with zero bias
|
||||||
if (src_bytes_per_sample == 1)
|
if (src_bytes_per_sample == 1)
|
||||||
*sample_ptr = static_cast<uint8_t>(*src) - 127;
|
*sample_ptr = static_cast<uint8_t>(*src) - 127;
|
||||||
else if (src_is_native_endian) {
|
else
|
||||||
#ifdef HAVE_LITTLE_ENDIAN
|
|
||||||
memcpy(sample_ptr, src, src_bytes_per_sample);
|
memcpy(sample_ptr, src, src_bytes_per_sample);
|
||||||
#else
|
|
||||||
memcpy(sample_ptr + sizeof(int64_t) - src_bytes_per_sample, src, src_bytes_per_sample);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (int byte_index = 0; i < src_bytes_per_sample; ++i) {
|
|
||||||
#ifdef HAVE_LITTLE_ENDIAN
|
|
||||||
sample_ptr[byte_index] = src[src_bytes_per_sample - byte_index - 1];
|
|
||||||
#else
|
|
||||||
sample_ptr[sizeof(int64_t) - byte_index - 1] = src[byte_index];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (static_cast<size_t>(src_bytes_per_sample) > sizeof(Target))
|
if (static_cast<size_t>(src_bytes_per_sample) > sizeof(Target))
|
||||||
sample >>= (src_bytes_per_sample - sizeof(Target)) * 8;
|
sample >>= (src_bytes_per_sample - sizeof(Target)) * 8;
|
||||||
|
@ -113,8 +95,6 @@ template<class Source, class Target>
|
||||||
class FloatConvertAudioProvider : public AudioProviderConverter {
|
class FloatConvertAudioProvider : public AudioProviderConverter {
|
||||||
public:
|
public:
|
||||||
FloatConvertAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
|
FloatConvertAudioProvider(std::unique_ptr<AudioProvider>&& src) : AudioProviderConverter(std::move(src)) {
|
||||||
if (!source->AreSamplesNativeEndian())
|
|
||||||
throw agi::AudioProviderOpenError("Audio format converter: Float audio with non-native endianness is currently unsupported.", 0);
|
|
||||||
bytes_per_sample = sizeof(Target);
|
bytes_per_sample = sizeof(Target);
|
||||||
float_samples = false;
|
float_samples = false;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +201,7 @@ std::unique_ptr<AudioProvider> CreateConvertAudioProvider(std::unique_ptr<AudioP
|
||||||
else
|
else
|
||||||
provider = agi::util::make_unique<FloatConvertAudioProvider<double, int16_t>>(std::move(provider));
|
provider = agi::util::make_unique<FloatConvertAudioProvider<double, int16_t>>(std::move(provider));
|
||||||
}
|
}
|
||||||
if (provider->GetBytesPerSample() != 2 || !provider->AreSamplesNativeEndian()) {
|
if (provider->GetBytesPerSample() != 2) {
|
||||||
LOG_D("audio_provider") << "Converting " << provider->GetBytesPerSample() << " bytes per sample or wrong endian to S16";
|
LOG_D("audio_provider") << "Converting " << provider->GetBytesPerSample() << " bytes per sample or wrong endian to S16";
|
||||||
provider = agi::util::make_unique<BitdepthConvertAudioProvider<int16_t>>(std::move(provider));
|
provider = agi::util::make_unique<BitdepthConvertAudioProvider<int16_t>>(std::move(provider));
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,4 @@ class DummyAudioProvider : public AudioProvider {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DummyAudioProvider(agi::fs::path const& uri);
|
DummyAudioProvider(agi::fs::path const& uri);
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,10 +52,6 @@ class FFmpegSourceAudioProvider : public AudioProvider, FFmpegSourceProvider {
|
||||||
public:
|
public:
|
||||||
FFmpegSourceAudioProvider(agi::fs::path const& filename);
|
FFmpegSourceAudioProvider(agi::fs::path const& filename);
|
||||||
|
|
||||||
/// @brief Checks sample endianness
|
|
||||||
/// @return Returns true.
|
|
||||||
/// FFMS always delivers native endian samples.
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
|
||||||
bool NeedsCache() const { return true; }
|
bool NeedsCache() const { return true; }
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -85,15 +85,11 @@ public:
|
||||||
IndexPoint p = { 0, 0, num_samples };
|
IndexPoint p = { 0, 0, num_samples };
|
||||||
index_points.push_back(p);
|
index_points.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HDAudioProvider::HDAudioProvider(std::unique_ptr<AudioProvider>&& src, agi::BackgroundRunner *br) {
|
HDAudioProvider::HDAudioProvider(std::unique_ptr<AudioProvider>&& src, agi::BackgroundRunner *br) {
|
||||||
assert(src->AreSamplesNativeEndian()); // Byteswapping should be done before caching
|
|
||||||
|
|
||||||
bytes_per_sample = src->GetBytesPerSample();
|
bytes_per_sample = src->GetBytesPerSample();
|
||||||
num_samples = src->GetNumSamples();
|
num_samples = src->GetNumSamples();
|
||||||
channels = src->GetChannels();
|
channels = src->GetChannels();
|
||||||
|
|
|
@ -56,6 +56,4 @@ class HDAudioProvider : public AudioProvider {
|
||||||
public:
|
public:
|
||||||
HDAudioProvider(std::unique_ptr<AudioProvider>&& source, agi::BackgroundRunner *br);
|
HDAudioProvider(std::unique_ptr<AudioProvider>&& source, agi::BackgroundRunner *br);
|
||||||
~HDAudioProvider();
|
~HDAudioProvider();
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return true; }
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,5 +28,4 @@ class LockAudioProvider : public AudioProvider {
|
||||||
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
public:
|
public:
|
||||||
LockAudioProvider(std::unique_ptr<AudioProvider>&& source);
|
LockAudioProvider(std::unique_ptr<AudioProvider>&& source);
|
||||||
bool AreSamplesNativeEndian() const { return source->AreSamplesNativeEndian(); }
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
|
|
||||||
#include "audio_provider_pcm.h"
|
#include "audio_provider_pcm.h"
|
||||||
|
|
||||||
#include "aegisub_endian.h"
|
|
||||||
#include "audio_controller.h"
|
#include "audio_controller.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
@ -270,7 +269,7 @@ public:
|
||||||
|
|
||||||
// Count how much more data we can have in the entire file
|
// Count how much more data we can have in the entire file
|
||||||
// The first 4 bytes are already eaten by the header.format field
|
// The first 4 bytes are already eaten by the header.format field
|
||||||
uint32_t data_left = Endian::LittleToMachine(header.ch.size) - 4;
|
uint32_t data_left = header.ch.size - 4;
|
||||||
// How far into the file we have processed.
|
// How far into the file we have processed.
|
||||||
// Must be incremented by the riff chunk size fields.
|
// Must be incremented by the riff chunk size fields.
|
||||||
uint32_t filepos = sizeof(header);
|
uint32_t filepos = sizeof(header);
|
||||||
|
@ -294,13 +293,13 @@ public:
|
||||||
|
|
||||||
fmtChunk &fmt = *(fmtChunk*)EnsureRangeAccessible(filepos, sizeof(fmtChunk));
|
fmtChunk &fmt = *(fmtChunk*)EnsureRangeAccessible(filepos, sizeof(fmtChunk));
|
||||||
|
|
||||||
if (Endian::LittleToMachine(fmt.compression) != 1)
|
if (fmt.compression != 1)
|
||||||
throw agi::AudioProviderOpenError("Can't use file, not PCM encoding", 0);
|
throw agi::AudioProviderOpenError("Can't use file, not PCM encoding", 0);
|
||||||
|
|
||||||
// Set stuff inherited from the AudioProvider class
|
// Set stuff inherited from the AudioProvider class
|
||||||
sample_rate = Endian::LittleToMachine(fmt.samplerate);
|
sample_rate = fmt.samplerate;
|
||||||
channels = Endian::LittleToMachine(fmt.channels);
|
channels = fmt.channels;
|
||||||
bytes_per_sample = (Endian::LittleToMachine(fmt.significant_bits_sample) + 7) / 8; // round up to nearest whole byte
|
bytes_per_sample = (fmt.significant_bits_sample + 7) / 8; // round up to nearest whole byte
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (CheckFourcc(ch.type, "data")) {
|
else if (CheckFourcc(ch.type, "data")) {
|
||||||
|
@ -309,7 +308,7 @@ public:
|
||||||
|
|
||||||
if (!got_fmt_header) throw agi::AudioProviderOpenError("Found 'data' chunk before 'fmt ' chunk, file is invalid.", 0);
|
if (!got_fmt_header) throw agi::AudioProviderOpenError("Found 'data' chunk before 'fmt ' chunk, file is invalid.", 0);
|
||||||
|
|
||||||
int64_t samples = Endian::LittleToMachine(ch.size) / bytes_per_sample;
|
int64_t samples = ch.size / bytes_per_sample;
|
||||||
int64_t frames = samples / channels;
|
int64_t frames = samples / channels;
|
||||||
|
|
||||||
IndexPoint ip;
|
IndexPoint ip;
|
||||||
|
@ -325,18 +324,10 @@ public:
|
||||||
|
|
||||||
// Update counters
|
// Update counters
|
||||||
// Make sure they're word aligned
|
// Make sure they're word aligned
|
||||||
data_left -= (Endian::LittleToMachine(ch.size) + 1) & ~1;
|
data_left -= (ch.size + 1) & ~1;
|
||||||
filepos += (Endian::LittleToMachine(ch.size) + 1) & ~1;
|
filepos += (ch.size + 1) & ~1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const {
|
|
||||||
// 8 bit samples don't consider endianness
|
|
||||||
if (bytes_per_sample < 2) return true;
|
|
||||||
// Otherwise test whether we're little endian
|
|
||||||
uint32_t testvalue = 0x008800ff;
|
|
||||||
return testvalue == Endian::LittleToMachine(testvalue);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t w64GuidRIFF[16] = {
|
static const uint8_t w64GuidRIFF[16] = {
|
||||||
|
@ -424,7 +415,7 @@ public:
|
||||||
throw agi::AudioDataNotFoundError("File is not a Wave64 WAVE file", 0);
|
throw agi::AudioDataNotFoundError("File is not a Wave64 WAVE file", 0);
|
||||||
|
|
||||||
// Count how much more data we can have in the entire file
|
// Count how much more data we can have in the entire file
|
||||||
uint64_t data_left = Endian::LittleToMachine(header.file_size) - sizeof(RiffChunk);
|
uint64_t data_left = header.file_size - sizeof(RiffChunk);
|
||||||
// How far into the file we have processed.
|
// How far into the file we have processed.
|
||||||
// Must be incremented by the riff chunk size fields.
|
// Must be incremented by the riff chunk size fields.
|
||||||
uint64_t filepos = sizeof(header);
|
uint64_t filepos = sizeof(header);
|
||||||
|
@ -437,7 +428,7 @@ public:
|
||||||
// Continue reading chunks until out of data
|
// Continue reading chunks until out of data
|
||||||
while (data_left) {
|
while (data_left) {
|
||||||
uint8_t *chunk_guid = (uint8_t*)EnsureRangeAccessible(filepos, 16);
|
uint8_t *chunk_guid = (uint8_t*)EnsureRangeAccessible(filepos, 16);
|
||||||
uint64_t chunk_size = Endian::LittleToMachine(*(uint64_t*)EnsureRangeAccessible(filepos+16, sizeof(uint64_t)));
|
uint64_t chunk_size = *(uint64_t*)EnsureRangeAccessible(filepos+16, sizeof(uint64_t));
|
||||||
|
|
||||||
if (CheckGuid(chunk_guid, w64Guidfmt)) {
|
if (CheckGuid(chunk_guid, w64Guidfmt)) {
|
||||||
if (got_fmt_header)
|
if (got_fmt_header)
|
||||||
|
@ -446,15 +437,15 @@ public:
|
||||||
FormatChunk &fmt = *(FormatChunk*)EnsureRangeAccessible(filepos, sizeof(FormatChunk));
|
FormatChunk &fmt = *(FormatChunk*)EnsureRangeAccessible(filepos, sizeof(FormatChunk));
|
||||||
got_fmt_header = true;
|
got_fmt_header = true;
|
||||||
|
|
||||||
if (Endian::LittleToMachine(fmt.format.wFormatTag) == 3)
|
if (fmt.format.wFormatTag == 3)
|
||||||
throw agi::AudioProviderOpenError("File is IEEE 32 bit float format which isn't supported. Bug the developers if this matters.", 0);
|
throw agi::AudioProviderOpenError("File is IEEE 32 bit float format which isn't supported. Bug the developers if this matters.", 0);
|
||||||
if (Endian::LittleToMachine(fmt.format.wFormatTag) != 1)
|
if (fmt.format.wFormatTag != 1)
|
||||||
throw agi::AudioProviderOpenError("Can't use file, not PCM encoding", 0);
|
throw agi::AudioProviderOpenError("Can't use file, not PCM encoding", 0);
|
||||||
|
|
||||||
// Set stuff inherited from the AudioProvider class
|
// Set stuff inherited from the AudioProvider class
|
||||||
sample_rate = Endian::LittleToMachine(fmt.format.nSamplesPerSec);
|
sample_rate = fmt.format.nSamplesPerSec;
|
||||||
channels = Endian::LittleToMachine(fmt.format.nChannels);
|
channels = fmt.format.nChannels;
|
||||||
bytes_per_sample = (Endian::LittleToMachine(fmt.format.wBitsPerSample) + 7) / 8; // round up to nearest whole byte
|
bytes_per_sample = (fmt.format.wBitsPerSample + 7) / 8; // round up to nearest whole byte
|
||||||
}
|
}
|
||||||
else if (CheckGuid(chunk_guid, w64Guiddata)) {
|
else if (CheckGuid(chunk_guid, w64Guiddata)) {
|
||||||
if (!got_fmt_header)
|
if (!got_fmt_header)
|
||||||
|
@ -478,14 +469,6 @@ public:
|
||||||
filepos += (chunk_size + 7) & ~7;
|
filepos += (chunk_size + 7) & ~7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const {
|
|
||||||
// 8 bit samples don't consider endianness
|
|
||||||
if (bytes_per_sample < 2) return true;
|
|
||||||
// Otherwise test whether we're little endian
|
|
||||||
uint32_t testvalue = 0x008800ff;
|
|
||||||
return testvalue == Endian::LittleToMachine(testvalue);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename) {
|
std::unique_ptr<AudioProvider> CreatePCMAudioProvider(agi::fs::path const& filename) {
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
#define CacheBlockSize (1 << CacheBits)
|
#define CacheBlockSize (1 << CacheBits)
|
||||||
|
|
||||||
RAMAudioProvider::RAMAudioProvider(std::unique_ptr<AudioProvider>&& src, agi::BackgroundRunner *br) {
|
RAMAudioProvider::RAMAudioProvider(std::unique_ptr<AudioProvider>&& src, agi::BackgroundRunner *br) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
blockcache.resize((src->GetNumSamples() * src->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
|
blockcache.resize((src->GetNumSamples() * src->GetBytesPerSample() + CacheBlockSize - 1) >> CacheBits);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +55,6 @@ RAMAudioProvider::RAMAudioProvider(std::unique_ptr<AudioProvider>&& src, agi::Ba
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy parameters
|
// Copy parameters
|
||||||
samples_native_endian = src->AreSamplesNativeEndian();
|
|
||||||
bytes_per_sample = src->GetBytesPerSample();
|
bytes_per_sample = src->GetBytesPerSample();
|
||||||
num_samples = src->GetNumSamples();
|
num_samples = src->GetNumSamples();
|
||||||
channels = src->GetChannels();
|
channels = src->GetChannels();
|
||||||
|
|
|
@ -48,13 +48,10 @@ class RAMAudioProvider : public AudioProvider {
|
||||||
#else
|
#else
|
||||||
boost::container::stable_vector<std::array<char, 1 << 22>> blockcache;
|
boost::container::stable_vector<std::array<char, 1 << 22>> blockcache;
|
||||||
#endif
|
#endif
|
||||||
bool samples_native_endian;
|
|
||||||
|
|
||||||
void FillCache(AudioProvider *source, agi::ProgressSink *ps);
|
void FillCache(AudioProvider *source, agi::ProgressSink *ps);
|
||||||
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
void FillBuffer(void *buf, int64_t start, int64_t count) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RAMAudioProvider(std::unique_ptr<AudioProvider>&& source, agi::BackgroundRunner *br);
|
RAMAudioProvider(std::unique_ptr<AudioProvider>&& source, agi::BackgroundRunner *br);
|
||||||
|
|
||||||
bool AreSamplesNativeEndian() const { return samples_native_endian; }
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,7 +71,6 @@ public:
|
||||||
|
|
||||||
/// @brief Does this provider benefit from external caching?
|
/// @brief Does this provider benefit from external caching?
|
||||||
virtual bool NeedsCache() const { return false; }
|
virtual bool NeedsCache() const { return false; }
|
||||||
virtual bool AreSamplesNativeEndian() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioProviderFactory : public Factory1<AudioProvider, agi::fs::path> {
|
class AudioProviderFactory : public Factory1<AudioProvider, agi::fs::path> {
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
#include "subtitle_format_ebu3264.h"
|
#include "subtitle_format_ebu3264.h"
|
||||||
|
|
||||||
#include "aegisub_endian.h"
|
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
#include "ass_style.h"
|
#include "ass_style.h"
|
||||||
|
@ -491,7 +490,7 @@ namespace
|
||||||
// construct a base block that can be copied and filled
|
// construct a base block that can be copied and filled
|
||||||
BlockTTI base;
|
BlockTTI base;
|
||||||
base.sgn = sub.group_number;
|
base.sgn = sub.group_number;
|
||||||
base.sn = Endian::MachineToLittle(subtitle_number++);
|
base.sn = subtitle_number++;
|
||||||
base.ebn = 255;
|
base.ebn = 255;
|
||||||
base.cf = sub.comment_flag;
|
base.cf = sub.comment_flag;
|
||||||
memset(base.tf, EBU_FORMAT_UNUSED_SPACE, sizeof(base.tf));
|
memset(base.tf, EBU_FORMAT_UNUSED_SPACE, sizeof(base.tf));
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#ifdef WITH_FFMS2
|
#ifdef WITH_FFMS2
|
||||||
#include "video_provider_ffmpegsource.h"
|
#include "video_provider_ffmpegsource.h"
|
||||||
|
|
||||||
#include "aegisub_endian.h"
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
Loading…
Reference in New Issue