41 mVorbis = vb::stb_vorbis_open_memory(data.
data(),
static_cast<fl::i32
>(data.
size()), &error,
nullptr);
47 vb::stb_vorbis_close(
static_cast<vb::stb_vorbis*
>(
mVorbis));
59 vb::stb_vorbis_info vi = vb::stb_vorbis_get_info(
static_cast<vb::stb_vorbis*
>(
mVorbis));
62 info.
maxFrameSize =
static_cast<fl::u32
>(vi.max_frame_size);
63 info.
totalSamples = vb::stb_vorbis_stream_length_in_samples(
static_cast<vb::stb_vorbis*
>(
mVorbis));
72 return static_cast<fl::i32
>(vb::stb_vorbis_get_samples_short_interleaved(
73 static_cast<vb::stb_vorbis*
>(
mVorbis),
76 static_cast<fl::i32
>(numShorts)
82 return static_cast<fl::i32
>(vb::stb_vorbis_get_samples_float(
83 static_cast<vb::stb_vorbis*
>(
mVorbis),
86 static_cast<fl::i32
>(numSamples)
92 return vb::stb_vorbis_seek(
static_cast<vb::stb_vorbis*
>(
mVorbis), sampleNumber) != 0;
97 return static_cast<fl::u32
>(vb::stb_vorbis_get_sample_offset(
static_cast<vb::stb_vorbis*
>(
mVorbis)));
102 return vb::stb_vorbis_stream_length_in_samples(
static_cast<vb::stb_vorbis*
>(
mVorbis));
152 fl::size bytesRead = stream->
read(buffer,
sizeof(buffer));
153 if (bytesRead == 0)
break;
154 for (fl::size i = 0; i < bytesRead; ++i) {
166 mError =
"Failed to decode Vorbis stream";
200 fl::i32 samplesDecoded =
mDecoder.getSamplesShortInterleaved(
206 if (samplesDecoded == 0) {
213 fl::u32 totalSamples =
mDecoder.getTotalSamples();
214 if (totalSamples > 0) {
215 fl::u32 currentSample =
mDecoder.getSampleOffset();
223 for (fl::i32 i = 0; i < samplesDecoded; ++i) {
226 mono.
push_back(
static_cast<fl::i16
>((left + right) / 2));
270 if (errorMessage) *errorMessage =
"Failed to parse Vorbis header";
281 if (errorMessage) *errorMessage =
"Failed to open Vorbis stream";
287 constexpr fl::i32 FRAME_SIZE = 1024;
295 if (samplesDecoded == 0)
break;
301 for (fl::i32 i = 0; i < samplesDecoded; ++i) {
302 fl::i32 left = buffer[i * 2];
303 fl::i32 right = buffer[i * 2 + 1];
304 mono.
push_back(
static_cast<fl::i16
>((left + right) / 2));
fl::i32 getSamplesFloat(fl::i32 channels, float **buffer, fl::i32 numSamples)
fl::u32 getTotalSamples() const
StbVorbisDecoder() FL_NOEXCEPT
~StbVorbisDecoder() FL_NOEXCEPT
bool openMemory(fl::span< const fl::u8 > data)
fl::u32 getSampleOffset() const
VorbisInfo getInfo() const
bool seek(fl::u32 sampleNumber)
fl::i32 getSamplesShortInterleaved(fl::i32 channels, fl::i16 *buffer, fl::i32 numShorts)
static VorbisInfo parseVorbisInfo(fl::span< const fl::u8 > data, fl::string *errorMessage=nullptr)
static bool isSupported()
static fl::vector< audio::Sample > decodeAll(fl::span< const fl::u8 > data, fl::string *errorMessage=nullptr)
static VorbisDecoderPtr createDecoder(fl::string *errorMessage=nullptr)
~VorbisDecoder() FL_NOEXCEPT
bool hasError(fl::string *msg=nullptr) const
VorbisDecoder() FL_NOEXCEPT
bool begin(fl::filebuf_ptr stream)
VorbisInfo getInfo() const
fl::unique_ptr< VorbisDecoderImpl > mImpl
fl::size getPosition() const
bool decodeNextFrame(audio::Sample *outSample)
bool hasError(fl::string *msg=nullptr) const
VorbisInfo getInfo() const
fl::vector< fl::u8 > mFileData
fl::vector< fl::i16 > mPcmBuffer
bool begin(fl::filebuf_ptr stream)
StbVorbisDecoder mDecoder
fl::size getPosition() const
VorbisDecoderImpl() FL_NOEXCEPT
static constexpr fl::size FRAME_SIZE
~VorbisDecoderImpl() FL_NOEXCEPT
bool decodeNextFrame(audio::Sample *outSample)
virtual bool available() const
virtual fl::size_t read(char *buffer, fl::size_t count)=0
const T * data() const FL_NOEXCEPT
constexpr fl::size size() const FL_NOEXCEPT
fl::size size() const FL_NOEXCEPT
void reserve(fl::size n) FL_NOEXCEPT
void push_back(const T &value) FL_NOEXCEPT
fl::enable_if<!fl::is_array< T >::value, unique_ptr< T > >::type make_unique(Args &&... args) FL_NOEXCEPT
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
fl::shared_ptr< filebuf > filebuf_ptr
Base definition for an LED controller.