Skip to content

Commit 0f93ca3

Browse files
committed
Ogg vorbis support
1 parent 745f7a5 commit 0f93ca3

26 files changed

+881
-92
lines changed

examples/graphics/source/examples/AudioFileDemo.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,9 @@ class AudioFileDemo : public yup::Component
335335
, saveButton ("Save As")
336336
, loopButton ("Loop")
337337
{
338-
formatManager.registerDefaultFormats();
338+
formatManager.registerDefaultFormats (
339+
yup::AudioFormatType::all & ~yup::AudioFormatType::coreAudio);
340+
339341
deviceManager.initialiseWithDefaultDevices (0, 2);
340342
deviceManager.addAudioCallback (&sourcePlayer);
341343
sourcePlayer.setSource (&transportSource);
@@ -608,7 +610,7 @@ class AudioFileDemo : public yup::Component
608610

609611
yup::String getAudioFileFilter() const
610612
{
611-
return "*.wav;*.aiff;*.aif;*.flac;*.mp3;*.opus;*.m4a;*.wma";
613+
return "*.wav;*.aiff;*.aif;*.flac;*.mp3;*.opus;*.m4a;*.wma;*.ogg";
612614
}
613615

614616
yup::AudioFormatManager formatManager;

modules/yup_audio_formats/common/yup_AudioFormatManager.cpp

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,15 @@ void AudioFormatManager::registerDefaultFormats (AudioFormatType types)
5353
registerFormat (std::make_unique<Mp3AudioFormat>());
5454
#endif
5555

56+
#if YUP_AUDIO_FORMAT_OGG
57+
if (hasBitValueSet (types, AudioFormatType::ogg))
58+
registerFormat (std::make_unique<OggVorbisAudioFormat>());
59+
#endif
60+
5661
#if YUP_AUDIO_FORMAT_OPUS
5762
if (hasBitValueSet (types, AudioFormatType::opus))
5863
registerFormat (std::make_unique<OpusAudioFormat>());
5964
#endif
60-
61-
// TODO: Add other formats like:
62-
// registerFormat (std::make_unique<OggVorbisAudioFormat>());
6365
}
6466

