mirror of https://github.com/jetkvm/kvm.git
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:
parent
4001ef651f
commit
584b9fe3bf
32
Makefile
32
Makefile
|
|
@ -47,6 +47,10 @@ BIN_DIR := $(shell pwd)/bin
|
||||||
|
|
||||||
TEST_DIRS := $(shell find . -name "*_test.go" -type f -exec dirname {} \; | sort -u)
|
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:
|
build_native:
|
||||||
@if [ "$(SKIP_NATIVE_IF_EXISTS)" = "1" ] && [ -f "internal/native/cgo/lib/libjknative.a" ]; then \
|
@if [ "$(SKIP_NATIVE_IF_EXISTS)" = "1" ] && [ -f "internal/native/cgo/lib/libjknative.a" ]; then \
|
||||||
echo "libjknative.a already exists, skipping native build..."; \
|
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
|
@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 r2://jetkvm-update/app/$(VERSION)/jetkvm_app
|
||||||
rclone copyto bin/jetkvm_app.sha256 r2://jetkvm-update/app/$(VERSION)/jetkvm_app.sha256
|
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
|
||||||
|
|
|
||||||
9
audio.go
9
audio.go
|
|
@ -257,6 +257,9 @@ func setPendingInputTrack(track *webrtc.TrackRemote) {
|
||||||
go handleInputTrackForSession(track)
|
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 {
|
func SetAudioOutputEnabled(enabled bool) error {
|
||||||
if audioOutputEnabled.Swap(enabled) == enabled {
|
if audioOutputEnabled.Swap(enabled) == enabled {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -274,6 +277,9 @@ func SetAudioOutputEnabled(enabled bool) error {
|
||||||
return nil
|
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 {
|
func SetAudioInputEnabled(enabled bool) error {
|
||||||
if audioInputEnabled.Swap(enabled) == enabled {
|
if audioInputEnabled.Swap(enabled) == enabled {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -329,6 +335,9 @@ func SetAudioOutputSource(source string) error {
|
||||||
return nil
|
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 {
|
func RestartAudioOutput() error {
|
||||||
audioMutex.Lock()
|
audioMutex.Lock()
|
||||||
hasActiveOutput := audioOutputEnabled.Load() && currentAudioTrack != nil && outputSource.Load() != nil
|
hasActiveOutput := audioOutputEnabled.Load() && currentAudioTrack != nil && outputSource.Load() != nil
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@
|
||||||
* Key features:
|
* Key features:
|
||||||
* - ARM NEON SIMD optimization for all audio operations
|
* - ARM NEON SIMD optimization for all audio operations
|
||||||
* - Opus in-band FEC for packet loss resilience
|
* - 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>
|
#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 capture_stop_requested = 0;
|
||||||
static atomic_int playback_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
|
// These prevent race conditions when jetkvm_audio_*_close() is called while
|
||||||
// jetkvm_audio_read_encode() or jetkvm_audio_decode_write() are executing.
|
// jetkvm_audio_read_encode() or jetkvm_audio_decode_write() are executing.
|
||||||
// The mutexes are held during ALSA I/O and codec operations to ensure
|
// The mutexes protect initialization, cleanup, ALSA I/O, codec operations, and handle validation
|
||||||
// handles remain valid throughout the operation.
|
// to ensure handles remain valid from acquisition through release.
|
||||||
static pthread_mutex_t capture_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t capture_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static pthread_mutex_t playback_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)
|
* Initialize INPUT path (Opus decoder → device speakers)
|
||||||
* Opens ALSA playback device from ALSA_PLAYBACK_DEVICE env (default: hw:1,0)
|
* 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
|
* @return 0 on success, -EBUSY if initializing, -1/-2 on errors
|
||||||
*/
|
*/
|
||||||
int jetkvm_audio_playback_init() {
|
int jetkvm_audio_playback_init() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue