Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ccb3a16
update gitignore
tassaron Jan 25, 2026
fe443be
F1 opens help window, create appName variable, move undostack class
tassaron Jan 25, 2026
bacc47e
fix kaleidoscope effect, increase default Y values by +4
tassaron Jan 25, 2026
b7c8f1a
update version number
tassaron Jan 25, 2026
bf889b2
add minimumWidth to undo history window
tassaron Jan 25, 2026
a12d847
Classic Visualizer: option to include 64th bar
tassaron Jan 25, 2026
34c5751
Waveform component: fix #74 - new animation speed option
tassaron Jan 26, 2026
6f0e972
move shared visualizer code into toolkit
tassaron Jan 27, 2026
f538753
Waveform component: compress audio by default
tassaron Jan 27, 2026
06b95c3
Waveform component: fix 100% animation speed
tassaron Jan 27, 2026
36663e9
new components receive random color
tassaron Jan 27, 2026
24c9828
update to Qt 6
tassaron Jan 27, 2026
3706b21
fix pushbutton stylesheet
tassaron Jan 27, 2026
b28fd2d
fix #92: replace ok/cancel with save/discard/cancel
tassaron Jan 27, 2026
73ed65a
remove obsolete PaintColor subclass
tassaron Jan 28, 2026
56810e1
mv common shadow code into addShadow func
tassaron Jan 28, 2026
13273a9
add 3rd option of ok/cancel back to showMessage
tassaron Jan 28, 2026
b3b9219
Image component: add shadow option
tassaron Jan 28, 2026
599e773
small test of rgbFromString
tassaron Jan 28, 2026
3bee82d
fix color tuple string
tassaron Jan 28, 2026
6aeda14
test another way to get comp names from CLI
tassaron Jan 28, 2026
58a7143
rename component tests, add some more
tassaron Jan 28, 2026
a52dccf
Image component: scale shadow based on resolution
tassaron Jan 28, 2026
d55d92e
catch AttributeError if previewRender returns None
tassaron Jan 28, 2026
5f65cb9
Text component: fix blur radius only able to increase
tassaron Jan 28, 2026
5d5063d
remove unnecessary QVBoxLayout
tassaron Jan 28, 2026
5136b40
paste shadow at x,y instead of using offset method
tassaron Jan 28, 2026
d6fc41f
fix tests due to shadow change
tassaron Jan 28, 2026
2b48521
don't print warning in connectWidget due to QFontComboBox
tassaron Jan 28, 2026
6f38518
hopefully fix tests
tassaron Jan 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ __pycache__
build/
dist/
env/
prof/
.venv/
.env/
.vscode/
Expand All @@ -24,3 +25,5 @@ ffmpeg
*.goutput*
*.kate-swp
*.code-workspace
.coverage
htmlcov/
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build-backend = "uv_build"
name = "audio-visualizer-python"
description = "Create audio visualization videos from a GUI or commandline"
readme = "README.md"
version = "2.2.0"
version = "2.2.1"
requires-python = ">= 3.12"
license = "MIT"
classifiers=[
Expand Down
2 changes: 1 addition & 1 deletion src/avp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging


__version__ = "2.2.0"
__version__ = "2.2.1"


class Logger(logging.getLoggerClass()):
Expand Down
12 changes: 11 additions & 1 deletion src/avp/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
setWidgetValue,
connectWidget,
rgbFromString,
randomColor,
blockSignals,
)

Expand Down Expand Up @@ -635,9 +636,17 @@ def pickColor_():

self._colorFuncs = {attr: makeColorFunc(attr) for attr in kwargs[kwarg]}
for attr, func in self._colorFuncs.items():
colorText = self._trackedWidgets[attr].text()
if colorText == "":
rndColor = randomColor()
self._trackedWidgets[attr].setText(str(rndColor)[1:-1])
self._colorWidgets[attr].clicked.connect(func)
self._colorWidgets[attr].setStyleSheet(
"QPushButton {" "background-color : #FFFFFF; outline: none; }"
"QPushButton {"
"background-color : %s; outline: none; }"
% QColor(
*rgbFromString(colorText) if colorText else rndColor
).name()
)