6567
void AudioFormatManager::registerFormat (std::unique_ptr<AudioFormat> format)
@@ -72,20 +74,21 @@ std::unique_ptr<AudioFormatReader> AudioFormatManager::createReaderFor (const Fi
7274
{
7375
// Try to open the file
7476
auto stream = file.createInputStream();
75-
7677
if (stream == nullptr)
7778
return nullptr;
7879

7980
// Try each format
8081
for (auto& format : formats)
8182
{
82-
if (format->canHandleFile (file))
83-
{
84-
stream->setPosition (0);
83+
if (! format->canHandleFile (file, AudioFormat::forReading))
84+
continue;
8585

86-
if (auto reader = format->createReaderFor (stream.release()))
87-
return reader;
88-
}
86+
stream->setPosition (0);
87+
88+
if (auto reader = format->createReaderFor (stream.release()))
89+
return reader;
90+
else
91+
stream = file.createInputStream();
8992
}
9093

9194
return nullptr;
@@ -94,28 +97,33 @@ std::unique_ptr<AudioFormatReader> AudioFormatManager::createReaderFor (const Fi
9497
std::unique_ptr<AudioFormatWriter> AudioFormatManager::createWriterFor (const File& file,
9598
int sampleRate,
9699
int numChannels,
97-
int bitsPerSample)
100+
int bitsPerSample,
101+
const StringPairArray& metadataValues,
102+
int qualityOptionIndex)
98103
{
99104
// Try to create the output file
100105
auto stream = file.createOutputStream();
101-
102106
if (stream == nullptr)
103107
return nullptr;
104108

105109
// Try each format
106110
for (auto& format : formats)
107111
{
108-
if (format->canHandleFile (file))
112+
if (! format->canHandleFile (file, AudioFormat::forWriting))
113+
continue;
114+
115+
if (auto writer = format->createWriterFor (stream.release(),
116+
sampleRate,
117+
numChannels,
118+
bitsPerSample,
119+
metadataValues,
120+
qualityOptionIndex))
121+
{
122+
return writer;
123+
}
124+
else
109125
{
110-
StringPairArray metadataValues;
111-
112-
if (auto writer = format->createWriterFor (stream.release(),
113-
sampleRate,
114-
numChannels,
115-
bitsPerSample,
116-
metadataValues,
117-
0))
118-
return writer;
126+
stream = file.createOutputStream();
119127
}
120128
}
121129

modules/yup_audio_formats/common/yup_AudioFormatManager.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,7 @@ class YUP_API AudioFormatManager
119119
should handle it, then attempts to create a reader for that format. The file
120120
is opened and its header is parsed to extract audio properties.
121121
122-
@param file The audio file to create a reader for. The file must exist and
123-
be readable.
122+
@param file The audio file to create a reader for. The file must exist and be readable.
124123
125124
@returns A unique pointer to an AudioFormatReader if a compatible format
126125
was found and the file could be parsed successfully, nullptr otherwise.
@@ -134,11 +133,12 @@ class YUP_API AudioFormatManager
134133
its extension, then creates a writer configured with the specified audio parameters.
135134
The format's capabilities are validated against the requested parameters.
136135
137-
@param file The destination file where audio data will be written. Parent
138-
directories must exist and be writable.
136+
@param file The destination file where audio data will be written. Parent directories must exist and be writable.
139137
@param sampleRate The sample rate for the output audio in Hz (e.g., 44100, 48000).
140138
@param numChannels The number of audio channels (1 for mono, 2 for stereo, etc.).
141139
@param bitsPerSample The bit depth for sample encoding (e.g., 16, 24, 32).
140+
@param metadataValues The metadata values to write (if supported).
141+
@param qualityOptionIndex The quality option index (if supported).
142142
143143
@returns A unique pointer to an AudioFormatWriter if a compatible format was found
144144
and supports the specified parameters, nullptr if no suitable format is
@@ -147,7 +147,9 @@ class YUP_API AudioFormatManager
147147
std::unique_ptr<AudioFormatWriter> createWriterFor (const File& file,
148148
int sampleRate,
149149
int numChannels,
150-
int bitsPerSample);
150+
int bitsPerSample,
151+
const StringPairArray& metadataValues = {},
152+
int qualityOptionIndex = 0);
151153

152154
private:
153155
std::vector<std::unique_ptr<AudioFormat>> formats;

modules/yup_audio_formats/format/yup_AudioFormat.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
namespace yup
2323
{
2424

25-
bool AudioFormat::canHandleFile (const File& file) const
25+
bool AudioFormat::canHandleFile (const File& file, Mode handleMode) const
2626
{
27-
auto extensions = getFileExtensions();
27+
auto extensions = getFileExtensions (handleMode);
2828
auto fileExt = file.getFileExtension().toLowerCase();
2929

3030
for (auto& ext : extensions)
@@ -36,4 +36,4 @@ bool AudioFormat::canHandleFile (const File& file) const
3636
return false;
3737
}
3838

39-
} // namespace yup
39+
} // namespace yup

modules/yup_audio_formats/format/yup_AudioFormat.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ class AudioFormatWriter;
5353
class YUP_API AudioFormat
5454
{
5555
public:
56+
/** Mode of operation. */
57+
enum Mode
58+
{
59+
forReading,
60+
forWriting
61+
};
62+
5663
/** Destructor. */
5764
virtual ~AudioFormat() = default;
5865

@@ -64,21 +71,21 @@ class YUP_API AudioFormat
6471

6572
/** Returns the file extensions associated with this format.
6673
67-
@returns An array of file extensions (including the dot) that this format can handle
68-
(e.g., {".wav", ".wave"} for WAV format)
74+
@returns An array of file extensions (including the dot) that this format can handle (e.g., {".wav", ".wave"} for WAV format)
6975
*/
70-
virtual Array<String> getFileExtensions() const = 0;
76+
virtual Array<String> getFileExtensions (Mode handleMode) const = 0;
7177

7278
/** Tests whether this format can handle files with the given file extension.
7379
7480
This method provides a convenient way to check if a file can be processed by this format
7581
based on its extension, without needing to attempt to open the file.
7682
7783
@param file The file to test for compatibility
84+
@param handleMode The mode to check for compatibility
7885
7986
@returns true if this format can potentially handle the file, false otherwise
8087
*/
81-
virtual bool canHandleFile (const File& file) const;
88+
virtual bool canHandleFile (const File& file, Mode handleMode) const;
8289

8390
/** Creates a reader object capable of parsing audio data from the given stream.
8491
@@ -168,4 +175,4 @@ class YUP_API AudioFormat
168175
virtual StringArray getQualityOptions() const { return {}; }
169176
};
170177

171-
} // namespace yup
178+
} // namespace yup

modules/yup_audio_formats/formats/yup_AppleCoreAudioFormat.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,20 +1053,27 @@ const String& AppleCoreAudioFormat::getFormatName() const
10531053
return formatName;
10541054
}
10551055

1056-
Array<String> AppleCoreAudioFormat::getFileExtensions() const
1056+
Array<String> AppleCoreAudioFormat::getFileExtensions (Mode handleMode) const
10571057
{
1058-
if (streamKind != StreamKind::kNone)
1058+
if (handleMode == Mode::forReading)
10591059
{
1060-
const auto extensions = findFileExtensionsForCoreAudioCodec (toAudioFileTypeID (streamKind));
1060+
if (streamKind != StreamKind::kNone)
1061+
{
1062+
const auto extensions = findFileExtensionsForCoreAudioCodec (toAudioFileTypeID (streamKind));
1063+
if (! extensions.isEmpty())
1064+
return extensions;
1065+
}
1066+
1067+
const auto extensions = findFileExtensionsForCoreAudioCodecs();
10611068
if (! extensions.isEmpty())
10621069
return extensions;
1063-
}
10641070

1065-
const auto extensions = findFileExtensionsForCoreAudioCodecs();
1066-
if (! extensions.isEmpty())
1067-
return extensions;
1068-
1069-
return { ".wav", ".aiff", ".aif", ".aifc", ".wav", ".sd2", ".au", ".snd", ".mp4", ".mp3", ".mp2", ".mp1", ".ac3", ".aac", ".m4a", ".m4b", ".caf", ".3gp", ".3g2", ".amr" };
1071+
return { ".wav", ".aiff", ".aif", ".aifc", ".wav", ".sd2", ".au", ".snd", ".mp4", ".mp3", ".mp2", ".mp1", ".ac3", ".aac", ".m4a", ".m4b", ".caf", ".3gp", ".3g2", ".amr" };
1072+
}
1073+
else
1074+
{
1075+
return { ".aiff", ".aif", ".aifc", ".sd2", ".au", ".snd", ".mp4", ".mp2", ".mp1", ".ac3", ".aac", ".m4a", ".m4b", ".caf", ".3gp", ".3g2", ".amr" };
1076+
}
10701077
}
10711078

10721079
std::unique_ptr<AudioFormatReader> AppleCoreAudioFormat::createReaderFor (InputStream* sourceStream)

modules/yup_audio_formats/formats/yup_AppleCoreAudioFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class YUP_API AppleCoreAudioFormat : public AudioFormat
8181
const String& getFormatName() const override;
8282

8383
/** Returns the file extensions that this format can handle. */
84-
Array<String> getFileExtensions() const override;
84+
Array<String> getFileExtensions (Mode handleMode) const override;
8585

8686
/** Creates a reader for decoding CoreAudio-supported audio data. */
8787
std::unique_ptr<AudioFormatReader> createReaderFor (InputStream* sourceStream) override;

modules/yup_audio_formats/formats/yup_FlacAudioFormat.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ const String& FlacAudioFormat::getFormatName() const
529529
return formatName;
530530
}
531531

532-
Array<String> FlacAudioFormat::getFileExtensions() const
532+
Array<String> FlacAudioFormat::getFileExtensions ([[maybe_unused]] Mode handleMode) const
533533
{
534534
return { ".flac" };
535535
}

modules/yup_audio_formats/formats/yup_FlacAudioFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class YUP_API FlacAudioFormat : public AudioFormat
4747
const String& getFormatName() const override;
4848

4949
/** Returns the file extensions that this format can handle. */
50-
Array<String> getFileExtensions() const override;
50+
Array<String> getFileExtensions (Mode handleMode) const override;
5151

5252
/** Creates a reader for decoding FLAC audio data from the provided stream. */
5353
std::unique_ptr<AudioFormatReader> createReaderFor (InputStream* sourceStream) override;

modules/yup_audio_formats/formats/yup_Mp3AudioFormat.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ const String& Mp3AudioFormat::getFormatName() const
448448
return formatName;
449449
}
450450

451-
Array<String> Mp3AudioFormat::getFileExtensions() const
451+
Array<String> Mp3AudioFormat::getFileExtensions ([[maybe_unused]] Mode handleMode) const
452452
{
453453
return { ".mp3" };
454454
}

0 commit comments

Comments
 (0)