- 合并样式【渐变线】到【线】,【线】与【波浪】新增方向(水平与垂直)设置选项
- 样式【波浪】、【圆】、【实心圆】添加渐变设置选项 - 优化服务器调试逻辑(调试模式:服务器崩溃自动打开日志文件) - 优化API
This commit is contained in:
parent
4f9e8d57c5
commit
beffc3a791
BIN
Locales/ja.qm
BIN
Locales/ja.qm
Binary file not shown.
BIN
Locales/zh.qm
BIN
Locales/zh.qm
Binary file not shown.
BIN
Locales/zh_TW.qm
BIN
Locales/zh_TW.qm
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.7 KiB |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/circle"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/circle">{"Main Color":"#ff4500","Line Position":0,"Line Width":1,"Max Range":50,"Data Length":0,"Channel":2,"Reverse":false,"Rotate":false,"Ratate Speed":10,"Angle":0,"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/circle">{"Gradient Style":0,"Radial Gradient Settings":{"Inside Position Color":"#f44336","Middle Position Color":"#4caf50","Outside Position Color":"#03a9f4","Inside Position":40,"Middle Position":60,"Outside Position":80},"Conical Gradient Settings":{"Start Position Color":"#f44336","Quarter Position Color":"#4caf50","Middle Position Color":"#03a9f4","End Position Color":"#ffeb3b"},"Main Color":"#ff4500","Line Position":0,"Line Width":1,"Max Range":80,"Data Length":0,"Channel":2,"Reverse":false,"Rotate":false,"Ratate Speed":10,"Angle":0,"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
|
||||
</map>
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"source": "nvg://advp.widget.mashiros.top/widget",
|
||||
"settings": "settings.xml"
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 5.3 KiB |
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/gradient_line"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/gradient_line">{"Gradient Direction":0,"Start Position Color":"#f44336","Middle Position Color":"#4caf50","End Position Color":"#03a9f4","Center Line":true,"Line Position":0,"Data Length":0,"Channel":2,"Rotate Settings":{"Center Enable":false,"Center Angle":10,"Line Enable":false,"Line Angle":10},"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
|
||||
</map>
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/line">{"Center Line":true,"Center Color":"#ff4500","Line Color":"#ff4500","Line Position":0,"Data Length":0,"Channel":2,"Rotate Settings":{"Center Enable":false,"Center Angle":10,"Line Enable":false,"Line Angle":10},"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/line">{"Enable Gradient":false,"Gradient Direction":0,"Start Position Color":"#f44336","Middle Position Color":"#4caf50","End Position Color":"#03a9f4","Center Line":true,"Center Color":"#ff4500","Center Width":20,"Line Color":"#ff4500","Line Position":0,"Data Length":0,"Channel":2,"Direction":0,"Rotate Settings":{"Center Enable":false,"Center Angle":10,"Line Enable":false,"Line Angle":10,"X Scale":100,"Y Scale":100,"X Offset":0,"Y Offset":0},"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/line"</value>
|
||||
</map>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 5.5 KiB |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/solidcircle"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/solidcircle">{"Main Color":"#ff4500","Line Position":0,"Line Width":1,"Max Range":50,"Data Length":0,"Channel":2,"Reverse":false,"Rotate":false,"Ratate Speed":10,"Angle":0,"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/solidcircle">{"Gradient Style":0,"Radial Gradient Settings":{"Inside Position Color":"#f44336","Middle Position Color":"#4caf50","Outside Position Color":"#03a9f4","Inside Position":40,"Middle Position":60,"Outside Position":80},"Conical Gradient Settings":{"Start Position Color":"#f44336","Quarter Position Color":"#4caf50","Middle Position Color":"#03a9f4","End Position Color":"#ffeb3b"},"Main Color":"#ff4500","Line Position":0,"Line Width":1,"Max Range":80,"Data Length":0,"Channel":2,"Reverse":false,"Rotate":false,"Ratate Speed":10,"Angle":0,"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
|
||||
</map>
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/waves"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/waves">{"Line Width":1,"Line Color":"#ff4500","Data Length":0,"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/waves">{"Enable Gradient":false,"Gradient Direction":0,"Start Position Color":"#f44336","Middle Position Color":"#4caf50","End Position Color":"#03a9f4","Direction":0,"Line Color":"#ff4500","Line Width":1,"Data Length":0,"Rotate Settings":{"Center Enable":false,"Center Angle":10,"Line Enable":false,"Line Angle":10,"X Scale":100,"Y Scale":100,"X Offset":0,"Y Offset":0},"Data Settings":{"Auto Normalizing":true,"Amplitude":10,"Unit Style":0}}</value>
|
||||
</map>
|
||||
26
package.json
26
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
{
|
||||
"name": "top.mashiros.widget.advp",
|
||||
"version": "1.3.0",
|
||||
"version": "1.4.0",
|
||||
|
||||
"title": {
|
||||
"en": "ADV Plugin",
|
||||
@ -61,17 +61,6 @@
|
||||
},
|
||||
"entry": "./styles/Preset_line/Style.qml"
|
||||
},
|
||||
{
|
||||
"location": "/advp-style-preset/gradient_line",
|
||||
"catalog": "top.mashiros.advp-style",
|
||||
"title": {
|
||||
"en": "Gradient Line",
|
||||
"zh": "渐变线",
|
||||
"zh_TW": "漸變線",
|
||||
"ja": "グラデーションライン"
|
||||
},
|
||||
"entry": "./styles/Preset_gradient_line/Style.qml"
|
||||
},
|
||||
{
|
||||
"location": "/advp-style-preset/waves",
|
||||
"catalog": "top.mashiros.advp-style",
|
||||
@ -187,6 +176,17 @@
|
||||
},
|
||||
"preview": "Presets/Ordinal_Scale_UI_bottom/preview.png",
|
||||
"entry": "Presets/Ordinal_Scale_UI_bottom/preset.json"
|
||||
},
|
||||
{
|
||||
"location": "/advp-style-preset/gradient_line",
|
||||
"catalog": "top.mashiros.advp-style-temp",
|
||||
"title": {
|
||||
"en": "Gradient Line",
|
||||
"zh": "渐变线",
|
||||
"zh_TW": "漸變線",
|
||||
"ja": "グラデーションライン"
|
||||
},
|
||||
"entry": "./styles/Preset_line/Style.qml"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -128,6 +128,8 @@ Item {
|
||||
for (let prop in sourceObj) {
|
||||
if (sourceObj.hasOwnProperty(prop) && sourceObj[prop] !== undefined) {
|
||||
if (typeof sourceObj[prop] === 'object') {
|
||||
if (targetObj[prop] === undefined)
|
||||
targetObj[prop] = {};
|
||||
Object.assign(targetObj[prop], sourceObj[prop]);
|
||||
} else {
|
||||
targetObj[prop] = sourceObj[prop];
|
||||
|
||||
@ -37,12 +37,6 @@ T.Widget {
|
||||
preference = item.preference;
|
||||
defaultValues = item.defaultValues;
|
||||
style = item.style;
|
||||
if (!widget.settings[widget.settings.current_style]) {
|
||||
widget.settings[widget.settings.current_style] = defaultValues;
|
||||
}else if(widget.settings[widget.settings.current_style]["Version"] !== defaultValues["Version"]) {
|
||||
delete widget.settings[widget.settings.current_style]["Version"];
|
||||
widget.settings[widget.settings.current_style] = Common.updateObject(Common.deepClone(defaultValues), widget.settings[widget.settings.current_style]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +66,7 @@ T.Widget {
|
||||
|
||||
Component.onCompleted: {
|
||||
Common.widgetsNum++;
|
||||
if ((!widget.settings.current_style) || (Common.stylesURL.indexOf(widget.settings.current_style) === -1)) {
|
||||
if (!widget.settings.current_style) {
|
||||
widget.settings.current_style = Common.stylesURL[0];
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,8 +11,20 @@ Canvas {
|
||||
|
||||
signal audioDataUpdeted(var data)
|
||||
signal configsUpdated()
|
||||
signal completed()
|
||||
signal versionUpdated(string old)
|
||||
|
||||
readonly property var configs: widget.settings[widget.settings.current_style] ?? defaultValues
|
||||
|
||||
function updateObject(target, source) {
|
||||
return Common.updateObject(Common.deepClone(target), Common.deepClone(source));
|
||||
}
|
||||
|
||||
onVersionUpdated: {
|
||||
delete widget.settings[widget.settings.current_style]["Version"];
|
||||
widget.settings[widget.settings.current_style] = updateObject(defaultValues, widget.settings[widget.settings.current_style]);
|
||||
}
|
||||
|
||||
onConfigsChanged: {
|
||||
if (context) {
|
||||
configsUpdated();
|
||||
@ -30,4 +42,13 @@ Canvas {
|
||||
target: Common
|
||||
onAudioDataUpdated: audioDataUpdeted(audioData)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (!widget.settings[widget.settings.current_style]) {
|
||||
widget.settings[widget.settings.current_style] = defaultValues;
|
||||
}else if(widget.settings[widget.settings.current_style]["Version"] !== defaultValues["Version"]) {
|
||||
versionUpdated(widget.settings[widget.settings.current_style]["Version"]);
|
||||
}
|
||||
completed();
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
## 特色
|
||||
* 整合客户端与服务器端的功能,使用更简单
|
||||
* 预设6种频谱显示形式,其中每种都可以进一步自定义设置其样式
|
||||
* 预设5种频谱显示形式,其中每种都可以进一步自定义设置其样式
|
||||
* 提供了Style的开发接口,供开发者添加更多的可视化样式
|
||||
* 导入第三方Style类似其他插件,预计支持steam创意工坊下载
|
||||
* 服务端崩溃后自启动
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
安装并启用插件后,默认加载第一种预设Style样式。右键点击挂件可调出菜单,在挂件菜单中点击“样式设置...”选项,呼出样式设置窗口。点击其中的样式选项可切换不同的样式风格,若此样式提供可配置项,则在样式选项下方会出现配置项。
|
||||
|
||||
<div align="center"><img src="https://s3.bmp.ovh/imgs/2022/05/25/ad36cd0eccc8dd61.png" style="zoom:80%;" /></div>
|
||||
<div align="center"><img src="https://s3.bmp.ovh/imgs/2022/06/04/b608a46f85afc715.png" style="zoom:80%;" /></div>
|
||||
|
||||
## 服务器设置
|
||||
|
||||
|
||||
@ -110,7 +110,7 @@ AdvpStyleTemplate {
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
|
||||
@ -1,115 +1,185 @@
|
||||
import QtQuick 2.12
|
||||
import QtGraphicalEffects 1.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api"
|
||||
|
||||
AdvpStyleTemplate {
|
||||
style: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
style: Rectangle {
|
||||
id: main
|
||||
width: widget.width;
|
||||
height: widget.height;
|
||||
|
||||
//configs
|
||||
readonly property int linePosition: configs["Line Position"]
|
||||
readonly property real maxRange: configs["Max Range"] / 100
|
||||
readonly property int uDataLen: Math.pow(2, configs["Data Length"])
|
||||
readonly property int dataLength: 64/uDataLen
|
||||
readonly property int channel: configs["Channel"]
|
||||
readonly property bool reverse: configs["Reverse"]
|
||||
readonly property bool rotateFlag: configs["Rotate"]
|
||||
readonly property real rSpeed: configs["Ratate Speed"] / 100
|
||||
readonly property real angle: configs["Angle"]
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: 400/configs["Data Settings"]["Amplitude"]
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
property int gradientStyle
|
||||
|
||||
readonly property int total: channel*dataLength
|
||||
|
||||
readonly property real dotGap: 360/total
|
||||
property real offsetAngle: 0
|
||||
property var outerPos: []
|
||||
property var innerPos: []
|
||||
readonly property real degUnit: Math.PI/180
|
||||
|
||||
readonly property real subRatio: 0.2*maxRange
|
||||
readonly property real mainRatio: 1-subRatio*2.5
|
||||
|
||||
readonly property real minLength: Math.min(width, height)
|
||||
readonly property real ratio:minLength*subRatio
|
||||
readonly property real halfWidth: width/2
|
||||
readonly property real halfHeight: height/2
|
||||
readonly property real halfMinLength: minLength/2
|
||||
|
||||
|
||||
onConfigsUpdated: {
|
||||
context.lineWidth = configs["Line Width"];
|
||||
context.strokeStyle = configs["Main Color"];
|
||||
}
|
||||
|
||||
function createPoint() {
|
||||
outerPos.length = 0;
|
||||
innerPos.length = 0;
|
||||
let deg, deltaR, r1, r2, _rhmLen;
|
||||
_rhmLen = mainRatio*halfMinLength;
|
||||
|
||||
for (let j=0; j < channel; j++) {
|
||||
for (let i=0; i < dataLength; i++) {
|
||||
deg = degUnit*((i+j*dataLength)*dotGap + offsetAngle);
|
||||
deltaR = audioData[reverse*(dataLength-i-1)+(!reverse)*(i+j*dataLength)] * ratio;
|
||||
r1 = _rhmLen+1+deltaR*(linePosition!==2);
|
||||
r2 = _rhmLen-1-deltaR*(linePosition!==1);
|
||||
outerPos.push([halfWidth+Math.cos(deg)*r1,halfHeight+Math.sin(deg)*r1]);
|
||||
innerPos.push([halfWidth+Math.cos(deg)*r2,halfHeight+Math.sin(deg)*r2]);
|
||||
}
|
||||
RadialGradient {
|
||||
id: radialGradient
|
||||
anchors.fill: parent
|
||||
visible: gradientStyle===1
|
||||
horizontalRadius: Math.min(width, height)/2
|
||||
verticalRadius: horizontalRadius
|
||||
gradient: Gradient {
|
||||
GradientStop {id: radialGradient_pstart}
|
||||
GradientStop {id: radialGradient_pmiddle}
|
||||
GradientStop {id: radialGradient_pend}
|
||||
}
|
||||
offsetAngle = rotateFlag ? ((offsetAngle + rSpeed) % 360) : angle;
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
let normalizing_ratio = autoNormalizing ? data[128] : amplitude;
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=0; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[i*uDataLen+j]/normalizing_ratio)) + 1.0);
|
||||
ConicalGradient {
|
||||
id: conicalGradient
|
||||
anchors.fill: parent
|
||||
visible: gradientStyle===2
|
||||
angle: -90;
|
||||
gradient: Gradient {
|
||||
GradientStop{id: conicalGradient_pstart; position: 0.0}
|
||||
GradientStop{id: conicalGradient_pquarter; position: 0.25}
|
||||
GradientStop {id: conicalGradient_phalf; position: 0.5}
|
||||
GradientStop {id: conicalGradient_p3quarter; position: 0.75}
|
||||
GradientStop{id: conicalGradient_pend; position: 1.0}
|
||||
}
|
||||
}
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask{
|
||||
maskSource: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
|
||||
//configs
|
||||
readonly property int linePosition: configs["Line Position"]
|
||||
readonly property real maxRange: configs["Max Range"] / 100
|
||||
readonly property int uDataLen: Math.pow(2, configs["Data Length"])
|
||||
readonly property int dataLength: 64/uDataLen
|
||||
readonly property int channel: configs["Channel"]
|
||||
readonly property bool reverse: configs["Reverse"]
|
||||
readonly property bool rotateFlag: configs["Rotate"]
|
||||
readonly property real rSpeed: configs["Ratate Speed"] / 100
|
||||
readonly property real angle: configs["Angle"]
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: 400/configs["Data Settings"]["Amplitude"]
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
readonly property int total: channel*dataLength
|
||||
|
||||
readonly property real dotGap: 360/total
|
||||
property real offsetAngle: 0
|
||||
property var outerPos: []
|
||||
property var innerPos: []
|
||||
readonly property real degUnit: Math.PI/180
|
||||
|
||||
readonly property real subRatio: 0.2*maxRange
|
||||
readonly property real mainRatio: 1-subRatio*2.5
|
||||
|
||||
readonly property real minLength: Math.min(width, height)
|
||||
readonly property real ratio:minLength*subRatio
|
||||
readonly property real halfWidth: width/2
|
||||
readonly property real halfHeight: height/2
|
||||
readonly property real halfMinLength: minLength/2
|
||||
|
||||
|
||||
onConfigsUpdated: {
|
||||
gradientStyle = configs["Gradient Style"];
|
||||
context.lineWidth = configs["Line Width"];
|
||||
main.color = configs["Main Color"];
|
||||
if (gradientStyle === 1) {
|
||||
radialGradient_pstart.color = configs["Radial Gradient Settings"]["Inside Position Color"];
|
||||
radialGradient_pstart.position = configs["Radial Gradient Settings"]["Inside Position"]/100;
|
||||
radialGradient_pmiddle.color = configs["Radial Gradient Settings"]["Middle Position Color"];
|
||||
radialGradient_pmiddle.position = configs["Radial Gradient Settings"]["Middle Position"]/100;
|
||||
radialGradient_pend.color = configs["Radial Gradient Settings"]["Outside Position Color"];
|
||||
radialGradient_pend.position = configs["Radial Gradient Settings"]["Outside Position"]/100;
|
||||
} else if (gradientStyle === 2) {
|
||||
conicalGradient_pstart.color = configs["Conical Gradient Settings"]["Start Position Color"];
|
||||
conicalGradient_pquarter.color = configs["Conical Gradient Settings"]["Quarter Position Color"];
|
||||
conicalGradient_phalf.color = configs["Conical Gradient Settings"]["Middle Position Color"];
|
||||
conicalGradient_p3quarter.color = configs["Conical Gradient Settings"]["End Position Color"];
|
||||
conicalGradient_pend.color = configs["Conical Gradient Settings"]["Start Position Color"];
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[i*uDataLen+j];
|
||||
|
||||
function createPoint() {
|
||||
outerPos.length = 0;
|
||||
innerPos.length = 0;
|
||||
let deg, deltaR, r1, r2, _rhmLen;
|
||||
_rhmLen = mainRatio*halfMinLength;
|
||||
|
||||
for (let j=0; j < channel; j++) {
|
||||
for (let i=0; i < dataLength; i++) {
|
||||
deg = degUnit*((i+j*dataLength)*dotGap+offsetAngle);
|
||||
deltaR = audioData[reverse*(dataLength-i-1)+(!reverse)*(i+j*dataLength)] * ratio;
|
||||
r1 = _rhmLen+1+deltaR*(linePosition!==2);
|
||||
r2 = _rhmLen-1-deltaR*(linePosition!==1);
|
||||
outerPos.push([halfWidth+Math.cos(deg)*r1,halfHeight+Math.sin(deg)*r1]);
|
||||
innerPos.push([halfWidth+Math.cos(deg)*r2,halfHeight+Math.sin(deg)*r2]);
|
||||
}
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
conicalGradient.rotation = offsetAngle;
|
||||
offsetAngle = rotateFlag ? ((offsetAngle + rSpeed) % 360) : angle;
|
||||
}
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
createPoint();
|
||||
onAudioDataUpdeted: {
|
||||
let normalizing_ratio = autoNormalizing ? data[128] : amplitude;
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=0; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[i*uDataLen+j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[i*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
context.beginPath();
|
||||
for(let i=0; i<total; i++) {
|
||||
context.moveTo(outerPos[i][0], outerPos[i][1]);
|
||||
context.lineTo(innerPos[i][0], innerPos[i][1]);
|
||||
}
|
||||
context.stroke();
|
||||
requestPaint();
|
||||
}
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
createPoint();
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
context.beginPath();
|
||||
for(let i=0; i<total; i++) {
|
||||
context.moveTo(outerPos[i][0], outerPos[i][1]);
|
||||
context.lineTo(innerPos[i][0], innerPos[i][1]);
|
||||
}
|
||||
context.stroke();
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultValues: {
|
||||
"Version": "1.1.0",
|
||||
"Version": "1.2.0",
|
||||
"Gradient Style": 0,
|
||||
"Radial Gradient Settings": {
|
||||
"Inside Position Color": "#f44336",
|
||||
"Middle Position Color": "#4caf50",
|
||||
"Outside Position Color": "#03a9f4",
|
||||
"Inside Position": 40,
|
||||
"Middle Position": 60,
|
||||
"Outside Position": 80
|
||||
},
|
||||
"Conical Gradient Settings": {
|
||||
"Start Position Color": "#f44336",
|
||||
"Quarter Position Color": "#4caf50",
|
||||
"Middle Position Color": "#03a9f4",
|
||||
"End Position Color": "#ffeb3b"
|
||||
},
|
||||
"Main Color": "#ff4500",
|
||||
"Line Position": 0,
|
||||
"Line Width": 1,
|
||||
"Max Range": 50,
|
||||
"Max Range": 80,
|
||||
"Data Length": 0,
|
||||
"Channel": 2,
|
||||
"Reverse": false,
|
||||
@ -126,9 +196,107 @@ AdvpStyleTemplate {
|
||||
preference: AdvpPreference {
|
||||
version: defaultValues["Version"]
|
||||
|
||||
P.SelectPreference {
|
||||
id: _cfg_gradient_style
|
||||
name: "Gradient Style"
|
||||
label: qsTr("Gradient Style")
|
||||
defaultValue: defaultValues["Gradient Style"]
|
||||
model: [qsTr("None"), qsTr("Radial Gradient"), qsTr("Conical Gradient")]
|
||||
}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Radial Gradient Settings"
|
||||
label: qsTr("Radial Gradient Settings")
|
||||
live: true
|
||||
visible: _cfg_gradient_style.value===1
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Inside Position Color"
|
||||
label: qsTr("Inside Position Color")
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Inside Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Middle Position Color"
|
||||
label: qsTr("Middle Position Color")
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Middle Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Outside Position Color"
|
||||
label: qsTr("Outside Position Color")
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Outside Position Color"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
id: _cfg_gradient_settings_inside_position
|
||||
name: "Inside Position"
|
||||
label: qsTr("Inside Position")
|
||||
from: 0
|
||||
to: 75
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Inside Position"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
id: _cfg_gradient_settings_middle_position
|
||||
name: "Middle Position"
|
||||
label: qsTr("Middle Position")
|
||||
from: _cfg_gradient_settings_inside_position.value + 1
|
||||
to: 90
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Middle Position"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Outside Position"
|
||||
label: qsTr("Outside Position")
|
||||
from: _cfg_gradient_settings_middle_position.value + 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Outside Position"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Conical Gradient Settings"
|
||||
label: qsTr("Conical Gradient Settings")
|
||||
live: true
|
||||
visible: _cfg_gradient_style.value===2
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Start Position Color"
|
||||
label: qsTr("Start Position Color")
|
||||
defaultValue: defaultValues["Conical Gradient Settings"]["Start Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Quarter Position Color"
|
||||
label: qsTr("Quarter Position Color")
|
||||
defaultValue: defaultValues["Conical Gradient Settings"]["Quarter Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Middle Position Color"
|
||||
label: qsTr("Middle Position Color")
|
||||
defaultValue: defaultValues["Conical Gradient Settings"]["Middle Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "End Position Color"
|
||||
label: qsTr("End Position Color")
|
||||
defaultValue: defaultValues["Conical Gradient Settings"]["End Position Color"]
|
||||
}
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Main Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
visible: !_cfg_gradient_style.value
|
||||
defaultValue: defaultValues["Main Color"]
|
||||
}
|
||||
|
||||
@ -179,8 +347,6 @@ AdvpStyleTemplate {
|
||||
defaultValue: defaultValues["Channel"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
|
||||
@ -1,310 +0,0 @@
|
||||
import QtQuick 2.12
|
||||
import QtGraphicalEffects 1.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api"
|
||||
|
||||
AdvpStyleTemplate {
|
||||
style: Rectangle {
|
||||
width: widget.width;
|
||||
height: widget.height;
|
||||
|
||||
LinearGradient {
|
||||
id: gradient_mask
|
||||
anchors.fill: parent
|
||||
gradient: Gradient {
|
||||
GradientStop { id: p_start; position: 0.0 }
|
||||
GradientStop { id: p_middle; position: 0.5 }
|
||||
GradientStop { id: p_end; position: 1.0 }
|
||||
}
|
||||
}
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask{
|
||||
maskSource: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
|
||||
readonly property bool centerLineFlag: configs["Center Line"]
|
||||
readonly property int linePosition: configs["Line Position"]
|
||||
readonly property int uDataLen: Math.pow(2, configs["Data Length"]);
|
||||
readonly property int dataLength: 64/uDataLen
|
||||
readonly property int channel: configs["Channel"]
|
||||
readonly property bool centerRotateFlag: configs["Rotate Settings"]["Center Enable"]
|
||||
readonly property real centerRotateAngle: configs["Rotate Settings"]["Center Angle"]*Math.PI/180
|
||||
readonly property bool lineRotateFlag: configs["Rotate Settings"]["Line Enable"]
|
||||
readonly property real lineRotateAngle: configs["Rotate Settings"]["Line Angle"]*Math.PI/180
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: 400.0/configs["Data Settings"]["Amplitude"]
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
property real halfWidth: width/2
|
||||
property real halfHeight: height/2
|
||||
|
||||
readonly property int l_start: (channel===1)*dataLength
|
||||
readonly property int r_stop: dataLength+dataLength*(channel!==0)
|
||||
|
||||
readonly property int total: r_stop-l_start
|
||||
readonly property real _y_dy: centerRotateFlag*Math.tan(centerRotateAngle)*halfWidth
|
||||
readonly property real _ux: width/(r_stop-l_start)
|
||||
readonly property real _dx: Math.round(_ux/2)
|
||||
|
||||
onConfigsUpdated: {
|
||||
context.fillStyle = "black";
|
||||
gradient_mask.start = Qt.point(0, height*(configs["Gradient Direction"]===2))
|
||||
gradient_mask.end = Qt.point(width*(configs["Gradient Direction"]!==1), height*(configs["Gradient Direction"]%2))
|
||||
p_start.color = configs["Start Position Color"];
|
||||
p_middle.color = configs["Middle Position Color"];
|
||||
p_end.color = configs["End Position Color"];
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
let normalizing_ratio = autoNormalizing ? data[128] : amplitude;
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=l_start; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[63-i*uDataLen-j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
for(let i=dataLength; i<r_stop; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[i*uDataLen+j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=l_start; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[63-i*uDataLen-j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
for(let i=dataLength; i<r_stop; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[i*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
|
||||
let _y;
|
||||
let _dy;
|
||||
//绘制频谱
|
||||
if(lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(1, Math.sin(centerRotateFlag*centerRotateAngle), -Math.sin(lineRotateFlag*lineRotateAngle), 1, Math.sin(lineRotateFlag*lineRotateAngle)*(halfHeight-_y_dy), 0);
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[i])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[i];
|
||||
context.fillRect(_ux * (i-l_start), _y, _dx, _dy);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(0, halfHeight-_y_dy, width, 2);
|
||||
}
|
||||
context.resetTransform();
|
||||
} else if (linePosition) {
|
||||
let _flag = 1-2*(linePosition===1);
|
||||
_y = halfHeight + halfHeight*(3-2*linePosition)*Boolean(linePosition);
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_dy = height*audioData[i]*_flag;
|
||||
context.fillRect(_ux * (i-l_start), _y, _dx, _dy);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(0, _y-(2-linePosition)*2, width, 2);
|
||||
}
|
||||
} else {
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[i])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[i];
|
||||
context.fillRect(_ux * (i-l_start), _y, _dx, _dy);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(0, halfHeight-_y_dy, width, 2);
|
||||
}
|
||||
}
|
||||
|
||||
context.fill();
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultValues: {
|
||||
"Version": "1.2.0",
|
||||
"Gradient Direction": 0,
|
||||
"Start Position Color": "#f44336",
|
||||
"Middle Position Color": "#4caf50",
|
||||
"End Position Color": "#03a9f4",
|
||||
"Center Line": true,
|
||||
"Line Position": 0,
|
||||
"Data Length": 0,
|
||||
"Channel": 2,
|
||||
"Rotate Settings": {
|
||||
"Center Enable": false,
|
||||
"Center Angle": 10,
|
||||
"Line Enable": false,
|
||||
"Line Angle": 10
|
||||
},
|
||||
"Data Settings": {
|
||||
"Auto Normalizing": true,
|
||||
"Amplitude": 10,
|
||||
"Unit Style": 0
|
||||
}
|
||||
}
|
||||
|
||||
preference: AdvpPreference {
|
||||
version: defaultValues["Version"]
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Gradient Direction"
|
||||
label: qsTr("Gradient Direction")
|
||||
defaultValue: defaultValues["Gradient Direction"]
|
||||
model: [qsTr("Horizontal"), qsTr("Vertical"), qsTr("Oblique Upward"), qsTr("Oblique downward")]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Start Position Color"
|
||||
label: qsTr("Start Position Color")
|
||||
defaultValue: defaultValues["Start Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Middle Position Color"
|
||||
label: qsTr("Middle Position Color")
|
||||
defaultValue: defaultValues["Middle Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "End Position Color"
|
||||
label: qsTr("End Position Color")
|
||||
defaultValue: defaultValues["End Position Color"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Center Line"
|
||||
label: qsTr("Show Center Line")
|
||||
defaultValue: defaultValues["Center Line"]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Line Position"
|
||||
label: qsTr("Spectrum Line Position")
|
||||
defaultValue: defaultValues["Line Position"]
|
||||
model: [qsTr("Both"), qsTr("Up"), qsTr("Down")]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Data Length"
|
||||
label: qsTr("Spectrum Length")
|
||||
defaultValue: defaultValues["Data Length"]
|
||||
model: [64, 32, 16, 8]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Channel"
|
||||
label: qsTr("Channel")
|
||||
defaultValue: defaultValues["Channel"]
|
||||
model: [qsTr("Left Channel"), qsTr("Right Channel"), qsTr("Stereo")]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Rotate Settings"
|
||||
label: qsTr("Rotate Settings")
|
||||
live: true
|
||||
icon.name: "regular:\uf1de"
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_Rotate_Center_Enable
|
||||
name: "Center Enable"
|
||||
label: qsTr("Rotate Center Line")
|
||||
defaultValue: defaultValues["Rotate Settings"]["Center Enable"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Center Angle"
|
||||
label: qsTr("Angle of Center Line")
|
||||
enabled: _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: -45
|
||||
to: 45
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["Center Angle"]
|
||||
displayValue: value + "°"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_Rotate_Line_Enable
|
||||
name: "Line Enable"
|
||||
label: qsTr("Rotate Spectrum Line")
|
||||
defaultValue: defaultValues["Rotate Settings"]["Line Enable"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Line Angle"
|
||||
label: qsTr("Angle of Spectrum Line")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value
|
||||
from: -75
|
||||
to: 75
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["Line Angle"]
|
||||
displayValue: value + "°"
|
||||
}
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Data Settings"
|
||||
label: qsTr("Data Settings")
|
||||
live: true
|
||||
icon.name: "regular:\uf1de"
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_dataSettings_autoNormalizing
|
||||
name: "Auto Normalizing"
|
||||
label: qsTr("Auto Normalizing")
|
||||
defaultValue: defaultValues["Data Settings"]["Auto Normalizing"]
|
||||
}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Amplitude"
|
||||
label: qsTr("Amplitude Ratio")
|
||||
enabled: !_cfg_preset_line_dataSettings_autoNormalizing.value
|
||||
message: "1 to 100"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: true
|
||||
from: 1
|
||||
to: 100
|
||||
defaultValue: defaultValues["Data Settings"]["Amplitude"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Unit Style"
|
||||
label: qsTr("Display Style")
|
||||
defaultValue: defaultValues["Data Settings"]["Unit Style"]
|
||||
model: [qsTr("Linear"), qsTr("Decibel")]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,140 +1,288 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick 2.12
|
||||
import QtGraphicalEffects 1.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api"
|
||||
|
||||
AdvpStyleTemplate {
|
||||
style: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
style: Rectangle {
|
||||
id: main
|
||||
width: widget.width;
|
||||
height: widget.height;
|
||||
|
||||
readonly property bool centerLineFlag: configs["Center Line"]
|
||||
readonly property string center_color: configs["Center Color"]
|
||||
readonly property string line_color: configs["Line Color"]
|
||||
readonly property int linePosition: configs["Line Position"]
|
||||
readonly property int uDataLen: Math.pow(2, configs["Data Length"]);
|
||||
readonly property int dataLength: 64/uDataLen
|
||||
readonly property int channel: configs["Channel"]
|
||||
readonly property bool centerRotateFlag: configs["Rotate Settings"]["Center Enable"]
|
||||
readonly property real centerRotateAngle: configs["Rotate Settings"]["Center Angle"]*Math.PI/180
|
||||
readonly property bool lineRotateFlag: configs["Rotate Settings"]["Line Enable"]
|
||||
readonly property real lineRotateAngle: configs["Rotate Settings"]["Line Angle"]*Math.PI/180
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: 400.0/configs["Data Settings"]["Amplitude"]
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
property bool gradientEnable
|
||||
property bool centerLineFlag
|
||||
property string center_color
|
||||
property real center_width
|
||||
property int linePosition
|
||||
property bool vertical_flag
|
||||
property real _y_dy
|
||||
|
||||
property real halfWidth: width/2
|
||||
property real halfHeight: height/2
|
||||
|
||||
readonly property int l_start: (channel===1)*dataLength
|
||||
readonly property int r_stop: dataLength+dataLength*(channel!==0)
|
||||
readonly property int total: r_stop-l_start
|
||||
readonly property real _y_dy: centerRotateFlag*Math.tan(centerRotateAngle)*halfWidth
|
||||
readonly property real _ux: width/(r_stop-l_start)
|
||||
readonly property real _dx: Math.round(_ux/2)
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
let normalizing_ratio = autoNormalizing ? data[128] : amplitude;
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=l_start; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[63-i*uDataLen-j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
for(let i=dataLength; i<r_stop; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[i*uDataLen+j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=l_start; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[63-i*uDataLen-j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
for(let i=dataLength; i<r_stop; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[i*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
LinearGradient {
|
||||
id: gradient_mask
|
||||
anchors.fill: parent
|
||||
visible: gradientEnable
|
||||
gradient: Gradient {
|
||||
GradientStop { id: p_start; position: 0.0 }
|
||||
GradientStop { id: p_middle; position: 0.5 }
|
||||
GradientStop { id: p_end; position: 1.0 }
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
|
||||
let _y;
|
||||
let _dy;
|
||||
//绘制频谱
|
||||
if(lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(1, Math.sin(centerRotateFlag*centerRotateAngle), -Math.sin(lineRotateFlag*lineRotateAngle), 1, Math.sin(lineRotateFlag*lineRotateAngle)*(halfHeight-_y_dy), 0);
|
||||
context.fillStyle = line_color;
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[i])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[i];
|
||||
context.fillRect(_ux * (i-l_start), _y, _dx, _dy);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillStyle = center_color;
|
||||
context.fillRect(0, halfHeight-_y_dy, width, 2);
|
||||
}
|
||||
context.resetTransform();
|
||||
} else if (linePosition) {
|
||||
let _flag = 1-2*(linePosition===1);
|
||||
_y = halfHeight + halfHeight*(3-2*linePosition)*Boolean(linePosition);
|
||||
context.fillStyle = line_color;
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_dy = height*audioData[i]*_flag;
|
||||
context.fillRect(_ux * (i-l_start), _y, _dx, _dy);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillStyle = center_color;
|
||||
context.fillRect(0, _y-(2-linePosition)*2, width, 2);
|
||||
}
|
||||
} else {
|
||||
context.fillStyle = line_color;
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[i])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[i];
|
||||
context.fillRect(_ux * (i-l_start), _y, _dx, _dy);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillStyle = center_color;
|
||||
context.fillRect(0, halfHeight-_y_dy, width, 2);
|
||||
}
|
||||
}
|
||||
|
||||
context.fill();
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
Canvas {
|
||||
id: centerLine
|
||||
anchors.fill: parent
|
||||
contextType: "2d"
|
||||
renderTarget: Canvas.FramebufferObject
|
||||
renderStrategy: Canvas.Cooperative
|
||||
visible: centerLineFlag && !gradientEnable
|
||||
onPaint: {
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
context.fillStyle = center_color;
|
||||
if (vertical_flag) {
|
||||
if (linePosition) {
|
||||
let _y = width/2 + width/2*(3-2*linePosition)*Boolean(linePosition);
|
||||
context.fillRect(_y+(linePosition-2)*center_width, 0, center_width, height);
|
||||
} else {
|
||||
context.fillRect(width/2-_y_dy-center_width/2, 0, center_width, width);
|
||||
}
|
||||
} else {
|
||||
if (linePosition) {
|
||||
let _y = height/2 + height/2*(3-2*linePosition)*Boolean(linePosition);
|
||||
context.fillRect(0, _y+(linePosition-2)*center_width, width, center_width);
|
||||
} else {
|
||||
context.fillRect(0, height/2-_y_dy-center_width/2, width, center_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask{
|
||||
maskSource: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
|
||||
readonly property string line_color: configs["Line Color"]
|
||||
readonly property int uDataLen: Math.pow(2, configs["Data Length"]);
|
||||
readonly property int dataLength: 64/uDataLen
|
||||
readonly property int channel: configs["Channel"]
|
||||
readonly property bool centerRotateFlag: configs["Rotate Settings"]["Center Enable"]
|
||||
readonly property real centerRotateAngleTangent: centerRotateFlag*Math.tan(configs["Rotate Settings"]["Center Angle"]*Math.PI/180)
|
||||
readonly property bool lineRotateFlag: configs["Rotate Settings"]["Line Enable"]
|
||||
readonly property real lineRotateAngleTangent: lineRotateFlag*Math.tan(configs["Rotate Settings"]["Line Angle"]*Math.PI/180)
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: 400.0/configs["Data Settings"]["Amplitude"]
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
readonly property real xOffset: configs["Rotate Settings"]["X Offset"]/100
|
||||
readonly property real yOffset: configs["Rotate Settings"]["Y Offset"]/100
|
||||
readonly property real xScale: configs["Rotate Settings"]["X Scale"]/100
|
||||
readonly property real yScale: configs["Rotate Settings"]["Y Scale"]/100
|
||||
|
||||
readonly property real halfWidth: vertical_flag ? height/2 : width/2
|
||||
readonly property real halfHeight: vertical_flag ? width/2 : height/2
|
||||
|
||||
readonly property int l_start: (channel===1)*dataLength
|
||||
readonly property int r_stop: dataLength+dataLength*(channel!==0)
|
||||
readonly property int total: r_stop-l_start
|
||||
readonly property real _ux: halfWidth*2/(r_stop-l_start)
|
||||
readonly property real _dx: Math.round(_ux/2)
|
||||
|
||||
onWidthChanged: {
|
||||
if (gradientEnable) {
|
||||
gradient_mask.end = Qt.point(width*(configs["Gradient Direction"]!==1), height*(configs["Gradient Direction"]%2));
|
||||
}
|
||||
centerLine.requestPaint();
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
if (gradientEnable) {
|
||||
gradient_mask.start = Qt.point(0, height*(configs["Gradient Direction"]===2));
|
||||
gradient_mask.end = Qt.point(width*(configs["Gradient Direction"]!==1), height*(configs["Gradient Direction"]%2));
|
||||
}
|
||||
centerLine.requestPaint();
|
||||
}
|
||||
|
||||
onConfigsUpdated: {
|
||||
//尽量不要使用绑定configs的属性以免造成竞争,若一定要使用推荐使用Qt.callLater(()=>{})
|
||||
centerLineFlag = configs["Center Line"];
|
||||
center_color = configs["Center Color"];
|
||||
center_width = configs["Center Width"]/10;
|
||||
linePosition = configs["Line Position"];
|
||||
vertical_flag = configs["Direction"];
|
||||
gradientEnable = configs["Enable Gradient"];
|
||||
context.lineWidth = configs["Line Width"];
|
||||
main.color = configs["Line Color"];
|
||||
_y_dy = configs["Rotate Settings"]["Center Enable"]*Math.tan(configs["Rotate Settings"]["Center Angle"]*Math.PI/180)*(vertical_flag ? height/2 : width/2);
|
||||
if (gradientEnable) {
|
||||
gradient_mask.start = Qt.point(0, height*(configs["Gradient Direction"]===2));
|
||||
gradient_mask.end = Qt.point(width*(configs["Gradient Direction"]!==1), height*(configs["Gradient Direction"]%2));
|
||||
p_start.color = configs["Start Position Color"];
|
||||
p_middle.color = configs["Middle Position Color"];
|
||||
p_end.color = configs["End Position Color"];
|
||||
}
|
||||
centerLine.requestPaint();
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
let normalizing_ratio = autoNormalizing ? data[128] : amplitude;
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=l_start; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[63-i*uDataLen-j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
for(let i=dataLength; i<r_stop; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[i*uDataLen+j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=l_start; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[63-i*uDataLen-j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
for(let i=dataLength; i<r_stop; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[i*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
|
||||
let _y;
|
||||
let _dy;
|
||||
if (vertical_flag) {
|
||||
if(lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(yScale, lineRotateAngleTangent, -centerRotateAngleTangent, xScale, 2*_y_dy+yOffset*height, xOffset*width-lineRotateAngleTangent*(halfHeight-_y_dy));
|
||||
context.fillStyle = line_color;
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[i])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[i];
|
||||
context.fillRect(_y, _ux * (i-l_start), _dy, _dx);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(halfHeight-_y_dy-center_width/2, 0, center_width, height);
|
||||
}
|
||||
context.resetTransform();
|
||||
} else if (linePosition) {
|
||||
let _flag = 1-2*(linePosition===1);
|
||||
_y = halfHeight + halfHeight*(3-2*linePosition)*Boolean(linePosition);
|
||||
context.fillStyle = line_color;
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_dy = width*audioData[i]*_flag;
|
||||
context.fillRect(_y, _ux * (i-l_start), _dy, _dx);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(_y+(linePosition-2)*center_width, 0, center_width, height);
|
||||
}
|
||||
} else {
|
||||
context.fillStyle = line_color;
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[i])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[i];
|
||||
context.fillRect(_y, _ux * (i-l_start), _dy, _dx);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(halfHeight-_y_dy-center_width/2, 0, center_width, height);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//绘制频谱
|
||||
if(lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(xScale, centerRotateAngleTangent, -lineRotateAngleTangent, yScale, xOffset*width+lineRotateAngleTangent*(halfHeight-_y_dy), yOffset*height);
|
||||
context.fillStyle = line_color;
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[i])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[i];
|
||||
context.fillRect(_ux * (i-l_start), _y, _dx, _dy);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(0, halfHeight-_y_dy-center_width/2, width, center_width);
|
||||
}
|
||||
context.resetTransform();
|
||||
} else if (linePosition) {
|
||||
let _flag = 1-2*(linePosition===1);
|
||||
_y = halfHeight + halfHeight*(3-2*linePosition)*Boolean(linePosition);
|
||||
context.fillStyle = line_color;
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_dy = height*audioData[i]*_flag;
|
||||
context.fillRect(_ux * (i-l_start), _y, _dx, _dy);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(0, _y+(linePosition-2)*center_width, width, center_width);
|
||||
}
|
||||
} else {
|
||||
context.fillStyle = line_color;
|
||||
for (let i=l_start; i<r_stop; i++) {
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[i])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[i];
|
||||
context.fillRect(_ux * (i-l_start), _y, _dx, _dy);
|
||||
}
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(0, halfHeight-_y_dy-center_width/2, width, center_width);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.fill();
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
onVersionUpdated: {
|
||||
if (widget.settings.current_style === "nvg://advp.widget.mashiros.top/advp-style-preset/gradient_line") {
|
||||
widget.settings.current_style = "nvg://advp.widget.mashiros.top/advp-style-preset/line";
|
||||
widget.settings[widget.settings.current_style] = updateObject(widget.settings["nvg://advp.widget.mashiros.top/advp-style-preset/gradient_line"], widget.settings[widget.settings.current_style]);
|
||||
widget.settings[widget.settings.current_style]["Enable Gradient"] = true;
|
||||
}
|
||||
delete widget.settings[widget.settings.current_style]["Version"];
|
||||
widget.settings[widget.settings.current_style] = updateObject(defaultValues, widget.settings[widget.settings.current_style]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultValues: {
|
||||
"Version": "1.2.0",
|
||||
"Version": "1.3.0",
|
||||
"Enable Gradient": false,
|
||||
"Gradient Direction": 0,
|
||||
"Start Position Color": "#f44336",
|
||||
"Middle Position Color": "#4caf50",
|
||||
"End Position Color": "#03a9f4",
|
||||
"Center Line": true,
|
||||
"Center Color": "#ff4500",
|
||||
"Center Width": 20,
|
||||
"Line Color": "#ff4500",
|
||||
"Line Position": 0,
|
||||
"Data Length": 0,
|
||||
"Channel": 2,
|
||||
"Direction": 0,
|
||||
"Rotate Settings": {
|
||||
"Center Enable": false,
|
||||
"Center Angle": 10,
|
||||
"Line Enable": false,
|
||||
"Line Angle": 10
|
||||
"Line Angle": 10,
|
||||
"X Scale": 100,
|
||||
"Y Scale": 100,
|
||||
"X Offset": 0,
|
||||
"Y Offset": 0
|
||||
},
|
||||
"Data Settings": {
|
||||
"Auto Normalizing": true,
|
||||
@ -146,6 +294,44 @@ AdvpStyleTemplate {
|
||||
preference: AdvpPreference {
|
||||
version: defaultValues["Version"]
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_enable_gradient
|
||||
name: "Enable Gradient"
|
||||
label: qsTr("Enable Gradient")
|
||||
defaultValue: defaultValues["Enable Gradient"]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Gradient Direction"
|
||||
label: qsTr("Gradient Direction")
|
||||
visible: _cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["Gradient Direction"]
|
||||
model: [qsTr("Horizontal"), qsTr("Vertical"), qsTr("Oblique Upward"), qsTr("Oblique downward")]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Start Position Color"
|
||||
label: qsTr("Start Position Color")
|
||||
visible: _cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["Start Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Middle Position Color"
|
||||
label: qsTr("Middle Position Color")
|
||||
visible: _cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["Middle Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "End Position Color"
|
||||
label: qsTr("End Position Color")
|
||||
visible: _cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["End Position Color"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_Center_Line
|
||||
name: "Center Line"
|
||||
@ -156,15 +342,35 @@ AdvpStyleTemplate {
|
||||
P.ColorPreference {
|
||||
name: "Center Color"
|
||||
label: qsTr("Center Line Color")
|
||||
enabled: _cfg_preset_line_Center_Line.value
|
||||
visible: !_cfg_enable_gradient.value && _cfg_preset_line_Center_Line.value
|
||||
defaultValue: defaultValues["Center Color"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Center Width"
|
||||
label: qsTr("Center Line Width")
|
||||
visible: _cfg_preset_line_Center_Line.value
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Center Width"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SelectPreference {
|
||||
id: _cfg_direction
|
||||
name: "Direction"
|
||||
label: qsTr("Direction")
|
||||
defaultValue: defaultValues["Direction"]
|
||||
model: [qsTr("Horizontal"), qsTr("Vertical")]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Line Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
visible: !_cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["Line Color"]
|
||||
}
|
||||
|
||||
@ -172,7 +378,7 @@ AdvpStyleTemplate {
|
||||
name: "Line Position"
|
||||
label: qsTr("Spectrum Line Position")
|
||||
defaultValue: defaultValues["Line Position"]
|
||||
model: [qsTr("Both"), qsTr("Up"), qsTr("Down")]
|
||||
model: [qsTr("Both"), [qsTr("Up"), qsTr("Left")][_cfg_direction.value], [qsTr("Down"), qsTr("Right")][_cfg_direction.value]]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
@ -228,12 +434,58 @@ AdvpStyleTemplate {
|
||||
name: "Line Angle"
|
||||
label: qsTr("Angle of Spectrum Line")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value
|
||||
from: -75
|
||||
to: 75
|
||||
from: -45
|
||||
to: 45
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["Line Angle"]
|
||||
displayValue: value + "°"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "X Scale"
|
||||
label: qsTr("Scale of Center Line Direction")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value || _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["X Scale"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Y Scale"
|
||||
label: qsTr("Scale of Spectrum Line Direction")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value || _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["Y Scale"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "X Offset"
|
||||
label: qsTr("Offset of Center Line Direction")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value || _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: -100
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["X Offset"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Y Offset"
|
||||
label: qsTr("Offset of Spectrum Line Direction")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value || _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: -100
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["Y Offset"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
@ -1,131 +1,201 @@
|
||||
import QtQuick 2.12
|
||||
import QtGraphicalEffects 1.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api"
|
||||
|
||||
AdvpStyleTemplate {
|
||||
style: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
style: Rectangle {
|
||||
id: main
|
||||
width: widget.width;
|
||||
height: widget.height;
|
||||
|
||||
//configs
|
||||
readonly property int linePosition: configs["Line Position"]
|
||||
readonly property real maxRange: configs["Max Range"] / 100
|
||||
readonly property int uDataLen: Math.pow(2, configs["Data Length"])
|
||||
readonly property int dataLength: 64/uDataLen
|
||||
readonly property int channel: configs["Channel"]
|
||||
readonly property bool reverse: configs["Reverse"]
|
||||
readonly property bool rotateFlag: configs["Rotate"]
|
||||
readonly property real rSpeed: configs["Ratate Speed"] / 100
|
||||
readonly property real angle: configs["Angle"]
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: 400/configs["Data Settings"]["Amplitude"]
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
property int gradientStyle
|
||||
|
||||
readonly property int total: channel*dataLength
|
||||
|
||||
readonly property real dotGap: 360/total
|
||||
property real offsetAngle: 0
|
||||
property var outerPos: []
|
||||
property var innerPos: []
|
||||
readonly property real degUnit: Math.PI/180
|
||||
|
||||
readonly property real subRatio: 0.2*maxRange
|
||||
readonly property real mainRatio: 1-subRatio*2.5
|
||||
|
||||
readonly property real minLength: Math.min(width, height)
|
||||
readonly property real ratio:minLength*subRatio
|
||||
readonly property real halfWidth: width/2
|
||||
readonly property real halfHeight: height/2
|
||||
readonly property real halfMinLength: minLength/2
|
||||
|
||||
|
||||
onConfigsUpdated: {
|
||||
context.lineWidth = configs["Line Width"];
|
||||
context.strokeStyle = configs["Main Color"];
|
||||
}
|
||||
|
||||
function createPoint() {
|
||||
outerPos.length = 0;
|
||||
innerPos.length = 0;
|
||||
let deg, deltaR, r1, r2, _rhmLen;
|
||||
_rhmLen = mainRatio*halfMinLength;
|
||||
|
||||
for (let j=0; j < channel; j++) {
|
||||
for (let i=0; i < dataLength; i++) {
|
||||
deg = degUnit*((i+j*dataLength)*dotGap + offsetAngle);
|
||||
deltaR = audioData[reverse*(dataLength-i-1)+(!reverse)*(i+j*dataLength)] * ratio;
|
||||
r1 = _rhmLen+1+deltaR*(linePosition!==2);
|
||||
r2 = _rhmLen-1-deltaR*(linePosition!==1);
|
||||
outerPos.push([halfWidth+Math.cos(deg)*r1,halfHeight+Math.sin(deg)*r1]);
|
||||
innerPos.push([halfWidth+Math.cos(deg)*r2,halfHeight+Math.sin(deg)*r2]);
|
||||
}
|
||||
RadialGradient {
|
||||
id: radialGradient
|
||||
anchors.fill: parent
|
||||
visible: gradientStyle===1
|
||||
horizontalRadius: Math.min(width, height)/2
|
||||
verticalRadius: horizontalRadius
|
||||
gradient: Gradient {
|
||||
GradientStop {id: radialGradient_pstart}
|
||||
GradientStop {id: radialGradient_pmiddle}
|
||||
GradientStop {id: radialGradient_pend}
|
||||
}
|
||||
offsetAngle = rotateFlag ? ((offsetAngle + rSpeed) % 360) : angle;
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
let normalizing_ratio = autoNormalizing ? data[128] : amplitude;
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=0; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[i*uDataLen+j]/normalizing_ratio)) + 1.0);
|
||||
ConicalGradient {
|
||||
id: conicalGradient
|
||||
anchors.fill: parent
|
||||
visible: gradientStyle===2
|
||||
angle: -90;
|
||||
gradient: Gradient {
|
||||
GradientStop{id: conicalGradient_pstart; position: 0.0}
|
||||
GradientStop{id: conicalGradient_pquarter; position: 0.25}
|
||||
GradientStop {id: conicalGradient_phalf; position: 0.5}
|
||||
GradientStop {id: conicalGradient_p3quarter; position: 0.75}
|
||||
GradientStop{id: conicalGradient_pend; position: 1.0}
|
||||
}
|
||||
}
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask{
|
||||
maskSource: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
|
||||
//configs
|
||||
readonly property int linePosition: configs["Line Position"]
|
||||
readonly property real maxRange: configs["Max Range"] / 100
|
||||
readonly property int uDataLen: Math.pow(2, configs["Data Length"])
|
||||
readonly property int dataLength: 64/uDataLen
|
||||
readonly property int channel: configs["Channel"]
|
||||
readonly property bool reverse: configs["Reverse"]
|
||||
readonly property bool rotateFlag: configs["Rotate"]
|
||||
readonly property real rSpeed: configs["Ratate Speed"] / 100
|
||||
readonly property real angle: configs["Angle"]
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: 400/configs["Data Settings"]["Amplitude"]
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
readonly property int total: channel*dataLength
|
||||
|
||||
readonly property real dotGap: 360/total
|
||||
property real offsetAngle: 0
|
||||
property var outerPos: []
|
||||
property var innerPos: []
|
||||
readonly property real degUnit: Math.PI/180
|
||||
|
||||
readonly property real subRatio: 0.2*maxRange
|
||||
readonly property real mainRatio: 1-subRatio*2.5
|
||||
|
||||
readonly property real minLength: Math.min(width, height)
|
||||
readonly property real ratio:minLength*subRatio
|
||||
readonly property real halfWidth: width/2
|
||||
readonly property real halfHeight: height/2
|
||||
readonly property real halfMinLength: minLength/2
|
||||
|
||||
|
||||
onConfigsUpdated: {
|
||||
gradientStyle = configs["Gradient Style"];
|
||||
context.lineWidth = configs["Line Width"];
|
||||
main.color = configs["Main Color"];
|
||||
if (gradientStyle === 1) {
|
||||
radialGradient_pstart.color = configs["Radial Gradient Settings"]["Inside Position Color"];
|
||||
radialGradient_pstart.position = configs["Radial Gradient Settings"]["Inside Position"]/100;
|
||||
radialGradient_pmiddle.color = configs["Radial Gradient Settings"]["Middle Position Color"];
|
||||
radialGradient_pmiddle.position = configs["Radial Gradient Settings"]["Middle Position"]/100;
|
||||
radialGradient_pend.color = configs["Radial Gradient Settings"]["Outside Position Color"];
|
||||
radialGradient_pend.position = configs["Radial Gradient Settings"]["Outside Position"]/100;
|
||||
} else if (gradientStyle === 2) {
|
||||
conicalGradient_pstart.color = configs["Conical Gradient Settings"]["Start Position Color"];
|
||||
conicalGradient_pquarter.color = configs["Conical Gradient Settings"]["Quarter Position Color"];
|
||||
conicalGradient_phalf.color = configs["Conical Gradient Settings"]["Middle Position Color"];
|
||||
conicalGradient_p3quarter.color = configs["Conical Gradient Settings"]["End Position Color"];
|
||||
conicalGradient_pend.color = configs["Conical Gradient Settings"]["Start Position Color"];
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[i*uDataLen+j];
|
||||
|
||||
function createPoint() {
|
||||
outerPos.length = 0;
|
||||
innerPos.length = 0;
|
||||
let deg, deltaR, r1, r2, _rhmLen;
|
||||
_rhmLen = mainRatio*halfMinLength;
|
||||
|
||||
for (let j=0; j < channel; j++) {
|
||||
for (let i=0; i < dataLength; i++) {
|
||||
deg = degUnit*((i+j*dataLength)*dotGap+offsetAngle);
|
||||
deltaR = audioData[reverse*(dataLength-i-1)+(!reverse)*(i+j*dataLength)] * ratio;
|
||||
r1 = _rhmLen+1+deltaR*(linePosition!==2);
|
||||
r2 = _rhmLen-1-deltaR*(linePosition!==1);
|
||||
outerPos.push([halfWidth+Math.cos(deg)*r1,halfHeight+Math.sin(deg)*r1]);
|
||||
innerPos.push([halfWidth+Math.cos(deg)*r2,halfHeight+Math.sin(deg)*r2]);
|
||||
}
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
conicalGradient.rotation = offsetAngle;
|
||||
offsetAngle = rotateFlag ? ((offsetAngle + rSpeed) % 360) : angle;
|
||||
}
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
createPoint();
|
||||
onAudioDataUpdeted: {
|
||||
let normalizing_ratio = autoNormalizing ? data[128] : amplitude;
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=0; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[i*uDataLen+j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[i*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
context.beginPath();
|
||||
context.moveTo(outerPos[0][0], outerPos[0][1]);
|
||||
for(let i=0; i<total; i++) {
|
||||
context.lineTo(outerPos[i][0], outerPos[i][1]);
|
||||
}
|
||||
context.closePath();
|
||||
context.stroke();
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
createPoint();
|
||||
|
||||
context.beginPath();
|
||||
context.moveTo(innerPos[0][0], innerPos[0][1]);
|
||||
for(let i=0; i<total; i++) {
|
||||
context.lineTo(innerPos[i][0], innerPos[i][1]);
|
||||
}
|
||||
context.closePath();
|
||||
context.stroke();
|
||||
context.beginPath();
|
||||
context.moveTo(outerPos[0][0], outerPos[0][1]);
|
||||
for(let i=0; i<total; i++) {
|
||||
context.lineTo(outerPos[i][0], outerPos[i][1]);
|
||||
}
|
||||
context.closePath();
|
||||
context.stroke();
|
||||
|
||||
context.beginPath();
|
||||
for(let i=0; i<total; i++) {
|
||||
context.moveTo(outerPos[i][0], outerPos[i][1]);
|
||||
context.lineTo(innerPos[i][0], innerPos[i][1]);
|
||||
}
|
||||
context.stroke();
|
||||
requestPaint();
|
||||
}
|
||||
context.beginPath();
|
||||
context.moveTo(innerPos[0][0], innerPos[0][1]);
|
||||
for(let i=0; i<total; i++) {
|
||||
context.lineTo(innerPos[i][0], innerPos[i][1]);
|
||||
}
|
||||
context.closePath();
|
||||
context.stroke();
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
context.beginPath();
|
||||
for(let i=0; i<total; i++) {
|
||||
context.moveTo(outerPos[i][0], outerPos[i][1]);
|
||||
context.lineTo(innerPos[i][0], innerPos[i][1]);
|
||||
}
|
||||
context.stroke();
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultValues: {
|
||||
"Version": "1.1.0",
|
||||
"Version": "1.2.0",
|
||||
"Gradient Style": 0,
|
||||
"Radial Gradient Settings": {
|
||||
"Inside Position Color": "#f44336",
|
||||
"Middle Position Color": "#4caf50",
|
||||
"Outside Position Color": "#03a9f4",
|
||||
"Inside Position": 40,
|
||||
"Middle Position": 60,
|
||||
"Outside Position": 80
|
||||
},
|
||||
"Conical Gradient Settings": {
|
||||
"Start Position Color": "#f44336",
|
||||
"Quarter Position Color": "#4caf50",
|
||||
"Middle Position Color": "#03a9f4",
|
||||
"End Position Color": "#ffeb3b"
|
||||
},
|
||||
"Main Color": "#ff4500",
|
||||
"Line Position": 0,
|
||||
"Line Width": 1,
|
||||
"Max Range": 50,
|
||||
"Max Range": 80,
|
||||
"Data Length": 0,
|
||||
"Channel": 2,
|
||||
"Reverse": false,
|
||||
@ -142,9 +212,107 @@ AdvpStyleTemplate {
|
||||
preference: AdvpPreference {
|
||||
version: defaultValues["Version"]
|
||||
|
||||
P.SelectPreference {
|
||||
id: _cfg_gradient_style
|
||||
name: "Gradient Style"
|
||||
label: qsTr("Gradient Style")
|
||||
defaultValue: defaultValues["Gradient Style"]
|
||||
model: [qsTr("None"), qsTr("Radial Gradient"), qsTr("Conical Gradient")]
|
||||
}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Radial Gradient Settings"
|
||||
label: qsTr("Radial Gradient Settings")
|
||||
live: true
|
||||
visible: _cfg_gradient_style.value===1
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Inside Position Color"
|
||||
label: qsTr("Inside Position Color")
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Inside Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Middle Position Color"
|
||||
label: qsTr("Middle Position Color")
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Middle Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Outside Position Color"
|
||||
label: qsTr("Outside Position Color")
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Outside Position Color"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
id: _cfg_gradient_settings_inside_position
|
||||
name: "Inside Position"
|
||||
label: qsTr("Inside Position")
|
||||
from: 0
|
||||
to: 75
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Inside Position"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
id: _cfg_gradient_settings_middle_position
|
||||
name: "Middle Position"
|
||||
label: qsTr("Middle Position")
|
||||
from: _cfg_gradient_settings_inside_position.value + 1
|
||||
to: 90
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Middle Position"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Outside Position"
|
||||
label: qsTr("Outside Position")
|
||||
from: _cfg_gradient_settings_middle_position.value + 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Radial Gradient Settings"]["Outside Position"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Conical Gradient Settings"
|
||||
label: qsTr("Conical Gradient Settings")
|
||||
live: true
|
||||
visible: _cfg_gradient_style.value===2
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Start Position Color"
|
||||
label: qsTr("Start Position Color")
|
||||
defaultValue: defaultValues["Conical Gradient Settings"]["Start Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Quarter Position Color"
|
||||
label: qsTr("Quarter Position Color")
|
||||
defaultValue: defaultValues["Conical Gradient Settings"]["Quarter Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Middle Position Color"
|
||||
label: qsTr("Middle Position Color")
|
||||
defaultValue: defaultValues["Conical Gradient Settings"]["Middle Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "End Position Color"
|
||||
label: qsTr("End Position Color")
|
||||
defaultValue: defaultValues["Conical Gradient Settings"]["End Position Color"]
|
||||
}
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Main Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
visible: !_cfg_gradient_style.value
|
||||
defaultValue: defaultValues["Main Color"]
|
||||
}
|
||||
|
||||
@ -195,8 +363,6 @@ AdvpStyleTemplate {
|
||||
defaultValue: defaultValues["Channel"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
|
||||
@ -1,94 +1,179 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick 2.12
|
||||
import QtGraphicalEffects 1.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api"
|
||||
|
||||
AdvpStyleTemplate {
|
||||
style: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
style: Rectangle {
|
||||
id: main
|
||||
width: widget.width;
|
||||
height: widget.height;
|
||||
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: 400/configs["Data Settings"]["Amplitude"]
|
||||
property bool gradientEnable
|
||||
|
||||
readonly property int uDataLen: Math.pow(2, configs["Data Length"]);
|
||||
readonly property int dataLength: 64/uDataLen
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
readonly property int total: dataLength*2
|
||||
|
||||
readonly property real ux: width/(total+1)
|
||||
readonly property real halfHeight: height/2
|
||||
|
||||
onConfigsUpdated: {
|
||||
//尽量不要使用绑定configs的属性以免造成竞争,若一定要使用推荐使用Qt.callLater(()=>{})
|
||||
context.lineWidth = configs["Line Width"];
|
||||
context.strokeStyle = configs["Line Color"];
|
||||
LinearGradient {
|
||||
id: gradient_mask
|
||||
anchors.fill: parent
|
||||
visible: gradientEnable
|
||||
gradient: Gradient {
|
||||
GradientStop { id: p_start; position: 0.0 }
|
||||
GradientStop { id: p_middle; position: 0.5 }
|
||||
GradientStop { id: p_end; position: 1.0 }
|
||||
}
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
let normalizing_ratio = autoNormalizing ? data[128]*2 : amplitude;
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[63-i*uDataLen-j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask{
|
||||
maskSource: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: 400/configs["Data Settings"]["Amplitude"]
|
||||
|
||||
readonly property int uDataLen: Math.pow(2, configs["Data Length"]);
|
||||
readonly property int dataLength: 64/uDataLen
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
readonly property int total: dataLength*2
|
||||
|
||||
readonly property bool vertical_flag: configs["Direction"]
|
||||
readonly property real halfWidth: vertical_flag ? height/2 : width/2
|
||||
readonly property real halfHeight: vertical_flag ? width/2 : height/2
|
||||
readonly property real ux: halfWidth*2/(total+1)
|
||||
readonly property real _y_dy: centerRotateAngleTangent*halfWidth
|
||||
|
||||
readonly property bool centerRotateFlag: configs["Rotate Settings"]["Center Enable"]
|
||||
readonly property real centerRotateAngleTangent: centerRotateFlag*Math.tan(configs["Rotate Settings"]["Center Angle"]*Math.PI/180)
|
||||
readonly property bool lineRotateFlag: configs["Rotate Settings"]["Line Enable"]
|
||||
readonly property real lineRotateAngleTangent: lineRotateFlag*Math.tan(configs["Rotate Settings"]["Line Angle"]*Math.PI/180)
|
||||
|
||||
readonly property real xOffset: configs["Rotate Settings"]["X Offset"]/100
|
||||
readonly property real yOffset: configs["Rotate Settings"]["Y Offset"]/100
|
||||
readonly property real xScale: configs["Rotate Settings"]["X Scale"]/100
|
||||
readonly property real yScale: configs["Rotate Settings"]["Y Scale"]/100
|
||||
|
||||
onWidthChanged: {
|
||||
gradient_mask.end = Qt.point(width*(configs["Gradient Direction"]!==1), height*(configs["Gradient Direction"]%2));
|
||||
}
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[i*uDataLen+j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
|
||||
onHeightChanged: {
|
||||
gradient_mask.start = Qt.point(0, height*(configs["Gradient Direction"]===2));
|
||||
gradient_mask.end = Qt.point(width*(configs["Gradient Direction"]!==1), height*(configs["Gradient Direction"]%2));
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[63-i*uDataLen-j];
|
||||
|
||||
onConfigsUpdated: {
|
||||
//尽量不要使用绑定configs的属性以免造成竞争,若一定要使用推荐使用Qt.callLater(()=>{})
|
||||
gradientEnable = configs["Enable Gradient"];
|
||||
context.lineWidth = configs["Line Width"];
|
||||
main.color = configs["Line Color"];
|
||||
if (gradientEnable) {
|
||||
gradient_mask.start = Qt.point(0, height*(configs["Gradient Direction"]===2));
|
||||
gradient_mask.end = Qt.point(width*(configs["Gradient Direction"]!==1), height*(configs["Gradient Direction"]%2));
|
||||
p_start.color = configs["Start Position Color"];
|
||||
p_middle.color = configs["Middle Position Color"];
|
||||
p_end.color = configs["End Position Color"];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[i*uDataLen+j];
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
let normalizing_ratio = autoNormalizing ? data[128]*2 : amplitude;
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[63-i*uDataLen-j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[i*uDataLen+j]/normalizing_ratio)) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[63-i*uDataLen-j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[i*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
}
|
||||
}
|
||||
audioData[i] /= (uDataLen * normalizing_ratio);
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
context.beginPath();
|
||||
context.resetTransform();
|
||||
if (vertical_flag) {
|
||||
if (lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(yScale, lineRotateAngleTangent, -centerRotateAngleTangent, xScale, _y_dy+yOffset*height, xOffset*width-lineRotateAngleTangent*(halfHeight));
|
||||
}
|
||||
context.moveTo(halfHeight, 0);
|
||||
|
||||
for (let i=0; i<dataLength*2; i+=2) {
|
||||
context.lineTo(halfHeight*(1+audioData[i]), ux*i);
|
||||
context.lineTo(halfHeight*(1-audioData[i+1]), ux*(i+1));
|
||||
}
|
||||
|
||||
context.lineTo(halfHeight, height);
|
||||
} else {
|
||||
if (lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(xScale, centerRotateAngleTangent, -lineRotateAngleTangent, yScale, xOffset*width+lineRotateAngleTangent*(halfHeight), yOffset*height-_y_dy);
|
||||
}
|
||||
context.moveTo(0, halfHeight);
|
||||
|
||||
for (let i=0; i<dataLength*2; i+=2) {
|
||||
context.lineTo(ux*i, halfHeight*(1+audioData[i]));
|
||||
context.lineTo(ux*(i+1), halfHeight*(1-audioData[i+1]));
|
||||
}
|
||||
|
||||
context.lineTo(width, halfHeight);
|
||||
}
|
||||
context.stroke();
|
||||
requestPaint();
|
||||
}
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
|
||||
context.beginPath();
|
||||
context.moveTo(0, halfHeight);
|
||||
|
||||
for (let i=0; i<dataLength*2; i+=2) {
|
||||
context.lineTo(ux*i, halfHeight*(1+audioData[i]));
|
||||
context.lineTo(ux*(i+1), halfHeight*(1-audioData[i+1]));
|
||||
}
|
||||
|
||||
context.lineTo(width, halfHeight);
|
||||
context.stroke();
|
||||
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultValues: {
|
||||
"Version": "1.1.0",
|
||||
"Line Width": 1,
|
||||
"Version": "1.2.0",
|
||||
"Enable Gradient": false,
|
||||
"Gradient Direction": 0,
|
||||
"Start Position Color": "#f44336",
|
||||
"Middle Position Color": "#4caf50",
|
||||
"End Position Color": "#03a9f4",
|
||||
"Line Color": "#ff4500",
|
||||
"Line Width": 1,
|
||||
"Data Length": 0,
|
||||
"Direction": 0,
|
||||
"Rotate Settings": {
|
||||
"Center Enable": false,
|
||||
"Center Angle": 10,
|
||||
"Line Enable": false,
|
||||
"Line Angle": 10,
|
||||
"X Scale": 100,
|
||||
"Y Scale": 100,
|
||||
"X Offset": 0,
|
||||
"Y Offset": 0
|
||||
},
|
||||
"Data Settings": {
|
||||
"Auto Normalizing": true,
|
||||
"Amplitude": 10,
|
||||
@ -99,6 +184,58 @@ AdvpStyleTemplate {
|
||||
preference: AdvpPreference {
|
||||
version: defaultValues["Version"]
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_enable_gradient
|
||||
name: "Enable Gradient"
|
||||
label: qsTr("Enable Gradient")
|
||||
defaultValue: defaultValues["Enable Gradient"]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Gradient Direction"
|
||||
label: qsTr("Gradient Direction")
|
||||
visible: _cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["Gradient Direction"]
|
||||
model: [qsTr("Horizontal"), qsTr("Vertical"), qsTr("Oblique Upward"), qsTr("Oblique downward")]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Start Position Color"
|
||||
label: qsTr("Start Position Color")
|
||||
visible: _cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["Start Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Middle Position Color"
|
||||
label: qsTr("Middle Position Color")
|
||||
visible: _cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["Middle Position Color"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "End Position Color"
|
||||
label: qsTr("End Position Color")
|
||||
visible: _cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["End Position Color"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Direction"
|
||||
label: qsTr("Direction")
|
||||
defaultValue: defaultValues["Direction"]
|
||||
model: [qsTr("Horizontal"), qsTr("Vertical")]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Line Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
visible: !_cfg_enable_gradient.value
|
||||
defaultValue: defaultValues["Line Color"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Line Width"
|
||||
label: qsTr("Spectrum Line Width")
|
||||
@ -109,14 +246,6 @@ AdvpStyleTemplate {
|
||||
displayValue: value.toFixed(1) + "px"
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Line Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
defaultValue: defaultValues["Line Color"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Data Length"
|
||||
label: qsTr("Spectrum Length")
|
||||
@ -124,6 +253,101 @@ AdvpStyleTemplate {
|
||||
model: [64, 32, 16, 8]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Rotate Settings"
|
||||
label: qsTr("Rotate Settings")
|
||||
live: true
|
||||
icon.name: "regular:\uf1de"
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_Rotate_Center_Enable
|
||||
name: "Center Enable"
|
||||
label: qsTr("Rotate Center Line")
|
||||
defaultValue: defaultValues["Rotate Settings"]["Center Enable"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Center Angle"
|
||||
label: qsTr("Angle of Center Line")
|
||||
enabled: _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: -45
|
||||
to: 45
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["Center Angle"]
|
||||
displayValue: value + "°"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_Rotate_Line_Enable
|
||||
name: "Line Enable"
|
||||
label: qsTr("Rotate Spectrum Line")
|
||||
defaultValue: defaultValues["Rotate Settings"]["Line Enable"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Line Angle"
|
||||
label: qsTr("Angle of Spectrum Line")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value
|
||||
from: -45
|
||||
to: 45
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["Line Angle"]
|
||||
displayValue: value + "°"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "X Scale"
|
||||
label: qsTr("Scale of Center Line Direction")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value || _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["X Scale"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Y Scale"
|
||||
label: qsTr("Scale of Spectrum Line Direction")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value || _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["Y Scale"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "X Offset"
|
||||
label: qsTr("Offset of Center Line Direction")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value || _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: -100
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["X Offset"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Y Offset"
|
||||
label: qsTr("Offset of Spectrum Line Direction")
|
||||
enabled: _cfg_preset_line_Rotate_Line_Enable.value || _cfg_preset_line_Rotate_Center_Enable.value
|
||||
from: -100
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Rotate Settings"]["Y Offset"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Data Settings"
|
||||
label: qsTr("Data Settings")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user