- 利用QtObject整合Style.qml与Config.qml,重构ADVP接口
- 优化样式初始化过程与设置项存储 - 规范文件命名
This commit is contained in:
parent
938b522082
commit
613857c67f
BIN
Locales/ja_JP.qm
BIN
Locales/ja_JP.qm
Binary file not shown.
BIN
Locales/zh.qm
BIN
Locales/zh.qm
Binary file not shown.
BIN
Locales/zh_CN.qm
BIN
Locales/zh_CN.qm
Binary file not shown.
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="styles">{"index":3}</value>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/circle#Style.qml"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/circle#Style.qml">{"__version":"1.0.0","__cfg_height":740,"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="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>
|
||||
</map>
|
||||
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="styles">{"index":1}</value>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/gradient_line#Style.qml"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/gradient_line#Style.qml">{"__version":"1.0.0","__cfg_height":660,"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,"Reverse":false,"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="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,"Reverse":false,"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,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/line#Style.qml">{"__version":"1.0.0","__cfg_height":580,"Center Line":true,"Center Color":"#ff4500","Line Color":"#ff4500","Line Position":0,"Data Length":0,"Channel":2,"Reverse":false,"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="styles">{"index":0}</value>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/line#Style.qml"</value>
|
||||
<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,"Reverse":false,"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="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/line"</value>
|
||||
</map>
|
||||
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="styles">{"index":5}</value>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/ordinal_scale_ui_bottom#Style.qml"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/ordinal_scale_ui_bottom#Style.qml">{"__version":"1.0.0","__cfg_height":710,"Bass Color":"#dc143c","Alto Color":"#f8f8ff","Treble Color":"#4169e1","Bass AM":100,"Alto AM":150,"Treble AM":200,"Static AM":25,"Speed":20,"Data Settings":{"Auto Normalizing":true,"Amplitude":10}}</value>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/ordinal_scale_ui_bottom"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/ordinal_scale_ui_bottom">{"Bass Color":"#dc143c","Alto Color":"#f8f8ff","Treble Color":"#4169e1","Bass AM":100,"Alto AM":150,"Treble AM":200,"Static AM":25,"Speed":20,"Data Settings":{"Auto Normalizing":true,"Amplitude":10}}</value>
|
||||
</map>
|
||||
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="styles">{"index":4}</value>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/solidcircle#Style.qml"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/solidcircle#Style.qml">{"__version":"1.0.0","__cfg_height":740,"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="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>
|
||||
</map>
|
||||
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map>
|
||||
<value name="styles">{"index":2}</value>
|
||||
<value name="current_style">"nvg://advp.widget.mashiros.top/advp-style-preset/waves#Style.qml"</value>
|
||||
<value name="nvg://advp.widget.mashiros.top/advp-style-preset/waves#Style.qml">{"__version":"1.0.0","__cfg_height":580,"Line Width":1,"Line Color":"#ff4500","Data Settings":{"Auto Normalizing":true,"Amplitude":10}}</value>
|
||||
<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>
|
||||
</map>
|
||||
26
package.json
26
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "top.mashiros.widget.advp",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
|
||||
"title": {
|
||||
"en": "ADV Plugin",
|
||||
@ -59,7 +59,7 @@
|
||||
"zh_TW": "預置 線",
|
||||
"ja": "プリセット 線"
|
||||
},
|
||||
"entry": "./styles/Preset_line"
|
||||
"entry": "./styles/Preset_line/Style.qml"
|
||||
},
|
||||
{
|
||||
"location": "/advp-style-preset/gradient_line",
|
||||
@ -70,7 +70,7 @@
|
||||
"zh_TW": "預置 漸變線",
|
||||
"ja": "プリセット グラデーションライン"
|
||||
},
|
||||
"entry": "./styles/Preset_gradient_line"
|
||||
"entry": "./styles/Preset_gradient_line/Style.qml"
|
||||
},
|
||||
{
|
||||
"location": "/advp-style-preset/waves",
|
||||
@ -81,7 +81,7 @@
|
||||
"zh_TW": "預置 波浪",
|
||||
"ja": "プリセット 波浪"
|
||||
},
|
||||
"entry": "./styles/Preset_waves"
|
||||
"entry": "./styles/Preset_waves/Style.qml"
|
||||
},
|
||||
{
|
||||
"location": "/advp-style-preset/circle",
|
||||
@ -92,7 +92,7 @@
|
||||
"zh_TW": "預置 圓",
|
||||
"ja": "プリセット 円"
|
||||
},
|
||||
"entry": "./styles/Preset_circle"
|
||||
"entry": "./styles/Preset_circle/Style.qml"
|
||||
},
|
||||
{
|
||||
"location": "/advp-style-preset/solidcircle",
|
||||
@ -103,7 +103,7 @@
|
||||
"zh_TW": "預置 實心圓",
|
||||
"ja": "プリセット 固形円"
|
||||
},
|
||||
"entry": "./styles/Preset_solidcircle"
|
||||
"entry": "./styles/Preset_solidcircle/Style.qml"
|
||||
},
|
||||
{
|
||||
"location": "/advp-style-preset/ordinal_scale_ui_bottom",
|
||||
@ -114,10 +114,10 @@
|
||||
"zh_TW": "預置 序列之爭底部UI",
|
||||
"ja": "プリセット オーディナル・スケール- UI 下部"
|
||||
},
|
||||
"entry": "./styles/Preset_Ordinal_Scale_UI_bottom"
|
||||
"entry": "./styles/Preset_Ordinal_Scale_UI_bottom/Style.qml"
|
||||
},
|
||||
{
|
||||
"location": "/preset/advp-style-preset_line",
|
||||
"location": "/preset/advp-style-preset/line",
|
||||
"catalog": "preset/widget",
|
||||
"title": {
|
||||
"en": "ADV Preset Line",
|
||||
@ -129,7 +129,7 @@
|
||||
"entry": "Presets/Line/preset.json"
|
||||
},
|
||||
{
|
||||
"location": "/preset/advp-style-preset_gradient_line",
|
||||
"location": "/preset/advp-style-preset/gradient_line",
|
||||
"catalog": "preset/widget",
|
||||
"title": {
|
||||
"en": "ADV Preset Gradient Line",
|
||||
@ -141,7 +141,7 @@
|
||||
"entry": "Presets/Gradient_Line/preset.json"
|
||||
},
|
||||
{
|
||||
"location": "/preset/advp-style-preset_waves",
|
||||
"location": "/preset/advp-style-preset/waves",
|
||||
"catalog": "preset/widget",
|
||||
"title": {
|
||||
"en": "ADV Preset Waves",
|
||||
@ -153,7 +153,7 @@
|
||||
"entry": "Presets/Waves/preset.json"
|
||||
},
|
||||
{
|
||||
"location": "/preset/advp-style-preset_circle",
|
||||
"location": "/preset/advp-style-preset/circle",
|
||||
"catalog": "preset/widget",
|
||||
"title": {
|
||||
"en": "ADV Preset Circle",
|
||||
@ -165,7 +165,7 @@
|
||||
"entry": "Presets/Circle/preset.json"
|
||||
},
|
||||
{
|
||||
"location": "/preset/advp-style-preset_solidcircle",
|
||||
"location": "/preset/advp-style-preset/solidcircle",
|
||||
"catalog": "preset/widget",
|
||||
"title": {
|
||||
"en": "ADV Preset Solid-circle",
|
||||
@ -177,7 +177,7 @@
|
||||
"entry": "Presets/Solidcircle/preset.json"
|
||||
},
|
||||
{
|
||||
"location": "/preset/advp-style-preset_ordinal_scale_ui_bottom",
|
||||
"location": "/preset/advp-style-preset/ordinal_scale_ui_bottom",
|
||||
"catalog": "preset/widget",
|
||||
"title": {
|
||||
"en": "ADV Preset Ordinal Scale UI bottom",
|
||||
|
||||
@ -9,7 +9,6 @@ import NERvGear 1.0 as NVG
|
||||
Item {
|
||||
readonly property var styles: []
|
||||
readonly property var stylesURL: []
|
||||
readonly property var stylesCFG: []
|
||||
|
||||
property int widgetsNum: 0
|
||||
|
||||
@ -103,20 +102,9 @@ Item {
|
||||
return 0;
|
||||
});
|
||||
resource_list.forEach(function (resource) {
|
||||
let name = resource.title;
|
||||
let styleURL = "";
|
||||
let styleCFG = "";
|
||||
resource.files().forEach(function (file) {
|
||||
if (file.entry === "Style.qml") {
|
||||
styleURL = String(file.url);
|
||||
} else if (file.entry === "Config.qml") {
|
||||
styleCFG = String(file.url);
|
||||
}
|
||||
});
|
||||
if (styleURL && stylesURL.indexOf(styleURL) === -1) {
|
||||
styles.push(name);
|
||||
stylesURL.push(styleURL);
|
||||
stylesCFG.push(styleCFG);
|
||||
if (resource.url && stylesURL.indexOf(resource.url.toString()) === -1) {
|
||||
styles.push(resource.title);
|
||||
stylesURL.push(resource.url.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -124,7 +112,6 @@ Item {
|
||||
function updateStyleList() {
|
||||
styles.length = 0;
|
||||
stylesURL.length = 0;
|
||||
stylesCFG.length = 0;
|
||||
const preset_list = NVG.Resources.filter(/advp.widget.mashiros.top/, /top.mashiros.advp-style/);
|
||||
parse_resource(preset_list, true);
|
||||
const third_list = NVG.Resources.filter(/.*/, /top.mashiros.advp-style/);
|
||||
|
||||
39
qml/Main.qml
39
qml/Main.qml
@ -15,27 +15,34 @@ T.Widget {
|
||||
|
||||
editing: styleDialog.active
|
||||
|
||||
property bool initial: true
|
||||
|
||||
function setStyleURL(url) {
|
||||
styleLoader.source = url;
|
||||
}
|
||||
property Component style
|
||||
property Component preference
|
||||
property var defaultValues
|
||||
|
||||
Loader {
|
||||
id: styleDialog
|
||||
active: false
|
||||
visible: false
|
||||
sourceComponent: StylePreferences {
|
||||
transientParent: widget.NVG.View.window
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: styleObjectLoader
|
||||
active: widget.NVG.View.exposed
|
||||
enabled: true
|
||||
source: Qt.resolvedUrl(widget.settings.current_style)
|
||||
|
||||
onLoaded: {
|
||||
if(initial) {
|
||||
styleDialog.active = false;
|
||||
styleDialog.visible = true;
|
||||
initial = false;
|
||||
} else {
|
||||
item.visible = true;
|
||||
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]["__cfg_height"];
|
||||
delete widget.settings[widget.settings.current_style]["Version"];
|
||||
widget.settings[widget.settings.current_style] = Object.assign(defaultValues, widget.settings[widget.settings.current_style]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -44,7 +51,7 @@ T.Widget {
|
||||
id: styleLoader
|
||||
active: widget.NVG.View.exposed
|
||||
enabled: true
|
||||
source: ""
|
||||
sourceComponent: style
|
||||
}
|
||||
|
||||
menu: Menu {
|
||||
@ -53,14 +60,16 @@ T.Widget {
|
||||
enabled: !styleDialog.active
|
||||
onTriggered: {
|
||||
Common.updateStyleList();
|
||||
styleDialog.active = true
|
||||
styleDialog.active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
styleDialog.active = true;
|
||||
Common.widgetsNum++;
|
||||
if ((!widget.settings.current_style) || (Common.stylesURL.indexOf(widget.settings.current_style) === -1)) {
|
||||
widget.settings.current_style = Common.stylesURL[0];
|
||||
}
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
|
||||
@ -12,7 +12,7 @@ import "."
|
||||
NVG.Window {
|
||||
id: window
|
||||
title: qsTr("ADV-Plugin: Settings")
|
||||
visible: false
|
||||
visible: true
|
||||
minimumWidth: 480
|
||||
minimumHeight: 580
|
||||
width: minimumWidth
|
||||
@ -25,8 +25,8 @@ NVG.Window {
|
||||
}
|
||||
}
|
||||
|
||||
property var configuration
|
||||
property var old_style_cfg
|
||||
property int last_style_index
|
||||
|
||||
Page {
|
||||
id: cfg_page
|
||||
@ -38,22 +38,15 @@ NVG.Window {
|
||||
standardButtons: Dialog.Save | Dialog.Reset
|
||||
|
||||
onAccepted: {
|
||||
configuration = rootPreference.save();
|
||||
let index = configuration["index"];
|
||||
widget.settings[Common.stylesURL[index]] = configuration[Common.stylesURL[index]];
|
||||
delete configuration[Common.stylesURL[index]];
|
||||
widget.settings.styles = configuration;
|
||||
widget.settings.current_style = Common.stylesURL[index];
|
||||
let cfg = rootPreference.save();
|
||||
widget.settings[widget.settings.current_style] = cfg[widget.settings.current_style];
|
||||
styleDialog.active = false;
|
||||
}
|
||||
|
||||
onReset: {
|
||||
styleLoader.load();
|
||||
stylePreferenceLoader.load();
|
||||
let cfg = rootPreference.save();
|
||||
let index = cfg["index"];
|
||||
widget.settings[Common.stylesURL[index]] = cfg[Common.stylesURL[index]];
|
||||
widget.setStyleURL("");
|
||||
widget.setStyleURL(Qt.resolvedUrl(Common.stylesURL[widget.settings.styles["index"]]));
|
||||
widget.settings[widget.settings.current_style] = cfg[widget.settings.current_style];
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,18 +75,13 @@ NVG.Window {
|
||||
label: qsTr("Configuration")
|
||||
|
||||
onPreferenceEdited: {
|
||||
let cfg = rootPreference.save();
|
||||
let index = cfg["index"];
|
||||
if (widget.settings.styles["index"] !== index) {
|
||||
widget.setStyleURL("");
|
||||
widget.settings[Common.stylesURL[widget.settings.styles["index"]]] = old_style_cfg;
|
||||
old_style_cfg = widget.settings[Common.stylesURL[index]];
|
||||
if (widget.settings.current_style !== Common.stylesURL[styleList.value]) {
|
||||
widget.settings[widget.settings.current_style] = old_style_cfg;
|
||||
old_style_cfg = widget.settings[Common.stylesURL[styleList.value]];
|
||||
widget.settings.current_style = Common.stylesURL[styleList.value];
|
||||
}
|
||||
|
||||
widget.settings[Common.stylesURL[index]] = cfg[Common.stylesURL[index]];
|
||||
delete cfg[Common.stylesURL[index]];
|
||||
widget.settings.styles = cfg;
|
||||
widget.setStyleURL(Qt.resolvedUrl(Common.stylesURL[index]));
|
||||
let cfg = rootPreference.save();
|
||||
widget.settings[widget.settings.current_style] = cfg[widget.settings.current_style];
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
@ -108,24 +96,21 @@ NVG.Window {
|
||||
P.Separator {}
|
||||
|
||||
P.PreferenceLoader {
|
||||
id: styleLoader
|
||||
name: Common.stylesURL[styleList.value]
|
||||
source: Qt.resolvedUrl(Common.stylesCFG[styleList.value])
|
||||
id: stylePreferenceLoader
|
||||
name: widget.settings.current_style
|
||||
sourceComponent: preference
|
||||
onLoaded: {
|
||||
let cfg = save();
|
||||
if (!widget.settings[Common.stylesURL[styleList.value]]) {
|
||||
widget.settings[Common.stylesURL[styleList.value]] = cfg;
|
||||
} else if(widget.settings[Common.stylesURL[styleList.value]]["__version"] === cfg["__version"]) {
|
||||
load(widget.settings[Common.stylesURL[styleList.value]]);
|
||||
} else {
|
||||
widget.settings[Common.stylesURL[styleList.value]] = cfg;
|
||||
}
|
||||
load(widget.settings[widget.settings.current_style]);
|
||||
window.minimumHeight = cfg["__cfg_height"];
|
||||
}
|
||||
|
||||
onContentItemChanged: {
|
||||
if(contentItem) {
|
||||
contentItem.label = Common.styles[styleList.value];
|
||||
let index = Common.stylesURL.indexOf(widget.settings.current_style);
|
||||
if (index === -1)
|
||||
index = 0;
|
||||
contentItem.label = Common.styles[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,30 +118,14 @@ NVG.Window {
|
||||
P.Separator {}
|
||||
|
||||
Component.onCompleted: {
|
||||
if(!widget.settings.styles) {
|
||||
configuration = rootPreference.save();
|
||||
let index = configuration["index"];
|
||||
widget.settings[Common.stylesURL[index]] = configuration[Common.stylesURL[index]];
|
||||
old_style_cfg = configuration[Common.stylesURL[index]];
|
||||
delete configuration[Common.stylesURL[index]];
|
||||
widget.settings.current_style = Common.stylesURL[index];
|
||||
widget.settings.styles = configuration;
|
||||
last_style_index = Common.stylesURL.indexOf(widget.settings.current_style);
|
||||
if (last_style_index === -1) {
|
||||
last_style_index = 0;
|
||||
widget.settings.current_style = Common.stylesURL[0];
|
||||
}
|
||||
|
||||
let index = Common.stylesURL.indexOf(widget.settings.current_style);
|
||||
if (index === -1) {
|
||||
index = 0;
|
||||
widget.settings.current_style = Common.stylesURL[index];
|
||||
}
|
||||
|
||||
widget.settings.styles["index"] = index;
|
||||
widget.setStyleURL(Qt.resolvedUrl(Common.stylesURL[widget.settings.styles["index"]]));
|
||||
|
||||
rootPreference.load(widget.settings.styles);
|
||||
configuration = widget.settings.styles;
|
||||
old_style_cfg = widget.settings[Common.stylesURL[index]];
|
||||
|
||||
styleLoader.load(widget.settings[Common.stylesURL[index]]);
|
||||
rootPreference.load({"index": last_style_index});
|
||||
old_style_cfg = widget.settings[widget.settings.current_style];
|
||||
stylePreferenceLoader.load(widget.settings[widget.settings.current_style]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,10 +134,8 @@ NVG.Window {
|
||||
}
|
||||
|
||||
onClosing: {
|
||||
widget.setStyleURL("");
|
||||
widget.settings[Common.stylesURL[widget.settings.styles["index"]]] = old_style_cfg;
|
||||
widget.settings.styles = configuration;
|
||||
widget.setStyleURL(Qt.resolvedUrl(Common.stylesURL[widget.settings.styles["index"]]));
|
||||
widget.settings[widget.settings.current_style] = old_style_cfg;
|
||||
widget.settings.current_style = Common.stylesURL[last_style_index]
|
||||
styleDialog.active = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ Canvas {
|
||||
|
||||
signal audioDataUpdeted(var data)
|
||||
signal configsUpdated()
|
||||
property var configs: widget.settings[Common.stylesURL[widget.settings.styles["index"]]]
|
||||
readonly property var configs: widget.settings[widget.settings.current_style] ?? defaultValues
|
||||
|
||||
onConfigsChanged: {
|
||||
if (context) {
|
||||
@ -9,7 +9,7 @@ P.DialogPreference {
|
||||
property int cfg_height: 580
|
||||
|
||||
P.TextFieldPreference {
|
||||
name: "__version"
|
||||
name: "Version"
|
||||
visible: false
|
||||
enabled: false
|
||||
defaultValue: version
|
||||
@ -39,5 +39,5 @@ P.DialogPreference {
|
||||
}
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
P.Separator {visible: version}
|
||||
}
|
||||
9
qml/api/AdvpStyleTemplate.qml
Normal file
9
qml/api/AdvpStyleTemplate.qml
Normal file
@ -0,0 +1,9 @@
|
||||
import QtQuick 2.12
|
||||
|
||||
QtObject {
|
||||
property Component style
|
||||
|
||||
property var defaultValues
|
||||
|
||||
property Component preference
|
||||
}
|
||||
@ -1,111 +0,0 @@
|
||||
import QtQuick 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api" //导入CfgAPI.qml
|
||||
|
||||
CfgAPI {
|
||||
version: "1.0.0"
|
||||
cfg_height: 710
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Bass Color"
|
||||
label: qsTr("Bass Line Color")
|
||||
defaultValue: "#DC143C"
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Alto Color"
|
||||
label: qsTr("Alto Line Color")
|
||||
defaultValue: "#F8F8FF"
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Treble Color"
|
||||
label: qsTr("Treble Line Color")
|
||||
defaultValue: "#4169E1"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Bass AM"
|
||||
label: qsTr("Bass Amplitude")
|
||||
from: 10
|
||||
to: 300
|
||||
stepSize: 5
|
||||
defaultValue: 100
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Alto AM"
|
||||
label: qsTr("Alto Amplitude")
|
||||
from: 10
|
||||
to: 300
|
||||
stepSize: 5
|
||||
defaultValue: 150
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Treble AM"
|
||||
label: qsTr("Treble Amplitude")
|
||||
from: 10
|
||||
to: 300
|
||||
stepSize: 5
|
||||
defaultValue: 200
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Static AM"
|
||||
label: qsTr("Static Amplitude")
|
||||
from: 5
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: 15
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Speed"
|
||||
label: qsTr("Wave Speed")
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: 20
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Data Settings"
|
||||
label: qsTr("Data Settings")
|
||||
live: true
|
||||
icon.name: "regular:\uf1de"
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_osui_dataSettings_autoNormalizing
|
||||
name: "Auto Normalizing"
|
||||
label: qsTr("Auto Normalizing")
|
||||
defaultValue: true
|
||||
}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Amplitude"
|
||||
label: qsTr("Amplitude Ratio")
|
||||
enabled: !_cfg_preset_osui_dataSettings_autoNormalizing.value
|
||||
message: "1 to 100"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: true
|
||||
from: 1
|
||||
to: 100
|
||||
defaultValue: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -1,139 +0,0 @@
|
||||
import QtQuick 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api" //导入CfgAPI.qml
|
||||
|
||||
CfgAPI {
|
||||
version: "1.0.0"
|
||||
cfg_height: 740
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Main Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
defaultValue: "#FF4500"
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Line Position"
|
||||
label: qsTr("Spectrum Line Position")
|
||||
defaultValue: 0
|
||||
model: [qsTr("Both"), qsTr("Outside"), qsTr("Inside")]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Line Width"
|
||||
label: qsTr("Spectrum Line Width")
|
||||
from: 0.1
|
||||
to: 10
|
||||
stepSize: 0.1
|
||||
defaultValue: 1
|
||||
displayValue: value.toFixed(1) + "px"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Max Range"
|
||||
label: qsTr("Max Amplitude")
|
||||
from: 0
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: 50
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Data Length"
|
||||
label: qsTr("Spectrum Length")
|
||||
defaultValue: 0
|
||||
model: [64, 32, 16, 8]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Channel"
|
||||
label: qsTr("Channel")
|
||||
message: "1 to 2"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: false
|
||||
from: 1
|
||||
to: 2
|
||||
defaultValue: 2
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
defaultValue: false
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_rotate
|
||||
name: "Rotate"
|
||||
label: qsTr("Auto Rotate")
|
||||
defaultValue: false
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Ratate Speed"
|
||||
label: qsTr("Ratate Speed")
|
||||
enabled: _cfg_preset_line_rotate.value
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: 10
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Angle"
|
||||
label: qsTr("Initial Angle")
|
||||
message: "0 to 359"
|
||||
enabled: !_cfg_preset_line_rotate.value
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: true
|
||||
from: 0
|
||||
to: 359
|
||||
defaultValue: 0
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Data Settings"
|
||||
label: qsTr("Data Settings")
|
||||
live: true
|
||||
icon.name: "regular:\uf1de"
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_circle_dataSettings_autoNormalizing
|
||||
name: "Auto Normalizing"
|
||||
label: qsTr("Auto Normalizing")
|
||||
defaultValue: true
|
||||
}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Amplitude"
|
||||
label: qsTr("Amplitude Ratio")
|
||||
enabled: !_cfg_preset_circle_dataSettings_autoNormalizing.value
|
||||
message: "1 to 100"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: true
|
||||
from: 1
|
||||
to: 100
|
||||
defaultValue: 10
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Unit Style"
|
||||
label: qsTr("Display Style")
|
||||
defaultValue: 0
|
||||
model: [qsTr("Linear"), qsTr("Decibel")]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,132 +1,286 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api"
|
||||
|
||||
StyleAPI {
|
||||
readonly property var audioData: new Array(128)
|
||||
AdvpStyleTemplate {
|
||||
style: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
|
||||
//configs
|
||||
readonly property string color: configs["Main Color"]
|
||||
readonly property int linePosition: configs["Line Position"]
|
||||
readonly property real lineWidth: configs["Line Width"]
|
||||
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: configs["Data Settings"]["Amplitude"] / 400
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
//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: configs["Data Settings"]["Amplitude"] / 400
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
readonly property int total: channel*dataLength
|
||||
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 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 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
|
||||
readonly property real logAmplitude: Math.log10(amplitude)
|
||||
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
|
||||
readonly property real logAmplitude: Math.log10(amplitude)
|
||||
|
||||
|
||||
onConfigsUpdated: {
|
||||
context.lineWidth = lineWidth;
|
||||
context.strokeStyle = color;
|
||||
}
|
||||
|
||||
function getPos(r, deg) {
|
||||
return [halfWidth+Math.cos(deg)*r,halfHeight+Math.sin(deg)*r];
|
||||
}
|
||||
|
||||
function createPoint() {
|
||||
outerPos = [];
|
||||
innerPos = [];
|
||||
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(getPos(r1, deg));
|
||||
innerPos.push(getPos(r2, deg));
|
||||
}
|
||||
onConfigsUpdated: {
|
||||
context.lineWidth = configs["Line Width"];
|
||||
context.strokeStyle = configs["Main Color"];
|
||||
}
|
||||
offsetAngle = rotateFlag ? ((offsetAngle + rSpeed) % 360) : angle;
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
if(autoNormalizing) {
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
let logPeak = Math.log10(data[128]);
|
||||
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])-logPeak) + 1.0);
|
||||
function getPos(r, deg) {
|
||||
return [halfWidth+Math.cos(deg)*r,halfHeight+Math.sin(deg)*r];
|
||||
}
|
||||
|
||||
function createPoint() {
|
||||
outerPos = [];
|
||||
innerPos = [];
|
||||
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(getPos(r1, deg));
|
||||
innerPos.push(getPos(r2, deg));
|
||||
}
|
||||
}
|
||||
offsetAngle = rotateFlag ? ((offsetAngle + rSpeed) % 360) : angle;
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
if(autoNormalizing) {
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
let logPeak = Math.log10(data[128]);
|
||||
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])-logPeak) + 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] / data[128];
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
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] / data[128];
|
||||
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.35 * (Math.log10(data[i*uDataLen+j])+logAmplitude) + 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] * amplitude;
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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.35 * (Math.log10(data[i*uDataLen+j])+logAmplitude) + 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] * amplitude;
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
createPoint();
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
createPoint();
|
||||
|
||||
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.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();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
context.stroke();
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
defaultValues: {
|
||||
"Version": "1.0.0",
|
||||
"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
|
||||
}
|
||||
}
|
||||
|
||||
preference: AdvpPreference {
|
||||
version: defaultValues["Version"]
|
||||
cfg_height: 740
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Main Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
defaultValue: defaultValues["Main Color"]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Line Position"
|
||||
label: qsTr("Spectrum Line Position")
|
||||
defaultValue: defaultValues["Line Position"]
|
||||
model: [qsTr("Both"), qsTr("Outside"), qsTr("Inside")]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Line Width"
|
||||
label: qsTr("Spectrum Line Width")
|
||||
from: 0.1
|
||||
to: 10
|
||||
stepSize: 0.1
|
||||
defaultValue: defaultValues["Line Width"]
|
||||
displayValue: value.toFixed(1) + "px"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Max Range"
|
||||
label: qsTr("Max Amplitude")
|
||||
from: 0
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Max Range"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Data Length"
|
||||
label: qsTr("Spectrum Length")
|
||||
defaultValue: defaultValues["Data Length"]
|
||||
model: [64, 32, 16, 8]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Channel"
|
||||
label: qsTr("Channel")
|
||||
message: "1 to 2"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: false
|
||||
from: 1
|
||||
to: 2
|
||||
defaultValue: defaultValues["Channel"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
defaultValue: defaultValues["Reverse"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_rotate
|
||||
name: "Rotate"
|
||||
label: qsTr("Auto Rotate")
|
||||
defaultValue: defaultValues["Rotate"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Ratate Speed"
|
||||
label: qsTr("Ratate Speed")
|
||||
enabled: _cfg_preset_line_rotate.value
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Ratate Speed"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Angle"
|
||||
label: qsTr("Initial Angle")
|
||||
message: "0 to 359"
|
||||
enabled: !_cfg_preset_line_rotate.value
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: true
|
||||
from: 0
|
||||
to: 359
|
||||
defaultValue: defaultValues["Angle"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Data Settings"
|
||||
label: qsTr("Data Settings")
|
||||
live: true
|
||||
icon.name: "regular:\uf1de"
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_circle_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_circle_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,161 +0,0 @@
|
||||
import QtQuick 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api" //导入CfgAPI.qml
|
||||
|
||||
CfgAPI {
|
||||
version: "1.0.0"
|
||||
cfg_height: 660
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Gradient Direction"
|
||||
label: qsTr("Gradient Direction")
|
||||
defaultValue: 0
|
||||
model: [qsTr("Horizontal"), qsTr("Vertical"), qsTr("Oblique Upward"), qsTr("Oblique downward")]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Start Position Color"
|
||||
label: qsTr("Start Position Color")
|
||||
defaultValue: "#f44336"
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Middle Position Color"
|
||||
label: qsTr("Middle Position Color")
|
||||
defaultValue: "#4caf50"
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "End Position Color"
|
||||
label: qsTr("End Position Color")
|
||||
defaultValue: "#03a9f4"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Center Line"
|
||||
label: qsTr("Show Center Line")
|
||||
defaultValue: true
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Line Position"
|
||||
label: qsTr("Spectrum Line Position")
|
||||
defaultValue: 0
|
||||
model: [qsTr("Both"), qsTr("Up"), qsTr("Down")]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Data Length"
|
||||
label: qsTr("Spectrum Length")
|
||||
defaultValue: 0
|
||||
model: [64, 32, 16, 8]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SpinPreference {
|
||||
id: _cfg_preset_line_Channel
|
||||
name: "Channel"
|
||||
label: qsTr("Channel")
|
||||
message: "1 to 2"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: false
|
||||
from: 1
|
||||
to: 2
|
||||
defaultValue: 2
|
||||
}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
enabled: _cfg_preset_line_Channel.value === 1
|
||||
defaultValue: false
|
||||
}
|
||||
|
||||
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: false
|
||||
}
|
||||
|
||||
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: 10
|
||||
displayValue: value + "°"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_Rotate_Line_Enable
|
||||
name: "Line Enable"
|
||||
label: qsTr("Rotate Spectrum Line")
|
||||
defaultValue: false
|
||||
}
|
||||
|
||||
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: 10
|
||||
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: true
|
||||
}
|
||||
|
||||
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: 10
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Unit Style"
|
||||
label: qsTr("Display Style")
|
||||
defaultValue: 0
|
||||
model: [qsTr("Linear"), qsTr("Decibel")]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,187 +1,367 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import QtGraphicalEffects 1.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api" //导入CfgAPI.qml
|
||||
import "../../qml/api"
|
||||
|
||||
Rectangle {
|
||||
width: widget.width;
|
||||
height: widget.height;
|
||||
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: StyleAPI {
|
||||
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 reverse: configs["Reverse"]
|
||||
readonly property bool centerRotateFlag: configs["Rotate Settings"]["Center Enable"]
|
||||
readonly property real centerRotateAngle: configs["Rotate Settings"]["Center Angle"]
|
||||
readonly property bool lineRotateFlag: configs["Rotate Settings"]["Line Enable"]
|
||||
readonly property real lineRotateAngle: configs["Rotate Settings"]["Line Angle"]
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: configs["Data Settings"]["Amplitude"] / 400.0
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
property int total: channel * dataLength
|
||||
property real logAmplitude: Math.log10(amplitude)
|
||||
property real degUnit: Math.PI / 180
|
||||
|
||||
property real halfWidth: width/2
|
||||
property real halfHeight: height/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"];
|
||||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
if(autoNormalizing) {
|
||||
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[64-i*uDataLen-j-1]/data[128])) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
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 reverse: configs["Reverse"]
|
||||
readonly property bool centerRotateFlag: configs["Rotate Settings"]["Center Enable"]
|
||||
readonly property real centerRotateAngle: configs["Rotate Settings"]["Center Angle"]
|
||||
readonly property bool lineRotateFlag: configs["Rotate Settings"]["Line Enable"]
|
||||
readonly property real lineRotateAngle: configs["Rotate Settings"]["Line Angle"]
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: configs["Data Settings"]["Amplitude"] / 400.0
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
property int total: channel * dataLength
|
||||
property real logAmplitude: Math.log10(amplitude)
|
||||
property real degUnit: Math.PI / 180
|
||||
|
||||
property real halfWidth: width/2
|
||||
property real halfHeight: height/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: {
|
||||
if(autoNormalizing) {
|
||||
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[64+(i-dataLength)*uDataLen+j]/data[128])) + 1.0);
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[64-i*uDataLen-j-1]/data[128])) + 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[64-i*uDataLen-j-1];
|
||||
if (channel === 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[64+(i-dataLength)*uDataLen+j]/data[128])) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
}
|
||||
audioData[i] /= (uDataLen * data[128]);
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
audioData[i] += data[64-i*uDataLen-j-1];
|
||||
}
|
||||
audioData[i] /= (uDataLen * data[128]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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.35 * (Math.log10(data[64-i*uDataLen-j-1])+logAmplitude) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.35 * (Math.log10(data[64+(i-dataLength)*uDataLen+j])+logAmplitude) + 1.0);
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * data[128]);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64-i*uDataLen-j-1];
|
||||
}
|
||||
audioData[i] /= (uDataLen/amplitude);
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
audioData[i] += Math.max(0, 0.35 * (Math.log10(data[64-i*uDataLen-j-1])+logAmplitude) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.35 * (Math.log10(data[64+(i-dataLength)*uDataLen+j])+logAmplitude) + 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[64-i*uDataLen-j-1];
|
||||
}
|
||||
audioData[i] /= (uDataLen/amplitude);
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen/amplitude);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let _dy;
|
||||
let _y_dy = centerRotateFlag*Math.tan(centerRotateAngle*degUnit)*halfWidth;
|
||||
let _ux = width/total;
|
||||
let _dx = Math.round(_ux/2);
|
||||
let _y = halfHeight-_y_dy
|
||||
let _dy;
|
||||
let _y_dy = centerRotateFlag*Math.tan(centerRotateAngle*degUnit)*halfWidth;
|
||||
let _ux = width/total;
|
||||
let _dx = Math.round(_ux/2);
|
||||
let _y = halfHeight-_y_dy
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
|
||||
if(lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(1, centerRotateFlag*centerRotateAngle * degUnit, -lineRotateFlag*lineRotateAngle * degUnit, 1, lineRotateFlag*Math.sin(1.05*lineRotateAngle*degUnit)*_y, 0);
|
||||
}
|
||||
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(0, _y, width, 2);
|
||||
}
|
||||
|
||||
//绘制频谱
|
||||
if (channel === 1 && reverse) {
|
||||
for (let i = 0; i < dataLength; i++) {
|
||||
let index = dataLength - i - 1;
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[index])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[index];
|
||||
context.fillRect(_ux * i, _y, _dx, _dy);
|
||||
if(lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(1, centerRotateFlag*centerRotateAngle * degUnit, -lineRotateFlag*lineRotateAngle * degUnit, 1, lineRotateFlag*Math.sin(1.05*lineRotateAngle*degUnit)*_y, 0);
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < channel; j++) {
|
||||
|
||||
if (centerLineFlag) {
|
||||
context.fillRect(0, _y, width, 2);
|
||||
}
|
||||
|
||||
//绘制频谱
|
||||
if (channel === 1 && reverse) {
|
||||
for (let i = 0; i < dataLength; i++) {
|
||||
let index = j ? ((total - dataLength) + i) : i;
|
||||
let index = dataLength - i - 1;
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[index])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[index];
|
||||
context.fillRect(_ux * (i + j * dataLength), _y, _dx, _dy);
|
||||
context.fillRect(_ux * i, _y, _dx, _dy);
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < channel; j++) {
|
||||
for (let i = 0; i < dataLength; i++) {
|
||||
let index = j ? ((total - dataLength) + i) : i;
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[index])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[index];
|
||||
context.fillRect(_ux * (i + j * dataLength), _y, _dx, _dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (centerRotateFlag || lineRotateFlag)
|
||||
context.resetTransform();
|
||||
|
||||
context.fill();
|
||||
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
if (centerRotateFlag || lineRotateFlag)
|
||||
context.resetTransform();
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.fill();
|
||||
defaultValues: {
|
||||
"Version": "1.0.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,
|
||||
"Reverse": false,
|
||||
"Rotate Settings": {
|
||||
"Center Enable": false,
|
||||
"Center Angle": 10,
|
||||
"Line Enable": false,
|
||||
"Line Angle": 10
|
||||
},
|
||||
"Data Settings": {
|
||||
"Auto Normalizing": true,
|
||||
"Amplitude": 10,
|
||||
"Unit Style": 0
|
||||
}
|
||||
}
|
||||
|
||||
requestPaint();
|
||||
preference: AdvpPreference {
|
||||
version: defaultValues["Version"]
|
||||
cfg_height: 670
|
||||
|
||||
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.Separator {}
|
||||
|
||||
P.SpinPreference {
|
||||
id: _cfg_preset_line_Channel
|
||||
name: "Channel"
|
||||
label: qsTr("Channel")
|
||||
message: "1 to 2"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: false
|
||||
from: 1
|
||||
to: 2
|
||||
defaultValue: defaultValues["Channel"]
|
||||
}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
enabled: _cfg_preset_line_Channel.value === 1
|
||||
defaultValue: defaultValues["Reverse"]
|
||||
}
|
||||
|
||||
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"]
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
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,150 +0,0 @@
|
||||
import QtQuick 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api" //导入CfgAPI.qml
|
||||
|
||||
CfgAPI {
|
||||
version: "1.0.0"
|
||||
cfg_height: 580
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_Center_Line
|
||||
name: "Center Line"
|
||||
label: qsTr("Show Center Line")
|
||||
defaultValue: true
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Center Color"
|
||||
label: qsTr("Center Line Color")
|
||||
enabled: _cfg_preset_line_Center_Line.value
|
||||
defaultValue: "#FF4500"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Line Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
defaultValue: "#FF4500"
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Line Position"
|
||||
label: qsTr("Spectrum Line Position")
|
||||
defaultValue: 0
|
||||
model: [qsTr("Both"), qsTr("Up"), qsTr("Down")]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Data Length"
|
||||
label: qsTr("Spectrum Length")
|
||||
defaultValue: 0
|
||||
model: [64, 32, 16, 8]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SpinPreference {
|
||||
id: _cfg_preset_line_Channel
|
||||
name: "Channel"
|
||||
label: qsTr("Channel")
|
||||
message: "1 to 2"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: false
|
||||
from: 1
|
||||
to: 2
|
||||
defaultValue: 2
|
||||
}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
enabled: _cfg_preset_line_Channel.value === 1
|
||||
defaultValue: false
|
||||
}
|
||||
|
||||
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: false
|
||||
}
|
||||
|
||||
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: 10
|
||||
displayValue: value + "°"
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_Rotate_Line_Enable
|
||||
name: "Line Enable"
|
||||
label: qsTr("Rotate Spectrum Line")
|
||||
defaultValue: false
|
||||
}
|
||||
|
||||
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: 10
|
||||
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: true
|
||||
}
|
||||
|
||||
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: 10
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Unit Style"
|
||||
label: qsTr("Display Style")
|
||||
defaultValue: 0
|
||||
model: [qsTr("Linear"), qsTr("Decibel")]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,163 +1,333 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api"
|
||||
|
||||
StyleAPI {
|
||||
readonly property var audioData: new Array(128)
|
||||
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 reverse: configs["Reverse"]
|
||||
readonly property bool centerRotateFlag: configs["Rotate Settings"]["Center Enable"]
|
||||
readonly property real centerRotateAngle: configs["Rotate Settings"]["Center Angle"]
|
||||
readonly property bool lineRotateFlag: configs["Rotate Settings"]["Line Enable"]
|
||||
readonly property real lineRotateAngle: configs["Rotate Settings"]["Line Angle"]
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: configs["Data Settings"]["Amplitude"] / 400.0
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
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 reverse: configs["Reverse"]
|
||||
readonly property bool centerRotateFlag: configs["Rotate Settings"]["Center Enable"]
|
||||
readonly property real centerRotateAngle: configs["Rotate Settings"]["Center Angle"]
|
||||
readonly property bool lineRotateFlag: configs["Rotate Settings"]["Line Enable"]
|
||||
readonly property real lineRotateAngle: configs["Rotate Settings"]["Line Angle"]
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: configs["Data Settings"]["Amplitude"] / 400.0
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
property int total: channel * dataLength
|
||||
property real logAmplitude: Math.log10(amplitude)
|
||||
property real degUnit: Math.PI / 180
|
||||
property int total: channel * dataLength
|
||||
property real logAmplitude: Math.log10(amplitude)
|
||||
property real degUnit: Math.PI / 180
|
||||
|
||||
property real halfWidth: width/2
|
||||
property real halfHeight: height/2
|
||||
property real halfWidth: width/2
|
||||
property real halfHeight: height/2
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
if(autoNormalizing) {
|
||||
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[64-i*uDataLen-j-1]/data[128])) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
onAudioDataUpdeted: {
|
||||
if(autoNormalizing) {
|
||||
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[64+(i-dataLength)*uDataLen+j]/data[128])) + 1.0);
|
||||
audioData[i] += Math.max(0, 0.4 * (Math.log10(data[64-i*uDataLen-j-1]/data[128])) + 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[64-i*uDataLen-j-1];
|
||||
if (channel === 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[64+(i-dataLength)*uDataLen+j]/data[128])) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
}
|
||||
audioData[i] /= (uDataLen * data[128]);
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
audioData[i] += data[64-i*uDataLen-j-1];
|
||||
}
|
||||
audioData[i] /= (uDataLen * data[128]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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.35 * (Math.log10(data[64-i*uDataLen-j-1])+logAmplitude) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.35 * (Math.log10(data[64+(i-dataLength)*uDataLen+j])+logAmplitude) + 1.0);
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * data[128]);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64-i*uDataLen-j-1];
|
||||
}
|
||||
audioData[i] /= (uDataLen/amplitude);
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
for(let i=0; i<dataLength; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
audioData[i] += Math.max(0, 0.35 * (Math.log10(data[64-i*uDataLen-j-1])+logAmplitude) + 1.0);
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += Math.max(0, 0.35 * (Math.log10(data[64+(i-dataLength)*uDataLen+j])+logAmplitude) + 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[64-i*uDataLen-j-1];
|
||||
}
|
||||
audioData[i] /= (uDataLen/amplitude);
|
||||
}
|
||||
if (channel === 2) {
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen/amplitude);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let _dy;
|
||||
let _y_dy = centerRotateFlag*Math.tan(centerRotateAngle*degUnit)*halfWidth;
|
||||
let _ux = width/total;
|
||||
let _dx = Math.round(_ux/2);
|
||||
let _y = halfHeight-_y_dy
|
||||
let _dy;
|
||||
let _y_dy = centerRotateFlag*Math.tan(centerRotateAngle*degUnit)*halfWidth;
|
||||
let _ux = width/total;
|
||||
let _dx = Math.round(_ux/2);
|
||||
let _y = halfHeight-_y_dy
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
|
||||
if(lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(1, centerRotateFlag*centerRotateAngle * degUnit, -lineRotateFlag*lineRotateAngle * degUnit, 1, lineRotateFlag*Math.sin(1.05*lineRotateAngle*degUnit)*_y, 0);
|
||||
}
|
||||
|
||||
if (centerLineFlag) {
|
||||
context.fillStyle = center_color;
|
||||
context.fillRect(0, _y, width, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
context.fillStyle = line_color;
|
||||
|
||||
//绘制频谱
|
||||
if (channel === 1 && reverse) {
|
||||
for (let i = 0; i < dataLength; i++) {
|
||||
let index = dataLength - i - 1;
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[index])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[index];
|
||||
context.fillRect(_ux * i, _y, _dx, _dy);
|
||||
if(lineRotateFlag || centerRotateFlag) {
|
||||
context.transform(1, centerRotateFlag*centerRotateAngle * degUnit, -lineRotateFlag*lineRotateAngle * degUnit, 1, lineRotateFlag*Math.sin(1.05*lineRotateAngle*degUnit)*_y, 0);
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < channel; j++) {
|
||||
|
||||
if (centerLineFlag) {
|
||||
context.fillStyle = center_color;
|
||||
context.fillRect(0, _y, width, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
context.fillStyle = line_color;
|
||||
|
||||
//绘制频谱
|
||||
if (channel === 1 && reverse) {
|
||||
for (let i = 0; i < dataLength; i++) {
|
||||
let index = j ? ((total - dataLength) + i) : i;
|
||||
let index = dataLength - i - 1;
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[index])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[index];
|
||||
context.fillRect(_ux * (i + j * dataLength), _y, _dx, _dy);
|
||||
context.fillRect(_ux * i, _y, _dx, _dy);
|
||||
}
|
||||
} else {
|
||||
for (let j = 0; j < channel; j++) {
|
||||
for (let i = 0; i < dataLength; i++) {
|
||||
let index = j ? ((total - dataLength) + i) : i;
|
||||
_y = halfHeight*(1-(linePosition!==2)*audioData[index])-_y_dy;
|
||||
_dy = (halfHeight + (!linePosition)*halfHeight)*audioData[index];
|
||||
context.fillRect(_ux * (i + j * dataLength), _y, _dx, _dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (centerRotateFlag || lineRotateFlag)
|
||||
context.resetTransform();
|
||||
|
||||
context.fill();
|
||||
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultValues: {
|
||||
"Version": "1.0.0",
|
||||
"Center Line": true,
|
||||
"Center Color": "#ff4500",
|
||||
"Line Color": "#ff4500",
|
||||
"Line Position": 0,
|
||||
"Data Length": 0,
|
||||
"Channel": 2,
|
||||
"Reverse": false,
|
||||
"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"]
|
||||
cfg_height: 580
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_Center_Line
|
||||
name: "Center Line"
|
||||
label: qsTr("Show Center Line")
|
||||
defaultValue: defaultValues["Center Line"]
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Center Color"
|
||||
label: qsTr("Center Line Color")
|
||||
enabled: _cfg_preset_line_Center_Line.value
|
||||
defaultValue: defaultValues["Center Color"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Line Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
defaultValue: defaultValues["Line Color"]
|
||||
}
|
||||
|
||||
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.Separator {}
|
||||
|
||||
P.SpinPreference {
|
||||
id: _cfg_preset_line_Channel
|
||||
name: "Channel"
|
||||
label: qsTr("Channel")
|
||||
message: "1 to 2"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: false
|
||||
from: 1
|
||||
to: 2
|
||||
defaultValue: defaultValues["Channel"]
|
||||
}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
enabled: _cfg_preset_line_Channel.value === 1
|
||||
defaultValue: defaultValues["Reverse"]
|
||||
}
|
||||
|
||||
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 + "°"
|
||||
}
|
||||
}
|
||||
|
||||
if (centerRotateFlag || lineRotateFlag)
|
||||
context.resetTransform();
|
||||
P.Separator {}
|
||||
|
||||
context.fill();
|
||||
P.DialogPreference {
|
||||
name: "Data Settings"
|
||||
label: qsTr("Data Settings")
|
||||
live: true
|
||||
icon.name: "regular:\uf1de"
|
||||
|
||||
requestPaint();
|
||||
}
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_dataSettings_autoNormalizing
|
||||
name: "Auto Normalizing"
|
||||
label: qsTr("Auto Normalizing")
|
||||
defaultValue: defaultValues["Data Settings"]["Auto Normalizing"]
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
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,139 +0,0 @@
|
||||
import QtQuick 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api" //导入CfgAPI.qml
|
||||
|
||||
CfgAPI {
|
||||
version: "1.0.0"
|
||||
cfg_height: 740
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Main Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
defaultValue: "#FF4500"
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Line Position"
|
||||
label: qsTr("Spectrum Line Position")
|
||||
defaultValue: 0
|
||||
model: [qsTr("Both"), qsTr("Outside"), qsTr("Inside")]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Line Width"
|
||||
label: qsTr("Spectrum Line Width")
|
||||
from: 0.1
|
||||
to: 4
|
||||
stepSize: 0.1
|
||||
defaultValue: 1
|
||||
displayValue: value.toFixed(1) + "px"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Max Range"
|
||||
label: qsTr("Max Amplitude")
|
||||
from: 0
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: 50
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Data Length"
|
||||
label: qsTr("Spectrum Length")
|
||||
defaultValue: 0
|
||||
model: [64, 32, 16, 8]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Channel"
|
||||
label: qsTr("Channel")
|
||||
message: "1 to 2"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: false
|
||||
from: 1
|
||||
to: 2
|
||||
defaultValue: 2
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
defaultValue: false
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_rotate
|
||||
name: "Rotate"
|
||||
label: qsTr("Auto Rotate")
|
||||
defaultValue: false
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Ratate Speed"
|
||||
label: qsTr("Ratate Speed")
|
||||
enabled: _cfg_preset_line_rotate.value
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: 10
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Angle"
|
||||
label: qsTr("Initial Angle")
|
||||
message: "0 to 359"
|
||||
enabled: !_cfg_preset_line_rotate.value
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: true
|
||||
from: 0
|
||||
to: 359
|
||||
defaultValue: 0
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Data Settings"
|
||||
label: qsTr("Data Settings")
|
||||
live: true
|
||||
icon.name: "regular:\uf1de"
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_solidcircle_dataSettings_autoNormalizing
|
||||
name: "Auto Normalizing"
|
||||
label: qsTr("Auto Normalizing")
|
||||
defaultValue: true
|
||||
}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Amplitude"
|
||||
label: qsTr("Amplitude Ratio")
|
||||
enabled: !_cfg_preset_solidcircle_dataSettings_autoNormalizing.value
|
||||
message: "1 to 100"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: true
|
||||
from: 1
|
||||
to: 100
|
||||
defaultValue: 10
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Unit Style"
|
||||
label: qsTr("Display Style")
|
||||
defaultValue: 0
|
||||
model: [qsTr("Linear"), qsTr("Decibel")]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,149 +1,303 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api"
|
||||
|
||||
StyleAPI {
|
||||
readonly property var audioData: new Array(128)
|
||||
AdvpStyleTemplate {
|
||||
style: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
|
||||
//configs
|
||||
readonly property string color: configs["Main Color"]
|
||||
readonly property int linePosition: configs["Line Position"]
|
||||
readonly property real lineWidth: configs["Line Width"]
|
||||
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: configs["Data Settings"]["Amplitude"] / 400
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
//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: configs["Data Settings"]["Amplitude"] / 400
|
||||
readonly property int unitStyle: configs["Data Settings"]["Unit Style"]
|
||||
|
||||
readonly property int total: channel*dataLength
|
||||
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 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 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
|
||||
readonly property real logAmplitude: Math.log10(amplitude)
|
||||
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
|
||||
readonly property real logAmplitude: Math.log10(amplitude)
|
||||
|
||||
|
||||
onConfigsUpdated: {
|
||||
context.lineWidth = lineWidth;
|
||||
context.strokeStyle = color;
|
||||
}
|
||||
|
||||
function getPos(r, deg) {
|
||||
return [halfWidth+Math.cos(deg)*r,halfHeight+Math.sin(deg)*r];
|
||||
}
|
||||
|
||||
function createPoint() {
|
||||
outerPos = [];
|
||||
innerPos = [];
|
||||
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(getPos(r1, deg));
|
||||
innerPos.push(getPos(r2, deg));
|
||||
}
|
||||
onConfigsUpdated: {
|
||||
context.lineWidth = configs["Line Width"];
|
||||
context.strokeStyle = configs["Main Color"];
|
||||
}
|
||||
offsetAngle = rotateFlag ? ((offsetAngle + rSpeed) % 360) : angle;
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
if(autoNormalizing) {
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
let logPeak = Math.log10(data[128]);
|
||||
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])-logPeak) + 1.0);
|
||||
function getPos(r, deg) {
|
||||
return [halfWidth+Math.cos(deg)*r,halfHeight+Math.sin(deg)*r];
|
||||
}
|
||||
|
||||
function createPoint() {
|
||||
outerPos = [];
|
||||
innerPos = [];
|
||||
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(getPos(r1, deg));
|
||||
innerPos.push(getPos(r2, deg));
|
||||
}
|
||||
}
|
||||
offsetAngle = rotateFlag ? ((offsetAngle + rSpeed) % 360) : angle;
|
||||
}
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
if(autoNormalizing) {
|
||||
if (unitStyle) {
|
||||
//对数化显示
|
||||
let logPeak = Math.log10(data[128]);
|
||||
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])-logPeak) + 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] / data[128];
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
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] / data[128];
|
||||
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.35 * (Math.log10(data[i*uDataLen+j])+logAmplitude) + 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] * amplitude;
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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.35 * (Math.log10(data[i*uDataLen+j])+logAmplitude) + 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] * amplitude;
|
||||
}
|
||||
audioData[i] /= uDataLen;
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
createPoint();
|
||||
|
||||
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();
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
createPoint();
|
||||
|
||||
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();
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
defaultValues: {
|
||||
"Version": "1.0.0",
|
||||
"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
|
||||
}
|
||||
}
|
||||
|
||||
preference: AdvpPreference {
|
||||
version: defaultValues["Version"]
|
||||
cfg_height: 740
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Main Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
defaultValue: defaultValues["Main Color"]
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Line Position"
|
||||
label: qsTr("Spectrum Line Position")
|
||||
defaultValue: defaultValues["Line Position"]
|
||||
model: [qsTr("Both"), qsTr("Outside"), qsTr("Inside")]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Line Width"
|
||||
label: qsTr("Spectrum Line Width")
|
||||
from: 0.1
|
||||
to: 10
|
||||
stepSize: 0.1
|
||||
defaultValue: defaultValues["Line Width"]
|
||||
displayValue: value.toFixed(1) + "px"
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Max Range"
|
||||
label: qsTr("Max Amplitude")
|
||||
from: 0
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Max Range"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SelectPreference {
|
||||
name: "Data Length"
|
||||
label: qsTr("Spectrum Length")
|
||||
defaultValue: defaultValues["Data Length"]
|
||||
model: [64, 32, 16, 8]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Channel"
|
||||
label: qsTr("Channel")
|
||||
message: "1 to 2"
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: false
|
||||
from: 1
|
||||
to: 2
|
||||
defaultValue: defaultValues["Channel"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
name: "Reverse"
|
||||
label: qsTr("Reverse Spectrum")
|
||||
defaultValue: defaultValues["Reverse"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_line_rotate
|
||||
name: "Rotate"
|
||||
label: qsTr("Auto Rotate")
|
||||
defaultValue: defaultValues["Rotate"]
|
||||
}
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Ratate Speed"
|
||||
label: qsTr("Ratate Speed")
|
||||
enabled: _cfg_preset_line_rotate.value
|
||||
from: 1
|
||||
to: 100
|
||||
stepSize: 1
|
||||
defaultValue: defaultValues["Ratate Speed"]
|
||||
displayValue: value + "%"
|
||||
}
|
||||
|
||||
P.SpinPreference {
|
||||
name: "Angle"
|
||||
label: qsTr("Initial Angle")
|
||||
message: "0 to 359"
|
||||
enabled: !_cfg_preset_line_rotate.value
|
||||
display: P.TextFieldPreference.ExpandLabel
|
||||
editable: true
|
||||
from: 0
|
||||
to: 359
|
||||
defaultValue: defaultValues["Angle"]
|
||||
}
|
||||
|
||||
P.Separator {}
|
||||
|
||||
P.DialogPreference {
|
||||
name: "Data Settings"
|
||||
label: qsTr("Data Settings")
|
||||
live: true
|
||||
icon.name: "regular:\uf1de"
|
||||
|
||||
P.SwitchPreference {
|
||||
id: _cfg_preset_circle_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_circle_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,53 +0,0 @@
|
||||
import QtQuick 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api" //导入CfgAPI.qml
|
||||
|
||||
CfgAPI {
|
||||
version: "1.0.0"
|
||||
cfg_height: 580
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Line Width"
|
||||
label: qsTr("Spectrum Line Width")
|
||||
from: 0.1
|
||||
to: 4
|
||||
stepSize: 0.1
|
||||
defaultValue: 1
|
||||
displayValue: value.toFixed(1) + "px"
|
||||
}
|
||||
|
||||
P.ColorPreference {
|
||||
name: "Line Color"
|
||||
label: qsTr("Spectrum Line Color")
|
||||
defaultValue: "#FF4500"
|
||||
}
|
||||
|
||||
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: true
|
||||
}
|
||||
|
||||
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: 10
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,62 +1,199 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import NERvGear.Preferences 1.0 as P
|
||||
|
||||
import "../../qml/api"
|
||||
|
||||
StyleAPI {
|
||||
readonly property var audioData: new Array(128)
|
||||
AdvpStyleTemplate {
|
||||
style: AdvpCanvasTemplate {
|
||||
readonly property var audioData: new Array(128)
|
||||
|
||||
readonly property real lineWidth: configs["Line Width"]
|
||||
readonly property string line_color: configs["Line Color"]
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: configs["Data Settings"]["Amplitude"] / 400.0
|
||||
readonly property bool autoNormalizing: configs["Data Settings"]["Auto Normalizing"]
|
||||
readonly property real amplitude: configs["Data Settings"]["Amplitude"] / 400.0
|
||||
|
||||
readonly property real ux: width/129
|
||||
readonly property real halfHeight: height/2
|
||||
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"]
|
||||
|
||||
onConfigsUpdated: {
|
||||
context.lineWidth = lineWidth;
|
||||
context.strokeStyle = line_color;
|
||||
}
|
||||
readonly property int total: dataLength*2
|
||||
|
||||
onAudioDataUpdeted: {
|
||||
data[128] *= 2;
|
||||
if(autoNormalizing) {
|
||||
//线性化显示
|
||||
for(let i=0; i<64; i++) {
|
||||
audioData[i] = data[64-i-1] / data[128];
|
||||
}
|
||||
for(let i=64; i<128; i++) {
|
||||
audioData[i] = data[i] / data[128];
|
||||
}
|
||||
} else {
|
||||
//线性化显示
|
||||
for(let i=0; i<64; i++) {
|
||||
audioData[i] = data[64-i-1] * amplitude;
|
||||
}
|
||||
for(let i=64; i<128; i++) {
|
||||
audioData[i] = data[i] * amplitude;
|
||||
}
|
||||
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"];
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, width+32, height+32);
|
||||
onAudioDataUpdeted: {
|
||||
data[128] *= 2;
|
||||
if(autoNormalizing) {
|
||||
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[64-i*uDataLen-j-1]/data[128])) + 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[64+(i-dataLength)*uDataLen+j]/data[128])) + 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[64-i*uDataLen-j-1];
|
||||
}
|
||||
audioData[i] /= (uDataLen * data[128]);
|
||||
}
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen * data[128]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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.35 * (Math.log10(data[64-i*uDataLen-j-1])+logAmplitude) + 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.35 * (Math.log10(data[64+(i-dataLength)*uDataLen+j])+logAmplitude) + 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[64-i*uDataLen-j-1];
|
||||
}
|
||||
audioData[i] /= (uDataLen/amplitude);
|
||||
}
|
||||
for(let i=dataLength; i<total; i++) {
|
||||
audioData[i] = 0;
|
||||
for(let j=0; j<uDataLen; j++) {
|
||||
audioData[i] += data[64+(i-dataLength)*uDataLen+j];
|
||||
}
|
||||
audioData[i] /= (uDataLen/amplitude);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.beginPath();
|
||||
context.moveTo(0, halfHeight);
|
||||
for(let i=0; i<128; i+=2) {
|
||||
context.lineTo(ux*i, halfHeight*(1+audioData[i]));
|
||||
context.lineTo(ux*(i+1), halfHeight*(1-audioData[i+1]));
|
||||
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();
|
||||
}
|
||||
context.lineTo(width, halfHeight);
|
||||
// context.closePath();
|
||||
context.stroke();
|
||||
|
||||
requestPaint();
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
for (let i = 0; i < 128; i++) {
|
||||
audioData[i] = 0;
|
||||
defaultValues: {
|
||||
"Version": "1.1.0",
|
||||
"Line Width": 1,
|
||||
"Line Color": "#ff4500",
|
||||
"Data Length": 0,
|
||||
"Data Settings": {
|
||||
"Auto Normalizing": true,
|
||||
"Amplitude": 10,
|
||||
"Unit Style": 0
|
||||
}
|
||||
}
|
||||
|
||||
preference: AdvpPreference {
|
||||
version: defaultValues["Version"]
|
||||
cfg_height: 400
|
||||
|
||||
P.SliderPreference {
|
||||
name: "Line Width"
|
||||
label: qsTr("Spectrum Line Width")
|
||||
from: 0.1
|
||||
to: 4
|
||||
stepSize: 0.1
|
||||
defaultValue: defaultValues["Line Width"]
|
||||
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")
|
||||
defaultValue: defaultValues["Data Length"]
|
||||
model: [64, 32, 16, 8]
|
||||
}
|
||||
|
||||
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")]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user