Skip to content

Commit 804b63e

Browse files
committed
More tweaks
1 parent b03178f commit 804b63e

File tree

8 files changed

+413
-126
lines changed

8 files changed

+413
-126
lines changed

modules/yup_audio_formats/common/yup_AudioFormatManager.h

Lines changed: 81 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,42 +23,109 @@ namespace yup
2323
{
2424

2525
//==============================================================================
26-
/** A class that manages audio formats. */
26+
/**
27+
Central registry and factory for audio format handlers.
28+
29+
AudioFormatManager serves as the primary entry point for working with multiple audio
30+
file formats in a unified way. It maintains a collection of registered AudioFormat
31+
implementations and provides convenient methods for creating appropriate readers
32+
and writers based on file extensions or format requirements.
33+
34+
Key responsibilities:
35+
- Registry of available audio format implementations
36+
- Format detection based on file extensions
37+
- Automatic creation of format-specific readers and writers
38+
- Centralized management of format capabilities and limitations
39+
- Support for both built-in and custom audio format plugins
40+
41+
The manager simplifies audio I/O operations by abstracting away the complexities
42+
of format-specific handling. Applications typically register the formats they need
43+
(often using registerDefaultFormats() for common formats) and then use the
44+
convenience methods to create readers and writers without needing to know the
45+
specific format implementation details.
46+
47+
Example usage:
48+
@code
49+
AudioFormatManager manager;
50+
manager.registerDefaultFormats();
51+
52+
auto reader = manager.createReaderFor(audioFile);
53+
if (reader != nullptr)
54+
{
55+
// Read audio data using the format-appropriate reader
56+
}
57+
@endcode
58+
59+
@see AudioFormat, AudioFormatReader, AudioFormatWriter
60+
61+
@tags{Audio}
62+
*/
2763
class YUP_API AudioFormatManager
2864
{
2965
public:
3066
//==============================================================================
31-
/** Constructor. */
67+
/** Constructs an empty AudioFormatManager with no registered formats.
68+
69+
After construction, you'll typically want to call registerDefaultFormats()
70+
or manually register specific formats using registerFormat().
71+
*/
3272
AudioFormatManager();
3373

3474
//==============================================================================
35-
/** Register the default formats. */
75+
/** Registers all built-in audio format implementations.
76+
77+
This convenience method automatically registers the standard audio formats
78+
that are included with the YUP library, such as WAV, potentially FLAC,
79+
and other commonly-used formats. This is the most common way to initialize
80+
the manager for typical use cases.
81+
82+
The specific formats registered may depend on compile-time configuration
83+
and available dependencies.
84+
*/
3685
void registerDefaultFormats();
3786

38-
/** Register a format.
87+
/** Registers a custom audio format implementation.
88+
89+
This method allows you to add support for additional audio formats beyond
90+
the built-in ones. The manager takes ownership of the provided format object
91+
and will use it for format detection and reader/writer creation.
3992
40-
@param format The format to register.
93+
@param format A unique pointer to the AudioFormat implementation to register.
94+
The manager takes ownership of this object.
4195
*/
4296
void registerFormat (std::unique_ptr<AudioFormat> format);
4397

4498
//==============================================================================
45-
/** Create a reader for a file.
99+
/** Creates an appropriate reader for the specified audio file.
46100
47-
@param file The file to create a reader for.
101+
This method examines the file's extension to determine which registered format
102+
should handle it, then attempts to create a reader for that format. The file
103+
is opened and its header is parsed to extract audio properties.
48104
49-
@return A pointer to the reader, or nullptr if the format cannot handle the file.
105+
@param file The audio file to create a reader for. The file must exist and
106+
be readable.
107+
108+
@returns A unique pointer to an AudioFormatReader if a compatible format
109+
was found and the file could be parsed successfully, nullptr otherwise.
50110
*/
51111
std::unique_ptr<AudioFormatReader> createReaderFor (const File& file);
52112

53113
//==============================================================================
54-
/** Create a writer for a file.
114+
/** Creates an appropriate writer for the specified audio file with given parameters.
115+
116+
This method determines which registered format should handle the file based on
117+
its extension, then creates a writer configured with the specified audio parameters.
118+
The format's capabilities are validated against the requested parameters.
55119
56-
@param file The file to create a writer for.
57-
@param sampleRate The sample rate to use.
58-
@param numChannels The number of channels to use.
59-
@param bitsPerSample The number of bits per sample to use.
120+
@param file The destination file where audio data will be written. Parent
121+
directories must exist and be writable.
122+
@param sampleRate The sample rate for the output audio in Hz (e.g., 44100, 48000).
123+
@param numChannels The number of audio channels (1 for mono, 2 for stereo, etc.).
124+
@param bitsPerSample The bit depth for sample encoding (e.g., 16, 24, 32).
60125
61-
@return A pointer to the writer, or nullptr if the format cannot handle the file.
126+
@returns A unique pointer to an AudioFormatWriter if a compatible format was found
127+
and supports the specified parameters, nullptr if no suitable format is
128+
available or the parameters are not supported.
62129
*/
63130
std::unique_ptr<AudioFormatWriter> createWriterFor (const File& file,
64131
int sampleRate,

modules/yup_audio_formats/format/yup_AudioFormat.h

Lines changed: 105 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,53 +27,144 @@ class AudioFormatWriter;
2727

2828
//==============================================================================
2929
/**
30-
Base class for audio format descriptions.
30+
Abstract base class for audio format implementations.
3131
32-
This class represents a type of audio file format, and can create
33-
reader and writer objects for parsing and writing that format.
32+
This class serves as the foundation for all audio file format handlers within
33+
the YUP library. Each concrete implementation represents a specific audio file
34+
format (such as WAV, FLAC, or MP3) and provides the necessary functionality to
35+
create reader and writer objects for parsing and writing files in that particular
36+
format.
37+
38+
The AudioFormat class defines a common interface for:
39+
- Identifying supported file extensions
40+
- Creating format-specific readers and writers
41+
- Querying format capabilities (sample rates, bit depths, channel configurations)
42+
- Handling format-specific metadata and quality settings
43+
44+
Subclasses must implement all pure virtual methods to provide format-specific
45+
behavior. The AudioFormatManager typically manages instances of AudioFormat
46+
subclasses to provide a unified interface for handling multiple audio formats
47+
in an application.
48+
49+
@see AudioFormatReader, AudioFormatWriter, AudioFormatManager
50+
51+
@tags{Audio}
3452
*/
3553
class YUP_API AudioFormat
3654
{
3755
public:
3856
/** Destructor. */
3957
virtual ~AudioFormat() = default;
4058

41-
/** Returns the name of this format. */
59+
/** Returns the descriptive name of this audio format.
60+
61+
@returns A string containing the human-readable name of the format (e.g., "Wave file", "FLAC Audio")
62+
*/
4263
virtual const String& getFormatName() const = 0;
4364

44-
/** Returns the file extensions associated with this format. */
65+
/** Returns the file extensions associated with this format.
66+
67+
@returns An array of file extensions (including the dot) that this format can handle
68+
(e.g., {".wav", ".wave"} for WAV format)
69+
*/
4570
virtual Array<String> getFileExtensions() const = 0;
4671

47-
/** Tests whether this format can handle the given file extension. */
72+
/** Tests whether this format can handle files with the given file extension.
73+
74+
This method provides a convenient way to check if a file can be processed by this format
75+
based on its extension, without needing to attempt to open the file.
76+
77+
@param file The file to test for compatibility
78+
79+
@returns true if this format can potentially handle the file, false otherwise
80+
*/
4881
virtual bool canHandleFile (const File& file) const;
4982

50-
/** Creates a reader for this format. */
83+
/** Creates a reader object capable of parsing audio data from the given stream.
84+
85+
This method attempts to create a format-specific reader for the provided input stream.
86+
The reader will be configured with the appropriate parameters extracted from the stream's
87+
audio data (sample rate, channels, bit depth, etc.).
88+
89+
@param sourceStream The input stream containing audio data to be read. The AudioFormat
90+
takes ownership of this stream if successful.
91+
92+
@returns A unique pointer to an AudioFormatReader if successful, nullptr if the stream
93+
cannot be parsed by this format
94+
*/
5195
virtual std::unique_ptr<AudioFormatReader> createReaderFor (InputStream* sourceStream) = 0;
5296

53-
/** Creates a writer for this format. */
97+
/** Creates a writer object capable of writing audio data to the given stream.
98+
99+
This method creates a format-specific writer configured with the specified audio parameters.
100+
The writer will encode audio data according to the format's specifications and write it
101+
to the provided output stream.
102+
103+
@param streamToWriteTo The output stream where audio data will be written
104+
@param sampleRate The sample rate of the audio data (e.g., 44100, 48000)
105+
@param numberOfChannels The number of audio channels (1 for mono, 2 for stereo, etc.)
106+
@param bitsPerSample The bit depth for each sample (e.g., 16, 24, 32)
107+
@param metadataValues A collection of metadata key-value pairs to embed in the file
108+
@param qualityOptionIndex Index into the quality options array for compressed formats
109+
110+
@returns A unique pointer to an AudioFormatWriter if successful, nullptr if the
111+
parameters are not supported by this format
112+
*/
54113
virtual std::unique_ptr<AudioFormatWriter> createWriterFor (OutputStream* streamToWriteTo,
55114
double sampleRate,
56115
int numberOfChannels,
57116
int bitsPerSample,
58117
const StringPairArray& metadataValues,
59118
int qualityOptionIndex) = 0;
60119

61-
/** Returns a set of bit depths that the format can write. */
120+
/** Returns the set of bit depths that this format supports for writing.
121+
122+
Different audio formats support different bit depths. This method allows clients
123+
to query which bit depths are available before attempting to create a writer.
124+
125+
@returns An array of supported bit depths in bits per sample (e.g., {8, 16, 24, 32})
126+
*/
62127
virtual Array<int> getPossibleBitDepths() const = 0;
63128

64-
/** Returns a set of sample rates that the format can write. */
129+
/** Returns the set of sample rates that this format supports for writing.
130+
131+
Audio formats may have limitations on supported sample rates. This method provides
132+
a way to discover these limitations before attempting to create a writer.
133+
134+
@returns An array of supported sample rates in Hz (e.g., {44100, 48000, 96000})
135+
*/
65136
virtual Array<int> getPossibleSampleRates() const = 0;
66137

67-
/** Returns true if this format can write files with multiple channels. */
138+
/** Returns true if this format supports writing mono (single-channel) audio files.
139+
140+
@returns true if mono files can be written, false otherwise
141+
*/
68142
virtual bool canDoMono() const = 0;
69143

70-
/** Returns true if this format can write stereo files. */
144+
/** Returns true if this format supports writing stereo (two-channel) audio files.
145+
146+
@returns true if stereo files can be written, false otherwise
147+
*/
71148
virtual bool canDoStereo() const = 0;
72149

73-
/** Returns true if the format can encode at different qualities. */
150+
/** Returns true if this format supports compression with variable quality settings.
151+
152+
Formats like MP3, OGG Vorbis, and FLAC support different compression levels or quality
153+
settings. Uncompressed formats like WAV typically return false.
154+
155+
@returns true if the format supports quality options, false for uncompressed formats
156+
*/
74157
virtual bool isCompressed() const { return false; }
75158

76-
/** Returns a list of different qualities that can be used when writing. */
159+
/** Returns a list of quality option descriptions for compressed formats.
160+
161+
For compressed formats that support multiple quality levels, this method returns
162+
human-readable descriptions of the available quality options. The index of the
163+
desired quality can be passed to createWriterFor().
164+
165+
@returns An array of quality descriptions (e.g., {"Low", "Medium", "High"}) or
166+
empty array for formats that don't support quality options
167+
*/
77168
virtual StringArray getQualityOptions() const { return {}; }
78169
};
79170

modules/yup_audio_formats/format/yup_AudioFormatReader.cpp

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,7 @@ AudioFormatReader::AudioFormatReader (InputStream* sourceStream, const String& f
2828
{
2929
}
3030

31-
bool AudioFormatReader::read (float* const* destChannels, int numDestChannels, int64 startSampleInSource, int numSamplesToRead)
32-
{
33-
if (numSamplesToRead <= 0)
34-
return true;
35-
36-
const auto numChannelsToRead = jmin (numDestChannels, (int) numChannels);
37-
38-
if (numChannelsToRead == 0)
39-
return true;
40-
41-
// Since readSamples now uses float, we can read directly into destChannels
42-
if (! readSamples (destChannels, numChannelsToRead, 0, startSampleInSource, numSamplesToRead))
43-
return false;
44-
45-
// Clear any remaining channels
46-
for (int i = numChannelsToRead; i < numDestChannels; ++i)
47-
if (destChannels[i] != nullptr)
48-
FloatVectorOperations::clear (destChannels[i], numSamplesToRead);
49-
50-
return true;
51-
}
52-
53-
bool AudioFormatReader::read (int* const* destChannels, int numDestChannels, int64 startSampleInSource, int numSamplesToRead, bool fillLeftoverChannelsWithCopies)
31+
bool AudioFormatReader::read (float* const* destChannels, int numDestChannels, int64 startSampleInSource, int numSamplesToRead, bool fillLeftoverChannelsWithCopies)
5432
{
5533
if (numSamplesToRead <= 0)
5634
return true;
@@ -70,11 +48,6 @@ bool AudioFormatReader::read (int* const* destChannels, int numDestChannels, int
7048
if (! readSamples (floatChans.getData(), numChannelsToRead, 0, startSampleInSource, numSamplesToRead))
7149
return false;
7250

73-
// Convert float to int
74-
for (int i = 0; i < numChannelsToRead; ++i)
75-
if (destChannels[i] != nullptr)
76-
FloatVectorOperations::convertFloatToFixed (destChannels[i], floatChans[i], 0x7fffffff, numSamplesToRead);
77-
7851
if (numChannelsToRead < numDestChannels)
7952
{
8053
if (fillLeftoverChannelsWithCopies && numChannelsToRead > 0)

0 commit comments

Comments
 (0)