diff --git a/.gitmodules b/.gitmodules index c47fa23b..d97f8bae 100644 --- a/.gitmodules +++ b/.gitmodules @@ -27,3 +27,6 @@ path = external/st_audiofile/thirdparty/stb_vorbis url = https://github.com/sfztools/stb_vorbis.git shallow = true +[submodule "external/st_audiofile/thirdparty/libaiff"] + path = external/st_audiofile/thirdparty/libaiff + url = https://github.com/sfztools/libaiff.git diff --git a/benchmarks/BM_audioReaders.cpp b/benchmarks/BM_audioReaders.cpp index 98483a8d..3a4b23e7 100644 --- a/benchmarks/BM_audioReaders.cpp +++ b/benchmarks/BM_audioReaders.cpp @@ -94,6 +94,7 @@ public: static TemporaryFile fileWav; static TemporaryFile fileFlac; + static TemporaryFile fileAiff; static TemporaryFile fileOgg; std::vector workBuffer; @@ -101,6 +102,7 @@ public: TemporaryFile AudioReaderFixture::fileWav = createAudioFile(SF_FORMAT_WAV|SF_FORMAT_PCM_16); TemporaryFile AudioReaderFixture::fileFlac = createAudioFile(SF_FORMAT_FLAC|SF_FORMAT_PCM_16); +TemporaryFile AudioReaderFixture::fileAiff = createAudioFile(SF_FORMAT_AIFF|SF_FORMAT_PCM_16); TemporaryFile AudioReaderFixture::fileOgg = createAudioFile(SF_FORMAT_OGG|SF_FORMAT_VORBIS); TemporaryFile AudioReaderFixture::createAudioFile(int format) @@ -196,6 +198,27 @@ BENCHMARK_DEFINE_F(AudioReaderFixture, ReverseFlac)(benchmark::State& state) } } +BENCHMARK_DEFINE_F(AudioReaderFixture, EntireAiff)(benchmark::State& state) +{ + for (auto _ : state) { + doEntireRead(fileAiff.path()); + } +} + +BENCHMARK_DEFINE_F(AudioReaderFixture, ForwardAiff)(benchmark::State& state) +{ + for (auto _ : state) { + doReaderBenchmark(fileAiff.path(), workBuffer, sfz::AudioReaderType::Forward); + } +} + +BENCHMARK_DEFINE_F(AudioReaderFixture, ReverseAiff)(benchmark::State& state) +{ + for (auto _ : state) { + doReaderBenchmark(fileAiff.path(), workBuffer, sfz::AudioReaderType::Reverse); + } +} + BENCHMARK_DEFINE_F(AudioReaderFixture, EntireOgg)(benchmark::State& state) { for (auto _ : state) { @@ -225,6 +248,9 @@ BENCHMARK_REGISTER_F(AudioReaderFixture, EntireWav)->Range(1, 1); BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardFlac)->RangeMultiplier(2)->Range((1 << 6), (1 << 10)); BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseFlac)->RangeMultiplier(2)->Range((1 << 6), (1 << 10)); BENCHMARK_REGISTER_F(AudioReaderFixture, EntireFlac)->Range(1, 1); +BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardAiff)->RangeMultiplier(2)->Range((1 << 6), (1 << 10)); +BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseAiff)->RangeMultiplier(2)->Range((1 << 6), (1 << 10)); +BENCHMARK_REGISTER_F(AudioReaderFixture, EntireAiff)->Range(1, 1); BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardOgg)->RangeMultiplier(2)->Range((1 << 6), (1 << 10)); #if !defined(ST_AUDIO_FILE_USE_SNDFILE) BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseOgg)->RangeMultiplier(2)->Range((1 << 6), (1 << 10)); diff --git a/external/st_audiofile/CMakeLists.txt b/external/st_audiofile/CMakeLists.txt index e0fb1e4e..643c0992 100644 --- a/external/st_audiofile/CMakeLists.txt +++ b/external/st_audiofile/CMakeLists.txt @@ -19,7 +19,10 @@ add_executable(st_info target_link_libraries(st_info PRIVATE st_audiofile) -if(ST_AUDIO_FILE_USE_SNDFILE) +if(NOT ST_AUDIO_FILE_USE_SNDFILE) + add_subdirectory("thirdparty/libaiff" EXCLUDE_FROM_ALL) + target_link_libraries(st_audiofile PRIVATE aiff::aiff) +else() target_compile_definitions(st_audiofile PUBLIC "ST_AUDIO_FILE_USE_SNDFILE=1") if(ST_AUDIO_FILE_EXTERNAL_SNDFILE) diff --git a/external/st_audiofile/src/st_audiofile.c b/external/st_audiofile/src/st_audiofile.c index 64f1cccf..f9d1e869 100644 --- a/external/st_audiofile/src/st_audiofile.c +++ b/external/st_audiofile/src/st_audiofile.c @@ -14,11 +14,13 @@ struct st_audio_file { union { drwav *wav; drflac *flac; + AIFF_Ref aiff; drmp3 *mp3; stb_vorbis* ogg; }; union { + struct { uint32_t channels; float sample_rate; uint64_t frames; } aiff; struct { uint64_t frames; } mp3; struct { uint32_t channels; float sample_rate; uint64_t frames; } ogg; } cache; @@ -68,6 +70,30 @@ static st_audio_file* st_generic_open_file(const void* filename, int widepath) } } + // Try AIFF + { + af->aiff = +#if defined(_WIN32) + widepath ? AIFF_OpenFileW((const wchar_t*)filename, F_RDONLY) : +#endif + AIFF_OpenFile((const char*)filename, F_RDONLY); + if (af->aiff) { + int channels; + double sample_rate; + uint64_t frames; + if (AIFF_GetAudioFormat(af->aiff, &frames, &channels, &sample_rate, NULL, NULL) == -1) { + AIFF_CloseFile(af->aiff); + free(af); + return NULL; + } + af->cache.aiff.channels = (uint32_t)channels; + af->cache.aiff.sample_rate = (float)sample_rate; + af->cache.aiff.frames = frames; + af->type = st_audio_file_aiff; + return af; + } + } + // Try OGG { af->ogg = @@ -142,6 +168,9 @@ void st_close(st_audio_file* af) case st_audio_file_flac: drflac_close(af->flac); break; + case st_audio_file_aiff: + AIFF_CloseFile(af->aiff); + break; case st_audio_file_ogg: stb_vorbis_close(af->ogg); break; @@ -170,6 +199,9 @@ uint32_t st_get_channels(st_audio_file* af) case st_audio_file_flac: channels = af->flac->channels; break; + case st_audio_file_aiff: + channels = af->cache.aiff.channels; + break; case st_audio_file_ogg: channels = af->cache.ogg.channels; break; @@ -192,6 +224,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_aiff: + sample_rate = af->cache.aiff.sample_rate; + break; case st_audio_file_ogg: sample_rate = af->cache.ogg.sample_rate; break; @@ -214,6 +249,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_aiff: + frames = af->cache.aiff.frames; + break; case st_audio_file_ogg: frames = af->cache.ogg.frames; break; @@ -236,6 +274,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_aiff: + success = AIFF_Seek(af->aiff, frame) != -1; + break; case st_audio_file_ogg: success = stb_vorbis_seek(af->ogg, (unsigned)frame) != 0; break; @@ -256,6 +297,13 @@ 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_aiff: + { + uint32_t channels = af->cache.aiff.channels; + unsigned samples = AIFF_ReadSamples16Bit(af->aiff, buffer, (unsigned)(channels * count)); + count = ((int)samples != -1) ? (samples / channels) : 0; + } + break; case st_audio_file_ogg: count = stb_vorbis_get_samples_short_interleaved( af->ogg, af->cache.ogg.channels, buffer, @@ -278,6 +326,13 @@ 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_aiff: + { + uint32_t channels = af->cache.aiff.channels; + unsigned samples = AIFF_ReadSamplesFloat(af->aiff, buffer, (unsigned)(channels * count)); + count = ((int)samples != -1) ? (samples / channels) : 0; + } + break; case st_audio_file_ogg: count = stb_vorbis_get_samples_float_interleaved( af->ogg, af->cache.ogg.channels, buffer, diff --git a/external/st_audiofile/src/st_audiofile.h b/external/st_audiofile/src/st_audiofile.h index fd62c77f..3fbcbfd8 100644 --- a/external/st_audiofile/src/st_audiofile.h +++ b/external/st_audiofile/src/st_audiofile.h @@ -23,6 +23,7 @@ typedef struct st_audio_file st_audio_file; typedef enum st_audio_file_type { st_audio_file_wav, st_audio_file_flac, + st_audio_file_aiff, st_audio_file_ogg, st_audio_file_mp3, st_audio_file_other, diff --git a/external/st_audiofile/src/st_audiofile_common.c b/external/st_audiofile/src/st_audiofile_common.c index d8e2ac6e..c3e14297 100644 --- a/external/st_audiofile/src/st_audiofile_common.c +++ b/external/st_audiofile/src/st_audiofile_common.c @@ -23,6 +23,9 @@ const char* st_type_string(int type) case st_audio_file_flac: type_string = "FLAC"; break; + case st_audio_file_aiff: + type_string = "AIFF"; + break; case st_audio_file_ogg: type_string = "OGG"; break; diff --git a/external/st_audiofile/src/st_audiofile_libs.h b/external/st_audiofile/src/st_audiofile_libs.h index 21727c6b..67aacaba 100644 --- a/external/st_audiofile/src/st_audiofile_libs.h +++ b/external/st_audiofile/src/st_audiofile_libs.h @@ -14,6 +14,7 @@ # undef STB_VORBIS_HEADER_ONLY #endif #include "stb_vorbis.c" +#include "libaiff/libaiff.h" #if defined(_WIN32) #include diff --git a/external/st_audiofile/src/st_audiofile_sndfile.c b/external/st_audiofile/src/st_audiofile_sndfile.c index 480daa34..c1b8fed8 100644 --- a/external/st_audiofile/src/st_audiofile_sndfile.c +++ b/external/st_audiofile/src/st_audiofile_sndfile.c @@ -69,6 +69,9 @@ int st_get_type(st_audio_file* af) case SF_FORMAT_FLAC: type = st_audio_file_flac; break; + case SF_FORMAT_AIFF: + type = st_audio_file_aiff; + break; case SF_FORMAT_OGG: type = st_audio_file_ogg; break; diff --git a/external/st_audiofile/thirdparty/libaiff b/external/st_audiofile/thirdparty/libaiff new file mode 160000 index 00000000..f18eefcd --- /dev/null +++ b/external/st_audiofile/thirdparty/libaiff @@ -0,0 +1 @@ +Subproject commit f18eefcd27108fdfdd0b6620426b404f132e39c4