Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
34dcad6
Opus audio format
kunitoki Dec 29, 2025
49164ab
Move pffft to upstream fetch
kunitoki Dec 29, 2025
d70d187
dr_libs use upstream
kunitoki Dec 29, 2025
f907722
Add some opus files
kunitoki Dec 30, 2025
daa4c00
Some opus tests
kunitoki Dec 30, 2025
5d31f05
More tests
kunitoki Dec 30, 2025
250050c
Fix path on android
kunitoki Dec 30, 2025
9445c3e
Fix compilation
kunitoki Dec 30, 2025
ea34785
Cosmetics
kunitoki Dec 30, 2025
93d910b
Fix builds
kunitoki Dec 30, 2025
a99feae
Add and fix mp3 audio format
kunitoki Dec 30, 2025
b9abd5d
Fix failures
kunitoki Dec 30, 2025
2f33e1e
Added flac and fixed more stuff
kunitoki Dec 30, 2025
2f27b59
Reenable test for opus
kunitoki Dec 30, 2025
36e068a
Fix flac encoding and decoding
kunitoki Dec 30, 2025
e6637e7
Improved readme
kunitoki Dec 30, 2025
d18ea4f
Fix tests
kunitoki Dec 30, 2025
2dfc469
Reduce warnings
kunitoki Dec 30, 2025
b02465b
More blind fixes
kunitoki Dec 30, 2025
6554868
Disable warnings
kunitoki Dec 30, 2025
804a407
Fix more warnings
kunitoki Dec 30, 2025
9c1a6b0
Fix linux
kunitoki Dec 30, 2025
f3a9d60
Fix windows
kunitoki Dec 30, 2025
7f04159
More tweaks
kunitoki Dec 30, 2025
c4be2cb
Skip defines in includes
kunitoki Dec 30, 2025
93ea52c
More warning fixes
kunitoki Dec 30, 2025
a0db11e
More warnings removal
kunitoki Dec 30, 2025
276a3ca
Core audio format
kunitoki Dec 30, 2025
8c97448
More warning fixes
kunitoki Dec 30, 2025
5f8cfcf
Windows media foundation support
kunitoki Dec 31, 2025
315774d
Fix tests
kunitoki Dec 31, 2025
c9afe67
Fix WMF
kunitoki Dec 31, 2025
8f39946
More windows fixes
kunitoki Dec 31, 2025
d13133c
More work on audio formats
kunitoki Dec 31, 2025
b565d7b
Added support for writing mp3s on platforms that doesn't support it n…
kunitoki Dec 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
407 changes: 407 additions & 0 deletions AGENTS.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ option (YUP_BUILD_JAVA_SUPPORT "Build the Java support" OFF)
option (YUP_BUILD_EXAMPLES "Build the examples" ${PROJECT_IS_TOP_LEVEL})
option (YUP_BUILD_TESTS "Build the tests" ${PROJECT_IS_TOP_LEVEL})
option (YUP_BUILD_WHEEL "Build the wheel" OFF)
option (YUP_FETCH_UPSTREAM_MODULES "Fetch missing upstream sources for modules" ON)

# Dependencies modules
if (YUP_EXPORT_MODULES)
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
<a href="./examples/graphics/source/examples/CrossoverDemo.h"><img src="./docs/images/yup_dsp_crossover.png" style="width:43.5%;" /></a>
</div>

<div style="display: flex; width: 100%; flex-wrap: nowrap;">
<a href="./examples/graphics/source/examples/AudioFileDemo.h"><img src="./docs/images/yup_audio_scope.png" style="width:99%;" /></a>
</p>

<div style="display: flex; width: 100%; flex-wrap: nowrap;">
<a href="./examples/graphics/source/examples/SpectrumAnalyzer.h"><img src="./docs/images/yup_dsp_spectrum_fill.png" style="width:99%;" /></a>
<a href="./examples/graphics/source/examples/SpectrumAnalyzer.h"><img src="./docs/images/yup_dsp_spectrum_line.png" style="width:99%;" /></a>
Expand Down Expand Up @@ -102,6 +106,23 @@ YUP brings a suite of powerful features, including:
| **Linux** | :construction: | :construction: | | | | | |


## Supported Sound Formats

