WaveBank streaming updated to support Advanced Format (4Kn) (#293)

This commit is contained in:
Chuck Walbourn 2021-12-06 19:01:36 -08:00 коммит произвёл GitHub
Родитель faa6bd944a
Коммит e6bb9ef701
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 31 добавлений и 9 удалений

Просмотреть файл

@ -40,7 +40,7 @@ using namespace DirectX;
namespace
{
const size_t DVD_SECTOR_SIZE = 2048;
const size_t MEMORY_ALLOC_SIZE = 4096;
const size_t ADVANCED_FORMAT_SECTOR_SIZE = 4096;
const size_t MAX_BUFFER_COUNT = 3;
#ifdef DIRECTX_ENABLE_SEEK_TABLES
@ -53,7 +53,7 @@ namespace
struct apu_deleter { void operator()(void* p) noexcept { if (p) ApuFree(p); } };
#endif
size_t ComputeAsyncPacketSize(_In_ const WAVEFORMATEX* wfx, uint32_t tag)
size_t ComputeAsyncPacketSize(_In_ const WAVEFORMATEX* wfx, uint32_t tag, uint32_t alignment)
{
if (!wfx)
return 0;
@ -71,13 +71,10 @@ namespace
UNREFERENCED_PARAMETER(tag);
#endif
buffer = AlignUp(buffer, MEMORY_ALLOC_SIZE);
buffer = AlignUp(buffer, size_t(alignment) * 2);
buffer = std::max<size_t>(65536u, buffer);
return buffer;
}
static_assert(MEMORY_ALLOC_SIZE >= DVD_SECTOR_SIZE, "Memory size should be larger than sector size");
static_assert(MEMORY_ALLOC_SIZE >= DVD_SECTOR_SIZE || (MEMORY_ALLOC_SIZE% DVD_SECTOR_SIZE) == 0, "Memory size should be multiples of sector size");
}
@ -105,6 +102,7 @@ public:
mCurrentDiskReadBuffer(0),
mCurrentPlayBuffer(0),
mBlockAlign(0),
mAsyncAlign(DVD_SECTOR_SIZE),
mCurrentPosition(0),
mOffsetBytes(0),
mLengthInBytes(0),
@ -129,6 +127,7 @@ public:
mOffsetBytes = metadata.offsetBytes;
mLengthInBytes = metadata.lengthBytes;
mAsyncAlign = mWaveBank->IsAdvancedFormat() ? ADVANCED_FORMAT_SECTOR_SIZE : DVD_SECTOR_SIZE;
#ifdef DIRECTX_ENABLE_SEEK_TABLES
WaveBankSeekData seekData = {};
@ -372,6 +371,7 @@ private:
uint32_t mCurrentDiskReadBuffer;
uint32_t mCurrentPlayBuffer;
uint32_t mBlockAlign;
uint32_t mAsyncAlign;
size_t mCurrentPosition;
size_t mOffsetBytes;
size_t mLengthInBytes;
@ -403,7 +403,7 @@ HRESULT SoundStreamInstance::Impl::AllocateStreamingBuffers(const WAVEFORMATEX*
uint32_t tag = GetFormatTag(wfx);
size_t packetSize = ComputeAsyncPacketSize(wfx, tag);
size_t packetSize = ComputeAsyncPacketSize(wfx, tag, mAsyncAlign);
if (!packetSize)
return E_UNEXPECTED;
@ -420,7 +420,7 @@ HRESULT SoundStreamInstance::Impl::AllocateStreamingBuffers(const WAVEFORMATEX*
{
mSitching = true;
stitchSize = AlignUp<size_t>(wfx->nBlockAlign, DVD_SECTOR_SIZE);
stitchSize = AlignUp<size_t>(wfx->nBlockAlign, mAsyncAlign);
totalSize += uint64_t(stitchSize) * uint64_t(MAX_BUFFER_COUNT);
if (totalSize > UINT32_MAX)
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
@ -531,6 +531,13 @@ HRESULT SoundStreamInstance::Impl::ReadBuffers() noexcept
DWORD error = GetLastError();
if (error != ERROR_IO_PENDING)
{
#ifdef _DEBUG
if (error == ERROR_INVALID_PARAMETER)
{
// May be due to Advanced Format (4Kn) vs. DVD sector size. See the xwbtool -af switch.
OutputDebugStringA("ERROR: non-buffered async I/O failed: check disk sector size vs. streaming wave bank alignment!\n");
}
#endif
return HRESULT_FROM_WIN32(error);
}
}

Просмотреть файл

@ -444,6 +444,12 @@ bool WaveBank::IsStreamingBank() const noexcept
}
bool WaveBank::IsAdvancedFormat() const noexcept
{
return (pImpl->mReader.GetWaveAlignment() == 4096);
}
size_t WaveBank::GetSampleSizeInBytes(unsigned int index) const noexcept
{
if (index >= pImpl->mReader.Count())

Просмотреть файл

@ -1388,3 +1388,9 @@ HANDLE WaveBankReader::GetAsyncHandle() const noexcept
{
return (pImpl->m_data.dwFlags & BANKDATA::TYPE_STREAMING) ? pImpl->m_async : INVALID_HANDLE_VALUE;
}
uint32_t WaveBankReader::GetWaveAlignment() const noexcept
{
return pImpl->m_data.dwAlignment;
}

Просмотреть файл

@ -62,6 +62,8 @@ namespace DirectX
HANDLE GetAsyncHandle() const noexcept;
uint32_t GetWaveAlignment() const noexcept;
struct Metadata
{
uint32_t duration;

Просмотреть файл

@ -333,6 +333,7 @@ namespace DirectX
bool __cdecl IsPrepared() const noexcept;
bool __cdecl IsInUse() const noexcept;
bool __cdecl IsStreamingBank() const noexcept;
bool __cdecl IsAdvancedFormat() const noexcept;
size_t __cdecl GetSampleSizeInBytes(unsigned int index) const noexcept;
// Returns size of wave audio data

Просмотреть файл

@ -1441,7 +1441,7 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
else if (xma)
{
// Xbox requires 2K alignment for XMA2
dwAlignment = 2048;
dwAlignment = 2048 /* XMA_BYTES_PER_PACKET */;
}
// Convert wave format to miniformat, failing if any won't map