diff options
Diffstat (limited to 'src/avp')
| -rw-r--r-- | src/avp/__init__.py | 2 | ||||
| -rw-r--r-- | src/avp/component.py | 12 | ||||
| -rw-r--r-- | src/avp/components/color.py | 10 | ||||
| -rw-r--r-- | src/avp/components/color.ui | 36 | ||||
| -rw-r--r-- | src/avp/components/image.py | 51 | ||||
| -rw-r--r-- | src/avp/components/image.ui | 10 | ||||
| -rw-r--r-- | src/avp/components/life.py | 103 | ||||
| -rw-r--r-- | src/avp/components/life.ui | 2 | ||||
| -rw-r--r-- | src/avp/components/original.py | 96 | ||||
| -rw-r--r-- | src/avp/components/original.ui | 58 | ||||
| -rw-r--r-- | src/avp/components/text.py | 13 | ||||
| -rw-r--r-- | src/avp/components/text.ui | 1213 | ||||
| -rw-r--r-- | src/avp/components/video.ui | 325 | ||||
| -rw-r--r-- | src/avp/components/waveform.py | 92 | ||||
| -rw-r--r-- | src/avp/components/waveform.ui | 340 | ||||
| -rw-r--r-- | src/avp/core.py | 2 | ||||
| -rw-r--r-- | src/avp/gui/mainwindow.py | 80 | ||||
| -rw-r--r-- | src/avp/gui/presetmanager.py | 4 | ||||
| -rw-r--r-- | src/avp/gui/preview_thread.py | 13 | ||||
| -rw-r--r-- | src/avp/gui/undostack.py | 16 | ||||
| -rw-r--r-- | src/avp/toolkit/common.py | 18 | ||||
| -rw-r--r-- | src/avp/toolkit/frame.py | 26 | ||||
| -rw-r--r-- | src/avp/toolkit/visualizer.py | 87 |
23 files changed, 1383 insertions, 1226 deletions
diff --git a/src/avp/__init__.py b/src/avp/__init__.py index ea32f26..a88bf10 100644 --- a/src/avp/__init__.py +++ b/src/avp/__init__.py @@ -3,7 +3,7 @@ import os import logging -__version__ = "2.2.0" +__version__ = "2.2.1" class Logger(logging.getLoggerClass()): diff --git a/src/avp/component.py b/src/avp/component.py index 6c5e381..5906ab1 100644 --- a/src/avp/component.py +++ b/src/avp/component.py @@ -18,6 +18,7 @@ from .toolkit import ( setWidgetValue, connectWidget, rgbFromString, + randomColor, blockSignals, ) @@ -635,9 +636,17 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass): 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": @@ -798,6 +807,7 @@ class Component(QtCore.QObject, metaclass=ComponentMetaclass): 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, diff --git a/src/avp/components/color.py b/src/avp/components/color.py index 1f32c23..cb0960a 100644 --- a/src/avp/components/color.py +++ b/src/avp/components/color.py @@ -2,7 +2,7 @@ from PyQt6 import QtGui 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") @@ -152,13 +152,13 @@ class Component(Component): 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) diff --git a/src/avp/components/color.ui b/src/avp/components/color.ui index c1713fb..c36bdd8 100644 --- a/src/avp/components/color.ui +++ b/src/avp/components/color.ui @@ -74,7 +74,7 @@ </size> </property> <property name="text"> - <string>0,0,0</string> + <string/> </property> <property name="maxLength"> <number>12</number> @@ -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> @@ -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> @@ -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> @@ -370,7 +370,7 @@ <number>-1</number> </property> <property name="sizeAdjustPolicy"> - <enum>QComboBox::AdjustToContentsOnFirstShow</enum> + <enum>QComboBox::SizeAdjustPolicy::AdjustToContentsOnFirstShow</enum> </property> </widget> </item> @@ -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> @@ -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"> @@ -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> @@ -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> @@ -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"> @@ -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> @@ -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> @@ -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> @@ -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> diff --git a/src/avp/components/image.py b/src/avp/components/image.py index bada15f..e012cec 100644 --- a/src/avp/components/image.py +++ b/src/avp/components/image.py @@ -4,13 +4,13 @@ import os 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) @@ -35,6 +35,7 @@ class Component(Component): "mirror": self.page.checkBox_mirror, "respondToAudio": self.page.checkBox_respondToAudio, "sensitivity": self.page.spinBox_sensitivity, + "shadow": self.page.checkBox_shadow, }, presetNames={ "imagePath": "image", @@ -75,31 +76,16 @@ class Component(Component): # 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( @@ -139,9 +125,16 @@ class Component(Component): 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, ( @@ -161,6 +154,8 @@ class Component(Component): ) if self.rotate != 0: frame = frame.rotate(self.rotate) + if self.shadow: + frame = addShadow(frame, shadBlur, shadX, shadY) return frame diff --git a/src/avp/components/image.ui b/src/avp/components/image.ui index 72593a3..b53c4b0 100644 --- a/src/avp/components/image.ui +++ b/src/avp/components/image.ui @@ -307,6 +307,16 @@ </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"> <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> diff --git a/src/avp/components/life.py b/src/avp/components/life.py index 9e5e202..a062617 100644 --- a/src/avp/components/life.py +++ b/src/avp/components/life.py @@ -8,8 +8,8 @@ import logging from ..component import Component -from ..toolkit.frame import BlankFrame, scale -from .original import Component as Visualizer +from ..toolkit.frame import BlankFrame, scale, addShadow +from ..toolkit.visualizer import createSpectrumArray log = logging.getLogger("AVP.Component.Life") @@ -17,7 +17,7 @@ log = logging.getLogger("AVP.Component.Life") class Component(Component): name = "Conway's Game of Life" - version = "2.0.0" + version = "2.0.1" def widget(self, *args): super().widget(*args) @@ -27,26 +27,26 @@ class Component(Component): # https://conwaylife.com/wiki/Queen_bee_shuttle self.startingGrid = set( [ - (3, 7), - (3, 8), - (4, 7), - (4, 8), - (8, 7), - (9, 6), - (9, 8), - (10, 5), + (3, 11), + (3, 12), + (4, 11), + (4, 12), + (8, 11), + (9, 10), + (9, 12), (10, 9), - (11, 6), - (11, 7), - (11, 8), - (12, 4), - (12, 5), + (10, 13), + (11, 10), + (11, 11), + (11, 12), + (12, 8), (12, 9), - (12, 10), - (23, 6), - (23, 7), - (24, 6), - (24, 7), + (12, 13), + (12, 14), + (23, 10), + (23, 11), + (24, 10), + (24, 11), ] ) @@ -163,41 +163,27 @@ class Component(Component): def previewRender(self): image = self.drawGrid(self.startingGrid, self.color) image = self.addKaleidoscopeEffect(image) - image = self.addShadow(image) + if self.shadow: + image = addShadow(image, 5.00, -2, 2) image = self.addGridLines(image) return image def preFrameRender(self, *args, **kwargs): super().preFrameRender(*args, **kwargs) self.tickGrids = {0: self.startingGrid} - - smoothConstantDown = 0.08 + 0 - smoothConstantUp = 0.8 - 0 - self.lastSpectrum = None - self.spectrumArray = {} if self.sensitivity == 0: return - 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, + 20, + self.progressBarUpdate, + self.progressBarSetText, + ) def properties(self): if self.customImg and (not self.image or not os.path.exists(self.image)): @@ -256,21 +242,11 @@ class Component(Component): if not self.customImg: image = Image.alpha_composite(previousGridImage, image) image = self.addKaleidoscopeEffect(image) - image = self.addShadow(image) + if self.shadow: + image = addShadow(image, 5.00, -2, 2) image = self.addGridLines(image) return image - def addShadow(self, frame): - if not self.shadow: - return frame - - shadImg = ImageEnhance.Contrast(frame).enhance(0.0) - shadImg = shadImg.filter(ImageFilter.GaussianBlur(5.00)) - shadImg = ImageChops.offset(shadImg, -2, 2) - shadImg.paste(frame, box=(0, 0), mask=frame) - frame = shadImg - return frame - def addGridLines(self, frame): if not self.showGrid: return frame @@ -299,11 +275,6 @@ class Component(Component): flippedImage = frame.transpose(Image.Transpose.FLIP_LEFT_RIGHT) frame.paste(flippedImage, (0, 0), mask=flippedImage) - flippedImage = frame.transpose(Image.Transpose.ROTATE_90) - frame.paste(flippedImage, (0, 0), mask=flippedImage) - - flippedImage = frame.transpose(Image.Transpose.ROTATE_270) - frame.paste(flippedImage, (0, 0), mask=flippedImage) return frame def drawGrid(self, grid, color, spectrumData=None, didntChange=None): @@ -506,10 +477,10 @@ class Component(Component): for x, y in grid: drawPtX = x * self.pxWidth - if drawPtX > self.width: + if drawPtX > self.width or drawPtX + self.pxWidth < 0: continue drawPtY = y * self.pxHeight - if drawPtY > self.height: + if drawPtY > self.height or drawPtY + self.pxHeight < 0: continue audioMorphWidth = ( diff --git a/src/avp/components/life.ui b/src/avp/components/life.ui index a0c8999..0070fa4 100644 --- a/src/avp/components/life.ui +++ b/src/avp/components/life.ui @@ -68,7 +68,7 @@ </size> </property> <property name="text"> - <string>255,255,255</string> + <string></string> </property> </widget> </item> diff --git a/src/avp/components/original.py b/src/avp/components/original.py index 64eba4d..0da78dc 100644 --- a/src/avp/components/original.py +++ b/src/avp/components/original.py @@ -4,11 +4,12 @@ from copy import copy from ..component import Component from ..toolkit.frame import BlankFrame +from ..toolkit.visualizer import createSpectrumArray class Component(Component): name = "Classic Visualizer" - version = "1.0.0" + version = "1.1.0" def names(*args): return ["Original Audio Visualization"] @@ -18,6 +19,7 @@ class Component(Component): def widget(self, *args): self.scale = 20 + self.bars = 63 self.y = 0 super().widget(*args) @@ -27,15 +29,14 @@ class Component(Component): self.page.comboBox_visLayout.addItem("Top") self.page.comboBox_visLayout.setCurrentIndex(0) - self.page.lineEdit_visColor.setText("255,255,255") - self.trackWidgets( { "visColor": self.page.lineEdit_visColor, "layout": self.page.comboBox_visLayout, "scale": self.page.spinBox_scale, "y": self.page.spinBox_y, - "smooth": self.page.spinBox_smooth, + "smooth": self.page.spinBox_sensitivity, + "bars": self.page.spinBox_bars, }, colorWidgets={ "visColor": self.page.pushButton_visColor, @@ -59,29 +60,16 @@ class Component(Component): super().preFrameRender(**kwargs) smoothConstantDown = 0.08 if not self.smooth else self.smooth / 15 smoothConstantUp = 0.8 if not self.smooth else self.smooth / 15 - self.lastSpectrum = None - self.spectrumArray = {} - - for i in range(0, len(self.completeAudioArray), self.sampleSize): - if self.canceled: - break - self.lastSpectrum = self.transformData( - i, - self.completeAudioArray, - self.sampleSize, - smoothConstantDown, - smoothConstantUp, - self.lastSpectrum, - self.scale, - ) - 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, + smoothConstantDown, + smoothConstantUp, + self.scale, + self.progressBarUpdate, + self.progressBarSetText, + ) def frameRender(self, frameNo): arrayNo = frameNo * self.sampleSize @@ -93,60 +81,10 @@ class Component(Component): self.layout, ) - @staticmethod - def transformData( - i, - completeAudioArray, - sampleSize, - smoothConstantDown, - smoothConstantUp, - lastSpectrum, - scale, - ): - if len(completeAudioArray) < (i + sampleSize): - sampleSize = len(completeAudioArray) - i - - window = numpy.hanning(sampleSize) - data = completeAudioArray[i : i + sampleSize][::1] * window - paddedSampleSize = 2048 - paddedData = numpy.pad(data, (0, paddedSampleSize - sampleSize), "constant") - spectrum = numpy.fft.fft(paddedData) - sample_rate = 44100 - frequencies = numpy.fft.fftfreq(len(spectrum), 1.0 / sample_rate) - - y = abs(spectrum[0 : int(paddedSampleSize / 2) - 1]) - - # filter the noise away - # y[y<80] = 0 - - with numpy.errstate(divide="ignore"): - y = scale * numpy.log10(y) - - y[numpy.isinf(y)] = 0 - - if lastSpectrum is not None: - lastSpectrum[y < lastSpectrum] = y[ - y < lastSpectrum - ] * smoothConstantDown + lastSpectrum[y < lastSpectrum] * ( - 1 - smoothConstantDown - ) - - lastSpectrum[y >= lastSpectrum] = y[ - y >= lastSpectrum - ] * smoothConstantUp + lastSpectrum[y >= lastSpectrum] * ( - 1 - smoothConstantUp - ) - else: - lastSpectrum = y - - x = frequencies[0 : int(paddedSampleSize / 2) - 1] - - return lastSpectrum - def drawBars(self, width, height, spectrum, color, layout): bigYCoord = height - height / 8 smallYCoord = height / 1200 - bigXCoord = width / 64 + bigXCoord = width / (self.bars + 1) middleXCoord = bigXCoord / 2 smallXCoord = bigXCoord / 4 @@ -155,7 +93,7 @@ class Component(Component): r, g, b = color color2 = (r, g, b, 125) - for i in range(0, 63): + for i in range(self.bars): x0 = middleXCoord + i * bigXCoord y0 = bigYCoord + smallXCoord y1 = bigYCoord + smallXCoord - spectrum[i * 4] * smallYCoord - middleXCoord diff --git a/src/avp/components/original.ui b/src/avp/components/original.ui index c7b7e22..8dbdaa2 100644 --- a/src/avp/components/original.ui +++ b/src/avp/components/original.ui @@ -44,10 +44,10 @@ <item> <spacer name="horizontalSpacer_5"> <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> @@ -84,15 +84,19 @@ </widget> </item> <item> - <widget class="QLineEdit" name="lineEdit_visColor"/> + <widget class="QLineEdit" name="lineEdit_visColor"> + <property name="text"> + <string></string> + </property> + </widget> </item> <item> <spacer name="horizontalSpacer_4"> <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> @@ -112,7 +116,7 @@ <item> <widget class="QSpinBox" name="spinBox_y"> <property name="buttonSymbols"> - <enum>QAbstractSpinBox::UpDownArrows</enum> + <enum>QAbstractSpinBox::ButtonSymbols::UpDownArrows</enum> </property> <property name="minimum"> <number>-5000</number> @@ -131,7 +135,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -158,7 +162,7 @@ <item> <widget class="QSpinBox" name="spinBox_scale"> <property name="buttonSymbols"> - <enum>QAbstractSpinBox::PlusMinus</enum> + <enum>QAbstractSpinBox::ButtonSymbols::PlusMinus</enum> </property> <property name="minimum"> <number>1</number> @@ -169,12 +173,26 @@ </widget> </item> <item> + <widget class="QLabel" name="label_sensitivity"> + <property name="text"> + <string>Sensitivity</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_sensitivity"> + <property name="maximum"> + <number>5</number> + </property> + </widget> + </item> + <item> <spacer name="horizontalSpacer_3"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + <enum>QSizePolicy::Policy::Expanding</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -189,29 +207,35 @@ <item> <layout class="QHBoxLayout" name="horizontalLayout"> <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> + <enum>QLayout::SizeConstraint::SetDefaultConstraint</enum> </property> <property name="leftMargin"> <number>4</number> </property> <item> - <widget class="QLabel" name="label_smooth"> + <widget class="QLabel" name="label_bars"> <property name="text"> - <string>Sensitivity</string> + <string>Bars</string> </property> </widget> </item> <item> - <widget class="QSpinBox" name="spinBox_smooth"> + <widget class="QSpinBox" name="spinBox_bars"> + <property name="minimum"> + <number>63</number> + </property> <property name="maximum"> - <number>5</number> + <number>64</number> + </property> + <property name="value"> + <number>63</number> </property> </widget> </item> <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -226,7 +250,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> diff --git a/src/avp/components/text.py b/src/avp/components/text.py index 40c981a..bee117e 100644 --- a/src/avp/components/text.py +++ b/src/avp/components/text.py @@ -5,7 +5,7 @@ import os import logging from ..component import Component -from ..toolkit.frame import FramePainter, PaintColor +from ..toolkit.frame import FramePainter, addShadow log = logging.getLogger("AVP.Components.Text") @@ -26,7 +26,6 @@ class Component(Component): self.page.comboBox_textAlign.addItem("Right") self.page.comboBox_textAlign.setCurrentIndex(int(self.alignment)) self.page.spinBox_fontSize.setValue(int(self.fontSize)) - self.page.lineEdit_title.setText(self.title) self.page.pushButton_center.clicked.connect(self.centerXY) self.page.fontComboBox_titleFont.currentFontChanged.connect( @@ -35,7 +34,7 @@ class Component(Component): # The QFontComboBox must be connected directly to the Qt Signal # which triggers the preview to update. # This unfortunately makes changing the font into a non-undoable action. - # Must be something broken in the conversion to a ComponentAction + # Fix requires updating ComponentAction to handle fonts self.trackWidgets( { @@ -173,7 +172,7 @@ class Component(Component): path.addText(x, y, font, self.title) path = outliner.createStroke(path) image.setPen(QtCore.Qt.PenStyle.NoPen) - image.setBrush(PaintColor(*self.strokeColor)) + image.setBrush(QtGui.QColor(*self.strokeColor)) image.drawPath(path) image.setFont(font) @@ -183,11 +182,7 @@ class Component(Component): # turn QImage into Pillow frame frame = image.finalize() if self.shadow: - shadImg = ImageEnhance.Contrast(frame).enhance(0.0) - shadImg = shadImg.filter(ImageFilter.GaussianBlur(self.shadBlur)) - shadImg = ImageChops.offset(shadImg, self.shadX, self.shadY) - shadImg.paste(frame, box=(0, 0), mask=frame) - frame = shadImg + frame = addShadow(frame, self.shadBlur / 10, self.shadX, self.shadY) return frame diff --git a/src/avp/components/text.ui b/src/avp/components/text.ui index b62e0ed..ce961fe 100644 --- a/src/avp/components/text.ui +++ b/src/avp/components/text.ui @@ -15,646 +15,645 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="spacing"> - <number>6</number> - </property> - <property name="sizeConstraint"> - <enum>QLayout::SetDefaultConstraint</enum> - </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label_title"> + <property name="text"> + <string>Title</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_title"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Text</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Font</string> + </property> + </widget> + </item> + <item> + <widget class="QFontComboBox" name="fontComboBox_titleFont"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_7"> <property name="leftMargin"> - <number>4</number> + <number>0</number> </property> <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="label_title"> - <property name="text"> - <string>Title</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_title"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Testing New GUI</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Font</string> - </property> - </widget> - </item> - <item> - <widget class="QFontComboBox" name="fontComboBox_titleFont"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - </widget> - </item> - </layout> + <widget class="QLabel" name="label_textLayout"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Text Layout</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBox_textAlign"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Policy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_center"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Center Text</string> + </property> + </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <property name="leftMargin"> + <spacer name="horizontalSpacer_6"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Policy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_xTitleAlign"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>X</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_xTextAlign"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>16777215</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="minimum"> <number>0</number> </property> - <item> - <widget class="QLabel" name="label_textLayout"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Text Layout</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_textAlign"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>100</width> - <height>16777215</height> - </size> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>5</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="pushButton_center"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Center Text</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_6"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>5</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_xTitleAlign"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>X</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="spinBox_xTextAlign"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>50</width> - <height>16777215</height> - </size> - </property> - <property name="baseSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="minimum"> - <number>0</number> - </property> - <property name="maximum"> - <number>999999999</number> - </property> - <property name="value"> - <number>0</number> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_yTitleAlign"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Y</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="spinBox_yTextAlign"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>50</width> - <height>16777215</height> - </size> - </property> - <property name="maximum"> - <number>999999999</number> - </property> - </widget> - </item> - </layout> + <property name="maximum"> + <number>999999999</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <widget class="QLabel" name="label_textColor"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>Text Color</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_textColor"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>32</width> - <height>32</height> - </size> - </property> - <property name="text"> - <string/> - </property> - <property name="MaximumSize" stdset="0"> - <size> - <width>32</width> - <height>32</height> - </size> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_8"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>5</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_fontSize"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Font Size</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="spinBox_fontSize"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="suffix"> - <string/> - </property> - <property name="prefix"> - <string/> - </property> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>500</number> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_7"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>5</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_3"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Font Style</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_fontStyle"> - <item> - <property name="text"> - <string>Normal</string> - </property> - </item> - <item> - <property name="text"> - <string>Semi-Bold</string> - </property> - </item> - <item> - <property name="text"> - <string>Bold</string> - </property> - </item> - <item> - <property name="text"> - <string>Italic</string> - </property> - </item> - <item> - <property name="text"> - <string>Bold Italic</string> - </property> - </item> - <item> - <property name="text"> - <string>Faux Italic</string> - </property> - </item> - <item> - <property name="text"> - <string>Small Caps</string> - </property> - </item> - </widget> - </item> - </layout> + <widget class="QLabel" name="label_yTitleAlign"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Y</string> + </property> + </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_12"> - <item> - <widget class="QLineEdit" name="lineEdit_textColor"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>0</width> - <height>16777215</height> - </size> - </property> - <property name="focusPolicy"> - <enum>Qt::NoFocus</enum> - </property> - <property name="text"> - <string>255,255,255</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Stroke</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="spinBox_stroke"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="suffix"> - <string>px</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_5"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Stroke Color</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_strokeColor"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>0</width> - <height>16777215</height> - </size> - </property> - <property name="focusPolicy"> - <enum>Qt::NoFocus</enum> - </property> - <property name="text"> - <string>0,0,0</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_strokeColor"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>32</width> - <height>32</height> - </size> - </property> - <property name="text"> - <string/> - </property> - <property name="MaximumSize" stdset="0"> - <size> - <width>32</width> - <height>32</height> - </size> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> + <widget class="QSpinBox" name="spinBox_yTextAlign"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>16777215</height> + </size> + </property> + <property name="maximum"> + <number>999999999</number> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_8"> + <item> + <widget class="QLabel" name="label_textColor"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Text Color</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_textColor"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="MaximumSize" stdset="0"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_8"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Policy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_fontSize"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Font Size</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_fontSize"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string/> + </property> + <property name="prefix"> + <string/> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>500</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_7"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Policy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Font Style</string> + </property> + </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> + <widget class="QComboBox" name="comboBox_fontStyle"> <item> - <widget class="QCheckBox" name="checkBox_shadow"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Shadow</string> - </property> - </widget> + <property name="text"> + <string>Normal</string> + </property> </item> <item> - <widget class="QLabel" name="label_shadX"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Shadow Offset</string> - </property> - </widget> + <property name="text"> + <string>Semi-Bold</string> + </property> </item> <item> - <widget class="QSpinBox" name="spinBox_shadX"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimum"> - <number>-1000</number> - </property> - <property name="maximum"> - <number>1000</number> - </property> - <property name="value"> - <number>-4</number> - </property> - </widget> + <property name="text"> + <string>Bold</string> + </property> </item> <item> - <widget class="QSpinBox" name="spinBox_shadY"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimum"> - <number>-1000</number> - </property> - <property name="maximum"> - <number>1000</number> - </property> - <property name="value"> - <number>8</number> - </property> - </widget> + <property name="text"> + <string>Italic</string> + </property> </item> <item> - <widget class="QLabel" name="label_shadBlur"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Shadow Blur</string> - </property> - </widget> + <property name="text"> + <string>Bold Italic</string> + </property> </item> <item> - <widget class="QDoubleSpinBox" name="spinBox_shadBlur"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximum"> - <double>99.000000000000000</double> - </property> - <property name="singleStep"> - <double>0.100000000000000</double> - </property> - <property name="value"> - <double>5.000000000000000</double> - </property> - </widget> + <property name="text"> + <string>Faux Italic</string> + </property> </item> <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Minimum</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> + <property name="text"> + <string>Small Caps</string> + </property> </item> - </layout> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_12"> + <item> + <widget class="QLineEdit" name="lineEdit_textColor"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>0</width> + <height>16777215</height> + </size> + </property> + <property name="focusPolicy"> + <enum>Qt::FocusPolicy::NoFocus</enum> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Stroke</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_stroke"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string>px</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_5"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Stroke Color</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_strokeColor"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>0</width> + <height>16777215</height> + </size> + </property> + <property name="focusPolicy"> + <enum>Qt::FocusPolicy::NoFocus</enum> + </property> + <property name="text"> + <string>0,0,0</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_strokeColor"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="MaximumSize" stdset="0"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Policy::MinimumExpanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QCheckBox" name="checkBox_shadow"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Shadow</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Policy::Preferred</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_shadX"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Shadow Offset</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_shadX"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>-1000</number> + </property> + <property name="maximum"> + <number>1000</number> + </property> + <property name="value"> + <number>2</number> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_shadY"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>-1000</number> + </property> + <property name="maximum"> + <number>1000</number> + </property> + <property name="value"> + <number>-2</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_shadBlur"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Shadow Blur</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_shadBlur"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::ButtonSymbols::PlusMinus</enum> + </property> + <property name="correctionMode"> + <enum>QAbstractSpinBox::CorrectionMode::CorrectToPreviousValue</enum> + </property> + <property name="maximum"> + <number>1000</number> + </property> + <property name="stepType"> + <enum>QAbstractSpinBox::StepType::DefaultStepType</enum> + </property> + <property name="value"> + <number>35</number> + </property> + <property name="displayIntegerBase"> + <number>10</number> + </property> + </widget> </item> </layout> </item> <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> diff --git a/src/avp/components/video.ui b/src/avp/components/video.ui index 08d15d3..72ecb0c 100644 --- a/src/avp/components/video.ui +++ b/src/avp/components/video.ui @@ -27,168 +27,161 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="leftMargin"> - <number>4</number> - </property> + <layout class="QHBoxLayout" name="horizontalLayout_8"> + <item> + <widget class="QLabel" name="label_textColor"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>31</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Video</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit_video"> + <property name="minimumSize"> + <size> + <width>1</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="pushButton_video"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>1</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="MaximumSize" stdset="0"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_9"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Policy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_xTitleAlign"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>X</string> + </property> + </widget> + </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <widget class="QLabel" name="label_textColor"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>31</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Video</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="lineEdit_video"> - <property name="minimumSize"> - <size> - <width>1</width> - <height>0</height> - </size> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="pushButton_video"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>1</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>32</width> - <height>32</height> - </size> - </property> - <property name="text"> - <string>...</string> - </property> - <property name="MaximumSize" stdset="0"> - <size> - <width>32</width> - <height>32</height> - </size> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_9"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>5</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_xTitleAlign"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>X</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="spinBox_x"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - <property name="minimum"> - <number>-10000</number> - </property> - <property name="maximum"> - <number>10000</number> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="label_yTitleAlign"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Y</string> - </property> - </widget> - </item> - <item> - <widget class="QSpinBox" name="spinBox_y"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - <property name="baseSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="minimum"> - <number>-10000</number> - </property> - <property name="maximum"> - <number>10000</number> - </property> - <property name="value"> - <number>0</number> - </property> - </widget> - </item> - </layout> + <widget class="QSpinBox" name="spinBox_x"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="minimum"> + <number>-10000</number> + </property> + <property name="maximum"> + <number>10000</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_yTitleAlign"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Y</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_y"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="minimum"> + <number>-10000</number> + </property> + <property name="maximum"> + <number>10000</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> </item> </layout> </item> @@ -204,7 +197,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -227,14 +220,14 @@ <string>Scale</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_scale"> <property name="buttonSymbols"> - <enum>QAbstractSpinBox::UpDownArrows</enum> + <enum>QAbstractSpinBox::ButtonSymbols::UpDownArrows</enum> </property> <property name="suffix"> <string>%</string> @@ -296,7 +289,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -311,7 +304,7 @@ <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> diff --git a/src/avp/components/waveform.py b/src/avp/components/waveform.py index 7dc0b99..e10dec2 100644 --- a/src/avp/components/waveform.py +++ b/src/avp/components/waveform.py @@ -1,12 +1,12 @@ -from PIL import Image -from PyQt6 import QtGui, QtCore, QtWidgets +from PIL import Image, ImageChops from PyQt6.QtGui import QColor import os -import math import subprocess import logging +from copy import copy from ..component import Component +from ..toolkit.visualizer import transformData, createSpectrumArray from ..toolkit.frame import BlankFrame, scale from ..toolkit import checkOutput from ..toolkit.ffmpeg import ( @@ -23,14 +23,20 @@ log = logging.getLogger("AVP.Components.Waveform") class Component(Component): name = "Waveform" - version = "1.0.0" + version = "2.0.0" + + @property + def updateInterval(self): + """How many frames from FFmpeg are ignored between each final frame""" + return 100 - self.speed + + def properties(self): + return [] if self.speed == 100 else ["pcm"] def widget(self, *args): super().widget(*args) self._image = BlankFrame(self.width, self.height) - self.page.lineEdit_color.setText("255,255,255") - if hasattr(self.parent, "lineEdit_audioFile"): self.parent.lineEdit_audioFile.textChanged.connect(self.update) @@ -46,6 +52,7 @@ class Component(Component): "opacity": self.page.spinBox_opacity, "compress": self.page.checkBox_compress, "mono": self.page.checkBox_mono, + "speed": self.page.spinBox_speed, }, colorWidgets={ "color": self.page.pushButton_color, @@ -65,6 +72,10 @@ class Component(Component): return frame def preFrameRender(self, **kwargs): + self._fadingImage = None + self._prevImage = None + self._currImage = None + self._lastUpdatedFrame = 0 super().preFrameRender(**kwargs) self.updateChunksize() w, h = scale(self.scale, self.width, self.height, str) @@ -79,11 +90,64 @@ class Component(Component): component=self, debug=True, ) + if self.speed == 100: + return + self.spectrumArray = createSpectrumArray( + self, + self.completeAudioArray, + self.sampleSize, + 0.08, + 0.8, + 20, + self.progressBarUpdate, + self.progressBarSetText, + ) def frameRender(self, frameNo): if FfmpegVideo.threadError is not None: raise FfmpegVideo.threadError - return self.finalizeFrame(self.video.frame(frameNo)) + newFrame = self.finalizeFrame(self.video.frame(frameNo)) + if self.speed == 100: + return newFrame + frameDiff = 0 if frameNo == 0 else frameNo % self.updateInterval + peaks = [ + self.spectrumArray[frameNo * self.sampleSize][i * 4] for i in range(64) + ] + peakValue = 70 - (max(*peaks) - min(*peaks)) + isValidPeak = ( + peakValue > 27 + and frameNo - self._lastUpdatedFrame > self.updateInterval / 2 + ) + if frameDiff == 0 or isValidPeak: + self._lastUpdatedFrame = frameNo + self._fadingImage = self._prevImage + self._prevImage = self._image + self._currImage = newFrame + usualAlpha = 0.0 + (1 / self.updateInterval) * frameDiff + alpha = max( + 0.1 + + ( + 1 + / max( + 10, + peakValue, + ) + ), + usualAlpha, + ) + baseImage = self._prevImage + if self._fadingImage is not None: + # fade away the old previous frame from ages ago + baseImage = ImageChops.blend( + self._prevImage, self._fadingImage, max(0.0, 0.9 - usualAlpha) + ) + blendedImage = ImageChops.blend( + baseImage, + ImageChops.lighter(self._prevImage, newFrame), + alpha, + ) + baseImage.paste(blendedImage, (0, 0), mask=blendedImage) + return Image.alpha_composite(self._currImage, baseImage) def postFrameRender(self): closePipe(self.video.pipe) @@ -162,17 +226,17 @@ class Component(Component): def makeFfmpegFilter(self, preview=False, startPt=0): w, h = scale(self.scale, self.width, self.height, str) if self.amplitude == 0: - amplitude = "lin" - elif self.amplitude == 1: amplitude = "log" - elif self.amplitude == 2: + elif self.amplitude == 1: amplitude = "sqrt" - elif self.amplitude == 3: + elif self.amplitude == 2: amplitude = "cbrt" + elif self.amplitude == 3: + amplitude = "lin" hexcolor = QColor(*self.color).name() opacity = "{0:.1f}".format(self.opacity / 100) genericPreview = self.settings.value("pref_genericPreview") - if self.mode < 3: + if self.mode > 1: filter_ = ( "showwaves=" f'r={str(self.settings.value("outputFrameRate"))}:' @@ -180,10 +244,10 @@ class Component(Component): f'mode={self.page.comboBox_mode.currentText().lower() if self.mode != 3 else "p2p"}:' f"colors={hexcolor}@{opacity}:scale={amplitude}" ) - elif self.mode > 2: + elif self.mode < 2: filter_ = ( f'showfreqs=s={str(self.settings.value("outputWidth"))}x{str(self.settings.value("outputHeight"))}:' - f'mode={"line" if self.mode == 4 else "bar"}:' + f'mode={"line" if self.mode == 0 else "bar"}:' f"colors={hexcolor}@{opacity}" f":ascale={amplitude}:fscale={'log' if self.mono else 'lin'}" ) diff --git a/src/avp/components/waveform.ui b/src/avp/components/waveform.ui index 5473f33..434ba62 100644 --- a/src/avp/components/waveform.ui +++ b/src/avp/components/waveform.ui @@ -27,156 +27,144 @@ </property> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <layout class="QVBoxLayout" name="verticalLayout"> - <property name="leftMargin"> - <number>4</number> - </property> + <layout class="QHBoxLayout" name="horizontalLayout_8"> <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <widget class="QLabel" name="label_textColor"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>31</width> - <height>0</height> - </size> - </property> - <property name="text"> - <string>Mode</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="comboBox_mode"> - <item> - <property name="text"> - <string>Cline</string> - </property> - </item> - <item> - <property name="text"> - <string>Line</string> - </property> - </item> - <item> - <property name="text"> - <string>Point</string> - </property> - </item> - <item> - <property name="text"> - <string>Frequency Bar</string> - </property> - </item> - <item> - <property name="text"> - <string>Frequency Line</string> - </property> - </item> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_9"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>5</width> - <height>20</height> - </size> - </property> - </spacer> - </item> + <widget class="QLabel" name="label_textColor"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>31</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Mode</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBox_mode"> <item> - <widget class="QLabel" name="label_xTitleAlign"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>X</string> - </property> - </widget> + <property name="text"> + <string>Frequency Line</string> + </property> </item> <item> - <widget class="QSpinBox" name="spinBox_x"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - <property name="minimum"> - <number>-10000</number> - </property> - <property name="maximum"> - <number>10000</number> - </property> - </widget> + <property name="text"> + <string>Frequency Bar</string> + </property> </item> <item> - <widget class="QLabel" name="label_yTitleAlign"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Y</string> - </property> - </widget> + <property name="text"> + <string>Cline</string> + </property> </item> <item> - <widget class="QSpinBox" name="spinBox_y"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize"> - <size> - <width>80</width> - <height>16777215</height> - </size> - </property> - <property name="baseSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="minimum"> - <number>-10000</number> - </property> - <property name="maximum"> - <number>10000</number> - </property> - <property name="value"> - <number>0</number> - </property> - </widget> + <property name="text"> + <string>Line</string> + </property> </item> - </layout> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_9"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Policy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_xTitleAlign"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>X</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_x"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="minimum"> + <number>-10000</number> + </property> + <property name="maximum"> + <number>10000</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_yTitleAlign"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Y</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_y"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="minimum"> + <number>-10000</number> + </property> + <property name="maximum"> + <number>10000</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> </item> </layout> </item> @@ -192,7 +180,7 @@ <item> <widget class="QLineEdit" name="lineEdit_color"> <property name="inputMethodHints"> - <set>Qt::ImhNone</set> + <set>Qt::InputMethodHint::ImhNone</set> </property> </widget> </item> @@ -224,7 +212,7 @@ <item> <spacer name="horizontalSpacer"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -240,14 +228,14 @@ <string>Opacity</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_opacity"> <property name="buttonSymbols"> - <enum>QAbstractSpinBox::UpDownArrows</enum> + <enum>QAbstractSpinBox::ButtonSymbols::UpDownArrows</enum> </property> <property name="suffix"> <string>%</string> @@ -269,14 +257,14 @@ <string>Scale</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_scale"> <property name="buttonSymbols"> - <enum>QAbstractSpinBox::UpDownArrows</enum> + <enum>QAbstractSpinBox::ButtonSymbols::UpDownArrows</enum> </property> <property name="suffix"> <string>%</string> @@ -301,6 +289,9 @@ <property name="text"> <string>Compress</string> </property> + <property name="checked"> + <bool>true</bool> + </property> </widget> </item> <item> @@ -320,7 +311,7 @@ <item> <spacer name="horizontalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Orientation::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> @@ -341,22 +332,22 @@ <widget class="QComboBox" name="comboBox_amplitude"> <item> <property name="text"> - <string>Linear</string> + <string>Logarithmic</string> </property> </item> <item> <property name="text"> - <string>Logarithmic</string> + <string>Square root</string> </property> </item> <item> <property name="text"> - <string>Square root</string> + <string>Cubic root</string> </property> </item> <item> <property name="text"> - <string>Cubic root</string> + <string>Linear</string> </property> </item> </widget> @@ -364,9 +355,52 @@ </layout> </item> <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label_speed"> + <property name="text"> + <string>Animation Speed</string> + </property> + </widget> + </item> + <item> + <widget class="QSpinBox" name="spinBox_speed"> + <property name="suffix"> + <string>%</string> + </property> + <property name="minimum"> + <number>10</number> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="singleStep"> + <number>10</number> + </property> + <property name="value"> + <number>50</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> <spacer name="verticalSpacer"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Orientation::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> diff --git a/src/avp/core.py b/src/avp/core.py index 196cd7d..099b0b4 100644 --- a/src/avp/core.py +++ b/src/avp/core.py @@ -12,7 +12,7 @@ import logging from . import toolkit - +appName = "Audio Visualizer Python" log = logging.getLogger("AVP.Core") STDOUT_LOGLVL = logging.WARNING diff --git a/src/avp/gui/mainwindow.py b/src/avp/gui/mainwindow.py index e7a5fe3..5a051fd 100644 --- a/src/avp/gui/mainwindow.py +++ b/src/avp/gui/mainwindow.py @@ -7,7 +7,7 @@ projects and exporting the video at a later time. from PyQt6 import QtCore, QtWidgets, uic import PyQt6.QtWidgets as QtWidgets -from PyQt6.QtGui import QUndoStack, QShortcut +from PyQt6.QtGui import QShortcut from PIL import Image from queue import Queue import sys @@ -16,12 +16,16 @@ import signal import filecmp import time import logging +from textwrap import wrap -from ..core import Core +from ..__init__ import __version__ +from ..core import Core, appName +from .undostack import UndoStack from . import preview_thread from .preview_win import PreviewWindow from .presetmanager import PresetManager from .actions import * +from ..toolkit.ffmpeg import createFfmpegCommand from ..toolkit import ( disableWhenEncoding, disableWhenOpeningProject, @@ -30,25 +34,9 @@ from ..toolkit import ( ) -appName = "Audio Visualizer" log = logging.getLogger("AVP.Gui.MainWindow") -class MyQUndoStack(QUndoStack): - # FIXME move this class - @property - def encoding(self): - return self.parent().encoding - - @disableWhenEncoding - def undo(self, *args, **kwargs): - super().undo(*args, **kwargs) - - @disableWhenEncoding - def redo(self, *args, **kwargs): - super().redo(*args, **kwargs) - - class MainWindow(QtWidgets.QMainWindow): """ The MainWindow wraps many Core methods in order to update the GUI @@ -91,7 +79,7 @@ class MainWindow(QtWidgets.QMainWindow): self.settings = Core.settings # Create stack of undoable user actions - self.undoStack = MyQUndoStack(self) + self.undoStack = UndoStack(self) undoLimit = self.settings.value("pref_undoLimit") self.undoStack.setUndoLimit(undoLimit) @@ -102,6 +90,7 @@ class MainWindow(QtWidgets.QMainWindow): layout = QtWidgets.QVBoxLayout() layout.addWidget(undoView) self.undoDialog.setLayout(layout) + self.undoDialog.setMinimumWidth(int(self.width() / 2)) # Create Preset Manager self.presetManager = PresetManager(self) @@ -325,7 +314,11 @@ class MainWindow(QtWidgets.QMainWindow): self.drawPreview(True) log.info("Pillow version %s", Image.__version__) - log.info("PyQt version %s (Qt version %s)", QtCore.PYQT_VERSION_STR, QtCore.QT_VERSION_STR) + log.info( + "PyQt version %s (Qt version %s)", + QtCore.PYQT_VERSION_STR, + QtCore.QT_VERSION_STR, + ) # verify Ffmpeg version if not self.core.FFMPEG_BIN: @@ -408,6 +401,7 @@ class MainWindow(QtWidgets.QMainWindow): activated=lambda: self.moveComponent("bottom"), ) + QShortcut("F1", self, self.showHelpWindow) QShortcut("Ctrl+Shift+F", self, self.showFfmpegCommand) QShortcut("Ctrl+Shift+U", self, self.showUndoStack) @@ -422,6 +416,12 @@ class MainWindow(QtWidgets.QMainWindow): if not self.core.selectedComponents: self.core.insertComponent(0, 0, self) self.core.insertComponent(1, 1, self) + # set colors to white and black to match classic appearance of program + self.core.selectedComponents[0].page.lineEdit_visColor.setText( + "255,255,255" + ) + self.core.selectedComponents[1].page.lineEdit_color1.setText("0,0,0") + self.undoStack.clear() def __repr__(self): return ( @@ -762,10 +762,10 @@ class MainWindow(QtWidgets.QMainWindow): def showUndoStack(self): self.undoDialog.show() - def showFfmpegCommand(self): - from textwrap import wrap - from ..toolkit.ffmpeg import createFfmpegCommand + def showHelpWindow(self): + self.showMessage(msg=f"{appName} v{__version__}") + def showFfmpegCommand(self): command = createFfmpegCommand( self.lineEdit_audioFile.text(), self.lineEdit_outputFile.text(), @@ -899,7 +899,9 @@ class MainWindow(QtWidgets.QMainWindow): @disableWhenEncoding def createNewProject(self, prompt=True): if prompt: - self.openSaveChangesDialog("starting a new project") + ch = self.openSaveChangesDialog("starting a new project") + if ch is None: + return self.clear() self.currentProject = None @@ -919,18 +921,19 @@ class MainWindow(QtWidgets.QMainWindow): def openSaveChangesDialog(self, phrase): success = True + ch = True if self.autosaveExists(identical=False): ch = self.showMessage( msg="You have unsaved changes in project '%s'. " "Save before %s?" % (os.path.basename(self.currentProject)[:-4], phrase), - showCancel=True, + showDiscard=True, ) if ch: success = self.saveProjectChanges() - - if success and os.path.exists(self.autosavePath): + if ch is not None and success and os.path.exists(self.autosavePath): os.remove(self.autosavePath) + return success and ch def openSaveProjectDialog(self): filename, _ = QtWidgets.QFileDialog.getSaveFileName( @@ -967,10 +970,12 @@ class MainWindow(QtWidgets.QMainWindow): ): return - self.clear() # ask to save any changes that are about to get deleted if prompt: - self.openSaveChangesDialog("opening another project") + ch = self.openSaveChangesDialog("opening another project") + if ch is None: + return + self.clear() self.currentProject = filepath self.settings.setValue("currentProject", filepath) @@ -992,7 +997,13 @@ class MainWindow(QtWidgets.QMainWindow): else QtWidgets.QMessageBox.Icon.Information ) msg.setDetailedText(kwargs["detail"] if "detail" in kwargs else None) - if "showCancel" in kwargs and kwargs["showCancel"]: + if "showDiscard" in kwargs and kwargs["showDiscard"]: + msg.setStandardButtons( + QtWidgets.QMessageBox.StandardButton.Save + | QtWidgets.QMessageBox.StandardButton.Discard + | QtWidgets.QMessageBox.StandardButton.Cancel + ) + elif "showCancel" in kwargs and kwargs["showCancel"]: msg.setStandardButtons( QtWidgets.QMessageBox.StandardButton.Ok | QtWidgets.QMessageBox.StandardButton.Cancel @@ -1000,9 +1011,14 @@ class MainWindow(QtWidgets.QMainWindow): else: msg.setStandardButtons(QtWidgets.QMessageBox.StandardButton.Ok) ch = msg.exec() - if ch == 1024: + if ch == 1024 or ch == 2048: + # OK or Save return True - return False + elif ch > 8000000: + # Discard + return False + # Cancel + return None @disableWhenEncoding def componentContextMenu(self, QPos): diff --git a/src/avp/gui/presetmanager.py b/src/avp/gui/presetmanager.py index 980a969..ca0029d 100644 --- a/src/avp/gui/presetmanager.py +++ b/src/avp/gui/presetmanager.py @@ -9,7 +9,7 @@ import os import logging from ..toolkit import badName -from ..core import Core +from ..core import Core, appName from .actions import * @@ -137,7 +137,7 @@ class PresetManager(QtWidgets.QDialog): currentPreset = selectedComponents[index].currentPreset newName, OK = QtWidgets.QInputDialog.getText( self.parent, - "Audio Visualizer", + appName, "New Preset Name:", QtWidgets.QLineEdit.EchoMode.Normal, currentPreset, diff --git a/src/avp/gui/preview_thread.py b/src/avp/gui/preview_thread.py index 1d78516..a59652a 100644 --- a/src/avp/gui/preview_thread.py +++ b/src/avp/gui/preview_thread.py @@ -65,17 +65,18 @@ class Worker(QtCore.QObject): component.unlockSize() frame = Image.alpha_composite(frame, newFrame) - except ValueError as e: + except (AttributeError, ValueError) as e: errMsg = ( "Bad frame returned by %s's preview renderer. " - "%s. New frame size was %s*%s; should be %s*%s." + "%s. New frame %s." % ( str(component), str(e).capitalize(), - newFrame.width, - newFrame.height, - width, - height, + "is None" if newFrame is None else "size was %s*%s; should be %s*%s" % ( + newFrame.width, + newFrame.height, + width, + height), ) ) log.critical(errMsg) diff --git a/src/avp/gui/undostack.py b/src/avp/gui/undostack.py new file mode 100644 index 0000000..fd1a3e9 --- /dev/null +++ b/src/avp/gui/undostack.py @@ -0,0 +1,16 @@ +from PyQt6.QtGui import QUndoStack +from ..toolkit.common import disableWhenEncoding + + +class UndoStack(QUndoStack): + @property + def encoding(self): + return self.parent().encoding + + @disableWhenEncoding + def undo(self, *args, **kwargs): + super().undo(*args, **kwargs) + + @disableWhenEncoding + def redo(self, *args, **kwargs): + super().redo(*args, **kwargs) diff --git a/src/avp/toolkit/common.py b/src/avp/toolkit/common.py index e35aba2..a6195ed 100644 --- a/src/avp/toolkit/common.py +++ b/src/avp/toolkit/common.py @@ -4,7 +4,7 @@ Common functions from PyQt6 import QtWidgets import string -import os +import random import sys import subprocess import logging @@ -135,7 +135,12 @@ def rgbFromString(string): if i > 255 or i < 0: raise ValueError return tup - except: + except Exception as e: + log.warning( + "Could not parse '%s' as a color (encountered %s).", + string, + type(e).__name__, + ) return (255, 255, 255) @@ -150,6 +155,7 @@ def formatTraceback(tb=None): def connectWidget(widget, func): + unsupportedWidgets = ["QtWidgets.QFontComboBox"] if type(widget) == QtWidgets.QLineEdit: widget.textChanged.connect(func) elif type(widget) == QtWidgets.QSpinBox or type(widget) == QtWidgets.QDoubleSpinBox: @@ -158,6 +164,10 @@ def connectWidget(widget, func): widget.stateChanged.connect(func) elif type(widget) == QtWidgets.QComboBox: widget.currentIndexChanged.connect(func) + elif type(widget) in unsupportedWidgets: + log.info( + "Could not connect %s using connectWidget()", str(widget.__class__.__name__) + ) else: log.warning("Failed to connect %s ", str(widget.__class__.__name__)) return False @@ -190,3 +200,7 @@ def getWidgetValue(widget): return widget.isChecked() elif type(widget) == QtWidgets.QComboBox: return widget.currentIndex() + + +def randomColor(): + return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) diff --git a/src/avp/toolkit/frame.py b/src/avp/toolkit/frame.py index 94537a6..829b05b 100644 --- a/src/avp/toolkit/frame.py +++ b/src/avp/toolkit/frame.py @@ -3,7 +3,7 @@ Common tools for drawing compatible frames in a Component's frameRender() """ from PyQt6 import QtGui -from PIL import Image +from PIL import Image, ImageEnhance, ImageChops, ImageFilter from PIL.ImageQt import ImageQt from PyQt6 import QtCore import sys @@ -30,7 +30,7 @@ class FramePainter(QtGui.QPainter): def setPen(self, penStyle): if type(penStyle) is tuple: - super().setPen(PaintColor(*penStyle)) + super().setPen(QtGui.QColor(*penStyle)) else: super().setPen(penStyle) @@ -45,24 +45,14 @@ class FramePainter(QtGui.QPainter): buffer.close() self.end() return frame - imBytes = self.image.bits().asstring(self.image.byteCount()) - frame = Image.frombytes( - "RGBA", (self.image.width(), self.image.height()), imBytes - ) - self.end() - return frame - -class PaintColor(QtGui.QColor): - """ - Subclass of QtGui.QColor with an added scale() method - Previously this class reversed the painter colour to solve - hardware issues related to endianness, - but Qt appears to deal with this itself nowadays - """ - def __init__(self, r, g, b, a=255): - super().__init__(r, g, b, a) +def addShadow(frame, blurRadius, blurOffsetX, blurOffsetY): + shadImg = ImageEnhance.Contrast(frame).enhance(0.0) + shadImg = shadImg.filter(ImageFilter.GaussianBlur(blurRadius)) + frame = shadImg.paste(frame, box=(-blurOffsetX, -blurOffsetY), mask=frame) + frame = shadImg + return frame def scale(scalePercent, width, height, returntype=None): diff --git a/src/avp/toolkit/visualizer.py b/src/avp/toolkit/visualizer.py new file mode 100644 index 0000000..c55a3f3 --- /dev/null +++ b/src/avp/toolkit/visualizer.py @@ -0,0 +1,87 @@ +"""Functions used to transform and manipulate audio for use by visualizers""" + +from copy import copy +import numpy + + +def createSpectrumArray( + component, + completeAudioArray, + sampleSize, + smoothConstantDown, + smoothConstantUp, + scale, + progressBarUpdate, + progressBarSetText, +): + lastSpectrum = None + spectrumArray = {} + for i in range(0, len(completeAudioArray), sampleSize): + if component.canceled: + break + lastSpectrum = transformData( + i, + completeAudioArray, + sampleSize, + smoothConstantDown, + smoothConstantUp, + lastSpectrum, + scale, + ) + spectrumArray[i] = copy(lastSpectrum) + + progress = int(100 * (i / len(completeAudioArray))) + if progress >= 100: + progress = 100 + progressText = f"Analyzing audio: {str(progress)}%" + progressBarSetText.emit(progressText) + progressBarUpdate.emit(int(progress)) + return spectrumArray + + +def transformData( + i, + completeAudioArray, + sampleSize, + smoothConstantDown, + smoothConstantUp, + lastSpectrum, + scale, +): + if len(completeAudioArray) < (i + sampleSize): + sampleSize = len(completeAudioArray) - i + + window = numpy.hanning(sampleSize) + data = completeAudioArray[i : i + sampleSize][::1] * window + paddedSampleSize = 2048 + paddedData = numpy.pad(data, (0, paddedSampleSize - sampleSize), "constant") + spectrum = numpy.fft.fft(paddedData) + sample_rate = 44100 + frequencies = numpy.fft.fftfreq(len(spectrum), 1.0 / sample_rate) + + y = abs(spectrum[0 : int(paddedSampleSize / 2) - 1]) + + # filter the noise away + # y[y<80] = 0 + + with numpy.errstate(divide="ignore"): + y = scale * numpy.log10(y) + + y[numpy.isinf(y)] = 0 + + if lastSpectrum is not None: + lastSpectrum[y < lastSpectrum] = y[ + y < lastSpectrum + ] * smoothConstantDown + lastSpectrum[y < lastSpectrum] * ( + 1 - smoothConstantDown + ) + + lastSpectrum[y >= lastSpectrum] = y[ + y >= lastSpectrum + ] * smoothConstantUp + lastSpectrum[y >= lastSpectrum] * (1 - smoothConstantUp) + else: + lastSpectrum = y + + x = frequencies[0 : int(paddedSampleSize / 2) - 1] + + return lastSpectrum |