| | **Wav** | **Wav64** | **Mp3** | **OGG** | **Flac** | **Opus** | **AAC** | **WMF** |
|-------------------|:------------------:|:------------------:|:------------------:|:--------------:|:------------------:|:------------------:|:------------------:|:--------------:|
| **Windows** (enc) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :construction: | :white_check_mark: | :white_check_mark: | :construction: | :construction: |
| **Windows** (dec) | :white_check_mark: | :white_check_mark: | :construction: | :construction: | :white_check_mark: | :white_check_mark: | :construction: | :construction: |
| **macOS** (enc) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :construction: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
| **macOS** (dec) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :construction: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
| **Linux** (enc) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :construction: | :white_check_mark: | :white_check_mark: | | |
| **Linux** (dec) | :white_check_mark: | :white_check_mark: | :construction: | :construction: | :white_check_mark: | :white_check_mark: | | |
| **WASM** (enc) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :construction: | :white_check_mark: | :white_check_mark: | | |
| **WASM** (dec) | :white_check_mark: | :white_check_mark: | :construction: | :construction: | :white_check_mark: | :white_check_mark: | | |
| **Android** (enc) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :construction: | :white_check_mark: | :white_check_mark: | | |
| **Android** (dec) | :white_check_mark: | :white_check_mark: | :construction: | :construction: | :white_check_mark: | :white_check_mark: | | |
| **iOS** (enc) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :construction: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |
| **iOS** (dec) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :construction: | :white_check_mark: | :white_check_mark: | :white_check_mark: | |

## Prerequisites
Before building, ensure you have a:
- C++20-compliant compiler
Expand Down
220 changes: 218 additions & 2 deletions cmake/yup_modules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
#
# ==============================================================================

#==============================================================================

function (_yup_module_parse_config module_header output_module_configs output_module_user_configs)
set (module_configs "")
set (module_user_configs "")
Expand Down Expand Up @@ -58,6 +56,181 @@ endfunction()

#==============================================================================

function (_yup_module_upstream_has_content module_name module_path output_variable)
_yup_collect_upstream_candidate_paths ("${module_name}" "${module_path}" candidate_paths)
foreach (candidate_path IN LISTS candidate_paths)
if (EXISTS "${candidate_path}")
file (GLOB upstream_items "${candidate_path}/*")
list (LENGTH upstream_items upstream_items_len)
if (upstream_items_len GREATER 0)
set (${output_variable} ON PARENT_SCOPE)
return()
endif()
endif()
endforeach()

set (${output_variable} OFF PARENT_SCOPE)
endfunction()

#==============================================================================

function (_yup_module_get_upstream_path module_name module_path output_variable)
_yup_collect_upstream_candidate_paths ("${module_name}" "${module_path}" candidate_paths)
foreach (candidate_path IN LISTS candidate_paths)
if (EXISTS "${candidate_path}")
set (${output_variable} "${candidate_path}" PARENT_SCOPE)
return()
endif()
endforeach()

set (${output_variable} "" PARENT_SCOPE)
endfunction()

#==============================================================================

function (_yup_module_fetch_upstream module_name module_path module_upstream module_sha256 module_repository module_branch module_submodules output_target_variable)
if (NOT YUP_FETCH_UPSTREAM_MODULES)
return()
endif()

if (module_upstream AND module_repository)
_yup_message (FATAL_ERROR "Module ${module_name} defines both upstream and repository sources")
endif()

if (NOT module_upstream AND NOT module_repository)
return()
endif()

_yup_module_upstream_has_content ("${module_name}" "${module_path}" upstream_has_content)
if (upstream_has_content)
return()
endif()

_yup_message (STATUS "Fetching upstream sources for ${module_name}")

if (module_upstream)
set (download_dir "${CMAKE_BINARY_DIR}/_yup_upstream_downloads")
file (MAKE_DIRECTORY "${download_dir}")
get_filename_component (archive_name "${module_upstream}" NAME)
if ("${archive_name}" STREQUAL "")
set (archive_name "${module_name}.archive")
endif()
set (archive_path "${download_dir}/${archive_name}")

