mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 15:25:46 +00:00
refactor(lib): fold utils/audio + autodj-overlap into lib/audio (audio-transition infra; drains utils/playback)
This commit is contained in:
@@ -3,7 +3,7 @@ import type { OrbitTransitionSettings } from '@/features/orbit/api/orbit';
|
|||||||
import {
|
import {
|
||||||
sanitizeAutodjOverlapCapMode,
|
sanitizeAutodjOverlapCapMode,
|
||||||
sanitizeAutodjOverlapCapSec,
|
sanitizeAutodjOverlapCapSec,
|
||||||
} from '@/utils/playback/autodjOverlapCap';
|
} from '@/lib/audio/autodjOverlapCap';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bridge between the local playback-transition settings (in `authStore`) and
|
* Bridge between the local playback-transition settings (in `authStore`) and
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import {
|
|||||||
} from '@/features/playback/utils/playback/playbackServer';
|
} from '@/features/playback/utils/playback/playbackServer';
|
||||||
import { resolvePlaybackUrl } from '@/features/playback/utils/playback/resolvePlaybackUrl';
|
import { resolvePlaybackUrl } from '@/features/playback/utils/playback/resolvePlaybackUrl';
|
||||||
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
||||||
import { audioPlayHiResBlendArgs } from '@/utils/audio/hiResCrossfadeResample';
|
import { audioPlayHiResBlendArgs } from '@/lib/audio/hiResCrossfadeResample';
|
||||||
import { showToast } from '@/utils/ui/toast';
|
import { showToast } from '@/utils/ui/toast';
|
||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { getPlayGeneration, setIsAudioPaused } from '@/features/playback/store/engineState';
|
import { getPlayGeneration, setIsAudioPaused } from '@/features/playback/store/engineState';
|
||||||
@@ -89,7 +89,7 @@ import {
|
|||||||
} from '@/features/playback/store/seekTargetState';
|
} from '@/features/playback/store/seekTargetState';
|
||||||
import { refreshWaveformForTrack } from '@/features/playback/store/waveformRefresh';
|
import { refreshWaveformForTrack } from '@/features/playback/store/waveformRefresh';
|
||||||
import { analyzeBoundary, computeWaveformSilence } from '@/lib/waveform/waveformSilence';
|
import { analyzeBoundary, computeWaveformSilence } from '@/lib/waveform/waveformSilence';
|
||||||
import { autodjMaxOverlapCapSec } from '@/utils/playback/autodjOverlapCap';
|
import { autodjMaxOverlapCapSec } from '@/lib/audio/autodjOverlapCap';
|
||||||
import {
|
import {
|
||||||
autodjJsTriggerAtSec,
|
autodjJsTriggerAtSec,
|
||||||
clampCrossfadeSecs,
|
clampCrossfadeSecs,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/utils/audio/loudnessPreAnalysisSlider';
|
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { onAnalysisStorageChanged } from '@/store/analysisSync';
|
import { onAnalysisStorageChanged } from '@/store/analysisSync';
|
||||||
import { emitNormalizationDebug } from '@/features/playback/store/normalizationDebug';
|
import { emitNormalizationDebug } from '@/features/playback/store/normalizationDebug';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/utils/audio/loudnessPreAnalysisSlider';
|
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { emitNormalizationDebug } from '@/features/playback/store/normalizationDebug';
|
import { emitNormalizationDebug } from '@/features/playback/store/normalizationDebug';
|
||||||
import { invokeAudioSetNormalizationDeduped } from '@/features/playback/store/normalizationIpcDedupe';
|
import { invokeAudioSetNormalizationDeduped } from '@/features/playback/store/normalizationIpcDedupe';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { autodjMaxOverlapCapSec } from '@/utils/playback/autodjOverlapCap';
|
import { autodjMaxOverlapCapSec } from '@/lib/audio/autodjOverlapCap';
|
||||||
import { computeWaveformSilence, planCrossfadeTransition } from '@/lib/waveform/waveformSilence';
|
import { computeWaveformSilence, planCrossfadeTransition } from '@/lib/waveform/waveformSilence';
|
||||||
import { findLocalPlaybackUrl } from '@/store/localPlaybackResolve';
|
import { findLocalPlaybackUrl } from '@/store/localPlaybackResolve';
|
||||||
import { playbackCacheKeyForRef } from '@/features/playback/utils/playback/playbackServer';
|
import { playbackCacheKeyForRef } from '@/features/playback/utils/playback/playbackServer';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
} from '@/features/playback/utils/playback/playbackServer';
|
} from '@/features/playback/utils/playback/playbackServer';
|
||||||
import { resolvePlaybackUrl } from '@/features/playback/utils/playback/resolvePlaybackUrl';
|
import { resolvePlaybackUrl } from '@/features/playback/utils/playback/resolvePlaybackUrl';
|
||||||
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
||||||
import { audioPlayHiResBlendArgs } from '@/utils/audio/hiResCrossfadeResample';
|
import { audioPlayHiResBlendArgs } from '@/lib/audio/hiResCrossfadeResample';
|
||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { getPlayGeneration, setIsAudioPaused } from '@/features/playback/store/engineState';
|
import { getPlayGeneration, setIsAudioPaused } from '@/features/playback/store/engineState';
|
||||||
import { touchHotCacheOnPlayback } from '@/features/playback/store/hotCacheTouch';
|
import { touchHotCacheOnPlayback } from '@/features/playback/store/hotCacheTouch';
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const { authState, invokeMock } = vi.hoisted(() => ({
|
|||||||
|
|
||||||
vi.mock('@tauri-apps/api/core', () => ({ invoke: invokeMock }));
|
vi.mock('@tauri-apps/api/core', () => ({ invoke: invokeMock }));
|
||||||
vi.mock('@/store/authStore', () => ({ useAuthStore: { getState: () => authState } }));
|
vi.mock('@/store/authStore', () => ({ useAuthStore: { getState: () => authState } }));
|
||||||
vi.mock('@/utils/audio/loudnessPreAnalysisSlider', () => ({
|
vi.mock('@/lib/audio/loudnessPreAnalysisSlider', () => ({
|
||||||
effectiveLoudnessPreAnalysisAttenuationDb: (attenuation: number) => attenuation,
|
effectiveLoudnessPreAnalysisAttenuationDb: (attenuation: number) => attenuation,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/utils/audio/loudnessPreAnalysisSlider';
|
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Two IPC entry points to the Rust normalization pipeline that get hammered
|
* Two IPC entry points to the Rust normalization pipeline that get hammered
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import {
|
|||||||
} from '@/store/localPlaybackResolve';
|
} from '@/store/localPlaybackResolve';
|
||||||
import { resolvePlaybackUrl } from '@/features/playback/utils/playback/resolvePlaybackUrl';
|
import { resolvePlaybackUrl } from '@/features/playback/utils/playback/resolvePlaybackUrl';
|
||||||
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
||||||
import { audioPlayHiResBlendArgs } from '@/utils/audio/hiResCrossfadeResample';
|
import { audioPlayHiResBlendArgs } from '@/lib/audio/hiResCrossfadeResample';
|
||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { consumeCrossfadeDynamicOverlap, getCrossfadeTransition, peekArmedCrossfadeDynamicOverlap } from '@/features/playback/store/crossfadeTrimCache';
|
import { consumeCrossfadeDynamicOverlap, getCrossfadeTransition, peekArmedCrossfadeDynamicOverlap } from '@/features/playback/store/crossfadeTrimCache';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
} from '@/features/playback/utils/playback/playbackServer';
|
} from '@/features/playback/utils/playback/playbackServer';
|
||||||
import { resolvePlaybackUrl } from '@/features/playback/utils/playback/resolvePlaybackUrl';
|
import { resolvePlaybackUrl } from '@/features/playback/utils/playback/resolvePlaybackUrl';
|
||||||
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
||||||
import { audioPlayHiResBlendArgs } from '@/utils/audio/hiResCrossfadeResample';
|
import { audioPlayHiResBlendArgs } from '@/lib/audio/hiResCrossfadeResample';
|
||||||
import { songToTrack } from '@/lib/media/songToTrack';
|
import { songToTrack } from '@/lib/media/songToTrack';
|
||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/utils/audio/loudnessPreAnalysisSlider';
|
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||||
import { loudnessGainPlaceholderUntilCacheDb } from '@/features/playback/utils/audio/loudnessPlaceholder';
|
import { loudnessGainPlaceholderUntilCacheDb } from '@/features/playback/utils/audio/loudnessPlaceholder';
|
||||||
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
import { resolveReplayGainDb } from '@/features/playback/utils/audio/resolveReplayGainDb';
|
||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useAuthStore } from '@/store/authStore';
|
import { useAuthStore } from '@/store/authStore';
|
||||||
import { autodjMaxOverlapCapSec } from '@/utils/playback/autodjOverlapCap';
|
import { autodjMaxOverlapCapSec } from '@/lib/audio/autodjOverlapCap';
|
||||||
import {
|
import {
|
||||||
analyzeBoundary,
|
analyzeBoundary,
|
||||||
planCrossfadeTransition,
|
planCrossfadeTransition,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
renderStars,
|
renderStars,
|
||||||
} from '@/utils/componentHelpers/queuePanelHelpers';
|
} from '@/utils/componentHelpers/queuePanelHelpers';
|
||||||
import { loudnessGainPlaceholderUntilCacheDb } from '@/features/playback/utils/audio/loudnessPlaceholder';
|
import { loudnessGainPlaceholderUntilCacheDb } from '@/features/playback/utils/audio/loudnessPlaceholder';
|
||||||
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/utils/audio/loudnessPreAnalysisSlider';
|
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||||
import { formatQueueBpmTech, formatQueueMoodLabels } from '@/lib/library/trackEnrichment';
|
import { formatQueueBpmTech, formatQueueMoodLabels } from '@/lib/library/trackEnrichment';
|
||||||
import { useQueueTrackEnrichment } from '@/features/queue/hooks/useQueueTrackEnrichment';
|
import { useQueueTrackEnrichment } from '@/features/queue/hooks/useQueueTrackEnrichment';
|
||||||
import { QueueLufsTargetMenu } from '@/features/queue/components/QueueLufsTargetMenu';
|
import { QueueLufsTargetMenu } from '@/features/queue/components/QueueLufsTargetMenu';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Equalizer } from '@/features/equalizer';
|
|||||||
import SettingsSubSection from '@/features/settings/components/SettingsSubSection';
|
import SettingsSubSection from '@/features/settings/components/SettingsSubSection';
|
||||||
import { SettingsGroup } from '@/features/settings/components/SettingsGroup';
|
import { SettingsGroup } from '@/features/settings/components/SettingsGroup';
|
||||||
import { SettingsToggle } from '@/features/settings/components/SettingsToggle';
|
import { SettingsToggle } from '@/features/settings/components/SettingsToggle';
|
||||||
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/utils/audio/loudnessPreAnalysisSlider';
|
import { effectiveLoudnessPreAnalysisAttenuationDb } from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||||
import { useAudioDevicesProbe } from '@/features/playback/hooks/useAudioDevicesProbe';
|
import { useAudioDevicesProbe } from '@/features/playback/hooks/useAudioDevicesProbe';
|
||||||
import { IS_MACOS } from '@/lib/util/platform';
|
import { IS_MACOS } from '@/lib/util/platform';
|
||||||
import { AudioOutputDeviceSection } from '@/features/settings/components/audio/AudioOutputDeviceSection';
|
import { AudioOutputDeviceSection } from '@/features/settings/components/audio/AudioOutputDeviceSection';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
HI_RES_CROSSFADE_RESAMPLE_OPTIONS,
|
HI_RES_CROSSFADE_RESAMPLE_OPTIONS,
|
||||||
type HiResCrossfadeResampleHz,
|
type HiResCrossfadeResampleHz,
|
||||||
sanitizeHiResCrossfadeResampleHz,
|
sanitizeHiResCrossfadeResampleHz,
|
||||||
} from '@/utils/audio/hiResCrossfadeResample';
|
} from '@/lib/audio/hiResCrossfadeResample';
|
||||||
import type { TFunction } from 'i18next';
|
import type { TFunction } from 'i18next';
|
||||||
import { SettingsSubCard, SettingsField } from '@/features/settings/components/SettingsSubCard';
|
import { SettingsSubCard, SettingsField } from '@/features/settings/components/SettingsSubCard';
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useOrbitStore } from '@/features/orbit';
|
|||||||
import {
|
import {
|
||||||
AUTODJ_OVERLAP_CAP_MAX_SEC,
|
AUTODJ_OVERLAP_CAP_MAX_SEC,
|
||||||
AUTODJ_OVERLAP_CAP_MIN_SEC,
|
AUTODJ_OVERLAP_CAP_MIN_SEC,
|
||||||
} from '@/utils/playback/autodjOverlapCap';
|
} from '@/lib/audio/autodjOverlapCap';
|
||||||
import {
|
import {
|
||||||
getTransitionMode,
|
getTransitionMode,
|
||||||
setTransitionMode,
|
setTransitionMode,
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import {
|
|||||||
autodjMaxOverlapCapSec,
|
autodjMaxOverlapCapSec,
|
||||||
DEFAULT_AUTODJ_OVERLAP_CAP_SEC,
|
DEFAULT_AUTODJ_OVERLAP_CAP_SEC,
|
||||||
sanitizeAutodjOverlapCapSec,
|
sanitizeAutodjOverlapCapSec,
|
||||||
} from './autodjOverlapCap';
|
} from '@/lib/audio/autodjOverlapCap';
|
||||||
|
|
||||||
describe('autodjOverlapCap', () => {
|
describe('autodjOverlapCap', () => {
|
||||||
it('sanitizes cap seconds to 2–30', () => {
|
it('sanitizes cap seconds to 2–30', () => {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { AuthState } from '../../store/authStoreTypes';
|
import type { AuthState } from '@/store/authStoreTypes';
|
||||||
import { DYNAMIC_OVERLAP_HARD_CAP_SEC } from '@/lib/waveform/waveformSilence';
|
import { DYNAMIC_OVERLAP_HARD_CAP_SEC } from '@/lib/waveform/waveformSilence';
|
||||||
|
|
||||||
export type AutodjOverlapCapMode = 'auto' | 'limit';
|
export type AutodjOverlapCapMode = 'auto' | 'limit';
|
||||||
+1
-1
@@ -3,7 +3,7 @@ import {
|
|||||||
DEFAULT_HI_RES_CROSSFADE_RESAMPLE_HZ,
|
DEFAULT_HI_RES_CROSSFADE_RESAMPLE_HZ,
|
||||||
audioPlayHiResBlendArgs,
|
audioPlayHiResBlendArgs,
|
||||||
sanitizeHiResCrossfadeResampleHz,
|
sanitizeHiResCrossfadeResampleHz,
|
||||||
} from './hiResCrossfadeResample';
|
} from '@/lib/audio/hiResCrossfadeResample';
|
||||||
|
|
||||||
describe('hiResCrossfadeResample', () => {
|
describe('hiResCrossfadeResample', () => {
|
||||||
it('defaults unknown values to 44.1 kHz', () => {
|
it('defaults unknown values to 44.1 kHz', () => {
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import { clampStoredLoudnessPreAnalysisAttenuationRefDb } from '../utils/audio/loudnessPreAnalysisSlider';
|
import { clampStoredLoudnessPreAnalysisAttenuationRefDb } from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||||
import {
|
import {
|
||||||
sanitizeAutodjOverlapCapMode,
|
sanitizeAutodjOverlapCapMode,
|
||||||
sanitizeAutodjOverlapCapSec,
|
sanitizeAutodjOverlapCapSec,
|
||||||
} from '../utils/playback/autodjOverlapCap';
|
} from '@/lib/audio/autodjOverlapCap';
|
||||||
import { DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB } from './authStoreDefaults';
|
import { DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB } from './authStoreDefaults';
|
||||||
import { updateReplayGainForCurrentTrack } from './playbackEngineBridge';
|
import { updateReplayGainForCurrentTrack } from './playbackEngineBridge';
|
||||||
import type { AuthState } from './authStoreTypes';
|
import type { AuthState } from './authStoreTypes';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { clampStoredLoudnessPreAnalysisAttenuationRefDb } from '../utils/audio/loudnessPreAnalysisSlider';
|
import { clampStoredLoudnessPreAnalysisAttenuationRefDb } from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||||
import {
|
import {
|
||||||
DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB,
|
DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB,
|
||||||
DEFAULT_LIBRARY_GRID_MAX_COLUMNS,
|
DEFAULT_LIBRARY_GRID_MAX_COLUMNS,
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { IS_LINUX } from '@/lib/util/platform';
|
import { IS_LINUX } from '@/lib/util/platform';
|
||||||
import { sanitizeHiResCrossfadeResampleHz } from '../utils/audio/hiResCrossfadeResample';
|
import { sanitizeHiResCrossfadeResampleHz } from '@/lib/audio/hiResCrossfadeResample';
|
||||||
import {
|
import {
|
||||||
sanitizeAutodjOverlapCapMode,
|
sanitizeAutodjOverlapCapMode,
|
||||||
sanitizeAutodjOverlapCapSec,
|
sanitizeAutodjOverlapCapSec,
|
||||||
} from '../utils/playback/autodjOverlapCap';
|
} from '@/lib/audio/autodjOverlapCap';
|
||||||
import {
|
import {
|
||||||
LOUDNESS_PRE_ANALYSIS_REF_TARGET_LUFS,
|
LOUDNESS_PRE_ANALYSIS_REF_TARGET_LUFS,
|
||||||
clampStoredLoudnessPreAnalysisAttenuationRefDb,
|
clampStoredLoudnessPreAnalysisAttenuationRefDb,
|
||||||
} from '../utils/audio/loudnessPreAnalysisSlider';
|
} from '@/lib/audio/loudnessPreAnalysisSlider';
|
||||||
import { DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB } from './authStoreDefaults';
|
import { DEFAULT_LOUDNESS_PRE_ANALYSIS_ATTENUATION_DB } from './authStoreDefaults';
|
||||||
import {
|
import {
|
||||||
clampMixFilterMinStars,
|
clampMixFilterMinStars,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { HiResCrossfadeResampleHz } from '../utils/audio/hiResCrossfadeResample';
|
import type { HiResCrossfadeResampleHz } from '@/lib/audio/hiResCrossfadeResample';
|
||||||
import type { EntityRatingSupportLevel } from '@/lib/api/subsonicTypes';
|
import type { EntityRatingSupportLevel } from '@/lib/api/subsonicTypes';
|
||||||
import type {
|
import type {
|
||||||
AudiomusePluginProbeResult,
|
AudiomusePluginProbeResult,
|
||||||
|
|||||||
Reference in New Issue
Block a user