完成C++ DLL迁移

This commit is contained in:
LanZhan
2026-04-21 00:10:10 +08:00
parent 669aa43cb0
commit f4b2de29ef
16 changed files with 106 additions and 125 deletions

View File

@@ -137,8 +137,8 @@
<AdditionalLibraryDirectories>$(ProjectDir)Libraries\$(Platform)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>del "$(OutDir)$(TargetName).lib"
del "$(OutDir)$(TargetName).exp"</Command>
<Command>if exist "$(OutDir)$(TargetName).lib" del "$(OutDir)$(TargetName).lib"
if exist "$(OutDir)$(TargetName).exp" del "$(OutDir)$(TargetName).exp"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -154,6 +154,9 @@ del "$(OutDir)$(TargetName).exp"</Command>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard_C>stdclatest</LanguageStandard_C>
<FloatingPointModel>Fast</FloatingPointModel>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -161,10 +164,12 @@ del "$(OutDir)$(TargetName).exp"</Command>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>bass.lib;bass_fx.lib;basswasapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)Libraries\$(Platform)</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>del "$(OutDir)$(TargetName).lib"
del "$(OutDir)$(TargetName).exp"</Command>
<Command>if exist "$(OutDir)$(TargetName).lib" del "$(OutDir)$(TargetName).lib"
if exist "$(OutDir)$(TargetName).exp" del "$(OutDir)$(TargetName).exp"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -187,8 +192,8 @@ del "$(OutDir)$(TargetName).exp"</Command>
<AdditionalLibraryDirectories>$(ProjectDir)Libraries\$(Platform)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>del "$(OutDir)$(TargetName).lib"
del "$(OutDir)$(TargetName).exp"</Command>
<Command>if exist "$(OutDir)$(TargetName).lib" del "$(OutDir)$(TargetName).lib"
if exist "$(OutDir)$(TargetName).exp" del "$(OutDir)$(TargetName).exp"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
@@ -211,8 +216,8 @@ del "$(OutDir)$(TargetName).exp"</Command>
<AdditionalLibraryDirectories>$(ProjectDir)Libraries\$(Platform)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>del "$(OutDir)$(TargetName).lib"
del "$(OutDir)$(TargetName).exp"</Command>
<Command>if exist "$(OutDir)$(TargetName).lib" del "$(OutDir)$(TargetName).lib"
if exist "$(OutDir)$(TargetName).exp" del "$(OutDir)$(TargetName).exp"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -228,6 +233,9 @@ del "$(OutDir)$(TargetName).exp"</Command>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard_C>stdclatest</LanguageStandard_C>
<FloatingPointModel>Fast</FloatingPointModel>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -235,10 +243,11 @@ del "$(OutDir)$(TargetName).exp"</Command>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>bass.lib;bass_fx.lib;basswasapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)Libraries\$(Platform)</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
</Link>
<PostBuildEvent>
<Command>del "$(OutDir)$(TargetName).lib"
del "$(OutDir)$(TargetName).exp"</Command>
<Command>if exist "$(OutDir)$(TargetName).lib" del "$(OutDir)$(TargetName).lib"
if exist "$(OutDir)$(TargetName).exp" del "$(OutDir)$(TargetName).exp"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
@@ -254,6 +263,9 @@ del "$(OutDir)$(TargetName).exp"</Command>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard_C>stdclatest</LanguageStandard_C>
<FloatingPointModel>Fast</FloatingPointModel>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -261,10 +273,11 @@ del "$(OutDir)$(TargetName).exp"</Command>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>bass.lib;bass_fx.lib;basswasapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(ProjectDir)Libraries\$(Platform)</AdditionalLibraryDirectories>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
</Link>
<PostBuildEvent>
<Command>del "$(OutDir)$(TargetName).lib"
del "$(OutDir)$(TargetName).exp"</Command>
<Command>if exist "$(OutDir)$(TargetName).lib" del "$(OutDir)$(TargetName).lib"
if exist "$(OutDir)$(TargetName).exp" del "$(OutDir)$(TargetName).exp"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>

View File

