#include #include #include #include #include #include #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif #include #ifdef __GNUC__ #pragma GCC diagnostic pop #endif namespace psemek::audio { namespace { std::vector convert_audio(std::vector> const & channels, int frequency) { if (channels.empty() || channels.size() > 2) throw util::exception(util::to_string("Can't convert audio with ", static_cast(channels.size()), " channels")); std::vector result(channels[0].size() * 2); auto out = result.begin(); if (channels.size() == 1) { for (auto p = channels[0].begin(); p != channels[0].end(); ++p) { *out++ = *p; *out++ = *p; } } else if (channels.size() == 2) { for (auto p0 = channels[0].begin(), p1 = channels[1].begin(); p0 != channels[0].end(); ++p0, ++p1) { *out++ = *p0; *out++ = *p1; } } if (frequency != audio::frequency) { audio::resampler resampler(audio::frequency * 1.f / frequency); resampler.feed(result); result = resampler.grab_result(); } return result; } } track_ptr load_wav(util::span data) { std::vector data_u8(data.size()); std::copy(data.begin(), data.end(), reinterpret_cast(data_u8.data())); AudioFile audio_file; audio_file.shouldLogErrorsToConsole(false); audio_file.onError = [](std::string const & error) { throw util::exception("Failed to load WAV file: " + error); }; audio_file.loadFromMemory(data_u8); return load_raw(convert_audio(audio_file.samples, audio_file.getSampleRate())); } track_ptr load_wav(std::vector const & data) { return load_wav(util::span(data)); } }