blob: 8cc5b78eedbae104c8d957704457696aaa8a037c [file] [log] [blame]
#ifdef WITH_RIVE_AUDIO
#include "rive/audio/audio_source.hpp"
#include "rive/audio/audio_engine.hpp"
#include "rive/audio/audio_sound.hpp"
#include "rive/audio/audio_reader.hpp"
#include "rive/audio/audio_reader.hpp"
using namespace rive;
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;
}
#endif