From f57fc490d335f25e917d7d674b870fac1234abf8 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Fri, 9 Oct 2020 17:29:53 +0200 Subject: [PATCH] Add OGG --- .gitmodules | 4 ++ external/st_audiofile/CMakeLists.txt | 3 +- external/st_audiofile/src/st_audiofile.c | 55 +++++++++++++++++++ external/st_audiofile/src/st_audiofile_libs.c | 19 +++++++ external/st_audiofile/src/st_audiofile_libs.h | 11 ++++ external/st_audiofile/thirdparty/stb_vorbis | 1 + 6 files changed, 92 insertions(+), 1 deletion(-) create mode 160000 external/st_audiofile/thirdparty/stb_vorbis diff --git a/.gitmodules b/.gitmodules index f4453c71..c47fa23b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -23,3 +23,7 @@ path = external/st_audiofile/thirdparty/dr_libs url = https://github.com/mackron/dr_libs.git shallow = true +[submodule "external/st_audiofile/thirdparty/stb_vorbis"] + path = external/st_audiofile/thirdparty/stb_vorbis + url = https://github.com/sfztools/stb_vorbis.git + shallow = true diff --git a/external/st_audiofile/CMakeLists.txt b/external/st_audiofile/CMakeLists.txt index d876b8f0..e0fb1e4e 100644 --- a/external/st_audiofile/CMakeLists.txt +++ b/external/st_audiofile/CMakeLists.txt @@ -11,7 +11,8 @@ add_library(st_audiofile STATIC "src/st_audiofile_sndfile.c") target_include_directories(st_audiofile PUBLIC "src" - PUBLIC "thirdparty/dr_libs") + PUBLIC "thirdparty/dr_libs" + PUBLIC "thirdparty/stb_vorbis") add_executable(st_info "src/st_info.c") diff --git a/external/st_audiofile/src/st_audiofile.c b/external/st_audiofile/src/st_audiofile.c index 671e8618..8325617a 100644 --- a/external/st_audiofile/src/st_audiofile.c +++ b/external/st_audiofile/src/st_audiofile.c @@ -15,10 +15,12 @@ struct st_audio_file { drwav *wav; drflac *flac; drmp3 *mp3; + stb_vorbis* ogg; }; union { struct { uint64_t frames; } mp3; + struct { uint32_t channels; float sample_rate; uint64_t frames; } ogg; } cache; }; @@ -52,6 +54,20 @@ st_audio_file* st_open_file(const char* filename) af->type = st_audio_file_flac; } + if (af->type == st_audio_file_null) { + af->ogg = stb_vorbis_open_filename(filename, NULL, NULL); + if (af->ogg) { + if ((af->cache.ogg.frames = stb_vorbis_stream_length_in_samples(af->ogg)) == 0) + stb_vorbis_close(af->ogg); + else { + stb_vorbis_info info = stb_vorbis_get_info(af->ogg); + af->cache.ogg.channels = info.channels; + af->cache.ogg.sample_rate = info.sample_rate; + af->type = st_audio_file_ogg; + } + } + } + if (af->type == st_audio_file_null) { af->mp3 = (drmp3*)malloc(sizeof(drmp3)); if (!af->mp3) { @@ -100,6 +116,20 @@ st_audio_file* st_open_file_w(const wchar_t* filename) af->type = st_audio_file_flac; } + if (af->type == st_audio_file_null) { + af->ogg = stb_vorbis_open_filename_w(filename, NULL, NULL); + if (af->ogg) { + if ((af->cache.ogg.frames = stb_vorbis_stream_length_in_samples(af->ogg)) == 0) + stb_vorbis_close(af->ogg); + else { + stb_vorbis_info info = stb_vorbis_get_info(af->ogg); + af->cache.ogg.channels = info.channels; + af->cache.ogg.sample_rate = info.sample_rate; + af->type = st_audio_file_ogg; + } + } + } + if (af->type == st_audio_file_null) { af->mp3 = (drmp3*)malloc(sizeof(drmp3)); if (!af->mp3) { @@ -132,6 +162,9 @@ void st_close(st_audio_file* af) case st_audio_file_flac: drflac_close(af->flac); break; + case st_audio_file_ogg: + stb_vorbis_close(af->ogg); + break; case st_audio_file_mp3: drmp3_uninit(af->mp3); free(af->mp3); @@ -157,6 +190,9 @@ uint32_t st_get_channels(st_audio_file* af) case st_audio_file_flac: channels = af->flac->channels; break; + case st_audio_file_ogg: + channels = af->cache.ogg.channels; + break; case st_audio_file_mp3: channels = af->mp3->channels; break; @@ -176,6 +212,9 @@ float st_get_sample_rate(st_audio_file* af) case st_audio_file_flac: sample_rate = af->flac->sampleRate; break; + case st_audio_file_ogg: + sample_rate = af->cache.ogg.sample_rate; + break; case st_audio_file_mp3: sample_rate = af->mp3->sampleRate; break; @@ -195,6 +234,9 @@ uint64_t st_get_frame_count(st_audio_file* af) case st_audio_file_flac: frames = af->flac->totalPCMFrameCount; break; + case st_audio_file_ogg: + frames = af->cache.ogg.frames; + break; case st_audio_file_mp3: frames = af->cache.mp3.frames; break; @@ -214,6 +256,9 @@ bool st_seek(st_audio_file* af, uint64_t frame) case st_audio_file_flac: success = drflac_seek_to_pcm_frame(af->flac, frame); break; + case st_audio_file_ogg: + success = stb_vorbis_seek(af->ogg, (unsigned)frame) != 0; + break; case st_audio_file_mp3: success = drmp3_seek_to_pcm_frame(af->mp3, frame); break; @@ -231,6 +276,11 @@ uint64_t st_read_s16(st_audio_file* af, int16_t* buffer, uint64_t count) case st_audio_file_flac: count = drflac_read_pcm_frames_s16(af->flac, count, buffer); break; + case st_audio_file_ogg: + count = stb_vorbis_get_samples_short_interleaved( + af->ogg, af->cache.ogg.channels, buffer, + count * af->cache.ogg.channels); + break; case st_audio_file_mp3: count = drmp3_read_pcm_frames_s16(af->mp3, count, buffer); break; @@ -248,6 +298,11 @@ uint64_t st_read_f32(st_audio_file* af, float* buffer, uint64_t count) case st_audio_file_flac: count = drflac_read_pcm_frames_f32(af->flac, count, buffer); break; + case st_audio_file_ogg: + count = stb_vorbis_get_samples_float_interleaved( + af->ogg, af->cache.ogg.channels, buffer, + count * af->cache.ogg.channels); + break; case st_audio_file_mp3: count = drmp3_read_pcm_frames_f32(af->mp3, count, buffer); break; diff --git a/external/st_audiofile/src/st_audiofile_libs.c b/external/st_audiofile/src/st_audiofile_libs.c index 4c39e703..0bbcccca 100644 --- a/external/st_audiofile/src/st_audiofile_libs.c +++ b/external/st_audiofile/src/st_audiofile_libs.c @@ -7,4 +7,23 @@ #define DR_WAV_IMPLEMENTATION #define DR_FLAC_IMPLEMENTATION #define DR_MP3_IMPLEMENTATION +#define STB_VORBIS_HEADER_ONLY 0 #include "st_audiofile_libs.h" + +#if defined(_WIN32) +stb_vorbis* stb_vorbis_open_filename_w(const wchar_t* filename, int* error, const stb_vorbis_alloc* alloc) +{ + FILE* f; +#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__) + if (0 != _wfopen_s(&f, filename, L"rb")) + f = NULL; +#else + f = _wfopen(filename, L"rb"); +#endif + if (f) + return stb_vorbis_open_file(f, TRUE, error, alloc); + if (error) + *error = VORBIS_file_open_failure; + return NULL; +} +#endif diff --git a/external/st_audiofile/src/st_audiofile_libs.h b/external/st_audiofile/src/st_audiofile_libs.h index 16f329b0..21727c6b 100644 --- a/external/st_audiofile/src/st_audiofile_libs.h +++ b/external/st_audiofile/src/st_audiofile_libs.h @@ -8,3 +8,14 @@ #include "dr_wav.h" #include "dr_flac.h" #include "dr_mp3.h" +#if !defined(STB_VORBIS_HEADER_ONLY) +# define STB_VORBIS_HEADER_ONLY 1 +#elif STB_VORBIS_HEADER_ONLY == 0 +# undef STB_VORBIS_HEADER_ONLY +#endif +#include "stb_vorbis.c" + +#if defined(_WIN32) +#include +stb_vorbis* stb_vorbis_open_filename_w(const wchar_t* filename, int* error, const stb_vorbis_alloc* alloc); +#endif diff --git a/external/st_audiofile/thirdparty/stb_vorbis b/external/st_audiofile/thirdparty/stb_vorbis new file mode 160000 index 00000000..fc0bd698 --- /dev/null +++ b/external/st_audiofile/thirdparty/stb_vorbis @@ -0,0 +1 @@ +Subproject commit fc0bd698b26888da0a632da33f4c49b90763e69b