# SHOW_PROGRESS
if (module_sha256)
file (DOWNLOAD "${module_upstream}" "${archive_path}" EXPECTED_HASH SHA256=${module_sha256})
else()
file (DOWNLOAD "${module_upstream}" "${archive_path}")
endif()

set (extract_dir "${CMAKE_BINARY_DIR}/_yup_upstream_extract/${module_name}")
file (REMOVE_RECURSE "${extract_dir}")
file (MAKE_DIRECTORY "${extract_dir}")
file (ARCHIVE_EXTRACT INPUT "${archive_path}" DESTINATION "${extract_dir}")

file (GLOB extracted_entries RELATIVE "${extract_dir}" "${extract_dir}/*")
list (LENGTH extracted_entries extracted_entries_len)
set (source_dir "${extract_dir}")
if (extracted_entries_len EQUAL 1)
list (GET extracted_entries 0 single_entry)
if (IS_DIRECTORY "${extract_dir}/${single_entry}")
set (source_dir "${extract_dir}/${single_entry}")
endif()
endif()

set (upstream_target_dir "${CMAKE_BINARY_DIR}/externals/${module_name}/upstream")
file (REMOVE_RECURSE "${upstream_target_dir}")
file (MAKE_DIRECTORY "${upstream_target_dir}")
file (GLOB extracted_items "${source_dir}/*")
if (extracted_items)
file (COPY ${extracted_items} DESTINATION "${upstream_target_dir}")
endif()
else()
if (NOT module_branch)
set (module_branch "HEAD")
endif()

set (upstream_target_dir "${CMAKE_BINARY_DIR}/externals/${module_name}/upstream")
if (module_submodules)
set (module_submodules_recurse ON)
else()
set (module_submodules_recurse OFF)
endif()

