nahue-passano commited on
Commit
ab70807
1 Parent(s): 358ef2a

update: new streamlit layout and fixed processing

Browse files
README.md CHANGED
@@ -5,7 +5,7 @@ colorFrom: indigo
5
  colorTo: gray
6
  sdk: streamlit
7
  sdk_version: 1.21.0
8
- app_file: app.py
9
  pinned: false
10
  license: gpl-2.0
11
  ---
 
5
  colorTo: gray
6
  sdk: streamlit
7
  sdk_version: 1.21.0
8
+ app_file: aira/streamlit_app.py
9
  pinned: false
10
  license: gpl-2.0
11
  ---
aira/__pycache__/__init__.cpython-38.pyc CHANGED
Binary files a/aira/__pycache__/__init__.cpython-38.pyc and b/aira/__pycache__/__init__.cpython-38.pyc differ
 
aira/__pycache__/core.cpython-38.pyc CHANGED
Binary files a/aira/__pycache__/core.cpython-38.pyc and b/aira/__pycache__/core.cpython-38.pyc differ
 
aira/core.py CHANGED
@@ -16,27 +16,18 @@ from aira.engine.reflections import detect_reflections
16
  from aira.utils import read_signals_dict, cartesian_to_spherical
17
 
18
 
19
- INTEGRATION_TIME = 0.005
20
- INTENSITY_THRESHOLD = -60
21
- ANALYSIS_LENGTH = 1
22
-
23
-
24
  @dataclass
25
  class AmbisonicsImpulseResponseAnalyzer:
26
  """Main class for analyzing Ambisonics impulse responses"""
27
 
28
- integration_time: float = INTEGRATION_TIME
29
- intensity_threshold: float = INTENSITY_THRESHOLD
30
- analysis_length: float = ANALYSIS_LENGTH
31
- bformat_frequency_correction: bool = True
32
  input_builder = InputProcessorChain()
33
 
34
  def analyze(
35
  self,
36
  input_dict: dict,
37
- integration_time: float = INTEGRATION_TIME,
38
- intensity_threshold: float = INTENSITY_THRESHOLD,
39
- analysis_length: float = ANALYSIS_LENGTH,
40
  show: bool = False,
41
  ) -> go.Figure:
42
  """Analyzes a set of measurements in Ambisonics format and plots a hedgehog
@@ -150,7 +141,15 @@ if __name__ == "__main__":
150
  # "channels_per_file": 4,
151
  # "frequency_correction": False,
152
  # }
153
-
 
 
154
  analyzer = AmbisonicsImpulseResponseAnalyzer()
155
- fig = analyzer.analyze(data, show=True)
 
 
 
 
 
 
156
  analyzer.export_xy_projection(fig, "projection.png")
 
16
  from aira.utils import read_signals_dict, cartesian_to_spherical
17
 
18
 
 
 
 
 
 
19
  @dataclass
20
  class AmbisonicsImpulseResponseAnalyzer:
21
  """Main class for analyzing Ambisonics impulse responses"""
22
 
 
 
 
 
23
  input_builder = InputProcessorChain()
24
 
25
  def analyze(
26
  self,
27
  input_dict: dict,
28
+ integration_time: float,
29
+ intensity_threshold: float,
30
+ analysis_length: float,
31
  show: bool = False,
32
  ) -> go.Figure:
33
  """Analyzes a set of measurements in Ambisonics format and plots a hedgehog
 
141
  # "channels_per_file": 4,
142
  # "frequency_correction": False,
143
  # }
144
+ integration_time = 0.01
145
+ intensity_threshold = -50
146
+ analysis_length = 0.3
147
  analyzer = AmbisonicsImpulseResponseAnalyzer()
148
+ fig = analyzer.analyze(
149
+ input_dict=data,
150
+ integration_time=integration_time,
151
+ intensity_threshold=intensity_threshold,
152
+ analysis_length=analysis_length,
153
+ show=True,
154
+ )
155
  analyzer.export_xy_projection(fig, "projection.png")
aira/engine/__pycache__/__init__.cpython-38.pyc CHANGED
Binary files a/aira/engine/__pycache__/__init__.cpython-38.pyc and b/aira/engine/__pycache__/__init__.cpython-38.pyc differ
 
