20 std::vector< uint8_t >::size_type index,
25 return ( source[ index + 3 ] << 24 ) | ( source[ index + 2 ] << 16 ) |
26 ( source[ index + 1 ] << 8 ) | source[ index ];
29 return ( source[ index ] << 24 ) | ( source[ index + 1 ] << 16 ) |
30 ( source[ index + 2 ] << 8 ) | source[ index + 3 ];
34 std::vector< uint8_t >::size_type index,
39 return std::int16_t( source[ index + 1 ] << 8 ) | source[ index ];
42 return std::int16_t( source[ index ] << 8 ) | source[ index + 1 ];
47 std::string header( data.begin(), data.begin() + 4 );
49 if ( header ==
"RIFF" )
53 if ( header ==
"FORM" )
61 inline std::vector< uint8_t >::difference_type
index_of(
const std::vector< uint8_t >& source,
62 const std::string& str )
64 const auto length = str.length();
66 for ( decltype( source.size() - length ) i = 0; i < source.size() - length; i++ )
68 using diff_t = std::vector< uint8_t >::difference_type;
69 std::string section( source.begin() + diff_t( i ),
70 source.begin() + diff_t( i + length ) );
83 return float( sample - 128 ) / float( 128 );
88 return float( sample ) / 32768.f;
91 inline std::vector< std::vector< float > >
read(
const std::vector< std::uint8_t >& data )
93 const std::string header_chunk_id( data.begin(), data.begin() + 4 );
94 const std::string format( data.begin() + 8, data.begin() + 12 );
96 const auto index_of_data_chunk =
index_of( data,
"data" );
97 const auto index_of_format_chunk =
index_of( data,
"fmt" );
99 if ( index_of_data_chunk == -1 || index_of_format_chunk == -1 ||
100 header_chunk_id !=
"RIFF" || format !=
"WAVE" )
102 std::cerr <<
"ERROR: this doesn't seem to be a valid .WAV file" << std::endl;
106 const auto f = index_of_format_chunk;
107 using size_t = std::vector< std::uint8_t >::size_type;
108 const std::string format_chunk_id( data.begin() + f, data.begin() + f + 4 );
116 const int bytes_per_sample = bit_depth / 8;
119 if ( audio_format != 1 )
121 std::cout <<
"ERROR: this is a compressed .WAV file and this library does not support " 122 "decoding them at present" 127 if ( channel_count < 1 || channel_count > 2 )
129 std::cout <<
"ERROR: this WAV file seems to be neither mono nor stereo (perhaps " 130 "multi-track, or corrupted?)" 135 if ( ( bytes_per_second != ( channel_count * sample_rate * bit_depth ) / 8 ) ||
136 ( bytes_per_block != ( channel_count * bytes_per_sample ) ) )
138 std::cout <<
"ERROR: the header data in this WAV file seems to be inconsistent" 143 if ( bit_depth != 8 && bit_depth != 16 && bit_depth != 24 )
145 std::cout <<
"ERROR: this file has a bit depth that is not 8, 16 or 24 bits" 150 const auto d = index_of_data_chunk;
151 const std::string data_chunk_id( data.begin() + d, data.begin() + d + 4 );
152 const auto data_chunk_size =
155 const auto num_samples = data_chunk_size / ( channel_count * bit_depth / 8 );
156 const auto sample_start_index = index_of_data_chunk + 8;
158 std::vector< std::vector< float > > samples;
159 samples.resize( channel_count );
161 for (
int i = 0; i < num_samples; i++ )
163 for (
int channel = 0; channel < channel_count; channel++ )
165 const auto sample_index =
166 sample_start_index + ( bytes_per_block * i ) + channel * bytes_per_sample;
168 if ( bit_depth == 8 )
171 samples[ channel ].push_back( sample );
173 else if ( bit_depth == 16 )
177 samples[ channel ].push_back( sample );
179 else if ( bit_depth == 24 )
181 auto sample_as_int = 0;
182 sample_as_int = ( data[ sample_index + 2 ] << 16 ) |
183 ( data[ sample_index + 1 ] << 8 ) | data[ sample_index ];
185 if ( ( sample_as_int & 0x800000 ) >
193 const auto sample = sample_as_int / 8388608.f;
194 samples[ channel ].push_back( sample );
202 inline std::vector< std::vector< float > >
read(
const std::string& filename )
204 std::ifstream file( filename, std::ios::binary );
208 std::cerr <<
"ERROR: File doesn't exist or otherwise can't load file: " << filename
213 file.unsetf( std::ios::skipws );
214 std::istream_iterator< std::uint8_t > begin( file );
215 std::istream_iterator< std::uint8_t > end;
216 std::vector< std::uint8_t > data( begin, end );
222 std::cerr <<
"wrong format: " << format << std::endl;
int audio_file_format(const std::vector< std::uint8_t > &data)
Definition: wave_reader.hpp:45
std::int16_t two_bytes_to_int(const std::vector< uint8_t > &source, std::vector< uint8_t >::size_type index, endian_t endianness=endian_t::LittleEndian)
Definition: wave_reader.hpp:33
std::vector< uint8_t >::difference_type index_of(const std::vector< uint8_t > &source, const std::string &str)
Definition: wave_reader.hpp:61
endian_t
Definition: wave_reader.hpp:13
float two_bytes_to_sample(int16_t sample)
Definition: wave_reader.hpp:86
float byte_to_sample(uint8_t sample)
Definition: wave_reader.hpp:81
std::int32_t four_bytes_to_int(const std::vector< uint8_t > &source, std::vector< uint8_t >::size_type index, endian_t endianness=endian_t::LittleEndian)
Definition: wave_reader.hpp:19
std::vector< std::vector< float > > read(const std::vector< std::uint8_t > &data)
Definition: wave_reader.hpp:91
Definition: wave_reader.hpp:11