file (MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/externals/${module_name}")

file (REMOVE_RECURSE "${upstream_target_dir}")
set (module_branch_value "${module_branch}")
string (STRIP "${module_branch_value}" module_branch_value)
string (REGEX REPLACE "^\"(.*)\"$" "\\1" module_branch_value "${module_branch_value}")
string (REGEX REPLACE "^'(.*)'$" "\\1" module_branch_value "${module_branch_value}")

if (module_branch_value AND NOT module_branch_value STREQUAL "HEAD")
string (REGEX MATCH "^[0-9a-fA-F]+$" module_branch_is_hex "${module_branch_value}")
string (LENGTH "${module_branch_value}" module_branch_length)
if (module_branch_is_hex AND module_branch_length GREATER_EQUAL 7 AND module_branch_length LESS_EQUAL 40)
set (module_branch_is_commit ON)
else()
set (module_branch_is_commit "")
endif()
else()
set (module_branch_is_commit "")
endif()

if (module_branch_is_commit)
execute_process (
COMMAND git clone -q --no-checkout "${module_repository}" "${upstream_target_dir}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals/${module_name}"
RESULT_VARIABLE clone_result)
if (clone_result EQUAL 0)
execute_process (
COMMAND git -c advice.detachedHead=false -C "${upstream_target_dir}" fetch -q --depth=1 origin "${module_branch_value}"
RESULT_VARIABLE fetch_result)
execute_process (
COMMAND git -c advice.detachedHead=false -C "${upstream_target_dir}" checkout -q "${module_branch_value}"
RESULT_VARIABLE checkout_result)
if (module_submodules_recurse AND fetch_result EQUAL 0 AND checkout_result EQUAL 0)
execute_process (
COMMAND git -c advice.detachedHead=false -C "${upstream_target_dir}" submodule update --init --recursive --depth=1
RESULT_VARIABLE submodule_result)
endif()
endif()
else()
set (clone_args git clone)
if (module_submodules_recurse)
list (APPEND clone_args --recurse-submodules --shallow-submodules)
endif()
list (APPEND clone_args -q --depth=1)
if (module_branch_value AND NOT module_branch_value STREQUAL "HEAD")
list (APPEND clone_args --branch "${module_branch_value}")
endif()
list (APPEND clone_args "${module_repository}" "${upstream_target_dir}")
execute_process (
COMMAND ${clone_args}
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals/${module_name}"
RESULT_VARIABLE clone_result)
endif()

if (module_branch_is_commit)
if (NOT clone_result EQUAL 0 OR NOT fetch_result EQUAL 0 OR NOT checkout_result EQUAL 0)
_yup_message (FATAL_ERROR "Failed to clone ${module_repository} at commit ${module_branch} for ${module_name}")
endif()
if (module_submodules_recurse AND NOT submodule_result EQUAL 0)
_yup_message (FATAL_ERROR "Failed to update submodules for ${module_repository} at commit ${module_branch}")
endif()
else()
if (NOT clone_result EQUAL 0)
_yup_message (FATAL_ERROR "Failed to clone ${module_repository} for ${module_name}")
endif()
endif()

set (${output_target_variable} "" PARENT_SCOPE)
endif()
endfunction()

#==============================================================================

function (_yup_module_collect_sources folder output_variable)
set(source_extensions ".c;.cc;.cxx;.cpp;.h;.hh;.hxx;.hpp")
if (APPLE)
Expand Down Expand Up @@ -363,14 +536,37 @@ function (yup_add_module module_path modules_definitions module_group)
_yup_boolean_property ("${value}" module_arc_enabled)
elseif (${key} MATCHES "^needsPython$")
_yup_boolean_property ("${value}" module_needs_python)
elseif (${key} MATCHES "^upstream$")
set (module_upstream "${value}")
elseif (${key} MATCHES "^sha256$")
set (module_sha256 "${value}")
elseif (${key} MATCHES "^repository$")
set (module_repository "${value}")
elseif (${key} MATCHES "^branch$")
set (module_branch "${value}")
elseif (${key} MATCHES "^submodules$")
_yup_boolean_property ("${value}" module_submodules)
endif()
endforeach()

_yup_set_default (module_cpp_standard "20")
_yup_set_default (module_arc_enabled OFF)
_yup_set_default (module_needs_python OFF)
_yup_set_default (module_submodules ON)
_yup_resolve_variable_paths ("${module_searchpaths}" module_searchpaths)

set (module_upstream_target "")
if (module_upstream OR module_repository)
_yup_module_upstream_has_content ("${module_name}" "${module_path}" upstream_has_content)
if (NOT upstream_has_content)
if (YUP_FETCH_UPSTREAM_MODULES)
_yup_module_fetch_upstream ("${module_name}" "${module_path}" "${module_upstream}" "${module_sha256}" "${module_repository}" "${module_branch}" "${module_submodules}" module_upstream_target)
else()
_yup_message (WARNING "Upstream sources for ${module_name} are missing and YUP_FETCH_UPSTREAM_MODULES is OFF")
endif()
endif()
endif()

# ==== Setup Platform-Specific Configurations
if (YUP_PLATFORM_IOS)
if (module_appleCppStandard)
Expand Down Expand Up @@ -513,11 +709,24 @@ function (yup_add_module module_path modules_definitions module_group)
get_filename_component (module_include_path ${module_path} DIRECTORY)
list (APPEND module_include_paths "${module_include_path}")

if (module_upstream OR module_repository)
_yup_module_get_upstream_path ("${module_name}" "${module_path}" module_upstream_path)
if (module_upstream_path)
list (APPEND module_include_paths "${module_upstream_path}")
else()
list (APPEND module_include_paths "${CMAKE_BINARY_DIR}/externals/${module_name}/upstream")
endif()
endif()

foreach (searchpath IN LISTS module_searchpaths)
if (EXISTS "${searchpath}")
list (APPEND module_include_paths "${searchpath}")
elseif (EXISTS "${module_path}/${searchpath}")
list (APPEND module_include_paths "${module_path}/${searchpath}")
elseif (module_upstream_path AND EXISTS "${module_upstream_path}/${searchpath}")
list (APPEND module_include_paths "${module_upstream_path}/${searchpath}")
elseif (module_upstream OR module_repository)
list (APPEND module_include_paths "${CMAKE_BINARY_DIR}/externals/${module_name}/upstream/${searchpath}")
endif()
endforeach()

Expand Down Expand Up @@ -558,6 +767,10 @@ function (yup_add_module module_path modules_definitions module_group)
"${module_dependencies}"
"${module_arc_enabled}")

if (module_upstream_target)
add_dependencies (${module_name} "${module_upstream_target}")
endif()

