FastLED 3.9.15
Loading...
Searching...
No Matches
vorbis.h
Go to the documentation of this file.
1#pragma once
2
3#include "fl/codec/common.h" // IWYU pragma: keep
4#include "fl/audio/audio.h" // IWYU pragma: keep
5#include "fl/stl/span.h"
6#include "fl/stl/vector.h"
7#include "fl/stl/stdint.h"
8#include "fl/stl/shared_ptr.h"
9#include "fl/stl/unique_ptr.h"
10#include "fl/stl/string.h" // IWYU pragma: keep
11#include "fl/stl/noexcept.h"
12
13namespace fl {
14
15// Vorbis metadata information structure
16struct VorbisInfo {
17 fl::u32 sampleRate = 0; // Sample rate in Hz
18 fl::u8 channels = 0; // Number of channels (1=mono, 2=stereo)
19 fl::u32 totalSamples = 0; // Total samples (0 if unknown/streaming)
20 fl::u32 maxFrameSize = 0; // Maximum frame size in samples
21 bool isValid = false; // True if metadata was successfully parsed
22
24 VorbisInfo(fl::u32 rate, fl::u8 ch)
25 : sampleRate(rate), channels(ch), isValid(true) {}
26};
27
28// Forward declaration of internal implementation
29class VorbisDecoderImpl;
30
31// VorbisFrame represents a decoded Vorbis audio frame
33 const float* pcm; // Interleaved PCM data (float, -1.0 to 1.0)
34 fl::i32 samples; // Samples per channel
35 fl::i32 channels; // 1 (mono) or 2 (stereo)
36 fl::i32 sampleRate; // Sample rate in Hz
37};
38
39// Low-level stb_vorbis wrapper for testing
41public:
44
45 // Open from memory buffer (entire file must be in memory)
47
48 // Close and release resources
49 void close();
50
51 // Check if decoder is open
52 bool isOpen() const;
53
54 // Get stream info
55 VorbisInfo getInfo() const;
56
57 // Decode samples into buffer
58 // Returns number of samples decoded per channel (0 = end of stream)
59 fl::i32 getSamplesShortInterleaved(fl::i32 channels, fl::i16* buffer, fl::i32 numShorts);
60
61 // Decode float samples
62 fl::i32 getSamplesFloat(fl::i32 channels, float** buffer, fl::i32 numSamples);
63
64 // Seek to sample position
65 bool seek(fl::u32 sampleNumber);
66
67 // Get current sample offset
68 fl::u32 getSampleOffset() const;
69
70 // Get total samples in stream
71 fl::u32 getTotalSamples() const;
72
73private:
74 void* mVorbis; // stb_vorbis* handle
75};
76
77// Vorbis decoder with streaming byte interface
78// This decoder consumes Vorbis data from a filebuf and decodes audio frames on demand
80public:
83
84 // Initialize the decoder with a byte stream
85 // Note: stb_vorbis requires the entire stream in memory for pulldata API
86 // Returns true on success, false on failure
87 bool begin(fl::filebuf_ptr stream);
88
89 // Clean up decoder resources
90 void end();
91
92 // Check if decoder is ready to use
93 bool isReady() const;
94
95 // Check for errors
96 bool hasError(fl::string* msg = nullptr) const;
97
98 // Decode the next audio frame from the stream
99 // Returns true if a frame was decoded, false if end of stream or error
100 bool decodeNextFrame(audio::Sample* outSample);
101
102 // Get current stream position in bytes
103 fl::size getPosition() const;
104
105 // Reset decoder state (but keep stream)
106 void reset();
107
108 // Get Vorbis stream information
109 VorbisInfo getInfo() const;
110
111private:
113};
114
116
117// Vorbis factory for creating decoders and parsing metadata
118//
119// PERFORMANCE NOTE:
120// Benchmark testing (see REPORT.md) compared MP3 vs OGG Vorbis decoding performance
121// using FFmpeg on a host machine (not embedded platform). Results showed:
122// - OGG decode time: 327ms (10 second audio sample)
123// - MP3 decode time: 420ms (OGG 28.6% faster than MP3)
124// - OGG file size: 108KB at 128kbps
125// - MP3 file size: 157KB at 128kbps (OGG 31% smaller than MP3)
126// - Audio quality difference: 0.67% RMS error (negligible)
127//
128// IMPORTANT: These benchmarks used native FFmpeg decoders on a desktop host.
129// Performance on embedded platforms (ESP32, ARM, etc.) using the stb_vorbis
130// decoder may differ significantly due to:
131// - Different decoder implementations (stb_vorbis vs FFmpeg)
132// - CPU architecture differences (ARM Cortex-M vs x86/x64)
133// - Clock speeds and available RAM
134// - Compiler optimizations and platform-specific code paths
135//
136// RECOMMENDATION: Always profile on your target platform before choosing a codec.
137// What works best on desktop FFmpeg may not match embedded performance characteristics.
138// Run your own benchmarks using your specific hardware, sample data, and use case.
139//
140class Vorbis {
141public:
142 // Create a Vorbis decoder for streaming playback
143 static VorbisDecoderPtr createDecoder(fl::string* errorMessage = nullptr);
144
145 // Check if Vorbis decoding is supported on this platform
146 static bool isSupported();
147
148 // Parse Vorbis metadata from byte data without full decoding
150 fl::string* errorMessage = nullptr);
151
152 // Decode entire file to audio::Sample vector (convenience function)
154 fl::string* errorMessage = nullptr);
155};
156
157} // namespace fl
fl::i32 getSamplesFloat(fl::i32 channels, float **buffer, fl::i32 numSamples)
fl::u32 getTotalSamples() const
bool isOpen() 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
bool isReady() const
VorbisDecoder() FL_NOEXCEPT
bool begin(fl::filebuf_ptr stream)
VorbisInfo getInfo() const
fl::unique_ptr< VorbisDecoderImpl > mImpl
Definition vorbis.h:112
fl::size getPosition() const
bool decodeNextFrame(audio::Sample *outSample)
unsigned char u8
Definition s16x16x4.h:132
unsigned char u8
Definition stdint.h:131
fl::shared_ptr< filebuf > filebuf_ptr
Definition idecoder.h:15
FASTLED_SHARED_PTR(Channel)
Base definition for an LED controller.
Definition crgb.hpp:179
fl::i32 channels
Definition vorbis.h:35
fl::i32 samples
Definition vorbis.h:34
fl::i32 sampleRate
Definition vorbis.h:36
const float * pcm
Definition vorbis.h:33
#define FL_NOEXCEPT
bool isValid
Definition vorbis.h:21
fl::u32 maxFrameSize
Definition vorbis.h:20
VorbisInfo() FL_NOEXCEPT=default
fl::u8 channels
Definition vorbis.h:18
fl::u32 totalSamples
Definition vorbis.h:19
fl::u32 sampleRate
Definition vorbis.h:17