Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake support, modernized rnnoise example with libsoundfile and CI setup based on Github Actions #227

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
100 changes: 100 additions & 0 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
name: CMake on multiple platforms

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: ${{ matrix.os }}

strategy:
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
fail-fast: false

# Set up a matrix to run the following 3 configurations:
# 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
# 2. <Linux, Release, latest GCC compiler toolchain on the default runner image, default generator>
# 3. <Linux, Release, latest Clang compiler toolchain on the default runner image, default generator>
#
# To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
matrix:
os: [ubuntu-latest, windows-latest]
build_type: [Release]
c_compiler: [gcc, clang, cl]
conan_profile: [conan-default, conan-release]
include:
- os: windows-latest
c_compiler: cl
cpp_compiler: cl
conan_profile: conan-default
- os: ubuntu-latest
c_compiler: gcc
cpp_compiler: g++
conan_profile: conan-release
- os: ubuntu-latest
c_compiler: clang
cpp_compiler: clang++
conan_profile: conan-release
exclude:
- os: windows-latest
c_compiler: gcc
- os: windows-latest
c_compiler: clang
- os: windows-latest
conan_profile: conan-release
- os: ubuntu-latest
c_compiler: cl
- os: ubuntu-latest
conan_profile: conan-default

steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install conan dependencies for runner
run: pip install conan

- name: Set reusable strings
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
id: strings
shell: bash
run: |
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"

- name: Install conan dependencies
run: |
conan profile detect --force
conan install ${{ github.workspace }}/conanfile.txt --build=missing --settings=build_type=Release

- name: Configure CMake under Linux OS
if: matrix.os == 'ubuntu-latest'
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/build/Release/generators/conan_toolchain.cmake
-S ${{ github.workspace }}
- name: Configure CMake under Windows
if: matrix.os == 'windows-latest'
run : >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-S ${{ github.workspace }}
--preset=${{ matrix.conan_profile }}

- name: Build
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}

- name: Test
working-directory: ${{ steps.strings.outputs.build-output-dir }}
# Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest --build-config ${{ matrix.build_type }}
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
build/
downloads
src/rnnoise_data_little.c
src/rnnoise_data_little.h
src/rnnoise_data.h
src/rnnoise_data.c
CMakeUserPresets.json
.vscode/
.DS_Store
sample_audios/
evaluation_output/
rnnoise_env/
120 changes: 120 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
cmake_minimum_required(VERSION 3.21)
project(rnnoise)

option(RNNOISE_COMPILE_OPUS OFF)
option(RNNOISE_COMPILE_DEMO ON)
option(RNNOISE_BAREMETAL OFF)

if(NOT RNNOISE_BAREMETAL)
find_package(mimalloc REQUIRED)
endif()

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping")
endif()

if(RNNOISE_COMPILE_OPUS)
add_definitions(-DCOMPILE_OPUS)
endif()

# Ignore CRT warnings on MSVC
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()

#Pre-Generate library resources
set(RNNOISE_MODEL_VERSION "0b50c45")
set(RNNOISE_MODEL_TAR "rnnoise_data-${RNNOISE_MODEL_VERSION}.tar.gz")
set(FILE_URL "https://media.xiph.org/rnnoise/models/${RNNOISE_MODEL_TAR}")
set(RNNOISE_DATA_DOWNLOADS_DIR ${CMAKE_CURRENT_LIST_DIR}/downloads/)
set(RNNOISE_DOWNLOADED_PATH ${RNNOISE_DATA_DOWNLOADS_DIR}/${RNNOISE_MODEL_TAR})



if(NOT EXISTS "${RNNOISE_DOWNLOADED_PATH}")

file(DOWNLOAD ${FILE_URL} ${RNNOISE_DOWNLOADED_PATH}
STATUS RNNOISE_DOWNLOAD_STATUS
TIMEOUT 60
SHOW_PROGRESS)

if(RNNOISE_DOWNLOAD_STATUS EQUAL 0)
message("File downloaded successfully.")
else()
message(FATAL_ERROR "Failed to download file: ${RNNOISE_DOWNLOAD_STATUS}")

endif()

execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf ${RNNOISE_DOWNLOADED_PATH}
WORKING_DIRECTORY ${RNNOISE_DATA_DOWNLOADS_DIR}
)

endif()

if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/src/rnnoise_data.c")
set(RNNOISE_MODEL_UNPACKED_SOURCE_DIR ${RNNOISE_DATA_DOWNLOADS_DIR}/src)
set(RNNOIDE_MODEL_FILES_DESTINATION ${CMAKE_CURRENT_LIST_DIR}/src)

