| #include "rive/audio/audio_source.hpp" |
| #ifdef WITH_RIVE_AUDIO |
| #include "rive/audio/audio_engine.hpp" |
| #include "rive/audio/audio_sound.hpp" |
| #include "rive/audio/audio_reader.hpp" |
| #include "rive/audio/audio_reader.hpp" |
| #endif |
| |
| using namespace rive; |
| |
| #ifdef WITH_RIVE_AUDIO |
| AudioSource::AudioSource(rive::Span<float> samples, uint32_t numChannels, uint32_t sampleRate) : |
| m_isBuffered(true), |
| m_channels(numChannels), |
| m_sampleRate(sampleRate), |
| m_ownedBytes((uint8_t*)samples.data(), samples.size() * sizeof(float)) |
| { |
| assert(numChannels != 0); |
| assert(sampleRate != 0); |
| } |
| |
| AudioSource::AudioSource(rive::Span<uint8_t> fileBytes) : |
| m_isBuffered(false), m_channels(0), m_sampleRate(0), m_fileBytes(fileBytes) |
| {} |
| |
| AudioSource::AudioSource(rive::SimpleArray<uint8_t> fileBytes) : |
| m_isBuffered(false), |
| m_channels(0), |
| m_sampleRate(0), |
| m_fileBytes(fileBytes.data(), fileBytes.size()), |
| m_ownedBytes(std::move(fileBytes)) |
| {} |
| |
| const rive::Span<float> AudioSource::bufferedSamples() const |
| { |
| assert(m_isBuffered); |
| return rive::Span<float>((float*)m_ownedBytes.data(), m_ownedBytes.size() / sizeof(float)); |
| } |
| |
| class AudioSourceDecoder |
| { |
| public: |
| AudioSourceDecoder(rive::Span<uint8_t> fileBytes) : m_decoder({}) |
| { |
| ma_decoder_config config = ma_decoder_config_init(ma_format_f32, 0, 0); |
| if (ma_decoder_init_memory(fileBytes.data(), fileBytes.size(), &config, &m_decoder) != |
| MA_SUCCESS) |
| { |
| fprintf(stderr, "AudioSourceDecoder - Failed to initialize decoder.\n"); |
| } |
| } |
| |
| ~AudioSourceDecoder() { ma_decoder_uninit(&m_decoder); } |
| |
| uint32_t channels() { return (uint32_t)m_decoder.outputChannels; } |
| |
| uint32_t sampleRate() { return (uint32_t)m_decoder.outputSampleRate; } |
| |
| private: |
| ma_decoder m_decoder; |
| }; |
| |
| uint32_t AudioSource::channels() |
| { |
| if (m_channels != 0) |
| { |
| return m_channels; |
| } |
| AudioSourceDecoder audioDecoder(m_fileBytes); |
| return m_channels = audioDecoder.channels(); |
| } |
| |
| uint32_t AudioSource::sampleRate() |
| { |
| if (m_sampleRate != 0) |
| { |
| return m_sampleRate; |
| } |
| AudioSourceDecoder audioDecoder(m_fileBytes); |
| return m_sampleRate = audioDecoder.sampleRate(); |
| } |
| |
| AudioFormat AudioSource::format() const |
| { |
| if (m_isBuffered) |
| { |
| return AudioFormat::buffered; |
| } |
| ma_decoder decoder; |
| ma_decoder_config config = ma_decoder_config_init(ma_format_f32, 0, 0); |
| if (ma_decoder_init_memory(m_fileBytes.data(), m_fileBytes.size(), &config, &decoder) != |
| MA_SUCCESS) |
| { |
| fprintf(stderr, "AudioSource::format - Failed to initialize decoder.\n"); |
| return AudioFormat::unknown; |
| } |
| ma_encoding_format encodingFormat; |
| |
| AudioFormat format = AudioFormat::unknown; |
| if (ma_decoder_get_encoding_format(&decoder, &encodingFormat) == MA_SUCCESS) |
| { |
| switch (encodingFormat) |
| { |
| case ma_encoding_format_mp3: |
| format = AudioFormat::mp3; |
| break; |
| case ma_encoding_format_wav: |
| format = AudioFormat::wav; |
| break; |
| case ma_encoding_format_vorbis: |
| format = AudioFormat::vorbis; |
| break; |
| case ma_encoding_format_flac: |
| format = AudioFormat::flac; |
| break; |
| default: |
| format = AudioFormat::unknown; |
| break; |
| } |
| } |
| |
| ma_decoder_uninit(&decoder); |
| |
| return format; |
| } |
| |
| rcp<AudioReader> AudioSource::makeReader(uint32_t numChannels, uint32_t sampleRate) |
| { |
| if (m_isBuffered) |
| { |
| return nullptr; |
| } |
| |
| rive::rcp<rive::AudioSource> rcSource = rive::rcp<rive::AudioSource>(this); |
| rcSource->ref(); |
| auto reader = rcp<AudioReader>(new AudioReader(rcSource, numChannels)); |
| |
| ma_decoder_config config = ma_decoder_config_init(ma_format_f32, numChannels, sampleRate); |
| |
| if (ma_decoder_init_memory(m_fileBytes.data(), |
| m_fileBytes.size(), |
| &config, |
| reader->decoder()) != MA_SUCCESS) |
| { |
| fprintf(stderr, "AudioSource::makeReader - Failed to initialize decoder.\n"); |
| return nullptr; |
| } |
| |
| return reader; |
| } |
| #else |
| AudioSource::AudioSource(rive::Span<uint8_t> fileBytes) {} |
| AudioSource::AudioSource(rive::SimpleArray<uint8_t> fileBytes) {} |
| AudioSource::AudioSource(rive::Span<float> samples, uint32_t numChannels, uint32_t sampleRate) {} |
| uint32_t AudioSource::channels() { return 0; } |
| uint32_t AudioSource::sampleRate() { return 0; } |
| AudioFormat AudioSource::format() const { return AudioFormat::unknown; } |
| const rive::Span<float> AudioSource::bufferedSamples() const |
| { |
| return rive::Span<float>(nullptr, 0); |
| } |
| #endif |