Skip to content

Commit 64b4856

Browse files
Nathanael UrmoneitNathaU
authored andcommitted
Added SPL plot and a setting to enter the calibration factor
1 parent d186361 commit 64b4856

File tree

10 files changed

+963
-0
lines changed

10 files changed

+963
-0
lines changed

friture/Levels.qml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,28 @@ Rectangle {
7575
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
7676
color: systemPalette.windowText
7777
}
78+
79+
Text {
80+
id: splValues
81+
textFormat: Text.MarkdownText
82+
text: level_view_model.two_channels ? "1: " + level_to_text(level_view_model.level_data_slow.level_spl) + "<br />2: " + level_to_text(level_view_model.level_data_slow_2.level_spl) : level_to_text(level_view_model.level_data_slow.level_spl)
83+
font.pointSize: 14
84+
font.bold: true
85+
verticalAlignment: Text.AlignBottom
86+
horizontalAlignment: Text.AlignRight
87+
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
88+
color: systemPalette.windowText
89+
}
90+
91+
Text {
92+
id: splLegend
93+
textFormat: Text.PlainText
94+
text: "dB SPL"
95+
verticalAlignment: Text.AlignTop
96+
horizontalAlignment: Text.AlignRight
97+
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
98+
color: systemPalette.windowText
99+
}
78100