@@ -1,4 +1,4 @@
#include "pch.h"
#include "pch.h"
#include "bass_audio_engine_exports.h"
@@ -34,37 +34,24 @@ namespace
{
std::array<wchar_t, MAX_PATH> buffer{};
auto length = GetModuleFileNameW(nullptr, buffer.data(), static_cast<DWORD>(buffer.size()));
if (length == 0)
if (length == 0) [[unlikely]]
{
return {};
}
auto appPath = std::filesystem::path{ std::wstring_view{ buffer.data(), length } };
auto appPath = std::filesystem::path{std::wstring_view{buffer.data(), length}};
return appPath.parent_path().wstring();
}
[[nodiscard]] std::string WideToUtf8(const wchar_t* text)
{
const auto utf8Length = WideCharToMultiByte(CP_UTF8, 0, text, -1, nullptr, 0, nullptr, nullptr);
if (utf8Length <= 0)
{
return {};
}
auto utf8Text = std::string(static_cast<size_t>(utf8Length), '\0');
WideCharToMultiByte(CP_UTF8, 0, text, -1, utf8Text.data(), utf8Length, nullptr, nullptr);
return utf8Text;
}
void LoadBassPlugins()
{
if (g_engine.pluginsLoaded)
if (g_engine.pluginsLoaded) [[unlikely]]
{
return;
}
const auto appDirectory = GetAppDirectory();
if (appDirectory.empty())
if (appDirectory.empty()) [[unlikely]]
{
return;
}
@@ -83,7 +70,7 @@ namespace
for (const auto pluginName : pluginNames)
{
const auto fullPath = std::filesystem::path{ appDirectory } / pluginName;
const auto fullPath = std::filesystem::path{appDirectory} / pluginName;
BASS_PluginLoad(fullPath.c_str(), 0);
}
@@ -92,12 +79,12 @@ namespace
[[nodiscard]] bool EnsureBassInitialized()
{
if (g_engine.bassInitialized)
if (g_engine.bassInitialized) [[unlikely]]
{
return true;
}
if (!BASS_Init(-1, 44100, 0, nullptr, nullptr))
if (!BASS_Init(-1, 44100, 0, nullptr, nullptr)) [[unlikely]]
{
return false;
}
@@ -120,40 +107,40 @@ namespace
g_engine.wasapiInitialized = false;
}
if (g_engine.fxHandle != 0)
if (g_engine.fxHandle != 0) [[likely]]
{
BASS_StreamFree(g_engine.fxHandle);
g_engine.fxHandle = 0;
}
if (g_engine.mainHandle != 0)
if (g_engine.mainHandle != 0) [[likely]]
{
BASS_StreamFree(g_engine.mainHandle);
g_engine.mainHandle = 0;
}
}
void CALLBACK OnPlaybackEndedSync(HSYNC, DWORD, DWORD, void*)
void CALLBACK OnPlaybackEndedSync(HSYNC, DWORD, DWORD, void *)
{
const auto callback = g_engine.playbackEndedCallback;
if (callback != nullptr)
if (callback != nullptr) [[likely]]
{
callback();
}
}
void CALLBACK OnPlaybackFailedSync(HSYNC, DWORD, DWORD, void*)
void CALLBACK OnPlaybackFailedSync(HSYNC, DWORD, DWORD, void *)
{
const auto callback = g_engine.playbackFailedCallback;
if (callback != nullptr)
if (callback != nullptr) [[likely]]
{
callback();
}
}
DWORD CALLBACK WasapiProc(void* buffer, DWORD length, void*)
DWORD CALLBACK WasapiProc(void *buffer, DWORD length, void *)
{
if (g_engine.fxHandle == 0)
if (g_engine.fxHandle == 0) [[unlikely]]
{
return 0;
}
@@ -161,47 +148,39 @@ namespace
return BASS_ChannelGetData(g_engine.fxHandle, buffer, length);
}
[[nodiscard]] HSTREAM CreateMainStream(const wchar_t* path, BOOL isOnline)
[[nodiscard]] HSTREAM CreateMainStream(const wchar_t *path, BOOL isOnline)
{
constexpr auto streamFlags = BASS_UNICODE | BASS_SAMPLE_FLOAT | BASS_ASYNCFILE | BASS_STREAM_DECODE;
if (isOnline)
{
const auto utf8Length = WideCharToMultiByte(CP_UTF8, 0, path, -1, nullptr, 0, nullptr, nullptr);
if (utf8Length <= 0)
{
return 0;
}
auto utf8Path = std::string(static_cast<size_t>(utf8Length), '\0');
WideCharToMultiByte(CP_UTF8, 0, path, -1, utf8Path.data(), utf8Length, nullptr, nullptr);
return BASS_StreamCreateURL(utf8Path.c_str(), 0, streamFlags, nullptr, nullptr);
constexpr auto streamFlags = BASS_UNICODE | BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE;
return BASS_StreamCreateURL(reinterpret_cast<const char *>(path), 0, streamFlags, nullptr, nullptr);
}
constexpr auto streamFlags = BASS_UNICODE | BASS_SAMPLE_FLOAT | BASS_ASYNCFILE | BASS_STREAM_DECODE;
return BASS_StreamCreateFile(FALSE, path, 0, 0, streamFlags);
}
}
void WINAPI BaeSetCallbacks(BassAudioEngineCallback playbackEndedCallback, BassAudioEngineCallback playbackFailedCallback)
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
g_engine.playbackEndedCallback = playbackEndedCallback;
g_engine.playbackFailedCallback = playbackFailedCallback;
}
BOOL WINAPI BaeInitialize()
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
return EnsureBassInitialized() ? TRUE : FALSE;
}
void WINAPI BaeShutdown()
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
FreeStreamsUnsafe();
if (g_engine.bassInitialized)
if (g_engine.bassInitialized) [[likely]]
{
BASS_Free();
g_engine.bassInitialized = false;
@@ -211,22 +190,22 @@ void WINAPI BaeShutdown()
g_engine.playbackFailedCallback = nullptr;
}
BOOL WINAPI BaeLoadSong(const wchar_t* path, BOOL isOnline, BOOL isExclusiveMode, double volume, double speed, double* totalSeconds)
BOOL WINAPI BaeLoadSong(const wchar_t *path, BOOL isOnline, BOOL isExclusiveMode, double volume, double speed, double *totalSeconds)
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
FreeStreamsUnsafe();
if (!EnsureBassInitialized())
if (!EnsureBassInitialized()) [[unlikely]]
{
return FALSE;
}
g_engine.mainHandle = CreateMainStream(path, isOnline);
if (g_engine.mainHandle == 0 && BASS_ErrorGetCode() == BASS_ERROR_INIT)
if (g_engine.mainHandle == 0 && BASS_ErrorGetCode() == BASS_ERROR_INIT) [[unlikely]]
{
g_engine.bassInitialized = false;
if (!EnsureBassInitialized())
if (!EnsureBassInitialized()) [[unlikely]]
{
return FALSE;
}
@@ -234,14 +213,14 @@ BOOL WINAPI BaeLoadSong(const wchar_t* path, BOOL isOnline, BOOL isExclusiveMode
g_engine.mainHandle = CreateMainStream(path, isOnline);
}
if (g_engine.mainHandle == 0)
if (g_engine.mainHandle == 0) [[unlikely]]
{
return FALSE;
}
const auto tempoFlags = isExclusiveMode ? BASS_STREAM_DECODE : BASS_FX_FREESOURCE;
g_engine.fxHandle = BASS_FX_TempoCreate(g_engine.mainHandle, tempoFlags);
if (g_engine.fxHandle == 0)
if (g_engine.fxHandle == 0) [[unlikely]]
{
BASS_StreamFree(g_engine.mainHandle);
g_engine.mainHandle = 0;
@@ -255,7 +234,7 @@ BOOL WINAPI BaeLoadSong(const wchar_t* path, BOOL isOnline, BOOL isExclusiveMode
BASS_ChannelSetAttribute(g_engine.fxHandle, BASS_ATTRIB_TEMPO, tempoPercent);
BASS_ChannelSetAttribute(g_engine.fxHandle, BASS_ATTRIB_VOL, static_cast<float>(volume));
if (totalSeconds != nullptr)
if (totalSeconds != nullptr) [[likely]]
{
const auto lengthBytes = BASS_ChannelGetLength(g_engine.fxHandle, BASS_POS_BYTE);
*totalSeconds = BASS_ChannelBytes2Seconds(g_engine.fxHandle, lengthBytes);
@@ -266,22 +245,22 @@ BOOL WINAPI BaeLoadSong(const wchar_t* path, BOOL isOnline, BOOL isExclusiveMode
void WINAPI BaeStop()
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
FreeStreamsUnsafe();
}
BOOL WINAPI BaePlay(BOOL isExclusiveMode)
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
if (g_engine.fxHandle == 0)
if (g_engine.fxHandle == 0) [[unlikely]]
{
return FALSE;
}
if (isExclusiveMode)
{
if (BASS_WASAPI_IsStarted())
if (BASS_WASAPI_IsStarted()) [[unlikely]]
{
return TRUE;
}
@@ -292,13 +271,13 @@ BOOL WINAPI BaePlay(BOOL isExclusiveMode)
}
BASS_CHANNELINFO channelInfo{};
if (!BASS_ChannelGetInfo(g_engine.fxHandle, &channelInfo))
if (!BASS_ChannelGetInfo(g_engine.fxHandle, &channelInfo)) [[unlikely]]
{
return FALSE;
}
const auto initFlags = BASS_WASAPI_EXCLUSIVE | BASS_WASAPI_EVENT;
if (!BASS_WASAPI_Init(-1, channelInfo.freq, channelInfo.chans, initFlags, 0.1F, 0.025F, WasapiProc, nullptr))
if (!BASS_WASAPI_Init(-1, channelInfo.freq, channelInfo.chans, initFlags, 0.1F, 0.025F, WasapiProc, nullptr)) [[unlikely]]
{
return FALSE;
}
@@ -307,12 +286,12 @@ BOOL WINAPI BaePlay(BOOL isExclusiveMode)
return BASS_WASAPI_Start() ? TRUE : FALSE;
}
if (BASS_ChannelIsActive(g_engine.fxHandle) == BASS_ACTIVE_PLAYING)
if (BASS_ChannelIsActive(g_engine.fxHandle) == BASS_ACTIVE_PLAYING) [[unlikely]]
{
return TRUE;
}
if (BASS_ChannelPlay(g_engine.fxHandle, FALSE))
if (BASS_ChannelPlay(g_engine.fxHandle, FALSE)) [[likely]]
{
return TRUE;
}
@@ -327,16 +306,16 @@ BOOL WINAPI BaePlay(BOOL isExclusiveMode)
void WINAPI BaePause(BOOL isExclusiveMode)
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
if (g_engine.fxHandle == 0)
if (g_engine.fxHandle == 0) [[unlikely]]
{
return;
}
if (isExclusiveMode)
{
if (BASS_WASAPI_IsStarted())
if (BASS_WASAPI_IsStarted()) [[likely]]
{
BASS_WASAPI_Stop(FALSE);
}
@@ -349,9 +328,9 @@ void WINAPI BaePause(BOOL isExclusiveMode)
void WINAPI BaeSetSpeed(double speed)
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
if (g_engine.fxHandle == 0)
if (g_engine.fxHandle == 0) [[unlikely]]
{
return;
}
@@ -362,9 +341,9 @@ void WINAPI BaeSetSpeed(double speed)
void WINAPI BaeSetVolume(double volume)
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
if (g_engine.fxHandle == 0)
if (g_engine.fxHandle == 0) [[unlikely]]
{
return;
}
@@ -374,9 +353,9 @@ void WINAPI BaeSetVolume(double volume)
double WINAPI BaeGetPositionSeconds()
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
if (g_engine.fxHandle == 0)
if (g_engine.fxHandle == 0) [[unlikely]]
{
return -1.0;
}
@@ -387,9 +366,9 @@ double WINAPI BaeGetPositionSeconds()
BOOL WINAPI BaeSetPositionSeconds(double targetSeconds)
{
const auto lock = std::lock_guard{ g_engineMutex };
const auto lock = std::lock_guard{g_engineMutex};
if (g_engine.fxHandle == 0)
if (g_engine.fxHandle == 0) [[unlikely]]
{
return FALSE;
}
@@ -397,11 +376,11 @@ BOOL WINAPI BaeSetPositionSeconds(double targetSeconds)
const auto targetBytes = BASS_ChannelSeconds2Bytes(g_engine.fxHandle, targetSeconds);
auto result = BASS_ChannelSetPosition(g_engine.fxHandle, targetBytes, BASS_POS_BYTE);
if (!result && BASS_ErrorGetCode() == BASS_ERROR_POSITION)
if (!result && BASS_ErrorGetCode() == BASS_ERROR_POSITION) [[unlikely]]
{
for (auto retryCount = 0; retryCount < 20 && !result; ++retryCount)
{
std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
std::this_thread::sleep_for(std::chrono::milliseconds{100});
result = BASS_ChannelSetPosition(g_engine.fxHandle, targetBytes, BASS_POS_BYTE);
}
}
@@ -418,9 +397,3 @@ BOOL WINAPI BaeIsLastErrorBusy()
{
return BASS_ErrorGetCode() == BASS_ERROR_BUSY ? TRUE : FALSE;
}

View File

@@ -8,12 +8,12 @@
#define BAE_API extern "C" __declspec(dllimport)
#endif
using BassAudioEngineCallback = void(CALLBACK*)();
using BassAudioEngineCallback = void(CALLBACK *)();
BAE_API void WINAPI BaeSetCallbacks(BassAudioEngineCallback playbackEndedCallback, BassAudioEngineCallback playbackFailedCallback);
BAE_API BOOL WINAPI BaeInitialize();
BAE_API void WINAPI BaeShutdown();
BAE_API BOOL WINAPI BaeLoadSong(const wchar_t* path, BOOL isOnline, BOOL isExclusiveMode, double volume, double speed, double* totalSeconds);
BAE_API BOOL WINAPI BaeLoadSong(const wchar_t *path, BOOL isOnline, BOOL isExclusiveMode, double volume, double speed, double *totalSeconds);
BAE_API void WINAPI BaeStop();
BAE_API BOOL WINAPI BaePlay(BOOL isExclusiveMode);
BAE_API void WINAPI BaePause(BOOL isExclusiveMode);

View File

@@ -6,8 +6,7 @@
<Platform Name="x86" />
</Configurations>
<Project Path="BassAudioEngine/BassAudioEngine.vcxproj" Id="ad06a049-a46d-4b45-ab74-471d5138a519">
<Platform Solution="Debug|arm64" Project="ARM64" />
<Platform Solution="Release|arm64" Project="x64" />
<Platform Solution="*|arm64" Project="ARM64" />
</Project>
<Project Path="UntamedMusicPlayer/UntamedMusicPlayer.csproj">
<Platform Solution="*|Any CPU" Project="x64" />

View File

@@ -1,7 +1,6 @@
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using UntamedMusicPlayer.Helpers;
using UntamedMusicPlayer.Messages;
using UntamedMusicPlayer.Models;
using UntamedMusicPlayer.Services;

View File

@@ -3,7 +3,7 @@ using UntamedMusicPlayer.Models;
namespace UntamedMusicPlayer.Converters;
public partial class AlbumCoverConverter : IValueConverter
public sealed partial class AlbumCoverConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{

View File

@@ -4,7 +4,7 @@ using UntamedMusicPlayer.Models;
namespace UntamedMusicPlayer.Converters;
public partial class InverseAlbumCoverToVisibilityConverter : IValueConverter
public sealed partial class InverseAlbumCoverToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{

View File

@@ -4,7 +4,7 @@ using UntamedMusicPlayer.Models;
namespace UntamedMusicPlayer.Converters;
public partial class InversePlaylistCoverToVisibilityConverter : IValueConverter
public sealed partial class InversePlaylistCoverToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{

View File

@@ -3,7 +3,7 @@ using UntamedMusicPlayer.Models;
namespace UntamedMusicPlayer.Converters;
public partial class PlaylistCoverConverter : IValueConverter
public sealed partial class PlaylistCoverConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{

View File

@@ -6,7 +6,7 @@ using Microsoft.UI.Xaml.Media;
namespace UntamedMusicPlayer.Helpers.Animations;
public partial class CompositionFactory : DependencyObject
public sealed class CompositionFactory : DependencyObject
{
public const double DefaultOffsetDuration = 0.325;

View File

@@ -6,7 +6,7 @@ using Microsoft.UI.Xaml.Controls;
namespace UntamedMusicPlayer.Helpers.Animations;
public class CommonStatesHelper : DependencyObject
public sealed class CommonStatesHelper : DependencyObject
{
public event EventHandler<VisualStateChangedEventArgs>? StateChanging;
public event EventHandler<VisualStateChangedEventArgs>? StateChanged;
@@ -55,7 +55,7 @@ public class CommonStatesHelper : DependencyObject
}
}
public class FluentAnimationHelper
public sealed class FluentAnimationHelper
{
private readonly VisualStateGroup _group;
private FrameworkElement? _pointerTarget = null;
@@ -303,7 +303,7 @@ public class FluentAnimationHelper
#endregion
}
public class FluentAnimation
public sealed class FluentAnimation
{
#region Helper

View File

@@ -1,16 +1,14 @@
using System.Collections;
using CommunityToolkit.WinUI;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media.Animation;
using Windows.UI;
namespace UntamedMusicPlayer.Helpers.Animations;
public class Properties : DependencyObject
public sealed class Properties : DependencyObject
{
public static string GetStyleKey(DependencyObject obj) =>
(string)obj.GetValue(StyleKeyProperty);

View File

@@ -17,7 +17,7 @@ public enum ZoomTriggerMode
Delta,
}
public class ZoomHelper : DependencyObject, IAttached
public sealed class ZoomHelper : DependencyObject, IAttached
{
public const double DefaultSliderScaleFactor = 0.033d;

View File

@@ -1,4 +1,3 @@
using System.Diagnostics;
using CommunityToolkit.WinUI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

View File

@@ -155,7 +155,7 @@ public sealed partial class AudioEngine : IDisposable
_logger.PlaybackDeviceBusy();
return false;
}
_logger.ZLogInformation($"Bass初始化失败: {NativeMethods.GetLastError()}");
_logger.ZLogInformation($"Bass初始化失败, 错误码: {NativeMethods.GetLastError()}");
return false;
}
@@ -196,7 +196,7 @@ public sealed partial class AudioEngine : IDisposable
if (!success)
{
_logger.ZLogInformation(
$"创建Bass流失败: {NativeMethods.GetLastError()}, 文件: {_state.CurrentSong.Path}"
$"创建Bass流失败, 错误码: {NativeMethods.GetLastError()}, 文件: {_state.CurrentSong.Path}"
);
return false;
}
@@ -242,18 +242,23 @@ public sealed partial class AudioEngine : IDisposable
if (_state.IsExclusiveMode)
{
_logger.SongPlaybackError(_state.CurrentSong!.Title);
_logger.ZLogInformation($"独占播放失败: {NativeMethods.GetLastError()}");
_logger.ZLogInformation(
$"独占播放失败, 错误码: {NativeMethods.GetLastError()}, 文件: {_state.CurrentSong.Path}"
);
return false;
}
_logger.ZLogInformation($"共享播放失败: {NativeMethods.GetLastError()}");
_logger.ZLogInformation(
$"共享播放失败, 错误码: {NativeMethods.GetLastError()}, 文件: {_state.CurrentSong!.Path}"
);
return false;
});
/// <summary>
/// 暂停
/// </summary>
public void Pause() => ExecuteOnPlaybackThread(() => NativeMethods.Pause(_state.IsExclusiveMode));
public void Pause() =>
ExecuteOnPlaybackThread(() => NativeMethods.Pause(_state.IsExclusiveMode));
/// <summary>
/// 停止
@@ -304,7 +309,7 @@ public sealed partial class AudioEngine : IDisposable
_dispatcher.TryEnqueue(() => _state.PlayState = MediaPlaybackState.Paused);
}
}
await SetPositionInternal(position);
SetPositionInternal(position);
});
}
@@ -336,7 +341,7 @@ public sealed partial class AudioEngine : IDisposable
if (currentPosition >= 0)
{
var newPosition = Math.Max(0, currentPosition - 10);
_ = SetPositionInternal(newPosition);
SetPositionInternal(newPosition);
}
});
@@ -353,7 +358,7 @@ public sealed partial class AudioEngine : IDisposable
_state.TotalPlayingTime.TotalSeconds,
currentPosition + 30
);
_ = SetPositionInternal(newPosition);
SetPositionInternal(newPosition);
}
});
@@ -366,12 +371,12 @@ public sealed partial class AudioEngine : IDisposable
/// 设置播放位置(秒)
/// </summary>
public void SetPosition(double targetSeconds) =>
ExecuteOnPlaybackThread(() => _ = SetPositionInternal(targetSeconds));
ExecuteOnPlaybackThread(() => SetPositionInternal(targetSeconds));
/// <summary>
/// 设置播放位置(秒)- 内部方法
/// </summary>
private Task SetPositionInternal(double targetSeconds)
private void SetPositionInternal(double targetSeconds)
{
if (_hasLoadedSong)
{
@@ -380,8 +385,6 @@ public sealed partial class AudioEngine : IDisposable
_state.CurrentPlayingTime = TimeSpan.FromSeconds(targetSeconds)
);
}
return Task.CompletedTask;
}
public void Dispose()

View File

@@ -34,9 +34,6 @@
<PackageReference Include="CommunityToolkit.WinUI.Converters" Version="8.2.251219" />
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.2.251219" />
<PackageReference Include="hyjiacan.pinyin4net" Version="4.1.1" />
<PackageReference Include="ManagedBass" Version="4.0.2" />
<PackageReference Include="ManagedBass.Fx" Version="4.0.2" />
<PackageReference Include="ManagedBass.Wasapi" Version="4.0.2" />
<PackageReference Include="MemoryPack" Version="1.21.4" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.6" />
<PackageReference Include="Microsoft.Graphics.Win2D" Version="1.4.0" />