duongthienz commited on
Commit
c39c912
·
verified ·
1 Parent(s): c07f4bc

Update state.py

Browse files
Files changed (1) hide show
  1. state.py +115 -0
state.py CHANGED
@@ -247,6 +247,121 @@ def register_file(fname):
247
  st.session_state.file_names.append(fname)
248
 
249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  # ---------------------------------------------------------------------------
251
  # analyze() — build and cache all DataFrames for one file
252
  # ---------------------------------------------------------------------------
 
247
  st.session_state.file_names.append(fname)
248
 
249
 
250
+ # ---------------------------------------------------------------------------
251
+ # File loading helpers
252
+ # ---------------------------------------------------------------------------
253
+
254
+ def load_annotation_file(fname, fpath):
255
+ """Load an annotation-only file (.txt / .rttm / .csv) into session state."""
256
+ ext = fpath.lower()
257
+ if ext.endswith(".txt"):
258
+ _, annotations = su.loadAudioTXT(fpath)
259
+ elif ext.endswith(".rttm"):
260
+ _, annotations = su.loadAudioRTTM(fpath)
261
+ elif ext.endswith(".csv"):
262
+ _, annotations = su.loadAudioCSV(fpath)
263
+ else:
264
+ raise ValueError(f"Unsupported annotation format: {fpath}")
265
+ totalSeconds = max((s.end for s in annotations.itersegments()), default=0)
266
+ st.session_state.results[fname] = (annotations, totalSeconds)
267
+ st.session_state.summaries[fname] = {}
268
+ st.session_state.unusedSpeakers[fname] = list(annotations.labels())
269
+ return annotations, totalSeconds
270
+
271
+
272
+ def load_demo_single(demo_path):
273
+ """Register and load a single RTTM demo file, then run analyze()."""
274
+ import time
275
+ dname = demo_path.split("/")[-1]
276
+ register_file(dname)
277
+ st.session_state.file_paths[dname] = demo_path
278
+ start_time = time.time()
279
+ with st.spinner("Loading Demo Sample"):
280
+ load_annotation_file(dname, demo_path)
281
+ with st.spinner("Analyzing Demo Data"):
282
+ analyze(dname)
283
+ st.success(f"Took {time.time() - start_time:.1f}s to analyze the demo file!")
284
+ st.session_state.select_currFile = dname
285
+ return dname
286
+
287
+
288
+ def load_demo_multi(demo_paths):
289
+ """Register and load multiple RTTM demo files."""
290
+ for demo_path in demo_paths:
291
+ dname = demo_path.split("/")[-1]
292
+ register_file(dname)
293
+ st.session_state.file_paths[dname] = demo_path
294
+ with st.spinner(f"Loading: {dname}"):
295
+ load_annotation_file(dname, demo_path)
296
+ st.session_state.analyzeAllToggle = True
297
+
298
+
299
+ def run_analysis_loop(file_names, file_paths_dict, pipeline,
300
+ enable_denoise, early_cleanup,
301
+ gain_window, minimum_gain, maximum_gain,
302
+ df_model, df_state, atten_lim_db):
303
+ """Process every file in file_names and populate session state."""
304
+ import time
305
+ import utils as _utils
306
+ start_time = time.time()
307
+ totalFiles = len(file_names)
308
+
309
+ for i, fname in enumerate(file_names):
310
+ fpath = file_paths_dict.get(fname, "")
311
+ ext = fpath.lower()
312
+
313
+ if ext.endswith((".txt", ".rttm", ".csv")):
314
+ label = ext.rsplit(".", 1)[-1].upper()
315
+ with st.spinner(f"Loading {label} {i+1}/{totalFiles}"):
316
+ load_annotation_file(fname, fpath)
317
+ else:
318
+ with st.spinner(f"Processing Audio {i+1}/{totalFiles}"):
319
+ annotations, totalSeconds, waveform, sample_rate = _utils.processFile(
320
+ fpath, pipeline, enable_denoise, early_cleanup,
321
+ gain_window, minimum_gain, maximum_gain,
322
+ df_model, df_state, atten_lim_db,
323
+ )
324
+ st.session_state.results[fname] = (annotations, totalSeconds)
325
+ st.session_state.summaries[fname] = {}
326
+ st.session_state.unusedSpeakers[fname] = list(annotations.labels())
327
+ with st.spinner(f"Generating clips {i+1}/{totalFiles}"):
328
+ store_speaker_clips(fname, annotations, waveform, sample_rate)
329
+ del waveform
330
+
331
+ with st.spinner(f"Analyzing {i+1}/{totalFiles}"):
332
+ analyze(fname)
333
+
334
+ st.success(f"Analyzed {totalFiles} file(s) in {time.time() - start_time:.1f}s")
335
+ st.session_state.analyzeAllToggle = False
336
+
337
+
338
+ def build_table_df(displayDF):
339
+ """Return a display-only copy of displayDF with cosmetic transforms applied:
340
+ - Rename 'Resource' -> 'Speaker'
341
+ - Drop 'Task' column if present
342
+ - Format Start / Finish as HH:MM:SS.cs strings
343
+ """
344
+ def _fmt(val):
345
+ try:
346
+ secs = float(val)
347
+ except (TypeError, ValueError):
348
+ return str(val)
349
+ h = int(secs // 3600)
350
+ m = int(secs % 3600 // 60)
351
+ s = int(secs % 60)
352
+ cs = round((secs % 1) * 100)
353
+ return f"{h:02d}:{m:02d}:{s:02d}.{cs:02d}"
354
+
355
+ df = displayDF.copy()
356
+ if "Task" in df.columns:
357
+ df = df.drop(columns=["Task"])
358
+ if "Start" in df.columns:
359
+ df["Start"] = df["Start"].apply(_fmt)
360
+ if "Finish" in df.columns:
361
+ df["Finish"] = df["Finish"].apply(_fmt)
362
+ return df.rename(columns={"Resource": "Speaker"})
363
+
364
+
365
  # ---------------------------------------------------------------------------
366
  # analyze() — build and cache all DataFrames for one file
367
  # ---------------------------------------------------------------------------