Fix comment inaccuracies and restore lint targets

- Clarify sample rate is configurable (8k/12k/16k/24k/48k), not fixed at 48kHz
- Expand mutex comment to include full lifecycle protection scope
- Document that ALSA playback init fails immediately with no fallback
- Add async behavior documentation to audio enable/restart functions
- Restore build_audio_deps target lost during merge
- Restore lint-fix, lint-go, lint-ui Makefile targets
- Fix variable alignment per linter
This commit is contained in:
Alex P 2025-11-21 01:10:04 +02:00
parent 4001ef651f
commit 584b9fe3bf
3 changed files with 52 additions and 10 deletions

View File

@ -47,6 +47,10 @@ BIN_DIR := $(shell pwd)/bin
TEST_DIRS := $(shell find . -name "*_test.go" -type f -exec dirname {} \; | sort -u)
# Build ALSA and Opus static libs for ARM in /opt/jetkvm-audio-libs
build_audio_deps:
bash .devcontainer/install_audio_deps.sh
build_native:
@if [ "$(SKIP_NATIVE_IF_EXISTS)" = "1" ] && [ -f "internal/native/cgo/lib/libjknative.a" ]; then \
echo "libjknative.a already exists, skipping native build..."; \
@ -137,3 +141,31 @@ release:
@shasum -a 256 bin/jetkvm_app | cut -d ' ' -f 1 > bin/jetkvm_app.sha256
rclone copyto bin/jetkvm_app r2://jetkvm-update/app/$(VERSION)/jetkvm_app
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION)/jetkvm_app.sha256
# Run golangci-lint locally with the same configuration as CI
lint-go: build_audio_deps
@echo "Running golangci-lint..."
@mkdir -p static && touch static/.gitkeep
golangci-lint run --verbose
# Run both Go and UI linting with auto-fix
lint-fix: lint-go-fix lint-ui-fix
@echo "All linting with auto-fix completed successfully!"
# Run golangci-lint with auto-fix
lint-go-fix: build_audio_deps
@echo "Running golangci-lint with auto-fix..."
@mkdir -p static && touch static/.gitkeep
golangci-lint run --fix --verbose
# Run UI linting locally (mirrors GitHub workflow ui-lint.yml)
lint-ui:
@echo "Running UI lint..."
@cd ui && npm ci && npm run lint
# Run UI linting with auto-fix
lint-ui-fix:
@echo "Running UI lint with auto-fix..."
@cd ui && npm ci && npm run lint:fix
# Legacy alias for UI linting (for backward compatibility)
ui-lint: lint-ui

View File

@ -13,10 +13,10 @@ import (
)
var (
audioMutex sync.Mutex
inputSourceMutex sync.Mutex // Prevents concurrent WebRTC packets from racing during lazy connect + write
outputSource atomic.Pointer[audio.AudioSource]
inputSource atomic.Pointer[audio.AudioSource]
audioMutex sync.Mutex
inputSourceMutex sync.Mutex // Prevents concurrent WebRTC packets from racing during lazy connect + write
outputSource atomic.Pointer[audio.AudioSource]
inputSource atomic.Pointer[audio.AudioSource]
outputRelay atomic.Pointer[audio.OutputRelay]
inputRelay atomic.Pointer[audio.InputRelay]
audioInitialized bool
@ -257,6 +257,9 @@ func setPendingInputTrack(track *webrtc.TrackRemote) {
go handleInputTrackForSession(track)
}
// SetAudioOutputEnabled enables or disables audio output capture.
// Returns immediately; when enabling, audio starts asynchronously to prevent UI blocking.
// Check logs for async operation status.
func SetAudioOutputEnabled(enabled bool) error {
if audioOutputEnabled.Swap(enabled) == enabled {
return nil
@ -274,6 +277,9 @@ func SetAudioOutputEnabled(enabled bool) error {
return nil
}
// SetAudioInputEnabled enables or disables audio input playback.
// Returns immediately; when enabling, audio starts asynchronously to prevent UI blocking.
// Check logs for async operation status.
func SetAudioInputEnabled(enabled bool) error {
if audioInputEnabled.Swap(enabled) == enabled {
return nil
@ -329,6 +335,9 @@ func SetAudioOutputSource(source string) error {
return nil
}
// RestartAudioOutput stops and restarts the audio output capture.
// Returns immediately; restart happens asynchronously to prevent UI blocking.
// Check logs for async operation status.
func RestartAudioOutput() error {
audioMutex.Lock()
hasActiveOutput := audioOutputEnabled.Load() && currentAudioTrack != nil && outputSource.Load() != nil

View File

@ -11,7 +11,8 @@
* Key features:
* - ARM NEON SIMD optimization for all audio operations
* - Opus in-band FEC for packet loss resilience
* - S16_LE stereo, 20ms frames at 48kHz (ALSA resamples non-48kHz sources)
* - S16_LE stereo, 20ms frames (sample rate configurable: 8k/12k/16k/24k/48kHz)
* - ALSA rate plugin resamples hardware output to match requested Opus-compatible rate
*/
#include <alsa/asoundlib.h>
@ -75,11 +76,11 @@ static uint32_t max_backoff_us_global = 500000;
static atomic_int capture_stop_requested = 0;
static atomic_int playback_stop_requested = 0;
// Mutexes to protect concurrent access to ALSA handles and codecs
// Mutexes to protect concurrent access to ALSA handles and codecs throughout their lifecycle
// These prevent race conditions when jetkvm_audio_*_close() is called while
// jetkvm_audio_read_encode() or jetkvm_audio_decode_write() are executing.
// The mutexes are held during ALSA I/O and codec operations to ensure
// handles remain valid throughout the operation.
// The mutexes protect initialization, cleanup, ALSA I/O, codec operations, and handle validation
// to ensure handles remain valid from acquisition through release.
static pthread_mutex_t capture_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t playback_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -606,7 +607,7 @@ retry_read:
/**
* Initialize INPUT path (Opus decoder device speakers)
* Opens ALSA playback device from ALSA_PLAYBACK_DEVICE env (default: hw:1,0)
* and creates Opus decoder
* and creates Opus decoder. Returns immediately on device open failure (no fallback).
* @return 0 on success, -EBUSY if initializing, -1/-2 on errors
*/
int jetkvm_audio_playback_init() {