Skip to content

Commit 3eb3eb9

Browse files
WAV: support uncompressed 32-bit float and 64-bit double IEEE formats
1 parent 65fda2e commit 3eb3eb9

File tree

1 file changed

+50
-4
lines changed

1 file changed

+50
-4
lines changed

src/Decoders/WAV/WAVDataProvider.cpp

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@ std::shared_ptr<clBlob> TryMP3InsideWAV( const std::shared_ptr<clBlob>& Data )
5353
return nullptr;
5454
}
5555

56+
template <typename T> void ConvertClamp_IEEEToInt16( const T* Src, int16_t* Dst, size_t NumFloats )
57+
{
58+
const T* End = Src + NumFloats;
59+
60+
while ( Src < End )
61+
{
62+
T f = *Src++;
63+
int32_t v = int( f * 32167.0 );
64+
*Dst++ = ( v > 32167 ) ? 32167 : ( v < -32167 ) ? -32167 : v;
65+
}
66+
}
67+
5668
clWAVDataProvider::clWAVDataProvider( const std::shared_ptr<clBlob>& Data )
5769
: m_Data( Data )
5870
, m_DataSize( Data ? Data->GetDataSize() : 0 )
@@ -62,22 +74,51 @@ clWAVDataProvider::clWAVDataProvider( const std::shared_ptr<clBlob>& Data )
6274
{
6375
const sWAVHeader* Header = reinterpret_cast<const sWAVHeader*>( Data->GetDataPtr() );
6476

65-
const uint16_t FORMAT_PCM = 0x0001;
77+
const uint16_t FORMAT_PCM = 0x0001;
78+
const uint16_t FORMAT_FLOAT = 0x0003;
6679

67-
bool IsPCM = Header->FormatTag == FORMAT_PCM;
80+
bool IsPCM = Header->FormatTag == FORMAT_PCM;
81+
bool IsFloat = Header->FormatTag == FORMAT_FLOAT;
6882
bool IsRIFF = memcmp( &Header->RIFF, "RIFF", 4 ) == 0;
6983
bool IsWAVE = memcmp( &Header->WAVE, "WAVE", 4 ) == 0;
7084

7185
// can only handle uncompressed .WAV files
72-
if ( IsRIFF && IsWAVE && IsPCM )
86+
if ( IsRIFF && IsWAVE && (IsPCM|IsFloat) )
7387
{
7488
m_Format.m_NumChannels = Header->Channels;
7589
m_Format.m_SamplesPerSecond = Header->SampleRate;
7690
m_Format.m_BitsPerSample = Header->nBitsperSample;
7791

7892
m_DataSize = std::min( static_cast<size_t>(Header->DataSize), Data->GetDataSize() - sizeof(sWAVHeader) );
7993

80-
// m_DataSize = Data->GetDataSize() - sizeof(sWAVHeader);
94+
if ( IsFloat )
95+
{
96+
// replace the blob and convert data to 16-bit
97+
std::vector<uint8_t> NewData;
98+
NewData.resize( m_Data->GetDataSize() );
99+
int16_t* Dst = reinterpret_cast<int16_t*>( NewData.data()+sizeof(sWAVHeader) );
100+
101+
if ( Header->nBitsperSample == 32 )
102+
{
103+
const float* Src = reinterpret_cast<const float*>( m_Data->GetDataPtr()+sizeof(sWAVHeader)+2 );
104+
ConvertClamp_IEEEToInt16<float>( Src, Dst, m_DataSize / 4 );
105+
m_DataSize = m_DataSize/2 - 3;
106+
}
107+
else if ( Header->nBitsperSample == 64 )
108+
{
109+
const double* Src = reinterpret_cast<const double*>( m_Data->GetDataPtr()+sizeof(sWAVHeader)+2 );
110+
ConvertClamp_IEEEToInt16<double>( Src, Dst, m_DataSize / 8 );
111+
m_DataSize = m_DataSize/4 - 3;
112+
}
113+
else
114+
{
115+
Log_Error( "Unknown float format in WAV" );
116+
m_DataSize = 0;
117+
}
118+
119+
m_Data = std::make_shared<clBlob>( NewData );
120+
m_Format.m_BitsPerSample = 16;
121+
}
81122

82123
if ( IsVerbose() )
83124
{
@@ -91,6 +132,11 @@ clWAVDataProvider::clWAVDataProvider( const std::shared_ptr<clBlob>& Data )
91132
}
92133

93134
}
135+
else
136+
{
137+
Log_Error( "Unsupported WAV file" );
138+
m_DataSize = 0;
139+
}
94140
}
95141
}
96142

0 commit comments

Comments
 (0)