diff --git a/.github/actions/build-whisper/action.yaml b/.github/actions/build-whisper/action.yaml
index 319f35e..1f3d62c 100644
--- a/.github/actions/build-whisper/action.yaml
+++ b/.github/actions/build-whisper/action.yaml
@@ -8,7 +8,7 @@ inputs:
whisper-cpp-version:
description: 'The version of whisper.cpp to use'
required: true
- default: 'v1.6.2-openmp'
+ default: 'v1.7.2-windows-fix'
os:
description: 'The operating system to build for'
required: true
@@ -21,10 +21,6 @@ inputs:
description: 'The shell to use'
required: true
default: 'bash'
- cc:
- description: 'The C compiler to use'
- required: true
- default: 'gcc'
runs:
using: composite
steps:
@@ -33,9 +29,10 @@ runs:
uses: actions/cache/restore@v4
with:
path: |
- third_party/whisper.cpp/libwhisper.a
- third_party/whisper.cpp/*.h
- key: whisper-${{ inputs.whisper-cpp-version }}-${{ inputs.os }}-{{ inputs.arch }}-cache
+ third_party/whisper.cpp/*whisper.a
+ third_party/whisper.cpp/include/*.h
+ third_party/whisper.cpp/include/ggml/*.h
+ key: whisper-${{ inputs.whisper-cpp-version }}-${{ inputs.os }}-${{ inputs.arch }}-10-cache
- name: Checkout whisper.cpp
if: steps.cache-whisper-restore.outputs.cache-hit != 'true'
uses: actions/checkout@v4
@@ -45,14 +42,12 @@ runs:
ref: ${{ inputs.whisper-cpp-version }}
- name: Build whisper.cpp
if: steps.cache-whisper-restore.outputs.cache-hit != 'true'
- env:
- CC: ${{ inputs.cc }}
shell: ${{ inputs.shell }}
run: make whisper
- name: Set whisper paths
shell: ${{ inputs.shell }}
run: |
- echo "C_INCLUDE_PATH=${{ github.workspace }}/third_party/whisper.cpp/" >> $GITHUB_ENV
+ echo "C_INCLUDE_PATH=${{ github.workspace }}/third_party/whisper.cpp/include:{{ github.workspace }}/third_party/whisper.cpp/ggml/include" >> $GITHUB_ENV
echo "LIBRARY_PATH=${{ github.workspace }}/third_party/whisper.cpp/" >> $GITHUB_ENV
echo "GOARCH=${{ inputs.arch }}" >> $GITHUB_ENV
- name: Save whisper.cpp artifacts
@@ -61,6 +56,7 @@ runs:
uses: actions/cache/save@v4
with:
path: |
- third_party/whisper.cpp/libwhisper.a
- third_party/whisper.cpp/*.h
- key: ${{ steps.cache-whisper-restore.outputs.cache-primary-key }}
\ No newline at end of file
+ third_party/whisper.cpp/*whisper.a
+ third_party/whisper.cpp/include/*.h
+ third_party/whisper.cpp/include/ggml/*.h
+ key: ${{ steps.cache-whisper-restore.outputs.cache-primary-key }}
diff --git a/.github/workflows/skyeye.yaml b/.github/workflows/skyeye.yaml
index c523436..b95e78b 100644
--- a/.github/workflows/skyeye.yaml
+++ b/.github/workflows/skyeye.yaml
@@ -89,7 +89,6 @@ jobs:
with:
os: macos
arch: arm64
- cc: clang
- name: Build SkyEye
run: make skyeye
- name: Build SkyEye Scaler
@@ -134,7 +133,6 @@ jobs:
mingw-w64-ucrt-x86_64-toolchain
mingw-w64-ucrt-x86_64-opus
mingw-w64-ucrt-x86_64-libsoxr
- mingw-w64-ucrt-x86_64-openblas
mingw-w64-ucrt-x86_64-gcc
mingw-w64-ucrt-x86_64-go
mingw-w64-ucrt-x86_64-curl
@@ -242,4 +240,4 @@ jobs:
registry-password: ${{ secrets.GITHUB_TOKEN }}
image-name: ${{ github.repository }}-scaler
target: skyeye-scaler
- skyeye-version: ${{ env.GITHUB_REF_NAME }}
\ No newline at end of file
+ skyeye-version: ${{ env.GITHUB_REF_NAME }}
diff --git a/Dockerfile b/Dockerfile
index d5994f3..26be568 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -7,7 +7,6 @@ RUN apt-get update && apt-get install -y \
gcc \
libopus-dev \
libsoxr-dev \
- libopenblas-openmp-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /skyeye
COPY third_party third_party
@@ -26,7 +25,6 @@ FROM debian:bookworm-slim AS skyeye
RUN apt-get update && apt-get install -y \
libopus0 \
libsoxr0 \
- libopenblas0-openmp \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /skyeye/skyeye /opt/skyeye/bin/skyeye
ENTRYPOINT ["/opt/skyeye/bin/skyeye"]
diff --git a/Makefile b/Makefile
index 87d0e18..d32d290 100644
--- a/Makefile
+++ b/Makefile
@@ -16,8 +16,8 @@ else
OS_DISTRIBUTION := $(shell lsb_release -si)
endif
+
# Source code paths
-SKYEYE_PATH = $(shell pwd)
SKYEYE_SOURCES = $(shell find . -type f -name '*.go')
SKYEYE_SOURCES += go.mod go.sum
SKYEYE_BIN = skyeye
@@ -25,22 +25,34 @@ SKYEYE_SCALER_BIN = skyeye-scaler
WHISPER_CPP_PATH = third_party/whisper.cpp
LIBWHISPER_PATH = $(WHISPER_CPP_PATH)/libwhisper.a
-WHISPER_H_PATH = $(WHISPER_CPP_PATH)/whisper.h
+WHISPER_H_PATH = $(WHISPER_CPP_PATH)/include/whisper.h
WHISPER_CPP_REPO = https://github.com/dharmab/whisper.cpp.git
-WHISPER_CPP_VERSION = v1.6.2-openmp
+WHISPER_CPP_VERSION = v1.7.2-windows-fix
+WHISPER_CPP_BUILD_ENV =
# Compiler variables and flags
GOBUILDVARS = GOARCH=$(GOARCH)
+ABS_WHISPER_CPP_PATH = $(abspath $(WHISPER_CPP_PATH))
BUILD_VARS = CGO_ENABLED=1 \
- C_INCLUDE_PATH="$(SKYEYE_PATH)/$(WHISPER_CPP_PATH)" \
- LIBRARY_PATH="$(SKYEYE_PATH)/$(WHISPER_CPP_PATH)"
+ C_INCLUDE_PATH="$(ABS_WHISPER_CPP_PATH)/include:$(ABS_WHISPER_CPP_PATH)/ggml/include" \
+ LIBRARY_PATH="$(ABS_WHISPER_CPP_PATH)"
BUILD_FLAGS = -tags nolibopusfile
# Populate --version from Git tag
ifeq ($(SKYEYE_VERSION),)
SKYEYE_VERSION=$(shell git describe --tags || echo devel)
endif
-LDFLAGS= -X "main.Version=$(SKYEYE_VERSION)"
+LDFLAGS= -X "main.Version=$(SKYEYE_VERSION) -fopenmp"
+
+# macOS-specific settings
+ifeq ($(OS_DISTRIBUTION),macOS)
+# Use Homebrew LLVM/Clang for OpenMP support
+CC=$(shell brew --prefix llvm)/bin/clang
+CXX=$(shell brew --prefix llvm)/bin/clang++
+BUILD_VARS += CC=$(CC) CXX=$(CXX)
+# Enable GPU acceleration
+WHISPER_CPP_BUILD_ENV = GGML_METAL=1
+endif
# Windows-specific settings
ifeq ($(OS_DISTRIBUTION),Windows)
@@ -51,11 +63,11 @@ SKYEYE_SCALER_BIN = skyeye-scaler.exe
GO = /ucrt64/bin/go
GOBUILDVARS += GOROOT="/ucrt64/lib/go" GOPATH="/ucrt64"
# Static linking on Windows to avoid MSYS2 dependency at runtime
-LIBRARIES = opus soxr openblas
+LIBRARIES = opus soxr
CFLAGS = $(pkg-config $(LIBRARIES) --cflags --static)
BUILD_VARS += CFLAGS=$(CFLAGS)
EXTLDFLAGS = $(pkg-config $(LIBRARIES) --libs --static)
-LDFLAGS += -linkmode external -extldflags "$(EXTLDFLAGS) -static -fopenmp"
+LDFLAGS += -linkmode external -extldflags "$(EXTLDFLAGS) -static"
endif
BUILD_VARS += LDFLAGS='$(LDFLAGS)'
@@ -73,8 +85,7 @@ install-msys2-dependencies:
$(MINGW_PACKAGE_PREFIX)-toolchain \
$(MINGW_PACKAGE_PREFIX)-go \
$(MINGW_PACKAGE_PREFIX)-opus \
- $(MINGW_PACKAGE_PREFIX)-libsoxr \
- $(MINGW_PACKAGE_PREFIX)-openblas
+ $(MINGW_PACKAGE_PREFIX)-libsoxr
.PHONY: install-arch-linux-dependencies
install-arch-linux-dependencies:
@@ -83,8 +94,7 @@ install-arch-linux-dependencies:
base-devel \
go \
opus \
- libsoxr \
- openblas
+ libsoxr
.PHONY: install-debian-dependencies
install-debian-dependencies:
@@ -95,25 +105,22 @@ install-debian-dependencies:
libopus-dev \
libopus0 \
libsoxr-dev \
- libsoxr0 \
- libopenblas0-openmp \
- libopenblas-openmp-dev \
+ libsoxr0
.PHONY: install-macos-dependencies
install-macos-dependencies:
+ xcode-select --install || true
brew install \
git \
go \
- opus \
- libsoxr
-
-WHISPER_CPP_BUILD_ENV =
-ifneq ($(OS_DISTRIBUTION),macOS)
-WHISPER_CPP_BUILD_ENV = GGML_OPENBLAS=1
-endif
+ libomp \
+ libsoxr \
+ llvm \
+ opus
$(LIBWHISPER_PATH) $(WHISPER_H_PATH):
if [ ! -f $(LIBWHISPER_PATH) -o ! -f $(WHISPER_H_PATH) ]; then git -C "$(WHISPER_CPP_PATH)" checkout --quiet $(WHISPER_CPP_VERSION) || git clone --depth 1 --branch $(WHISPER_CPP_VERSION) -c advice.detachedHead=false "$(WHISPER_CPP_REPO)" "$(WHISPER_CPP_PATH)" && $(WHISPER_CPP_BUILD_ENV) make -C $(WHISPER_CPP_PATH)/bindings/go whisper; fi
+ if [ -f third_party/whisper.cpp/whisper.a ] && [ ! -f third_party/whisper.cpp/libwhisper.a ]; then cp third_party/whisper.cpp/whisper.a third_party/whisper.cpp/libwhisper.a; fi
.PHONY: whisper
whisper: $(LIBWHISPER_PATH) $(WHISPER_H_PATH)
diff --git a/docs/ADMIN.md b/docs/ADMIN.md
index 8953656..ebf9626 100644
--- a/docs/ADMIN.md
+++ b/docs/ADMIN.md
@@ -13,11 +13,11 @@ This is a technical article on how to deploy SkyEye, targeted at multiplayer ser
SkyEye works best when run on a dedicated system, separate from the DCS World and SRS servers.
-_Recommended Architecture: DCS, TacView and SRS on one Windows server. SkyEye on another Linux server._
+_Recommended Architecture: DCS, TacView and SRS on one Windows server. SkyEye on another Linux or macOS server._
```mermaid
flowchart LR
- dcs[Windows
DCS World Server
TacView Exporter
SRS Server] <--> skyeye[Linux
SkyEye]
+ dcs[Windows
DCS World Server
TacView Exporter
SRS Server] <--> skyeye[Linux/macOS
SkyEye]
```
If you insist on running SkyEye on the same system as DCS, I cannot offer you any guarantees of performance. If you choose to try this anyway, I do recommend configuring Process Affinity to pin SkyEye to a set of dedicated CPU cores separate from any other CPU-intensive software. The easiest way to do this on Windows is by using the [CPU Affinities feature in Process Lasso](https://bitsum.com/processlasso-docs/#default_affinities).
@@ -26,12 +26,11 @@ SkyEye will automatically reconnect to TacView if the connection is lost. Howeve
## Software
-SkyEye is officially supported on Windows and Linux. The Windows version bundles all required libraries within skyeye.exe. The Linux version
-requires Opus, SOXR and OpenBLAS to be installed using the OS package manager.
+SkyEye is officially supported on Windows AMD64, Linux AMD64 and Apple Silicon. The Windows version bundles all required libraries within skyeye.exe. The Linux version requires Opus and SOXR to be installed using the OS package manager. The macOS version requires Opus and SOXR to be installed using Homebrew.
## Hardware
-SkyEye requires a fast, multithreaded, **dedicated** CPU, 3GB of RAM, and about 2GB of disk space. The CPU must have support for [AVX2](https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2).
+SkyEye requires a fast, multithreaded, **dedicated** CPU, 3GB of RAM, and about 2GB of disk space. On AMD64, the CPU must have support for [AVX2](https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2).
CPU Series|AVX2 Added In
-|-
@@ -39,7 +38,7 @@ Intel Core|Haswell (2013)
AMD|Excavator (2015)
Intel Pentium/Celeron|Tiger Lake (2020)
-SkyEye currently only officially supports the AMD64 (x86-64) CPU architecture; ARM CPUs are not yet officially supported. I've found that at least 4 dedicated CPU cores are needed for a good experience, but this may differ by the exact CPU being used, so experiment and see what works well for you.
+SkyEye currently only officially supports the AMD64 (x86-64) and Apple Sillicon CPU architectures; ARM CPUs are not yet officially supported on Windows and Linux. On Windows and Linux I've found that at least 4 dedicated CPU cores are needed for a good experience, but this may differ by the exact CPU being used, so experiment and see what works well for you. On macOS, SkyEye uses GPU acceleration for some operations, so CPU load is lower.
It is important that the CPU cores be **dedicated** cores. Shared core virtual machines are **not supported** and will result in **high latency and stuttering audio.**
@@ -47,6 +46,8 @@ Non-scientific speech recognition performance:
System|CPU|Speech Recognition Model|Speech Recognition Time (Synthetic benchmark)|Speech Recognition Time (In practice)
-|-|-|-|-
+M4 Mac Mini|Apple M4|ggml-small.en.bin|0.25-0.5s|?
+M4 Mac Mini|Apple M4|ggml-medium.en.bin|0.9-1.0s|?
My current PC|AMD 5900X|ggml-small.en.bin|1.0-1.5s|1.5-2.0s
My older PC|AMD 3900XT|ggml-small.en.bin|2-3s|?
Vultr Optimized Cloud (CPU Optimized)|AMD EPYC Milan (4 dedicated cores)|ggml-small.en.bin|3.0-3.5s|3.0-3.5s
@@ -130,7 +131,9 @@ I recommend you retain your logs so that you can include them in any bug reports
On Linux, the easiest way to retain your logs is to run SkyEye as a systemd-managed service. This will automatically retain your logs in the system journal, and you'll be able to query and search the logs using `journalctl -u skyeye`.
-On Windows, the easiest way to retain your logs is to use [redirection](https://learn.microsoft.com/en-us/troubleshoot/developer/visualstudio/cpp/language-compilers/redirecting-error-command-prompt).
+On macOS, the easiest way to retain your logs is to pipe the output of SkyEye to a file using `tee`.
+
+On Windows, SkyEye is bundled with WinSW and a service configuration file which will log to a file.
Advanced users should consider sending their logs to a log aggregator such as [Grafana Cloud](https://grafana.com/products/cloud/logs/). If you do this, I also recommend using `--log-format=json` to log in JSON format, which is easier to search and filter when using an aggregator.
@@ -187,19 +190,19 @@ A sample [cloud-init](https://cloudinit.readthedocs.io/en/latest/) config is pro
### Manual Installation
-Install shared libraries for [Opus](https://opus-codec.org/), [SoX Resampler](https://sourceforge.net/p/soxr/wiki/Home/) and [OpenBLAS](http://www.openblas.net/) with [OpenMP](https://www.openmp.org/about/openmp-faq/#OMPAPI).
+Install shared libraries for [Opus](https://opus-codec.org/) and [SoX Resampler](https://sourceforge.net/p/soxr/wiki/Home/).
Ubuntu:
```bash
sudo apt-get update
-sudo apt-get install libopus0 libsoxr0 libopenblas0-openmp
+sudo apt-get install libopus0 libsoxr0
```
Arch Linux:
```bash
-sudo pacman -Syu opus soxr openblas
+sudo pacman -Syu opus soxr
```
Download SkyEye and an AI model. Copy them to `/opt/skyeye/`. Create a `skyeye` user to run SkyEye.
@@ -279,6 +282,22 @@ journalctl -u skyeye
journalctl -u skyeye > skyeye.log
```
+## macOS
+
+_Work in Progress_
+
+Download the SkyEye release ZIP from the [releases page](https://github.com/dharmab/skyeye/releases) and extract it.
+
+Download an AI model.
+
+Edit `config.yaml` as required.
+
+Open Terminal and run:
+
+```sh
+./skyeye --config-file=config.yaml | tee skyeye.log
+```
+
## Windows
Download the SkyEye release ZIP from the [releases page](https://github.com/dharmab/skyeye/releases) and extract it.
diff --git a/go.mod b/go.mod
index e7dee72..7c634fd 100644
--- a/go.mod
+++ b/go.mod
@@ -10,7 +10,7 @@ require (
github.com/bwmarrin/discordgo v0.28.1
github.com/dharmab/goacmi v1.0.2
github.com/gammazero/deque v0.2.1
- github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20240727173504-6739eb83c3ca
+ github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20241121150429-8c6a9b8bb6a0
github.com/golangci/golangci-lint v1.60.3
github.com/gopxl/beep/v2 v2.0.3
github.com/hbollon/go-edlib v1.6.0
diff --git a/go.sum b/go.sum
index aa786b0..bb66a7b 100644
--- a/go.sum
+++ b/go.sum
@@ -176,8 +176,8 @@ github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
github.com/gammazero/deque v0.2.1 h1:qSdsbG6pgp6nL7A0+K/B7s12mcCY/5l5SIUpMOl+dC0=
github.com/gammazero/deque v0.2.1/go.mod h1:LFroj8x4cMYCukHJDbxFCkT+r9AndaJnFMuZDV34tuU=
-github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20240727173504-6739eb83c3ca h1:s1f7gd0NpwAdjyAcJvn03TnQqQZTJojXtmdfPy7kTOk=
-github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20240727173504-6739eb83c3ca/go.mod h1:QIjZ9OktHFG7p+/m3sMvrAJKKdWrr1fZIK0rM6HZlyo=
+github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20241121150429-8c6a9b8bb6a0 h1:vSv0WhsCkhau0BdC1H7Q2lHR8pzz0skaQkXZdEPYp/4=
+github.com/ggerganov/whisper.cpp/bindings/go v0.0.0-20241121150429-8c6a9b8bb6a0/go.mod h1:qyHjS/50ORo01H0NsuEEGsQR9VCtOcEye0gUl2sx1s8=
github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk=
github.com/ghostiam/protogetter v0.3.6/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw=
github.com/go-audio/audio v1.0.0 h1:zS9vebldgbQqktK4H0lUqWrG8P0NxCJVqcj7ZpNnwd4=
diff --git a/init/cloud-init/ubuntu.yaml b/init/cloud-init/ubuntu.yaml
index 536ae61..9aa5f7b 100644
--- a/init/cloud-init/ubuntu.yaml
+++ b/init/cloud-init/ubuntu.yaml
@@ -5,7 +5,6 @@ users:
packages:
- libopus0
- libsoxr0
- - libopenblas0-openmp
package_update: true
package_upgrade: true
write_files: