Anchor-annotator 0.3.1__py3-none-any.whl → 0.3.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Anchor_annotator
3
- Version: 0.3.1
3
+ Version: 0.3.3
4
4
  Summary: Anchor annotator is a program for inspecting corpora for the Montreal Forced Aligner and correcting transcriptions and pronunciations.
5
5
  Home-page: https://github.com/MontrealCorpusTools/Anchor-annotator
6
6
  Author: Montreal Corpus Tools
@@ -1,22 +1,22 @@
1
1
  anchor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  anchor/__main__.py,sha256=5ufG8lcx2x1am-04xI991AG7saJd24dxPw5JzjmB878,45
3
- anchor/_version.py,sha256=HzPz9rq3s1AiZXregKlqKaJJ2wGMtvH_a3V9la9CnpM,411
3
+ anchor/_version.py,sha256=FKnJIExgNrZG2xJ0y_dGNBpxGbGBYylvfat-jHhLUuM,411
4
4
  anchor/command_line.py,sha256=EucG805HyWk_zkMO9RXv9Yj0I0JVdDLZb1_DX2_ISjM,503
5
5
  anchor/db.py,sha256=ef4lO6HtCKoxC9CorIc0ZbPxKpjHa576a0ZIBOWNU9E,4956
6
- anchor/main.py,sha256=eazWSZC94_nyBx_6rJ85hxC9wkCJYVP5FN_t9vnRm44,120658
7
- anchor/models.py,sha256=QBVSvmoqee0aIuMUMEbc7D5vDqsZ2sC7njwwI_NOuEg,96005
8
- anchor/plot.py,sha256=7Z_UeHyrrNk5oEFyFG_RdgiV4ray75juuuq-Nxb9FZo,104379
6
+ anchor/main.py,sha256=wX6LLudTX5-HOxqBB-BGLXTdYJuDGQbV11gA2XBvQ8w,120605
7
+ anchor/models.py,sha256=sCZf5wF6g1KorMgb0AifmqhaxZp5fiYmlmaJoow-tFI,95230
8
+ anchor/plot.py,sha256=eNVG9sDdRA9_KKrHKSb2TF66bIluJsJzVnTGN3q-Brk,104878
9
9
  anchor/resources_rc.py,sha256=94wgxDTpP4Oy55Br7CZ_YnmvaqzHr4n-AydBPhZc-es,8427242
10
10
  anchor/settings.py,sha256=QdfBtJowHpkBLzJ_3bZRKxF1rJDBW9Z5kp83sJVz0pA,46965
11
11
  anchor/ui_corpus_manager.py,sha256=e3ybOd4UdYarrLBATxI8vIFnioa4R_BHrbsEz5mJ5eA,8564
12
12
  anchor/ui_error_dialog.py,sha256=c_QS0s1VaJEV9AhcrQZQyWHHpUPudWjJY1NI7Ytipio,3832
13
13
  anchor/ui_main_window.py,sha256=MYb4PtV1sHYgnc3QwPphKjU3LepzBJpxllhN4nyDook,63525
14
14
  anchor/ui_preferences.py,sha256=MOC2dY4qkViW9cUbC0DVSO7FLg-dGSbmR630WFQ6V9c,41843
15
- anchor/undo.py,sha256=PLtiAxC7U27vbega_p21vDRy4m9QBiHatDELlcNx08Y,32523
16
- anchor/widgets.py,sha256=th0zg-bgmHfwEbdfLKkt-OZUsmjy01PSAGGwcnlwwNM,158375
17
- anchor/workers.py,sha256=WceIGLKC8s9PqQw4VXPppBerHV1JUtJJxawHtQT1MXk,171183
18
- Anchor_annotator-0.3.1.dist-info/LICENSE,sha256=C0oIsblENEgWQ7XMNdYoXyXsIA5wa3YF0I9lK3H7A1s,1076
19
- Anchor_annotator-0.3.1.dist-info/METADATA,sha256=jW9m88-K6vEKIRvkqKddvCE9fB7PNMDoqXQamawFwNA,1500
20
- Anchor_annotator-0.3.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
21
- Anchor_annotator-0.3.1.dist-info/top_level.txt,sha256=wX6ZKxImGRZKFQjs3f6XYw_TfbAp6Xs3SmbLfLbFAJ0,7
22
- Anchor_annotator-0.3.1.dist-info/RECORD,,
15
+ anchor/undo.py,sha256=HXhrzV-T2JKwPd28KCaR9S6GWmi2Wr2Xk7IBEonRRCs,32564
16
+ anchor/widgets.py,sha256=arL006v_cOGWudEF4Adbh_wRjiyFRGHP9BXOtfCr0h0,158301
17
+ anchor/workers.py,sha256=iWLBGCg6jJr_OmVFJCRGMgF5Rw5G9IhpdNiqDv8ZBxU,171083
18
+ Anchor_annotator-0.3.3.dist-info/LICENSE,sha256=C0oIsblENEgWQ7XMNdYoXyXsIA5wa3YF0I9lK3H7A1s,1076
19
+ Anchor_annotator-0.3.3.dist-info/METADATA,sha256=KPemKhTKt7Rh3N4-k-f8V4tHoAkvoUKrhUlonplJrLo,1500
20
+ Anchor_annotator-0.3.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
21
+ Anchor_annotator-0.3.3.dist-info/top_level.txt,sha256=wX6ZKxImGRZKFQjs3f6XYw_TfbAp6Xs3SmbLfLbFAJ0,7
22
+ Anchor_annotator-0.3.3.dist-info/RECORD,,
anchor/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.3.1'
16
- __version_tuple__ = version_tuple = (0, 3, 1)
15
+ __version__ = version = '0.3.3'
16
+ __version_tuple__ = version_tuple = (0, 3, 3)
anchor/main.py CHANGED
@@ -1087,8 +1087,8 @@ class MainWindow(QtWidgets.QMainWindow):
1087
1087
  )
1088
1088
  for m in (
1089
1089
  session.query(anchor.db.AcousticModel)
1090
- .order_by(anchor.db.AcousticModel.last_used.desc())
1091
1090
  .filter_by(available_locally=True)
1091
+ .order_by(anchor.db.AcousticModel.last_used.desc())
1092
1092
  ):
1093
1093
  a = QtGui.QAction(f"{m.path} [{m.name}]", parent=self)
1094
1094
  a.setData(m.id)
@@ -1105,8 +1105,8 @@ class MainWindow(QtWidgets.QMainWindow):
1105
1105
 
1106
1106
  for m in (
1107
1107
  session.query(anchor.db.Dictionary)
1108
- .order_by(anchor.db.Dictionary.last_used.desc())
1109
1108
  .filter_by(available_locally=True)
1109
+ .order_by(anchor.db.Dictionary.last_used.desc())
1110
1110
  ):
1111
1111
  a = QtGui.QAction(text=f"{m.path} [{m.name}]", parent=self)
1112
1112
  a.setData(m.id)
@@ -1122,8 +1122,8 @@ class MainWindow(QtWidgets.QMainWindow):
1122
1122
 
1123
1123
  for m in (
1124
1124
  session.query(anchor.db.LanguageModel)
1125
- .order_by(anchor.db.LanguageModel.last_used.desc())
1126
1125
  .filter_by(available_locally=True)
1126
+ .order_by(anchor.db.LanguageModel.last_used.desc())
1127
1127
  ):
1128
1128
  a = QtGui.QAction(text=f"{m.path} [{m.name}]", parent=self)
1129
1129
  a.setData(m.id)
@@ -1139,8 +1139,8 @@ class MainWindow(QtWidgets.QMainWindow):
1139
1139
 
1140
1140
  for m in (
1141
1141
  session.query(anchor.db.G2PModel)
1142
- .order_by(anchor.db.G2PModel.last_used.desc())
1143
1142
  .filter_by(available_locally=True)
1143
+ .order_by(anchor.db.G2PModel.last_used.desc())
1144
1144
  ):
1145
1145
  a = QtGui.QAction(text=f"{m.path} [{m.name}]", parent=self)
1146
1146
  a.setData(m.id)
@@ -1932,7 +1932,7 @@ class MainWindow(QtWidgets.QMainWindow):
1932
1932
  session.query(anchor.db.AnchorCorpus).filter_by(current=True).update(
1933
1933
  {anchor.db.AnchorCorpus.acoustic_model_id: m_id}
1934
1934
  )