aira/engine/__pycache__/filtering.cpython-38.pyc CHANGED
Binary files a/aira/engine/__pycache__/filtering.cpython-38.pyc and b/aira/engine/__pycache__/filtering.cpython-38.pyc differ
 
aira/engine/__pycache__/input.cpython-38.pyc CHANGED
Binary files a/aira/engine/__pycache__/input.cpython-38.pyc and b/aira/engine/__pycache__/input.cpython-38.pyc differ
 
aira/engine/__pycache__/intensity.cpython-38.pyc CHANGED
Binary files a/aira/engine/__pycache__/intensity.cpython-38.pyc and b/aira/engine/__pycache__/intensity.cpython-38.pyc differ
 
aira/engine/__pycache__/plot.cpython-38.pyc CHANGED
Binary files a/aira/engine/__pycache__/plot.cpython-38.pyc and b/aira/engine/__pycache__/plot.cpython-38.pyc differ
 
aira/engine/__pycache__/pressure.cpython-38.pyc CHANGED
Binary files a/aira/engine/__pycache__/pressure.cpython-38.pyc and b/aira/engine/__pycache__/pressure.cpython-38.pyc differ
 
aira/engine/__pycache__/reflections.cpython-38.pyc CHANGED
Binary files a/aira/engine/__pycache__/reflections.cpython-38.pyc and b/aira/engine/__pycache__/reflections.cpython-38.pyc differ
 
aira/engine/plot.py CHANGED
@@ -145,6 +145,7 @@ def setup_plotly_layout() -> go.Figure:
145
  _type_
146
  _description_
147
  """
 
148
  fig = make_subplots(
149
  rows=2,
150
  cols=1,
@@ -152,6 +153,7 @@ def setup_plotly_layout() -> go.Figure:
152
  vertical_spacing=0.05,
153
  specs=[[{"type": "scene"}], [{"type": "xy"}]],
154
  subplot_titles=("<b>Hedgehog</b>", "<b>Omnidirectional channel</b>"),
 
155
  )
156
 
157
  camera, buttons = get_plotly_scenes()
 
145
  _type_
146
  _description_
147
  """
148
+ initial_fig = go.Figure()
149
  fig = make_subplots(
150
  rows=2,
151
  cols=1,
 
153
  vertical_spacing=0.05,
154
  specs=[[{"type": "scene"}], [{"type": "xy"}]],
155
  subplot_titles=("<b>Hedgehog</b>", "<b>Omnidirectional channel</b>"),
156
+ figure=initial_fig,
157
  )
158
 
159
  camera, buttons = get_plotly_scenes()
aira/{gui.py → pyqt_gui.py} RENAMED
@@ -12,26 +12,21 @@ from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
12
  from PyQt5.QtWidgets import (
13
  QLabel,
14
  QFileDialog,
15
- QMessageBox,
16
  )
17
- from PyQt5.QtGui import QPixmap
18
- from PyQt5.QtCore import Qt
19
- import os
20
  from pathlib import Path
21
 
22
  from aira.core import AmbisonicsImpulseResponseAnalyzer
23
  from aira.engine.input import InputMode
24
 
25
- INTEGRATION_TIME = 0.01
26
-
27
- analyzer = AmbisonicsImpulseResponseAnalyzer(integration_time=INTEGRATION_TIME)
28
-
29
 
30
  class Ui_MainWindow(object):
31
  def setupUi(self, MainWindow):
32
  MainWindow.setObjectName("MainWindow")
33
  MainWindow.resize(1350, 727)
34
- MainWindow.setMinimumSize(QtCore.QSize(1000, 800))
35
  MainWindow.setWindowIcon(QtGui.QIcon(str(Path("docs/images/aira-icon.png"))))
36
  self.centralwidget = QtWidgets.QWidget(MainWindow)
37
  self.centralwidget.setStyleSheet("background-color:#313438 ; ")
@@ -258,7 +253,6 @@ class Ui_MainWindow(object):
258
  font.setPointSize(12)
259
  self.rB_1ms.setFont(font)
260
  self.rB_1ms.setObjectName("rB_1ms")
261
- self.rB_1ms.setChecked(True)
262
  self.verticalLayout_6.addWidget(self.rB_1ms)
263
  self.rB_5ms = QtWidgets.QRadioButton(self.frame_analyze)
264
  palette = QtGui.QPalette()
