-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #448 from 4ms/headless-sim
Headless simulator
- Loading branch information
Showing
25 changed files
with
4,021 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
cmake_minimum_required(VERSION 3.14) | ||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) | ||
|
||
project(MetaModuleHeadless LANGUAGES C CXX) | ||
|
||
set(SIMULATOR 1) | ||
set(METAMODULE_HEADLESS 1) | ||
|
||
set(FWDIR ${CMAKE_CURRENT_LIST_DIR}/../firmware) | ||
set(LIBDIR ${CMAKE_CURRENT_LIST_DIR}/../firmware/lib) | ||
|
||
add_compile_options( | ||
-Ofast | ||
-ffast-math | ||
-funsafe-math-optimizations | ||
) | ||
include(${FWDIR}/cmake/log_levels.cmake) | ||
enable_logging() | ||
|
||
# #################### cpputil ######################################### | ||
|
||
add_subdirectory(${LIBDIR}/cpputil cpputil) | ||
target_compile_definitions(cpputil PUBLIC CPPUTIL_STATIC_STRING_USE_STD_STRING) | ||
|
||
|
||
# #################### RYML ################################## | ||
|
||
add_subdirectory(${LIBDIR}/patch-serial ${CMAKE_CURRENT_BINARY_DIR}/patch-serial) | ||
|
||
|
||
# #################### VCV Adaptor ################################## | ||
|
||
add_subdirectory(${FWDIR}/vcv_plugin ${CMAKE_CURRENT_BINARY_DIR}/vcv_plugin) | ||
|
||
# #################### Other brands ################################## | ||
|
||
add_subdirectory(${FWDIR}/vcv_ports/ ${CMAKE_CURRENT_BINARY_DIR}/vcv_ports) | ||
target_compile_options(vcv_ports INTERFACE -Wno-double-promotion) | ||
|
||
# #################### Application ############################################ | ||
|
||
add_subdirectory(${LIBDIR}/CoreModules ${CMAKE_CURRENT_BINARY_DIR}/CoreModules) | ||
add_subdirectory(${LIBDIR}/CoreModules/4ms ${CMAKE_CURRENT_BINARY_DIR}/CoreModules-4ms) | ||
target_compile_options(CoreModules INTERFACE -Wno-double-promotion) | ||
|
||
|
||
add_executable( | ||
headless | ||
src/main.cc | ||
src/audio_files.cc | ||
stubs/svg.cc | ||
stubs/random.cpp | ||
|
||
${FWDIR}/coreproc_plugin/create.cc | ||
|
||
${FWDIR}/metamodule-plugin-sdk/version.cc | ||
) | ||
|
||
target_include_directories( | ||
headless | ||
PRIVATE src | ||
stubs | ||
${FWDIR}/src | ||
${FWDIR}/src/console | ||
${FWDIR}/src/medium | ||
${FWDIR} | ||
. | ||
) | ||
|
||
target_compile_options(headless PRIVATE -Wall -Og) | ||
target_compile_options(headless PRIVATE -Wno-double-promotion) | ||
|
||
# Workaround for std::expected not available in clang | ||
# https://www.reddit.com/r/cpp/comments/1b6f3s4/any_news_on_when_libc_is_going_to_support/ | ||
# https://github.com/llvm/llvm-project/issues/62801 | ||
|
||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") | ||
target_compile_options(headless PRIVATE | ||
$<$<COMPILE_LANGUAGE:CXX>:-D__cpp_concepts=202002> | ||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-builtin-macro-redefined> | ||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-macro-redefined> | ||
) | ||
endif() | ||
|
||
|
||
target_link_libraries(headless PRIVATE | ||
metamodule::patch-serial | ||
vcv_ports | ||
) | ||
target_link_libraries(headless PUBLIC "$<LINK_LIBRARY:WHOLE_ARCHIVE,CoreModules-4ms>") | ||
target_link_libraries(headless PUBLIC "$<LINK_LIBRARY:WHOLE_ARCHIVE,vcv_plugin_internal>") | ||
target_link_libraries(headless PUBLIC "$<LINK_LIBRARY:WHOLE_ARCHIVE,vcv_plugin_export>") | ||
|
||
target_compile_definitions(headless PUBLIC SIMULATOR) | ||
|
||
set_property(TARGET headless PROPERTY CXX_STANDARD 23) | ||
|
||
# Arch-dependent Link options: | ||
message("CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}") | ||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") | ||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") | ||
target_link_options(headless PUBLIC "-Wl,-map,headless.map") | ||
else() | ||
target_link_options(headless PUBLIC LINKER:-Map,headless.map) | ||
endif() | ||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") | ||
target_link_options(headless PUBLIC LINKER:-Map,headless.map) | ||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | ||
target_link_options(headless PRIVATE "/MAP:headless.map") | ||
endif() | ||
|
||
|
||
## Debugging | ||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") | ||
find_program(CMAKE_DEBUGGER_BINARY lldb) | ||
set(DEBUG_COMMAND ${CMAKE_DEBUGGER_BINARY} $<TARGET_FILE:headless> -- | ||
--sdcarddir ${CMAKE_CURRENT_LIST_DIR}/patches | ||
--flashdir ${CMAKE_CURRENT_LIST_DIR}/../patches/default | ||
--assets ${CMAKE_CURRENT_LIST_DIR}/build/assets.uimg | ||
) | ||
|
||
|
||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") | ||
find_program(CMAKE_DEBUGGER_BINARY gdb) | ||
set(DEBUG_COMMAND ${CMAKE_DEBUGGER_BINARY} -q | ||
-ex \"set debuginfod enabled off\" | ||
-ex \"set pagination off\" | ||
-ex \"run\" | ||
--args $<TARGET_FILE:headless> | ||
--sdcarddir ${CMAKE_CURRENT_LIST_DIR}/patches | ||
--flashdir ${CMAKE_CURRENT_LIST_DIR}/../shared/patch/default | ||
--assets ${CMAKE_CURRENT_LIST_DIR}/build/assets.uimg | ||
) | ||
else () | ||
set(DEBUG_COMMAND echo "Compiler is ${CMAKE_CXX_COMPILER_ID}, but must be Clang, AppleClang, or GNU to debug") | ||
endif() | ||
|
||
add_custom_target( | ||
debug | ||
DEPENDS headless | ||
COMMAND ${DEBUG_COMMAND} | ||
USES_TERMINAL | ||
) | ||
|
||
include(ext-plugins.cmake) | ||
target_include_directories(headless PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/ext_plugin) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"version": 2, | ||
"cmakeMinimumRequired": { | ||
"major": 3, | ||
"minor": 20, | ||
"patch": 0 | ||
}, | ||
"configurePresets": [ | ||
{ | ||
"name": "Default", | ||
"displayName": "Normal headless build", | ||
"description": "Sets Ninja generator, build and install directory", | ||
"generator": "Ninja", | ||
"binaryDir": "${sourceDir}/build", | ||
"cacheVariables": { | ||
"CMAKE_BUILD_TYPE": "Debug", | ||
"CMAKE_INSTALL_PREFIX": "${sourceDir}/build" | ||
} | ||
}, | ||
{ | ||
"name": "gcc-warn", | ||
"displayName": "GCC", | ||
"description": "Warnings-enabled build options for GCC", | ||
"generator": "Ninja", | ||
"binaryDir": "${sourceDir}/build", | ||
"cacheVariables": { | ||
"CMAKE_CXX_FLAGS": "-Wall -Wpedantic -Werror=return-type -Wsuggest-override -Wuninitialized -Wdouble-promotion" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
BUILDDIR := build | ||
|
||
all: | $(BUILDDIR) | ||
cmake --build $(BUILDDIR) | ||
|
||
$(BUILDDIR): | ||
cmake --fresh --preset Default -DLOG_LEVEL=DEBUG | ||
|
||
clean: | ||
cmake --fresh --preset Default -DLOG_LEVEL=DEBUG | ||
|
||
realclean: | ||
rm -rf $(BUILDDIR) | ||
|
||
warnings: | ||
cmake --fresh --preset gcc-warn -DLOG_LEVEL=TRACE | ||
|
||
run: all | ||
build/headless | ||
|
||
debug: | ||
cmake --build ${BUILDDIR} --target debug | ||
|
||
.PHONY: all clean warnings run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
## MetaModule Headless | ||
|
||
This is designed to run a single patch, reading audio in from a file and saving | ||
the audio output to a file. | ||
|
||
**Usage:** | ||
``` | ||
cd headless | ||
cmake -B build | ||
cmake --build build | ||
build/headless -p../patches/default/Djembe4Verb.yml | ||
``` | ||
The `-p` option specifies the patch file to load. | ||
|
||
You can provide it a stereo .wav file with the `--in` option. This will be sent | ||
to In 1 and In 2. If you don't provide a file, then it will send silence to | ||
those channels. | ||
|
||
The output from Out 1 and Out 2 is saved to a .wav file, you can specify it | ||
with `--out` or else a default name will be used. | ||
|
||
You can specify the number of samples to process with `-n`, for example `-n | ||
48000` will process 1 second of sound at 48kHz. | ||
|
||
|
||
**Purpose:** | ||
This project is useful for testing the audio stream while developing, for | ||
example, making sure that optimizations do not effect the audio outputs. It | ||
also displays the processing time as a percentage of sample time at 48kHz, | ||
which is useful for seeing if optimizations are having an effect (on the host | ||
computer, at least). | ||
|
||
Finally, we've been using this already to compare the MM engine performance on | ||
various processors. | ||
|
||
**Future:** | ||
|
||
A future improvement would be to tie it into the OS's audio drivers, so it | ||
could stream audio. The driver adaptor should be done such that it can tie into | ||
the hardware MM's audio stream easily (so we can run headless on the MM). | ||
|
||
With streaming audio working, it could then respond to MIDI events on the host | ||
computer, so you could use it as a full headless synth. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Two steps to build an external plugin into the simulator: | ||
# | ||
# 1. Copy/paste the two `list APPEND commands` below, puttting in the path to the | ||
# plugin (where the CMakeLists.txt lives), and the plugin cmake library name | ||
# | ||
# 2. In the plugin, find the file where init(rack::Plugin*) is defined, and rename it to init_Brand | ||
# You can use #if defined(METAMODULE_BUILTIN) so that it's still called init() when building as a plugin for Rack or MM. | ||
# `Brand` in init_Brand must match the plugin cmake library name you used in step 1. | ||
|
||
# Example with Venom: | ||
# list(APPEND ext_builtin_brand_paths "${CMAKE_CURRENT_LIST_DIR}/../../metamodule-plugin-examples/Venom") | ||
# list(APPEND ext_builtin_brand_libname "Venom") | ||
|
||
|
||
# | ||
# Asset dir | ||
# | ||
|
||
cmake_path(SET ASSET_DIR "${CMAKE_CURRENT_BINARY_DIR}/assets") | ||
set(ASSET_IMG_FILENAME assets.uimg) | ||
cmake_path(APPEND ASSET_IMG_PATH "${CMAKE_CURRENT_BINARY_DIR}" "${ASSET_IMG_FILENAME}") | ||
|
||
message("set ASSET_DIR to ${ASSET_DIR}") | ||
message("set ASSET_IMG_PATH to ${ASSET_IMG_PATH}") | ||
|
||
add_custom_command( | ||
OUTPUT ${ASSET_DIR} | ||
COMMAND ${CMAKE_COMMAND} -E echo Copying "${FWDIR}/assets" to "${ASSET_DIR}" | ||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${FWDIR}/assets" "${ASSET_DIR}" | ||
COMMENT "Copying assets/ dir from ${FWDIR}/assets to ${ASSET_DIR}" | ||
VERBATIM USES_TERMINAL | ||
) | ||
|
||
add_custom_command( | ||
OUTPUT ${ASSET_IMG_PATH} | ||
COMMAND cd ${ASSET_DIR} && ${CMAKE_COMMAND} -E tar -cf ${ASSET_IMG_PATH}.tar . | ||
COMMAND cd ${FWDIR} && flashing/uimg_header.py --name Assets ${ASSET_IMG_PATH}.tar ${ASSET_IMG_PATH} | ||
COMMENT "Creating assets uimg file at ${ASSET_IMG_PATH}" | ||
DEPENDS ${ASSET_DIR} | ||
VERBATIM USES_TERMINAL | ||
) | ||
|
||
add_custom_target(asset-image ALL | ||
DEPENDS ${ASSET_IMG_PATH} | ||
) | ||
|
||
set(EXT_PLUGIN_INIT_CALLS "") | ||
|
||
foreach(branddir brand IN ZIP_LISTS ext_builtin_brand_paths ext_builtin_brand_libname) | ||
set(METAMODULE_SDK_DIR ${CMAKE_CURRENT_LIST_DIR}) | ||
add_subdirectory(${branddir} ${CMAKE_CURRENT_BINARY_DIR}/builtins/${brand}) | ||
|
||
target_link_libraries(${brand} PRIVATE metamodule::vcv-plugin-interface) | ||
target_link_libraries(${brand} PRIVATE cpputil::cpputil) | ||
target_compile_definitions(${brand} PRIVATE METAMODULE METAMODULE_BUILTIN) | ||
|
||
target_link_libraries(_vcv_ports_internal PUBLIC ${brand}) | ||
add_dependencies(asset-image ${brand}-assets) | ||
|
||
string(APPEND EXT_PLUGIN_INIT_CALLS "\textern void init_${brand}(rack::plugin::Plugin *);\n\tinit_${brand}(&internal_plugins.emplace_back(\"${brand}\"));") | ||
endforeach() | ||
|
||
configure_file(src/ext_plugin_builtin.hh.in ${CMAKE_CURRENT_BINARY_DIR}/ext_plugin/ext_plugin_builtin.hh) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# TODO: Get cmake to copy the source file that contains init() and rename that function to init_BRAND() | ||
# Also see if Cmake can generate the calls to init (currently manually written into simulator/src/ext_plugin_builtin.hh) | ||
|
||
# file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/replace.cmake" | ||
# [=[ | ||
# file(READ "${SOURCE}" TEXT) | ||
# string(REPLACE "foo" "bar" TEXT "${TEXT}") | ||
# file(WRITE "${TARGET}" "${TEXT}") | ||
# ]=]) | ||
|
||
# add_custom_command( | ||
# OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/plugin.cpp" | ||
# COMMAND "${CMAKE_COMMAND}" | ||
# "-DSOURCE=${CMAKE_CURRENT_SOURCE_DIR}/plugin.cpp" | ||
# "-DTARGET=${CMAKE_CURRENT_BINARY_DIR}/plugin.cpp" | ||
# -P "${CMAKE_CURRENT_BINARY_DIR}/replace.cmake" | ||
# DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/plugin.cpp" "${CMAKE_CURRENT_BINARY_DIR}/replace.cmake" | ||
# ) | ||
|
||
|
||
function(create_plugin) | ||
message("Building ${brand} as built-in plugin (create_plugin)") | ||
|
||
# target_sources(${PLUGIN_OPTIONS_SOURCE_LIB} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/plugin.cpp) | ||
|
||
set(oneValueArgs SOURCE_LIB SOURCE_ASSETS DESTINATION PLUGIN_NAME PLUGIN_JSON) | ||
cmake_parse_arguments(PLUGIN_OPTIONS "" "${oneValueArgs}" "" ${ARGN} ) | ||
|
||
add_custom_command( | ||
OUTPUT "${ASSET_DIR}/${PLUGIN_OPTIONS_PLUGIN_NAME}" | ||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${PLUGIN_OPTIONS_SOURCE_ASSETS}" "${ASSET_DIR}/${PLUGIN_OPTIONS_PLUGIN_NAME}" | ||
COMMENT "Copying ${PLUGIN_OPTIONS_SOURCE_ASSETS} to ${ASSET_DIR}/${PLUGIN_OPTIONS_PLUGIN_NAME}" | ||
VERBATIM | ||
) | ||
|
||
add_custom_target(${PLUGIN_OPTIONS_SOURCE_LIB}-assets | ||
DEPENDS "${ASSET_DIR}/${PLUGIN_OPTIONS_PLUGIN_NAME}" | ||
) | ||
|
||
|
||
endfunction() |
Oops, something went wrong.