2017-05-28 07:34:34 -04:00
|
|
|
import numpy
|
|
|
|
from PIL import Image, ImageDraw
|
2017-05-28 14:19:28 -04:00
|
|
|
from PyQt4 import uic, QtGui
|
|
|
|
from PyQt4.QtGui import QColor
|
2017-05-28 07:34:34 -04:00
|
|
|
import os, random
|
2017-05-29 20:39:11 -04:00
|
|
|
from . import __base__
|
2017-06-01 10:52:40 -04:00
|
|
|
import time
|
|
|
|
from copy import copy
|
2017-05-28 07:34:34 -04:00
|
|
|
|
|
|
|
|
2017-05-29 20:39:11 -04:00
|
|
|
class Component(__base__.Component):
|
|
|
|
'''Original Audio Visualization'''
|
2017-05-28 14:19:28 -04:00
|
|
|
def widget(self, parent):
|
2017-05-28 07:34:34 -04:00
|
|
|
self.parent = parent
|
2017-05-28 14:19:28 -04:00
|
|
|
self.visColor = (255,255,255)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
|
|
|
page = uic.loadUi(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'original.ui'))
|
|
|
|
page.comboBox_visLayout.addItem("Classic")
|
|
|
|
page.comboBox_visLayout.addItem("Split")
|
|
|
|
page.comboBox_visLayout.addItem("Bottom")
|
|
|
|
#visLayoutValue = int(self.settings.value('visLayout'))
|
|
|
|
page.comboBox_visLayout.setCurrentIndex(0)
|
|
|
|
page.comboBox_visLayout.currentIndexChanged.connect(self.update)
|
2017-05-28 14:19:28 -04:00
|
|
|
page.lineEdit_visColor.setText('%s,%s,%s' % self.visColor)
|
|
|
|
page.pushButton_visColor.clicked.connect(lambda: self.pickColor())
|
|
|
|
btnStyle = "QPushButton { background-color : %s; outline: none; }" % QColor(*self.visColor).name()
|
|
|
|
page.pushButton_visColor.setStyleSheet(btnStyle)
|
|
|
|
page.lineEdit_visColor.textChanged.connect(self.update)
|
|
|
|
self.page = page
|
2017-06-02 01:30:44 -04:00
|
|
|
self.canceled = False
|
2017-05-28 07:34:34 -04:00
|
|
|
return page
|
2017-05-28 14:19:28 -04:00
|
|
|
|
2017-05-28 07:34:34 -04:00
|
|
|
def update(self):
|
|
|
|
self.layout = self.page.comboBox_visLayout.currentIndex()
|
2017-05-29 20:39:11 -04:00
|
|
|
self.visColor = self.RGBFromString(self.page.lineEdit_visColor.text())
|
2017-05-28 07:34:34 -04:00
|
|
|
self.parent.drawPreview()
|
|
|
|
|
2017-05-30 22:05:56 -04:00
|
|
|
def loadPreset(self, pr):
|
|
|
|
self.page.lineEdit_visColor.setText('%s,%s,%s' % pr['visColor'])
|
|
|
|
btnStyle = "QPushButton { background-color : %s; outline: none; }" % QColor(*pr['visColor']).name()
|
|
|
|
self.page.pushButton_visColor.setStyleSheet(btnStyle)
|
|
|
|
self.page.comboBox_visLayout.setCurrentIndex(pr['layout'])
|
2017-05-28 22:58:13 -04:00
|
|
|
|
2017-05-28 21:24:51 -04:00
|
|
|
def savePreset(self):
|
2017-05-30 22:05:56 -04:00
|
|
|
return { 'layout' : self.layout,
|
|
|
|
'visColor' : self.visColor,
|
2017-05-30 19:31:10 -04:00
|
|
|
}
|
2017-05-28 21:24:51 -04:00
|
|
|
|
2017-05-28 14:19:28 -04:00
|
|
|
def previewRender(self, previewWorker):
|
2017-05-28 07:34:34 -04:00
|
|
|
spectrum = numpy.fromfunction(lambda x: 0.008*(x-128)**2, (255,), dtype="int16")
|
|
|
|
width = int(previewWorker.core.settings.value('outputWidth'))
|
|
|
|
height = int(previewWorker.core.settings.value('outputHeight'))
|
2017-06-01 12:01:51 -04:00
|
|
|
return self.drawBars(width, height, spectrum, self.visColor, self.layout)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
|
|
|
def preFrameRender(self, **kwargs):
|
2017-05-29 20:39:11 -04:00
|
|
|
super().preFrameRender(**kwargs)
|
2017-05-28 07:34:34 -04:00
|
|
|
self.smoothConstantDown = 0.08
|
|
|
|
self.smoothConstantUp = 0.8
|
|
|
|
self.lastSpectrum = None
|
2017-05-31 03:15:09 -04:00
|
|
|
self.spectrumArray = {}
|
2017-06-04 13:00:36 -04:00
|
|
|
self.width = int(self.worker.core.settings.value('outputWidth'))
|
|
|
|
self.height = int(self.worker.core.settings.value('outputHeight'))
|
2017-05-31 03:15:09 -04:00
|
|
|
|
|
|
|
for i in range(0, len(self.completeAudioArray), self.sampleSize):
|
2017-06-02 01:30:44 -04:00
|
|
|
if self.canceled:
|
|
|
|
break
|
2017-06-01 10:52:40 -04:00
|
|
|
self.lastSpectrum = self.transformData(i, self.completeAudioArray, self.sampleSize,
|
2017-05-31 03:15:09 -04:00
|
|
|
self.smoothConstantDown, self.smoothConstantUp, self.lastSpectrum)
|
2017-06-01 10:52:40 -04:00
|
|
|
self.spectrumArray[i] = copy(self.lastSpectrum)
|
2017-05-31 03:15:09 -04:00
|
|
|
|
2017-06-02 04:30:51 -04:00
|
|
|
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))
|
2017-06-04 13:00:36 -04:00
|
|
|
|
|
|
|
def frameRender(self, moduleNo, arrayNo, frameNo):
|
|
|
|
return self.drawBars(self.width, self.height, self.spectrumArray[arrayNo], self.visColor, self.layout)
|
2017-05-28 14:19:28 -04:00
|
|
|
|
|
|
|
def pickColor(self):
|
2017-05-29 20:39:11 -04:00
|
|
|
RGBstring, btnStyle = super().pickColor()
|
2017-05-30 22:05:56 -04:00
|
|
|
if not RGBstring:
|
|
|
|
return
|
2017-05-29 20:39:11 -04:00
|
|
|
self.page.lineEdit_visColor.setText(RGBstring)
|
|
|
|
self.page.pushButton_visColor.setStyleSheet(btnStyle)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 10:52:40 -04:00
|
|
|
def transformData(self, i, completeAudioArray, sampleSize, smoothConstantDown, smoothConstantUp, lastSpectrum):
|
|
|
|
if len(completeAudioArray) < (i + sampleSize):
|
|
|
|
sampleSize = len(completeAudioArray) - i
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 10:52:40 -04:00
|
|
|
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./sample_rate)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 10:52:40 -04:00
|
|
|
y = abs(spectrum[0:int(paddedSampleSize/2) - 1])
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 10:52:40 -04:00
|
|
|
# filter the noise away
|
|
|
|
# y[y<80] = 0
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 10:52:40 -04:00
|
|
|
y = 20 * numpy.log10(y)
|
|
|
|
y[numpy.isinf(y)] = 0
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 10:52:40 -04:00
|
|
|
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
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 10:52:40 -04:00
|
|
|
x = frequencies[0:int(paddedSampleSize/2) - 1]
|
|
|
|
|
|
|
|
return lastSpectrum
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 12:01:51 -04:00
|
|
|
def drawBars(self, width, height, spectrum, color, layout):
|
|
|
|
vH = height-height/8
|
|
|
|
bF = width / 64
|
|
|
|
bH = bF / 2
|
|
|
|
bQ = bF / 4
|
|
|
|
imTop = Image.new("RGBA", (width, height),(0,0,0,0))
|
|
|
|
draw = ImageDraw.Draw(imTop)
|
|
|
|
r, g, b = color
|
|
|
|
color2 = (r, g, b, 125)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 12:01:51 -04:00
|
|
|
bP = height / 1200
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 12:01:51 -04:00
|
|
|
for j in range(0, 63):
|
|
|
|
draw.rectangle((bH + j * bF, vH+bQ, bH + j * bF + bF, vH + bQ - spectrum[j * 4] * bP - bH), fill=color2)
|
|
|
|
draw.rectangle((bH + bQ + j * bF, vH , bH + bQ + j * bF + bH, vH - spectrum[j * 4] * bP), fill=color)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 12:01:51 -04:00
|
|
|
imBottom = imTop.transpose(Image.FLIP_TOP_BOTTOM)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 12:01:51 -04:00
|
|
|
im = Image.new("RGBA", (width, height),(0,0,0,0))
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 12:01:51 -04:00
|
|
|
if layout == 0:
|
|
|
|
y = 0 - int(height/100*43)
|
|
|
|
im.paste(imTop, (0, y), mask=imTop)
|
|
|
|
y = 0 + int(height/100*43)
|
|
|
|
im.paste(imBottom, (0, y), mask=imBottom)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 12:01:51 -04:00
|
|
|
if layout == 1:
|
|
|
|
y = 0 + int(height/100*10)
|
|
|
|
im.paste(imTop, (0, y), mask=imTop)
|
|
|
|
y = 0 - int(height/100*10)
|
|
|
|
im.paste(imBottom, (0, y), mask=imBottom)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 12:01:51 -04:00
|
|
|
if layout == 2:
|
|
|
|
y = 0 + int(height/100*10)
|
|
|
|
im.paste(imTop, (0, y), mask=imTop)
|
2017-05-28 07:34:34 -04:00
|
|
|
|
2017-06-01 12:01:51 -04:00
|
|
|
return im
|
2017-06-02 01:30:44 -04:00
|
|
|
|