@@ -304,6 +298,7 @@ class Ui_MainWindow(object):
304
  font.setPointSize(12)
305
  self.rB_5ms.setFont(font)
306
  self.rB_5ms.setObjectName("rB_5ms")
 
307
  self.verticalLayout_6.addWidget(self.rB_5ms)
308
  self.rB_10ms = QtWidgets.QRadioButton(self.frame_analyze)
309
  palette = QtGui.QPalette()
@@ -427,7 +422,7 @@ class Ui_MainWindow(object):
427
  self.label_analysis_length.setObjectName("label_analysis_length")
428
  self.verticalLayout_6.addWidget(self.label_analysis_length)
429
  self.lineEdit_aLength = QtWidgets.QLineEdit(self.frame_analyze)
430
- self.lineEdit_aLength.setText("100")
431
  font = QtGui.QFont()
432
  font.setFamily("Lato")
433
  font.setPointSize(10)
@@ -494,7 +489,7 @@ class Ui_MainWindow(object):
494
  self.lineEdit_threshold.setStyleSheet(
495
  "background-color: rgb(255, 255, 255);\n" "\n" ""
496
  )
497
- self.lineEdit_threshold.setText("60")
498
  self.lineEdit_threshold.setObjectName("lineEdit_threshold")
499
  self.verticalLayout_6.addWidget(self.lineEdit_threshold)
500
  spacerItem5 = QtWidgets.QSpacerItem(
@@ -559,19 +554,9 @@ class Ui_MainWindow(object):
559
  self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.frame_hedgehog)
560
  self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
561
  self.verticalLayout_8.setObjectName("verticalLayout_8")
562
- self.frame_hedgehog_label = QtWidgets.QFrame(self.frame_hedgehog)
563
- self.frame_hedgehog_label.setMaximumSize(QtCore.QSize(16777215, 42))
564
- self.frame_hedgehog_label.setFrameShape(QtWidgets.QFrame.StyledPanel)
565
- self.frame_hedgehog_label.setFrameShadow(QtWidgets.QFrame.Raised)
566
- self.frame_hedgehog_label.setObjectName("frame_hedgehog_label")
567
- self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_hedgehog_label)
568
- self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
569
- self.horizontalLayout_2.setObjectName("horizontalLayout_2")
570
  spacerItem11 = QtWidgets.QSpacerItem(
571
  430, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum
572
  )
573
- self.horizontalLayout_2.addItem(spacerItem11)
574
- self.label_hedgehog = QtWidgets.QLabel(self.frame_hedgehog_label)
575
  palette = QtGui.QPalette()
576
  brush = QtGui.QBrush(QtGui.QColor(69, 113, 213))
577
  brush.setStyle(QtCore.Qt.SolidPattern)
@@ -609,19 +594,12 @@ class Ui_MainWindow(object):
609
  brush = QtGui.QBrush(QtGui.QColor(49, 52, 56))
610
  brush.setStyle(QtCore.Qt.SolidPattern)
611
  palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
612
- self.label_hedgehog.setPalette(palette)
613
  font = QtGui.QFont()
614
  font.setFamily("Lato")
615
  font.setPointSize(15)
616
- self.label_hedgehog.setFont(font)
617
- self.label_hedgehog.setAlignment(QtCore.Qt.AlignCenter)
618
- self.label_hedgehog.setObjectName("label_hedgehog")
619
- self.horizontalLayout_2.addWidget(self.label_hedgehog)
620
  spacerItem12 = QtWidgets.QSpacerItem(
621
  429, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum
622
  )
623
- self.horizontalLayout_2.addItem(spacerItem12)
624
- self.verticalLayout_8.addWidget(self.frame_hedgehog_label)
625
  self.frame_hedgehog_plot = QtWidgets.QFrame(self.frame_hedgehog)
626
  self.frame_hedgehog_plot.setFrameShape(QtWidgets.QFrame.StyledPanel)
627
  self.frame_hedgehog_plot.setFrameShadow(QtWidgets.QFrame.Raised)
@@ -646,6 +624,7 @@ class Ui_MainWindow(object):
646
  self.verticalLayout_10.setObjectName("verticalLayout_10")
647
  self.frame_plan_header = QtWidgets.QFrame(self.frame_tab_plan)
