mirror of
https://github.com/SFML/SFML.git
synced 2025-01-31 13:45:13 +08:00
Added support for extensible format PCM wave files.
This commit is contained in:
parent
2aa70def6f
commit
fc54dba3d7
@ -31,6 +31,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -88,6 +89,14 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sf::Uint64 mainChunkSize = 12;
|
const sf::Uint64 mainChunkSize = 12;
|
||||||
|
|
||||||
|
const sf::Uint16 waveFormatPcm = 1;
|
||||||
|
|
||||||
|
const sf::Uint16 waveFormatExtensible= 65534;
|
||||||
|
|
||||||
|
const char* waveSubformatPcm =
|
||||||
|
"\x01\x00\x00\x00\x00\x00\x10\x00"
|
||||||
|
"\x80\x00\x00\xAA\x00\x38\x9B\x71";
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
@ -226,6 +235,9 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
|||||||
Uint32 subChunkSize = 0;
|
Uint32 subChunkSize = 0;
|
||||||
if (!decode(*m_stream, subChunkSize))
|
if (!decode(*m_stream, subChunkSize))
|
||||||
return false;
|
return false;
|
||||||
|
Int64 subChunkStart = m_stream->tell();
|
||||||
|
if (subChunkStart == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Check which chunk it is
|
// Check which chunk it is
|
||||||
if ((subChunkId[0] == 'f') && (subChunkId[1] == 'm') && (subChunkId[2] == 't') && (subChunkId[3] == ' '))
|
if ((subChunkId[0] == 'f') && (subChunkId[1] == 'm') && (subChunkId[2] == 't') && (subChunkId[3] == ' '))
|
||||||
@ -236,7 +248,7 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
|||||||
Uint16 format = 0;
|
Uint16 format = 0;
|
||||||
if (!decode(*m_stream, format))
|
if (!decode(*m_stream, format))
|
||||||
return false;
|
return false;
|
||||||
if (format != 1) // PCM
|
if ((format != waveFormatPcm) && (format != waveFormatExtensible))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Channel count
|
// Channel count
|
||||||
@ -272,12 +284,45 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
|||||||
}
|
}
|
||||||
m_bytesPerSample = bitsPerSample / 8;
|
m_bytesPerSample = bitsPerSample / 8;
|
||||||
|
|
||||||
// Skip potential extra information (should not exist for PCM)
|
if (format == waveFormatExtensible)
|
||||||
if (subChunkSize > 16)
|
|
||||||
{
|
{
|
||||||
if (m_stream->seek(m_stream->tell() + subChunkSize - 16) == -1)
|
// Extension size
|
||||||
|
Uint16 extensionSize = 0;
|
||||||
|
if (!decode(*m_stream, extensionSize))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Valid bits per sample
|
||||||
|
Uint16 validBitsPerSample = 0;
|
||||||
|
if (!decode(*m_stream, validBitsPerSample))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Channel mask
|
||||||
|
Uint32 channelMask = 0;
|
||||||
|
if (!decode(*m_stream, channelMask))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Subformat
|
||||||
|
char subformat[16];
|
||||||
|
if (m_stream->read(subformat, sizeof(subformat)) != sizeof(subformat))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (std::memcmp(subformat, waveSubformatPcm, sizeof(subformat)) != 0)
|
||||||
|
{
|
||||||
|
err() << "Unsupported format: extensible format with non-PCM subformat" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validBitsPerSample != bitsPerSample)
|
||||||
|
{
|
||||||
|
err() << "Unsupported format: sample size (" << validBitsPerSample << " bits) and "
|
||||||
|
"sample container size (" << bitsPerSample << " bits) differ" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip potential extra information
|
||||||
|
if (m_stream->seek(subChunkStart + subChunkSize) == -1)
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else if ((subChunkId[0] == 'd') && (subChunkId[1] == 'a') && (subChunkId[2] == 't') && (subChunkId[3] == 'a'))
|
else if ((subChunkId[0] == 'd') && (subChunkId[1] == 'a') && (subChunkId[2] == 't') && (subChunkId[3] == 'a'))
|
||||||
{
|
{
|
||||||
@ -287,7 +332,7 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
|||||||
info.sampleCount = subChunkSize / m_bytesPerSample;
|
info.sampleCount = subChunkSize / m_bytesPerSample;
|
||||||
|
|
||||||
// Store the start and end position of samples in the file
|
// Store the start and end position of samples in the file
|
||||||
m_dataStart = m_stream->tell();
|
m_dataStart = subChunkStart;
|
||||||
m_dataEnd = m_dataStart + info.sampleCount * m_bytesPerSample;
|
m_dataEnd = m_dataStart + info.sampleCount * m_bytesPerSample;
|
||||||
|
|
||||||
dataChunkFound = true;
|
dataChunkFound = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user