boris-behav-obs 8.16.5__py3-none-any.whl → 9.7.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- boris/__init__.py +1 -1
- boris/__main__.py +1 -1
- boris/about.py +28 -40
- boris/add_modifier.py +88 -80
- boris/add_modifier_ui.py +266 -144
- boris/advanced_event_filtering.py +23 -29
- boris/analysis_plugins/__init__.py +0 -0
- boris/analysis_plugins/_export_to_feral.py +225 -0
- boris/analysis_plugins/_latency.py +59 -0
- boris/analysis_plugins/irr_cohen_kappa.py +109 -0
- boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +112 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa.py +157 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +162 -0
- boris/analysis_plugins/list_of_dataframe_columns.py +22 -0
- boris/analysis_plugins/number_of_occurences.py +22 -0
- boris/analysis_plugins/number_of_occurences_by_independent_variable.py +54 -0
- boris/analysis_plugins/time_budget.py +61 -0
- boris/behav_coding_map_creator.py +235 -236
- boris/behavior_binary_table.py +33 -50
- boris/behaviors_coding_map.py +17 -18
- boris/boris_cli.py +6 -25
- boris/cmd_arguments.py +12 -1
- boris/coding_pad.py +19 -36
- boris/config.py +109 -50
- boris/config_file.py +58 -67
- boris/connections.py +105 -58
- boris/converters.py +13 -37
- boris/converters_ui.py +187 -110
- boris/cooccurence.py +250 -0
- boris/core.py +2174 -1303
- boris/core_qrc.py +15892 -10829
- boris/core_ui.py +941 -806
- boris/db_functions.py +17 -42
- boris/dev.py +27 -7
- boris/dialog.py +461 -242
- boris/duration_widget.py +9 -14
- boris/edit_event.py +61 -31
- boris/edit_event_ui.py +208 -97
- boris/event_operations.py +405 -281
- boris/events_cursor.py +25 -17
- boris/events_snapshots.py +36 -82
- boris/exclusion_matrix.py +4 -9
- boris/export_events.py +180 -203
- boris/export_observation.py +60 -73
- boris/external_processes.py +123 -98
- boris/geometric_measurement.py +427 -218
- boris/gui_utilities.py +91 -14
- boris/image_overlay.py +4 -4
- boris/import_observations.py +190 -98
- boris/ipc_mpv.py +325 -0
- boris/irr.py +20 -57
- boris/latency.py +31 -24
- boris/measurement_widget.py +14 -18
- boris/media_file.py +17 -19
- boris/menu_options.py +16 -6
- boris/modifier_coding_map_creator.py +1013 -0
- boris/modifiers_coding_map.py +7 -9
- boris/mpv2.py +128 -35
- boris/observation.py +501 -211
- boris/observation_operations.py +1037 -393
- boris/observation_ui.py +573 -363
- boris/observations_list.py +51 -58
- boris/otx_parser.py +74 -68
- boris/param_panel.py +45 -59
- boris/param_panel_ui.py +254 -138
- boris/player_dock_widget.py +91 -56
- boris/plot_data_module.py +20 -53
- boris/plot_events.py +56 -153
- boris/plot_events_rt.py +16 -30
- boris/plot_spectrogram_rt.py +83 -56
- boris/plot_waveform_rt.py +27 -49
- boris/plugins.py +468 -0
- boris/portion/__init__.py +18 -8
- boris/portion/const.py +35 -18
- boris/portion/dict.py +5 -5
- boris/portion/func.py +2 -2
- boris/portion/interval.py +21 -41
- boris/portion/io.py +41 -32
- boris/preferences.py +307 -123
- boris/preferences_ui.py +686 -227
- boris/project.py +294 -271
- boris/project_functions.py +626 -537
- boris/project_import_export.py +204 -213
- boris/project_ui.py +673 -441
- boris/qrc_boris.py +6 -3
- boris/qrc_boris5.py +6 -3
- boris/select_modifiers.py +62 -90
- boris/select_observations.py +19 -197
- boris/select_subj_behav.py +67 -39
- boris/state_events.py +51 -33
- boris/subjects_pad.py +7 -9
- boris/synthetic_time_budget.py +42 -26
- boris/time_budget_functions.py +169 -169
- boris/time_budget_widget.py +77 -89
- boris/transitions.py +41 -41
- boris/utilities.py +594 -226
- boris/version.py +3 -3
- boris/video_equalizer.py +16 -14
- boris/video_equalizer_ui.py +199 -130
- boris/video_operations.py +86 -28
- boris/view_df.py +104 -0
- boris/view_df_ui.py +75 -0
- boris/write_event.py +240 -136
- boris_behav_obs-9.7.12.dist-info/METADATA +139 -0
- boris_behav_obs-9.7.12.dist-info/RECORD +110 -0
- {boris_behav_obs-8.16.5.dist-info → boris_behav_obs-9.7.12.dist-info}/WHEEL +1 -1
- boris_behav_obs-9.7.12.dist-info/entry_points.txt +2 -0
- boris/README.TXT +0 -22
- boris/add_modifier.ui +0 -323
- boris/converters.ui +0 -289
- boris/core.qrc +0 -37
- boris/core.ui +0 -1571
- boris/edit_event.ui +0 -233
- boris/icons/logo_eye.ico +0 -0
- boris/map_creator.py +0 -982
- boris/observation.ui +0 -814
- boris/param_panel.ui +0 -379
- boris/preferences.ui +0 -537
- boris/project.ui +0 -1074
- boris/vlc_local.py +0 -90
- boris_behav_obs-8.16.5.dist-info/LICENSE.TXT +0 -674
- boris_behav_obs-8.16.5.dist-info/METADATA +0 -134
- boris_behav_obs-8.16.5.dist-info/RECORD +0 -107
- boris_behav_obs-8.16.5.dist-info/entry_points.txt +0 -2
- {boris → boris_behav_obs-9.7.12.dist-info/licenses}/LICENSE.TXT +0 -0
- {boris_behav_obs-8.16.5.dist-info → boris_behav_obs-9.7.12.dist-info}/top_level.txt +0 -0
boris/plot_spectrogram_rt.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2025 Olivier Friard
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
This program is free software; you can redistribute it and/or modify
|
|
@@ -24,12 +24,13 @@ Copyright 2012-2023 Olivier Friard
|
|
|
24
24
|
import wave
|
|
25
25
|
import matplotlib
|
|
26
26
|
|
|
27
|
-
matplotlib.use("
|
|
28
|
-
import numpy as np
|
|
27
|
+
matplotlib.use("QtAgg")
|
|
29
28
|
|
|
29
|
+
import numpy as np
|
|
30
|
+
from scipy import signal
|
|
30
31
|
from . import config as cfg
|
|
31
32
|
|
|
32
|
-
from
|
|
33
|
+
from PySide6.QtWidgets import (
|
|
33
34
|
QWidget,
|
|
34
35
|
QVBoxLayout,
|
|
35
36
|
QHBoxLayout,
|
|
@@ -37,17 +38,15 @@ from PyQt5.QtWidgets import (
|
|
|
37
38
|
QLabel,
|
|
38
39
|
QSpinBox,
|
|
39
40
|
)
|
|
40
|
-
from
|
|
41
|
-
from PyQt5 import Qt
|
|
41
|
+
from PySide6.QtCore import Signal, QEvent, Qt
|
|
42
42
|
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
|
43
43
|
from matplotlib.figure import Figure
|
|
44
44
|
import matplotlib.ticker as mticker
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
class Plot_spectrogram_RT(QWidget):
|
|
48
|
-
|
|
49
48
|
# send keypress event to mainwindow
|
|
50
|
-
sendEvent =
|
|
49
|
+
sendEvent = Signal(QEvent)
|
|
51
50
|
|
|
52
51
|
def __init__(self):
|
|
53
52
|
super().__init__()
|
|
@@ -75,7 +74,7 @@ class Plot_spectrogram_RT(QWidget):
|
|
|
75
74
|
"+",
|
|
76
75
|
self,
|
|
77
76
|
clicked=lambda: self.time_interval_changed(1),
|
|
78
|
-
focusPolicy=Qt.
|
|
77
|
+
focusPolicy=Qt.NoFocus,
|
|
79
78
|
)
|
|
80
79
|
)
|
|
81
80
|
hlayout1.addWidget(
|
|
@@ -83,21 +82,17 @@ class Plot_spectrogram_RT(QWidget):
|
|
|
83
82
|
"-",
|
|
84
83
|
self,
|
|
85
84
|
clicked=lambda: self.time_interval_changed(-1),
|
|
86
|
-
focusPolicy=Qt.
|
|
85
|
+
focusPolicy=Qt.NoFocus,
|
|
87
86
|
)
|
|
88
87
|
)
|
|
89
88
|
layout.addLayout(hlayout1)
|
|
90
89
|
|
|
91
90
|
hlayout2 = QHBoxLayout()
|
|
92
91
|
hlayout2.addWidget(QLabel("Frequency interval"))
|
|
93
|
-
self.sb_freq_min = QSpinBox(
|
|
94
|
-
valueChanged=self.frequency_interval_changed, focusPolicy=Qt.Qt.NoFocus
|
|
95
|
-
)
|
|
92
|
+
self.sb_freq_min = QSpinBox(valueChanged=self.frequency_interval_changed, focusPolicy=Qt.NoFocus)
|
|
96
93
|
self.sb_freq_min.setRange(0, 200000)
|
|
97
94
|
self.sb_freq_min.setSingleStep(100)
|
|
98
|
-
self.sb_freq_max = QSpinBox(
|
|
99
|
-
valueChanged=self.frequency_interval_changed, focusPolicy=Qt.Qt.NoFocus
|
|
100
|
-
)
|
|
95
|
+
self.sb_freq_max = QSpinBox(valueChanged=self.frequency_interval_changed, focusPolicy=Qt.NoFocus)
|
|
101
96
|
self.sb_freq_max.setRange(0, 200000)
|
|
102
97
|
self.sb_freq_max.setSingleStep(100)
|
|
103
98
|
hlayout2.addWidget(self.sb_freq_min)
|
|
@@ -118,7 +113,7 @@ class Plot_spectrogram_RT(QWidget):
|
|
|
118
113
|
else:
|
|
119
114
|
return False
|
|
120
115
|
|
|
121
|
-
def get_wav_info(self, wav_file: str):
|
|
116
|
+
def get_wav_info(self, wav_file: str) -> tuple[np.array, int]:
|
|
122
117
|
"""
|
|
123
118
|
read wav file and extract information
|
|
124
119
|
|
|
@@ -134,7 +129,8 @@ class Plot_spectrogram_RT(QWidget):
|
|
|
134
129
|
try:
|
|
135
130
|
wav = wave.open(wav_file, "r")
|
|
136
131
|
frames = wav.readframes(-1)
|
|
137
|
-
sound_info = np.fromstring(frames, dtype=np.int16)
|
|
132
|
+
# sound_info = np.fromstring(frames, dtype=np.int16)
|
|
133
|
+
sound_info = np.frombuffer(frames, dtype=np.int16)
|
|
138
134
|
frame_rate = wav.getframerate()
|
|
139
135
|
wav.close()
|
|
140
136
|
return sound_info, frame_rate
|
|
@@ -187,7 +183,7 @@ class Plot_spectrogram_RT(QWidget):
|
|
|
187
183
|
|
|
188
184
|
return {"media_length": self.media_length, "frame_rate": self.frame_rate}
|
|
189
185
|
|
|
190
|
-
def plot_spectro(self, current_time: float, force_plot: bool = False):
|
|
186
|
+
def plot_spectro(self, current_time: float, force_plot: bool = False) -> tuple[float, bool]:
|
|
191
187
|
"""
|
|
192
188
|
plot sound spectrogram centered on the current time
|
|
193
189
|
|
|
@@ -203,36 +199,71 @@ class Plot_spectrogram_RT(QWidget):
|
|
|
203
199
|
|
|
204
200
|
self.ax.clear()
|
|
205
201
|
|
|
202
|
+
window_type = "blackmanharris" # self.config_param.get(cfg.SPECTROGRAM_WINDOW_TYPE, cfg.SPECTROGRAM_DEFAULT_WINDOW_TYPE)
|
|
203
|
+
nfft = int(self.config_param.get(cfg.SPECTROGRAM_NFFT, cfg.SPECTROGRAM_DEFAULT_NFFT))
|
|
204
|
+
noverlap = self.config_param.get(cfg.SPECTROGRAM_NOVERLAP, cfg.SPECTROGRAM_DEFAULT_NOVERLAP)
|
|
205
|
+
vmin = self.config_param.get(cfg.SPECTROGRAM_VMIN, cfg.SPECTROGRAM_DEFAULT_VMIN)
|
|
206
|
+
vmax = self.config_param.get(cfg.SPECTROGRAM_VMAX, cfg.SPECTROGRAM_DEFAULT_VMAX)
|
|
207
|
+
|
|
208
|
+
if current_time is None:
|
|
209
|
+
return
|
|
210
|
+
|
|
206
211
|
# start
|
|
207
212
|
if current_time <= self.interval / 2:
|
|
208
|
-
|
|
209
213
|
self.ax.specgram(
|
|
210
|
-
self.sound_info[: int(
|
|
214
|
+
self.sound_info[: int(self.interval * self.frame_rate)],
|
|
211
215
|
mode="psd",
|
|
212
|
-
|
|
216
|
+
NFFT=nfft,
|
|
213
217
|
Fs=self.frame_rate,
|
|
214
|
-
|
|
218
|
+
noverlap=noverlap,
|
|
219
|
+
window=signal.get_window(window_type, nfft),
|
|
220
|
+
# matplotlib.mlab.window_hanning
|
|
221
|
+
# if window_type == "hanning"
|
|
222
|
+
# else matplotlib.mlab.window_hamming
|
|
223
|
+
# if window_type == "hamming"
|
|
224
|
+
# else matplotlib.mlab.window_blackmanharris
|
|
225
|
+
# if window_type == "blackmanharris"
|
|
226
|
+
# else matplotlib.mlab.window_hanning,
|
|
215
227
|
cmap=self.spectro_color_map,
|
|
228
|
+
vmin=vmin,
|
|
229
|
+
vmax=vmax,
|
|
230
|
+
# mode="psd",
|
|
231
|
+
## NFFT=1024,
|
|
232
|
+
# Fs=self.frame_rate,
|
|
233
|
+
## noverlap=900,
|
|
234
|
+
# cmap=self.spectro_color_map,
|
|
216
235
|
)
|
|
217
236
|
|
|
218
|
-
self.ax.set_xlim(
|
|
219
|
-
current_time - self.interval / 2, current_time + self.interval / 2
|
|
220
|
-
)
|
|
237
|
+
self.ax.set_xlim(current_time - self.interval / 2, current_time + self.interval / 2)
|
|
221
238
|
|
|
222
239
|
# cursor
|
|
223
240
|
self.ax.axvline(x=current_time, color=self.cursor_color, linestyle="-")
|
|
224
241
|
|
|
225
242
|
elif current_time >= self.media_length - self.interval / 2:
|
|
226
|
-
|
|
227
243
|
i = int(round(len(self.sound_info) - (self.interval * self.frame_rate), 0))
|
|
228
244
|
|
|
229
245
|
self.ax.specgram(
|
|
230
246
|
self.sound_info[i:],
|
|
231
247
|
mode="psd",
|
|
232
|
-
|
|
248
|
+
NFFT=nfft,
|
|
233
249
|
Fs=self.frame_rate,
|
|
234
|
-
|
|
250
|
+
noverlap=noverlap,
|
|
251
|
+
window=signal.get_window(window_type, nfft),
|
|
252
|
+
# matplotlib.mlab.window_hanning
|
|
253
|
+
# if window_type == "hanning"
|
|
254
|
+
# else matplotlib.mlab.window_hamming
|
|
255
|
+
# if window_type == "hamming"
|
|
256
|
+
# else matplotlib.mlab.window_blackmanharris
|
|
257
|
+
# if window_type == "blackmanharris"
|
|
258
|
+
# else matplotlib.mlab.window_hanning,
|
|
235
259
|
cmap=self.spectro_color_map,
|
|
260
|
+
vmin=vmin,
|
|
261
|
+
vmax=vmax,
|
|
262
|
+
# mode="psd",
|
|
263
|
+
## NFFT=1024,
|
|
264
|
+
# Fs=self.frame_rate,
|
|
265
|
+
## noverlap=900,
|
|
266
|
+
# cmap=self.spectro_color_map,
|
|
236
267
|
)
|
|
237
268
|
|
|
238
269
|
lim1 = current_time - (self.media_length - self.interval / 2)
|
|
@@ -240,48 +271,44 @@ class Plot_spectrogram_RT(QWidget):
|
|
|
240
271
|
|
|
241
272
|
self.ax.set_xlim(lim1, lim2)
|
|
242
273
|
|
|
243
|
-
self.ax.xaxis.set_major_locator(
|
|
244
|
-
|
|
245
|
-
)
|
|
246
|
-
self.ax.set_xticklabels(
|
|
247
|
-
[
|
|
248
|
-
str(round(w + self.media_length - self.interval, 1))
|
|
249
|
-
for w in self.ax.get_xticks()
|
|
250
|
-
]
|
|
251
|
-
)
|
|
274
|
+
self.ax.xaxis.set_major_locator(mticker.FixedLocator(self.ax.get_xticks().tolist()))
|
|
275
|
+
self.ax.set_xticklabels([str(round(w + self.media_length - self.interval, 1)) for w in self.ax.get_xticks()])
|
|
252
276
|
|
|
253
277
|
# cursor
|
|
254
|
-
self.ax.axvline(
|
|
255
|
-
x=lim1 + self.interval / 2, color=self.cursor_color, linestyle="-"
|
|
256
|
-
)
|
|
278
|
+
self.ax.axvline(x=lim1 + self.interval / 2, color=self.cursor_color, linestyle="-")
|
|
257
279
|
|
|
258
280
|
# middle
|
|
259
281
|
else:
|
|
260
|
-
|
|
261
282
|
self.ax.specgram(
|
|
262
283
|
self.sound_info[
|
|
263
|
-
int(
|
|
264
|
-
round((current_time - self.interval / 2) * self.frame_rate, 0)
|
|
265
|
-
) : int(
|
|
284
|
+
int(round((current_time - self.interval / 2) * self.frame_rate, 0)) : int(
|
|
266
285
|
round((current_time + self.interval / 2) * self.frame_rate, 0)
|
|
267
286
|
)
|
|
268
287
|
],
|
|
269
288
|
mode="psd",
|
|
270
|
-
|
|
289
|
+
NFFT=nfft,
|
|
271
290
|
Fs=self.frame_rate,
|
|
272
|
-
|
|
291
|
+
noverlap=noverlap,
|
|
292
|
+
window=signal.get_window(window_type, nfft),
|
|
293
|
+
# matplotlib.mlab.window_hanning
|
|
294
|
+
# if window_type == "hanning"
|
|
295
|
+
# else matplotlib.mlab.window_hamming
|
|
296
|
+
# if window_type == "hamming"
|
|
297
|
+
# else matplotlib.mlab.window_blackmanharris
|
|
298
|
+
# if window_type == "blackmanharris"
|
|
299
|
+
# else matplotlib.mlab.window_hanning,
|
|
273
300
|
cmap=self.spectro_color_map,
|
|
301
|
+
vmin=vmin,
|
|
302
|
+
vmax=vmax,
|
|
303
|
+
# mode="psd",
|
|
304
|
+
## NFFT=1024,
|
|
305
|
+
# Fs=self.frame_rate,
|
|
306
|
+
## noverlap=900,
|
|
307
|
+
# cmap=self.spectro_color_map,
|
|
274
308
|
)
|
|
275
309
|
|
|
276
|
-
self.ax.xaxis.set_major_locator(
|
|
277
|
-
|
|
278
|
-
)
|
|
279
|
-
self.ax.set_xticklabels(
|
|
280
|
-
[
|
|
281
|
-
str(round(current_time + w - self.interval / 2, 1))
|
|
282
|
-
for w in self.ax.get_xticks()
|
|
283
|
-
]
|
|
284
|
-
)
|
|
310
|
+
self.ax.xaxis.set_major_locator(mticker.FixedLocator(self.ax.get_xticks().tolist()))
|
|
311
|
+
self.ax.set_xticklabels([str(round(current_time + w - self.interval / 2, 1)) for w in self.ax.get_xticks()])
|
|
285
312
|
|
|
286
313
|
# cursor
|
|
287
314
|
self.ax.axvline(x=self.interval / 2, color=self.cursor_color, linestyle="-")
|
boris/plot_waveform_rt.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2025 Olivier Friard
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
This program is free software; you can redistribute it and/or modify
|
|
@@ -25,20 +25,21 @@ import wave
|
|
|
25
25
|
from . import config as cfg
|
|
26
26
|
import matplotlib
|
|
27
27
|
|
|
28
|
-
matplotlib.use("
|
|
28
|
+
matplotlib.use("QtAgg")
|
|
29
|
+
|
|
29
30
|
import numpy as np
|
|
30
|
-
from
|
|
31
|
-
from
|
|
32
|
-
from
|
|
33
|
-
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
|
31
|
+
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel
|
|
32
|
+
from PySide6.QtCore import Signal, QEvent, Qt
|
|
33
|
+
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
|
|
34
34
|
from matplotlib.figure import Figure
|
|
35
35
|
import matplotlib.ticker as mticker
|
|
36
36
|
|
|
37
|
+
# matplotlib.pyplot.switch_backend("Qt5Agg")
|
|
37
38
|
|
|
38
|
-
class Plot_waveform_RT(QWidget):
|
|
39
39
|
|
|
40
|
+
class Plot_waveform_RT(QWidget):
|
|
40
41
|
# send keypress event to mainwindow
|
|
41
|
-
sendEvent =
|
|
42
|
+
sendEvent = Signal(QEvent)
|
|
42
43
|
|
|
43
44
|
def __init__(self):
|
|
44
45
|
super().__init__()
|
|
@@ -66,7 +67,7 @@ class Plot_waveform_RT(QWidget):
|
|
|
66
67
|
"+",
|
|
67
68
|
self,
|
|
68
69
|
clicked=lambda: self.time_interval_changed(1),
|
|
69
|
-
focusPolicy=Qt.
|
|
70
|
+
focusPolicy=Qt.NoFocus,
|
|
70
71
|
)
|
|
71
72
|
)
|
|
72
73
|
hlayout1.addWidget(
|
|
@@ -74,7 +75,7 @@ class Plot_waveform_RT(QWidget):
|
|
|
74
75
|
"-",
|
|
75
76
|
self,
|
|
76
77
|
clicked=lambda: self.time_interval_changed(-1),
|
|
77
|
-
focusPolicy=Qt.
|
|
78
|
+
focusPolicy=Qt.NoFocus,
|
|
78
79
|
)
|
|
79
80
|
)
|
|
80
81
|
layout.addLayout(hlayout1)
|
|
@@ -108,7 +109,8 @@ class Plot_waveform_RT(QWidget):
|
|
|
108
109
|
try:
|
|
109
110
|
wav = wave.open(wav_file, "r")
|
|
110
111
|
frames = wav.readframes(-1)
|
|
111
|
-
signal = np.fromstring(frames, dtype=np.int16)
|
|
112
|
+
# signal = np.fromstring(frames, dtype=np.int16)
|
|
113
|
+
signal = np.frombuffer(frames, dtype=np.int16)
|
|
112
114
|
frame_rate = wav.getframerate()
|
|
113
115
|
wav.close()
|
|
114
116
|
return signal, frame_rate
|
|
@@ -154,7 +156,7 @@ class Plot_waveform_RT(QWidget):
|
|
|
154
156
|
self.interval += 5 * action
|
|
155
157
|
self.plot_waveform(current_time=self.time_mem, force_plot=True)
|
|
156
158
|
|
|
157
|
-
def plot_waveform(self, current_time: float, force_plot: bool = False):
|
|
159
|
+
def plot_waveform(self, current_time: float, force_plot: bool = False) -> None:
|
|
158
160
|
"""
|
|
159
161
|
plot sound waveform centered on the current time
|
|
160
162
|
|
|
@@ -170,28 +172,24 @@ class Plot_waveform_RT(QWidget):
|
|
|
170
172
|
|
|
171
173
|
self.ax.clear()
|
|
172
174
|
|
|
175
|
+
if current_time is None:
|
|
176
|
+
return
|
|
177
|
+
|
|
173
178
|
# start
|
|
174
179
|
if current_time <= self.interval / 2:
|
|
175
|
-
|
|
176
180
|
time_ = np.linspace(
|
|
177
181
|
0,
|
|
178
|
-
len(self.sound_info[: int((self.interval) * self.frame_rate)])
|
|
179
|
-
/ self.frame_rate,
|
|
182
|
+
len(self.sound_info[: int((self.interval) * self.frame_rate)]) / self.frame_rate,
|
|
180
183
|
num=len(self.sound_info[: int((self.interval) * self.frame_rate)]),
|
|
181
184
|
)
|
|
182
|
-
self.ax.plot(
|
|
183
|
-
time_, self.sound_info[: int((self.interval) * self.frame_rate)]
|
|
184
|
-
)
|
|
185
|
+
self.ax.plot(time_, self.sound_info[: int((self.interval) * self.frame_rate)])
|
|
185
186
|
|
|
186
|
-
self.ax.set_xlim(
|
|
187
|
-
current_time - self.interval / 2, current_time + self.interval / 2
|
|
188
|
-
)
|
|
187
|
+
self.ax.set_xlim(current_time - self.interval / 2, current_time + self.interval / 2)
|
|
189
188
|
|
|
190
189
|
# cursor
|
|
191
190
|
self.ax.axvline(x=current_time, color=self.cursor_color, linestyle="-")
|
|
192
191
|
|
|
193
192
|
elif current_time >= self.media_length - self.interval / 2:
|
|
194
|
-
|
|
195
193
|
i = int(round(len(self.sound_info) - (self.interval * self.frame_rate), 0))
|
|
196
194
|
|
|
197
195
|
time_ = np.linspace(
|
|
@@ -206,47 +204,27 @@ class Plot_waveform_RT(QWidget):
|
|
|
206
204
|
|
|
207
205
|
self.ax.set_xlim(lim1, lim2)
|
|
208
206
|
|
|
209
|
-
self.ax.xaxis.set_major_locator(
|
|
210
|
-
|
|
211
|
-
)
|
|
212
|
-
self.ax.set_xticklabels(
|
|
213
|
-
[
|
|
214
|
-
str(round(w + self.media_length - self.interval, 1))
|
|
215
|
-
for w in self.ax.get_xticks()
|
|
216
|
-
]
|
|
217
|
-
)
|
|
207
|
+
self.ax.xaxis.set_major_locator(mticker.FixedLocator(self.ax.get_xticks().tolist()))
|
|
208
|
+
self.ax.set_xticklabels([str(round(w + self.media_length - self.interval, 1)) for w in self.ax.get_xticks()])
|
|
218
209
|
|
|
219
210
|
# cursor
|
|
220
|
-
self.ax.axvline(
|
|
221
|
-
x=lim1 + self.interval / 2, color=self.cursor_color, linestyle="-"
|
|
222
|
-
)
|
|
211
|
+
self.ax.axvline(x=lim1 + self.interval / 2, color=self.cursor_color, linestyle="-")
|
|
223
212
|
|
|
224
213
|
# middle
|
|
225
214
|
else:
|
|
226
|
-
|
|
227
215
|
start = (current_time - self.interval / 2) * self.frame_rate
|
|
228
216
|
end = (current_time + self.interval / 2) * self.frame_rate
|
|
229
217
|
|
|
230
218
|
time_ = np.linspace(
|
|
231
219
|
0,
|
|
232
|
-
len(self.sound_info[int(round(start, 0)) : int(round(end, 0))])
|
|
233
|
-
/ self.frame_rate,
|
|
220
|
+
len(self.sound_info[int(round(start, 0)) : int(round(end, 0))]) / self.frame_rate,
|
|
234
221
|
num=len(self.sound_info[int(round(start, 0)) : int(round(end, 0))]),
|
|
235
222
|
)
|
|
236
223
|
|
|
237
|
-
self.ax.plot(
|
|
238
|
-
time_, self.sound_info[int(round(start, 0)) : int(round(end, 0))]
|
|
239
|
-
)
|
|
224
|
+
self.ax.plot(time_, self.sound_info[int(round(start, 0)) : int(round(end, 0))])
|
|
240
225
|
|
|
241
|
-
self.ax.xaxis.set_major_locator(
|
|
242
|
-
|
|
243
|
-
)
|
|
244
|
-
self.ax.set_xticklabels(
|
|
245
|
-
[
|
|
246
|
-
str(round(current_time + w - self.interval / 2, 1))
|
|
247
|
-
for w in self.ax.get_xticks()
|
|
248
|
-
]
|
|
249
|
-
)
|
|
226
|
+
self.ax.xaxis.set_major_locator(mticker.FixedLocator(self.ax.get_xticks().tolist()))
|
|
227
|
+
self.ax.set_xticklabels([str(round(current_time + w - self.interval / 2, 1)) for w in self.ax.get_xticks()])
|
|
250
228
|
|
|
251
229
|
# cursor
|
|
252
230
|
self.ax.axvline(x=self.interval / 2, color=self.cursor_color, linestyle="-")
|