commit
391fb7ab5b
15 changed files with 325 additions and 3 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ public:
|
|||
|
||||
static TemporaryFile fileWav;
|
||||
static TemporaryFile fileFlac;
|
||||
static TemporaryFile fileAiff;
|
||||
static TemporaryFile fileOgg;
|
||||
|
||||
std::vector<float> 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));
|
||||
|
|
|
|||
11
common.mk
11
common.mk
|
|
@ -156,6 +156,17 @@ SFIZZ_CXX_FLAGS += $(SFIZZ_SNDFILE_CXX_FLAGS) -DST_AUDIO_FILE_USE_SNDFILE=1
|
|||
SFIZZ_LINK_FLAGS += $(SFIZZ_SNDFILE_LINK_FLAGS)
|
||||
endif
|
||||
|
||||
# libaiff dependency
|
||||
|
||||
ifneq ($(SFIZZ_USE_SNDFILE),1)
|
||||
SFIZZ_SOURCES += \
|
||||
$(SFIZZ_DIR)/external/st_audiofile/thirdparty/libaiff/libaiff.all.c
|
||||
SFIZZ_C_FLAGS += \
|
||||
-I$(SFIZZ_DIR)/external/st_audiofile/thirdparty/libaiff
|
||||
SFIZZ_CXX_FLAGS += \
|
||||
-I$(SFIZZ_DIR)/external/st_audiofile/thirdparty/libaiff
|
||||
endif
|
||||
|
||||
### Abseil dependency
|
||||
|
||||
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/external/abseil-cpp
|
||||
|
|
|
|||
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
|
||||
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)
|
||||
|
|
|
|||
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 {
|
||||
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,
|
||||
|
|
|
|||
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 {
|
||||
st_audio_file_wav,
|
||||
st_audio_file_flac,
|
||||
st_audio_file_aiff,
|
||||
st_audio_file_ogg,
|
||||
st_audio_file_mp3,
|
||||
st_audio_file_other,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
// license. You should have receive a LICENSE.md file along with the code.
|
||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#if !defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
#define DR_WAV_IMPLEMENTATION
|
||||
#define DR_FLAC_IMPLEMENTATION
|
||||
#define DR_MP3_IMPLEMENTATION
|
||||
|
|
@ -27,3 +28,5 @@ stb_vorbis* stb_vorbis_open_filename_w(const wchar_t* filename, int* error, cons
|
|||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
# undef STB_VORBIS_HEADER_ONLY
|
||||
#endif
|
||||
#include "stb_vorbis.c"
|
||||
#include "libaiff/libaiff.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <wchar.h>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
1
external/st_audiofile/thirdparty/libaiff
vendored
Submodule
1
external/st_audiofile/thirdparty/libaiff
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 015f884a0458240a9b5f1f0d945a6084243def46
|
||||
|
|
@ -39,6 +39,18 @@ static uint32_t u32be(const uint8_t *bytes)
|
|||
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
|
||||
}
|
||||
|
||||
#if 0
|
||||
static uint16_t u16le(const uint8_t *bytes)
|
||||
{
|
||||
return bytes[0] | (bytes[1] << 8);
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint16_t u16be(const uint8_t *bytes)
|
||||
{
|
||||
return (bytes[0] << 8) | bytes[1];
|
||||
}
|
||||
|
||||
static bool fread_u32le(FILE* stream, uint32_t& value)
|
||||
{
|
||||
uint8_t bytes[4];
|
||||
|
|
@ -57,14 +69,38 @@ static bool fread_u32be(FILE* stream, uint32_t& value)
|
|||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool fread_u16le(FILE* stream, uint16_t& value)
|
||||
{
|
||||
uint8_t bytes[2];
|
||||
if (fread(bytes, 2, 1, stream) != 1)
|
||||
return false;
|
||||
value = u16le(bytes);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool fread_u16be(FILE* stream, uint16_t& value)
|
||||
{
|
||||
uint8_t bytes[2];
|
||||
if (fread(bytes, 2, 1, stream) != 1)
|
||||
return false;
|
||||
value = u16be(bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
struct FileMetadataReader::Impl {
|
||||
FILE_u stream_;
|
||||
std::vector<RiffChunkInfo> riffChunks_;
|
||||
|
||||
enum class ChunkType { None, Riff, Aiff };
|
||||
ChunkType chunkType_ = ChunkType::None;
|
||||
|
||||
bool openFlac();
|
||||
bool openRiff();
|
||||
bool openAiff();
|
||||
|
||||
bool extractClmWavetable(WavetableInfo &wt);
|
||||
bool extractSurgeWavetable(WavetableInfo &wt);
|
||||
|
|
@ -108,12 +144,21 @@ bool FileMetadataReader::open(const fs::path& path)
|
|||
close();
|
||||
return false;
|
||||
}
|
||||
impl_->chunkType_ = Impl::ChunkType::Riff;
|
||||
}
|
||||
else if (count >= 4 && !memcmp(magic, "RIFF", 4)) {
|
||||
if (!impl_->openRiff()) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
impl_->chunkType_ = Impl::ChunkType::Riff;
|
||||
}
|
||||
else if (count >= 4 && !memcmp(magic, "FORM", 4)) {
|
||||
if (!impl_->openAiff()) {
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
impl_->chunkType_ = Impl::ChunkType::Aiff;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -193,6 +238,46 @@ bool FileMetadataReader::Impl::openRiff()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FileMetadataReader::Impl::openAiff()
|
||||
{
|
||||
FILE* stream = stream_.get();
|
||||
|
||||
rewind(stream);
|
||||
|
||||
char formId[4];
|
||||
uint32_t formSize;
|
||||
if (fread(formId, 4, 1, stream) != 1 || memcmp(formId, "FORM", 4) ||
|
||||
!fread_u32be(stream, formSize))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char aiffId[4];
|
||||
if (fread(aiffId, 4, 1, stream) != 1 ||
|
||||
(memcmp(aiffId, "AIFF", 4) && memcmp(aiffId, "AIFC", 4)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<RiffChunkInfo>& riffChunks = riffChunks_;
|
||||
|
||||
char riffId[4];
|
||||
uint32_t riffChunkSize;
|
||||
while (fread(riffId, 4, 1, stream) == 1 && fread_u32be(stream, riffChunkSize)) {
|
||||
RiffChunkInfo info;
|
||||
info.index = riffChunks.size();
|
||||
info.fileOffset = ftell(stream);
|
||||
memcpy(info.id.data(), riffId, 4);
|
||||
info.length = riffChunkSize;
|
||||
riffChunks.push_back(info);
|
||||
|
||||
if (fseek(stream, riffChunkSize + (riffChunkSize & 1), SEEK_CUR) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t FileMetadataReader::riffChunkCount() const
|
||||
{
|
||||
return impl_->riffChunks_.size();
|
||||
|
|
@ -242,8 +327,22 @@ size_t FileMetadataReader::Impl::readRiffData(size_t index, void* buffer, size_t
|
|||
return fread(buffer, 1, count, stream);
|
||||
}
|
||||
|
||||
bool FileMetadataReader::extractInstrument(InstrumentInfo& ins)
|
||||
{
|
||||
if (extractRiffInstrument(ins))
|
||||
return true;
|
||||
|
||||
if (extractAiffInstrument(ins))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileMetadataReader::extractRiffInstrument(InstrumentInfo& ins)
|
||||
{
|
||||
if (impl_->chunkType_ != Impl::ChunkType::Riff)
|
||||
return false;
|
||||
|
||||
const RiffChunkInfo* riff = riffChunkById(RiffChunkId{'s', 'm', 'p', 'l'});
|
||||
if (!riff)
|
||||
return false;
|
||||
|
|
@ -299,6 +398,109 @@ bool FileMetadataReader::extractRiffInstrument(InstrumentInfo& ins)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FileMetadataReader::extractAiffInstrument(InstrumentInfo& ins)
|
||||
{
|
||||
if (impl_->chunkType_ != Impl::ChunkType::Aiff)
|
||||
return false;
|
||||
|
||||
const RiffChunkInfo* instChunk = riffChunkById(RiffChunkId{'I', 'N', 'S', 'T'});
|
||||
if (!instChunk)
|
||||
return false;
|
||||
|
||||
const RiffChunkInfo* markChunk = riffChunkById(RiffChunkId{'M', 'A', 'R', 'K'});
|
||||
|
||||
uint8_t insData[20];
|
||||
uint32_t length = readRiffData(instChunk->index, insData, sizeof(insData));
|
||||
if (length != 20)
|
||||
return false;
|
||||
|
||||
//
|
||||
std::map<uint16_t, uint32_t> markers;
|
||||
if (markChunk) {
|
||||
FILE* stream = impl_->stream_.get();
|
||||
if (fseek(stream, markChunk->fileOffset, SEEK_SET) != 0)
|
||||
return false;
|
||||
|
||||
uint16_t numMarkers;
|
||||
if (!fread_u16be(stream, numMarkers))
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 0; i < numMarkers; ++i) {
|
||||
uint16_t id;
|
||||
uint32_t position;
|
||||
uint8_t size;
|
||||
char name[256];
|
||||
|
||||
if (!fread_u16be(stream, id) || !fread_u32be(stream, position) || fread(&size, 1, 1, stream) != 1 || fread(name, size, 1, stream) != 1)
|
||||
return false;
|
||||
name[size] = '\0';
|
||||
|
||||
if (i + 1 < numMarkers && ((~size) & 1)) {
|
||||
if (fseek(stream, 1, SEEK_CUR) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
markers[id] = position;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
ins.basenote = insData[0];
|
||||
ins.detune = insData[1];
|
||||
ins.key_lo = insData[2];
|
||||
ins.key_hi = insData[3];
|
||||
ins.velocity_lo = insData[4];
|
||||
ins.velocity_hi = insData[5];
|
||||
ins.gain = (insData[6] << 8) | insData[7];
|
||||
|
||||
uint32_t loopCount = 0;
|
||||
for (uint32_t loopIndex = 0; loopIndex < 2; ++loopIndex) {
|
||||
const uint32_t loopOffset = 8 + loopIndex * 6;
|
||||
|
||||
int mode;
|
||||
switch ((insData[loopOffset] << 8) | insData[loopOffset + 1]) {
|
||||
default:
|
||||
mode = LoopNone;
|
||||
break;
|
||||
case 1:
|
||||
mode = LoopForward;
|
||||
break;
|
||||
case 2:
|
||||
mode = LoopBackward;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode == LoopNone)
|
||||
break;
|
||||
|
||||
const uint16_t startId = (insData[loopOffset + 2] << 8) | insData[loopOffset + 3];
|
||||
const uint16_t endId = (insData[loopOffset + 4] << 8) | insData[loopOffset + 5];
|
||||
|
||||
//
|
||||
uint32_t startPos = 0;
|
||||
uint32_t endPos = 0;
|
||||
|
||||
auto startIt = markers.find(startId);
|
||||
auto endIt = markers.find(endId);
|
||||
if (startIt != markers.end())
|
||||
startPos = startIt->second;
|
||||
if (endIt != markers.end())
|
||||
endPos = endIt->second;
|
||||
|
||||
//
|
||||
ins.loops[loopIndex].mode = mode;
|
||||
ins.loops[loopIndex].start = startPos;
|
||||
ins.loops[loopIndex].end = endPos;
|
||||
ins.loops[loopIndex].count = 0;
|
||||
|
||||
++loopCount;
|
||||
}
|
||||
|
||||
ins.loop_count = loopCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileMetadataReader::extractWavetableInfo(WavetableInfo& wt)
|
||||
{
|
||||
if (impl_->extractClmWavetable(wt))
|
||||
|
|
|
|||
|
|
@ -112,11 +112,21 @@ public:
|
|||
*/
|
||||
size_t readRiffData(size_t index, void* buffer, size_t count);
|
||||
|
||||
/**
|
||||
* @brief Extract the instrument data and convert it to sndfile instrument
|
||||
*/
|
||||
bool extractInstrument(InstrumentInfo& ins);
|
||||
|
||||
/**
|
||||
* @brief Extract the RIFF 'smpl' data and convert it to sndfile instrument
|
||||
*/
|
||||
bool extractRiffInstrument(InstrumentInfo& ins);
|
||||
|
||||
/**
|
||||
* @brief Extract the AIFF 'INST' data and convert it to sndfile instrument
|
||||
*/
|
||||
bool extractAiffInstrument(InstrumentInfo& ins);
|
||||
|
||||
/**
|
||||
* @brief Extract the wavetable information from various relevant RIFF chunks
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ absl::optional<sfz::FileInformation> sfz::FilePool::getFileInformation(const Fil
|
|||
if (!haveInstrumentInfo) {
|
||||
// if no instrument, then try extracting from embedded RIFF chunks (flac)
|
||||
if (mdReaderOpened)
|
||||
haveInstrumentInfo = mdReader.extractRiffInstrument(instrumentInfo);
|
||||
haveInstrumentInfo = mdReader.extractInstrument(instrumentInfo);
|
||||
}
|
||||
|
||||
if (mdReaderOpened) {
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
sfz::InstrumentInfo ins {};
|
||||
if (!reader.extractRiffInstrument(ins)) {
|
||||
if (!reader.extractInstrument(ins)) {
|
||||
fprintf(stderr, "Cannot get instrument\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue