diff --git a/buildspec.json b/buildspec.json
index fce3602..57e3ee1 100644
--- a/buildspec.json
+++ b/buildspec.json
@@ -38,7 +38,7 @@
},
"name": "audio-wave",
"displayName": "Create audio waves out of any audio source",
- "version": "1.1.2",
+ "version": "1.2.0",
"author": "MMLTech",
"website": "https://ko-fi.com/mmltech",
"email": "contact@obscountdown.com"
diff --git a/docs/index.html b/docs/index.html
index 21f024b..7bc2b7d 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -150,7 +150,7 @@
1. Install the plugin
Download the latest release from GitHub and extract the files. You will find a file such as:
- audio-wave-visualizer.dll
+ audio-wave.dll
To install manually, place the DLL file here:
diff --git a/installer/audio-wave-installer.nsi b/installer/audio-wave-installer.nsi
index d77c40b..e048e91 100644
--- a/installer/audio-wave-installer.nsi
+++ b/installer/audio-wave-installer.nsi
@@ -1,5 +1,5 @@
; ------------------------------------------------------------------------
-; Audio Wave – Windows Installer (NSIS)
+; Audio Wave – Windows Installer (NSIS) — polished, English only
; ------------------------------------------------------------------------
; Expects these defines from makensis:
; /DPRODUCT_NAME
@@ -11,12 +11,17 @@
; (optional)
; /DPLUGIN_ID
; /DPLUGIN_DLL
+; /DINSTALLER_ICON
+; /DPLUGIN_PUBLISHER
+; /DPLUGIN_URL
; ------------------------------------------------------------------------
Unicode true
!include "MUI2.nsh"
!include "Sections.nsh"
+!include "LogicLib.nsh"
+!include "FileFunc.nsh"
; ------------------------------------------------------------------------
; Compile-time defines (with sane fallbacks)
@@ -56,6 +61,14 @@ Unicode true
!define PLUGIN_DLL "audio-wave.dll"
!endif
+!ifndef PLUGIN_PUBLISHER
+ !define PLUGIN_PUBLISHER "MML Tech"
+!endif
+
+!ifndef PLUGIN_URL
+ !define PLUGIN_URL "https://mmltools.github.io/audio-wave/"
+!endif
+
; Where CMake installed the plugin:
; ${PROJECT_ROOT}\release\\\...
!define BUILD_ROOT "${PROJECT_ROOT}\release\${CONFIGURATION}\${PLUGIN_ID}"
@@ -65,9 +78,14 @@ Unicode true
!define INSTALLER_ICON "${PROJECT_ROOT}\installer\resources\audio-wave.ico"
!endif
-; Optional custom welcome/finish bitmap (164x314 or similar)
+; Optional custom welcome/finish bitmap (typically 164x314)
!define MUI_WELCOMEFINISHPAGE_BITMAP "${PROJECT_ROOT}\installer\resources\audio-wave-welcome.bmp"
+; Optional header bitmap (commonly ~150x57)
+!ifndef INSTALLER_HEADER_BMP
+ !define INSTALLER_HEADER_BMP "${PROJECT_ROOT}\installer\resources\audio-wave-header.bmp"
+!endif
+
; ------------------------------------------------------------------------
; Basic installer metadata
; ------------------------------------------------------------------------
@@ -75,72 +93,229 @@ Unicode true
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "${OUTPUT_EXE}"
-; We need admin rights to write into Program Files\obs-studio
+; We need admin rights to write into Program Files\obs-studio (typical)
RequestExecutionLevel admin
+; Use $INSTDIR as the OBS folder so NSIS behaves predictably
+InstallDir "$PROGRAMFILES64\obs-studio"
+
Var OBSDir
+Var PrevUninst
; ------------------------------------------------------------------------
-; Sections
+; Add/Remove Programs (ARP) registry constants
; ------------------------------------------------------------------------
-Section "Core OBS Plugin" SEC_CORE
- SectionIn RO
-
- ; --- Plugin DLL ---
- ; Final path: \obs-plugins\64bit\audio-wave.dll
- SetOutPath "$OBSDir\obs-plugins\64bit"
- File "/oname=${PLUGIN_DLL}" "${BUILD_ROOT}\bin\64bit\${PLUGIN_DLL}"
-
- ; --- Locale files (if present) ---
- ; Final path: \data\obs-plugins\audio-wave\locale\...
- SetOutPath "$OBSDir\data\obs-plugins\${PLUGIN_ID}\locale"
- File /nonfatal /r "${BUILD_ROOT}\data\locale\*.*"
-
-SectionEnd
+!define UNINST_ROOT HKLM
+!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PLUGIN_ID}"
+!define ESTIMATED_SIZE_KB 2500
; ------------------------------------------------------------------------
-; MUI pages
+; Modern UI (MUI2) — visual polish
; ------------------------------------------------------------------------
!define MUI_ABORTWARNING
-; Custom icon for installer + uninstaller
!define MUI_ICON "${INSTALLER_ICON}"
!define MUI_UNICON "${INSTALLER_ICON}"
+; Header branding (small banner on most pages)
+!define MUI_HEADERIMAGE
+!define MUI_HEADERIMAGE_RIGHT
+!define MUI_HEADERIMAGE_BITMAP "${INSTALLER_HEADER_BMP}"
+!define MUI_FINISHPAGE_SHOWREADME
+!define MUI_FINISHPAGE_SHOWREADME_TEXT "Open plugin documentation"
+!define MUI_FINISHPAGE_SHOWREADME_FUNCTION OpenDocs
+
+; Pages
!insertmacro MUI_PAGE_WELCOME
; OBS folder selection page
PageEx directory
DirText \
- "Select the folder where OBS Studio is installed." \
- "The ${PRODUCT_NAME} plugin (Audio Wave (Simple) source, shapes and wave styles) will be installed into this OBS Studio folder." \
+ "Select your OBS Studio installation folder." \
+ "Audio Wave Visualizer will be installed into this OBS folder (plugin DLL + locale files)." \
"Browse..."
DirVar $OBSDir
+ ; validate selection when leaving page
+ PageCallbacks "" "" DirPageLeave
PageExEnd
!insertmacro MUI_PAGE_INSTFILES
+!insertmacro MUI_PAGE_FINISH
-; Languages
+; English only
!insertmacro MUI_LANGUAGE "English"
; ------------------------------------------------------------------------
-; Init: default OBS folder
+; Init: auto-detect OBS folder + upgrade handling
; ------------------------------------------------------------------------
Function .onInit
- ; Default to standard 64-bit OBS install path; user can change it
+ ; Default
StrCpy $OBSDir "$PROGRAMFILES64\obs-studio"
+ StrCpy $INSTDIR $OBSDir
+
+ ; Try to detect OBS from registry (best-effort; different builds may vary)
+ ; Common candidates (we probe multiple keys, ignore failures)
+ ClearErrors
+ ReadRegStr $0 HKLM "SOFTWARE\OBS Studio" "InstallPath"
+ ${IfNot} ${Errors}
+ ${If} $0 != ""
+ StrCpy $OBSDir $0
+ StrCpy $INSTDIR $0
+ Goto done_detect
+ ${EndIf}
+ ${EndIf}
+
+ ClearErrors
+ ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\OBS Studio" "InstallPath"
+ ${IfNot} ${Errors}
+ ${If} $0 != ""
+ StrCpy $OBSDir $0
+ StrCpy $INSTDIR $0
+ Goto done_detect
+ ${EndIf}
+ ${EndIf}
+
+ ClearErrors
+ ReadRegStr $0 HKCU "SOFTWARE\OBS Studio" "InstallPath"
+ ${IfNot} ${Errors}
+ ${If} $0 != ""
+ StrCpy $OBSDir $0
+ StrCpy $INSTDIR $0
+ Goto done_detect
+ ${EndIf}
+ ${EndIf}
+
+done_detect:
+
+ ; If previous version installed (via our ARP key), offer clean upgrade
+ ClearErrors
+ ReadRegStr $PrevUninst ${UNINST_ROOT} "${UNINST_KEY}" "UninstallString"
+ ${IfNot} ${Errors}
+ ${If} $PrevUninst != ""
+ MessageBox MB_ICONQUESTION|MB_YESNO \
+ "A previous version of ${PRODUCT_NAME} appears to be installed.$\r$\n$\r$\nDo you want to update it now? (Recommended)" \
+ IDYES do_upgrade IDNO done
+do_upgrade:
+ ; Best effort: run prior uninstaller silently
+ ; If it fails, we continue (installer will overwrite files).
+ ExecWait '$PrevUninst /S'
+ ${EndIf}
+ ${EndIf}
+
+done:
+FunctionEnd
+
+; Validate OBS directory selection
+Function DirPageLeave
+ ; Keep INSTDIR in sync
+ StrCpy $INSTDIR $OBSDir
+
+ ; Require obs64.exe to exist (typical OBS layout)
+ ${IfNot} ${FileExists} "$OBSDir\bin\64bit\obs64.exe"
+ MessageBox MB_ICONEXCLAMATION|MB_OK \
+ "This folder does not look like a valid OBS Studio (64-bit) installation.$\r$\n$\r$\nPlease select the folder that contains:\$\r\$\n bin\64bit\obs64.exe"
+ Abort
+ ${EndIf}
+
+ ; Optional: warn if plugin target folders missing (we will create them)
+ ; No abort here — just proactive reassurance.
+FunctionEnd
+
+; ------------------------------------------------------------------------
+; Sections
+; ------------------------------------------------------------------------
+
+Section "Core OBS Plugin" SEC_CORE
+ SectionIn RO
+
+ ; Ensure we target the selected OBS folder
+ StrCpy $INSTDIR $OBSDir
+
+ ; Warn if OBS is likely running (lightweight heuristic; no plugins required)
+ ; If you want strict detection, use nsProcess plugin — keeping this installer dependency-free.
+ MessageBox MB_ICONINFORMATION|MB_OK \
+ "If OBS Studio is currently running, please close it before continuing to ensure the plugin can be updated cleanly."
+
+ ; --- Plugin DLL ---
+ ; Final path: \obs-plugins\64bit\audio-wave.dll
+ SetOutPath "$OBSDir\obs-plugins\64bit"
+ CreateDirectory "$OBSDir\obs-plugins\64bit"
+ File "/oname=${PLUGIN_DLL}" "${BUILD_ROOT}\bin\64bit\${PLUGIN_DLL}"
+
+ ; --- Locale files (if present) ---
+ ; Final path: \data\obs-plugins\audio-wave\locale\...
+ SetOutPath "$OBSDir\data\obs-plugins\${PLUGIN_ID}\locale"
+ CreateDirectory "$OBSDir\data\obs-plugins\${PLUGIN_ID}\locale"
+ File /nonfatal /r "${BUILD_ROOT}\data\locale\*.*"
+
+ ; --- Write uninstaller inside the plugin data folder ---
+ ; Final path: \data\obs-plugins\audio-wave\uninstall.exe
+ SetOutPath "$OBSDir\data\obs-plugins\${PLUGIN_ID}"
+ WriteUninstaller "$OBSDir\data\obs-plugins\${PLUGIN_ID}\uninstall.exe"
+
+ ; --- Register in Apps & Features (ARP) ---
+ ; NOTE: We store uninstall string with quotes for safety.
+ WriteRegStr ${UNINST_ROOT} "${UNINST_KEY}" "DisplayName" "${PRODUCT_NAME}"
+ WriteRegStr ${UNINST_ROOT} "${UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
+ WriteRegStr ${UNINST_ROOT} "${UNINST_KEY}" "Publisher" "${PLUGIN_PUBLISHER}"
+ WriteRegStr ${UNINST_ROOT} "${UNINST_KEY}" "URLInfoAbout" "${PLUGIN_URL}"
+ WriteRegStr ${UNINST_ROOT} "${UNINST_KEY}" "InstallLocation" "$OBSDir"
+ WriteRegStr ${UNINST_ROOT} "${UNINST_KEY}" "DisplayIcon" "$OBSDir\data\obs-plugins\${PLUGIN_ID}\uninstall.exe"
+ WriteRegStr ${UNINST_ROOT} "${UNINST_KEY}" "UninstallString" '"$OBSDir\data\obs-plugins\${PLUGIN_ID}\uninstall.exe"'
+ WriteRegDWORD ${UNINST_ROOT} "${UNINST_KEY}" "NoModify" 1
+ WriteRegDWORD ${UNINST_ROOT} "${UNINST_KEY}" "NoRepair" 1
+ WriteRegDWORD ${UNINST_ROOT} "${UNINST_KEY}" "EstimatedSize" ${ESTIMATED_SIZE_KB}
+
+SectionEnd
+
+; ------------------------------------------------------------------------
+; Uninstaller
+; ------------------------------------------------------------------------
+
+Section "Uninstall"
+ ; $INSTDIR for uninstall is not guaranteed if launched from ARP,
+ ; so infer OBS dir from the uninstaller location.
+ ; Uninstaller is stored at: \data\obs-plugins\audio-wave\uninstall.exe
+ ; So parent-parent-parent gives .
+ StrCpy $0 "$EXEDIR" ; \data\obs-plugins\audio-wave
+ ; Go up 3 levels to reach
+ ${GetParent} $0 $1 ; \data\obs-plugins
+ ${GetParent} $1 $2 ; \data
+ ${GetParent} $2 $3 ;
+
+ ; Remove installed files
+ Delete "$3\obs-plugins\64bit\${PLUGIN_DLL}"
+
+ RMDir /r "$3\data\obs-plugins\${PLUGIN_ID}\locale"
+ Delete "$3\data\obs-plugins\${PLUGIN_ID}\uninstall.exe"
+ ; Remove the plugin folder if empty (best-effort)
+ RMDir "$3\data\obs-plugins\${PLUGIN_ID}"
+
+ ; Remove ARP entry
+ DeleteRegKey ${UNINST_ROOT} "${UNINST_KEY}"
+SectionEnd
+
+; ------------------------------------------------------------------------
+; Finish page actions
+; ------------------------------------------------------------------------
+
+Function OpenDocs
+ ExecShell "open" "${PLUGIN_URL}"
FunctionEnd
; ------------------------------------------------------------------------
; Version info in EXE properties
; ------------------------------------------------------------------------
+; IMPORTANT: VIProductVersion must be numeric a.b.c.d
+; Assumes PRODUCT_VERSION is at least a.b.c (e.g. 1.2.3). If not, pass a sanitized value from CI.
VIProductVersion "${PRODUCT_VERSION}.0"
VIAddVersionKey "ProductName" "${PRODUCT_NAME}"
-VIAddVersionKey "FileDescription" "Audio Wave Visualizer plugin installer"
-VIAddVersionKey "CompanyName" "MML Tech"
+VIAddVersionKey "FileDescription" "${PRODUCT_NAME} plugin installer"
+VIAddVersionKey "CompanyName" "${PLUGIN_PUBLISHER}"
VIAddVersionKey "FileVersion" "${PRODUCT_VERSION}"
-VIAddVersionKey "LegalCopyright" "Copyright © MML Tech"
+VIAddVersionKey "ProductVersion" "${PRODUCT_VERSION}"
+VIAddVersionKey "LegalCopyright" "Copyright © ${PLUGIN_PUBLISHER}"
diff --git a/installer/resources/audio-wave-header.bmp b/installer/resources/audio-wave-header.bmp
new file mode 100644
index 0000000..3033f27
Binary files /dev/null and b/installer/resources/audio-wave-header.bmp differ
diff --git a/src/audio-wave.cpp b/src/audio-wave.cpp
index 937ca9e..e4316c6 100644
--- a/src/audio-wave.cpp
+++ b/src/audio-wave.cpp
@@ -13,30 +13,17 @@
static const char *kSourceId = "audio_wave_source";
static const char *kSourceName = "Audio Wave";
-
-// Local setting keys
static const char *SETTING_AUDIO_SOURCE = "audio_source";
static const char *SETTING_WIDTH = "width";
static const char *SETTING_HEIGHT = "height";
+static const char *SETTING_INSET = "inset_ratio"; // NEW: global inset
static const char *SETTING_AMPLITUDE = "amplitude";
static const char *SETTING_FRAME_DENSITY = "frame_density";
static const char *SETTING_CURVE = "curve_power";
static const char *SETTING_THEME = AW_SETTING_THEME;
-
-// Property ids
static const char *PROP_THEME_GROUP = "theme_group";
-
static struct obs_source_info audio_wave_source_info;
-
-#ifndef UNUSED_PARAMETER
-#define UNUSED_PARAMETER(x) (void)(x)
-#endif
-
-// ─────────────────────────────────────────────
-// Theme registry implementation
-// ─────────────────────────────────────────────
static std::vector g_themes;
-static bool g_themes_registered = false;
void audio_wave_register_theme(const audio_wave_theme *theme)
{
@@ -249,6 +236,10 @@ static void detach_from_audio_source(audio_wave_source *s)
// Properties / UI
// ─────────────────────────────────────────────
+#ifndef UNUSED_PARAMETER
+#define UNUSED_PARAMETER(x) (void)(x)
+#endif
+
static void clear_properties(obs_properties_t *props)
{
if (!props)
@@ -256,7 +247,6 @@ static void clear_properties(obs_properties_t *props)
obs_property_t *p = obs_properties_first(props);
while (p) {
- // Advance pointer using OBS API
obs_property_t *next = p;
if (!obs_property_next(&next)) {
next = nullptr;
@@ -285,14 +275,11 @@ static bool on_theme_modified(obs_properties_t *props, obs_property_t *property,
if (!group)
return true;
- // Clear previous theme-specific props
clear_properties(group);
- // Determine selected theme
const char *theme_id = settings ? obs_data_get_string(settings, SETTING_THEME) : nullptr;
const audio_wave_theme *theme = audio_wave_find_theme(theme_id);
- // Let theme populate its properties (styles, colors, mirror, etc.)
if (theme && theme->add_properties)
theme->add_properties(group);
@@ -307,20 +294,20 @@ static obs_properties_t *audio_wave_get_properties(void *data)
obs_properties_t *props = obs_properties_create();
- // Audio source
obs_property_t *p_list = obs_properties_add_list(props, SETTING_AUDIO_SOURCE, "Audio Source",
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
obs_enum_sources(enum_audio_sources, p_list);
- // Core visual settings
obs_properties_add_int(props, SETTING_WIDTH, "Width", 64, 4096, 1);
obs_properties_add_int(props, SETTING_HEIGHT, "Height", 32, 2048, 1);
+ // NEW: global inset, applies to ALL themes via render transform
+ obs_properties_add_float_slider(props, SETTING_INSET, "Inset (relative to canvas)", 0.0, 0.4, 0.01);
+
obs_properties_add_int_slider(props, SETTING_AMPLITUDE, "Amplitude (%)", 10, 400, 10);
obs_properties_add_int_slider(props, SETTING_CURVE, "Curve Power (%)", 20, 300, 5);
obs_properties_add_int_slider(props, SETTING_FRAME_DENSITY, "Shape Density (%)", 10, 300, 5);
- // Theme selection
obs_property_t *theme_prop =
obs_properties_add_list(props, SETTING_THEME, "Theme", OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
@@ -332,16 +319,13 @@ static obs_properties_t *audio_wave_get_properties(void *data)
obs_property_list_add_string(theme_prop, t->display_name, t->id);
}
- // Theme-specific options group
obs_properties_t *theme_group_content = obs_properties_create();
obs_property_t *theme_group = obs_properties_add_group(props, PROP_THEME_GROUP, "Theme Options",
OBS_GROUP_NORMAL, theme_group_content);
UNUSED_PARAMETER(theme_group);
- // Populate group with default theme's properties
on_theme_modified(props, theme_prop, nullptr);
- // Rebuild theme properties when theme changes
obs_property_set_modified_callback(theme_prop, on_theme_modified);
return props;
@@ -355,6 +339,9 @@ static void audio_wave_get_defaults(obs_data_t *settings)
obs_data_set_default_int(settings, SETTING_WIDTH, 800);
obs_data_set_default_int(settings, SETTING_HEIGHT, 200);
+ // NEW: default global inset
+ obs_data_set_default_double(settings, SETTING_INSET, 0.08);
+
obs_data_set_default_int(settings, SETTING_AMPLITUDE, 200);
obs_data_set_default_int(settings, SETTING_CURVE, 100);
obs_data_set_default_int(settings, SETTING_FRAME_DENSITY, 100);
@@ -379,13 +366,16 @@ static void audio_wave_update(void *data, obs_data_t *settings)
detach_from_audio_source(s);
- // Audio source
s->audio_source_name = obs_data_get_string(settings, SETTING_AUDIO_SOURCE);
- // Core visual settings
s->width = (int)aw_get_int_default(settings, SETTING_WIDTH, 800);
s->height = (int)aw_get_int_default(settings, SETTING_HEIGHT, 400);
+ // NEW: global inset (0..0.4)
+ double inset = aw_get_float_default(settings, SETTING_INSET, 0.08f);
+ inset = std::clamp(inset, 0.0, 0.4);
+ s->inset_ratio = (float)inset;
+
s->frame_density = (int)aw_get_int_default(settings, SETTING_FRAME_DENSITY, 100);
s->frame_density = std::clamp(s->frame_density, 10, 300);
@@ -402,11 +392,9 @@ static void audio_wave_update(void *data, obs_data_t *settings)
if (s->height < 1)
s->height = 1;
- // Theme selection
const char *theme_id = obs_data_get_string(settings, SETTING_THEME);
const audio_wave_theme *new_theme = audio_wave_find_theme(theme_id);
- // If theme changed, clean up old theme_data
if (s->theme && s->theme != new_theme && s->theme->destroy_data) {
s->theme->destroy_data(s);
s->theme_data = nullptr;
@@ -415,7 +403,6 @@ static void audio_wave_update(void *data, obs_data_t *settings)
s->theme = new_theme;
s->theme_id = theme_id ? theme_id : "";
- // Let theme read its own properties and configure s (color, mirror, style, etc.)
if (s->theme && s->theme->update) {
s->theme->update(s, settings);
}
@@ -429,11 +416,12 @@ static void *audio_wave_create(obs_data_t *settings, obs_source_t *source)
auto *s = new audio_wave_source{};
s->self = source;
-
- // default color in case theme doesn't override
s->color = 0xFFFFFF;
s->mirror = false;
+ // ensure a sane default even before update()
+ s->inset_ratio = 0.08f;
+
audio_wave_update(s, settings);
BLOG(LOG_INFO, "Created Audio Wave source");
@@ -517,15 +505,33 @@ static void audio_wave_video_render(void *data, gs_effect_t *effect)
if (!tech)
return;
- // Build audio wave from latest samples
audio_wave_build_wave(s);
+ const float w = (float)s->width;
+ const float h = (float)s->height;
+ const float min_dim = std::min(w, h);
+
+ // NEW: apply global inset to ALL themes as a render transform
+ const float inset_px = std::max(0.0f, s->inset_ratio) * min_dim;
+ const float inner_w = std::max(1.0f, w - 2.0f * inset_px);
+ const float inner_h = std::max(1.0f, h - 2.0f * inset_px);
+ const float sx = inner_w / w;
+ const float sy = inner_h / h;
+
size_t passes = gs_technique_begin(tech);
for (size_t i = 0; i < passes; ++i) {
gs_technique_begin_pass(tech, i);
+ gs_matrix_push();
+ if (inset_px > 0.0f) {
+ gs_matrix_translate3f(inset_px, inset_px, 0.0f);
+ gs_matrix_scale3f(sx, sy, 1.0f);
+ }
+
s->theme->draw(s, color_param);
+ gs_matrix_pop();
+
gs_technique_end_pass(tech);
}
gs_technique_end(tech);
diff --git a/src/audiowave-themes.cpp b/src/audiowave-themes.cpp
index 130a895..01b6234 100644
--- a/src/audiowave-themes.cpp
+++ b/src/audiowave-themes.cpp
@@ -40,4 +40,4 @@ void audio_wave_register_builtin_themes()
audio_wave_register_cartoonframe_theme();
audio_wave_register_lightning_theme();
audio_wave_register_rounded_bars_theme();
-}
\ No newline at end of file
+}
diff --git a/src/includes/audio-wave.hpp b/src/includes/audio-wave.hpp
index ae3e7b0..d1f8c77 100644
--- a/src/includes/audio-wave.hpp
+++ b/src/includes/audio-wave.hpp
@@ -48,6 +48,7 @@ struct audio_wave_source {
// Core visual parameters
int width = 800;
int height = 200;
+ float inset_ratio = 0.08f;
float gain = 2.0f; // overall amplitude multiplier
float curve_power = 1.0f; // curve shaping power
int frame_density = 100; // 10..300 (%), interpreted by themes
diff --git a/src/includes/audiowave-themes.hpp b/src/includes/audiowave-themes.hpp
index b22aa6a..fb92ee3 100644
--- a/src/includes/audiowave-themes.hpp
+++ b/src/includes/audiowave-themes.hpp
@@ -2,4 +2,4 @@
#include "audio-wave.hpp"
-void audio_wave_register_builtin_themes();
\ No newline at end of file
+void audio_wave_register_builtin_themes();
diff --git a/src/themes/theme-cartoonframe.cpp b/src/themes/theme-cartoonframe.cpp
index 8178ec4..8f22e6c 100644
--- a/src/themes/theme-cartoonframe.cpp
+++ b/src/themes/theme-cartoonframe.cpp
@@ -18,7 +18,7 @@ static const char *CFR_PROP_COLOR_FRAME = "cfr_color_frame";
static const char *CFR_PROP_COLOR_SPARK = "cfr_color_spark";
static const char *CFR_PROP_FRAME_THICKNESS = "cfr_frame_thickness";
-static const char *CFR_PROP_FRAME_INSET = "cfr_frame_inset";
+// REMOVED: static const char *CFR_PROP_FRAME_INSET = "cfr_frame_inset";
static const char *CFR_PROP_CORNER_LEN = "cfr_corner_length_ratio";
static const char *CFR_PROP_SPARK_COUNT = "cfr_spark_count";
@@ -59,7 +59,7 @@ struct cfr_spark {
// Per-source theme data
struct cartoonframe_theme_data {
int frame_thickness = 6;
- float inset_ratio = 0.08f;
+ // REMOVED: float inset_ratio = 0.08f;
float corner_len_ratio = 0.22f;
uint32_t spark_count = 40;
@@ -82,10 +82,11 @@ static void cartoonframe_theme_add_properties(obs_properties_t *props)
obs_properties_add_color(props, CFR_PROP_COLOR_FRAME, "Frame Color");
obs_properties_add_color(props, CFR_PROP_COLOR_SPARK, "Sparkle Color");
obs_properties_add_int_slider(props, CFR_PROP_FRAME_THICKNESS, "Frame Thickness", 1, 20, 1);
- obs_properties_add_float_slider(props, CFR_PROP_FRAME_INSET, "Frame Inset (relative to canvas)", 0.0, 0.4,
- 0.01);
- obs_properties_add_float_slider(props, CFR_PROP_CORNER_LEN, "Corner Length (fraction of side)", 0.05, 0.5,
- 0.01);
+
+ // REMOVED: per-theme inset; now global in Audio Wave source settings
+ // obs_properties_add_float_slider(props, CFR_PROP_FRAME_INSET, "Frame Inset (relative to canvas)", 0.0, 0.4, 0.01);
+
+ obs_properties_add_float_slider(props, CFR_PROP_CORNER_LEN, "Corner Length (fraction of side)", 0.05, 0.5, 0.01);
obs_properties_add_int_slider(props, CFR_PROP_SPARK_COUNT, "Spark Count", 0, 200, 2);
obs_properties_add_int_slider(props, CFR_PROP_SPARK_LENGTH, "Spark Length (px)", 5, 200, 5);
obs_properties_add_float_slider(props, CFR_PROP_SPARK_ENERGY, "Spark Energy Response", 0.0, 2.0, 0.05);
@@ -140,8 +141,8 @@ static void cartoonframe_theme_update(audio_wave_source *s, obs_data_t *settings
int frame_thickness = (int)aw_get_int_default(settings, CFR_PROP_FRAME_THICKNESS, 6);
frame_thickness = std::clamp(frame_thickness, 1, 20);
- double inset = aw_get_float_default(settings, CFR_PROP_FRAME_INSET, 0.08f);
- inset = std::clamp(inset, 0.0, 0.4);
+ // REMOVED: theme inset read (now global)
+ // double inset = aw_get_float_default(settings, CFR_PROP_FRAME_INSET, 0.08f);
double corner_len_ratio = aw_get_float_default(settings, CFR_PROP_CORNER_LEN, 0.22f);
corner_len_ratio = std::clamp(corner_len_ratio, 0.05, 0.5);
@@ -168,7 +169,7 @@ static void cartoonframe_theme_update(audio_wave_source *s, obs_data_t *settings
}
d->frame_thickness = frame_thickness;
- d->inset_ratio = (float)inset;
+ // REMOVED: d->inset_ratio = (float)inset;
d->corner_len_ratio = (float)corner_len_ratio;
d->spark_count = (uint32_t)spark_count;
@@ -247,11 +248,9 @@ static void cartoonframe_theme_draw(audio_wave_source *s, gs_eparam_t *color_par
const float cx = w * 0.5f;
const float cy = h * 0.5f;
- const float min_dim = std::min(w, h);
- const float margin = d->inset_ratio * min_dim;
-
- const float hx = std::max(0.0f, w * 0.5f - margin);
- const float hy = std::max(0.0f, h * 0.5f - margin);
+ // REMOVED: theme-local inset margin; global inset is applied in audio-wave.cpp render transform
+ const float hx = std::max(0.0f, w * 0.5f);
+ const float hy = std::max(0.0f, h * 0.5f);
const float sideX = 2.0f * hx;
const float sideY = 2.0f * hy;
diff --git a/src/themes/theme-fluidblob.hpp b/src/themes/theme-fluidblob.hpp
index d371e6e..066e44b 100644
--- a/src/themes/theme-fluidblob.hpp
+++ b/src/themes/theme-fluidblob.hpp
@@ -2,4 +2,4 @@
#include "audio-wave.hpp"
-void audio_wave_register_fluidblob_theme();
\ No newline at end of file
+void audio_wave_register_fluidblob_theme();