Warning, /utilities/krecorder/src/contents/ui/components/Visualization.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2020 Jonah BrĂ¼chert <jbb@kaidan.im>
0002 // SPDX-FileCopyrightText: 2020-2022 Devin Lin <espidev@gmail.com>
0003 // SPDX-License-Identifier: GPL-3.0-or-later
0004
0005 import QtQuick
0006 import QtQuick.Layouts
0007 import QtQuick.Controls as Controls
0008 import org.kde.kirigami as Kirigami
0009
0010 import KRecorder
0011
0012 Item {
0013 id: visualization
0014
0015 property var prober
0016
0017 property int maxBarHeight
0018 property int animationIndex // which index rectangle is being expanded
0019 property var volumes: []
0020 property bool showLine
0021 property bool showBarsFromMiddle
0022
0023 property int reservedBarWidth: Math.round(Kirigami.Units.gridUnit * 0.4)
0024
0025 property var simpleAudioFormatSetting: SettingsModel.simpleAudioFormat
0026
0027 // maximum volume to base off volume bar height
0028 property int maxVolumeData: 1000
0029
0030 // TODO: We need a more sophisticated algorithm to create the visualizer bars (probably using FFT)
0031 // currently we just see how much data is in a sample, which is really random and doesn't deal with spikes very well
0032
0033 function processVolume(volume) {
0034 // vorbis for some reason has its volume data upside-down
0035 if (simpleAudioFormatSetting == SettingsModel.VORBIS) {
0036 volume = Math.max(0, 17000 - volume);
0037 }
0038 return volume;
0039 }
0040
0041 Component.onCompleted: {
0042 visualization.prober.maxVolumes = (showBarsFromMiddle ? width / 2 : width) / reservedBarWidth;
0043 }
0044 onWidthChanged: {
0045 visualization.prober.maxVolumes = (showBarsFromMiddle ? width / 2 : width) / reservedBarWidth;
0046 }
0047
0048 Connections {
0049 target: visualization.prober
0050 function onVolumesListCleared() {
0051 visualization.maxVolumeData = 1000; // reset max
0052 }
0053 function onVolumesListAdded(volume) {
0054 visualization.maxVolumeData = Math.max(visualization.maxVolumeData, processVolume(volume));
0055 }
0056 }
0057
0058 // central line
0059 Rectangle {
0060 id: verticalBar
0061 visible: showLine
0062 z: 1
0063 anchors.top: list.top
0064 anchors.bottom: list.bottom
0065 anchors.horizontalCenter: parent.horizontalCenter
0066 width: Math.round(Kirigami.Units.gridUnit * 0.1)
0067 color: Kirigami.Theme.negativeTextColor
0068 }
0069
0070 ListView {
0071 id: list
0072 model: visualization.volumes
0073 orientation: Qt.Horizontal
0074
0075 interactive: false
0076 height: maxBarHeight
0077 anchors.verticalCenter: parent.verticalCenter
0078 anchors.left: parent.left
0079 anchors.leftMargin: showBarsFromMiddle ? Math.max(0, parent.width / 2 - list.count * reservedBarWidth) : 0 // gradually expand list
0080 anchors.right: showBarsFromMiddle ? verticalBar.left : parent.right
0081 spacing: 0
0082
0083 delegate: Item {
0084 width: reservedBarWidth
0085 height: list.height
0086
0087 Rectangle {
0088 color: Kirigami.Theme.disabledTextColor
0089 width: Math.round(Kirigami.Units.gridUnit * 0.12)
0090 radius: Math.round(width / 2)
0091 height: Math.max(Math.round(Kirigami.Units.gridUnit * 0.15), maxBarHeight * processVolume(modelData) / visualization.maxVolumeData)
0092 antialiasing: true
0093 anchors.verticalCenter: parent.verticalCenter
0094 }
0095 }
0096 }
0097 }