648
  self.frame_plan_header.setMaximumSize(QtCore.QSize(16777215, 60))
 
649
  self.frame_plan_header.setFrameShape(QtWidgets.QFrame.StyledPanel)
650
  self.frame_plan_header.setFrameShadow(QtWidgets.QFrame.Raised)
651
  self.frame_plan_header.setObjectName("frame_plan_header")
@@ -683,7 +662,6 @@ class Ui_MainWindow(object):
683
  self.label_plan_view.setPixmap(
684
  pixmap.scaled(750, 3000, aspectRatioMode=Qt.KeepAspectRatio)
685
  )
686
- # self.label_plan_view.addWidget(self.label_plan_view)
687
  self.horizontalLayout_6.addWidget(self.label_plan_view)
688
  self.horizontalLayout_5.addWidget(self.frame_plan_view)
689
  self.verticalLayout_10.addWidget(self.frame_view)
@@ -812,7 +790,7 @@ class Ui_MainWindow(object):
812
 
813
  # CONEXIONES DE GUI CON ACCIONES
814
 
815
- # Creo los labels para guardar la data que devuelven las funciones de import triggereadas
816
  self.path_1 = QLabel()
817
  self.path_2 = QLabel()
818
  self.path_3 = QLabel()
@@ -834,10 +812,11 @@ class Ui_MainWindow(object):
834
  self.actionImport_Bformat_4channels.triggered.connect(
835
  self.import_Bformat_4channels
836
  )
837
-
838
  self.pb_analyze.clicked.connect(self.analyze)
839
  self.pB_load_plan.clicked.connect(self.load_plan)
840
  self.pB_export_plan.clicked.connect(self.export_plan)
 
841
 
842
  def retranslateUi(self, MainWindow):
843
  _translate = QtCore.QCoreApplication.translate
@@ -855,7 +834,7 @@ class Ui_MainWindow(object):
855
  )
856
  self.label_threshold.setText(_translate("MainWindow", "Threshold [dB]"))
857
  self.pb_analyze.setText(_translate("MainWindow", "Analyze"))
858
- self.label_hedgehog.setText(_translate("MainWindow", "Hedgehog Plot"))
859
  self.tabWidget.setTabText(
860
  self.tabWidget.indexOf(self.tab_main), _translate("MainWindow", "Main")
861
  )
@@ -950,7 +929,7 @@ class Ui_MainWindow(object):
950
  "channel_Z": Z_path,
951
  "input_mode": input_mode,
952
  "channels_per_file": channels_per_file,
953
- "frequency_correction": True,
954
  }
955
  else:
956
  B4_path = self.path_1.text()
@@ -959,11 +938,31 @@ class Ui_MainWindow(object):
959
  "stacked_signals": B4_path,
960
  "input_mode": input_mode,
961
  "channels_per_file": channels_per_file,
962
- "frequency_correction": True,
963
  }
964
 