1935
- session.query(anchor.db.AcousticModel).filter_by(
1935
+ session.query(anchor.db.AcousticModel).filter(
1936
1936
  anchor.db.AcousticModel.id == m_id
1937
1937
  ).update(
1938
1938
  {
@@ -2003,9 +2003,7 @@ class MainWindow(QtWidgets.QMainWindow):
2003
2003
  session.query(anchor.db.AnchorCorpus).filter_by(current=True).update(
2004
2004
  {anchor.db.AnchorCorpus.dictionary_id: m_id}
2005
2005
  )
2006
- session.query(anchor.db.Dictionary).filter_by(
2007
- anchor.db.Dictionary.id == m_id
2008
- ).update(
2006
+ session.query(anchor.db.Dictionary).filter(anchor.db.Dictionary.id == m_id).update(
2009
2007
  {
2010
2008
  anchor.db.Dictionary.last_used: datetime.datetime.now(),
2011
2009
  }
@@ -2060,7 +2058,7 @@ class MainWindow(QtWidgets.QMainWindow):
2060
2058
  session.query(anchor.db.AnchorCorpus).filter_by(current=True).update(
2061
2059
  {anchor.db.AnchorCorpus.language_model_id: m_id}
2062
2060
  )
2063
- session.query(anchor.db.LanguageModel).filter_by(
2061
+ session.query(anchor.db.LanguageModel).filter(
2064
2062
  anchor.db.LanguageModel.id == m_id
2065
2063
  ).update(
2066
2064
  {
@@ -2139,7 +2137,7 @@ class MainWindow(QtWidgets.QMainWindow):
2139
2137
  anchor.db.AnchorCorpus.g2p_model_id: m_id,
2140
2138
  }
2141
2139
  )
2142
- session.query(anchor.db.G2PModel).filter_by(anchor.db.G2PModel.id == m_id).update(
2140
+ session.query(anchor.db.G2PModel).filter(anchor.db.G2PModel.id == m_id).update(
2143
2141
  {
2144
2142
  anchor.db.G2PModel.last_used: datetime.datetime.now(),
2145
2143
  }
@@ -2182,7 +2180,7 @@ class MainWindow(QtWidgets.QMainWindow):
2182
2180
  session.query(anchor.db.AnchorCorpus).filter_by(current=True).update(
2183
2181
  {anchor.db.AnchorCorpus.ivector_extractor_id: m_id}
2184
2182
  )
2185
- session.query(anchor.db.IvectorExtractor).filter_by(
2183
+ session.query(anchor.db.IvectorExtractor).filter(
2186
2184
  anchor.db.IvectorExtractor.id == m_id
2187
2185
  ).update(
2188
2186
  {
anchor/models.py CHANGED
@@ -166,6 +166,7 @@ class FileUtterancesModel(QtCore.QAbstractListModel):
166
166
 
167
167
  waveformReady = QtCore.Signal()
168
168
  utterancesReady = QtCore.Signal()
169
+ speakersChanged = QtCore.Signal()
169
170
 
170
171
  def __init__(self, *args, **kwargs):
171
172
  super().__init__(*args, **kwargs)
@@ -325,6 +326,7 @@ class FileUtterancesModel(QtCore.QAbstractListModel):
325
326
  if utterance.speaker_id not in self.speakers:
326
327
  self.speakers.append(utterance.speaker_id)
327
328
  self.speaker_channel_mapping[utterance.speaker_id] = utterance.channel
329
+ self.speakersChanged.emit()
328
330
  self._speaker_indices[index] = utterance.speaker_id
329
331
 
330
332
  def merge_table_utterances(
@@ -848,6 +850,8 @@ class FileSelectionModel(QtCore.QItemSelectionModel):
848
850
  except sqlalchemy.orm.exc.DetachedInstanceError:
849
851
  new_file = True
850
852
  self.requested_utterance_id = utterance_id
853
+ self.selected_min_time = None
854
+ self.selected_max_time = None
851
855
  if new_file:
852
856
  self.fileAboutToChange.emit()
853
857
  self.model().set_file(file_id)
@@ -943,8 +947,7 @@ class CorpusSelectionModel(QtCore.QItemSelectionModel):
943
947
  self.currentRowChanged.connect(self.switch_utterance)
944
948
  # self.selectionChanged.connect(self.update_selection_audio)
945
949
  # self.selectionChanged.connect(self.update_selection_audio)
946
- # self.model().changeCommandFired.connect(self.expire_current)
947
- self.model().layoutChanged.connect(self.check_selection)
950
+ self.model().newResults.connect(self.check_selection)
948
951
  self.model().unlockCorpus.connect(self.fileChanged.emit)
949
952
 
950
953
  def set_current_utterance(self, utterance_id):
@@ -2275,32 +2278,6 @@ class CorpusModel(TableModel):
2275
2278
  self._speaker_indices[row],
2276
2279
  )
2277
2280
 
2278
- def fileAt(self, index) -> int:
2279
- if not isinstance(index, int):
2280
- if not index.isValid():
2281
- return None
2282
- index = index.row()
2283
- return self._file_indices[index]
2284
-
2285
- def indexForUtterance(self, utterance_id: int, column: int = 1):
2286
- return self.createIndex(self.reversed_indices[utterance_id], column)
2287
-
2288
- def rollback_changes(self):
2289
- self.unsaved_files = set()
2290
- self.session.rollback()
2291
- # self.query_session.expire_all()
2292
- self.databaseSynced.emit(False)
2293
- self.update_data()
2294
-
2295
- def commit_changes(self):
2296
- self.session.bulk_update_mappings(
2297
- File, [{"id": x, "modified": True} for x in self.unsaved_files]
2298
- )
2299
-
2300
- self.unsaved_files = set()
2301
- self.session.commit()
2302
- self.databaseSynced.emit(True)
2303
-
2304
2281
  def finish_export_files(self):
2305
2282
  self.filesSaved.emit()
2306
2283
 
@@ -2586,7 +2563,6 @@ class CorpusTableModel(QtCore.QAbstractTableModel):
2586
2563
  self.session.commit()
2587
2564
  corpus_name = os.path.basename(corpus_directory)
2588
2565
  c = anchor.db.AnchorCorpus(name=corpus_name, path=corpus_directory, current=True, **kwargs)
2589
- print(c.current)
2590
2566
  self.session.add(c)
2591
2567
  self.session.commit()
2592
2568
  self.corpora.append(c)
anchor/plot.py CHANGED
@@ -2510,6 +2510,16 @@ class SpeakerTier(pg.GraphicsObject):
2510
2510
  self.corpus_model.refreshUtteranceText.connect(self.refreshTexts)
2511
2511
  self.selection_model.selectionChanged.connect(self.update_select)
2512
2512
  self.selection_model.model().utterancesReady.connect(self.refresh)
2513
+ self.file_model.speakersChanged.connect(self.update_available_speakers)
2514
+ self.available_speakers = {}
2515
+
2516
+ def update_available_speakers(self):
2517
+ self.available_speakers = {}
2518
+ for speaker_id in self.file_model.speakers:
2519
+ speaker_name = self.corpus_model.get_speaker_name(speaker_id)
2520
+ self.available_speakers[speaker_name] = speaker_id
2521
+ for reg in self.visible_utterances.values():
2522
+ reg.available_speakers = self.available_speakers
2513
2523
 
2514
2524
  def wheelEvent(self, ev):
2515
2525
  self.receivedWheelEvent.emit(ev)
anchor/undo.py CHANGED
@@ -6,7 +6,7 @@ import typing
6
6
  import pynini.lib
7
7
  import sqlalchemy
8
8
  from montreal_forced_aligner.data import WordType
9
- from montreal_forced_aligner.db import File, Pronunciation, Speaker, Utterance, Word
9
+ from montreal_forced_aligner.db import File, Pronunciation, Speaker, Utterance, Word, bulk_update
10
10
  from PySide6 import QtCore, QtGui
11
11
  from sqlalchemy.orm import make_transient
12
12
 
@@ -643,18 +643,18 @@ class UpdateUtteranceSpeakerCommand(FileCommand):
643
643
  )
644
644
  )
645
645
  session.flush()
646
+ mappings = []
646
647
  for u in self.utterances:
647
648
  u.speaker_id = self.new_speaker_id
648
- session.query(Speaker).filter(
649
- Speaker.id.in_(self.old_speaker_ids + [self.new_speaker_id])
650
- ).update({Speaker.modified: True})
649
+ mappings.append({"id": u.id, "speaker_id": self.new_speaker_id})
650
+ bulk_update(self.corpus_model.session, Utterance, mappings)
651
651
 
652
652
  def _undo(self, session) -> None:
653
+ mappings = []
653
654
  for i, u in enumerate(self.utterances):
654
655
  u.speaker_id = self.old_speaker_ids[i]
655
- session.query(Speaker).filter(
656
- Speaker.id.in_(self.old_speaker_ids + [self.new_speaker_id])
657
- ).update({Speaker.modified: True})
656
+ mappings.append({"id": u.id, "speaker_id": self.old_speaker_ids[i]})
657
+ bulk_update(self.corpus_model.session, Utterance, mappings)
658
658
 
659
659
  def update_data(self):
660
660
  super().update_data()
anchor/widgets.py CHANGED
@@ -125,6 +125,7 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
125
125
  or self.currentTime() >= self.maxTime()
126
126
  ):
127
127
  self.setCurrentTime(self.startTime())
128
+ self.timer.start()
128
129
  super(MediaPlayer, self).play()
129
130
  if fade_in:
130
131
  self.fade_in_anim.start()
@@ -155,8 +156,6 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
155
156
  self.timer.stop()
156
157
  self.setCurrentTime(self.startTime())
157
158
  self.timeChanged.emit(self.currentTime())
158
- elif state == QtMultimedia.QMediaPlayer.PlaybackState.PlayingState:
159
- self.timer.start()
160
159
  elif state == QtMultimedia.QMediaPlayer.PlaybackState.PausedState:
161
160
  self.timer.stop()
162
161
 
@@ -183,10 +182,10 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
183
182
  def set_volume(self, volume: int):
184
183
  if self.audioOutput() is None:
185
184
  return
186
- linearVolume = QtMultimedia.QAudio.convertVolume(
185
+ linearVolume = QtMultimedia.QtAudio.convertVolume(
187
186
  volume / 100.0,
188
- QtMultimedia.QAudio.VolumeScale.LogarithmicVolumeScale,
189
- QtMultimedia.QAudio.VolumeScale.LinearVolumeScale,
187
+ QtMultimedia.QtAudio.VolumeScale.LogarithmicVolumeScale,
188
+ QtMultimedia.QtAudio.VolumeScale.LinearVolumeScale,
190
189
  )
191
190
  self.audioOutput().setVolume(linearVolume)
192
191
 
@@ -195,10 +194,10 @@ class MediaPlayer(QtMultimedia.QMediaPlayer): # pragma: no cover
195
194
  return 100
196
195
  volume = self.audioOutput().volume()
197
196
  volume = int(
198
- QtMultimedia.QAudio.convertVolume(
197
+ QtMultimedia.QtAudio.convertVolume(
199
198
  volume,
200
- QtMultimedia.QAudio.VolumeScale.LinearVolumeScale,
201
- QtMultimedia.QAudio.VolumeScale.LogarithmicVolumeScale,
199
+ QtMultimedia.QtAudio.VolumeScale.LinearVolumeScale,
200
+ QtMultimedia.QtAudio.VolumeScale.LogarithmicVolumeScale,
202
201
  )
203
202
  * 100
204
203
  )
anchor/workers.py CHANGED
@@ -3171,7 +3171,6 @@ class SpectrogramWorker(FunctionWorker): # pragma: no cover
3171
3171
  self.y = scipy.signal.resample(
3172
3172
  self.y, int(self.y.shape[0] * max_sr / self.sample_rate)
3173
3173
  )
3174
- # self.y = resampy.resample(self.y, self.sample_rate, max_sr, filter='kaiser_fast')
3175
3174
  self.sample_rate = max_sr
3176
3175
  self.y = librosa.effects.preemphasis(self.y, coef=pre_emph_coeff)
3177
3176
  if self.stopped.is_set():