file(COPY ${RNNOISE_MODEL_UNPACKED_SOURCE_DIR}/rnnoise_data_little.h DESTINATION ${RNNOIDE_MODEL_FILES_DESTINATION})
file(COPY ${RNNOISE_MODEL_UNPACKED_SOURCE_DIR}/rnnoise_data_little.c DESTINATION ${RNNOIDE_MODEL_FILES_DESTINATION})
file(COPY ${RNNOISE_MODEL_UNPACKED_SOURCE_DIR}/rnnoise_data.c DESTINATION ${RNNOIDE_MODEL_FILES_DESTINATION})
file(COPY ${RNNOISE_MODEL_UNPACKED_SOURCE_DIR}/rnnoise_data.h DESTINATION ${RNNOIDE_MODEL_FILES_DESTINATION})
endif()

# Get source files

set(RN_NOISE_SRC
src/_kiss_fft_guts.h
src/arch.h
src/celt_lpc.h
src/common.h
src/cpu_support.h
src/denoise.h
src/kiss_fft.h
src/nnet_arch.h
src/nnet.h
src/opus_types.h
src/pitch.h
src/rnn.h
src/rnnoise_data_little.h
include/rnnoise.h
src/vec.h

src/celt_lpc.c
src/nnet_default.c
src/rnn.c
src/rnnoise_tables.c
src/denoise.c
src/kiss_fft.c
src/parse_lpcnet_weights.c
src/rnnoise_data_little.c
#write_weights.c
#dump_features.c
src/nnet.c
src/pitch.c
)

add_library(rnnoise STATIC ${RN_NOISE_SRC})

add_definitions(-DRNNOISE_BUILD)

# Include dirs
target_include_directories(rnnoise PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE src)


if(NOT RNNOISE_BAREMETAL)
target_link_libraries(rnnoise PUBLIC mimalloc-static)
target_compile_definitions(rnnoise PUBLIC USE_MIMALLOC_ALLOCATOR)
endif()

if (UNIX)
target_link_libraries(rnnoise PUBLIC m)
endif(UNIX)

if(RNNOISE_COMPILE_DEMO)
add_subdirectory(examples)
endif()
5 changes: 5 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,8 @@ model, rename rnnoise_data_little.c to rnnoise_data.c. It is possible
to build both the regular and little binary weights and load any of them
at run time since the little model has the same size as the regular one
(except for the increased sparsity).

## Build with Vitis Xilinx toolchain:
```shell
cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE="Release" DCMAKE_TOOLCHAIN_FILE="${PWD}/cmake/vitis_toolchain.cmake" -S="$PWD}" -B="${PWD}/build" -DRNNOISE_COMPILE_DEMO=OFF DRNNOISE_BAREMETAL=ON
```
11 changes: 11 additions & 0 deletions conanfile.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[requires]
libsndfile/1.2.2
cxxopts/3.2.0
fmt/10.2.1
mimalloc/2.1.2

[generators]
CMakeDeps
CMakeToolchain
[layout]
cmake_layout
32 changes: 32 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
set (CMAKE_CXX_STANDARD 17)

add_executable(rnnoise_demo rnnoise_demo.c)

target_link_libraries(rnnoise_demo PRIVATE rnnoise)

find_package(SndFile REQUIRED)
find_package(cxxopts REQUIRED)
find_package(fmt REQUIRED)
find_package(mimalloc REQUIRED)

add_executable(rnnoise_libsoundfile
rnnoise_libsndfile.cpp
profiling/xcorr_impl.cpp
profiling/xcorr_offload_kernel.cpp
)

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
message(WARNING "Compiling RNNOISE for Windows...")
target_compile_definitions(rnnoise_libsoundfile PRIVATE WINDOWS_SPECIFIC_MACRO)
endif()

target_link_libraries(
rnnoise_libsoundfile
PRIVATE
rnnoise
SndFile::sndfile
cxxopts::cxxopts
fmt::fmt
mimalloc-static
)
target_include_directories(rnnoise_libsoundfile PRIVATE ${CMAKE_CURRENT_LIST_DIR})
15 changes: 15 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Building with Conan
```shell
pip install conan
mkdir build

## For debug version of the app
conan install conanfile.txt --build=missing --settings=build_type=Debug
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=./Debug/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -B build
cmake --build build

## For Release version:
conan install conanfile.txt --build=missing
cmake -G"Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=./Release/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -B build
cmake --build buil
```
33 changes: 33 additions & 0 deletions examples/lazy_file_writer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once
#include <filesystem>
#include <fstream>
#include <iostream>

class LazyFileWriter {
private:
std::filesystem::path m_filepath;
std::fstream m_file_stream;
void openFileIfNeeded() {
if (!m_file_stream.is_open()) {
m_file_stream.open(m_filepath, std::ios::out | std::ios::app);
if (!m_file_stream.is_open()) {
throw std::runtime_error("Failed to open the lazy file writer");
}
}
}

public:
LazyFileWriter(const std::filesystem::path& filepath) : m_filepath{filepath}{}

~LazyFileWriter() {
if (m_file_stream.is_open()) {
m_file_stream.close();
}
}

template<typename TypeToWrite>
void write(TypeToWrite&& data) {
openFileIfNeeded();
m_file_stream << data << std::endl;
}
};
Loading