79101
LevelsMeter {
80102
Layout.fillHeight: true

friture/SPL.qml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import QtQuick 2.15
2+
import QtQuick.Window 2.2
3+
import QtQuick.Layouts 1.15
4+
import QtQuick.Shapes 1.15
5+
import Friture 1.0
6+
7+
Item {
8+
id: container
9+
property var stateId
10+
11+
// delay the load of the Plot until stateId has been set
12+
Loader {
13+
id: loader
14+
anchors.fill: parent
15+
}
16+
17+
onStateIdChanged: {
18+
console.log("stateId changed: " + stateId)
19+
loader.sourceComponent = plotComponent
20+
}
21+
22+
Component {
23+
id: plotComponent
24+
Plot {
25+
scopedata: Store.dock_states[container.stateId]
26+
27+
Repeater {
28+
model: scopedata.plot_items
29+
30+
PlotFilledCurve {
31+
anchors.fill: parent
32+
curve: modelData
33+
}
34+
}
35+
36+
Column {
37+
anchors.fill: parent
38+
spacing: 0
39+
FrequencyTracker {
40+
visible: scopedata.showFrequencyTracker
41+
anchors.left: parent.left
42+
anchors.right: parent.right
43+
fmaxValue: scopedata.fmaxValue
44+
fmaxLogicalValue: scopedata.fmaxLogicalValue
45+
}
46+
47+
FrequencyTracker {
48+
visible: scopedata.showPitchTracker
49+
anchors.left: parent.left
50+
anchors.right: parent.right
51+
fmaxValue: scopedata.fpitchDisplayText
52+
fmaxLogicalValue: scopedata.fpitchValue
53+
}
54+
}
55+
}
56+
}
57+
}

friture/analyzer.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
from friture.spectrogram_item import SpectrogramItem
5959
from friture.spectrogram_item_data import SpectrogramImageData
6060
from friture.spectrum_data import Spectrum_Data
61+
from friture.spl_data import SPLData
6162
from friture.plotFilledCurve import PlotFilledCurve
6263
from friture.filled_curve import FilledCurve
6364
from friture.qml_tools import qml_url
@@ -98,6 +99,7 @@ def __init__(self):
9899
qmlRegisterType(CoordinateTransform, 'Friture', 1, 0, 'CoordinateTransform')
99100
qmlRegisterType(Scope_Data, 'Friture', 1, 0, 'ScopeData')
100101
qmlRegisterType(Spectrum_Data, 'Friture', 1, 0, 'SpectrumData')
102+
qmlRegisterType(SPLData, 'Friture', 1, 0, 'SPLData')
101103
qmlRegisterType(LevelData, 'Friture', 1, 0, 'LevelData')
102104
qmlRegisterType(LevelViewModel, 'Friture', 1, 0, 'LevelViewModel')
103105
qmlRegisterType(Axis, 'Friture', 1, 0, 'Axis')

friture/level_data.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424

2525
class LevelData(QtCore.QObject):
2626
level_rms_changed = QtCore.pyqtSignal(float)
27+
level_spl_changed = QtCore.pyqtSignal(float)
2728
level_max_changed = QtCore.pyqtSignal(float)
2829

2930
def __init__(self, parent=None):
3031
super().__init__(parent)
3132

3233
self._level_rms = -30.
34+
self._level_spl = -30.
3335
self._level_max = -30.
3436

3537
@pyqtProperty(float, notify=level_rms_changed) # type: ignore
@@ -46,6 +48,20 @@ def level_rms(self, level_rms):
4648
self._level_rms = level_rms
4749
self.level_rms_changed.emit(level_rms)
4850

51+
@pyqtProperty(float, notify=level_spl_changed) # type: ignore
52+
def level_spl(self):
53+
return self._level_spl
54+
55+
@pyqtProperty(float, notify=level_spl_changed) # type: ignore
56+
def level_spl_iec(self):
57+
return dB_to_IEC(self._level_spl)
58+
59+
@level_spl.setter # type: ignore
60+
def level_spl(self, level_spl):
61+
if self._level_spl != level_spl:
62+
self._level_spl = level_spl
63+
self.level_spl_changed.emit(level_spl)
64+
4965
@pyqtProperty(float, notify=level_max_changed) # type: ignore
5066
def level_max(self):
5167
return self._level_max

friture/levels.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
from friture.audiobackend import SAMPLING_RATE
3434
from friture.qml_tools import qml_url, raise_if_error
3535

36+
from friture.spl_settings import SPL_Settings_Dialog
37+
3638
SMOOTH_DISPLAY_TIMER_PERIOD_MS = 25
3739
LEVEL_TEXT_LABEL_PERIOD_MS = 250
3840

@@ -73,6 +75,8 @@ def __init__(self, parent, engine):
7375
# initialize the settings dialog
7476
self.settings_dialog = Levels_Settings_Dialog(self)
7577

78+
self.calibration = 0
79+
7680
# initialize the class instance that will do the fft
7781
self.proc = audioproc()
7882

@@ -136,6 +140,7 @@ def handle_new_data(self, floatdata):
136140
self.old_rms = value_rms
137141

138142
self.level_view_model.level_data.level_rms = 10. * np.log10(value_rms + 0. * 1e-80)
143+
self.level_view_model.level_data.level_spl = self.level_view_model.level_data.level_rms + 94.0 + self.calibration
139144
self.level_view_model.level_data.level_max = 20. * np.log10(self.old_max + 0. * 1e-80)
140145
self.level_view_model.level_data_ballistic.peak_iec = dB_to_IEC(max(self.level_view_model.level_data.level_max, self.level_view_model.level_data.level_rms))
141146

@@ -156,7 +161,10 @@ def handle_new_data(self, floatdata):
156161
value_rms = pyx_exp_smoothed_value(self.kernel, self.alpha, y2 ** 2, self.old_rms_2)
157162
self.old_rms_2 = value_rms
158163

164+
value_spl = value_rms + 94.0 + self.calibration
165+
159166
self.level_view_model.level_data_2.level_rms = 10. * np.log10(value_rms + 0. * 1e-80)
167+
self.level_view_model.level_data_2.level_spl = self.level_view_model.level_data_2.level_rms + 94.0 + self.calibration
160168
self.level_view_model.level_data_2.level_max = 20. * np.log10(self.old_max_2 + 0. * 1e-80)
161169
self.level_view_model.level_data_ballistic_2.peak_iec = dB_to_IEC(max(self.level_view_model.level_data_2.level_max, self.level_view_model.level_data_2.level_rms))
162170

@@ -169,10 +177,12 @@ def canvasUpdate(self):
169177

170178
if self.i == LEVEL_TEXT_LABEL_STEPS:
171179
self.level_view_model.level_data_slow.level_rms = self.level_view_model.level_data.level_rms
180+
self.level_view_model.level_data_slow.level_spl = self.level_view_model.level_data.level_spl
172181
self.level_view_model.level_data_slow.level_max = self.level_view_model.level_data.level_max
173182

174183
if self.two_channels:
175184
self.level_view_model.level_data_slow_2.level_rms = self.level_view_model.level_data_2.level_rms
185+
self.level_view_model.level_data_slow_2.level_spl = self.level_view_model.level_data_2.level_spl
176186
self.level_view_model.level_data_slow_2.level_max = self.level_view_model.level_data_2.level_max
177187

178188
self.i = self.i % LEVEL_TEXT_LABEL_STEPS

0 commit comments

Comments
 (0)