Loading audio/include/audio/audio_source.hpp +0 −2 Original line number Diff line number Diff line Loading @@ -7,7 +7,6 @@ #include <vector> #include <cstdint> #include <string> #include <SDL2/SDL_audio.h> namespace lfs { struct ResourceHandle; } Loading Loading @@ -53,7 +52,6 @@ private: lfs::ResourceHandle* m_resource_handle; std::vector<float> m_audio_data; AudioDecoder* m_decoder; SDL_AudioSpec m_source_spec; std::uint32_t m_sample_rate; std::uint32_t m_channels; std::uint32_t m_playback_position; Loading audio/include/audio/audio_system.hpp +3 −5 Original line number Diff line number Diff line Loading @@ -2,8 +2,8 @@ # define AUDIO_AUDIO_SYSTEM_HPP_INCLUDED #include <com/library.hpp> #include <osi/audio.hpp> #include <cstdint> #include <SDL2/SDL_audio.h> namespace audio { Loading Loading @@ -38,7 +38,6 @@ struct AudioSystem final : public com::Library std::uint32_t get_sample_rate() const { return m_sample_rate; } std::uint32_t get_channels() const { return m_channels; } SDL_AudioSpec const& get_audio_spec() const { return m_audio_spec; } protected: void initialize() override; Loading @@ -50,15 +49,14 @@ private: AudioMixer* m_master_mixer; AudioProcessor* m_audio_processor; SDL_AudioDeviceID m_audio_device; SDL_AudioSpec m_audio_spec; osi::AudioDevice m_audio_device; std::uint32_t m_sample_rate; std::uint32_t m_channels; float m_master_volume; bool m_is_playing; // SDL callback wrapper // Callback wrapper to satisfy void* userdata format for audio friend void audio_callback(void* userdata, std::uint8_t* stream, int len); // concrete audio callback implementation void audio_callback_impl(std::uint8_t* stream, int len); Loading audio/include/audio/mp3_decoder.hpp +5 −5 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ # define AUDIO_MP3_DECODER_HPP_INCLUDED #include "audio_decoder.hpp" #include <SDL2/SDL_audio.h> #include <osi/audio.hpp> #include <vector> #include <cstdint> Loading @@ -18,7 +18,7 @@ namespace audio public: MP3Decoder(std::vector<std::uint8_t> const& mp3_data, std::uint32_t target_sample_rate, std::uint32_t target_channels); std::uint8_t target_channels); ~MP3Decoder() override; Loading @@ -30,10 +30,10 @@ namespace audio std::vector<std::uint8_t> const& m_mp3_data; mp3dec_ex_t* m_dec; std::uint32_t m_target_sample_rate; std::uint32_t m_target_channels; std::uint8_t m_target_channels; std::uint32_t m_source_sample_rate; std::uint32_t m_source_channels; SDL_AudioStream* m_audio_stream; std::uint8_t m_source_channels; osi::AudioConverter m_converter; std::vector<float> m_decode_buffer; bool m_valid; }; Loading audio/src/audio_processor.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ namespace audio { if (!m_ring_buffer.push(sample)) { std::cerr << "Audio: audio buffer overrun, dropping samples" << std::endl; LOG(logging_severity_level::LSL_WARNING, "Audio: audio buffer overrun, dropping samples"); return; // Stop if we can't push anymore } } Loading audio/src/audio_source.cpp +15 −108 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ #include <audio/audio_system.hpp> #include <audio/mp3_decoder.hpp> #include <lfs/index.hpp> #include <SDL2/SDL_audio.h> #include <osi/audio.hpp> #include <algorithm> #include <cstring> #include <iostream> Loading @@ -22,7 +22,6 @@ AudioSource::AudioSource(std::string const& name) , m_is_streaming(false) , m_volume(1.0f) { SDL_zero(m_source_spec); } AudioSource::~AudioSource() Loading Loading @@ -229,134 +228,42 @@ void AudioSource::decode_audio_data() } else { std::cerr << "Audio: Unknown audio file format" << std::endl; LOG(logging_severity_level::LSL_ERROR, "Audio: Unknown audio file format for file: " << m_resource_handle->name()); } } bool AudioSource::load_wav_file(std::vector<std::uint8_t> const& file_data) { SDL_RWops* rw = SDL_RWFromConstMem(file_data.data(), static_cast<int>(file_data.size())); if (rw == nullptr) return false; std::uint8_t* wav_buffer = nullptr; std::uint32_t wav_length = 0; if (SDL_LoadWAV_RW(rw, 1, &m_source_spec, &wav_buffer, &wav_length) == nullptr) { return false; } // TODO: unify this with audio system SDL_AudioSpec target_spec; SDL_zero(target_spec); target_spec.freq = 44100; target_spec.format = AUDIO_F32SYS; target_spec.channels = 2; SDL_AudioStream* stream = SDL_NewAudioStream( m_source_spec.format, m_source_spec.channels, m_source_spec.freq, target_spec.format, target_spec.channels, target_spec.freq ); if (stream == nullptr) { SDL_FreeWAV(wav_buffer); return false; } // Convert audio data if (SDL_AudioStreamPut(stream, wav_buffer, wav_length) < 0) { SDL_FreeAudioStream(stream); SDL_FreeWAV(wav_buffer); return false; } SDL_AudioStreamFlush(stream); int available = SDL_AudioStreamAvailable(stream); if (available <= 0) { SDL_FreeAudioStream(stream); SDL_FreeWAV(wav_buffer); return false; } m_audio_data.resize(available / sizeof(float)); SDL_AudioStreamGet(stream, m_audio_data.data(), available); // Use OSI audio loader to load and convert WAV file osi::WavData wav_data = osi::AudioLoader::load_wav( file_data, 44100, 2, osi::AudioFormat::Float32); m_sample_rate = target_spec.freq; m_channels = target_spec.channels; m_audio_data = std::move(wav_data.samples); m_sample_rate = wav_data.sample_rate; m_channels = wav_data.channels; m_total_samples = static_cast<std::uint32_t>(m_audio_data.size()); SDL_FreeAudioStream(stream); SDL_FreeWAV(wav_buffer); return true; } bool AudioSource::load_mp3_file(std::vector<std::uint8_t> const& file_data) { // Size threshold: files under 1MB are fully decoded, larger files are streamed constexpr std::uint32_t DECODE_THRESHOLD_BYTES = 1024 * 1024; bool should_stream = file_data.size() > DECODE_THRESHOLD_BYTES; MP3Decoder* mp3_decoder = new MP3Decoder(m_resource_handle->data(), 44100, 2); if (!mp3_decoder->is_valid()) { delete mp3_decoder; std::cerr << "Audio: Failed to create MP3 decoder" << std::endl; LOG(logging_severity_level::LSL_ERROR, "Audio: Failed to create MP3 decoder for file: " << m_resource_handle->name()); return false; } if (should_stream) { m_decoder = mp3_decoder; m_sample_rate = 44100; m_channels = 2; m_total_samples = 0; m_is_streaming = true; std::cout << "Audio: Loaded MP3 file for streaming (" << file_data.size() / 1024 << " KB)" << std::endl; return true; } else { // Decode entire file to memory using the decoder // Estimate size: assume ~10:1 compression ratio for MP3 std::size_t estimated_samples = file_data.size() * 10 / sizeof(float); m_audio_data.reserve(estimated_samples); constexpr std::uint32_t CHUNK_FRAMES = 4096; std::vector<float> decode_buffer(CHUNK_FRAMES * 2); std::uint32_t frames_decoded; do { frames_decoded = mp3_decoder->decode(decode_buffer.data(), CHUNK_FRAMES); if (frames_decoded > 0) { std::uint32_t samples_decoded = frames_decoded * 2; m_audio_data.insert(m_audio_data.end(), decode_buffer.begin(), decode_buffer.begin() + samples_decoded); } } while (frames_decoded == CHUNK_FRAMES); delete mp3_decoder; m_resource_handle->set_discardable(true); m_sample_rate = 44100; m_channels = 2; m_total_samples = static_cast<std::uint32_t>(m_audio_data.size()); m_is_streaming = false; std::cout << "Audio: Loaded MP3 file fully decoded (" << file_data.size() / 1024 << " KB -> " << m_audio_data.size() * sizeof(float) / 1024 << " KB PCM)" << std::endl; return true; } } } Loading
audio/include/audio/audio_source.hpp +0 −2 Original line number Diff line number Diff line Loading @@ -7,7 +7,6 @@ #include <vector> #include <cstdint> #include <string> #include <SDL2/SDL_audio.h> namespace lfs { struct ResourceHandle; } Loading Loading @@ -53,7 +52,6 @@ private: lfs::ResourceHandle* m_resource_handle; std::vector<float> m_audio_data; AudioDecoder* m_decoder; SDL_AudioSpec m_source_spec; std::uint32_t m_sample_rate; std::uint32_t m_channels; std::uint32_t m_playback_position; Loading
audio/include/audio/audio_system.hpp +3 −5 Original line number Diff line number Diff line Loading @@ -2,8 +2,8 @@ # define AUDIO_AUDIO_SYSTEM_HPP_INCLUDED #include <com/library.hpp> #include <osi/audio.hpp> #include <cstdint> #include <SDL2/SDL_audio.h> namespace audio { Loading Loading @@ -38,7 +38,6 @@ struct AudioSystem final : public com::Library std::uint32_t get_sample_rate() const { return m_sample_rate; } std::uint32_t get_channels() const { return m_channels; } SDL_AudioSpec const& get_audio_spec() const { return m_audio_spec; } protected: void initialize() override; Loading @@ -50,15 +49,14 @@ private: AudioMixer* m_master_mixer; AudioProcessor* m_audio_processor; SDL_AudioDeviceID m_audio_device; SDL_AudioSpec m_audio_spec; osi::AudioDevice m_audio_device; std::uint32_t m_sample_rate; std::uint32_t m_channels; float m_master_volume; bool m_is_playing; // SDL callback wrapper // Callback wrapper to satisfy void* userdata format for audio friend void audio_callback(void* userdata, std::uint8_t* stream, int len); // concrete audio callback implementation void audio_callback_impl(std::uint8_t* stream, int len); Loading
audio/include/audio/mp3_decoder.hpp +5 −5 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ # define AUDIO_MP3_DECODER_HPP_INCLUDED #include "audio_decoder.hpp" #include <SDL2/SDL_audio.h> #include <osi/audio.hpp> #include <vector> #include <cstdint> Loading @@ -18,7 +18,7 @@ namespace audio public: MP3Decoder(std::vector<std::uint8_t> const& mp3_data, std::uint32_t target_sample_rate, std::uint32_t target_channels); std::uint8_t target_channels); ~MP3Decoder() override; Loading @@ -30,10 +30,10 @@ namespace audio std::vector<std::uint8_t> const& m_mp3_data; mp3dec_ex_t* m_dec; std::uint32_t m_target_sample_rate; std::uint32_t m_target_channels; std::uint8_t m_target_channels; std::uint32_t m_source_sample_rate; std::uint32_t m_source_channels; SDL_AudioStream* m_audio_stream; std::uint8_t m_source_channels; osi::AudioConverter m_converter; std::vector<float> m_decode_buffer; bool m_valid; }; Loading
audio/src/audio_processor.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ namespace audio { if (!m_ring_buffer.push(sample)) { std::cerr << "Audio: audio buffer overrun, dropping samples" << std::endl; LOG(logging_severity_level::LSL_WARNING, "Audio: audio buffer overrun, dropping samples"); return; // Stop if we can't push anymore } } Loading
audio/src/audio_source.cpp +15 −108 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ #include <audio/audio_system.hpp> #include <audio/mp3_decoder.hpp> #include <lfs/index.hpp> #include <SDL2/SDL_audio.h> #include <osi/audio.hpp> #include <algorithm> #include <cstring> #include <iostream> Loading @@ -22,7 +22,6 @@ AudioSource::AudioSource(std::string const& name) , m_is_streaming(false) , m_volume(1.0f) { SDL_zero(m_source_spec); } AudioSource::~AudioSource() Loading Loading @@ -229,134 +228,42 @@ void AudioSource::decode_audio_data() } else { std::cerr << "Audio: Unknown audio file format" << std::endl; LOG(logging_severity_level::LSL_ERROR, "Audio: Unknown audio file format for file: " << m_resource_handle->name()); } } bool AudioSource::load_wav_file(std::vector<std::uint8_t> const& file_data) { SDL_RWops* rw = SDL_RWFromConstMem(file_data.data(), static_cast<int>(file_data.size())); if (rw == nullptr) return false; std::uint8_t* wav_buffer = nullptr; std::uint32_t wav_length = 0; if (SDL_LoadWAV_RW(rw, 1, &m_source_spec, &wav_buffer, &wav_length) == nullptr) { return false; } // TODO: unify this with audio system SDL_AudioSpec target_spec; SDL_zero(target_spec); target_spec.freq = 44100; target_spec.format = AUDIO_F32SYS; target_spec.channels = 2; SDL_AudioStream* stream = SDL_NewAudioStream( m_source_spec.format, m_source_spec.channels, m_source_spec.freq, target_spec.format, target_spec.channels, target_spec.freq ); if (stream == nullptr) { SDL_FreeWAV(wav_buffer); return false; } // Convert audio data if (SDL_AudioStreamPut(stream, wav_buffer, wav_length) < 0) { SDL_FreeAudioStream(stream); SDL_FreeWAV(wav_buffer); return false; } SDL_AudioStreamFlush(stream); int available = SDL_AudioStreamAvailable(stream); if (available <= 0) { SDL_FreeAudioStream(stream); SDL_FreeWAV(wav_buffer); return false; } m_audio_data.resize(available / sizeof(float)); SDL_AudioStreamGet(stream, m_audio_data.data(), available); // Use OSI audio loader to load and convert WAV file osi::WavData wav_data = osi::AudioLoader::load_wav( file_data, 44100, 2, osi::AudioFormat::Float32); m_sample_rate = target_spec.freq; m_channels = target_spec.channels; m_audio_data = std::move(wav_data.samples); m_sample_rate = wav_data.sample_rate; m_channels = wav_data.channels; m_total_samples = static_cast<std::uint32_t>(m_audio_data.size()); SDL_FreeAudioStream(stream); SDL_FreeWAV(wav_buffer); return true; } bool AudioSource::load_mp3_file(std::vector<std::uint8_t> const& file_data) { // Size threshold: files under 1MB are fully decoded, larger files are streamed constexpr std::uint32_t DECODE_THRESHOLD_BYTES = 1024 * 1024; bool should_stream = file_data.size() > DECODE_THRESHOLD_BYTES; MP3Decoder* mp3_decoder = new MP3Decoder(m_resource_handle->data(), 44100, 2); if (!mp3_decoder->is_valid()) { delete mp3_decoder; std::cerr << "Audio: Failed to create MP3 decoder" << std::endl; LOG(logging_severity_level::LSL_ERROR, "Audio: Failed to create MP3 decoder for file: " << m_resource_handle->name()); return false; } if (should_stream) { m_decoder = mp3_decoder; m_sample_rate = 44100; m_channels = 2; m_total_samples = 0; m_is_streaming = true; std::cout << "Audio: Loaded MP3 file for streaming (" << file_data.size() / 1024 << " KB)" << std::endl; return true; } else { // Decode entire file to memory using the decoder // Estimate size: assume ~10:1 compression ratio for MP3 std::size_t estimated_samples = file_data.size() * 10 / sizeof(float); m_audio_data.reserve(estimated_samples); constexpr std::uint32_t CHUNK_FRAMES = 4096; std::vector<float> decode_buffer(CHUNK_FRAMES * 2); std::uint32_t frames_decoded; do { frames_decoded = mp3_decoder->decode(decode_buffer.data(), CHUNK_FRAMES); if (frames_decoded > 0) { std::uint32_t samples_decoded = frames_decoded * 2; m_audio_data.insert(m_audio_data.end(), decode_buffer.begin(), decode_buffer.begin() + samples_decoded); } } while (frames_decoded == CHUNK_FRAMES); delete mp3_decoder; m_resource_handle->set_discardable(true); m_sample_rate = 44100; m_channels = 2; m_total_samples = static_cast<std::uint32_t>(m_audio_data.size()); m_is_streaming = false; std::cout << "Audio: Loaded MP3 file fully decoded (" << file_data.size() / 1024 << " KB -> " << m_audio_data.size() * sizeof(float) / 1024 << " KB PCM)" << std::endl; return true; } } }