@@ -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+
5668clWAVDataProvider::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