965
- fig = analyzer.analyze(input_dict=data)
966
- self.gV_hedgehog.setHtml(fig.to_html(include_plotlyjs="cdn"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
967
 
968
  def load_plan(self):
969
  file_dialog = QFileDialog()
@@ -971,12 +970,52 @@ class Ui_MainWindow(object):
971
  MainWindow, "Select image", "", "Image file (*.png *.jpg *.jpeg)"
972
  )
973
  if file_path:
974
- pixmap = QPixmap(file_path)
975
- self.label_plan_view.setPixmap(
976
- pixmap.scaled(750, 3000, aspectRatioMode=Qt.KeepAspectRatio)
 
977
  )
 
 
 
 
 
 
 
 
 
 
 
978
  self.enable_export()
979
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
980
  def enable_export(self):
981
  self.pB_export_plan.setEnabled(True)
982
  self.pB_export_plan.setStyleSheet(
@@ -999,6 +1038,8 @@ class Ui_MainWindow(object):
999
  save_path, _ = file_dialog.getSaveFileName(
1000
  MainWindow, "Export image", "", "Image file (*.png *.jpg *.jpeg)"
1001
  )
 
 
1002
 
1003
  def import_Aformat_1channel(self):
1004
  file_dialog = QFileDialog()
@@ -1090,6 +1131,7 @@ class Ui_MainWindow(object):
1090
  save_path, _ = file_dialog.getSaveFileName(
1091
  MainWindow, "Export image", "", "Image file (*.png *.jpg *.jpeg)"
1092
  )
 
1093
 
1094
 
1095
  if __name__ == "__main__":
 
12
  from PyQt5.QtWidgets import (
13
  QLabel,
14
  QFileDialog,
 
15
  )
16
+ from PyQt5.QtGui import QPixmap, QPainter, QImage
17
+ from PyQt5.QtCore import Qt, QPoint
18
+
19
  from pathlib import Path
20
 
21
  from aira.core import AmbisonicsImpulseResponseAnalyzer
22
  from aira.engine.input import InputMode
23
 
 
 
 
 
24
 
25
  class Ui_MainWindow(object):
26
  def setupUi(self, MainWindow):
27
  MainWindow.setObjectName("MainWindow")
28
  MainWindow.resize(1350, 727)
29
+ MainWindow.setMinimumSize(QtCore.QSize(1200, 900))
30
  MainWindow.setWindowIcon(QtGui.QIcon(str(Path("docs/images/aira-icon.png"))))
31
  self.centralwidget = QtWidgets.QWidget(MainWindow)
32
  self.centralwidget.setStyleSheet("background-color:#313438 ; ")
 
253
  font.setPointSize(12)
254
  self.rB_1ms.setFont(font)
255
  self.rB_1ms.setObjectName("rB_1ms")
 
256
  self.verticalLayout_6.addWidget(self.rB_1ms)
257
  self.rB_5ms = QtWidgets.QRadioButton(self.frame_analyze)
258
  palette = QtGui.QPalette()
 
298
  font.setPointSize(12)
299
  self.rB_5ms.setFont(font)
300
  self.rB_5ms.setObjectName("rB_5ms")
301
+ self.rB_5ms.setChecked(True)
302
  self.verticalLayout_6.addWidget(self.rB_5ms)
303
  self.rB_10ms = QtWidgets.QRadioButton(self.frame_analyze)
304
  palette = QtGui.QPalette()
 
422
  self.label_analysis_length.setObjectName("label_analysis_length")
423
  self.verticalLayout_6.addWidget(self.label_analysis_length)
424
  self.lineEdit_aLength = QtWidgets.QLineEdit(self.frame_analyze)
425
+ self.lineEdit_aLength.setText("500")
426
  font = QtGui.QFont()
427
  font.setFamily("Lato")
428
  font.setPointSize(10)
 
489
  self.lineEdit_threshold.setStyleSheet(
490
  "background-color: rgb(255, 255, 255);\n" "\n" ""
491
  )
492
+ self.lineEdit_threshold.setText("-60")
493
  self.lineEdit_threshold.setObjectName("lineEdit_threshold")
494
  self.verticalLayout_6.addWidget(self.lineEdit_threshold)
495
  spacerItem5 = QtWidgets.QSpacerItem(
 
554
  self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.frame_hedgehog)
555
  self.verticalLayout_8.setContentsMargins(0, 0, 0, 0)
556
  self.verticalLayout_8.setObjectName("verticalLayout_8")
 
 
 
 
 
 
 
 
557
  spacerItem11 = QtWidgets.QSpacerItem(
558
  430, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum
559
  )
 
 
560
  palette = QtGui.QPalette()
561
  brush = QtGui.QBrush(QtGui.QColor(69, 113, 213))
562
  brush.setStyle(QtCore.Qt.SolidPattern)
 
594
  brush = QtGui.QBrush(QtGui.QColor(49, 52, 56))
595
  brush.setStyle(QtCore.Qt.SolidPattern)
596
  palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
 
597
  font = QtGui.QFont()
598
  font.setFamily("Lato")
599
  font.setPointSize(15)
 
 
 
 
600
  spacerItem12 = QtWidgets.QSpacerItem(
601
  429, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum
602
  )
 
 
603
  self.frame_hedgehog_plot = QtWidgets.QFrame(self.frame_hedgehog)
604
  self.frame_hedgehog_plot.setFrameShape(QtWidgets.QFrame.StyledPanel)
605
  self.frame_hedgehog_plot.setFrameShadow(QtWidgets.QFrame.Raised)
 
624
  self.verticalLayout_10.setObjectName("verticalLayout_10")
625
  self.frame_plan_header = QtWidgets.QFrame(self.frame_tab_plan)
626
  self.frame_plan_header.setMaximumSize(QtCore.QSize(16777215, 60))
627
+ self.frame_plan_header.setMinimumSize(QtCore.QSize(0, 60))
628
  self.frame_plan_header.setFrameShape(QtWidgets.QFrame.StyledPanel)
629
  self.frame_plan_header.setFrameShadow(QtWidgets.QFrame.Raised)
630
  self.frame_plan_header.setObjectName("frame_plan_header")
 
662
  self.label_plan_view.setPixmap(
663
  pixmap.scaled(750, 3000, aspectRatioMode=Qt.KeepAspectRatio)
664
  )
 
665
  self.horizontalLayout_6.addWidget(self.label_plan_view)
666
  self.horizontalLayout_5.addWidget(self.frame_plan_view)
667
  self.verticalLayout_10.addWidget(self.frame_view)
 
790
 
791
  # CONEXIONES DE GUI CON ACCIONES
792
 
793
+ # Labels para guardar la data que devuelven las funciones de import triggereadas
794
  self.path_1 = QLabel()
795
  self.path_2 = QLabel()
796
  self.path_3 = QLabel()
 
812
  self.actionImport_Bformat_4channels.triggered.connect(
813
  self.import_Bformat_4channels
814
  )
815
+ self.actionExport_hedgehog_plot.triggered.connect(self.export_hedgehog)
816
  self.pb_analyze.clicked.connect(self.analyze)
817
  self.pB_load_plan.clicked.connect(self.load_plan)
818
  self.pB_export_plan.clicked.connect(self.export_plan)
819
+ self.label_plan_view.mousePressEvent = lambda event: self.mousePressEvent(event)
820
 
821
  def retranslateUi(self, MainWindow):
822
  _translate = QtCore.QCoreApplication.translate
 
834
  )
835
  self.label_threshold.setText(_translate("MainWindow", "Threshold [dB]"))
836
  self.pb_analyze.setText(_translate("MainWindow", "Analyze"))
837
+
838
  self.tabWidget.setTabText(
839
  self.tabWidget.indexOf(self.tab_main), _translate("MainWindow", "Main")
840
  )
 
929
  "channel_Z": Z_path,
930
  "input_mode": input_mode,
931
  "channels_per_file": channels_per_file,
932
+ "frequency_correction": False,
933
  }