#set (${module_name}_Configs "${module_user_configs}")
#set (${module_name}_Configs ${${module_name}_Configs} PARENT_SCOPE)

Expand Down Expand Up @@ -621,6 +834,9 @@ macro (yup_add_default_modules modules_path)
yup_add_module (${modules_path}/thirdparty/oboe_library "${modules_definitions}" ${thirdparty_group})
yup_add_module (${modules_path}/thirdparty/pffft_library "${modules_definitions}" ${thirdparty_group})
yup_add_module (${modules_path}/thirdparty/dr_libs "${modules_definitions}" ${thirdparty_group})
yup_add_module (${modules_path}/thirdparty/opus_library "${modules_definitions}" ${thirdparty_group})
yup_add_module (${modules_path}/thirdparty/flac_library "${modules_definitions}" ${thirdparty_group})
yup_add_module (${modules_path}/thirdparty/hmp3_library "${modules_definitions}" ${thirdparty_group})

# ==== Yup modules
set (modules_group "Modules")
Expand Down
31 changes: 31 additions & 0 deletions cmake/yup_utilities.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,37 @@ function (_yup_resolve_variable_path input_path output_variable)
set (${output_variable} "${input_path}" PARENT_SCOPE)
endfunction()

#==============================================================================

function (_yup_collect_upstream_candidate_paths module_name module_path output_variable)
set (candidate_paths "${module_path}/upstream")

if (DEFINED YUP_UPSTREAM_ROOT AND NOT "${YUP_UPSTREAM_ROOT}" STREQUAL "")
list (APPEND candidate_paths "${YUP_UPSTREAM_ROOT}/${module_name}/upstream")
endif()

if (CMAKE_SOURCE_DIR)
list (APPEND candidate_paths "${CMAKE_SOURCE_DIR}/build/externals/${module_name}/upstream")
list (APPEND candidate_paths "${CMAKE_SOURCE_DIR}/../build/externals/${module_name}/upstream")
endif()

set (candidate_root "${CMAKE_BINARY_DIR}")
set (max_depth 10)
while (max_depth GREATER 0)
list (APPEND candidate_paths "${candidate_root}/externals/${module_name}/upstream")

get_filename_component (candidate_parent "${candidate_root}" DIRECTORY)
if ("${candidate_parent}" STREQUAL "${candidate_root}")
break()
endif()

set (candidate_root "${candidate_parent}")
math (EXPR max_depth "${max_depth} - 1")
endwhile()

set (${output_variable} "${candidate_paths}" PARENT_SCOPE)
endfunction()

function (_yup_resolve_variable_paths input_list output_list)
set (resolved_list "")

Expand Down
4 changes: 2 additions & 2 deletions docs/YUP Module Format.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Possible values:
- (Optional) A list (space or comma-separated) of macro defines needed by this module.

- searchpaths
- (Optional) A space-separated list of internal include paths, relative to the module's parent folder, which need to be added to a project's header search path.
- (Optional) A space-separated list of internal include paths, relative to the module's parent folder or the upstream checkout folder, which need to be added to a project's header search path.

- [android|apple|ios|linux|mobile|msft|osx|wasm|win32|windows]CppStandard
- (Optional) A number indicating the minimum C++ language standard that is required for this module and this platform exclusively. This must be just the standard number with no prefix e.g. 20 for C++20.
Expand All @@ -156,7 +156,7 @@ Possible values:
- (Optional) A list (space or comma-separated) of link options needed by this module in a build.

- [android|apple|ios|linux|mobile|msft|osx|wasm|win32|windows]Searchpaths
- (Optional) A space-separated list of internal include paths, relative to the module's parent folder, which need to be added to a project's header search path.
- (Optional) A space-separated list of internal include paths, relative to the module's parent folder or the upstream checkout folder, which need to be added to a project's header search path.

- [ios|osx|apple]Frameworks
- (Optional) A list (space or comma-separated) of iOS/macOS/Apple frameworks that are needed by this module.
Expand Down
Binary file added docs/images/yup_audio_scope.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions examples/graphics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ yup_standalone_app (
yup::yup_audio_processors
yup::yup_audio_formats
pffft_library
opus_library
flac_library
hmp3_library
dr_libs
libpng
libwebp
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Loading