diff --git a/.github/actions/build-plugin/action.yaml b/.github/actions/build-plugin/action.yaml index 127f933..3bb219d 100644 --- a/.github/actions/build-plugin/action.yaml +++ b/.github/actions/build-plugin/action.yaml @@ -11,7 +11,7 @@ inputs: acceleration: description: 'Enable acceleration' required: false - default: 'cpu' + default: 'generic' codesign: description: 'Enable codesigning (macOS only)' required: false @@ -59,6 +59,8 @@ runs: if: runner.os == 'Linux' shell: zsh --no-rcs --errexit --pipefail {0} working-directory: ${{ inputs.workingDirectory }} + env: + ACCELERATION: ${{ inputs.acceleration }} run: | : Run Ubuntu Build diff --git a/.github/actions/package-plugin/action.yaml b/.github/actions/package-plugin/action.yaml index 2827bb3..d143b9f 100644 --- a/.github/actions/package-plugin/action.yaml +++ b/.github/actions/package-plugin/action.yaml @@ -11,7 +11,7 @@ inputs: acceleration: description: 'Enable acceleration' required: false - default: 'cpu' + default: 'generic' codesign: description: 'Enable codesigning (macOS only)' required: false @@ -88,6 +88,8 @@ runs: if: runner.os == 'Linux' shell: zsh --no-rcs --errexit --pipefail {0} working-directory: ${{ inputs.workingDirectory }} + env: + ACCELERATION: ${{ inputs.acceleration }} run: | : Run Ubuntu Packaging package_args=( diff --git a/.github/scripts/.Aptfile b/.github/scripts/.Aptfile index 1709f79..4197580 100644 --- a/.github/scripts/.Aptfile +++ b/.github/scripts/.Aptfile @@ -2,7 +2,13 @@ package 'cmake' package 'ccache' package 'git' package 'jq' +package 'libcurl4-openssl-dev' +package 'libicu-dev' +package 'libopenblas-dev' +package 'libopenblas-openmp-dev' +package 'libsimde-dev' package 'ninja-build', bin: 'ninja' +package 'nvidia-opencl-dev' +package 'ocl-icd-opencl-dev' +package 'opencl-headers' package 'pkg-config' -package 'libopenblas-dev' -package 'libavformat-dev' diff --git a/.github/scripts/.package.zsh b/.github/scripts/.package.zsh index cefb007..0a92c59 100755 --- a/.github/scripts/.package.zsh +++ b/.github/scripts/.package.zsh @@ -256,7 +256,7 @@ ${_usage_host:-}" popd } else { log_group "Archiving ${product_name}..." - local output_name="${product_name}-${product_version}-${target##*-}-linux-gnu" + local output_name="${product_name}-${product_version}-${target##*-}linux-gnu-${+ACCELERATION}" local _tarflags='cJf' if (( _loglevel > 1 || ${+CI} )) _tarflags="v${_tarflags}" diff --git a/.github/scripts/Package-Windows.ps1 b/.github/scripts/Package-Windows.ps1 index 63c34ab..17a8606 100644 --- a/.github/scripts/Package-Windows.ps1 +++ b/.github/scripts/Package-Windows.ps1 @@ -4,8 +4,8 @@ param( [string] $Target = 'x64', [ValidateSet('Debug', 'RelWithDebInfo', 'Release', 'MinSizeRel')] [string] $Configuration = 'RelWithDebInfo', - [ValidateSet('cpu', 'cuda', 'hipblas')] - [string] $acceleration = 'cpu', + [ValidateSet('generic', 'nvidia', 'amd')] + [string] $acceleration = 'generic', [switch] $BuildInstaller, [switch] $SkipDeps ) diff --git a/.github/scripts/utils.zsh/check_macos b/.github/scripts/utils.zsh/check_macos index 9c63496..714d09c 100644 --- a/.github/scripts/utils.zsh/check_macos +++ b/.github/scripts/utils.zsh/check_macos @@ -4,8 +4,8 @@ local macos_version=$(sw_vers -productVersion) log_group 'Install macOS build requirements' log_info 'Checking macOS version...' -if ! is-at-least 11.0 ${macos_version}; then - log_error "Minimum required macOS version is 11.0, but running on macOS ${macos_version}" +if ! is-at-least 12.0 ${macos_version}; then + log_error "Minimum required macOS version is 12.0, but running on macOS ${macos_version}" return 2 else log_status "macOS ${macos_version} is recent" diff --git a/.github/scripts/utils.zsh/setup_ccache b/.github/scripts/utils.zsh/setup_ccache index f06733d..b72d125 100644 --- a/.github/scripts/utils.zsh/setup_ccache +++ b/.github/scripts/utils.zsh/setup_ccache @@ -10,7 +10,6 @@ if (( ${+commands[ccache]} )) { typeset -gx CCACHE_CONFIGPATH="${project_root}/.ccache.conf" - ccache --set-config=run_second_cpp=true ccache --set-config=direct_mode=true ccache --set-config=inode_cache=true ccache --set-config=compiler_check=content diff --git a/.github/scripts/utils.zsh/setup_linux b/.github/scripts/utils.zsh/setup_linux index 9efe243..1c595e5 100644 --- a/.github/scripts/utils.zsh/setup_linux +++ b/.github/scripts/utils.zsh/setup_linux @@ -45,20 +45,11 @@ if (( ! (${skips[(Ie)all]} + ${skips[(Ie)deps]}) )) { local -a _qt_packages=() - if (( QT_VERSION == 5 )) { - _qt_packages+=( - qtbase5-dev${suffix} - libqt5svg5-dev${suffix} - qtbase5-private-dev${suffix} - libqt5x11extras5-dev${suffix} - ) - } else { - _qt_packages+=( - qt6-base-dev${suffix} - libqt6svg6-dev${suffix} - qt6-base-private-dev${suffix} - ) - } + _qt_packages+=( + qt6-base-dev${suffix} + libqt6svg6-dev${suffix} + qt6-base-private-dev${suffix} + ) sudo apt-get install ${apt_args} ${_qt_packages} log_group diff --git a/.github/workflows/build-project.yaml b/.github/workflows/build-project.yaml index 4470023..fdc1b8a 100644 --- a/.github/workflows/build-project.yaml +++ b/.github/workflows/build-project.yaml @@ -58,7 +58,7 @@ jobs: macos-build: name: Build for macOS 🍏 - runs-on: macos-13 + runs-on: macos-14 needs: check-event strategy: matrix: @@ -92,13 +92,18 @@ jobs: print "pluginName=${product_name}" >> $GITHUB_OUTPUT print "pluginVersion=${product_version}" >> $GITHUB_OUTPUT + - uses: maxim-lobanov/setup-xcode@v1.6.0 + id: set-xcode-version + with: + xcode-version: 16.2 + - uses: actions/cache@v4 id: ccache-cache with: path: ${{ github.workspace }}/.ccache - key: ${{ runner.os }}-ccache-${{ needs.check-event.outputs.config }} + key: ${{ runner.os }}-ccache-${{ needs.check-event.outputs.config }}-${{ matrix.architecture }} restore-keys: | - ${{ runner.os }}-ccache- + ${{ runner.os }}-ccache-${{ matrix.architecture }}- - name: Set Up Codesigning 🔑 uses: ./.github/actions/setup-macos-codesigning @@ -157,10 +162,30 @@ jobs: name: Build for Ubuntu 🐧 runs-on: ubuntu-22.04 needs: check-event + strategy: + matrix: + acceleration: [generic, nvidia, amd] defaults: run: shell: bash steps: + - name: Free Disk Space (Ubuntu) + if: ${{ matrix.acceleration == 'amd' || matrix.acceleration == 'nvidia' }} + uses: jlumbroso/free-disk-space@main + with: + # this might remove tools that are actually needed, + # if set to "true" but frees about 6 GB + tool-cache: false + # Needs to be false to prevent running out of memory + swap-storage: false + # large-packages takes a long time so don't remove them unless we need to + large-packages: false + + android: true + dotnet: true + haskell: true + docker-images: true + - uses: actions/checkout@v4 with: submodules: recursive @@ -178,6 +203,36 @@ jobs: echo "pluginName=${product_name}" >> $GITHUB_OUTPUT echo "pluginVersion=${product_version}" >> $GITHUB_OUTPUT + - name: "Install Vulkan SDK" + run: | + wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo tee /etc/apt/trusted.gpg.d/lunarg.asc + sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-jammy.list http://packages.lunarg.com/vulkan/lunarg-vulkan-jammy.list + sudo apt update + sudo apt -y install vulkan-sdk + + # CUDA toolkit needed for linking against so it can be found when looking up package dependencies + - name: "Install CUDA toolkit 12.8" + if: ${{ matrix.acceleration == 'nvidia' }} + run: | + wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb + sudo dpkg -i cuda-keyring_1.1-1_all.deb + sudo apt update + sudo apt -y install cuda-12-8 + export PATH=/usr/local/cuda-12.8/bin${PATH:+:${PATH}} + export LD_LIBRARY_PATH=/usr/local/cuda-12.8/lib ${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + + # hip SDK needed for linking against so it can be found when looking up package dependencies + - name: "Install AMD hip SDK v6.4.2" + if: ${{ matrix.acceleration == 'amd' }} + run: | + wget https://repo.radeon.com/amdgpu-install/6.4.2/ubuntu/jammy/amdgpu-install_6.4.60402-1_all.deb + sudo apt install ./amdgpu-install_6.4.60402-1_all.deb + sudo apt update + sudo apt install python3-setuptools python3-wheel + sudo usermod -a -G render,video $LOGNAME # Add the current user to the render and video groups + sudo apt install rocm + sudo apt update && sudo apt install hipblas + - uses: actions/cache@v4 id: ccache-cache with: @@ -194,6 +249,7 @@ jobs: with: target: x86_64 config: ${{ needs.check-event.outputs.config }} + acceleration: ${{ matrix.acceleration }} - name: Package Plugin 📀 uses: ./.github/actions/package-plugin @@ -201,9 +257,11 @@ jobs: package: ${{ fromJSON(needs.check-event.outputs.package) }} target: x86_64 config: ${{ needs.check-event.outputs.config }} + acceleration: ${{ matrix.acceleration }} - name: Upload Source Tarball 🗜️ uses: actions/upload-artifact@v4 + if: ${{ matrix.acceleration == 'generic' }} with: name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-sources-${{ needs.check-event.outputs.commitHash }} path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-source.* @@ -211,15 +269,15 @@ jobs: - name: Upload Artifacts 📡 uses: actions/upload-artifact@v4 with: - name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-22.04-x86_64-${{ needs.check-event.outputs.commitHash }} - path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-x86_64*.* + name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-22.04-x86_64-${{ matrix.acceleration }}-${{ needs.check-event.outputs.commitHash }} + path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-x86_64-linux-gnu-${{ matrix.acceleration }}*.* - name: Upload debug symbol artifacts 🪲 uses: actions/upload-artifact@v4 if: ${{ fromJSON(needs.check-event.outputs.package) }} with: - name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-22.04-x86_64-${{ needs.check-event.outputs.commitHash }}-dbgsym - path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-x86_64*-dbgsym.ddeb + name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-ubuntu-22.04-x86_64-${{ matrix.acceleration }}-${{ needs.check-event.outputs.commitHash }}-dbgsym + path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-x86_64-linux-gnu--${{ matrix.acceleration }}*-dbgsym.ddeb windows-build: name: Build for Windows 🪟 @@ -227,7 +285,7 @@ jobs: needs: check-event strategy: matrix: - acceleration: [cpu, hipblas, cuda] + acceleration: [generic, nvidia, amd] defaults: run: shell: pwsh diff --git a/.github/workflows/check-format.yaml b/.github/workflows/check-format.yaml index e30b916..2d7b8ff 100644 --- a/.github/workflows/check-format.yaml +++ b/.github/workflows/check-format.yaml @@ -3,7 +3,7 @@ on: workflow_call: jobs: clang-format: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 75e7dd2..3a6a5e9 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -75,12 +75,14 @@ jobs: commit_hash="${GITHUB_SHA:0:9}" variants=( - 'windows-x64-cpu;zip|exe' - 'windows-x64-cuda;zip|exe' - 'windows-x64-hipblas;zip|exe' + 'windows-x64-generic;zip|exe' + 'windows-x64-nvidia;zip|exe' + 'windows-x64-amd;zip|exe' 'macos-arm64;tar.xz|pkg' 'macos-x86_64;tar.xz|pkg' - 'ubuntu-22.04-x86_64;tar.xz|deb|ddeb' + 'ubuntu-22.04-x86_64-generic;tar.xz|deb|ddeb' + 'ubuntu-22.04-x86_64-nvidia;tar.xz|deb|ddeb' + 'ubuntu-22.04-x86_64-amd;tar.xz|deb|ddeb' 'sources;tar.xz' ) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b76239..fbb00bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16...3.26) +cmake_minimum_required(VERSION 3.28...4.12) include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/bootstrap.cmake" NO_POLICY_SCOPE) @@ -7,6 +7,11 @@ project(${_name} VERSION ${_version}) option(ENABLE_FRONTEND_API "Use obs-frontend-api for UI functionality" ON) option(ENABLE_QT "Use Qt functionality" ON) +if(CMAKE_MAJOR_VERSION EQUAL 4) + message(STATUS "CMake 4 detected") + set(CMAKE_POLICY_VERSION_MINIMUM 3.5) +endif() + include(compilerconfig) include(defaults) include(helpers) @@ -22,8 +27,8 @@ if(ENABLE_FRONTEND_API) endif() if(ENABLE_QT) - find_qt(COMPONENTS Widgets Core) - target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Qt::Core Qt::Widgets) + find_package(Qt6 COMPONENTS Widgets Core) + target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Qt6::Core Qt6::Widgets) target_compile_options( ${CMAKE_PROJECT_NAME} PRIVATE $<$:-Wno-quoted-include-in-framework-header -Wno-comma>) @@ -34,8 +39,10 @@ if(ENABLE_QT) AUTORCC ON) endif() -include(cmake/FindLibAv.cmake) -find_libav() +if(APPLE OR WIN32) + include(cmake/FindLibAv.cmake) + find_libav() +endif() set(USE_SYSTEM_CURL OFF @@ -50,19 +57,17 @@ else() target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE libcurl) endif() -if(WIN32) - if(DEFINED ENV{ACCELERATION}) - set(ACCELERATION - $ENV{ACCELERATION} - CACHE STRING "Acceleration to use" FORCE) - endif() - if(NOT DEFINED ACCELERATION) - set(ACCELERATION - "cpu" - CACHE STRING "Acceleration to use") - endif() - set_property(CACHE ACCELERATION PROPERTY STRINGS "cpu" "hipblas" "cuda") +if(DEFINED ENV{ACCELERATION}) + set(ACCELERATION + $ENV{ACCELERATION} + CACHE STRING "Acceleration to use" FORCE) +endif() +if(NOT DEFINED ACCELERATION) + set(ACCELERATION + "generic" + CACHE STRING "Acceleration to use") endif() +set_property(CACHE ACCELERATION PROPERTY STRINGS "generic" "nvidia" "amd") include(cmake/BuildWhispercpp.cmake) target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Whispercpp) diff --git a/CMakePresets.json b/CMakePresets.json index 8531afb..8101a7b 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -2,7 +2,7 @@ "version": 3, "cmakeMinimumRequired": { "major": 3, - "minor": 22, + "minor": 28, "patch": 0 }, "configurePresets": [ @@ -17,7 +17,7 @@ { "name": "macos", "displayName": "macOS Universal", - "description": "Build for macOS 11.0+ (Universal binary)", + "description": "Build for macOS 12.0+ (Universal binary)", "inherits": ["template"], "binaryDir": "${sourceDir}/build_macos", "condition": { @@ -28,7 +28,7 @@ "generator": "Xcode", "warnings": {"dev": true, "deprecated": true}, "cacheVariables": { - "CMAKE_OSX_DEPLOYMENT_TARGET": "11.0", + "CMAKE_OSX_DEPLOYMENT_TARGET": "12.0", "CODESIGN_IDENTITY": "$penv{CODESIGN_IDENT}", "CODESIGN_TEAM": "$penv{CODESIGN_TEAM}" } @@ -37,7 +37,7 @@ "name": "macos-ci", "inherits": ["macos"], "displayName": "macOS Universal CI build", - "description": "Build for macOS 11.0+ (Universal binary) for CI", + "description": "Build for macOS 12.0+ (Universal binary) for CI", "generator": "Xcode", "cacheVariables": { "CMAKE_COMPILE_WARNING_AS_ERROR": true @@ -84,7 +84,8 @@ "generator": "Ninja", "warnings": {"dev": true, "deprecated": true}, "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithDebInfo" + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "USE_SYSTEM_CURL": true } }, { diff --git a/README.md b/README.md index ae48bf7..13a3674 100644 --- a/README.md +++ b/README.md @@ -74,10 +74,16 @@ Start by cloning this repo to a directory of your choice. ### Mac OSX +Set the `MACOS_ARCH` environment variable to `x86_64` or `arm64` as appropriate for the architecture you want to build for + +```sh +$ export MACOS_ARCH="arm64" +``` + Using the CI pipeline scripts, locally you would just call the zsh script. ```sh -$ ./.github/scripts/build-macos.zsh -c Release -t macos-x86_64 +$ ./.github/scripts/build-macos.zsh ``` #### Install @@ -91,6 +97,12 @@ $ ./.github/scripts/package-macos.zsh -c Release -t macos-x86_64 ### Linux (Ubuntu-ish) +Set the `ACCELERATION` environment variable to `generic`, `nvidia`, or `amd` to use the appropriate pre-built whisper libraries. `nvidia` includes CUDA support, `amd` includes ROCm support via hipblas, and all variants include Vulkan, OpenCL and OpenBLAS support + +```sh +$ export ACCELERATION="nvidia" +``` + Use the CI scripts again ```sh $ ./.github/scripts/build-linux.sh @@ -98,6 +110,12 @@ $ ./.github/scripts/build-linux.sh ### Windows +Set the `ACCELERATION` environment variable to `generic`, `nvidia`, or `amd` to use the appropriate pre-built whisper libraries. `nvidia` includes CUDA support, `amd` includes ROCm support via hipblas, and all variants include Vulkan and OpenBLAS support + +```powershell +> $env:ACCELERATION = "nvidia" +``` + Use the CI scripts again, for example: ```powershell @@ -110,16 +128,6 @@ The build should exist in the `./release` folder off the root. You can manually > Copy-Item -Recurse -Force "release\Release\*" -Destination "C:\Program Files\obs-studio\" ``` -#### Building with CUDA support on Windows - -CleanStream will now build with CUDA support automatically through a prebuilt binary of Whisper.cpp from https://github.com/occ-ai/occ-ai-dep-whispercpp. The CMake scripts will download all necessary files. - -To build with cuda add `CPU_OR_CUDA` as an environment variable (with `cpu`, `12.2.0` or `11.8.0`) and build regularly - -```powershell -> $env:CPU_OR_CUDA="12.2.0" -> .github/scripts/Build-Windows.ps1 -Configuration Release -``` ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=locaal-ai/obs-cleanstream&type=Date)](https://star-history.com/#locaal-ai/obs-cleanstream&Date) diff --git a/buildspec.json b/buildspec.json index abdb4b9..8b5dd85 100644 --- a/buildspec.json +++ b/buildspec.json @@ -1,34 +1,31 @@ { "dependencies": { "obs-studio": { - "version": "30.1.2", + "version": "31.1.1", "baseUrl": "https://github.com/obsproject/obs-studio/archive/refs/tags", "label": "OBS sources", "hashes": { - "macos": "490bae1c392b3b344b0270afd8cb887da4bc50bd92c0c426e96713c1ccb9701a", - "windows-x64": "c2dd03fa7fd01fad5beafce8f7156da11f9ed9a588373fd40b44a06f4c03b867" + "macos": "39751f067bacc13d44b116c5138491b5f1391f91516d3d590d874edd21292291", + "windows-x64": "2c8427c10b55ac6d68008df2e9a3e82f4647aaad18f105e30d4713c2de678ccf" } }, "prebuilt": { - "version": "2024-03-19", + "version": "2025-07-11", "baseUrl": "https://github.com/obsproject/obs-deps/releases/download", "label": "Pre-Built obs-deps", "hashes": { - "macos": "2e9bfb55a5e0e4c1086fa1fda4cf268debfead473089df2aaea80e1c7a3ca7ff", - "windows-x64": "6e86068371526a967e805f6f9903f9407adb683c21820db5f07da8f30d11e998" + "macos": "495687e63383d1a287684b6e2e9bfe246bb8f156fe265926afb1a325af1edd2a", + "windows-x64": "c8c642c1070dc31ce9a0f1e4cef5bb992f4bff4882255788b5da12129e85caa7" } }, "qt6": { - "version": "2024-03-19", + "version": "2025-02-04", "baseUrl": "https://github.com/obsproject/obs-deps/releases/download", "label": "Pre-Built Qt6", - "hashes": { - "macos": "694f1e639c017e3b1f456f735330dc5afae287cbea85757101af1368de3142c8", - "windows-x64": "72d1df34a0ef7413a681d5fcc88cae81da60adc03dcd23ef17862ab170bcc0dd" - }, - "debugSymbols": { - "windows-x64": "fbddd1f659c360f2291911ac5709b67b6f8182e6bca519d24712e4f6fd3cc865" - } + "hashes": { + "macos": "9472224e6f927cd409f9c3fcb53389e3b80f613ca7c4b62c02fae51cf0b2f941", + "windows-x64": "cf6a5223bfea04dccec3bbfbdcdc964933404fc3eda9c3f374bc4ab8c98d8c7e" + } } }, "platformConfig": { @@ -37,7 +34,7 @@ } }, "name": "obs-cleanstream", - "version": "0.1.3", + "version": "0.2.0", "author": "Roy Shilkrot", "website": "https://github.com/locaal-ai/obs-cleanstream/", "email": "roy.shil@gmail.com", diff --git a/cmake/BuildWhispercpp.cmake b/cmake/BuildWhispercpp.cmake index b51332e..269165c 100644 --- a/cmake/BuildWhispercpp.cmake +++ b/cmake/BuildWhispercpp.cmake @@ -1,16 +1,169 @@ include(ExternalProject) include(FetchContent) -set(PREBUILT_WHISPERCPP_VERSION "0.0.7") +set(PREBUILT_WHISPERCPP_VERSION "0.0.10-2") set(PREBUILT_WHISPERCPP_URL_BASE "https://github.com/locaal-ai/occ-ai-dep-whispercpp/releases/download/${PREBUILT_WHISPERCPP_VERSION}") +add_library(Whispercpp INTERFACE) + +# Get the name for the whisper library file from the CMake component name +function(LIB_NAME COMPONENT WHISPER_COMPONENT_IMPORT_LIB) + if((COMPONENT STREQUAL "Whisper") OR (COMPONENT STREQUAL "Whispercpp::Whisper")) + set(WHISPER_COMPONENT_IMPORT_LIB + whisper + PARENT_SCOPE) + elseif((COMPONENT STREQUAL "GGML") OR (COMPONENT STREQUAL "Whispercpp::GGML")) + set(WHISPER_COMPONENT_IMPORT_LIB + ggml + PARENT_SCOPE) + elseif((COMPONENT STREQUAL "WhisperCoreML") OR (COMPONENT STREQUAL "Whispercpp::WhisperCoreML")) + set(WHISPER_COMPONENT_IMPORT_LIB + whisper.coreml + PARENT_SCOPE) + else() + string(REGEX REPLACE "(Whispercpp::)?(GGML)" "\\2" COMPONENT ${COMPONENT}) + string(REGEX REPLACE "GGML(.*)" "\\1" LIB_SUFFIX ${COMPONENT}) + string(TOLOWER ${LIB_SUFFIX} IMPORT_LIB_SUFFIX) + set(WHISPER_COMPONENT_IMPORT_LIB + "ggml-${IMPORT_LIB_SUFFIX}" + PARENT_SCOPE) + endif() +endfunction() + +# Get library paths for Whisper libs +function(WHISPER_LIB_PATHS COMPONENT SOURCE_DIR WHISPER_STATIC_LIB_PATH WHISPER_SHARED_LIB_PATH + WHISPER_SHARED_MODULE_PATH) + lib_name(${COMPONENT} WHISPER_COMPONENT_IMPORT_LIB) + + if(UNIX AND NOT APPLE) + if(${LINUX_SOURCE_BUILD}) + set(STATIC_PATH ${SOURCE_DIR}) + set(SHARED_PATH ${SOURCE_DIR}) + set(SHARED_BIN_PATH ${SOURCE_DIR}) + else() + set(STATIC_PATH ${SOURCE_DIR}/lib) + set(SHARED_PATH ${SOURCE_DIR}/lib) + set(SHARED_BIN_PATH ${SOURCE_DIR}/bin) + endif() + else() + set(STATIC_PATH ${SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}) + set(SHARED_PATH ${SOURCE_DIR}/${CMAKE_INSTALL_LIBDIR}) + set(SHARED_BIN_PATH ${SOURCE_DIR}/${CMAKE_INSTALL_BINDIR}) + endif() + + set(WHISPER_STATIC_LIB_PATH + "${STATIC_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_STATIC_LIBRARY_SUFFIX}" + PARENT_SCOPE) + set(WHISPER_SHARED_LIB_PATH + "${SHARED_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_SHARED_LIBRARY_SUFFIX}" + PARENT_SCOPE) + set(WHISPER_SHARED_MODULE_PATH + "${SHARED_BIN_PATH}/${CMAKE_SHARED_MODULE_PREFIX}${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_SHARED_MODULE_SUFFIX}" + PARENT_SCOPE) + + # Debugging + set(WHISPER_STATIC_LIB_PATH + "${STATIC_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(WHISPER_SHARED_LIB_PATH + "${SHARED_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_SHARED_LIBRARY_SUFFIX}") + set(WHISPER_SHARED_MODULE_PATH + "${SHARED_BIN_PATH}/${CMAKE_SHARED_MODULE_PREFIX}${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_SHARED_MODULE_SUFFIX}") + message(STATUS "Whisper lib import path: " ${WHISPER_STATIC_LIB_PATH}) + message(STATUS "Whisper shared lib import path: " ${WHISPER_SHARED_LIB_PATH}) + message(STATUS "Whisper shared MODULE import path: " ${WHISPER_SHARED_MODULE_PATH}) +endfunction() + +# Add a Whisper component to the build +function(ADD_WHISPER_COMPONENT COMPONENT LIB_TYPE SOURCE_DIR LIB_DIR) + whisper_lib_paths(${COMPONENT} ${LIB_DIR} WHISPER_STATIC_LIB_PATH WHISPER_SHARED_LIB_PATH WHISPER_SHARED_MODULE_PATH) + lib_name(${COMPONENT} WHISPER_COMPONENT_IMPORT_LIB) + + if(APPLE AND (LIB_TYPE STREQUAL SHARED)) + target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE "${WHISPER_SHARED_LIB_PATH}") + target_sources(${CMAKE_PROJECT_NAME} PRIVATE "${WHISPER_SHARED_LIB_PATH}") + set_property(SOURCE "${WHISPER_SHARED_LIB_PATH}" PROPERTY MACOSX_PACKAGE_LOCATION Frameworks) + source_group("Frameworks" FILES "${WHISPER_SHARED_LIB_PATH}") + add_custom_command( + TARGET "${CMAKE_PROJECT_NAME}" + PRE_BUILD VERBATIM + COMMAND /usr/bin/codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" "${WHISPER_SHARED_LIB_PATH}") + message(STATUS "lib name: ${WHISPER_COMPONENT_IMPORT_LIB}") + if(${WHISPER_COMPONENT_IMPORT_LIB} STREQUAL whisper) + set(DYLIB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${WHISPER_COMPONENT_IMPORT_LIB}.1${CMAKE_SHARED_LIBRARY_SUFFIX}) + else() + set(DYLIB_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() + add_custom_command( + TARGET "${CMAKE_PROJECT_NAME}" + POST_BUILD + COMMAND ${CMAKE_INSTALL_NAME_TOOL} -change "@rpath/${DYLIB_NAME}" "@loader_path/../Frameworks/${DYLIB_NAME}" + $) + else() + add_library(${COMPONENT} ${LIB_TYPE} IMPORTED) + + if(LIB_TYPE STREQUAL STATIC) + set_target_properties(${COMPONENT} PROPERTIES IMPORTED_LOCATION "${WHISPER_STATIC_LIB_PATH}") + else() + set_target_properties(${COMPONENT} PROPERTIES IMPORTED_LOCATION "${WHISPER_SHARED_LIB_PATH}") + set_target_properties(${COMPONENT} PROPERTIES IMPORTED_IMPLIB "${WHISPER_STATIC_LIB_PATH}") + endif() + set_target_properties(${COMPONENT} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include") + target_link_libraries(Whispercpp INTERFACE ${COMPONENT}) + endif() +endfunction() + +function(ADD_WHISPER_RUNTIME_MODULE COMPONENT SOURCE_DIR LIB_DIR) + whisper_lib_paths(${COMPONENT} ${LIB_DIR} WHISPER_STATIC_LIB_PATH WHISPER_SHARED_LIB_PATH WHISPER_SHARED_MODULE_PATH) + lib_name(${COMPONENT} WHISPER_COMPONENT_IMPORT_LIB) + + if(APPLE) + target_include_directories(${CMAKE_PROJECT_NAME} SYSTEM PUBLIC "${SOURCE_DIR}/include") + target_sources(${CMAKE_PROJECT_NAME} PRIVATE "${WHISPER_SHARED_MODULE_PATH}") + set_property(SOURCE "${WHISPER_SHARED_MODULE_PATH}" PROPERTY MACOSX_PACKAGE_LOCATION Frameworks) + source_group("Frameworks" FILES "${WHISPER_SHARED_MODULE_PATH}") + # add a codesigning step + add_custom_command( + TARGET "${CMAKE_PROJECT_NAME}" + PRE_BUILD VERBATIM + COMMAND /usr/bin/codesign --force --verify --verbose --sign "${CODESIGN_IDENTITY}" + "${WHISPER_SHARED_MODULE_PATH}") + add_custom_command( + TARGET "${CMAKE_PROJECT_NAME}" + POST_BUILD + COMMAND + ${CMAKE_INSTALL_NAME_TOOL} -change "@rpath/${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_SHARED_MODULE_SUFFIX}" + "@loader_path/../Frameworks/${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_SHARED_MODULE_SUFFIX}" + $) + else() + add_library(${COMPONENT} SHARED IMPORTED) + set_target_properties(${COMPONENT} PROPERTIES IMPORTED_LOCATION "${WHISPER_SHARED_LIB_PATH}") + set_target_properties(${COMPONENT} PROPERTIES IMPORTED_IMPLIB "${WHISPER_STATIC_LIB_PATH}") + set_target_properties(${COMPONENT} PROPERTIES IMPORTED_NO_SONAME TRUE) + set_target_properties(${COMPONENT} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${SOURCE_DIR}/include") + endif() +endfunction() + if(APPLE) + add_compile_definitions(WHISPER_DYNAMIC_BACKENDS) + # check the "MACOS_ARCH" env var to figure out if this is x86 or arm64 if($ENV{MACOS_ARCH} STREQUAL "x86_64") - set(WHISPER_CPP_HASH "dc7fd5ff9c7fbb8623f8e14d9ff2872186cab4cd7a52066fcb2fab790d6092fc") + set(WHISPER_CPP_HASH "02446b1d508711b26cc778db48d5b8ef2dd7b0c98f5c9dfe39a1ad2ef9e3df07") + list( + APPEND + WHISPER_RUNTIME_MODULES + GGMLCPU-X64 + GGMLCPU-SSE42 + GGMLCPU-SANDYBRIDGE + GGMLCPU-HASWELL + GGMLCPU-SKYLAKEX + GGMLCPU-ICELAKE + GGMLCPU-ALDERLAKE + GGMLCPU-SAPPHIRERAPIDS) elseif($ENV{MACOS_ARCH} STREQUAL "arm64") - set(WHISPER_CPP_HASH "ebed595ee431b182261bce41583993b149eed539e15ebf770d98a6bc85d53a92") + set(WHISPER_CPP_HASH "ff2764b113e0f1fbafe0d8f86a339cd541d86a06d40a10eeac352050cc3be920") + list(APPEND WHISPER_RUNTIME_MODULES GGMLCPU-APPLE_M1 GGMLCPU-APPLE_M2_M3 GGMLCPU-APPLE_M4) else() message( FATAL_ERROR @@ -19,56 +172,61 @@ if(APPLE) set(WHISPER_CPP_URL "${PREBUILT_WHISPERCPP_URL_BASE}/whispercpp-macos-$ENV{MACOS_ARCH}-${PREBUILT_WHISPERCPP_VERSION}.tar.gz") + set(WHISPER_LIBRARIES Whisper WhisperCoreML GGML GGMLBase) + list(APPEND WHISPER_RUNTIME_MODULES GGMLMetal GGMLBlas) + set(WHISPER_DEPENDENCY_LIBRARIES "-framework Accelerate" "-framework CoreML" "-framework Metal" ${BLAS_LIBRARIES}) + set(WHISPER_LIBRARY_TYPE SHARED) + FetchContent_Declare( whispercpp_fetch URL ${WHISPER_CPP_URL} URL_HASH SHA256=${WHISPER_CPP_HASH}) FetchContent_MakeAvailable(whispercpp_fetch) - add_library(Whispercpp::Whisper STATIC IMPORTED) - set_target_properties( - Whispercpp::Whisper - PROPERTIES IMPORTED_LOCATION - ${whispercpp_fetch_SOURCE_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}whisper${CMAKE_STATIC_LIBRARY_SUFFIX}) - set_target_properties(Whispercpp::Whisper PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - ${whispercpp_fetch_SOURCE_DIR}/include) - add_library(Whispercpp::GGML STATIC IMPORTED) - set_target_properties( - Whispercpp::GGML - PROPERTIES IMPORTED_LOCATION - ${whispercpp_fetch_SOURCE_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}ggml${CMAKE_STATIC_LIBRARY_SUFFIX}) - - add_library(Whispercpp::CoreML STATIC IMPORTED) - set_target_properties( - Whispercpp::CoreML - PROPERTIES - IMPORTED_LOCATION - ${whispercpp_fetch_SOURCE_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}whisper.coreml${CMAKE_STATIC_LIBRARY_SUFFIX}) + add_compile_definitions(LOCALVOCAL_WITH_COREML) + set(WHISPER_SOURCE_DIR ${whispercpp_fetch_SOURCE_DIR}) + set(WHISPER_LIB_DIR ${whispercpp_fetch_SOURCE_DIR}) + + file(GLOB WHISPER_DYLIBS ${whispercpp_fetch_SOURCE_DIR}/lib/*.dylib) + install(FILES ${WHISPER_DYLIBS} DESTINATION "${CMAKE_PROJECT_NAME}.plugin/Contents/Frameworks") elseif(WIN32) + add_compile_definitions(WHISPER_DYNAMIC_BACKENDS) + if(NOT DEFINED ACCELERATION) - message(FATAL_ERROR "ACCELERATION is not set. Please set it to either `cpu`, `cuda`, `vulkan` or `hipblas`") + message(FATAL_ERROR "ACCELERATION is not set. Please set it to either `generic`, `nvidia`, or `amd`") endif() - set(ARCH_PREFIX ${ACCELERATION}) + set(WHISPER_LIBRARIES Whisper GGML GGMLBase) + set(WHISPER_RUNTIME_MODULES + GGMLCPU-X64 + GGMLCPU-SSE42 + GGMLCPU-SANDYBRIDGE + GGMLCPU-HASWELL + GGMLCPU-SKYLAKEX + GGMLCPU-ICELAKE + GGMLCPU-ALDERLAKE + GGMLBlas + GGMLVulkan) + set(WHISPER_LIBRARY_TYPE SHARED) + + set(ARCH_PREFIX "") + set(ACCELERATION_PREFIX "-${ACCELERATION}") set(WHISPER_CPP_URL - "${PREBUILT_WHISPERCPP_URL_BASE}/whispercpp-windows-${ARCH_PREFIX}-${PREBUILT_WHISPERCPP_VERSION}.zip") - if(${ACCELERATION} STREQUAL "cpu") - set(WHISPER_CPP_HASH "c23862b4aac7d8448cf7de4d339a86498f88ecba6fa7d243bbd7fabdb13d4dd4") - add_compile_definitions("LOCALVOCAL_WITH_CPU") - elseif(${ACCELERATION} STREQUAL "cuda") - set(WHISPER_CPP_HASH "a0adeaccae76fab0678d016a62b79a19661ed34eb810d8bae3b610345ee9a405") - add_compile_definitions("LOCALVOCAL_WITH_CUDA") - elseif(${ACCELERATION} STREQUAL "hipblas") - set(WHISPER_CPP_HASH "bbad0b4eec01c5a801d384c03745ef5e97061958f8cf8f7724281d433d7d92a1") - add_compile_definitions("LOCALVOCAL_WITH_HIPBLAS") - elseif(${ACCELERATION} STREQUAL "vulkan") - set(WHISPER_CPP_HASH "12bb34821f9efcd31f04a487569abff2b669221f2706fe0d09c17883635ef58a") - add_compile_definitions("LOCALVOCAL_WITH_VULKAN") + "${PREBUILT_WHISPERCPP_URL_BASE}/whispercpp-windows${ARCH_PREFIX}${ACCELERATION_PREFIX}-${PREBUILT_WHISPERCPP_VERSION}.zip" + ) + if(${ACCELERATION} STREQUAL "generic") + set(WHISPER_CPP_HASH "affff7241d36aa09863d65fe5a2d581251a9955a4465186ffdec00c893abcaee") + elseif(${ACCELERATION} STREQUAL "nvidia") + set(WHISPER_CPP_HASH "2b07afba9ad3489e6f173be6be7ffde2625ba5c0d84af7e306308676cabf67a6") + list(APPEND WHISPER_RUNTIME_MODULES GGMLCUDA) + elseif(${ACCELERATION} STREQUAL "amd") + set(WHISPER_CPP_HASH "9713220e1427b94f733255a25c2cf9f26577d2ce7eb55c48a6a0cc651313e9e5") + list(APPEND WHISPER_RUNTIME_MODULES GGMLHip) else() message( FATAL_ERROR - "The ACCELERATION environment variable is not set to a valid value. Please set it to either `cpu` or `cuda` or `vulkan` or `hipblas`" + "The ACCELERATION environment variable is not set to a valid value. Please set it to either `generic`, `nvidia` or `amd`" ) endif() @@ -79,75 +237,273 @@ elseif(WIN32) DOWNLOAD_EXTRACT_TIMESTAMP TRUE) FetchContent_MakeAvailable(whispercpp_fetch) - add_library(Whispercpp::Whisper SHARED IMPORTED) - set_target_properties( - Whispercpp::Whisper - PROPERTIES IMPORTED_LOCATION - ${whispercpp_fetch_SOURCE_DIR}/bin/${CMAKE_SHARED_LIBRARY_PREFIX}whisper${CMAKE_SHARED_LIBRARY_SUFFIX}) - set_target_properties( - Whispercpp::Whisper - PROPERTIES IMPORTED_IMPLIB - ${whispercpp_fetch_SOURCE_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}whisper${CMAKE_STATIC_LIBRARY_SUFFIX}) - set_target_properties(Whispercpp::Whisper PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - ${whispercpp_fetch_SOURCE_DIR}/include) - - if(${ACCELERATION} STREQUAL "cpu") - # add openblas to the link line - add_library(Whispercpp::OpenBLAS STATIC IMPORTED) - set_target_properties(Whispercpp::OpenBLAS PROPERTIES IMPORTED_LOCATION - ${whispercpp_fetch_SOURCE_DIR}/lib/libopenblas.dll.a) - endif() + set(WHISPER_SOURCE_DIR ${whispercpp_fetch_SOURCE_DIR}) + set(WHISPER_LIB_DIR ${whispercpp_fetch_SOURCE_DIR}) + set(WHISPER_DEPENDENCY_LIBRARIES "${whispercpp_fetch_SOURCE_DIR}/lib/libopenblas.lib") # glob all dlls in the bin directory and install them file(GLOB WHISPER_DLLS ${whispercpp_fetch_SOURCE_DIR}/bin/*.dll) install(FILES ${WHISPER_DLLS} DESTINATION "obs-plugins/64bit") + file(GLOB WHISPER_PDBS ${whispercpp_fetch_SOURCE_DIR}/bin/*.pdb) + install(FILES ${WHISPER_PDBS} DESTINATION "obs-plugins/64bit") else() - if(${CMAKE_BUILD_TYPE} STREQUAL Release OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo) - set(Whispercpp_BUILD_TYPE Release) + # Linux + + # Enable ccache if available + find_program(CCACHE_PROGRAM ccache QUIET) + if(CCACHE_PROGRAM) + message(STATUS "Found ccache: ${CCACHE_PROGRAM}") + set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) + endif() + + set(BLA_VENDOR OpenBLAS) + find_package(BLAS REQUIRED) + + if(NOT LINUX_SOURCE_BUILD) + add_compile_definitions(WHISPER_DYNAMIC_BACKENDS) + set(WHISPER_LIBRARY_TYPE SHARED) + set(WHISPER_LIBRARIES Whisper GGML GGMLBase) + list(APPEND WHISPER_DEPENDENCY_LIBRARIES Vulkan::Vulkan BLAS::BLAS) + if(NOT ${ACCELERATION} STREQUAL "nvidia") + # NVidia CUDA has its own OpenCL library + list(APPEND WHISPER_DEPENDENCY_LIBRARIES OpenCL::OpenCL) + endif() + list( + APPEND + WHISPER_RUNTIME_MODULES + GGMLCPU-X64 + GGMLCPU-SSE42 + GGMLCPU-SANDYBRIDGE + GGMLCPU-HASWELL + GGMLCPU-SKYLAKEX + GGMLCPU-ICELAKE + GGMLCPU-ALDERLAKE + GGMLCPU-SAPPHIRERAPIDS + GGMLBlas + GGMLVulkan + GGMLOpenCL) + + find_package( + Vulkan + COMPONENTS glslc + REQUIRED) + find_package(OpenCL REQUIRED) + find_package(Python3 REQUIRED) + + set(ARCH_PREFIX "-x86_64") + set(ACCELERATION_PREFIX "-${ACCELERATION}") + set(WHISPER_CPP_URL + "${PREBUILT_WHISPERCPP_URL_BASE}/whispercpp-linux${ARCH_PREFIX}${ACCELERATION_PREFIX}-Release.tar.gz") + if(${ACCELERATION} STREQUAL "generic") + set(WHISPER_CPP_HASH "5a4f3baf7d7e030f3e5a29d78fdd06f069fe472ad0f9ca93d40ed222052a3fe5") + elseif(${ACCELERATION} STREQUAL "nvidia") + set(WHISPER_CPP_HASH "a43dc8a44577e965caf9b0baaae74f30a9e00d99a296768021e7ccf0b9217878") + list(APPEND WHISPER_RUNTIME_MODULES GGMLCUDA) + + # Find CUDA libraries and link against them + set(CUDAToolkit_ROOT /usr/local/cuda-12.8/) + find_package(CUDAToolkit REQUIRED) + list( + APPEND + WHISPER_DEPENDENCY_LIBRARIES + CUDA::cudart + CUDA::cublas + CUDA::cublasLt + CUDA::cuda_driver + CUDA::OpenCL) + elseif(${ACCELERATION} STREQUAL "amd") + set(WHISPER_CPP_HASH "1a7592da41493e57ead23c97a420f2db11a4fe31049c9b01cdb310bff05fdca1") + list(APPEND WHISPER_RUNTIME_MODULES GGMLHip) + + # Find hip libraries and link against them + set(CMAKE_PREFIX_PATH /opt/rocm-6.4.2/lib/cmake) + set(HIP_PLATFORM amd) + set(CMAKE_HIP_PLATFORM amd) + set(CMAKE_HIP_ARCHITECTURES OFF) + find_package(hip REQUIRED) + find_package(hipblas REQUIRED) + find_package(rocblas REQUIRED) + list(APPEND WHISPER_DEPENDENCY_LIBRARIES hip::host roc::rocblas roc::hipblas) + else() + message( + FATAL_ERROR + "The ACCELERATION environment variable is not set to a valid value. Please set it to either `generic`, `nvidia` or `amd`" + ) + endif() + + FetchContent_Declare( + whispercpp_fetch + URL ${WHISPER_CPP_URL} + URL_HASH SHA256=${WHISPER_CPP_HASH} + DOWNLOAD_EXTRACT_TIMESTAMP TRUE) + FetchContent_MakeAvailable(whispercpp_fetch) + + message(STATUS "Whispercpp URL: ${WHISPER_CPP_URL}") + message(STATUS "Whispercpp source dir: ${whispercpp_fetch_SOURCE_DIR}") + + set(WHISPER_SOURCE_DIR ${whispercpp_fetch_SOURCE_DIR}) + set(WHISPER_LIB_DIR ${whispercpp_fetch_SOURCE_DIR}) + + file(GLOB WHISPER_SOS ${whispercpp_fetch_SOURCE_DIR}/lib/*${CMAKE_SHARED_LIBRARY_SUFFIX}*) + install(FILES ${WHISPER_SOS} DESTINATION "${CMAKE_INSTALL_LIBDIR}/obs-plugins/${CMAKE_PROJECT_NAME}") + file(GLOB WHISPER_BIN_SOS ${whispercpp_fetch_SOURCE_DIR}/bin/*${CMAKE_SHARED_LIBRARY_SUFFIX}*) + install(FILES ${WHISPER_BIN_SOS} DESTINATION "${CMAKE_INSTALL_LIBDIR}/obs-plugins/${CMAKE_PROJECT_NAME}") else() - set(Whispercpp_BUILD_TYPE Debug) + # Source build + if(${CMAKE_BUILD_TYPE} STREQUAL Release OR ${CMAKE_BUILD_TYPE} STREQUAL RelWithDebInfo) + set(Whispercpp_BUILD_TYPE RelWithDebInfo) + else() + set(Whispercpp_BUILD_TYPE Debug) + endif() + set(Whispercpp_Build_GIT_TAG "v1.8.2") + set(WHISPER_EXTRA_CXX_FLAGS "-fPIC") + set(WHISPER_ADDITIONAL_CMAKE_ARGS -DGGML_BLAS=ON -DGGML_BLAS_VENDOR=OpenBLAS) + set(WHISPER_LIBRARIES Whisper GGML GGMLBase) + + set(WHISPER_DEPENDENCY_LIBRARIES ${BLAS_LIBRARIES}) + set(WHISPER_LIBRARY_TYPE SHARED) + + if(WHISPER_DYNAMIC_BACKENDS) + list(APPEND WHISPER_ADDITIONAL_CMAKE_ARGS -DGGML_NATIVE=OFF -DGGML_BACKEND_DL=ON -DGGML_CPU_ALL_VARIANTS=ON) + list( + APPEND + WHISPER_RUNTIME_MODULES + GGMLBlas + GGMLCPU-X64 + GGMLCPU-SSE42 + GGMLCPU-SANDYBRIDGE + GGMLCPU-HASWELL + GGMLCPU-SKYLAKEX + GGMLCPU-ICELAKE + GGMLCPU-ALDERLAKE + GGMLCPU-SAPPHIRERAPIDS) + add_compile_definitions(WHISPER_DYNAMIC_BACKENDS) + else() + list(APPEND WHISPER_ADDITIONAL_CMAKE_ARGS -DGGML_NATIVE=ON -DGGML_BACKEND_DL=OFF) + list(APPEND WHISPER_LIBRARIES GGMLBlas GGMLCPU) + endif() + + find_package( + Vulkan + COMPONENTS glslc + QUIET) + if(Vulkan_FOUND) + message(STATUS "Vulkan found, Libraries: ${Vulkan_LIBRARIES}") + list(APPEND WHISPER_ADDITIONAL_CMAKE_ARGS -DGGML_VULKAN=ON) + if(WHISPER_DYNAMIC_BACKENDS) + list(APPEND WHISPER_RUNTIME_MODULES GGMLVulkan) + else() + list(APPEND WHISPER_LIBRARIES GGMLVulkan) + endif() + list(APPEND WHISPER_DEPENDENCY_LIBRARIES Vulkan::Vulkan) + endif() + + find_package(OpenCL QUIET) + find_package(Python3 QUIET) + if(OpenCL_FOUND AND Python3_FOUND) + message(STATUS "OpenCL found, Libraries: ${OpenCL_LIBRARIES}") + list(APPEND WHISPER_ADDITIONAL_CMAKE_ARGS -DGGML_OPENCL=ON -DGGML_OPENCL_EMBED_KERNELS=ON + -DGGML_OPENCL_USE_ADRENO_KERNELS=OFF) + if(WHISPER_DYNAMIC_BACKENDS) + list(APPEND WHISPER_RUNTIME_MODULES GGMLOpenCL) + else() + list(APPEND WHISPER_LIBRARIES GGMLOpenCL) + endif() + list(APPEND WHISPER_DEPENDENCY_LIBRARIES OpenCL::OpenCL) + endif() + + set(HIP_PLATFORM amd) + set(CMAKE_HIP_PLATFORM amd) + set(CMAKE_HIP_ARCHITECTURES OFF) + find_package(hip QUIET) + find_package(hipblas QUIET) + find_package(rocblas QUIET) + if(hip_FOUND + AND hipblas_FOUND + AND rocblas_FOUND) + message(STATUS "hipblas found, Libraries: ${hipblas_LIBRARIES}") + list(APPEND WHISPER_ADDITIONAL_ENV "CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH};HIP_PLATFORM=${HIP_PLATFORM}") + list(APPEND WHISPER_ADDITIONAL_CMAKE_ARGS -DGGML_HIP=ON -DGGML_HIP_ROCWMMA_FATTN=ON) + if(WHISPER_DYNAMIC_BACKENDS) + list(APPEND WHISPER_RUNTIME_MODULES GGMLHip) + else() + list(APPEND WHISPER_LIBRARIES GGMLHip) + endif() + list(APPEND WHISPER_DEPENDENCY_LIBRARIES hip::host roc::rocblas roc::hipblas) + endif() + + find_package(CUDAToolkit QUIET) + if(CUDAToolkit_FOUND) + message(STATUS "CUDA found, Libraries: ${CUDAToolkit_LIBRARIES}") + list(APPEND WHISPER_ADDITIONAL_CMAKE_ARGS -DGGML_CUDA=ON) + + if(WHISPER_BUILD_ALL_CUDA_ARCHITECTURES) + list(APPEND WHISPER_ADDITIONAL_CMAKE_ARGS -DCMAKE_CUDA_ARCHITECTURES=all) + else() + list(APPEND WHISPER_ADDITIONAL_CMAKE_ARGS -DCMAKE_CUDA_ARCHITECTURES=native) + endif() + + if(WHISPER_DYNAMIC_BACKENDS) + list(APPEND WHISPER_RUNTIME_MODULES GGMLCUDA) + else() + list(APPEND WHISPER_LIBRARIES GGMLCUDA) + endif() + list(APPEND WHISPER_DEPENDENCY_LIBRARIES CUDA::cudart CUDA::cublas CUDA::cublasLt CUDA::cuda_driver) + endif() + + foreach(component ${WHISPER_LIBRARIES}) + lib_name(${component} WHISPER_COMPONENT_IMPORT_LIB) + list( + APPEND + WHISPER_BYPRODUCTS + "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/obs-plugins/${CMAKE_PROJECT_NAME}/${CMAKE_SHARED_LIBRARY_PREFIX}${WHISPER_COMPONENT_IMPORT_LIB}${CMAKE_SHARED_LIBRARY_SUFFIX}" + ) + endforeach(component ${WHISPER_LIBRARIES}) + + # On Linux build a shared Whisper library + ExternalProject_Add( + Whispercpp_Build + DOWNLOAD_EXTRACT_TIMESTAMP true + GIT_REPOSITORY https://github.com/ggerganov/whisper.cpp.git + GIT_TAG ${Whispercpp_Build_GIT_TAG} + BUILD_COMMAND ${CMAKE_COMMAND} --build --config ${Whispercpp_BUILD_TYPE} + BUILD_BYPRODUCTS ${WHISPER_BYPRODUCTS} + CMAKE_GENERATOR ${CMAKE_GENERATOR} + INSTALL_COMMAND ${CMAKE_COMMAND} --install --config ${Whispercpp_BUILD_TYPE} && ${CMAKE_COMMAND} -E + copy /ggml/include/ggml.h /include + CONFIGURE_COMMAND + ${CMAKE_COMMAND} -E env ${WHISPER_ADDITIONAL_ENV} ${CMAKE_COMMAND} -B -G + ${CMAKE_GENERATOR} -DCMAKE_INSTALL_PREFIX= + -DCMAKE_INSTALL_LIBDIR=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/obs-plugins/${CMAKE_PROJECT_NAME} + -DCMAKE_INSTALL_BINDIR=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/obs-plugins/${CMAKE_PROJECT_NAME} + -DCMAKE_BUILD_TYPE=${Whispercpp_BUILD_TYPE} -DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM} + -DCMAKE_CXX_FLAGS=${WHISPER_EXTRA_CXX_FLAGS} -DCMAKE_C_FLAGS=${WHISPER_EXTRA_CXX_FLAGS} + -DCMAKE_CUDA_FLAGS=${WHISPER_EXTRA_CXX_FLAGS} -DBUILD_SHARED_LIBS=ON -DWHISPER_BUILD_TESTS=OFF + -DWHISPER_BUILD_EXAMPLES=OFF ${WHISPER_ADDITIONAL_CMAKE_ARGS}) + + ExternalProject_Get_Property(Whispercpp_Build INSTALL_DIR) + + set(WHISPER_SOURCE_DIR ${INSTALL_DIR}) + set(WHISPER_LIB_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/obs-plugins/${CMAKE_PROJECT_NAME}) + + add_dependencies(Whispercpp Whispercpp_Build) endif() - set(Whispercpp_Build_GIT_TAG "v1.6.2") - set(WHISPER_EXTRA_CXX_FLAGS "-fPIC") - set(WHISPER_ADDITIONAL_CMAKE_ARGS -DWHISPER_BLAS=OFF -DWHISPER_CUBLAS=OFF -DWHISPER_OPENBLAS=OFF) - - # On Linux build a static Whisper library - ExternalProject_Add( - Whispercpp_Build - DOWNLOAD_EXTRACT_TIMESTAMP true - GIT_REPOSITORY https://github.com/ggerganov/whisper.cpp.git - GIT_TAG ${Whispercpp_Build_GIT_TAG} - BUILD_COMMAND ${CMAKE_COMMAND} --build --config ${Whispercpp_BUILD_TYPE} - BUILD_BYPRODUCTS /lib/static/${CMAKE_STATIC_LIBRARY_PREFIX}whisper${CMAKE_STATIC_LIBRARY_SUFFIX} - CMAKE_GENERATOR ${CMAKE_GENERATOR} - INSTALL_COMMAND ${CMAKE_COMMAND} --install --config ${Whispercpp_BUILD_TYPE} && ${CMAKE_COMMAND} -E - copy /ggml.h /include - CONFIGURE_COMMAND - ${CMAKE_COMMAND} -E env ${WHISPER_ADDITIONAL_ENV} ${CMAKE_COMMAND} -B -G - ${CMAKE_GENERATOR} -DCMAKE_INSTALL_PREFIX= -DCMAKE_BUILD_TYPE=${Whispercpp_BUILD_TYPE} - -DCMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM} -DCMAKE_OSX_DEPLOYMENT_TARGET=10.13 - -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES_} -DCMAKE_CXX_FLAGS=${WHISPER_EXTRA_CXX_FLAGS} - -DCMAKE_C_FLAGS=${WHISPER_EXTRA_CXX_FLAGS} -DBUILD_SHARED_LIBS=OFF -DWHISPER_BUILD_TESTS=OFF - -DWHISPER_BUILD_EXAMPLES=OFF ${WHISPER_ADDITIONAL_CMAKE_ARGS}) - - ExternalProject_Get_Property(Whispercpp_Build INSTALL_DIR) - - # add the static Whisper library to the link line - add_library(Whispercpp::Whisper STATIC IMPORTED) - set_target_properties( - Whispercpp::Whisper - PROPERTIES IMPORTED_LOCATION - ${INSTALL_DIR}/lib/static/${CMAKE_STATIC_LIBRARY_PREFIX}whisper${CMAKE_STATIC_LIBRARY_SUFFIX}) - set_target_properties(Whispercpp::Whisper PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) endif() -add_library(Whispercpp INTERFACE) -add_dependencies(Whispercpp Whispercpp_Build) -target_link_libraries(Whispercpp INTERFACE Whispercpp::Whisper) -if(WIN32 AND "${ACCELERATION}" STREQUAL "cpu") - target_link_libraries(Whispercpp INTERFACE Whispercpp::OpenBLAS) -endif() -if(APPLE) - target_link_libraries(Whispercpp INTERFACE "-framework Accelerate -framework CoreML -framework Metal") - target_link_libraries(Whispercpp INTERFACE Whispercpp::GGML Whispercpp::CoreML) -endif(APPLE) +foreach(lib ${WHISPER_LIBRARIES}) + message(STATUS "Adding " Whispercpp::${lib} " to build") + add_whisper_component(Whispercpp::${lib} ${WHISPER_LIBRARY_TYPE} ${WHISPER_SOURCE_DIR} ${WHISPER_LIB_DIR}) +endforeach(lib ${WHISPER_LIBRARIES}) + +foreach(lib ${WHISPER_RUNTIME_MODULES}) + message(STATUS "Adding " Whispercpp::${lib} " to build as runtime module") + add_whisper_runtime_module(Whispercpp::${lib} ${WHISPER_SOURCE_DIR} ${WHISPER_LIB_DIR}) +endforeach(lib ${WHISPER_RUNTIME_MODULES}) + +foreach(lib ${WHISPER_DEPENDENCY_LIBRARIES}) + message(STATUS "Adding dependency " ${lib} " to linker") + target_link_libraries(Whispercpp INTERFACE ${lib}) +endforeach(lib ${WHISPER_DEPENDENCY_LIBRARIES}) + +target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE Whisper) diff --git a/cmake/FetchOnnxruntime.cmake b/cmake/FetchOnnxruntime.cmake index 4d83a63..a5f3b14 100644 --- a/cmake/FetchOnnxruntime.cmake +++ b/cmake/FetchOnnxruntime.cmake @@ -8,7 +8,9 @@ set(CUSTOM_ONNXRUNTIME_HASH "" CACHE STRING "Hash of a downloaded ONNX Runtime tarball") -set(Onnxruntime_VERSION "1.19.2") +# v1.20.1 is the last version to support MacOS 12 v1.23.0 is the last version to support x86_64 on MacOS, as well as +# MacOS 13 +set(Onnxruntime_VERSION "1.20.1") if(CUSTOM_ONNXRUNTIME_URL STREQUAL "") set(USE_PREDEFINED_ONNXRUNTIME ON) @@ -25,17 +27,17 @@ if(USE_PREDEFINED_ONNXRUNTIME) if(APPLE) set(Onnxruntime_URL "${Onnxruntime_BASEURL}/onnxruntime-osx-universal2-${Onnxruntime_VERSION}.tgz") - set(Onnxruntime_HASH SHA256=b0289ddbc32f76e5d385abc7b74cc7c2c51cdf2285b7d118bf9d71206e5aee3a) + set(Onnxruntime_HASH SHA256=da4349e01a7e997f5034563183c7183d069caadc1d95f499b560961787813efd) elseif(MSVC) set(Onnxruntime_URL "${Onnxruntime_BASEURL}/onnxruntime-win-x64-${Onnxruntime_VERSION}.zip") - set(OOnnxruntime_HASH SHA256=dc4f841e511977c0a4f02e5066c3d9a58427644010ab4f89b918614a1cd4c2b0) + set(OOnnxruntime_HASH SHA256=78d447051e48bd2e1e778bba378bec4ece11191c9e538cf7b2c4a4565e8f5581) else() if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") set(Onnxruntime_URL "${Onnxruntime_BASEURL}/onnxruntime-linux-aarch64-${Onnxruntime_VERSION}.tgz") - set(Onnxruntime_HASH SHA256=dc4f841e511977c0a4f02e5066c3d9a58427644010ab4f89b918614a1cd4c2b0) + set(Onnxruntime_HASH SHA256=ae4fedbdc8c18d688c01306b4b50c63de3445cdf2dbd720e01a2fa3810b8106a) else() set(Onnxruntime_URL "${Onnxruntime_BASEURL}/onnxruntime-linux-x64-gpu-${Onnxruntime_VERSION}.tgz") - set(Onnxruntime_HASH SHA256=4d1c10f0b410b67261302c6e18bb1b05ba924ca9081e3a26959e0d12ab69f534) + set(Onnxruntime_HASH SHA256=6bfb87c6ebe55367a94509b8ef062239e188dccf8d5caac8d6909b2344893bf0) endif() endif() else() @@ -82,15 +84,14 @@ elseif(MSVC) target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Ort) else() + set(Onnxruntime_LINK_LIBS "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so.${Onnxruntime_VERSION}") + set(Onnxruntime_ADDITIONAL_LIBS + "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime_providers_shared.so" + "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so" "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so.1") if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") - set(Onnxruntime_LINK_LIBS "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so.${Onnxruntime_VERSION}") - set(Onnxruntime_INSTALL_LIBS ${Onnxruntime_LINK_LIBS} "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so.1" - "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so") + set(Onnxruntime_INSTALL_LIBS ${Onnxruntime_LINK_LIBS} ${Onnxruntime_ADDITIONAL_LIBS}) else() - set(Onnxruntime_LINK_LIBS "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so.${Onnxruntime_VERSION}") - set(Onnxruntime_INSTALL_LIBS - ${Onnxruntime_LINK_LIBS} "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime_providers_shared.so" - "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so.1" "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so") + set(Onnxruntime_INSTALL_LIBS ${Onnxruntime_LINK_LIBS} ${Onnxruntime_ADDITIONAL_LIBS}) endif() target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${Onnxruntime_LINK_LIBS}) target_include_directories(${CMAKE_PROJECT_NAME} SYSTEM PUBLIC "${onnxruntime_SOURCE_DIR}/include") diff --git a/cmake/common/bootstrap.cmake b/cmake/common/bootstrap.cmake index 27ad4a4..4c17382 100644 --- a/cmake/common/bootstrap.cmake +++ b/cmake/common/bootstrap.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.16...3.26) +cmake_minimum_required(VERSION 3.28...4.12) include_guard(GLOBAL) @@ -27,6 +27,12 @@ if(POLICY CMP0090) cmake_policy(SET CMP0090 NEW) endif() +# Allow invalid arguments to add_custom_command() - lua and python scripting CMake files in OBS source use these invalid +# args +if(POLICY CMP0175) + cmake_policy(SET CMP0175 OLD) +endif() + # Prohibit in-source builds if("${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") message(FATAL_ERROR "In-source builds are not supported. " @@ -49,8 +55,6 @@ string(JSON _author GET ${buildspec} author) string(JSON _email GET ${buildspec} email) string(JSON _version GET ${buildspec} version) string(JSON _bundleId GET ${buildspec} platformConfig macos bundleId) -string(JSON _macosPackageUUID GET ${buildspec} uuids macosPackage) -string(JSON _macosInstallerUUID GET ${buildspec} uuids macosInstaller) string(JSON _windowsAppUUID GET ${buildspec} uuids windowsApp) # cmake-format: on diff --git a/cmake/common/buildspec_common.cmake b/cmake/common/buildspec_common.cmake index b2c2414..a8c67d3 100644 --- a/cmake/common/buildspec_common.cmake +++ b/cmake/common/buildspec_common.cmake @@ -63,14 +63,12 @@ function(_setup_obs_studio) if(OS_WINDOWS) set(_cmake_generator "${CMAKE_GENERATOR}") - set(_cmake_arch "-A ${arch}") + set(_cmake_arch "-A ${arch},version=${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") set(_cmake_extra "-DCMAKE_SYSTEM_VERSION=${CMAKE_SYSTEM_VERSION} -DCMAKE_ENABLE_SCRIPTING=OFF") - set(_cmake_version "2.0.0") elseif(OS_MACOS) set(_cmake_generator "Xcode") set(_cmake_arch "-DCMAKE_OSX_ARCHITECTURES:STRING='arm64;x86_64'") set(_cmake_extra "-DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") - set(_cmake_version "3.0.0") endif() message(STATUS "Configure ${label} (${arch})") @@ -78,30 +76,39 @@ function(_setup_obs_studio) COMMAND "${CMAKE_COMMAND}" -S "${dependencies_dir}/${_obs_destination}" -B "${dependencies_dir}/${_obs_destination}/build_${arch}" -G ${_cmake_generator} "${_cmake_arch}" - -DOBS_CMAKE_VERSION:STRING=${_cmake_version} -DENABLE_PLUGINS:BOOL=OFF -DENABLE_UI:BOOL=OFF + -DOBS_CMAKE_VERSION:STRING=3.0.0 -DENABLE_PLUGINS:BOOL=OFF -DENABLE_FRONTEND:BOOL=OFF -DOBS_VERSION_OVERRIDE:STRING=${_obs_version} "-DCMAKE_PREFIX_PATH='${CMAKE_PREFIX_PATH}'" ${_is_fresh} ${_cmake_extra} RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY OUTPUT_QUIET) message(STATUS "Configure ${label} (${arch}) - done") - message(STATUS "Build ${label} (${arch})") + message(STATUS "Build ${label} (Debug - ${arch})") execute_process( COMMAND "${CMAKE_COMMAND}" --build build_${arch} --target obs-frontend-api --config Debug --parallel WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}" RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY OUTPUT_QUIET) - message(STATUS "Build ${label} (${arch}) - done") + message(STATUS "Build ${label} (Debug - ${arch}) - done") + + message(STATUS "Build ${label} (Release - ${arch})") + execute_process( + COMMAND "${CMAKE_COMMAND}" --build build_${arch} --target obs-frontend-api --config Release --parallel + WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}" + RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY + OUTPUT_QUIET) + message(STATUS "Build ${label} (Reelase - ${arch}) - done") message(STATUS "Install ${label} (${arch})") - if(OS_WINDOWS) - set(_cmake_extra "--component obs_libraries") - else() - set(_cmake_extra "") - endif() execute_process( COMMAND "${CMAKE_COMMAND}" --install build_${arch} --component Development --config Debug --prefix - "${dependencies_dir}" ${_cmake_extra} + "${dependencies_dir}" + WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}" + RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY + OUTPUT_QUIET) + execute_process( + COMMAND "${CMAKE_COMMAND}" --install build_${arch} --component Development --config Release --prefix + "${dependencies_dir}" WORKING_DIRECTORY "${dependencies_dir}/${_obs_destination}" RESULT_VARIABLE _process_result COMMAND_ERROR_IS_FATAL ANY OUTPUT_QUIET) @@ -144,12 +151,19 @@ function(_check_dependencies) string(REPLACE "-REVISION" "" file "${file}") endif() + if(EXISTS "${dependencies_dir}/.dependency_${dependency}_${arch}.sha256") + file(READ "${dependencies_dir}/.dependency_${dependency}_${arch}.sha256" + OBS_DEPENDENCY_${dependency}_${arch}_HASH) + endif() + set(skip FALSE) if(dependency STREQUAL prebuilt OR dependency STREQUAL qt6) - _check_deps_version(${version}) + if(OBS_DEPENDENCY_${dependency}_${arch}_HASH STREQUAL ${hash}) + _check_deps_version(${version}) - if(found) - set(skip TRUE) + if(found) + set(skip TRUE) + endif() endif() endif() @@ -182,6 +196,10 @@ function(_check_dependencies) endif() endif() + if(NOT OBS_DEPENDENCY_${dependency}_${arch}_HASH STREQUAL ${hash}) + file(REMOVE_RECURSE "${dependencies_dir}/${destination}") + endif() + if(NOT EXISTS "${dependencies_dir}/${destination}") file(MAKE_DIRECTORY "${dependencies_dir}/${destination}") if(dependency STREQUAL obs-studio) @@ -191,6 +209,8 @@ function(_check_dependencies) endif() endif() + file(WRITE "${dependencies_dir}/.dependency_${dependency}_${arch}.sha256" "${hash}") + if(dependency STREQUAL prebuilt) list(APPEND CMAKE_PREFIX_PATH "${dependencies_dir}/${destination}") elseif(dependency STREQUAL qt6) @@ -199,7 +219,6 @@ function(_check_dependencies) set(_obs_version ${version}) set(_obs_destination "${destination}") list(APPEND CMAKE_PREFIX_PATH "${dependencies_dir}") - endif() message(STATUS "Setting up ${label} (${arch}) - done") diff --git a/cmake/common/compiler_common.cmake b/cmake/common/compiler_common.cmake index 6cd5fb1..546c42f 100644 --- a/cmake/common/compiler_common.cmake +++ b/cmake/common/compiler_common.cmake @@ -3,11 +3,6 @@ include_guard(GLOBAL) # Set C and C++ language standards to C17 and C++17 -if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) - set(CMAKE_C_STANDARD 17) -else() - set(CMAKE_C_STANDARD 11) -endif() set(CMAKE_C_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) @@ -24,6 +19,7 @@ set(_obs_clang_c_options -Wbool-conversion -Wcomma -Wconstant-conversion + -Wdeprecated-declarations -Wempty-body -Wenum-conversion -Werror=return-type @@ -35,7 +31,6 @@ set(_obs_clang_c_options -Wint-conversion -Wnewline-eof -Wno-conversion - -Wno-deprecated-declarations -Wno-error=deprecated-declarations -Wno-float-conversion -Wno-implicit-fallthrough diff --git a/cmake/common/helpers_common.cmake b/cmake/common/helpers_common.cmake index 1d06adb..b61fa54 100644 --- a/cmake/common/helpers_common.cmake +++ b/cmake/common/helpers_common.cmake @@ -134,8 +134,10 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/plugin-support.c.in") PRIVATE plugin-support.c PUBLIC src/plugin-support.h) target_include_directories(plugin-support PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src") - if(UNIX AND NOT APPLE) - # add fPIC + if(OS_LINUX + OR OS_FREEBSD + OR OS_OPENBSD) + # add fPIC on Linux to prevent shared object errors set_property(TARGET plugin-support PROPERTY POSITION_INDEPENDENT_CODE ON) endif() endif() diff --git a/cmake/linux/defaults.cmake b/cmake/linux/defaults.cmake index 223756d..eb1d388 100644 --- a/cmake/linux/defaults.cmake +++ b/cmake/linux/defaults.cmake @@ -14,14 +14,15 @@ set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) set(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") set(CPACK_PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}") -set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_C_LIBRARY_ARCHITECTURE}") +set(CPACK_PACKAGE_FILE_NAME + "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_C_LIBRARY_ARCHITECTURE}-$ENV{ACCELERATION}") set(CPACK_GENERATOR "DEB") set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) set(CPACK_DEBIAN_PACKAGE_MAINTAINER "${PLUGIN_EMAIL}") set(CPACK_SET_DESTDIR ON) -if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.25.0 OR NOT CMAKE_CROSSCOMPILING) +if((CMAKE_VERSION VERSION_GREATER_EQUAL 3.25.0 OR NOT CMAKE_CROSSCOMPILING) AND NOT ($ENV{ACCELERATION} STREQUAL amd)) set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON) endif() diff --git a/cmake/macos/compilerconfig.cmake b/cmake/macos/compilerconfig.cmake index a2186e7..1fe9330 100644 --- a/cmake/macos/compilerconfig.cmake +++ b/cmake/macos/compilerconfig.cmake @@ -55,4 +55,4 @@ else() endif() add_compile_definitions($<$:DEBUG> $<$:_DEBUG> SIMDE_ENABLE_OPENMP) -add_compile_options(-Wno-error=deprecated-declarations -Wno-deprecated-declarations) +add_compile_options(-Wno-error=newline-eof -Wno-error=deprecated-declarations -Wno-deprecated-declarations) diff --git a/cmake/macos/defaults.cmake b/cmake/macos/defaults.cmake index cf46977..3d0f956 100644 --- a/cmake/macos/defaults.cmake +++ b/cmake/macos/defaults.cmake @@ -22,13 +22,13 @@ endif() include(buildspec) -# Set default deployment target to 11.0 if not set and enable selection in GUI up to 13.0 +# Set default deployment target to 12.0 if not set and enable selection in GUI up to 15.0 if(NOT CMAKE_OSX_DEPLOYMENT_TARGET) set(CMAKE_OSX_DEPLOYMENT_TARGET - 11.0 + 12.0 CACHE STRING "Minimum macOS version to target for deployment (at runtime). Newer APIs will be weak-linked." FORCE) endif() -set_property(CACHE CMAKE_OSX_DEPLOYMENT_TARGET PROPERTY STRINGS 13.0 12.0 11.0) +set_property(CACHE CMAKE_OSX_DEPLOYMENT_TARGET PROPERTY STRINGS 15.0 14.0 13.0 12.0) # Use Applications directory as default install destination if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) diff --git a/cmake/macos/helpers.cmake b/cmake/macos/helpers.cmake index 37b92bf..76541b8 100644 --- a/cmake/macos/helpers.cmake +++ b/cmake/macos/helpers.cmake @@ -57,22 +57,6 @@ function(set_target_properties_plugin target) PREFIX "UI Files" FILES ${target_ui_files}) - set(valid_uuid FALSE) - check_uuid(${_macosPackageUUID} valid_uuid) - if(NOT valid_uuid) - message(FATAL_ERROR "Specified macOS package UUID is not a valid UUID value: ${_macosPackageUUID}") - else() - set(UUID_PACKAGE ${_macosPackageUUID}) - endif() - - set(valid_uuid FALSE) - check_uuid(${_macosInstallerUUID} valid_uuid) - if(NOT valid_uuid) - message(FATAL_ERROR "Specified macOS package UUID is not a valid UUID value: ${_macosInstallerUUID}") - else() - set(UUID_INSTALLER ${_macosInstallerUUID}) - endif() - install(TARGETS ${target} LIBRARY DESTINATION .) install( FILES "$.dsym" diff --git a/cmake/windows/compilerconfig.cmake b/cmake/windows/compilerconfig.cmake index edc6188..c4c6421 100644 --- a/cmake/windows/compilerconfig.cmake +++ b/cmake/windows/compilerconfig.cmake @@ -4,10 +4,7 @@ include_guard(GLOBAL) include(compiler_common) -# CMake 3.24 introduces a bug mistakenly interpreting MSVC as supporting the '-pthread' compiler flag -if(CMAKE_VERSION VERSION_EQUAL 3.24.0) - set(THREADS_HAVE_PTHREAD_ARG FALSE) -endif() +set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT ProgramDatabase) message(DEBUG "Current Windows API version: ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}") if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM) @@ -19,20 +16,31 @@ if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION VERSION_LESS 10.0.20348) "Please download and install the most recent Windows platform SDK.") endif() +set(_obs_msvc_c_options /MP /Zc:__cplusplus /Zc:preprocessor) +set(_obs_msvc_cpp_options /MP /Zc:__cplusplus /Zc:preprocessor) + +if(CMAKE_CXX_STANDARD GREATER_EQUAL 20) + list(APPEND _obs_msvc_cpp_options /Zc:char8_t-) +endif() + add_compile_options( /W3 /utf-8 - /wd4996 - "$<$:/MP>" - "$<$:/MP>" + /Brepro + /permissive- + "$<$:${_obs_msvc_c_options}>" + "$<$:${_obs_msvc_cpp_options}>" "$<$:${_obs_clang_c_options}>" - "$<$:${_obs_clang_cxx_options}>") + "$<$:${_obs_clang_cxx_options}>" + $<$>:/Gy> + $<$>:/GL> + $<$>:/Oi>) add_compile_definitions(UNICODE _UNICODE _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS $<$:DEBUG> $<$:_DEBUG>) -add_link_options("$<$>:/OPT:REF>" "$<$:/INCREMENTAL:NO>" - "$<$:/INCREMENTAL:NO>" "$<$:/OPT:ICF>") +add_link_options($<$>:/OPT:REF> $<$>:/OPT:ICF> $<$>:/LTCG> + $<$>:/INCREMENTAL:NO> /DEBUG /Brepro) if(CMAKE_COMPILE_WARNING_AS_ERROR) add_link_options(/WX) diff --git a/cmake/windows/defaults.cmake b/cmake/windows/defaults.cmake index fd40d22..895e70f 100644 --- a/cmake/windows/defaults.cmake +++ b/cmake/windows/defaults.cmake @@ -6,3 +6,9 @@ include_guard(GLOBAL) set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) include(buildspec) + +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX + "$ENV{ALLUSERSPROFILE}/obs-studio/plugins" + CACHE STRING "Default plugin installation directory" FORCE) +endif() diff --git a/cmake/windows/helpers.cmake b/cmake/windows/helpers.cmake index 1849605..fb5ac29 100644 --- a/cmake/windows/helpers.cmake +++ b/cmake/windows/helpers.cmake @@ -92,7 +92,7 @@ function(target_install_resources target) install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data/" - DESTINATION data/obs-plugins/${target} + DESTINATION "data/obs-plugins/${target}" USE_SOURCE_PERMISSIONS) if(OBS_BUILD_DIR) diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 5fd30bb..8ca4e47 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -15,3 +15,7 @@ n_max_text_ctx="Number of max text context" no_context="No context" replace_sound_path="Replace Sound Path" replace_sound="Replace Sound" +backend_group="Whisper Backend Configuration" +backend_device="GPU device" +enable_flash_attn="Enable Flash Attention" +enable_flash_attn_tooltip="Improves transcription speed on some GPUs (NVidia: Ampere or newer, AMD: RDNA or newer). May slow down transcription in other cases" \ No newline at end of file diff --git a/src/cleanstream-filter-data.h b/src/cleanstream-filter-data.h index 72e0c68..1910368 100644 --- a/src/cleanstream-filter-data.h +++ b/src/cleanstream-filter-data.h @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include @@ -32,6 +32,12 @@ struct cleanstream_audio_info { uint64_t timestamp; }; +struct gpu_device_info { + size_t device_index; + const char *device_name; + const char *device_description; +}; + struct cleanstream_data { obs_source_t *context; // obs input source size_t channels; // number of channels @@ -46,10 +52,15 @@ struct cleanstream_data { /* Silero VAD */ std::unique_ptr vad; + // GPU device to use, or -1 for CPU only + int gpu_device; + std::vector gpu_devices; + bool enable_flash_attn; + /* PCM buffers */ float *copy_buffers[MAX_PREPROC_CHANNELS]; - struct circlebuf info_buffer; - struct circlebuf input_buffers[MAX_PREPROC_CHANNELS]; + struct deque info_buffer; + struct deque input_buffers[MAX_PREPROC_CHANNELS]; /* Resampler */ audio_resampler_t *resampler; diff --git a/src/cleanstream-filter.cpp b/src/cleanstream-filter.cpp index f3a5593..1cf124b 100644 --- a/src/cleanstream-filter.cpp +++ b/src/cleanstream-filter.cpp @@ -41,6 +41,61 @@ void whisper_loop(void *data); +void enumerate_gpu_devices(cleanstream_data *gf) +{ +#ifdef WHISPER_DYNAMIC_BACKENDS + // Load CPU backends + auto path = std::filesystem::path(obs_get_module_binary_path(obs_current_module())) + .parent_path(); +#if !defined(_WIN32) && defined(__linux__) + // Linux has modules in a subdirectory, Windows does not + path /= "obs-localvocal"; +#elif !defined(_WIN32) + // MacOS is just weird + path = path.parent_path() / "Frameworks"; +#endif + + obs_log(LOG_INFO, "Loading dynamic backends from %s", path.string().c_str()); + ggml_backend_load_all_from_path(path.string().c_str()); +#endif + + // Enumerate backend devices to populate list + auto backend_count = ggml_backend_dev_count(); + size_t gpu_count = 0; + for (size_t i = 0; i < backend_count; i++) { + auto backend_dev = ggml_backend_dev_get(i); + auto name = ggml_backend_dev_name(backend_dev); + auto desc = ggml_backend_dev_description(backend_dev); + auto type = "UNKNOWN"; + bool add_device_to_config = false; + switch (ggml_backend_dev_type(backend_dev)) { + case GGML_BACKEND_DEVICE_TYPE_CPU: + type = "CPU"; + break; + case GGML_BACKEND_DEVICE_TYPE_GPU: + type = "GPU"; + add_device_to_config = true; + break; + case GGML_BACKEND_DEVICE_TYPE_ACCEL: + type = "ACCEL"; + break; + case GGML_BACKEND_DEVICE_TYPE_IGPU: + type = "IGPU"; + add_device_to_config = true; + break; + }; + if (add_device_to_config) { + gpu_device_info device; + device.device_index = i; + device.device_name = name; + device.device_description = desc; + gf->gpu_devices.push_back(device); + gpu_count++; + } + obs_log(LOG_INFO, "Backend device %d (%s): %s - %s", i, type, name, desc); + }; +} + struct obs_audio_data *cleanstream_filter_audio(void *data, struct obs_audio_data *audio) { if (data == nullptr) { @@ -63,16 +118,16 @@ struct obs_audio_data *cleanstream_filter_audio(void *data, struct obs_audio_dat std::lock_guard lock(gf->whisper_buf_mutex); // scoped lock if (audio != nullptr && audio->frames > 0) { - // push back current audio data to input circlebuf + // push back current audio data to input deque for (size_t c = 0; c < gf->channels; c++) { - circlebuf_push_back(&gf->input_buffers[c], audio->data[c], - audio->frames * sizeof(float)); + deque_push_back(&gf->input_buffers[c], audio->data[c], + audio->frames * sizeof(float)); } - // push audio packet info (timestamp/frame count) to info circlebuf + // push audio packet info (timestamp/frame count) to info deque struct cleanstream_audio_info info = {0}; info.frames = audio->frames; // number of frames in this packet info.timestamp = audio->timestamp; // timestamp of this packet - circlebuf_push_back(&gf->info_buffer, &info, sizeof(info)); + deque_push_back(&gf->info_buffer, &info, sizeof(info)); } input_buffer_size = gf->input_buffers[0].size; } @@ -91,22 +146,22 @@ struct obs_audio_data *cleanstream_filter_audio(void *data, struct obs_audio_dat while (temporary_buffers[0].size() < num_frames_needed) { struct cleanstream_audio_info info_out = {0}; // pop from input buffers to get audio packet info - circlebuf_pop_front(&gf->info_buffer, &info_out, sizeof(info_out)); + deque_pop_front(&gf->info_buffer, &info_out, sizeof(info_out)); if (timestamp == 0) { timestamp = info_out.timestamp; } - // pop from input circlebuf to audio data + // pop from input deque to audio data for (size_t i = 0; i < gf->channels; i++) { // increase the size of the temporary buffer to hold the incoming audio in addition // to the existing audio on the temporary buffer temporary_buffers[i].resize(temporary_buffers[i].size() + info_out.frames); - circlebuf_pop_front(&gf->input_buffers[i], - temporary_buffers[i].data() + - temporary_buffers[i].size() - - info_out.frames, - info_out.frames * sizeof(float)); + deque_pop_front(&gf->input_buffers[i], + temporary_buffers[i].data() + + temporary_buffers[i].size() - + info_out.frames, + info_out.frames * sizeof(float)); } } } @@ -210,11 +265,11 @@ void cleanstream_destroy(void *data) bfree(gf->copy_buffers[0]); gf->copy_buffers[0] = nullptr; for (size_t i = 0; i < gf->channels; i++) { - circlebuf_free(&gf->input_buffers[i]); + deque_free(&gf->input_buffers[i]); } } - circlebuf_free(&gf->info_buffer); + deque_free(&gf->info_buffer); da_free(gf->output_data); bfree(gf); @@ -263,8 +318,7 @@ void cleanstream_update(void *data, obs_data_t *s) gf->whisper_params.split_on_word = obs_data_get_bool(s, "split_on_word"); gf->whisper_params.max_tokens = (int)obs_data_get_int(s, "max_tokens"); gf->whisper_params.suppress_blank = obs_data_get_bool(s, "suppress_blank"); - gf->whisper_params.suppress_non_speech_tokens = - obs_data_get_bool(s, "suppress_non_speech_tokens"); + gf->whisper_params.suppress_nst = obs_data_get_bool(s, "suppress_nst"); gf->whisper_params.temperature = (float)obs_data_get_double(s, "temperature"); gf->whisper_params.max_initial_ts = (float)obs_data_get_double(s, "max_initial_ts"); gf->whisper_params.length_penalty = (float)obs_data_get_double(s, "length_penalty"); @@ -290,10 +344,10 @@ void *cleanstream_create(obs_data_t *settings, obs_source_t *filter) gf->current_result_end_timestamp = 0; for (size_t i = 0; i < MAX_AUDIO_CHANNELS; i++) { - circlebuf_init(&gf->input_buffers[i]); + deque_init(&gf->input_buffers[i]); gf->output_audio.data[i] = nullptr; } - circlebuf_init(&gf->info_buffer); + deque_init(&gf->info_buffer); da_init(gf->output_data); gf->output_audio.frames = 0; @@ -307,7 +361,6 @@ void *cleanstream_create(obs_data_t *settings, obs_source_t *filter) } gf->context = filter; - gf->whisper_model_path = std::string(""); // The update function will set the model path gf->whisper_context = nullptr; obs_log(LOG_INFO, "CleanStream filter: channels %d, sample_rate %d", (int)gf->channels, @@ -353,6 +406,8 @@ void *cleanstream_create(obs_data_t *settings, obs_source_t *filter) } #endif + enumerate_gpu_devices(gf); + // call the update function to set the whisper model cleanstream_update(gf, settings); @@ -406,15 +461,45 @@ void cleanstream_defaults(obs_data_t *s) obs_data_set_default_int(s, "max_tokens", 7); obs_data_set_default_bool(s, "speed_up", false); obs_data_set_default_bool(s, "suppress_blank", true); - obs_data_set_default_bool(s, "suppress_non_speech_tokens", true); + obs_data_set_default_bool(s, "suppress_nst", true); obs_data_set_default_double(s, "temperature", 0.1); obs_data_set_default_double(s, "max_initial_ts", 1.0); obs_data_set_default_double(s, "length_penalty", -1.0); + + // backend options + obs_data_set_default_int(s, "backend_device", -1); + obs_data_set_default_bool(s, "enable_flash_attn", false); +} + +void add_whisper_backend_group_properties(obs_properties_t *ppts, struct cleanstream_data *gf) +{ + // add a group for setting the whisper backend(s) to use + obs_properties_t *backend_group = obs_properties_create(); + obs_properties_add_group(ppts, "backend_group", MT_("backend_group"), OBS_GROUP_NORMAL, + backend_group); + + obs_property_t *backend_device = + obs_properties_add_list(backend_group, "backend_device", MT_("backend_device"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + + obs_property_list_add_int(backend_device, "CPU only", -1); + for (size_t i = 0; i < gf->gpu_devices.size(); i++) { + auto name = gf->gpu_devices.at(i).device_name; + auto description = gf->gpu_devices.at(i).device_description; + obs_property_list_add_int( + backend_device, + std::string("GPU: ").append(name).append(" - ").append(description).c_str(), + i); + } + + obs_property_t *enable_flash_attn = obs_properties_add_bool( + backend_group, "enable_flash_attn", MT_("enable_flash_attn")); + obs_property_set_long_description(enable_flash_attn, MT_("enable_flash_attn_tooltip")); } obs_properties_t *cleanstream_properties(void *data) { - UNUSED_PARAMETER(data); + struct cleanstream_data *gf = static_cast(data); obs_properties_t *ppts = obs_properties_create(); @@ -428,8 +513,6 @@ obs_properties_t *cleanstream_properties(void *data) obs_property_list_add_int(replace_sounds_list, "Silence", REPLACE_SOUNDS_SILENCE); // on windows and mac, add external file path for replace sound #if defined(_WIN32) || defined(__APPLE__) - struct cleanstream_data *gf = static_cast(data); - if (!gf->audioFileCache["beep.wav"].empty()) { obs_property_list_add_int(replace_sounds_list, "Beep", REPLACE_SOUNDS_BEEP); } @@ -531,6 +614,8 @@ obs_properties_t *cleanstream_properties(void *data) return true; }); + add_whisper_backend_group_properties(ppts, gf); + obs_properties_t *advanced_settings_group = obs_properties_create(); obs_properties_add_group(ppts, "advanced_settings_group", MT_("Advanced_Settings"), OBS_GROUP_NORMAL, advanced_settings_group); @@ -597,9 +682,8 @@ obs_properties_t *cleanstream_properties(void *data) OBS_TEXT_DEFAULT); // bool suppress_blank obs_properties_add_bool(whisper_params_group, "suppress_blank", MT_("suppress_blank")); - // bool suppress_non_speech_tokens - obs_properties_add_bool(whisper_params_group, "suppress_non_speech_tokens", - MT_("suppress_non_speech_tokens")); + // bool suppress_nst + obs_properties_add_bool(whisper_params_group, "suppress_nst", MT_("suppress_nst")); // float temperature obs_properties_add_float_slider(whisper_params_group, "temperature", MT_("temperature"), 0.0f, 1.0f, 0.05f); diff --git a/src/whisper-utils/whisper-processing.cpp b/src/whisper-utils/whisper-processing.cpp index de89802..c11c4b4 100644 --- a/src/whisper-utils/whisper-processing.cpp +++ b/src/whisper-utils/whisper-processing.cpp @@ -55,19 +55,32 @@ struct whisper_context *init_whisper_context(const std::string &model_path_in, gf); struct whisper_context_params cparams = whisper_context_default_params(); -#ifdef LOCALVOCAL_WITH_CUDA - cparams.use_gpu = true; - cparams.gpu_device = 0; - obs_log(LOG_INFO, "Using CUDA GPU for inference, device %d", cparams.gpu_device); -#elif defined(LOCALVOCAL_WITH_CLBLAST) - cparams.use_gpu = true; - cparams.gpu_device = 0; - obs_log(LOG_INFO, "Using OpenCL for inference"); -#else - cparams.use_gpu = false; - obs_log(LOG_INFO, "Using CPU for inference"); -#endif - cparams.flash_attn = false; + + if (gf->gpu_device < 0) { + cparams.use_gpu = false; + obs_log(LOG_INFO, "Using CPU for inference"); + } else { + try { + if (gf->gpu_device >= (int)gf->gpu_devices.size()) { + obs_log(LOG_WARNING, + "Invalid GPU device selected: %d. Using CPU for inference", + cparams.gpu_device); + cparams.use_gpu = false; + } else { + cparams.use_gpu = true; + cparams.gpu_device = gf->gpu_device; + obs_log(LOG_INFO, "Using GPU device %d (%s) for inference", + cparams.gpu_device, + gf->gpu_devices.at(cparams.gpu_device).device_name); + } + } catch (const std::exception &e) { + obs_log(LOG_WARNING, + "Error retrieving selected GPU device. Using CPU for inference. Error: %s", + e.what()); + cparams.use_gpu = false; + } + } + cparams.flash_attn = gf->enable_flash_attn; struct whisper_context *ctx = nullptr; try { @@ -226,14 +239,14 @@ long long process_audio_from_buffer(struct cleanstream_data *gf) // copy gf->frames from the end of the input buffer to the copy_buffers for (size_t c = 0; c < gf->channels; c++) { - circlebuf_peek_back(&gf->input_buffers[c], gf->copy_buffers[c], - gf->frames * sizeof(float)); + deque_peek_back(&gf->input_buffers[c], gf->copy_buffers[c], + gf->frames * sizeof(float)); } // peek at the info_buffer to get the timestamp of the last info struct cleanstream_audio_info info_from_buf = {0}; - circlebuf_peek_back(&gf->info_buffer, &info_from_buf, - sizeof(struct cleanstream_audio_info)); + deque_peek_back(&gf->info_buffer, &info_from_buf, + sizeof(struct cleanstream_audio_info)); end_timestamp = info_from_buf.timestamp; start_timestamp = end_timestamp - (int)(gf->frames * 1000 / gf->sample_rate) * 1000000; diff --git a/src/whisper-utils/whisper-utils.cpp b/src/whisper-utils/whisper-utils.cpp index bf052dc..aee320a 100644 --- a/src/whisper-utils/whisper-utils.cpp +++ b/src/whisper-utils/whisper-utils.cpp @@ -147,7 +147,9 @@ void start_whisper_thread_with_path(struct cleanstream_data *gf, const std::stri gf->whisper_thread.swap(new_whisper_thread); } +// clang-format off #define is_lead_byte(c) (((c) & 0xe0) == 0xc0 || ((c) & 0xf0) == 0xe0 || ((c) & 0xf8) == 0xf0) +// clang-format off #define is_trail_byte(c) (((c) & 0xc0) == 0x80) inline int lead_byte_length(const uint8_t c)