934
  else:
935
  B4_path = self.path_1.text()
 
938
  "stacked_signals": B4_path,
939
  "input_mode": input_mode,
940
  "channels_per_file": channels_per_file,
941
+ "frequency_correction": False,
942
  }
943
 
944
+ if self.rB_1ms.isChecked():
945
+ integration_time = 0.001
946
+ elif self.rB_5ms.isChecked():
947
+ integration_time = 0.005
948
+ else:
949
+ integration_time = 0.01
950
+
951
+ intensity_threshold = float(self.lineEdit_threshold.text())
952
+ analysis_length = float(self.lineEdit_aLength.text()) / 1000
953
+
954
+ analyzer = AmbisonicsImpulseResponseAnalyzer()
955
+ fig = analyzer.analyze(
956
+ input_dict=data,
957
+ integration_time=integration_time,
958
+ intensity_threshold=intensity_threshold,
959
+ analysis_length=analysis_length,
960
+ )
961
+ analyzer.export_xy_projection(fig, "projection.png")
962
+ fig.write_html("out.html")
963
+ url = QtCore.QUrl.fromLocalFile(str(Path("out.html").resolve()))
964
+ self.gV_hedgehog.load(url)
965
+ self.plotly_fig = fig
966
 
967
  def load_plan(self):
968
  file_dialog = QFileDialog()
 
970
  MainWindow, "Select image", "", "Image file (*.png *.jpg *.jpeg)"
971
  )
972
  if file_path:
973
+ # Cargar la imagen base
974
+ self.base_image = QImage(file_path)
975
+ scaled_image = self.base_image.scaled(
976
+ 1000, 800, Qt.AspectRatioMode.KeepAspectRatio
977
  )
