| 167 | } |
| 168 | |
| 169 | static void read_wav(const std::string& path, std::vector<float>& left_ch, std::vector<float>& right_ch) { |
| 170 | // You can use this command to convert the file to the expected format: |
| 171 | // ffmpeg -i input_audio.mp3 -ar 44100 -ac 2 -c:a pcm_f32le -f wav output.wav |
| 172 | |
| 173 | constexpr uint16_t wave_format_pcm = 0x0001; |
| 174 | constexpr uint16_t wave_format_ieee_float = 0x0003; |
| 175 | constexpr uint16_t wave_format_extensible = 0xFFFE; |
| 176 | |
| 177 | std::ifstream input_stream(path, std::ios::binary); |
| 178 | |
| 179 | AUDIOGEN_CHECK(input_stream); |
| 180 | |
| 181 | char riff[4], wave[4], fmt[4]; |
| 182 | uint32_t riff_size, fmt_chunk_sz; |
| 183 | uint16_t audio_format, audio_num_channels; |
| 184 | uint32_t audio_sr, byte_rate, data_chunk_sz; |
| 185 | uint16_t block_align, audio_bits_per_sample; |
| 186 | |
| 187 | std::vector<float> data_chunk; |
| 188 | |
| 189 | std::streampos riff_base = input_stream.tellg(); |
| 190 | input_stream.read(riff, 4); |
| 191 | input_stream.read(reinterpret_cast<char*>(&riff_size), 4); |
| 192 | AUDIOGEN_CHECK(bool(riff_size)); |
| 193 | input_stream.read(wave, 4); |
| 194 | if(std::string(riff, 4) != "RIFF" || std::string(wave, 4) != "WAVE") { |
| 195 | fprintf(stderr, |
| 196 | "BAD file, or unsupported format, use this ffmpeg command to convert your file:\n" |
| 197 | "ffmpeg -i input_audio.mp3 -ar 44100 -ac 2 -c:a pcm_f32le -f wav output.wav\n\n"); |
| 198 | exit(EXIT_FAILURE); |
| 199 | } |
| 200 | |
| 201 | input_stream.read(fmt, 4); |
| 202 | AUDIOGEN_CHECK(std::string(fmt, 4) == "fmt "); |
| 203 | input_stream.read(reinterpret_cast<char*>(&fmt_chunk_sz), 4); |
| 204 | AUDIOGEN_CHECK(fmt_chunk_sz >= 16); |
| 205 | |
| 206 | input_stream.read(reinterpret_cast<char*>(&audio_format), 2); |
| 207 | input_stream.read(reinterpret_cast<char*>(&audio_num_channels), 2); |
| 208 | input_stream.read(reinterpret_cast<char*>(&audio_sr), 4); |
| 209 | input_stream.read(reinterpret_cast<char*>(&byte_rate), 4); |
| 210 | input_stream.read(reinterpret_cast<char*>(&block_align), 2); |
| 211 | input_stream.read(reinterpret_cast<char*>(&audio_bits_per_sample), 2); |
| 212 | |
| 213 | if (!(audio_format == wave_format_ieee_float || audio_format == wave_format_pcm || audio_format == wave_format_extensible) || |
| 214 | audio_num_channels != k_audio_num_channels || |
| 215 | audio_sr != k_audio_sr || |
| 216 | audio_bits_per_sample != k_bits_per_sample) { |
| 217 | fprintf(stderr, |
| 218 | "Unsupported WAV format (need 44.1kHz, stereo, 32-bit float), use this ffmpeg command to convert your file:\n" |
| 219 | "ffmpeg -i input_audio.mp3 -ar 44100 -ac 2 -c:a pcm_f32le -f wav output.wav\n\n"); |
| 220 | exit(EXIT_FAILURE); |
| 221 | } |
| 222 | |
| 223 | // Skip any extension bytes in the fmt chunk |
| 224 | if (fmt_chunk_sz > 16) { |
| 225 | input_stream.seekg(static_cast<std::streamoff>(fmt_chunk_sz - 16), std::ios::cur); |
| 226 | AUDIOGEN_CHECK(bool(input_stream)); |