forked from Mashiro_Sorata/ADV-Plugin
mashiros
2 years ago
23 changed files with 1221 additions and 715 deletions
Binary file not shown.
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" |
||||
} |
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> |
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> |
@ -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) |
||||
|
||||
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 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); |
||||
style: Rectangle { |
||||
id: main |
||||
width: widget.width; |
||||
height: widget.height; |
||||
|
||||
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 |
||||
|
||||
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 } |
||||
} |
||||
} |
||||
|
||||
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); |
||||
} |
||||
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); |
||||
} 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); |
||||
} |
||||
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]; |
||||
} |
||||
} |
||||
|
||||
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)); |
||||
} |
||||
audioData[i] /= (uDataLen * normalizing_ratio); |
||||
centerLine.requestPaint(); |
||||
} |
||||
for(let i=dataLength; i<r_stop; i++) { |
||||
audioData[i] = 0; |
||||
for(let j=0; j<uDataLen; j++) { |
||||
audioData[i] += data[i*uDataLen+j]; |
||||
|
||||
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)); |
||||
} |
||||
audioData[i] /= (uDataLen * normalizing_ratio); |
||||
centerLine.requestPaint(); |
||||
} |
||||
} |
||||
|
||||
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); |
||||
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(); |
||||
} |
||||
if (centerLineFlag) { |
||||
context.fillStyle = center_color; |
||||
context.fillRect(0, halfHeight-_y_dy, width, 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); |
||||
} |
||||
} |
||||
|
||||
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(); |
||||
} |
||||
} |
||||
|
||||
context.fill(); |
||||
requestPaint(); |
||||
} |
||||
onCompleted: { |
||||
for (let i = 0; i < 128; i++) { |
||||
audioData[i] = 0; |
||||
} |