978
+
979
+ # Crear una imagen resultante del mismo tamaño que la imagen base
980
+ self.result_image = QImage(scaled_image.size(), QImage.Format_ARGB32)
981
+ self.result_image.fill(0) # Rellenar con transparencia
982
+
983
+ # Mostrar la imagen base en un QLabel
984
+ self.label_plan_view.setPixmap(QPixmap.fromImage(scaled_image))
985
+
986
+ # Ajustar el tamaño del QLabel al tamaño de la imagen base escalada
987
+ self.label_plan_view.resize(scaled_image.size())
988
+
989
  self.enable_export()
990
 
991
+ def mousePressEvent(self, event):
992
+ if event.button() == Qt.LeftButton:
993
+ # Verificar si el clic ocurrió dentro de los límites de la imagen base
994
+ if (
995
+ event.x() < self.base_image.width()
996
+ and event.y() < self.base_image.height()
997
+ ):
998
+ # Cargar la imagen superpuesta
999
+ overlay_image = QImage("projection.png")
1000
+ overlay_position = QPoint(event.x() - 787, event.y() - 350)
1001
+
1002
+ # Dibujar la imagen base en la imagen resultante
1003
+ painter = QPainter(self.result_image)
1004
+ painter.drawImage(
1005
+ 0,
1006
+ 0,
1007
+ self.base_image.scaled(
1008
+ 1000, 800, Qt.AspectRatioMode.KeepAspectRatio
1009
+ ),
1010
+ )
1011
+
1012
+ # Dibujar la imagen superpuesta en la imagen resultante
1013
+ painter.drawImage(overlay_position, overlay_image)
1014
+ painter.end()
1015
+
1016
+ # Mostrar la imagen resultante en el QLabel
1017
+ self.label_plan_view.setPixmap(QPixmap.fromImage(self.result_image))
1018
+
1019
  def enable_export(self):
1020
  self.pB_export_plan.setEnabled(True)
1021
  self.pB_export_plan.setStyleSheet(
 
1038
  save_path, _ = file_dialog.getSaveFileName(
1039
  MainWindow, "Export image", "", "Image file (*.png *.jpg *.jpeg)"
1040
  )
1041
+ if save_path:
1042
+ self.result_image.save(save_path)
1043
 
1044
  def import_Aformat_1channel(self):
1045
  file_dialog = QFileDialog()
 
1131
  save_path, _ = file_dialog.getSaveFileName(
1132
  MainWindow, "Export image", "", "Image file (*.png *.jpg *.jpeg)"
1133
  )
1134
+ self.plotly_fig.write_image(save_path, "png", width=1366, height=768, scale=1.0)
1135
 
1136
 
1137
  if __name__ == "__main__":
app.py → aira/streamlit_app.py RENAMED
@@ -1,9 +1,9 @@
 
 
1
  import streamlit as st
2
- import plotly.graph_objects as go
3
  from aira.core import AmbisonicsImpulseResponseAnalyzer
4
  from aira.engine.input import InputMode
5
- import os
6
- import tempfile
7
 
8
 
9
  def save_temp_file(file):
@@ -23,14 +23,24 @@ def run_streamlit_app():
23
  logo_path = "docs/images/aira-banner.png"
24
  personal_logo_path = "docs/images/nahue-passano.png"
25
  st.columns(11)[10].image(personal_logo_path, use_column_width=True)
26
- st.columns(3)[1].image(logo_path, use_column_width=True)
27
 
28
  # Audio loading and settings
29
 
30
- audio_files, settings = st.columns(2)
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  with audio_files:
33
- st.header("🔉 LSS room responses in A-Format")
34
  up_files, down_files = st.columns(2)
35
 
36
  with up_files:
@@ -45,37 +55,32 @@ def run_streamlit_app():
45
  "Inverse filter", type=["mp3", "wav"]
46
  )
47
 
