mirror of
https://github.com/LanZhan-Harmony/WindowsMusicPlayer-TheUntamedMusicPlayer.git
synced 2026-05-06 11:10:16 +08:00
完成C++ DLL迁移
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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" />
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
using System.Diagnostics;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user