Support loading AIFF files
This commit is contained in:
parent
1df11d072b
commit
ef7a1969d3
9 changed files with 97 additions and 1 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -27,3 +27,6 @@
|
||||||
path = external/st_audiofile/thirdparty/stb_vorbis
|
path = external/st_audiofile/thirdparty/stb_vorbis
|
||||||
url = https://github.com/sfztools/stb_vorbis.git
|
url = https://github.com/sfztools/stb_vorbis.git
|
||||||
shallow = true
|
shallow = true
|
||||||
|
[submodule "external/st_audiofile/thirdparty/libaiff"]
|
||||||
|
path = external/st_audiofile/thirdparty/libaiff
|
||||||
|
url = https://github.com/sfztools/libaiff.git
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ public:
|
||||||
|
|
||||||
static TemporaryFile fileWav;
|
static TemporaryFile fileWav;
|
||||||
static TemporaryFile fileFlac;
|
static TemporaryFile fileFlac;
|
||||||
|
static TemporaryFile fileAiff;
|
||||||
static TemporaryFile fileOgg;
|
static TemporaryFile fileOgg;
|
||||||
|
|
||||||
std::vector<float> workBuffer;
|
std::vector<float> workBuffer;
|
||||||
|
|
@ -101,6 +102,7 @@ public:
|
||||||
|
|
||||||
TemporaryFile AudioReaderFixture::fileWav = createAudioFile(SF_FORMAT_WAV|SF_FORMAT_PCM_16);
|
TemporaryFile AudioReaderFixture::fileWav = createAudioFile(SF_FORMAT_WAV|SF_FORMAT_PCM_16);
|
||||||
TemporaryFile AudioReaderFixture::fileFlac = createAudioFile(SF_FORMAT_FLAC|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::fileOgg = createAudioFile(SF_FORMAT_OGG|SF_FORMAT_VORBIS);
|
||||||
|
|
||||||
TemporaryFile AudioReaderFixture::createAudioFile(int format)
|
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)
|
BENCHMARK_DEFINE_F(AudioReaderFixture, EntireOgg)(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : 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, ForwardFlac)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||||
BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseFlac)->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, 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));
|
BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardOgg)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||||
#if !defined(ST_AUDIO_FILE_USE_SNDFILE)
|
#if !defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||||
BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseOgg)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseOgg)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||||
|
|
|
||||||
5
external/st_audiofile/CMakeLists.txt
vendored
5
external/st_audiofile/CMakeLists.txt
vendored
|
|
@ -19,7 +19,10 @@ add_executable(st_info
|
||||||
target_link_libraries(st_info
|
target_link_libraries(st_info
|
||||||
PRIVATE st_audiofile)
|
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
|
target_compile_definitions(st_audiofile
|
||||||
PUBLIC "ST_AUDIO_FILE_USE_SNDFILE=1")
|
PUBLIC "ST_AUDIO_FILE_USE_SNDFILE=1")
|
||||||
if(ST_AUDIO_FILE_EXTERNAL_SNDFILE)
|
if(ST_AUDIO_FILE_EXTERNAL_SNDFILE)
|
||||||
|
|
|
||||||
55
external/st_audiofile/src/st_audiofile.c
vendored
55
external/st_audiofile/src/st_audiofile.c
vendored
|
|
@ -14,11 +14,13 @@ struct st_audio_file {
|
||||||
union {
|
union {
|
||||||
drwav *wav;
|
drwav *wav;
|
||||||
drflac *flac;
|
drflac *flac;
|
||||||
|
AIFF_Ref aiff;
|
||||||
drmp3 *mp3;
|
drmp3 *mp3;
|
||||||
stb_vorbis* ogg;
|
stb_vorbis* ogg;
|
||||||
};
|
};
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
struct { uint32_t channels; float sample_rate; uint64_t frames; } aiff;
|
||||||
struct { uint64_t frames; } mp3;
|
struct { uint64_t frames; } mp3;
|
||||||
struct { uint32_t channels; float sample_rate; uint64_t frames; } ogg;
|
struct { uint32_t channels; float sample_rate; uint64_t frames; } ogg;
|
||||||
} cache;
|
} 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
|
// Try OGG
|
||||||
{
|
{
|
||||||
af->ogg =
|
af->ogg =
|
||||||
|
|
@ -142,6 +168,9 @@ void st_close(st_audio_file* af)
|
||||||
case st_audio_file_flac:
|
case st_audio_file_flac:
|
||||||
drflac_close(af->flac);
|
drflac_close(af->flac);
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_aiff:
|
||||||
|
AIFF_CloseFile(af->aiff);
|
||||||
|
break;
|
||||||
case st_audio_file_ogg:
|
case st_audio_file_ogg:
|
||||||
stb_vorbis_close(af->ogg);
|
stb_vorbis_close(af->ogg);
|
||||||
break;
|
break;
|
||||||
|
|
@ -170,6 +199,9 @@ uint32_t st_get_channels(st_audio_file* af)
|
||||||
case st_audio_file_flac:
|
case st_audio_file_flac:
|
||||||
channels = af->flac->channels;
|
channels = af->flac->channels;
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_aiff:
|
||||||
|
channels = af->cache.aiff.channels;
|
||||||
|
break;
|
||||||
case st_audio_file_ogg:
|
case st_audio_file_ogg:
|
||||||
channels = af->cache.ogg.channels;
|
channels = af->cache.ogg.channels;
|
||||||
break;
|
break;
|
||||||
|
|
@ -192,6 +224,9 @@ float st_get_sample_rate(st_audio_file* af)
|
||||||
case st_audio_file_flac:
|
case st_audio_file_flac:
|
||||||
sample_rate = af->flac->sampleRate;
|
sample_rate = af->flac->sampleRate;
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_aiff:
|
||||||
|
sample_rate = af->cache.aiff.sample_rate;
|
||||||
|
break;
|
||||||
case st_audio_file_ogg:
|
case st_audio_file_ogg:
|
||||||
sample_rate = af->cache.ogg.sample_rate;
|
sample_rate = af->cache.ogg.sample_rate;
|
||||||
break;
|
break;
|
||||||
|
|
@ -214,6 +249,9 @@ uint64_t st_get_frame_count(st_audio_file* af)
|
||||||
case st_audio_file_flac:
|
case st_audio_file_flac:
|
||||||
frames = af->flac->totalPCMFrameCount;
|
frames = af->flac->totalPCMFrameCount;
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_aiff:
|
||||||
|
frames = af->cache.aiff.frames;
|
||||||
|
break;
|
||||||
case st_audio_file_ogg:
|
case st_audio_file_ogg:
|
||||||
frames = af->cache.ogg.frames;
|
frames = af->cache.ogg.frames;
|
||||||
break;
|
break;
|
||||||
|
|
@ -236,6 +274,9 @@ bool st_seek(st_audio_file* af, uint64_t frame)
|
||||||
case st_audio_file_flac:
|
case st_audio_file_flac:
|
||||||
success = drflac_seek_to_pcm_frame(af->flac, frame);
|
success = drflac_seek_to_pcm_frame(af->flac, frame);
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_aiff:
|
||||||
|
success = AIFF_Seek(af->aiff, frame) != -1;
|
||||||
|
break;
|
||||||
case st_audio_file_ogg:
|
case st_audio_file_ogg:
|
||||||
success = stb_vorbis_seek(af->ogg, (unsigned)frame) != 0;
|
success = stb_vorbis_seek(af->ogg, (unsigned)frame) != 0;
|
||||||
break;
|
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:
|
case st_audio_file_flac:
|
||||||
count = drflac_read_pcm_frames_s16(af->flac, count, buffer);
|
count = drflac_read_pcm_frames_s16(af->flac, count, buffer);
|
||||||
break;
|
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:
|
case st_audio_file_ogg:
|
||||||
count = stb_vorbis_get_samples_short_interleaved(
|
count = stb_vorbis_get_samples_short_interleaved(
|
||||||
af->ogg, af->cache.ogg.channels, buffer,
|
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:
|
case st_audio_file_flac:
|
||||||
count = drflac_read_pcm_frames_f32(af->flac, count, buffer);
|
count = drflac_read_pcm_frames_f32(af->flac, count, buffer);
|
||||||
break;
|
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:
|
case st_audio_file_ogg:
|
||||||
count = stb_vorbis_get_samples_float_interleaved(
|
count = stb_vorbis_get_samples_float_interleaved(
|
||||||
af->ogg, af->cache.ogg.channels, buffer,
|
af->ogg, af->cache.ogg.channels, buffer,
|
||||||
|
|
|
||||||
1
external/st_audiofile/src/st_audiofile.h
vendored
1
external/st_audiofile/src/st_audiofile.h
vendored
|
|
@ -23,6 +23,7 @@ typedef struct st_audio_file st_audio_file;
|
||||||
typedef enum st_audio_file_type {
|
typedef enum st_audio_file_type {
|
||||||
st_audio_file_wav,
|
st_audio_file_wav,
|
||||||
st_audio_file_flac,
|
st_audio_file_flac,
|
||||||
|
st_audio_file_aiff,
|
||||||
st_audio_file_ogg,
|
st_audio_file_ogg,
|
||||||
st_audio_file_mp3,
|
st_audio_file_mp3,
|
||||||
st_audio_file_other,
|
st_audio_file_other,
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@ const char* st_type_string(int type)
|
||||||
case st_audio_file_flac:
|
case st_audio_file_flac:
|
||||||
type_string = "FLAC";
|
type_string = "FLAC";
|
||||||
break;
|
break;
|
||||||
|
case st_audio_file_aiff:
|
||||||
|
type_string = "AIFF";
|
||||||
|
break;
|
||||||
case st_audio_file_ogg:
|
case st_audio_file_ogg:
|
||||||
type_string = "OGG";
|
type_string = "OGG";
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
# undef STB_VORBIS_HEADER_ONLY
|
# undef STB_VORBIS_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
#include "stb_vorbis.c"
|
#include "stb_vorbis.c"
|
||||||
|
#include "libaiff/libaiff.h"
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,9 @@ int st_get_type(st_audio_file* af)
|
||||||
case SF_FORMAT_FLAC:
|
case SF_FORMAT_FLAC:
|
||||||
type = st_audio_file_flac;
|
type = st_audio_file_flac;
|
||||||
break;
|
break;
|
||||||
|
case SF_FORMAT_AIFF:
|
||||||
|
type = st_audio_file_aiff;
|
||||||
|
break;
|
||||||
case SF_FORMAT_OGG:
|
case SF_FORMAT_OGG:
|
||||||
type = st_audio_file_ogg;
|
type = st_audio_file_ogg;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
1
external/st_audiofile/thirdparty/libaiff
vendored
Submodule
1
external/st_audiofile/thirdparty/libaiff
vendored
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit f18eefcd27108fdfdd0b6620426b404f132e39c4
|
||||||
Loading…
Add table
Reference in a new issue