Add managed codec DSP and initial control server
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
project(VoiceCatMedia LANGUAGES C)
|
||||
|
||||
if(MSVC)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
set(OPUS_STATIC_RUNTIME ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
message(FATAL_ERROR "iOS static NativeReference packaging belongs to the later client phase.")
|
||||
endif()
|
||||
|
||||
if(NOT TARGET Opus::opus)
|
||||
set(bundled_default OFF)
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(bundled_default ON)
|
||||
endif()
|
||||
option(VOICECAT_BUNDLED_OPUS "Build pinned Opus with DRED support" ${bundled_default})
|
||||
if(VOICECAT_BUNDLED_OPUS)
|
||||
include(FetchContent)
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
set(OPUS_DRED ON CACHE BOOL "" FORCE)
|
||||
set(OPUS_DEEP_PLC ON CACHE BOOL "" FORCE)
|
||||
set(OPUS_BUILD_PROGRAMS OFF CACHE BOOL "" FORCE)
|
||||
set(OPUS_BUILD_TESTING OFF CACHE BOOL "" FORCE)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
FetchContent_Declare(opus
|
||||
URL https://downloads.xiph.org/releases/opus/opus-1.5.2.tar.gz
|
||||
URL_HASH SHA256=65c1d2f78b9f2fb20082c38cbe47c951ad5839345876e46941612ee87f9a7ce1
|
||||
TIMEOUT 60
|
||||
INACTIVITY_TIMEOUT 30
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
|
||||
FetchContent_MakeAvailable(opus)
|
||||
set(VOICECAT_OPUS_LICENSE "${opus_SOURCE_DIR}/COPYING")
|
||||
else()
|
||||
find_package(Opus CONFIG REQUIRED)
|
||||
endif()
|
||||
endif()
|
||||
if(NOT VOICECAT_OPUS_LICENSE)
|
||||
find_file(VOICECAT_OPUS_LICENSE NAMES copyright COPYING HINTS "${Opus_DIR}" NO_DEFAULT_PATH)
|
||||
endif()
|
||||
if(NOT VOICECAT_OPUS_LICENSE)
|
||||
message(FATAL_ERROR "Set VOICECAT_OPUS_LICENSE to the imported Opus copyright file for native staging.")
|
||||
endif()
|
||||
set(RNNOISE_DIR "${CMAKE_CURRENT_LIST_DIR}/../../third_party/rnnoise")
|
||||
if(NOT TARGET rnnoise)
|
||||
add_library(rnnoise STATIC
|
||||
${RNNOISE_DIR}/src/denoise.c ${RNNOISE_DIR}/src/rnn.c
|
||||
${RNNOISE_DIR}/src/pitch.c ${RNNOISE_DIR}/src/kiss_fft.c
|
||||
${RNNOISE_DIR}/src/celt_lpc.c ${RNNOISE_DIR}/src/nnet.c
|
||||
${RNNOISE_DIR}/src/nnet_default.c ${RNNOISE_DIR}/src/parse_lpcnet_weights.c
|
||||
${RNNOISE_DIR}/src/rnnoise_data.c ${RNNOISE_DIR}/src/rnnoise_tables.c)
|
||||
target_include_directories(rnnoise PUBLIC ${RNNOISE_DIR}/include PRIVATE ${RNNOISE_DIR}/src)
|
||||
target_compile_definitions(rnnoise PRIVATE DISABLE_DEBUG_FLOAT)
|
||||
if(MSVC)
|
||||
target_compile_definitions(rnnoise PRIVATE restrict=__restrict)
|
||||
endif()
|
||||
target_compile_features(rnnoise PRIVATE c_std_11)
|
||||
set_target_properties(rnnoise PROPERTIES POSITION_INDEPENDENT_CODE ON C_VISIBILITY_PRESET hidden)
|
||||
endif()
|
||||
|
||||
add_library(voicecat_media SHARED media.c)
|
||||
target_compile_features(voicecat_media PRIVATE c_std_99)
|
||||
target_link_libraries(voicecat_media PRIVATE Opus::opus rnnoise)
|
||||
set_target_properties(voicecat_media PROPERTIES C_VISIBILITY_PRESET hidden)
|
||||
if(WIN32)
|
||||
set_target_properties(voicecat_media PROPERTIES PREFIX "")
|
||||
endif()
|
||||
if(NOT WIN32)
|
||||
target_link_libraries(voicecat_media PRIVATE m)
|
||||
elseif(MINGW)
|
||||
target_link_options(voicecat_media PRIVATE -static-libgcc -static)
|
||||
endif()
|
||||
|
||||
if(NOT VOICECAT_DOTNET_RID)
|
||||
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" architecture)
|
||||
if(architecture MATCHES "^(amd64|x86_64)$")
|
||||
set(architecture x64)
|
||||
elseif(architecture MATCHES "^(aarch64|arm64)$")
|
||||
set(architecture arm64)
|
||||
else()
|
||||
message(FATAL_ERROR "Set VOICECAT_DOTNET_RID for architecture ${architecture}")
|
||||
endif()
|
||||
if(WIN32)
|
||||
set(platform win)
|
||||
elseif(APPLE)
|
||||
set(platform osx)
|
||||
else()
|
||||
set(platform linux)
|
||||
endif()
|
||||
set(VOICECAT_DOTNET_RID "${platform}-${architecture}")
|
||||
endif()
|
||||
|
||||
install(TARGETS voicecat_media
|
||||
RUNTIME DESTINATION runtimes/${VOICECAT_DOTNET_RID}/native COMPONENT DotnetMedia
|
||||
LIBRARY DESTINATION runtimes/${VOICECAT_DOTNET_RID}/native COMPONENT DotnetMedia)
|
||||
install(FILES ${RNNOISE_DIR}/COPYING DESTINATION licenses RENAME RNNoise.txt COMPONENT DotnetMedia)
|
||||
install(FILES ${CMAKE_CURRENT_LIST_DIR}/NOTICE.txt DESTINATION licenses COMPONENT DotnetMedia)
|
||||
if(VOICECAT_OPUS_LICENSE)
|
||||
install(FILES ${VOICECAT_OPUS_LICENSE} DESTINATION licenses RENAME Opus.txt COMPONENT DotnetMedia)
|
||||
endif()
|
||||
@@ -0,0 +1,12 @@
|
||||
VoiceCat desktop codec/DSP bindings
|
||||
|
||||
Opus 1.5.2: BSD-3-Clause. See Opus.txt for copyright, license, and patent notices.
|
||||
Upstream: https://opus-codec.org/
|
||||
Release: https://downloads.xiph.org/releases/opus/opus-1.5.2.tar.gz
|
||||
SHA-256: 65c1d2f78b9f2fb20082c38cbe47c951ad5839345876e46941612ee87f9a7ce1
|
||||
|
||||
RNNoise code: BSD-3-Clause. See RNNoise.txt.
|
||||
RNNoise model weights: CC0-1.0, as recorded in third_party/README.md.
|
||||
Upstream: https://github.com/xiph/rnnoise
|
||||
Vendored commit: 70f1d256acd4b34a572f999a05c87bf00b67730d
|
||||
CC0: https://creativecommons.org/publicdomain/zero/1.0/
|
||||
@@ -0,0 +1,55 @@
|
||||
#include <opus.h>
|
||||
#include "rnnoise.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define VC_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define VC_EXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
VC_EXPORT const char *vcm_opus_version(void) { return opus_get_version_string(); }
|
||||
VC_EXPORT const char *vcm_opus_error(int error) { return opus_strerror(error); }
|
||||
VC_EXPORT OpusEncoder *vcm_encoder_create(int rate, int channels, int application, int *error) {
|
||||
return opus_encoder_create(rate, channels, application, error);
|
||||
}
|
||||
VC_EXPORT void vcm_encoder_destroy(OpusEncoder *encoder) { opus_encoder_destroy(encoder); }
|
||||
/* C varargs are called here, not through P/Invoke: Apple arm64 uses a distinct varargs ABI. */
|
||||
VC_EXPORT int vcm_encoder_set(OpusEncoder *encoder, int request, int value) {
|
||||
switch (request) {
|
||||
case OPUS_SET_BITRATE_REQUEST: case OPUS_SET_MAX_BANDWIDTH_REQUEST:
|
||||
case OPUS_SET_COMPLEXITY_REQUEST: case OPUS_SET_INBAND_FEC_REQUEST:
|
||||
case OPUS_SET_DTX_REQUEST: case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
|
||||
case OPUS_SET_DRED_DURATION_REQUEST:
|
||||
return opus_encoder_ctl(encoder, request, value);
|
||||
default: return OPUS_BAD_ARG;
|
||||
}
|
||||
}
|
||||
VC_EXPORT int vcm_encoder_get_dred(OpusEncoder *encoder, int *duration) {
|
||||
return opus_encoder_ctl(encoder, OPUS_GET_DRED_DURATION(duration));
|
||||
}
|
||||
VC_EXPORT int vcm_encode(OpusEncoder *encoder, const short *pcm, int samples, unsigned char *packet, int capacity) {
|
||||
return opus_encode(encoder, pcm, samples, packet, capacity);
|
||||
}
|
||||
VC_EXPORT OpusDecoder *vcm_decoder_create(int rate, int channels, int *error) {
|
||||
return opus_decoder_create(rate, channels, error);
|
||||
}
|
||||
VC_EXPORT void vcm_decoder_destroy(OpusDecoder *decoder) { opus_decoder_destroy(decoder); }
|
||||
VC_EXPORT int vcm_decode(OpusDecoder *decoder, const unsigned char *packet, int length, short *pcm, int samples, int fec) {
|
||||
return opus_decode(decoder, packet, length, pcm, samples, fec);
|
||||
}
|
||||
VC_EXPORT OpusDREDDecoder *vcm_dred_decoder_create(int *error) { return opus_dred_decoder_create(error); }
|
||||
VC_EXPORT void vcm_dred_decoder_destroy(OpusDREDDecoder *decoder) { opus_dred_decoder_destroy(decoder); }
|
||||
VC_EXPORT OpusDRED *vcm_dred_create(int *error) { return opus_dred_alloc(error); }
|
||||
VC_EXPORT void vcm_dred_destroy(OpusDRED *dred) { opus_dred_free(dred); }
|
||||
VC_EXPORT int vcm_dred_parse(OpusDREDDecoder *decoder, OpusDRED *dred, const unsigned char *packet,
|
||||
int length, int samples, int rate, int *end) {
|
||||
return opus_dred_parse(decoder, dred, packet, length, samples, rate, end, 0);
|
||||
}
|
||||
VC_EXPORT int vcm_dred_decode(OpusDecoder *decoder, OpusDRED *dred, int offset, short *pcm, int samples) {
|
||||
return opus_decoder_dred_decode(decoder, dred, offset, pcm, samples);
|
||||
}
|
||||
VC_EXPORT DenoiseState *vcm_rnnoise_create(void) { return rnnoise_create(NULL); }
|
||||
VC_EXPORT void vcm_rnnoise_destroy(DenoiseState *state) { rnnoise_destroy(state); }
|
||||
VC_EXPORT float vcm_rnnoise_process(DenoiseState *state, float *output, const float *input) {
|
||||
return rnnoise_process_frame(state, output, input);
|
||||
}
|
||||
Reference in New Issue
Block a user