Merge branch 'dev' into dev-0.12

This commit is contained in:
David Reid
2025-07-04 11:14:38 +10:00
6 changed files with 4019 additions and 1690 deletions
+33 -1
View File
@@ -62,9 +62,16 @@ option(MINIAUDIO_USE_STDINT "Use <stdint.h> for sized types"
option(MINIAUDIO_DEBUG_OUTPUT "Enable stdout debug output" OFF)
# Construct compiler options.
set(COMPILE_OPTIONS)
# Store libraries to install
# When installing any header that imports miniaudio.h from a relative path, we
# need to maintain its place in the directory tree so it can find Miniaudio
set(LIBS_TO_INSTALL)
if(MINIAUDIO_FORCE_CXX AND MINIAUDIO_FORCE_C89)
message(FATAL_ERROR "MINIAUDIO_FORCE_CXX and MINIAUDIO_FORCE_C89 cannot be enabled at the same time.")
endif()
@@ -88,7 +95,7 @@ if(MINIAUDIO_FORCE_C89)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
message(WARNING "MSVC does not support forcing C89. MINIAUDIO_FORCE_C89 ignored.")
else()
message(WARNING "MINIAUDIO_FORCE_C89 is enabled but the compiler does not support it. Ingoring.")
message(WARNING "MINIAUDIO_FORCE_C89 is enabled but the compiler does not support it. Ignoring.")
endif()
endif()
@@ -457,6 +464,9 @@ add_library(miniaudio STATIC
miniaudio.h
)
list(APPEND LIBS_TO_INSTALL miniaudio)
install(FILES miniaudio.h DESTINATION include/miniaudio)
target_include_directories(miniaudio PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_options (miniaudio PRIVATE ${COMPILE_OPTIONS})
target_compile_definitions(miniaudio PRIVATE ${COMPILE_DEFINES})
@@ -477,6 +487,9 @@ if(HAS_LIBVORBIS)
extras/decoders/libvorbis/miniaudio_libvorbis.h
)
list(APPEND LIBS_TO_INSTALL miniaudio_libvorbis)
install(FILES extras/decoders/libvorbis/miniaudio_libvorbis.h DESTINATION include/miniaudio/extras/decoders/libvorbis)
target_compile_options (miniaudio_libvorbis PRIVATE ${COMPILE_OPTIONS})
target_compile_definitions(miniaudio_libvorbis PRIVATE ${COMPILE_DEFINES})
target_link_libraries (miniaudio_libvorbis PRIVATE libvorbis_interface)
@@ -499,6 +512,10 @@ if(HAS_LIBOPUS)
extras/decoders/libopus/miniaudio_libopus.h
)
list(APPEND LIBS_TO_INSTALL miniaudio_libopus)
install(FILES extras/decoders/libopus/miniaudio_libopus.h DESTINATION include/miniaudio/extras/decoders/libopus)
target_compile_options (miniaudio_libopus PRIVATE ${COMPILE_OPTIONS})
target_compile_definitions(miniaudio_libopus PRIVATE ${COMPILE_DEFINES})
target_link_libraries (miniaudio_libopus PRIVATE libopus_interface)
@@ -511,6 +528,12 @@ if (NOT MINIAUDIO_NO_EXTRA_NODES)
extras/nodes/ma_${name}_node/ma_${name}_node.c
extras/nodes/ma_${name}_node/ma_${name}_node.h
)
set(libs "${LIBS_TO_INSTALL}")
list(APPEND libs miniaudio_${name}_node)
set(LIBS_TO_INSTALL "${libs}" PARENT_SCOPE) # without PARENT_SCOPE, any changes are lost
install(FILES extras/nodes/ma_${name}_node/ma_${name}_node.h DESTINATION include/miniaudio/extras/nodes/ma_${name}_node)
target_include_directories(miniaudio_${name}_node PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/extras/nodes/ma_${name}_node)
target_compile_options (miniaudio_${name}_node PRIVATE ${COMPILE_OPTIONS})
@@ -645,3 +668,12 @@ if (MINIAUDIO_BUILD_EXAMPLES)
add_miniaudio_example(miniaudio_simple_playback simple_playback.c)
add_miniaudio_example(miniaudio_simple_spatialization simple_spatialization.c)
endif()
include(GNUInstallDirs)
message(STATUS "Library list: ${LIBS_TO_INSTALL}")
install(TARGETS ${LIBS_TO_INSTALL}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
+13
View File
@@ -0,0 +1,13 @@
miniaudio_h := <../miniaudio.h>;
miniaudio_c := <../miniaudio.c>;
cleanup :: function(src:string) string
{
return @(src)
["\r\n"] <= "\n" // Normalize line endings to "\n". Needed for very old versions of GCC.
["\t"] <= " " // Tabs to spaces.
;
}
miniaudio_h = cleanup(@(miniaudio_h));
miniaudio_c = cleanup(@(miniaudio_c));
+289
View File
@@ -0,0 +1,289 @@
miniaudio_h := <../miniaudio.h>;
miniaudio_c := <../miniaudio.c>;
dr_wav_h :: <../../dr_libs/dr_wav.h>;
dr_flac_h :: <../../dr_libs/dr_flac.h>;
dr_mp3_h :: <../../dr_libs/dr_mp3.h>;
c89atomic_h :: <../../c89atomic/c89atomic.h>;
c89atomic_c :: <../../c89atomic/c89atomic.c>;
minify :: function(src:string) string
{
return @(src)
["/\*[^*]*\*+(?:[^/*][^*]*\*+)*/"] <= "" // Remove all block comments to keep things clean.
["(?m)^\s*\R"] <= "" // Remove all empty lines to compress it all down.
["[ \t]+(?=(?:\R|$))"] <= "" // Remove trailing whitespace.
;
}
// dr_wav
rename_wav_namespace :: function(src:string) string
{
return @(src)
["\bdrwav"] <= "ma_dr_wav"
["\bDRWAV"] <= "MA_DR_WAV"
["\bdr_wav"] <= "ma_dr_wav"
["\bDR_WAV"] <= "MA_DR_WAV"
["\bg_drwav"] <= "ma_dr_wav_g"
// Some common tokens will be namespaced as "ma_dr_wav" when we really want them to be "ma_".
["\bma_dr_wav_int"] <= "ma_int"
["\bma_dr_wav_uint"] <= "ma_uint"
["\bma_dr_wav_bool"] <= "ma_bool"
["\bma_dr_wav_uintptr"] <= "ma_uintptr"
["\bMA_DR_WAV_TRUE"] <= "MA_TRUE"
["\bMA_DR_WAV_FALSE"] <= "MA_FALSE"
["\bMA_DR_WAV_UINT64_MAX"] <= "MA_UINT64_MAX"
["\bMA_DR_WAV_32BIT"] <= "MA_32BIT"
["\bMA_DR_WAV_64BIT"] <= "MA_64BIT"
["\bMA_DR_WAV_ARM32"] <= "MA_ARM32"
["\bMA_DR_WAV_ARM64"] <= "MA_ARM64"
["\bMA_DR_WAV_X64"] <= "MA_X64"
["\bMA_DR_WAV_X86"] <= "MA_X86"
["\bMA_DR_WAV_ARM"] <= "MA_ARM"
["\bMA_DR_WAV_API"] <= "MA_API"
["\bMA_DR_WAV_PRIVATE"] <= "MA_PRIVATE"
["\bMA_DR_WAV_DLL"] <= "MA_DLL"
["\bMA_DR_WAV_DLL_IMPORT"] <= "MA_DLL_IMPORT"
["\bMA_DR_WAV_DLL_EXPORT"] <= "MA_DLL_EXPORT"
["\bMA_DR_WAV_DLL_PRIVATE"] <= "MA_DLL_PRIVATE"
["\bma_dr_wav_result"] <= "ma_result"
["\bma_dr_wav_allocation_callbacks"] <= "ma_allocation_callbacks"
["\bMA_DR_WAV_INLINE"] <= "MA_INLINE"
["\bMA_DR_WAV_SIZE_MAX"] <= "MA_SIZE_MAX"
["\bma_dr_wav_result_from_errno"] <= "ma_result_from_errno"
["\bma_dr_wav_fopen"] <= "ma_fopen"
["\bma_dr_wav_wfopen"] <= "ma_wfopen"
// Result codes.
["MA_DR_WAV_SUCCESS"] <= "MA_SUCCESS"
["MA_DR_WAV_INVALID_ARGS"] <= "MA_INVALID_ARGS"
["MA_DR_WAV_OUT_OF_MEMORY"] <= "MA_OUT_OF_MEMORY"
["MA_DR_WAV_INVALID_FILE"] <= "MA_INVALID_FILE"
["MA_DR_WAV_AT_END"] <= "MA_AT_END"
["MA_DR_WAV_BAD_SEEK"] <= "MA_BAD_SEEK"
;
}
convert_wav_h :: function(src:string) string
{
stripped := @(src);
stripped["/\* Sized Types \*/\R" : "\R/\* End Sized Types \*/" ] = "";
stripped["/\* Decorations \*/\R" : "\R/\* End Decorations \*/" ] = "";
stripped["/\* Result Codes \*/\R" : "\R/\* End Result Codes \*/" ] = "";
stripped["/\* Allocation Callbacks \*/\R" : "\R/\* End Allocation Callbacks \*/" ] = "";
return minify(rename_wav_namespace(stripped));
}
convert_wav_c :: function(src:string) string
{
stripped := @(src);
stripped["/\* Architecture Detection \*/\R" : "\R/\* End Architecture Detection \*/"] = "";
stripped["/\* Inline \*/\R" : "\R/\* End Inline \*/" ] = "";
stripped["/\* SIZE_MAX \*/\R" : "\R/\* End SIZE_MAX \*/" ] = "";
stripped["/\* Errno \*/\R" : "\R/\* End Errno \*/" ] = "";
stripped["/\* fopen \*/\R" : "\R/\* End fopen \*/" ] = "";
return minify(rename_wav_namespace(stripped));
}
miniaudio_h("/\* dr_wav_h begin \*/\R":"\R/\* dr_wav_h end \*/") = convert_wav_h(@(dr_wav_h["#ifndef dr_wav_h\R":"\R#endif /\* dr_wav_h \*/"]));
miniaudio_h("/\* dr_wav_c begin \*/\R":"\R/\* dr_wav_c end \*/") = convert_wav_c(@(dr_wav_h["#ifndef dr_wav_c\R":"\R#endif /\* dr_wav_c \*/"]));
// dr_flac
rename_flac_namespace :: function(src:string) string
{
return @(src)
["\bdrflac"] <= "ma_dr_flac"
["\bDRFLAC"] <= "MA_DR_FLAC"
["\bdr_flac"] <= "ma_dr_flac"
["\bDR_FLAC"] <= "MA_DR_FLAC"
["\bg_drflac"] <= "ma_dr_flac_g"
// Some common tokens will be namespaced as "ma_dr_flac" when we really want them to be "ma_".
["\bma_dr_flac_int"] <= "ma_int"
["\bma_dr_flac_uint"] <= "ma_uint"
["\bma_dr_flac_bool"] <= "ma_bool"
["\bma_dr_flac_uintptr"] <= "ma_uintptr"
["\bMA_DR_FLAC_TRUE"] <= "MA_TRUE"
["\bMA_DR_FLAC_FALSE"] <= "MA_FALSE"
["\bMA_DR_FLAC_UINT64_MAX"] <= "MA_UINT64_MAX"
["\bMA_DR_FLAC_32BIT"] <= "MA_32BIT"
["\bMA_DR_FLAC_64BIT"] <= "MA_64BIT"
["\bMA_DR_FLAC_ARM32"] <= "MA_ARM32"
["\bMA_DR_FLAC_ARM64"] <= "MA_ARM64"
["\bMA_DR_FLAC_X64"] <= "MA_X64"
["\bMA_DR_FLAC_X86"] <= "MA_X86"
["\bMA_DR_FLAC_ARM"] <= "MA_ARM"
["\bMA_DR_FLAC_API"] <= "MA_API"
["\bMA_DR_FLAC_PRIVATE"] <= "MA_PRIVATE"
["\bMA_DR_FLAC_DLL"] <= "MA_DLL"
["\bMA_DR_FLAC_DLL_IMPORT"] <= "MA_DLL_IMPORT"
["\bMA_DR_FLAC_DLL_EXPORT"] <= "MA_DLL_EXPORT"
["\bMA_DR_FLAC_DLL_PRIVATE"] <= "MA_DLL_PRIVATE"
["\bma_dr_flac_result"] <= "ma_result"
["\bma_dr_flac_allocation_callbacks"] <= "ma_allocation_callbacks"
["\bMA_DR_FLAC_INLINE"] <= "MA_INLINE"
["\bMA_DR_FLAC_SIZE_MAX"] <= "MA_SIZE_MAX"
["\bma_dr_flac_result_from_errno"] <= "ma_result_from_errno"
["\bma_dr_flac_fopen"] <= "ma_fopen"
["\bma_dr_flac_wfopen"] <= "ma_wfopen"
// Result codes.
["MA_DR_FLAC_SUCCESS"] <= "MA_SUCCESS"
["MA_DR_FLAC_ERROR"] <= "MA_ERROR"
["MA_DR_FLAC_AT_END"] <= "MA_AT_END"
["MA_DR_FLAC_CRC_MISMATCH"] <= "MA_CRC_MISMATCH"
;
}
convert_flac_h :: function(src:string) string
{
stripped := @(src);
stripped["/\* Sized Types \*/\R" : "\R/\* End Sized Types \*/" ] = "";
stripped["/\* Architecture Detection \*/\R" : "\R/\* End Architecture Detection \*/"] = "";
stripped["/\* Decorations \*/\R" : "\R/\* End Decorations \*/" ] = "";
stripped["/\* Allocation Callbacks \*/\R" : "\R/\* End Allocation Callbacks \*/" ] = "";
return minify(rename_flac_namespace(stripped));
}
convert_flac_c :: function(src:string) string
{
stripped := @(src);
stripped["/\* Result Codes \*/\R" : "\R/\* End Result Codes \*/" ] = "";
stripped["/\* Inline \*/\R" : "\R/\* End Inline \*/" ] = "";
stripped["/\* SIZE_MAX \*/\R" : "\R/\* End SIZE_MAX \*/" ] = "";
stripped["/\* Errno \*/\R" : "\R/\* End Errno \*/" ] = "";
stripped["/\* fopen \*/\R" : "\R/\* End fopen \*/" ] = "";
return minify(rename_flac_namespace(stripped));
}
miniaudio_h("/\* dr_flac_h begin \*/\R":"\R/\* dr_flac_h end \*/") = convert_flac_h(@(dr_flac_h["#ifndef dr_flac_h\R":"\R#endif /\* dr_flac_h \*/"]));
miniaudio_h("/\* dr_flac_c begin \*/\R":"\R/\* dr_flac_c end \*/") = convert_flac_c(@(dr_flac_h["#ifndef dr_flac_c\R":"\R#endif /\* dr_flac_c \*/"]));
// dr_mp3
rename_mp3_namespace :: function(src:string) string
{
return @(src)
["\bdrmp3"] <= "ma_dr_mp3"
["\bDRMP3"] <= "MA_DR_MP3"
["\bdr_mp3"] <= "ma_dr_mp3"
["\bDR_MP3"] <= "MA_DR_MP3"
["\bg_drmp3"] <= "ma_dr_mp3_g"
// Some common tokens will be namespaced as "ma_dr_mp3" when we really want them to be "ma_".
["\bma_dr_mp3_int"] <= "ma_int"
["\bma_dr_mp3_uint"] <= "ma_uint"
["\bma_dr_mp3_bool"] <= "ma_bool"
["\bma_dr_mp3_uintptr"] <= "ma_uintptr"
["\bMA_DR_MP3_TRUE"] <= "MA_TRUE"
["\bMA_DR_MP3_FALSE"] <= "MA_FALSE"
["\bMA_DR_MP3_UINT64_MAX"] <= "MA_UINT64_MAX"
["\bMA_DR_MP3_32BIT"] <= "MA_32BIT"
["\bMA_DR_MP3_64BIT"] <= "MA_64BIT"
["\bMA_DR_MP3_ARM32"] <= "MA_ARM32"
["\bMA_DR_MP3_ARM64"] <= "MA_ARM64"
["\bMA_DR_MP3_X64"] <= "MA_X64"
["\bMA_DR_MP3_X86"] <= "MA_X86"
["\bMA_DR_MP3_ARM"] <= "MA_ARM"
["\bMA_DR_MP3_API"] <= "MA_API"
["\bMA_DR_MP3_PRIVATE"] <= "MA_PRIVATE"
["\bMA_DR_MP3_DLL"] <= "MA_DLL"
["\bMA_DR_MP3_DLL_IMPORT"] <= "MA_DLL_IMPORT"
["\bMA_DR_MP3_DLL_EXPORT"] <= "MA_DLL_EXPORT"
["\bMA_DR_MP3_DLL_PRIVATE"] <= "MA_DLL_PRIVATE"
["\bma_dr_mp3_result"] <= "ma_result"
["\bma_dr_mp3_allocation_callbacks"] <= "ma_allocation_callbacks"
["\bMA_DR_MP3_INLINE"] <= "MA_INLINE"
["\bMA_DR_MP3_SIZE_MAX"] <= "MA_SIZE_MAX"
["\bma_dr_mp3_result_from_errno"] <= "ma_result_from_errno"
["\bma_dr_mp3_fopen"] <= "ma_fopen"
["\bma_dr_mp3_wfopen"] <= "ma_wfopen"
// Result codes.
["MA_DR_MP3_SUCCESS"] <= "MA_SUCCESS"
;
}
convert_mp3_h :: function(src:string) string
{
stripped := @(src);
stripped["/\* Sized Types \*/\R" : "\R/\* End Sized Types \*/" ] = "";
stripped["/\* Decorations \*/\R" : "\R/\* End Decorations \*/" ] = "";
stripped["/\* Result Codes \*/\R" : "\R/\* End Result Codes \*/" ] = "";
stripped["/\* Inline \*/\R" : "\R/\* End Inline \*/" ] = "";
stripped["/\* Allocation Callbacks \*/\R" : "\R/\* End Allocation Callbacks \*/" ] = "";
return minify(rename_mp3_namespace(stripped));
}
convert_mp3_c :: function(src:string) string
{
stripped := @(src);
stripped["/\* SIZE_MAX \*/\R" : "\R/\* End SIZE_MAX \*/" ] = "";
stripped["/\* Errno \*/\R" : "\R/\* End Errno \*/" ] = "";
stripped["/\* fopen \*/\R" : "\R/\* End fopen \*/" ] = "";
return minify(rename_mp3_namespace(stripped));
}
miniaudio_h("/\* dr_mp3_h begin \*/\R":"\R/\* dr_mp3_h end \*/") = convert_mp3_h(@(dr_mp3_h["#ifndef dr_mp3_h\R":"\R#endif /\* dr_mp3_h \*/"]));
miniaudio_h("/\* dr_mp3_c begin \*/\R":"\R/\* dr_mp3_c end \*/") = convert_mp3_c(@(dr_mp3_h["#ifndef dr_mp3_c\R":"\R#endif /\* dr_mp3_c \*/"]));
// c89atomic
rename_c89atomic_namespace :: function(src:string) string
{
return @(src)
["\bc89atomic"] <= "ma_atomic"
["\bC89ATOMIC"] <= "MA_ATOMIC"
// Some common tokens will be namespaced as "ma_atomic" when we really want them to be "ma_".
["\bma_atomic_int"] <= "ma_int"
["\bma_atomic_uint"] <= "ma_uint"
["\bma_atomic_bool"] <= "ma_bool32"
["\bMA_ATOMIC_32BIT"] <= "MA_32BIT"
["\bMA_ATOMIC_64BIT"] <= "MA_64BIT"
["\bMA_ATOMIC_ARM32"] <= "MA_ARM32"
["\bMA_ATOMIC_ARM64"] <= "MA_ARM64"
["\bMA_ATOMIC_X64"] <= "MA_X64"
["\bMA_ATOMIC_X86"] <= "MA_X86"
["\bMA_ATOMIC_ARM"] <= "MA_ARM"
["\bMA_ATOMIC_INLINE"] <= "MA_INLINE"
// We have an "extern c89atomic_spinlock" in c89atomic.h, but since we're putting this into the implementation section we can just
// drop the extern and not bother importing anything from c89atomic.c.
["\bextern ma_atomic_spinlock"] <= "ma_atomic_spinlock"
;
}
convert_c89atomic_h :: function(src:string) string
{
stripped := @(src);
stripped["/\* Sized Types \*/\R" : "\R/\* End Sized Types \*/" ] = "";
stripped["/\* Architecture Detection \*/\R" : "\R/\* End Architecture Detection \*/"] = "";
stripped["/\* Inline \*/\R" : "\R/\* End Inline \*/" ] = "";
return minify(rename_c89atomic_namespace(stripped));
}
miniaudio_h("/\* c89atomic.h begin \*/\R":"\R/\* c89atomic.h end \*/") = convert_c89atomic_h(@(c89atomic_h["#ifndef c89atomic_h\R":"\R#endif /\* c89atomic_h \*/"]));
// Cleanup. If we don't normalize line endings we'll fail to compile on old versions of GCC.
cleanup :: function(src:string) string
{
return @(src)
["\r\n"] <= "\n" // Normalize line endings to "\n". Needed for very old versions of GCC.
["\t"] <= " " // Tabs to spaces.
;
}
miniaudio_h = cleanup(@(miniaudio_h));
miniaudio_c = cleanup(@(miniaudio_c));
+34 -17
View File
@@ -112,9 +112,6 @@ static long ma_libvorbis_vf_callback__tell(void* pUserData)
static ma_result ma_libvorbis_init_internal(const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_libvorbis* pVorbis)
{
ma_result result;
ma_data_source_config dataSourceConfig;
if (pVorbis == NULL) {
return MA_INVALID_ARGS;
}
@@ -128,16 +125,19 @@ static ma_result ma_libvorbis_init_internal(const ma_decoding_backend_config* pC
/* Getting here means something other than f32 and s16 was specified. Just leave this unset to use the default format. */
}
dataSourceConfig = ma_data_source_config_init();
dataSourceConfig.vtable = &g_ma_libvorbis_ds_vtable;
result = ma_data_source_init(&dataSourceConfig, &pVorbis->ds);
if (result != MA_SUCCESS) {
return result; /* Failed to initialize the base data source. */
}
#if !defined(MA_NO_LIBVORBIS)
{
ma_result result;
ma_data_source_config dataSourceConfig;
dataSourceConfig = ma_data_source_config_init();
dataSourceConfig.vtable = &g_ma_libvorbis_ds_vtable;
result = ma_data_source_init(&dataSourceConfig, &pVorbis->ds);
if (result != MA_SUCCESS) {
return result; /* Failed to initialize the base data source. */
}
pVorbis->vf = (OggVorbis_File*)ma_malloc(sizeof(OggVorbis_File), pAllocationCallbacks);
if (pVorbis->vf == NULL) {
ma_data_source_uninit(&pVorbis->ds);
@@ -160,16 +160,16 @@ MA_API ma_result ma_libvorbis_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_
ma_result result;
(void)pAllocationCallbacks; /* Can't seem to find a way to configure memory allocations in libvorbis. */
if (onRead == NULL || onSeek == NULL) {
return MA_INVALID_ARGS; /* onRead and onSeek are mandatory. */
}
result = ma_libvorbis_init_internal(pConfig, pAllocationCallbacks, pVorbis);
if (result != MA_SUCCESS) {
return result;
}
if (onRead == NULL || onSeek == NULL) {
return MA_INVALID_ARGS; /* onRead and onSeek are mandatory. */
}
pVorbis->onRead = onRead;
pVorbis->onSeek = onSeek;
pVorbis->onTell = onTell;
@@ -188,6 +188,8 @@ MA_API ma_result ma_libvorbis_init(ma_read_proc onRead, ma_seek_proc onSeek, ma_
libvorbisResult = ov_open_callbacks(pVorbis, (OggVorbis_File*)pVorbis->vf, NULL, 0, libvorbisCallbacks);
if (libvorbisResult < 0) {
ma_data_source_uninit(&pVorbis->ds);
ma_free(pVorbis->vf, pAllocationCallbacks);
return MA_INVALID_FILE;
}
@@ -218,6 +220,8 @@ MA_API ma_result ma_libvorbis_init_file(const char* pFilePath, const ma_decoding
libvorbisResult = ov_fopen(pFilePath, (OggVorbis_File*)pVorbis->vf);
if (libvorbisResult < 0) {
ma_data_source_uninit(&pVorbis->ds);
ma_free(pVorbis->vf, pAllocationCallbacks);
return MA_INVALID_FILE;
}
@@ -482,8 +486,21 @@ MA_API ma_result ma_libvorbis_get_length_in_pcm_frames(ma_libvorbis* pVorbis, ma
#if !defined(MA_NO_LIBVORBIS)
{
/* I don't know how to reliably retrieve the length in frames using libvorbis, so returning 0 for now. */
*pLength = 0;
/*
Will work in the supermajority of cases where a file has a single logical bitstream. Concatenated streams
are much harder to determine the length of since they can have sample rate changes, but they should be
extremely rare outside of unseekable livestreams anyway.
*/
if (ov_streams((OggVorbis_File*)pVorbis->vf) == 1) {
ogg_int64_t length = ov_pcm_total((OggVorbis_File*)pVorbis->vf, 0);
if(length != OV_EINVAL) {
*pLength = (ma_uint64)length;
} else {
/* Unseekable. */
}
} else {
/* Concatenated stream. */
}
return MA_SUCCESS;
}
+3648 -1671
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1,4 +1,5 @@
#define MA_NO_THREADING
#define MA_NO_DEVICE_IO
#include "../common/common.c"
ma_result init_data_converter(ma_uint32 rateIn, ma_uint32 rateOut, ma_resample_algorithm algorithm, ma_data_converter* pDataConverter)