Commit bf9439fd authored by Matěj Toul's avatar Matěj Toul
Browse files

osi - audio: moved minimp3 to osi

parent dc58ce6b
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -6,36 +6,23 @@
#include <vector>
#include <cstdint>


#include <minimp3/minimp3_ex.h>
#undef min
#undef max

namespace audio
{
    class MP3Decoder : public AudioDecoder
    class MP3AudioDecoder : public AudioDecoder
    {
    public:
        MP3Decoder(std::vector<std::uint8_t> const& mp3_data, 
        MP3AudioDecoder(std::vector<std::uint8_t> const& mp3_data, 
                   std::uint32_t target_sample_rate, 
                   std::uint8_t target_channels);
        
        ~MP3Decoder() override;
        ~MP3AudioDecoder() override;

        std::uint32_t decode(float* output, std::uint32_t frame_count) override;
        void reset() override;
        bool is_valid() const override { return m_valid; }
        bool is_valid() const override { return m_decoder.is_open(); }

    private:
        std::vector<std::uint8_t> const& m_mp3_data;
        mp3dec_ex_t* m_dec;
        std::uint32_t m_target_sample_rate;
        std::uint8_t m_target_channels;
        std::uint32_t m_source_sample_rate;
        std::uint8_t m_source_channels;
        osi::AudioConverter m_converter;
        std::vector<float> m_decode_buffer;
        bool m_valid;
        osi::MP3Decoder m_decoder;
    };
}

+2 −2
Original line number Diff line number Diff line
#include <audio/audio_source.hpp>
#include <audio/audio_system.hpp>
#include <audio/mp3_decoder.hpp>
#include <audio/mp3_audio_decoder.hpp>
#include <lfs/index.hpp>
#include <osi/audio.hpp>
#include <algorithm>
@@ -248,7 +248,7 @@ bool AudioSource::load_wav_file(std::vector<std::uint8_t> const& file_data)

bool AudioSource::load_mp3_file(std::vector<std::uint8_t> const& file_data)
{
    MP3Decoder* mp3_decoder = new MP3Decoder(m_resource_handle->data(), 44100, 2);
    MP3AudioDecoder* mp3_decoder = new MP3AudioDecoder(m_resource_handle->data(), 44100, 2);

    if (!mp3_decoder->is_valid())
    {
+31 −0
Original line number Diff line number Diff line
#include "audio/mp3_audio_decoder.hpp"
#include <utils/log.hpp>

namespace audio
{
    MP3AudioDecoder::MP3AudioDecoder(std::vector<std::uint8_t> const& mp3_data,
                           std::uint32_t target_sample_rate,
                           std::uint8_t target_channels)
        : m_decoder()
    {
        if (!m_decoder.open(mp3_data, target_sample_rate, target_channels))
        {
            LOG(logging_severity_level::LSL_ERROR, "Audio: Failed to initialize MP3 decoder");
        }
    }

    MP3AudioDecoder::~MP3AudioDecoder()
    {
        m_decoder.close();
    }

    std::uint32_t MP3AudioDecoder::decode(float* output, std::uint32_t frame_count)
    {
        return m_decoder.decode(output, frame_count);
    }

    void MP3AudioDecoder::reset()
    {
        m_decoder.reset();
    }
}

audio/src/mp3_decoder.cpp

deleted100644 → 0
+0 −135
Original line number Diff line number Diff line
#define MINIMP3_IMPLEMENTATION
#define MINIMP3_FLOAT_OUTPUT
#define MINIMP3_NO_STDIO

#include "audio/mp3_decoder.hpp"
#include <iostream>
#include <utils/log.hpp>

namespace audio
{
    MP3Decoder::MP3Decoder(std::vector<std::uint8_t> const& mp3_data,
                           std::uint32_t target_sample_rate,
                           std::uint8_t target_channels)
        : m_mp3_data(mp3_data)
        , m_dec(nullptr)
        , m_target_sample_rate(target_sample_rate)
        , m_target_channels(target_channels)
        , m_source_sample_rate(0)
        , m_source_channels(0)
        , m_converter()
        , m_valid(false)
    {
        // Allocate decoder
        m_dec = new mp3dec_ex_t();

        // Initialize mp3 decoder
        if (mp3dec_ex_open_buf(m_dec, m_mp3_data.data(), m_mp3_data.size(), MP3D_SEEK_TO_SAMPLE) != 0)
        {
			LOG(logging_severity_level::LSL_ERROR, "Audio: Failed to initialize MP3 decoder");
            delete m_dec;
            m_dec = nullptr;
            return;
        }

        m_valid = true;
        m_source_sample_rate = m_dec->info.hz;
        m_source_channels = m_dec->info.channels;

        // Create audio stream for format conversion if needed
        if (m_source_sample_rate != m_target_sample_rate || m_source_channels != m_target_channels)
        {
            m_converter.create(
                osi::AudioFormat::Float32, m_source_channels, m_source_sample_rate,
                osi::AudioFormat::Float32, m_target_channels, m_target_sample_rate
            );
        }

        m_decode_buffer.resize(MINIMP3_MAX_SAMPLES_PER_FRAME * 2); // Stereo float samples
    }

    MP3Decoder::~MP3Decoder()
    {
        m_converter.destroy();

        if (m_dec != nullptr)
        {
            if (m_valid)
            {
                mp3dec_ex_close(m_dec);
            }
            delete m_dec;
            m_dec = nullptr;
        }
    }

    std::uint32_t MP3Decoder::decode(float* output, std::uint32_t frame_count)
    {
        if (!m_valid || m_dec == nullptr)
            return 0;

        std::uint32_t frames_decoded = 0;

        if (m_converter.is_valid())
        {
            // Need format conversion
            // Check if we have buffered data in the stream
            std::uint32_t available = m_converter.available();
            std::uint32_t frames_available = available / (sizeof(float) * m_target_channels);

            if (frames_available < frame_count)
            {
                // Decode more MP3 frames and feed to stream
                std::uint32_t frames_needed = frame_count - frames_available;
                std::uint32_t samples_to_decode = frames_needed * m_source_channels * 2; // Decode extra

                if (samples_to_decode > m_decode_buffer.size())
                    samples_to_decode = static_cast<std::uint32_t>(m_decode_buffer.size());

                std::uint32_t samples_decoded = static_cast<std::uint32_t>(
                    mp3dec_ex_read(m_dec, m_decode_buffer.data(), samples_to_decode)
                );

                if (samples_decoded > 0)
                {
                    m_converter.put(m_decode_buffer.data(), samples_decoded * sizeof(float));
                }
            }

            // Read converted samples from stream
            std::uint32_t bytes_to_read = frame_count * m_target_channels * sizeof(float);
            std::uint32_t bytes_read = m_converter.get(output, bytes_to_read);

            if (bytes_read > 0)
            {
                frames_decoded = bytes_read / (sizeof(float) * m_target_channels);
            }
        }
        else
        {
            // Direct decode (no conversion needed)
            std::uint32_t samples_to_decode = frame_count * m_source_channels;
            std::uint32_t samples_decoded = static_cast<std::uint32_t>(
                mp3dec_ex_read(m_dec, output, samples_to_decode)
            );
            frames_decoded = samples_decoded / m_source_channels;
        }

        return frames_decoded;
    }

    void MP3Decoder::reset()
    {
        if (!m_valid || m_dec == nullptr)
            return;

        // Seek back to beginning
        mp3dec_ex_seek(m_dec, 0);

        // Clear audio stream if present
        if (m_converter.is_valid())
        {
            m_converter.clear();
        }
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#   include <com/library.hpp>
#   include <math/math.hpp>
#   include <gfx/font.hpp>
#   include <numbers>

namespace gfx {

Loading