if kwarg == "relativeWidgets":
Expand Down Expand Up @@ -798,6 +807,7 @@ def updateRelativeWidget(self, attr):
if oldUserValue == newUserValue and oldRelativeVal != newRelativeVal:
# Float changed without pixel value changing, which
# means the pixel value needs to be updated
# TODO QDoubleSpinBox doesn't work with relativeWidgets because of this
log.debug(
"Updating %s #%s's relative widget: %s",
self.__class__.name,
Expand Down
10 changes: 5 additions & 5 deletions src/avp/components/color.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging

from ..component import Component
from ..toolkit.frame import BlankFrame, FloodFrame, FramePainter, PaintColor
from ..toolkit.frame import BlankFrame, FloodFrame, FramePainter


log = logging.getLogger("AVP.Components.Color")
Expand Down Expand Up @@ -152,13 +152,13 @@ def drawFrame(self, width, height):
elif self.spread == 2:
spread = QtGui.QGradient.Spread.RepeatSpread
brush.setSpread(spread)
brush.setColorAt(0.0, PaintColor(*self.color1))
brush.setColorAt(0.0, QtGui.QColor(*self.color1))
if self.trans:
brush.setColorAt(1.0, PaintColor(0, 0, 0, 0))
brush.setColorAt(1.0, QtGui.QColor(0, 0, 0, 0))
elif self.fillType == 1 and self.stretch:
brush.setColorAt(0.2, PaintColor(*self.color2))
brush.setColorAt(0.2, QtGui.QColor(*self.color2))
else:
brush.setColorAt(1.0, PaintColor(*self.color2))
brush.setColorAt(1.0, QtGui.QColor(*self.color2))
image.setBrush(brush)
image.drawRect(self.x, self.y, self.sizeWidth, self.sizeHeight)

Expand Down
36 changes: 18 additions & 18 deletions src/avp/components/color.ui
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
</size>
</property>
<property name="text">
<string>0,0,0</string>
<string/>
</property>
<property name="maxLength">
<number>12</number>
Expand All @@ -84,10 +84,10 @@
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Policy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down Expand Up @@ -176,7 +176,7 @@
<string>Width</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
Expand Down Expand Up @@ -246,10 +246,10 @@
<item>
<spacer name="horizontalSpacer_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Policy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down Expand Up @@ -370,7 +370,7 @@
<number>-1</number>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContentsOnFirstShow</enum>
<enum>QComboBox::SizeAdjustPolicy::AdjustToContentsOnFirstShow</enum>
</property>
</widget>
</item>
Expand Down Expand Up @@ -422,10 +422,10 @@
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
<enum>QSizePolicy::Policy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down Expand Up @@ -461,7 +461,7 @@
<x>-1</x>
<y>0</y>
<width>561</width>
<height>31</height>
<height>34</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
Expand Down Expand Up @@ -503,7 +503,7 @@
<string>End</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
Expand All @@ -523,7 +523,7 @@
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand All @@ -543,7 +543,7 @@
<x>-1</x>
<y>-1</y>
<width>561</width>
<height>31</height>
<height>34</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
Expand All @@ -559,7 +559,7 @@
<string>Start</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
Expand Down Expand Up @@ -588,7 +588,7 @@
<string>End</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
Expand Down Expand Up @@ -617,14 +617,14 @@
<string>Centre</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<set>Qt::AlignmentFlag::AlignRight|Qt::AlignmentFlag::AlignTrailing|Qt::AlignmentFlag::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_radialGradient_spread">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::PlusMinus</enum>
<enum>QAbstractSpinBox::ButtonSymbols::PlusMinus</enum>
</property>
<property name="minimum">
<number>-10000</number>
Expand All @@ -640,7 +640,7 @@
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
Expand Down
51 changes: 23 additions & 28 deletions src/avp/components/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
from copy import copy

from ..component import Component
from ..toolkit.frame import BlankFrame
from .original import Component as Visualizer
from ..toolkit.frame import BlankFrame, addShadow
from ..toolkit.visualizer import createSpectrumArray


class Component(Component):
name = "Image"
version = "2.0.0"
version = "2.1.0"

def widget(self, *args):
super().widget(*args)
Expand All @@ -35,6 +35,7 @@ def widget(self, *args):
"mirror": self.page.checkBox_mirror,
"respondToAudio": self.page.checkBox_respondToAudio,
"sensitivity": self.page.spinBox_sensitivity,
"shadow": self.page.checkBox_shadow,
},
presetNames={
"imagePath": "image",
Expand Down Expand Up @@ -75,31 +76,16 @@ def preFrameRender(self, **kwargs):
# Trigger creation of new base image
self.existingImage = None

smoothConstantDown = 0.08 + 0
smoothConstantUp = 0.8 - 0
self.lastSpectrum = None
self.spectrumArray = {}

for i in range(0, len(self.completeAudioArray), self.sampleSize):
if self.canceled:
break
self.lastSpectrum = Visualizer.transformData(
i,
self.completeAudioArray,
self.sampleSize,
smoothConstantDown,
smoothConstantUp,
self.lastSpectrum,
self.sensitivity,
)
self.spectrumArray[i] = copy(self.lastSpectrum)

progress = int(100 * (i / len(self.completeAudioArray)))
if progress >= 100:
progress = 100
pStr = "Analyzing audio: " + str(progress) + "%"
self.progressBarSetText.emit(pStr)
self.progressBarUpdate.emit(int(progress))
self.spectrumArray = createSpectrumArray(
self,
self.completeAudioArray,
self.sampleSize,
0.08,
0.8,
self.sensitivity,
self.progressBarUpdate,
self.progressBarSetText,
)

def frameRender(self, frameNo):
return self.drawFrame(
Expand Down Expand Up @@ -139,9 +125,16 @@ def drawFrame(self, width, height, dynamicScale):
self.existingImage = image

# Respond to audio
resolutionFactor = height / 1080
shadX = int(resolutionFactor * 1)
shadY = int(resolutionFactor * -1)
shadBlur = resolutionFactor * 3.50
scale = 0
if dynamicScale is not None:
scale = dynamicScale[36 * 4] / 4
shadX += int((scale / 4) * resolutionFactor)
shadY += int((scale / 2) * resolutionFactor)
shadBlur += (scale / 8) * resolutionFactor
image = ImageOps.contain(
image,
(
Expand All @@ -161,6 +154,8 @@ def drawFrame(self, width, height, dynamicScale):
)
if self.rotate != 0:
frame = frame.rotate(self.rotate)
if self.shadow:
frame = addShadow(frame, shadBlur, shadX, shadY)

return frame

Expand Down
10 changes: 10 additions & 0 deletions src/avp/components/image.ui
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,16 @@
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_shadow">
<property name="layoutDirection">
<enum>Qt::LayoutDirection::RightToLeft</enum>
</property>
<property name="text">
<string>Shadow</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
Expand Down
Loading