Retire legacy sources and verify managed iOS deployment
.NET port / test (macos-latest) (push) Canceled after 0s
.NET port / test (ubuntu-24.04) (push) Canceled after 0s
.NET port / test (windows-latest) (push) Canceled after 0s
.NET port / apple-client (push) Canceled after 0s

This commit is contained in:
2026-09-19 22:40:48 +02:00
parent 42e3bbe14c
commit c9ed832459
109 changed files with 877 additions and 4981 deletions
+103
View File
@@ -0,0 +1,103 @@
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()
set(VOICECAT_MEDIA_LIBRARY_TYPE SHARED)
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(VOICECAT_MEDIA_LIBRARY_TYPE STATIC)
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}/../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 ${VOICECAT_MEDIA_LIBRARY_TYPE} 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
ARCHIVE 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()
+12
View File
@@ -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/
+55
View File
@@ -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);
}