48
- with settings:
49
- st.header("⚙️ Settings")
50
- integration_time = st.selectbox("Integration time [ms]", [1, 5, 10])
51
- analysis_length = st.text_input("Analysis length [ms]", value="500")
52
- intensity_threshold = st.text_input("Intensity threshold [dB]", value=-60)
53
-
54
- # "Analyze" button
55
- if st.button("Analyze", use_container_width=True):
56
- data = {
57
- "front_left_up": save_temp_file(audio_file_flu),
58
- "front_right_down": save_temp_file(audio_file_frd),
59
- "back_right_up": save_temp_file(audio_file_bru),
60
- "back_left_down": save_temp_file(audio_file_bld),
61
- "inverse_filter": save_temp_file(audio_file_inverse_filter),
62
- "input_mode": InputMode.LSS,
63
- "channels_per_file": 1,
64
- "frequency_correction": True,
65
- }
66
-
67
- analyzer = AmbisonicsImpulseResponseAnalyzer(
68
- int(integration_time),
69
- float(intensity_threshold),
70
- float(analysis_length),
71
- )
72
- fig = analyzer.analyze(data, show=False)
73
- fig.update_layout(height=1080)
74
- st.plotly_chart(fig, use_container_width=True, height=1080)
75
-
76
- # Generar un gráfico genérico con Plotly
77
- fig = go.Figure(data=go.Scatter(x=[1, 2, 3, 4], y=[10, 5, 7, 2]))
78
- st.plotly_chart(fig)
79
 
80
 
81
  if __name__ == "__main__":
 
1
+ import os
2
+ import tempfile
3
  import streamlit as st
4
+
5
  from aira.core import AmbisonicsImpulseResponseAnalyzer
6
  from aira.engine.input import InputMode
 
 
7
 
8
 
9
  def save_temp_file(file):
 
23
  logo_path = "docs/images/aira-banner.png"
24
  personal_logo_path = "docs/images/nahue-passano.png"
25
  st.columns(11)[10].image(personal_logo_path, use_column_width=True)
 
26
 
27
  # Audio loading and settings
28
 
29
+ settings, audio_files = st.columns(2)
30
+
31
+ with settings:
32
+ st.image(logo_path, use_column_width=True)
33
+ st.subheader("⚙️ Settings")
34
+ col1, col2, col3 = st.columns(3)
35
+ with col1:
36
+ integration_time = st.selectbox("Integration time [ms]", [1, 5, 10])
37
+ with col2:
38
+ analysis_length = st.text_input("Analysis length [ms]", value="500")
39
+ with col3:
40
+ intensity_threshold = st.text_input("Intensity threshold [dB]", value=-60)
41
 
42
  with audio_files:
43
+ st.subheader("🔉 LSS room responses in A-Format")
44
  up_files, down_files = st.columns(2)
45
 
46
  with up_files:
 
55
  "Inverse filter", type=["mp3", "wav"]
56
  )
57
 
58
+ # "Analyze" button
59
+ if st.button("Analyze", use_container_width=True):
60
+ data = {
61
+ "front_left_up": save_temp_file(audio_file_flu),
62
+ "front_right_down": save_temp_file(audio_file_frd),
63
+ "back_right_up": save_temp_file(audio_file_bru),
64
+ "back_left_down": save_temp_file(audio_file_bld),
65
+ "inverse_filter": save_temp_file(audio_file_inverse_filter),
66
+ "input_mode": InputMode.LSS,
67
+ "channels_per_file": 1,
68
+ "frequency_correction": True,
69
+ }
70
+ analyzer = AmbisonicsImpulseResponseAnalyzer()
71
+ fig = analyzer.analyze(
72
+ input_dict=data,
73
+ integration_time=float(integration_time) / 1000,
74
+ intensity_threshold=float(intensity_threshold),
75
+ analysis_length=float(analysis_length) / 1000,
76
+ show=False,
77
+ )
78
+ fig.update_layout(
79
+ height=1080,
80
+ paper_bgcolor="rgb(14,17,23)",
81
+ plot_bgcolor="rgb(14,17,23)",
82
+ )
83
+ st.plotly_chart(fig, use_container_width=True, height=1080)
 
 
 
 
 
84
 
85
 
86
  if __name__ == "__main__":
aira/utils/__pycache__/__init__.cpython-38.pyc CHANGED
Binary files a/aira/utils/__pycache__/__init__.cpython-38.pyc and b/aira/utils/__pycache__/__init__.cpython-38.pyc differ
 
aira/utils/__pycache__/formatter.cpython-38.pyc CHANGED
Binary files a/aira/utils/__pycache__/formatter.cpython-38.pyc and b/aira/utils/__pycache__/formatter.cpython-38.pyc differ
 
aira/utils/__pycache__/utils.cpython-38.pyc CHANGED
Binary files a/aira/utils/__pycache__/utils.cpython-38.pyc and b/aira/utils/__pycache__/utils.cpython-38.pyc differ