Merge pull request #482 from jpcima/st-audiofile
Audio file reader without sndfile
This commit is contained in:
commit
401e0a4e21
28 changed files with 1072 additions and 128 deletions
8
.gitmodules
vendored
8
.gitmodules
vendored
|
|
@ -19,3 +19,11 @@
|
|||
path = editor/external/vstgui4
|
||||
url = https://github.com/sfztools/vstgui.git
|
||||
shallow = true
|
||||
[submodule "external/st_audiofile/thirdparty/dr_libs"]
|
||||
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
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ option (SFIZZ_BENCHMARKS "Enable benchmarks build [default: OFF]" OFF)
|
|||
option (SFIZZ_TESTS "Enable tests build [default: OFF]" OFF)
|
||||
option (SFIZZ_DEVTOOLS "Enable developer tools build [default: OFF]" OFF)
|
||||
option (SFIZZ_SHARED "Enable shared library build [default: ON]" ON)
|
||||
option (SFIZZ_USE_SNDFILE "Enable use of the sndfile library [default: ON]" ON)
|
||||
option (SFIZZ_USE_VCPKG "Assume that sfizz is build using vcpkg [default: OFF]" OFF)
|
||||
option (SFIZZ_STATIC_DEPENDENCIES "Link dependencies statically [default: OFF]" OFF)
|
||||
option (SFIZZ_RELEASE_ASSERTS "Forced assertions in release builds [default: OFF]" OFF)
|
||||
|
|
|
|||
|
|
@ -146,16 +146,12 @@ static void doReaderBenchmark(const fs::path& path, std::vector<float> &buffer,
|
|||
|
||||
static void doEntireRead(const fs::path& path)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
SndfileHandle handle(path.c_str());
|
||||
#else
|
||||
SndfileHandle handle(path.wstring().c_str());
|
||||
#endif
|
||||
if (handle.error())
|
||||
throw std::runtime_error("cannot open sound file for reading");
|
||||
sfz::AudioReaderPtr reader = sfz::createAudioReader(path, false);
|
||||
if (!reader)
|
||||
return;
|
||||
|
||||
std::vector<float> buffer(static_cast<size_t>(2 * handle.frames()));
|
||||
handle.read(buffer.data(), buffer.size());
|
||||
std::vector<float> buffer(static_cast<size_t>(2 * reader->frames()));
|
||||
reader->readNextBlock(buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
BENCHMARK_DEFINE_F(AudioReaderFixture, EntireWav)(benchmark::State& state)
|
||||
|
|
@ -214,12 +210,14 @@ BENCHMARK_DEFINE_F(AudioReaderFixture, ForwardOgg)(benchmark::State& state)
|
|||
}
|
||||
}
|
||||
|
||||
//BENCHMARK_DEFINE_F(AudioReaderFixture, ReverseOgg)(benchmark::State& state)
|
||||
//{
|
||||
// for (auto _ : state) {
|
||||
// doReaderBenchmark(fileOgg.path(), workBuffer, sfz::AudioReaderType::Reverse);
|
||||
// }
|
||||
//}
|
||||
#if !defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
BENCHMARK_DEFINE_F(AudioReaderFixture, ReverseOgg)(benchmark::State& state)
|
||||
{
|
||||
for (auto _ : state) {
|
||||
doReaderBenchmark(fileOgg.path(), workBuffer, sfz::AudioReaderType::Reverse);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardWav)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||
BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseWav)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||
|
|
@ -228,6 +226,8 @@ BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardFlac)->RangeMultiplier(2)->Range
|
|||
BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseFlac)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||
BENCHMARK_REGISTER_F(AudioReaderFixture, EntireFlac)->Range(1, 1);
|
||||
BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardOgg)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||
//BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseOgg)->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));
|
||||
#endif
|
||||
BENCHMARK_REGISTER_F(AudioReaderFixture, EntireOgg)->Range(1, 1);
|
||||
BENCHMARK_MAIN();
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ sfizz_add_benchmark(bm_flacfile BM_flacfile.cpp)
|
|||
target_link_libraries(bm_flacfile PRIVATE sfizz-sndfile)
|
||||
|
||||
sfizz_add_benchmark(bm_audioReaders BM_audioReaders.cpp ../src/sfizz/AudioReader.cpp)
|
||||
target_link_libraries(bm_audioReaders PRIVATE sfizz-sndfile)
|
||||
target_link_libraries(bm_audioReaders PRIVATE st_audiofile sfizz-sndfile)
|
||||
|
||||
sfizz_add_benchmark(bm_readChunk BM_readChunk.cpp)
|
||||
target_link_libraries(bm_readChunk PRIVATE sfizz-sndfile)
|
||||
|
|
|
|||
|
|
@ -79,30 +79,40 @@ function(sfizz_enable_fast_math NAME)
|
|||
endif()
|
||||
endfunction()
|
||||
|
||||
# The sndfile library
|
||||
add_library(sfizz-sndfile INTERFACE)
|
||||
|
||||
# The jsl utility library for C++
|
||||
add_library(sfizz-jsl INTERFACE)
|
||||
target_include_directories(sfizz-jsl INTERFACE "external/jsl/include")
|
||||
|
||||
if (SFIZZ_USE_VCPKG OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
find_package(SndFile CONFIG REQUIRED)
|
||||
find_path(SNDFILE_INCLUDE_DIR sndfile.hh)
|
||||
target_include_directories(sfizz-sndfile INTERFACE "${SNDFILE_INCLUDE_DIR}")
|
||||
target_link_libraries(sfizz-sndfile INTERFACE SndFile::sndfile)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SNDFILE "sndfile" REQUIRED)
|
||||
target_include_directories(sfizz-sndfile INTERFACE ${SNDFILE_INCLUDE_DIRS})
|
||||
if (SFIZZ_STATIC_DEPENDENCIES)
|
||||
target_link_libraries(sfizz-sndfile INTERFACE ${SNDFILE_STATIC_LIBRARIES})
|
||||
# The sndfile library
|
||||
if (SFIZZ_USE_SNDFILE OR SFIZZ_TESTS OR SFIZZ_BENCHMARKS OR SFIZZ_RENDER)
|
||||
add_library(sfizz-sndfile INTERFACE)
|
||||
if (SFIZZ_USE_VCPKG OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
find_package(SndFile CONFIG REQUIRED)
|
||||
find_path(SNDFILE_INCLUDE_DIR "sndfile.hh")
|
||||
target_include_directories(sfizz-sndfile INTERFACE "${SNDFILE_INCLUDE_DIR}")
|
||||
target_link_libraries(sfizz-sndfile INTERFACE SndFile::sndfile)
|
||||
else()
|
||||
target_link_libraries(sfizz-sndfile INTERFACE ${SNDFILE_LIBRARIES})
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SNDFILE "sndfile" REQUIRED)
|
||||
target_include_directories(sfizz-sndfile INTERFACE ${SNDFILE_INCLUDE_DIRS})
|
||||
if (SFIZZ_STATIC_DEPENDENCIES)
|
||||
target_link_libraries(sfizz-sndfile INTERFACE ${SNDFILE_STATIC_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(sfizz-sndfile INTERFACE ${SNDFILE_LIBRARIES})
|
||||
endif()
|
||||
link_directories(${SNDFILE_LIBRARY_DIRS})
|
||||
endif()
|
||||
link_directories(${SNDFILE_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
# The st_audiofile library
|
||||
if (SFIZZ_USE_SNDFILE)
|
||||
set(ST_AUDIO_FILE_USE_SNDFILE ON CACHE BOOL "" FORCE)
|
||||
set(ST_AUDIO_FILE_EXTERNAL_SNDFILE "sfizz-sndfile" CACHE STRING "" FORCE)
|
||||
else()
|
||||
set(ST_AUDIO_FILE_USE_SNDFILE OFF CACHE BOOL "" FORCE)
|
||||
set(ST_AUDIO_FILE_EXTERNAL_SNDFILE "" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
add_subdirectory("external/st_audiofile" EXCLUDE_FROM_ALL)
|
||||
|
||||
# If we build with Clang, optionally use libc++. Enabled by default on Apple OS.
|
||||
cmake_dependent_option(USE_LIBCPP "Use libc++ with clang" "${APPLE}"
|
||||
|
|
@ -154,6 +164,7 @@ Build VST plug-in: ${SFIZZ_VST}
|
|||
Build AU plug-in: ${SFIZZ_AU}
|
||||
Build benchmarks: ${SFIZZ_BENCHMARKS}
|
||||
Build tests: ${SFIZZ_TESTS}
|
||||
Use sndfile: ${SFIZZ_USE_SNDFILE}
|
||||
Use vcpkg: ${SFIZZ_USE_VCPKG}
|
||||
Statically link dependencies: ${SFIZZ_STATIC_DEPENDENCIES}
|
||||
Link libatomic: ${SFIZZ_LINK_LIBATOMIC}
|
||||
|
|
|
|||
27
common.mk
27
common.mk
|
|
@ -4,6 +4,10 @@ ifndef SFIZZ_DIR
|
|||
$(error sfizz: The source directory must be set before including)
|
||||
endif
|
||||
|
||||
### Options
|
||||
|
||||
SFIZZ_USE_SNDFILE ?= 1
|
||||
|
||||
###
|
||||
|
||||
SFIZZ_MACHINE := $(shell $(CC) -dumpmachine)
|
||||
|
|
@ -125,13 +129,32 @@ SFIZZ_PKG_CONFIG ?= pkg-config
|
|||
|
||||
# Sndfile dependency
|
||||
|
||||
ifeq ($(SFIZZ_USE_SNDFILE),1)
|
||||
SFIZZ_SNDFILE_C_FLAGS ?= $(shell $(SFIZZ_PKG_CONFIG) --cflags sndfile)
|
||||
SFIZZ_SNDFILE_CXX_FLAGS ?= $(SFIZZ_SNDFILE_C_FLAGS)
|
||||
SFIZZ_SNDFILE_LINK_FLAGS ?= $(shell $(SFIZZ_PKG_CONFIG) --libs sndfile)
|
||||
endif
|
||||
|
||||
SFIZZ_C_FLAGS += $(SFIZZ_SNDFILE_C_FLAGS)
|
||||
SFIZZ_CXX_FLAGS += $(SFIZZ_SNDFILE_CXX_FLAGS)
|
||||
# st_audiofile dependency
|
||||
|
||||
SFIZZ_SOURCES += \
|
||||
$(SFIZZ_DIR)/external/st_audiofile/src/st_audiofile.c \
|
||||
$(SFIZZ_DIR)/external/st_audiofile/src/st_audiofile_common.c \
|
||||
$(SFIZZ_DIR)/external/st_audiofile/src/st_audiofile_libs.c \
|
||||
$(SFIZZ_DIR)/external/st_audiofile/src/st_audiofile_sndfile.c
|
||||
|
||||
SFIZZ_C_FLAGS += \
|
||||
-I$(SFIZZ_DIR)/external/st_audiofile/src \
|
||||
-I$(SFIZZ_DIR)/external/st_audiofile/thirdparty/dr_libs
|
||||
SFIZZ_CXX_FLAGS += \
|
||||
-I$(SFIZZ_DIR)/external/st_audiofile/src \
|
||||
-I$(SFIZZ_DIR)/external/st_audiofile/thirdparty/dr_libs
|
||||
|
||||
ifeq ($(SFIZZ_USE_SNDFILE),1)
|
||||
SFIZZ_C_FLAGS += $(SFIZZ_SNDFILE_C_FLAGS) -DST_AUDIO_FILE_USE_SNDFILE=1
|
||||
SFIZZ_CXX_FLAGS += $(SFIZZ_SNDFILE_CXX_FLAGS) -DST_AUDIO_FILE_USE_SNDFILE=1
|
||||
SFIZZ_LINK_FLAGS += $(SFIZZ_SNDFILE_LINK_FLAGS)
|
||||
endif
|
||||
|
||||
### Abseil dependency
|
||||
|
||||
|
|
|
|||
38
external/st_audiofile/CMakeLists.txt
vendored
Normal file
38
external/st_audiofile/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
cmake_minimum_required(VERSION 3.5)
|
||||
project(st_audiofile)
|
||||
|
||||
option(ST_AUDIO_FILE_USE_SNDFILE "Use sndfile" OFF)
|
||||
set(ST_AUDIO_FILE_EXTERNAL_SNDFILE "" CACHE STRING "Name of external sndfile target")
|
||||
|
||||
add_library(st_audiofile STATIC
|
||||
"src/st_audiofile.c"
|
||||
"src/st_audiofile_common.c"
|
||||
"src/st_audiofile_libs.c"
|
||||
"src/st_audiofile_sndfile.c")
|
||||
target_include_directories(st_audiofile
|
||||
PUBLIC "src"
|
||||
PUBLIC "thirdparty/dr_libs"
|
||||
PUBLIC "thirdparty/stb_vorbis")
|
||||
|
||||
add_executable(st_info
|
||||
"src/st_info.c")
|
||||
target_link_libraries(st_info
|
||||
PRIVATE st_audiofile)
|
||||
|
||||
if(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
target_compile_definitions(st_audiofile
|
||||
PUBLIC "ST_AUDIO_FILE_USE_SNDFILE=1")
|
||||
if(ST_AUDIO_FILE_EXTERNAL_SNDFILE)
|
||||
target_link_libraries(st_audiofile
|
||||
PUBLIC "${ST_AUDIO_FILE_EXTERNAL_SNDFILE}")
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(Sndfile "sndfile" REQUIRED)
|
||||
target_include_directories(st_audiofile
|
||||
PUBLIC ${Sndfile_INCLUDE_DIRS})
|
||||
target_link_libraries(st_audiofile
|
||||
PUBLIC ${Sndfile_LIBRARIES})
|
||||
link_directories(
|
||||
${Sndfile_LIBRARY_DIRS})
|
||||
endif()
|
||||
endif()
|
||||
25
external/st_audiofile/LICENSE.md
vendored
Normal file
25
external/st_audiofile/LICENSE.md
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2020, Jean-Pierre Cimalando
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
298
external/st_audiofile/src/st_audiofile.c
vendored
Normal file
298
external/st_audiofile/src/st_audiofile.c
vendored
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// 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
|
||||
|
||||
#include "st_audiofile.h"
|
||||
#if !defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
#include "st_audiofile_libs.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
struct st_audio_file {
|
||||
int type;
|
||||
union {
|
||||
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;
|
||||
};
|
||||
|
||||
enum {
|
||||
st_audio_file_null = -1,
|
||||
};
|
||||
|
||||
static st_audio_file* st_generic_open_file(const void* filename, int widepath)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
if (widepath)
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
st_audio_file* af = (st_audio_file*)malloc(sizeof(st_audio_file));
|
||||
if (!af)
|
||||
return NULL;
|
||||
|
||||
// Try WAV
|
||||
{
|
||||
af->wav = (drwav*)malloc(sizeof(drwav));
|
||||
if (!af->wav) {
|
||||
free(af);
|
||||
return NULL;
|
||||
}
|
||||
drwav_bool32 ok =
|
||||
#if defined(_WIN32)
|
||||
widepath ? drwav_init_file_w(af->wav, (const wchar_t*)filename, NULL) :
|
||||
#endif
|
||||
drwav_init_file(af->wav, (const char*)filename, NULL);
|
||||
if (!ok)
|
||||
free(af->wav);
|
||||
else {
|
||||
af->type = st_audio_file_wav;
|
||||
return af;
|
||||
}
|
||||
}
|
||||
|
||||
// Try FLAC
|
||||
{
|
||||
af->flac =
|
||||
#if defined(_WIN32)
|
||||
widepath ? drflac_open_file_w((const wchar_t*)filename, NULL) :
|
||||
#endif
|
||||
drflac_open_file((const char*)filename, NULL);
|
||||
if (af->flac) {
|
||||
af->type = st_audio_file_flac;
|
||||
return af;
|
||||
}
|
||||
}
|
||||
|
||||
// Try OGG
|
||||
{
|
||||
af->ogg =
|
||||
#if defined(_WIN32)
|
||||
widepath ? stb_vorbis_open_filename_w((const wchar_t*)filename, NULL, NULL) :
|
||||
#endif
|
||||
stb_vorbis_open_filename((const char*)filename, NULL, NULL);
|
||||
if (af->ogg) {
|
||||
af->cache.ogg.frames = stb_vorbis_stream_length_in_samples(af->ogg);
|
||||
if (af->cache.ogg.frames == 0) {
|
||||
stb_vorbis_close(af->ogg);
|
||||
free(af);
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
return af;
|
||||
}
|
||||
}
|
||||
|
||||
// Try MP3
|
||||
if (af->type == st_audio_file_null) {
|
||||
af->mp3 = (drmp3*)malloc(sizeof(drmp3));
|
||||
if (!af->mp3) {
|
||||
free(af);
|
||||
return NULL;
|
||||
}
|
||||
drmp3_bool32 ok =
|
||||
#if defined(_WIN32)
|
||||
widepath ? drmp3_init_file_w(af->mp3, (const wchar_t*)filename, NULL) :
|
||||
#endif
|
||||
drmp3_init_file(af->mp3, (const char*)filename, NULL);
|
||||
if (!ok)
|
||||
free(af->mp3);
|
||||
else {
|
||||
af->cache.mp3.frames = drmp3_get_pcm_frame_count(af->mp3);
|
||||
if (af->cache.mp3.frames == 0) {
|
||||
free(af->mp3);
|
||||
free(af);
|
||||
return NULL;
|
||||
}
|
||||
af->type = st_audio_file_mp3;
|
||||
return af;
|
||||
}
|
||||
}
|
||||
|
||||
free(af);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
st_audio_file* st_open_file(const char* filename)
|
||||
{
|
||||
return st_generic_open_file(filename, 0);
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
st_audio_file* st_open_file_w(const wchar_t* filename)
|
||||
{
|
||||
return st_generic_open_file(filename, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void st_close(st_audio_file* af)
|
||||
{
|
||||
switch (af->type) {
|
||||
case st_audio_file_wav:
|
||||
drwav_uninit(af->wav);
|
||||
free(af->wav);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
af->type = st_audio_file_null;
|
||||
}
|
||||
|
||||
int st_get_type(st_audio_file* af)
|
||||
{
|
||||
return af->type;
|
||||
}
|
||||
|
||||
uint32_t st_get_channels(st_audio_file* af)
|
||||
{
|
||||
uint32_t channels = 0;
|
||||
|
||||
switch (af->type) {
|
||||
case st_audio_file_wav:
|
||||
channels = af->wav->channels;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
return channels;
|
||||
}
|
||||
|
||||
float st_get_sample_rate(st_audio_file* af)
|
||||
{
|
||||
float sample_rate = 0;
|
||||
|
||||
switch (af->type) {
|
||||
case st_audio_file_wav:
|
||||
sample_rate = af->wav->sampleRate;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
return sample_rate;
|
||||
}
|
||||
|
||||
uint64_t st_get_frame_count(st_audio_file* af)
|
||||
{
|
||||
uint64_t frames = 0;
|
||||
|
||||
switch (af->type) {
|
||||
case st_audio_file_wav:
|
||||
frames = af->wav->totalPCMFrameCount;
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
return frames;
|
||||
}
|
||||
|
||||
bool st_seek(st_audio_file* af, uint64_t frame)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
switch (af->type) {
|
||||
case st_audio_file_wav:
|
||||
success = drwav_seek_to_pcm_frame(af->wav, frame);
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
uint64_t st_read_s16(st_audio_file* af, int16_t* buffer, uint64_t count)
|
||||
{
|
||||
switch (af->type) {
|
||||
case st_audio_file_wav:
|
||||
count = drwav_read_pcm_frames_s16(af->wav, count, buffer);
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
uint64_t st_read_f32(st_audio_file* af, float* buffer, uint64_t count)
|
||||
{
|
||||
switch (af->type) {
|
||||
case st_audio_file_wav:
|
||||
count = drwav_read_pcm_frames_f32(af->wav, count, buffer);
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif // !defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
53
external/st_audiofile/src/st_audiofile.h
vendored
Normal file
53
external/st_audiofile/src/st_audiofile.h
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// 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
|
||||
|
||||
#pragma once
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
#include <sndfile.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#if defined(_WIN32)
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
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_ogg,
|
||||
st_audio_file_mp3,
|
||||
st_audio_file_other,
|
||||
} st_audio_file_type;
|
||||
|
||||
st_audio_file* st_open_file(const char* filename);
|
||||
#if defined(_WIN32)
|
||||
st_audio_file* st_open_file_w(const wchar_t* filename);
|
||||
#endif
|
||||
void st_close(st_audio_file* af);
|
||||
int st_get_type(st_audio_file* af);
|
||||
const char* st_get_type_string(st_audio_file* af);
|
||||
const char* st_type_string(int type);
|
||||
uint32_t st_get_channels(st_audio_file* af);
|
||||
float st_get_sample_rate(st_audio_file* af);
|
||||
uint64_t st_get_frame_count(st_audio_file* af);
|
||||
bool st_seek(st_audio_file* af, uint64_t frame);
|
||||
uint64_t st_read_s16(st_audio_file* af, int16_t* buffer, uint64_t count);
|
||||
uint64_t st_read_f32(st_audio_file* af, float* buffer, uint64_t count);
|
||||
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
SNDFILE* st_get_sndfile_handle(st_audio_file* af);
|
||||
int st_get_sndfile_format(st_audio_file* af);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
168
external/st_audiofile/src/st_audiofile.hpp
vendored
Normal file
168
external/st_audiofile/src/st_audiofile.hpp
vendored
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// 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
|
||||
|
||||
#pragma once
|
||||
#include "st_audiofile.h"
|
||||
|
||||
class ST_AudioFile {
|
||||
public:
|
||||
constexpr ST_AudioFile() noexcept;
|
||||
~ST_AudioFile() noexcept;
|
||||
|
||||
ST_AudioFile(ST_AudioFile&&) noexcept;
|
||||
ST_AudioFile& operator=(ST_AudioFile&&) noexcept;
|
||||
|
||||
ST_AudioFile(const ST_AudioFile&) = delete;
|
||||
ST_AudioFile& operator=(const ST_AudioFile&) = delete;
|
||||
|
||||
explicit operator bool() const noexcept;
|
||||
void reset(st_audio_file* new_af = nullptr) noexcept;
|
||||
|
||||
bool open_file(const char* filename);
|
||||
#if defined(_WIN32)
|
||||
bool open_file_w(const wchar_t* filename);
|
||||
#endif
|
||||
|
||||
int get_type() const noexcept;
|
||||
const char* get_type_string() const noexcept;
|
||||
static const char* type_string(int type) noexcept;
|
||||
uint32_t get_channels() const noexcept;
|
||||
float get_sample_rate() const noexcept;
|
||||
uint64_t get_frame_count() const noexcept;
|
||||
|
||||
bool seek(uint64_t frame) noexcept;
|
||||
uint64_t read_s16(int16_t* buffer, uint64_t count) noexcept;
|
||||
uint64_t read_f32(float* buffer, uint64_t count) noexcept;
|
||||
|
||||
st_audio_file* get_handle() const noexcept;
|
||||
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
void* get_sndfile_handle() const noexcept;
|
||||
int get_sndfile_format() const noexcept;
|
||||
#endif
|
||||
|
||||
private:
|
||||
st_audio_file* af_ = nullptr;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
inline constexpr ST_AudioFile::ST_AudioFile() noexcept
|
||||
{
|
||||
}
|
||||
|
||||
inline ST_AudioFile::~ST_AudioFile() noexcept
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
ST_AudioFile::ST_AudioFile(ST_AudioFile&& other) noexcept
|
||||
: af_(other.af_)
|
||||
{
|
||||
other.af_ = nullptr;
|
||||
}
|
||||
|
||||
ST_AudioFile& ST_AudioFile::operator=(ST_AudioFile&& other) noexcept
|
||||
{
|
||||
if (this != &other) {
|
||||
if (af_)
|
||||
st_close(af_);
|
||||
af_ = other.af_;
|
||||
other.af_ = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline ST_AudioFile::operator bool() const noexcept
|
||||
{
|
||||
return af_ != nullptr;
|
||||
}
|
||||
|
||||
inline void ST_AudioFile::reset(st_audio_file* new_af) noexcept
|
||||
{
|
||||
if (af_ != new_af) {
|
||||
if (af_)
|
||||
st_close(af_);
|
||||
af_ = new_af;
|
||||
}
|
||||
}
|
||||
|
||||
bool ST_AudioFile::open_file(const char* filename)
|
||||
{
|
||||
st_audio_file* new_af = st_open_file(filename);
|
||||
reset(new_af);
|
||||
return new_af != nullptr;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
inline bool ST_AudioFile::open_file_w(const wchar_t* filename)
|
||||
{
|
||||
st_audio_file* new_af = st_open_file_w(filename);
|
||||
reset(new_af);
|
||||
return new_af != nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline int ST_AudioFile::get_type() const noexcept
|
||||
{
|
||||
return st_get_type(af_);
|
||||
}
|
||||
|
||||
inline const char* ST_AudioFile::get_type_string() const noexcept
|
||||
{
|
||||
return st_get_type_string(af_);
|
||||
}
|
||||
|
||||
inline const char* ST_AudioFile::type_string(int type) noexcept
|
||||
{
|
||||
return st_type_string(type);
|
||||
}
|
||||
|
||||
inline uint32_t ST_AudioFile::get_channels() const noexcept
|
||||
{
|
||||
return st_get_channels(af_);
|
||||
}
|
||||
|
||||
inline float ST_AudioFile::get_sample_rate() const noexcept
|
||||
{
|
||||
return st_get_sample_rate(af_);
|
||||
}
|
||||
|
||||
inline uint64_t ST_AudioFile::get_frame_count() const noexcept
|
||||
{
|
||||
return st_get_frame_count(af_);
|
||||
}
|
||||
|
||||
inline bool ST_AudioFile::seek(uint64_t frame) noexcept
|
||||
{
|
||||
return st_seek(af_, frame);
|
||||
}
|
||||
|
||||
inline uint64_t ST_AudioFile::read_s16(int16_t* buffer, uint64_t count) noexcept
|
||||
{
|
||||
return st_read_s16(af_, buffer, count);
|
||||
}
|
||||
|
||||
inline uint64_t ST_AudioFile::read_f32(float* buffer, uint64_t count) noexcept
|
||||
{
|
||||
return st_read_f32(af_, buffer, count);
|
||||
}
|
||||
|
||||
inline st_audio_file* ST_AudioFile::get_handle() const noexcept
|
||||
{
|
||||
return af_;
|
||||
}
|
||||
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
inline void* ST_AudioFile::get_sndfile_handle() const noexcept
|
||||
{
|
||||
return st_get_sndfile_handle(af_);
|
||||
}
|
||||
|
||||
int ST_AudioFile::get_sndfile_format() const noexcept
|
||||
{
|
||||
return st_get_sndfile_format(af_);
|
||||
}
|
||||
#endif
|
||||
38
external/st_audiofile/src/st_audiofile_common.c
vendored
Normal file
38
external/st_audiofile/src/st_audiofile_common.c
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// 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
|
||||
|
||||
#include "st_audiofile.h"
|
||||
#include <stddef.h>
|
||||
|
||||
const char* st_get_type_string(st_audio_file* af)
|
||||
{
|
||||
return st_type_string(st_get_type(af));
|
||||
}
|
||||
|
||||
const char* st_type_string(int type)
|
||||
{
|
||||
const char *type_string = NULL;
|
||||
|
||||
switch (type) {
|
||||
case st_audio_file_wav:
|
||||
type_string = "WAV";
|
||||
break;
|
||||
case st_audio_file_flac:
|
||||
type_string = "FLAC";
|
||||
break;
|
||||
case st_audio_file_ogg:
|
||||
type_string = "OGG";
|
||||
break;
|
||||
case st_audio_file_mp3:
|
||||
type_string = "MP3";
|
||||
break;
|
||||
case st_audio_file_other:
|
||||
type_string = "other";
|
||||
break;
|
||||
}
|
||||
|
||||
return type_string;
|
||||
}
|
||||
29
external/st_audiofile/src/st_audiofile_libs.c
vendored
Normal file
29
external/st_audiofile/src/st_audiofile_libs.c
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// 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
|
||||
|
||||
#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
|
||||
21
external/st_audiofile/src/st_audiofile_libs.h
vendored
Normal file
21
external/st_audiofile/src/st_audiofile_libs.h
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// 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
|
||||
|
||||
#pragma once
|
||||
#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 <wchar.h>
|
||||
stb_vorbis* stb_vorbis_open_filename_w(const wchar_t* filename, int* error, const stb_vorbis_alloc* alloc);
|
||||
#endif
|
||||
120
external/st_audiofile/src/st_audiofile_sndfile.c
vendored
Normal file
120
external/st_audiofile/src/st_audiofile_sndfile.c
vendored
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// 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
|
||||
|
||||
#include "st_audiofile.h"
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
|
||||
#endif
|
||||
#include <sndfile.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct st_audio_file {
|
||||
SNDFILE* snd;
|
||||
SF_INFO info;
|
||||
};
|
||||
|
||||
st_audio_file* st_open_file(const char* filename)
|
||||
{
|
||||
st_audio_file* af = (st_audio_file*)malloc(sizeof(st_audio_file));
|
||||
if (!af)
|
||||
return NULL;
|
||||
|
||||
af->snd = sf_open(filename, SFM_READ, &af->info);
|
||||
if (!af->snd) {
|
||||
free(af);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return af;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
st_audio_file* st_open_file_w(const wchar_t* filename)
|
||||
{
|
||||
st_audio_file* af = (st_audio_file*)malloc(sizeof(st_audio_file));
|
||||
if (!af)
|
||||
return NULL;
|
||||
|
||||
af->snd = sf_wchar_open(filename, SFM_READ, &af->info);
|
||||
if (!af->snd) {
|
||||
free(af);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return af;
|
||||
}
|
||||
#endif
|
||||
|
||||
void st_close(st_audio_file* af)
|
||||
{
|
||||
if (af->snd) {
|
||||
sf_close(af->snd);
|
||||
af->snd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int st_get_type(st_audio_file* af)
|
||||
{
|
||||
int type = st_audio_file_other;
|
||||
|
||||
switch (af->info.format & SF_FORMAT_TYPEMASK) {
|
||||
case SF_FORMAT_WAV:
|
||||
type = st_audio_file_wav;
|
||||
break;
|
||||
case SF_FORMAT_FLAC:
|
||||
type = st_audio_file_flac;
|
||||
break;
|
||||
case SF_FORMAT_OGG:
|
||||
type = st_audio_file_ogg;
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
uint32_t st_get_channels(st_audio_file* af)
|
||||
{
|
||||
return af->info.channels;
|
||||
}
|
||||
|
||||
float st_get_sample_rate(st_audio_file* af)
|
||||
{
|
||||
return af->info.samplerate;
|
||||
}
|
||||
|
||||
uint64_t st_get_frame_count(st_audio_file* af)
|
||||
{
|
||||
return af->info.frames;
|
||||
}
|
||||
|
||||
bool st_seek(st_audio_file* af, uint64_t frame)
|
||||
{
|
||||
return sf_seek(af->snd, frame, SEEK_SET) != -1;
|
||||
}
|
||||
|
||||
uint64_t st_read_s16(st_audio_file* af, int16_t* buffer, uint64_t count)
|
||||
{
|
||||
return sf_readf_short(af->snd, buffer, count);
|
||||
}
|
||||
|
||||
uint64_t st_read_f32(st_audio_file* af, float* buffer, uint64_t count)
|
||||
{
|
||||
return sf_readf_float(af->snd, buffer, count);
|
||||
}
|
||||
|
||||
SNDFILE* st_get_sndfile_handle(st_audio_file* af)
|
||||
{
|
||||
return af->snd;
|
||||
}
|
||||
|
||||
int st_get_sndfile_format(st_audio_file* af)
|
||||
{
|
||||
return af->info.format;
|
||||
}
|
||||
|
||||
#endif // defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
33
external/st_audiofile/src/st_info.c
vendored
Normal file
33
external/st_audiofile/src/st_info.c
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||
// 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
|
||||
|
||||
#include "st_audiofile.h"
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Please indicate a sound file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* filename = argv[1];
|
||||
|
||||
st_audio_file* af = st_open_file(filename);
|
||||
if (!af) {
|
||||
fprintf(stderr, "Could not open the sound file.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("File name : %s\n", filename);
|
||||
printf("File type : %s\n", st_get_type_string(af));
|
||||
printf("Channels : %u\n", st_get_channels(af));
|
||||
printf("Sample rate : %f\n", st_get_sample_rate(af));
|
||||
printf("Frames : %" PRIu64 "\n", st_get_frame_count(af));
|
||||
|
||||
return 0;
|
||||
}
|
||||
1
external/st_audiofile/thirdparty/dr_libs
vendored
Submodule
1
external/st_audiofile/thirdparty/dr_libs
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit cac1785cee4abb455817b43d5dee33b49d61be2f
|
||||
1
external/st_audiofile/thirdparty/stb_vorbis
vendored
Submodule
1
external/st_audiofile/thirdparty/stb_vorbis
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit fc0bd698b26888da0a632da33f4c49b90763e69b
|
||||
1
rack.mk
1
rack.mk
|
|
@ -29,6 +29,7 @@
|
|||
#
|
||||
# SFIZZ_RACK_PLUGIN_DIR = <the root directory of the Rack plugin>
|
||||
# SFIZZ_PKG_CONFIG = <a custom pkg-config command>
|
||||
# SFIZZ_USE_SNDFILE = <0 disabled, 1 enabled (default)>
|
||||
# SFIZZ_SNDFILE_C_FLAGS = <compiler flags of sndfile for C>
|
||||
# SFIZZ_SNDFILE_CXX_FLAGS = <compiler flags of sndfile for C++>
|
||||
# SFIZZ_SNDFILE_LINK_FLAGS = <linker flags of sndfile>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ clang-tidy \
|
|||
vst/SfizzVstEditor.cpp \
|
||||
vst/SfizzVstState.cpp \
|
||||
-- -Iexternal/abseil-cpp -Iexternal/jsl/include -Isrc/external -Isrc/external/pugixml/src \
|
||||
-Iexternal/st_audiofile/src -Iexternal/st_audiofile/thirdparty/dr_libs \
|
||||
-Isrc/sfizz -Isrc -Isrc/external/spline -Isrc/external/cpuid/src \
|
||||
-Ivst -Ivst/external/VST_SDK/VST3_SDK -Ivst/external/VST_SDK/VST3_SDK/vstgui4 -Ivst/external/ring_buffer \
|
||||
-Ieditor/src \
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ target_sources(sfizz_static PRIVATE
|
|||
target_include_directories (sfizz_static PUBLIC .)
|
||||
target_include_directories (sfizz_static PUBLIC external)
|
||||
target_link_libraries (sfizz_static PUBLIC absl::strings absl::span)
|
||||
target_link_libraries (sfizz_static PRIVATE sfizz_parser absl::flat_hash_map Threads::Threads sfizz-sndfile sfizz-pugixml sfizz-spline sfizz-tunings sfizz-kissfft sfizz-cpuid sfizz-jsl sfizz-atomic)
|
||||
target_link_libraries (sfizz_static PRIVATE sfizz_parser absl::flat_hash_map Threads::Threads st_audiofile sfizz-pugixml sfizz-spline sfizz-tunings sfizz-kissfft sfizz-cpuid sfizz-jsl sfizz-atomic)
|
||||
set_target_properties (sfizz_static PROPERTIES OUTPUT_NAME sfizz PUBLIC_HEADER "sfizz.h;sfizz.hpp")
|
||||
if (WIN32)
|
||||
target_compile_definitions (sfizz_static PRIVATE _USE_MATH_DEFINES)
|
||||
|
|
@ -245,7 +245,7 @@ if (SFIZZ_SHARED)
|
|||
${SFIZZ_HEADERS} ${SFIZZ_SOURCES} ${FAUST_FILES} sfizz/sfizz_wrapper.cpp sfizz/sfizz.cpp)
|
||||
target_include_directories (sfizz_shared PRIVATE .)
|
||||
target_include_directories (sfizz_shared PRIVATE external)
|
||||
target_link_libraries (sfizz_shared PRIVATE absl::strings absl::span sfizz_parser absl::flat_hash_map Threads::Threads sfizz-sndfile sfizz-pugixml sfizz-spline sfizz-tunings sfizz-kissfft sfizz-cpuid sfizz-jsl sfizz-atomic)
|
||||
target_link_libraries (sfizz_shared PRIVATE absl::strings absl::span sfizz_parser absl::flat_hash_map Threads::Threads st_audiofile sfizz-pugixml sfizz-spline sfizz-tunings sfizz-kissfft sfizz-cpuid sfizz-jsl sfizz-atomic)
|
||||
if (WIN32)
|
||||
target_compile_definitions (sfizz_shared PRIVATE _USE_MATH_DEFINES)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -5,51 +5,60 @@
|
|||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#include "AudioReader.h"
|
||||
#include <sndfile.hh>
|
||||
#include "FileMetadata.h"
|
||||
#include <st_audiofile.hpp>
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
#include <sndfile.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
|
||||
namespace sfz {
|
||||
|
||||
class BasicSndfileReader : public AudioReader {
|
||||
public:
|
||||
explicit BasicSndfileReader(SndfileHandle handle) : handle_(handle) {}
|
||||
explicit BasicSndfileReader(ST_AudioFile handle) : handle_(std::move(handle)) {}
|
||||
virtual ~BasicSndfileReader() {}
|
||||
|
||||
int format() const override;
|
||||
int64_t frames() const override;
|
||||
unsigned channels() const override;
|
||||
unsigned sampleRate() const override;
|
||||
bool getInstrument(SF_INSTRUMENT* instrument) override;
|
||||
bool getInstrument(InstrumentInfo* instrument) override;
|
||||
|
||||
protected:
|
||||
SndfileHandle handle_;
|
||||
ST_AudioFile handle_;
|
||||
};
|
||||
|
||||
int BasicSndfileReader::format() const
|
||||
{
|
||||
return handle_.format();
|
||||
return handle_.get_type();
|
||||
}
|
||||
|
||||
int64_t BasicSndfileReader::frames() const
|
||||
{
|
||||
return handle_.frames();
|
||||
return handle_.get_frame_count();
|
||||
}
|
||||
|
||||
unsigned BasicSndfileReader::channels() const
|
||||
{
|
||||
return handle_.channels();
|
||||
return handle_.get_channels();
|
||||
}
|
||||
|
||||
unsigned BasicSndfileReader::sampleRate() const
|
||||
{
|
||||
return handle_.samplerate();
|
||||
return handle_.get_sample_rate();
|
||||
}
|
||||
|
||||
bool BasicSndfileReader::getInstrument(SF_INSTRUMENT* instrument)
|
||||
bool BasicSndfileReader::getInstrument(InstrumentInfo* instrument)
|
||||
{
|
||||
if (handle_.command(SFC_GET_INSTRUMENT, instrument, sizeof(SF_INSTRUMENT)) == SF_FALSE)
|
||||
return false;
|
||||
return true;
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
SNDFILE* sndfile = reinterpret_cast<SNDFILE*>(handle_.get_sndfile_handle());
|
||||
if (sf_command(sndfile, SFC_GET_INSTRUMENT, &instrument, sizeof(instrument)) == SF_TRUE)
|
||||
return true;
|
||||
#else
|
||||
(void)instrument;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -59,13 +68,13 @@ bool BasicSndfileReader::getInstrument(SF_INSTRUMENT* instrument)
|
|||
*/
|
||||
class ForwardReader : public BasicSndfileReader {
|
||||
public:
|
||||
explicit ForwardReader(SndfileHandle handle);
|
||||
explicit ForwardReader(ST_AudioFile handle);
|
||||
AudioReaderType type() const override;
|
||||
size_t readNextBlock(float* buffer, size_t frames) override;
|
||||
};
|
||||
|
||||
ForwardReader::ForwardReader(SndfileHandle handle)
|
||||
: BasicSndfileReader(handle)
|
||||
ForwardReader::ForwardReader(ST_AudioFile handle)
|
||||
: BasicSndfileReader(std::move(handle))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -76,7 +85,7 @@ AudioReaderType ForwardReader::type() const
|
|||
|
||||
size_t ForwardReader::readNextBlock(float* buffer, size_t frames)
|
||||
{
|
||||
sf_count_t readFrames = handle_.readf(buffer, frames);
|
||||
uint64_t readFrames = handle_.read_f32(buffer, frames);
|
||||
if (frames <= 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -93,7 +102,7 @@ struct AudioFrame {
|
|||
/**
|
||||
* @brief Reorder a sequence of frames in reverse
|
||||
*/
|
||||
static void reverse_frames(float* data, sf_count_t frames, unsigned channels)
|
||||
static void reverse_frames(float* data, size_t frames, unsigned channels)
|
||||
{
|
||||
switch (channels) {
|
||||
|
||||
|
|
@ -108,8 +117,8 @@ static void reverse_frames(float* data, sf_count_t frames, unsigned channels)
|
|||
SPECIALIZE_FOR(2);
|
||||
|
||||
default:
|
||||
for (sf_count_t i = 0; i < frames / 2; ++i) {
|
||||
sf_count_t j = frames - 1 - i;
|
||||
for (size_t i = 0; i < frames / 2; ++i) {
|
||||
size_t j = frames - 1 - i;
|
||||
float* frame1 = &data[i * channels];
|
||||
float* frame2 = &data[j * channels];
|
||||
for (unsigned c = 0; c < channels; ++c)
|
||||
|
|
@ -128,18 +137,18 @@ static void reverse_frames(float* data, sf_count_t frames, unsigned channels)
|
|||
*/
|
||||
class ReverseReader : public BasicSndfileReader {
|
||||
public:
|
||||
explicit ReverseReader(SndfileHandle handle);
|
||||
explicit ReverseReader(ST_AudioFile handle);
|
||||
AudioReaderType type() const override;
|
||||
size_t readNextBlock(float* buffer, size_t frames) override;
|
||||
|
||||
private:
|
||||
sf_count_t position_ {};
|
||||
uint64_t position_ {};
|
||||
};
|
||||
|
||||
ReverseReader::ReverseReader(SndfileHandle handle)
|
||||
: BasicSndfileReader(handle)
|
||||
ReverseReader::ReverseReader(ST_AudioFile handle)
|
||||
: BasicSndfileReader(std::move(handle))
|
||||
{
|
||||
position_ = handle.seek(0, SEEK_END);
|
||||
position_ = handle_.get_frame_count();
|
||||
}
|
||||
|
||||
AudioReaderType ReverseReader::type() const
|
||||
|
|
@ -149,16 +158,16 @@ AudioReaderType ReverseReader::type() const
|
|||
|
||||
size_t ReverseReader::readNextBlock(float* buffer, size_t frames)
|
||||
{
|
||||
sf_count_t position = position_;
|
||||
const unsigned channels = handle_.channels();
|
||||
uint64_t position = position_;
|
||||
const unsigned channels = handle_.get_channels();
|
||||
|
||||
const sf_count_t readFrames = std::min<sf_count_t>(frames, position);
|
||||
const uint64_t readFrames = std::min<uint64_t>(frames, position);
|
||||
if (readFrames <= 0)
|
||||
return false;
|
||||
|
||||
position -= readFrames;
|
||||
if (handle_.seek(position, SEEK_SET) != position ||
|
||||
handle_.readf(buffer, readFrames) != readFrames)
|
||||
if (!handle_.seek(position) ||
|
||||
handle_.read_f32(buffer, readFrames) != readFrames)
|
||||
return false;
|
||||
|
||||
position_ = position;
|
||||
|
|
@ -173,7 +182,7 @@ size_t ReverseReader::readNextBlock(float* buffer, size_t frames)
|
|||
*/
|
||||
class NoSeekReverseReader : public BasicSndfileReader {
|
||||
public:
|
||||
explicit NoSeekReverseReader(SndfileHandle handle);
|
||||
explicit NoSeekReverseReader(ST_AudioFile handle);
|
||||
AudioReaderType type() const override;
|
||||
size_t readNextBlock(float* buffer, size_t frames) override;
|
||||
|
||||
|
|
@ -182,11 +191,11 @@ private:
|
|||
|
||||
private:
|
||||
std::unique_ptr<float[]> fileBuffer_;
|
||||
sf_count_t fileFramesLeft_ { 0 };
|
||||
uint64_t fileFramesLeft_ { 0 };
|
||||
};
|
||||
|
||||
NoSeekReverseReader::NoSeekReverseReader(SndfileHandle handle)
|
||||
: BasicSndfileReader(handle)
|
||||
NoSeekReverseReader::NoSeekReverseReader(ST_AudioFile handle)
|
||||
: BasicSndfileReader(std::move(handle))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -203,9 +212,9 @@ size_t NoSeekReverseReader::readNextBlock(float* buffer, size_t frames)
|
|||
fileBuffer = fileBuffer_.get();
|
||||
}
|
||||
|
||||
const unsigned channels = handle_.channels();
|
||||
const sf_count_t fileFramesLeft = fileFramesLeft_;
|
||||
sf_count_t readFrames = std::min<sf_count_t>(frames, fileFramesLeft);
|
||||
const unsigned channels = handle_.get_channels();
|
||||
const uint64_t fileFramesLeft = fileFramesLeft_;
|
||||
uint64_t readFrames = std::min<uint64_t>(frames, fileFramesLeft);
|
||||
if (readFrames <= 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -220,15 +229,16 @@ size_t NoSeekReverseReader::readNextBlock(float* buffer, size_t frames)
|
|||
|
||||
void NoSeekReverseReader::readWholeFile()
|
||||
{
|
||||
const sf_count_t frames = handle_.frames();
|
||||
const unsigned channels = handle_.channels();
|
||||
const uint64_t frames = handle_.get_frame_count();
|
||||
const unsigned channels = handle_.get_channels();
|
||||
float* fileBuffer = new float[channels * frames];
|
||||
fileBuffer_.reset(fileBuffer);
|
||||
fileFramesLeft_ = handle_.readf(fileBuffer, frames);
|
||||
fileFramesLeft_ = handle_.read_f32(fileBuffer, frames);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
const std::error_category& sndfile_category()
|
||||
{
|
||||
class sndfile_category : public std::error_category {
|
||||
|
|
@ -248,6 +258,26 @@ const std::error_category& sndfile_category()
|
|||
static const sndfile_category cat;
|
||||
return cat;
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::error_category& undetailed_category()
|
||||
{
|
||||
class undetailed_category : public std::error_category {
|
||||
public:
|
||||
const char* name() const noexcept override
|
||||
{
|
||||
return "undetailed";
|
||||
}
|
||||
|
||||
std::string message(int condition) const override
|
||||
{
|
||||
return (condition == 0) ? "success" : "failure";
|
||||
}
|
||||
};
|
||||
|
||||
static const undetailed_category cat;
|
||||
return cat;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -260,7 +290,7 @@ public:
|
|||
unsigned channels() const override { return 1; }
|
||||
unsigned sampleRate() const override { return 44100; }
|
||||
size_t readNextBlock(float*, size_t) override { return 0; }
|
||||
bool getInstrument(SF_INSTRUMENT* ) override { return false; }
|
||||
bool getInstrument(InstrumentInfo* ) override { return false; }
|
||||
|
||||
private:
|
||||
AudioReaderType type_ {};
|
||||
|
|
@ -268,6 +298,7 @@ private:
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
static bool formatHasFastSeeking(int format)
|
||||
{
|
||||
bool fast;
|
||||
|
|
@ -300,8 +331,9 @@ static bool formatHasFastSeeking(int format)
|
|||
|
||||
return fast;
|
||||
}
|
||||
#endif
|
||||
|
||||
static AudioReaderPtr createAudioReaderWithHandle(SndfileHandle handle, bool reverse, std::error_code* ec)
|
||||
static AudioReaderPtr createAudioReaderWithHandle(ST_AudioFile handle, bool reverse, std::error_code* ec)
|
||||
{
|
||||
AudioReaderPtr reader;
|
||||
|
||||
|
|
@ -310,30 +342,38 @@ static AudioReaderPtr createAudioReaderWithHandle(SndfileHandle handle, bool rev
|
|||
|
||||
if (!handle) {
|
||||
if (ec)
|
||||
*ec = std::error_code(handle.error(), sndfile_category());
|
||||
*ec = std::error_code(1, undetailed_category());
|
||||
reader.reset(new DummyAudioReader(reverse ? AudioReaderType::Reverse : AudioReaderType::Forward));
|
||||
}
|
||||
else if (!reverse)
|
||||
reader.reset(new ForwardReader(handle));
|
||||
else if (formatHasFastSeeking(handle.format()))
|
||||
reader.reset(new ReverseReader(handle));
|
||||
else
|
||||
reader.reset(new NoSeekReverseReader(handle));
|
||||
reader.reset(new ForwardReader(std::move(handle)));
|
||||
else {
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
bool hasFastSeeking = formatHasFastSeeking(handle.get_sndfile_format());
|
||||
#else
|
||||
bool hasFastSeeking = true;
|
||||
#endif
|
||||
if (hasFastSeeking)
|
||||
reader.reset(new ReverseReader(std::move(handle)));
|
||||
else
|
||||
reader.reset(new NoSeekReverseReader(std::move(handle)));
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
AudioReaderPtr createAudioReader(const fs::path& path, bool reverse, std::error_code* ec)
|
||||
{
|
||||
ST_AudioFile handle;
|
||||
#if defined(_WIN32)
|
||||
SndfileHandle handle(path.wstring().c_str());
|
||||
handle.open_file_w(path.wstring().c_str());
|
||||
#else
|
||||
SndfileHandle handle(path.c_str());
|
||||
handle.open_file(path.c_str());
|
||||
#endif
|
||||
return createAudioReaderWithHandle(handle, reverse, ec);
|
||||
return createAudioReaderWithHandle(std::move(handle), reverse, ec);
|
||||
}
|
||||
|
||||
static AudioReaderPtr createExplicitAudioReaderWithHandle(SndfileHandle handle, AudioReaderType type, std::error_code* ec)
|
||||
static AudioReaderPtr createExplicitAudioReaderWithHandle(ST_AudioFile handle, AudioReaderType type, std::error_code* ec)
|
||||
{
|
||||
AudioReaderPtr reader;
|
||||
|
||||
|
|
@ -342,19 +382,19 @@ static AudioReaderPtr createExplicitAudioReaderWithHandle(SndfileHandle handle,
|
|||
|
||||
if (!handle) {
|
||||
if (ec)
|
||||
*ec = std::error_code(handle.error(), sndfile_category());
|
||||
*ec = std::error_code(1, undetailed_category());
|
||||
reader.reset(new DummyAudioReader(type));
|
||||
}
|
||||
else {
|
||||
switch (type) {
|
||||
case AudioReaderType::Forward:
|
||||
reader.reset(new ForwardReader(handle));
|
||||
reader.reset(new ForwardReader(std::move(handle)));
|
||||
break;
|
||||
case AudioReaderType::Reverse:
|
||||
reader.reset(new ReverseReader(handle));
|
||||
reader.reset(new ReverseReader(std::move(handle)));
|
||||
break;
|
||||
case AudioReaderType::NoSeekReverse:
|
||||
reader.reset(new NoSeekReverseReader(handle));
|
||||
reader.reset(new NoSeekReverseReader(std::move(handle)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -364,12 +404,13 @@ static AudioReaderPtr createExplicitAudioReaderWithHandle(SndfileHandle handle,
|
|||
|
||||
AudioReaderPtr createExplicitAudioReader(const fs::path& path, AudioReaderType type, std::error_code* ec)
|
||||
{
|
||||
ST_AudioFile handle;
|
||||
#if defined(_WIN32)
|
||||
SndfileHandle handle(path.wstring().c_str());
|
||||
handle.open_file_w(path.wstring().c_str());
|
||||
#else
|
||||
SndfileHandle handle(path.c_str());
|
||||
handle.open_file(path.c_str());
|
||||
#endif
|
||||
return createExplicitAudioReaderWithHandle(handle, type, ec);
|
||||
return createExplicitAudioReaderWithHandle(std::move(handle), type, ec);
|
||||
}
|
||||
|
||||
} // namespace sfz
|
||||
|
|
|
|||
|
|
@ -7,16 +7,13 @@
|
|||
#pragma once
|
||||
#include "absl/types/span.h"
|
||||
#include "ghc/fs_std.hpp"
|
||||
#include <st_audiofile.h>
|
||||
#include <system_error>
|
||||
#include <memory>
|
||||
#include <cstdio>
|
||||
#if defined(_WIN32)
|
||||
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <sndfile.h>
|
||||
|
||||
namespace sfz {
|
||||
struct InstrumentInfo;
|
||||
|
||||
/**
|
||||
* @brief Designation of a particular kind of audio reader
|
||||
|
|
@ -42,7 +39,7 @@ public:
|
|||
virtual unsigned channels() const = 0;
|
||||
virtual unsigned sampleRate() const = 0;
|
||||
virtual size_t readNextBlock(float* buffer, size_t frames) = 0;
|
||||
virtual bool getInstrument(SF_INSTRUMENT* instrument) = 0;
|
||||
virtual bool getInstrument(InstrumentInfo* instrument) = 0;
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<AudioReader> AudioReaderPtr;
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ size_t FileMetadataReader::Impl::readRiffData(size_t index, void* buffer, size_t
|
|||
return fread(buffer, 1, count, stream);
|
||||
}
|
||||
|
||||
bool FileMetadataReader::extractRiffInstrument(SF_INSTRUMENT& ins)
|
||||
bool FileMetadataReader::extractRiffInstrument(InstrumentInfo& ins)
|
||||
{
|
||||
const RiffChunkInfo* riff = riffChunkById(RiffChunkId{'s', 'm', 'p', 'l'});
|
||||
if (!riff)
|
||||
|
|
@ -278,16 +278,16 @@ bool FileMetadataReader::extractRiffInstrument(SF_INSTRUMENT& ins)
|
|||
|
||||
switch (extractU32(loopOffset + 0x04)) {
|
||||
default:
|
||||
ins.loops[i].mode = SF_LOOP_NONE;
|
||||
ins.loops[i].mode = LoopNone;
|
||||
break;
|
||||
case 0:
|
||||
ins.loops[i].mode = SF_LOOP_FORWARD;
|
||||
ins.loops[i].mode = LoopForward;
|
||||
break;
|
||||
case 1:
|
||||
ins.loops[i].mode = SF_LOOP_ALTERNATING;
|
||||
ins.loops[i].mode = LoopAlternating;
|
||||
break;
|
||||
case 2:
|
||||
ins.loops[i].mode = SF_LOOP_BACKWARD;
|
||||
ins.loops[i].mode = LoopBackward;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,15 +5,13 @@
|
|||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#pragma once
|
||||
#if defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
#include <sndfile.h>
|
||||
#endif
|
||||
#include "ghc/fs_std.hpp"
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <cstdio>
|
||||
#if defined(_WIN32)
|
||||
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <sndfile.h>
|
||||
|
||||
namespace sfz {
|
||||
|
||||
|
|
@ -26,6 +24,44 @@ struct RiffChunkInfo {
|
|||
uint32_t length;
|
||||
};
|
||||
|
||||
#if !defined(ST_AUDIO_FILE_USE_SNDFILE)
|
||||
/**
|
||||
@brief Loop mode, like SF_LOOP_*
|
||||
*/
|
||||
enum LoopMode {
|
||||
LoopNone,
|
||||
LoopForward,
|
||||
LoopBackward,
|
||||
LoopAlternating,
|
||||
};
|
||||
|
||||
/**
|
||||
@brief Instrument information, like SF_INSTRUMENT
|
||||
*/
|
||||
struct InstrumentInfo {
|
||||
int gain;
|
||||
int8_t basenote, detune;
|
||||
int8_t velocity_lo, velocity_hi;
|
||||
int8_t key_lo, key_hi;
|
||||
int loop_count;
|
||||
struct {
|
||||
int mode;
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
uint32_t count;
|
||||
} loops[16];
|
||||
};
|
||||
#else
|
||||
enum LoopMode {
|
||||
LoopNone = SF_LOOP_NONE,
|
||||
LoopForward = SF_LOOP_FORWARD,
|
||||
LoopBackward = SF_LOOP_BACKWARD,
|
||||
LoopAlternating = SF_LOOP_ALTERNATING,
|
||||
};
|
||||
|
||||
struct InstrumentInfo : SF_INSTRUMENT {};
|
||||
#endif
|
||||
|
||||
struct WavetableInfo {
|
||||
/**
|
||||
@brief Size of each successive table in the file
|
||||
|
|
@ -79,7 +115,7 @@ public:
|
|||
/**
|
||||
* @brief Extract the RIFF 'smpl' data and convert it to sndfile instrument
|
||||
*/
|
||||
bool extractRiffInstrument(SF_INSTRUMENT& ins);
|
||||
bool extractRiffInstrument(InstrumentInfo& ins);
|
||||
|
||||
/**
|
||||
* @brief Extract the wavetable information from various relevant RIFF chunks
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
#include <memory>
|
||||
#include <thread>
|
||||
#include <system_error>
|
||||
#include <sndfile.hh>
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
|
|
@ -235,7 +234,7 @@ absl::optional<sfz::FileInformation> sfz::FilePool::getFileInformation(const Fil
|
|||
returnedValue.sampleRate = static_cast<double>(reader->sampleRate());
|
||||
returnedValue.numChannels = reader->channels();
|
||||
|
||||
SF_INSTRUMENT instrumentInfo {};
|
||||
InstrumentInfo instrumentInfo {};
|
||||
bool haveInstrumentInfo = reader->getInstrument(&instrumentInfo);
|
||||
|
||||
FileMetadataReader mdReader;
|
||||
|
|
|
|||
|
|
@ -88,10 +88,10 @@ if(JACK_FOUND AND TARGET Qt5::Widgets)
|
|||
endif()
|
||||
|
||||
add_executable(eq_apply EQ.cpp)
|
||||
target_link_libraries(eq_apply PRIVATE sfizz::sfizz)
|
||||
target_link_libraries(eq_apply PRIVATE sfizz::sfizz sfizz-sndfile)
|
||||
|
||||
add_executable(filter_apply Filter.cpp)
|
||||
target_link_libraries(filter_apply PRIVATE sfizz::sfizz)
|
||||
target_link_libraries(filter_apply PRIVATE sfizz::sfizz sfizz-sndfile)
|
||||
|
||||
add_executable(sfizz_plot_curve PlotCurve.cpp)
|
||||
target_link_libraries(sfizz_plot_curve PRIVATE sfizz::sfizz)
|
||||
|
|
@ -100,10 +100,10 @@ add_executable(sfizz_plot_wavetables PlotWavetables.cpp)
|
|||
target_link_libraries(sfizz_plot_wavetables PRIVATE sfizz::sfizz)
|
||||
|
||||
add_executable(sfizz_plot_lfo PlotLFO.cpp)
|
||||
target_link_libraries(sfizz_plot_lfo PRIVATE sfizz::sfizz)
|
||||
target_link_libraries(sfizz_plot_lfo PRIVATE sfizz::sfizz sfizz-sndfile)
|
||||
|
||||
add_executable(sfizz_file_instrument FileInstrument.cpp)
|
||||
target_link_libraries(sfizz_file_instrument PRIVATE sfizz::sfizz)
|
||||
target_link_libraries(sfizz_file_instrument PRIVATE sfizz::sfizz sfizz-sndfile)
|
||||
|
||||
add_executable(sfizz_file_wavetable FileWavetable.cpp)
|
||||
target_link_libraries(sfizz_file_wavetable PRIVATE sfizz::sfizz)
|
||||
|
|
|
|||
|
|
@ -12,20 +12,21 @@
|
|||
static const char* modeString(int mode, const char* valueFallback = nullptr)
|
||||
{
|
||||
switch (mode) {
|
||||
case SF_LOOP_NONE:
|
||||
case sfz::LoopNone:
|
||||
return "none";
|
||||
case SF_LOOP_FORWARD:
|
||||
case sfz::LoopForward:
|
||||
return "forward";
|
||||
case SF_LOOP_BACKWARD:
|
||||
case sfz::LoopBackward:
|
||||
return "backward";
|
||||
case SF_LOOP_ALTERNATING:
|
||||
case sfz::LoopAlternating:
|
||||
return "alternating";
|
||||
default:
|
||||
return valueFallback;
|
||||
}
|
||||
}
|
||||
|
||||
static void printInstrument(const SF_INSTRUMENT& ins)
|
||||
template <class Instrument>
|
||||
static void printInstrument(const Instrument& ins)
|
||||
{
|
||||
printf("Gain: %d\n", ins.gain);
|
||||
printf("Base note: %d\n", ins.basenote);
|
||||
|
|
@ -34,7 +35,7 @@ static void printInstrument(const SF_INSTRUMENT& ins)
|
|||
printf("Key: %d:%d\n", ins.key_lo, ins.key_hi);
|
||||
printf("Loop count: %d\n", ins.loop_count);
|
||||
|
||||
for (int i = 0; i < ins.loop_count; ++i) {
|
||||
for (unsigned i = 0, n = ins.loop_count; i < n; ++i) {
|
||||
printf("\nLoop %d:\n", i + 1);
|
||||
printf("\tMode: %s\n", modeString(ins.loops[i].mode, "(unknown)"));
|
||||
printf("\tStart: %u\n", ins.loops[i].start);
|
||||
|
|
@ -83,18 +84,18 @@ int main(int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
SF_INSTRUMENT ins {};
|
||||
|
||||
if (method == kMethodRiff) {
|
||||
sfz::FileMetadataReader reader;
|
||||
if (!reader.open(path)) {
|
||||
fprintf(stderr, "Cannot open file\n");
|
||||
return 1;
|
||||
}
|
||||
sfz::InstrumentInfo ins {};
|
||||
if (!reader.extractRiffInstrument(ins)) {
|
||||
fprintf(stderr, "Cannot get instrument\n");
|
||||
return 1;
|
||||
}
|
||||
printInstrument(ins);
|
||||
}
|
||||
else {
|
||||
SndfileHandle sndFile(path);
|
||||
|
|
@ -102,13 +103,13 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, "Cannot open file\n");
|
||||
return 1;
|
||||
}
|
||||
SF_INSTRUMENT ins {};
|
||||
if (sndFile.command(SFC_GET_INSTRUMENT, &ins, sizeof(ins)) != 1) {
|
||||
fprintf(stderr, "Cannot get instrument\n");
|
||||
return 1;
|
||||
}
|
||||
printInstrument(ins);
|
||||
}
|
||||
|
||||
printInstrument(ins);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue