diff --git a/Extensions/SDL_Mixer/Definition.h b/Extensions/SDL_Mixer/Definition.h index 4a0a446a..393688dc 100644 --- a/Extensions/SDL_Mixer/Definition.h +++ b/Extensions/SDL_Mixer/Definition.h @@ -517,6 +517,7 @@ struct GlobalData { std::vector toRelease; HANDLE hSoundTouch = nullptr; + int masterVolume = 100; GlobalData() { SDL_GeneralInit(); @@ -870,6 +871,35 @@ struct GlobalData { static_cast(Mix_MaxVolume)) * static_cast(Fusion_MaxVolume)); } + // 0 ~ 100 + inline int GetNormalizedVolume(int chanVol) const { + const auto newVol = static_cast((chanVol * masterVolume) / static_cast(Fusion_MaxVolume)); + + return ::Range(newVol, Fusion_MinVolume, Fusion_MaxVolume); + } + + // 0 ~ 100 + inline void SetMasterVolume(int volume) { + masterVolume = ::Range(volume, Fusion_MinVolume, Fusion_MaxVolume); + + auto updateVolume = [&] (const std::vector& channels, + int(GlobalData::*pGetter)(int), + void(GlobalData::*pSetter)(int, int)) { + for (size_t channel = 0; channel < channels.size(); channel++) { + const auto channelVolume = (this->*pGetter)(channel); + (this->*pSetter)(channel, channelVolume); + } + }; + + updateVolume(exclusiveChannel, &GlobalData::GetExclusiveVolume, &GlobalData::SetExclusiveVolume); + updateVolume(mixingChannel, &GlobalData::GetMixingVolume, &GlobalData::SetMixingVolume); + } + + // 0 ~ 100 + inline int GetMasterVolume() const { + return ::Range(masterVolume, Fusion_MinVolume, Fusion_MaxVolume); + } + // 0 ~ 100 static inline void SetAudioVolume(Mix_Music* pMusic, int volume) { Mix_VolumeMusicStream(pMusic, VolumeConverter(volume)); @@ -1183,7 +1213,7 @@ struct GlobalData { const auto pAudioData = exclusiveChannel[channel]; if (pAudioData != nullptr) { - SetAudioVolume(pAudioData->pMusic, volume); + SetAudioVolume(pAudioData->pMusic, GetNormalizedVolume(volume)); } } @@ -1476,7 +1506,7 @@ struct GlobalData { for (const auto& pAudioData : vec) { if (pAudioData != nullptr) { - SetAudioVolume(pAudioData->pMusic, volume); + SetAudioVolume(pAudioData->pMusic, GetNormalizedVolume(volume)); } } } diff --git a/Extensions/SDL_Mixer/Ext.rc b/Extensions/SDL_Mixer/Ext.rc index 1094328c..60cabb79 100644 --- a/Extensions/SDL_Mixer/Ext.rc +++ b/Extensions/SDL_Mixer/Ext.rc @@ -145,7 +145,9 @@ BEGIN MENUITEM "Play Exclusive", IDMN_ACTION_PE MENUITEM "Play Mixing", IDMN_ACTION_PM MENUITEM SEPARATOR - MENUITEM "Set Volume", IDMN_ACTION_SV + MENUITEM "Set Master Volume", IDMN_ACTION_SMV + MENUITEM "Set Channel Volume", IDMN_ACTION_SV + MENUITEM SEPARATOR MENUITEM "Set Exclusive Position", IDMN_ACTION_SP MENUITEM "Set Exclusive ABLoop", IDMN_ACTION_SABL MENUITEM "Set Mixing Channel Score", IDMN_ACTION_SMCS @@ -173,8 +175,10 @@ BEGIN POPUP "" BEGIN MENUITEM SEPARATOR - MENUITEM "Get Channel ID By Name", IDMN_EXPRESSION_GCIDBN + MENUITEM "Get Master Volume", IDMN_EXPRESSION_GMV MENUITEM "Get Channel Volume", IDMN_EXPRESSION_GV + MENUITEM SEPARATOR + MENUITEM "Get Channel ID By Name", IDMN_EXPRESSION_GCIDBN MENUITEM "Get Channel State", IDMN_EXPRESSION_GCS MENUITEM SEPARATOR MENUITEM "Get Exclusive Channel Position", IDMN_EXPRESSION_GCP @@ -286,6 +290,7 @@ BEGIN M_ACTION_FADE "Fade (ms), -1 = No Fade" M_ACTION_SV "Set Channel %0 Volume to %1, Channel Type %2" + M_ACTION_SMV "Set Master Volume to %0" M_ACTION_VOLUME "Volume (0 ~ 100)" M_ACTION_EXCLUSIVE "Channel Type, 1 = Exclusive, 0 = Mixing" @@ -326,7 +331,8 @@ END STRINGTABLE DISCARDABLE BEGIN M_EXPRESSION_GCIDBN "GetID (" - M_EXPRESSION_GV "GetVolume (" + M_EXPRESSION_GV "GetChannelVolume (" + M_EXPRESSION_GMV "GetMasterVolume (" M_EXPRESSION_GCS "GetChannelState (" M_EXPRESSION_GCP "GetChannelPos (" M_EXPRESSION_GCD "GetChannelDur (" diff --git a/Extensions/SDL_Mixer/Main.cpp b/Extensions/SDL_Mixer/Main.cpp index cdf77929..d200af4d 100644 --- a/Extensions/SDL_Mixer/Main.cpp +++ b/Extensions/SDL_Mixer/Main.cpp @@ -50,8 +50,10 @@ short actionsInfos[]= IDMN_ACTION_SMCS, M_ACTION_SMCS, ACT_ACTION_SMCS, 0, 4, PARAM_EXPRESSION, PARAM_EXPRESSION, PARAM_EXPSTRING, PARAM_EXPRESSION, M_ACTION_CHANNEL, M_ACTION_ENABLE, M_ACTION_SCORE, M_ACTION_BASE, IDMN_ACTION_LB, M_ACTION_LB, ACT_ACTION_LB, 0, 2, PARAM_EXPSTRING, PARAM_EXPSTRING, M_ACTION_FILENAME, M_ACTION_KEY, - IDMN_ACTION_RB, M_ACTION_RB, ACT_ACTION_RB, 0, 2, PARAM_EXPSTRING, M_ACTION_FILENAME, + IDMN_ACTION_RB, M_ACTION_RB, ACT_ACTION_RB, 0, 1, PARAM_EXPSTRING, M_ACTION_FILENAME, IDMN_ACTION_UB, M_ACTION_UB, ACT_ACTION_UB, 0, 2, PARAM_EXPSTRING, PARAM_EXPSTRING, M_ACTION_FILENAME, M_ACTION_KEY, + + IDMN_ACTION_SMV, M_ACTION_SMV, ACT_ACTION_SMV, 0, 1, PARAM_EXPRESSION, M_ACTION_VOLUME, }; // Definitions of parameters for each expression @@ -66,6 +68,7 @@ short expressionsInfos[]= IDMN_EXPRESSION_GPFMN, M_EXPRESSION_GPFMN, EXP_EXPRESSION_GPFMN, EXPFLAG_STRING, 3, EXPPARAM_STRING, EXPPARAM_LONG, EXPPARAM_LONG, M_EXPRESSION_ACCESSFILENAME, M_EXPRESSION_ADDRESS, M_EXPRESSION_SIZE, IDMN_EXPRESSION_GPFHMN, M_EXPRESSION_GPFHMN, EXP_EXPRESSION_GPFHMN, EXPFLAG_STRING, 4, EXPPARAM_STRING, EXPPARAM_STRING, EXPPARAM_LONG, EXPPARAM_LONG, M_EXPRESSION_ACCESSFILENAME, M_ACTION_FILENAME, M_EXPRESSION_OFFSET, M_EXPRESSION_SIZE, IDMN_EXPRESSION_GBA, M_EXPRESSION_GBA, EXP_EXPRESSION_GBA, 0, 2, EXPPARAM_STRING, EXPPARAM_LONG, M_ACTION_FILENAME, M_EXPRESSION_OFFSET, + IDMN_EXPRESSION_GMV, M_EXPRESSION_GMV, EXP_EXPRESSION_GMV, 0, 0, }; @@ -174,6 +177,14 @@ short WINAPI DLLExport Action_SetVolume(LPRDATA rdPtr, long param1, long param2) return 0; } +short WINAPI DLLExport Action_SetMasterVolume(LPRDATA rdPtr, long param1, long param2) { + const auto masterVolume = (int)CNC_GetIntParameter(rdPtr); + + rdPtr->pData->SetMasterVolume(masterVolume); + + return 0; +} + short WINAPI DLLExport Action_StopChannel(LPRDATA rdPtr, long param1, long param2) { const auto channel = (int)CNC_GetIntParameter(rdPtr); const auto fadeMs = (int)CNC_GetIntParameter(rdPtr); @@ -294,6 +305,10 @@ long WINAPI DLLExport Expression_GetVolume(LPRDATA rdPtr,long param1) { : rdPtr->pData->GetMixingVolume(channel); } +long WINAPI DLLExport Expression_GetMasterVolume(LPRDATA rdPtr, long param1) { + return rdPtr->pData->GetMasterVolume(); +} + long WINAPI DLLExport Expression_GetChannelState(LPRDATA rdPtr, long param1) { const auto channel = (int)CNC_GetFirstExpressionParameter(rdPtr, param1, TYPE_INT); const auto bExclusive = (bool)CNC_GetNextExpressionParameter(rdPtr, param1, TYPE_INT); @@ -436,6 +451,8 @@ short (WINAPI * ActionJumps[])(LPRDATA rdPtr, long param1, long param2) = Action_ReleaseBinary, Action_UpdateBinary, + Action_SetMasterVolume, + 0 }; @@ -450,6 +467,7 @@ long (WINAPI * ExpressionJumps[])(LPRDATA rdPtr, long param) = Expression_GetPlayFromMemoryName, Expression_GetPlayFromHandledMemoryName, Expression_GetBinaryAddress, + Expression_GetMasterVolume, 0 }; \ No newline at end of file diff --git a/Extensions/SDL_Mixer/Main.h b/Extensions/SDL_Mixer/Main.h index fe1ddb2c..8c466a8c 100644 --- a/Extensions/SDL_Mixer/Main.h +++ b/Extensions/SDL_Mixer/Main.h @@ -32,8 +32,9 @@ #define ACT_ACTION_LB 10 #define ACT_ACTION_RB 11 #define ACT_ACTION_UB 12 +#define ACT_ACTION_SMV 13 -#define ACT_LAST 13 +#define ACT_LAST 14 // ------------------------------- // DEFINITION OF EXPRESSIONS CODES @@ -47,8 +48,9 @@ #define EXP_EXPRESSION_GPFMN 6 #define EXP_EXPRESSION_GPFHMN 7 #define EXP_EXPRESSION_GBA 8 +#define EXP_EXPRESSION_GMV 9 -#define EXP_LAST 9 +#define EXP_LAST 10 // --------------------- // OBJECT DATA STRUCTURE diff --git a/Extensions/SDL_Mixer/ReadMe.md b/Extensions/SDL_Mixer/ReadMe.md index 646c29f3..cc518ca9 100644 --- a/Extensions/SDL_Mixer/ReadMe.md +++ b/Extensions/SDL_Mixer/ReadMe.md @@ -38,6 +38,7 @@ cmake -G "Visual Studio 17 2022" -A Win32 -S .. -B "build32" -DCMAKE_BUILD_TYPE= cmake --build build32 --config Release -j 12 ``` + you can then build it with cmake or visual studio. To disable GPL part, remove macros like `MUSIC_MP3_MAD`, `MUSIC_MID_ADLMIDI`, `MUSIC_MID_OPNMIDI` and `MUSIC_FLAC` in properties, then remove the counterpart input of linker, or using the following code to generate a clipped project: diff --git a/Extensions/SDL_Mixer/Resource.h b/Extensions/SDL_Mixer/Resource.h index d1a3b229..ed3ec683 100644 --- a/Extensions/SDL_Mixer/Resource.h +++ b/Extensions/SDL_Mixer/Resource.h @@ -45,6 +45,7 @@ #define IDMN_ACTION_LB 25010 #define IDMN_ACTION_RB 25011 #define IDMN_ACTION_UB 25012 +#define IDMN_ACTION_SMV 25013 // Action strings #define M_ACTION_PE 5000 @@ -60,6 +61,7 @@ #define M_ACTION_LB 5010 #define M_ACTION_RB 5011 #define M_ACTION_UB 5012 +#define M_ACTION_SMV 5013 // Titles of action parameters #define M_ACTION_FILENAME 5501 @@ -122,6 +124,7 @@ #define IDMN_EXPRESSION_GPFMN 27006 #define IDMN_EXPRESSION_GPFHMN 27007 #define IDMN_EXPRESSION_GBA 27008 +#define IDMN_EXPRESSION_GMV 27009 // Expression strings #define M_EXPRESSION_GV 7000 @@ -133,6 +136,7 @@ #define M_EXPRESSION_GPFMN 7006 #define M_EXPRESSION_GPFHMN 7007 #define M_EXPRESSION_GBA 7008 +#define M_EXPRESSION_GMV 7009 // Names of expression parameters #define M_EXPRESSION_ADDRESS 7500 diff --git a/Extensions/SDL_Mixer/ToInstall/Files/Data/Runtime/Unicode/SDL_Mixer.mfx b/Extensions/SDL_Mixer/ToInstall/Files/Data/Runtime/Unicode/SDL_Mixer.mfx index 6b4bc081..55c73591 100644 Binary files a/Extensions/SDL_Mixer/ToInstall/Files/Data/Runtime/Unicode/SDL_Mixer.mfx and b/Extensions/SDL_Mixer/ToInstall/Files/Data/Runtime/Unicode/SDL_Mixer.mfx differ diff --git a/Extensions/SDL_Mixer/ToInstall/Files/Examples/SDL_Mixer/MasterVolume.mfa b/Extensions/SDL_Mixer/ToInstall/Files/Examples/SDL_Mixer/MasterVolume.mfa new file mode 100644 index 00000000..5994d2f6 Binary files /dev/null and b/Extensions/SDL_Mixer/ToInstall/Files/Examples/SDL_Mixer/MasterVolume.mfa differ diff --git a/Extensions/SDL_Mixer/ToInstall/Files/Examples/SDL_Mixer/PlayFromMemory.mfa b/Extensions/SDL_Mixer/ToInstall/Files/Examples/SDL_Mixer/PlayFromMemory.mfa index 679744c7..7aebf58e 100644 Binary files a/Extensions/SDL_Mixer/ToInstall/Files/Examples/SDL_Mixer/PlayFromMemory.mfa and b/Extensions/SDL_Mixer/ToInstall/Files/Examples/SDL_Mixer/PlayFromMemory.mfa differ diff --git a/Extensions/SDL_Mixer/ToInstall/Files/Extensions/Unicode/SDL_Mixer.mfx b/Extensions/SDL_Mixer/ToInstall/Files/Extensions/Unicode/SDL_Mixer.mfx index bcbbc69e..3ce940d5 100644 Binary files a/Extensions/SDL_Mixer/ToInstall/Files/Extensions/Unicode/SDL_Mixer.mfx and b/Extensions/SDL_Mixer/ToInstall/Files/Extensions/Unicode/SDL_Mixer.mfx differ diff --git a/Extensions/SDL_Mixer/ToInstall/Files/Help/SDL_Mixer/SDL_Mixer.md b/Extensions/SDL_Mixer/ToInstall/Files/Help/SDL_Mixer/SDL_Mixer.md index c53dba57..b859e1c1 100644 --- a/Extensions/SDL_Mixer/ToInstall/Files/Help/SDL_Mixer/SDL_Mixer.md +++ b/Extensions/SDL_Mixer/ToInstall/Files/Help/SDL_Mixer/SDL_Mixer.md @@ -27,7 +27,9 @@ This object has no properties - *you can use `Get Play From Memory Name` & `Get Play From Handled Memory Name` as filename here and keep key empty, to play from memory* - *when playing from memory, you should not release the memory it referenced, as it's not copied for sake of performance, or app may crash* -- Set Volume +- Set Master Volume +- Set Channel Volume + - Set Exclusive Position - Set Exclusive ABLoop - Set Mixing Channel Score @@ -64,10 +66,12 @@ This object has no properties ## Expression +- Get Master Volume +- Get Channel Volume + - Get Channel ID By Name - *Get channel ID by audio name it's playing* - *for mixing channel, will return channel that includes the name* -- Get Channel Volume - Get Channel State - Get Exclusive Channel Position