BitKnight commited on
Commit
4e019a3
·
verified ·
1 Parent(s): 8bf3976

Polyphase resampling (no aliasing); n_perm switch for tests

Browse files
Files changed (1) hide show
  1. app.py +13 -8
app.py CHANGED
@@ -33,16 +33,20 @@ SR = 16000
33
 
34
 
35
  def _to16k(audio):
 
 
 
 
36
  sr, x = audio
37
  x = np.asarray(x)
38
  if x.dtype.kind == "i":
39
- x = x.astype(np.float32) / np.iinfo(x.dtype).max
40
  x = x.astype(np.float32)
41
  if x.ndim == 2:
42
  x = x.mean(axis=1)
43
  if sr != SR:
44
- n = int(round(len(x) * SR / sr))
45
- x = np.interp(np.linspace(0, len(x) - 1, n), np.arange(len(x)), x).astype(np.float32)
46
  return x[: SR * 20] # at most 20 s
47
 
48
 
@@ -71,20 +75,20 @@ def parse_table(text, lang):
71
 
72
 
73
  @spaces.GPU(duration=20, size=GPU_SIZE)
74
- def _run(x, qs):
75
  t = time.perf_counter()
76
- res = DECIDER.decide(x, qs) if MOCK else DECIDER.decide(x, qs, n_perm=N_PERM)
77
  return res, (time.perf_counter() - t) * 1000
78
 
79
 
80
- def decide(audio, lang, text):
81
  if audio is None:
82
  raise gr.Error("Record or upload a clip first (or pick an example).")
83
  x = _to16k(audio)
84
  if len(x) < SR * 0.2:
85
  raise gr.Error("The clip is too short.")
86
  qs = parse_table(text, lang)
87
- res, ms = _run(x, qs)
88
  rows = []
89
  for q in qs:
90
  r = res[q.id]
@@ -135,6 +139,7 @@ with gr.Blocks(title="DuplexJev — speech to decisions", theme=gr.themes.Soft(p
135
  with gr.Accordion("Questions (editable) / 判断题(可编辑)", open=False):
136
  table = gr.Textbox(value=table_text("en"), lines=11, show_label=False)
137
  btn = gr.Button("Decide ⚡", variant="primary")
 
138
  gr.Examples(EXAMPLES, inputs=[audio, lang], label="Examples (synthetic or public-licence clips)",
139
  example_labels=["EN · angry barge-in", "EN · stops mid-request", "EN · “mm-hmm” backchannel", "laughter", "中文 · 等一下我想想", "中文 · 后排闲聊(不是对助手说)", "中文 · 开心道谢", "中文 · 导航请求"])
140
  with gr.Column(scale=6):
@@ -143,7 +148,7 @@ with gr.Blocks(title="DuplexJev — speech to decisions", theme=gr.themes.Soft(p
143
  interactive=False, max_height=1000, column_widths=["18%", "34%", "13%", "35%"])
144
  gr.Markdown(FOOT)
145
  lang.change(set_lang, lang, table)
146
- btn.click(decide, [audio, lang, table], [head, out], api_name="decide")
147
 
148
  if __name__ == "__main__":
149
  demo.queue(max_size=40).launch()
 
33
 
34
 
35
  def _to16k(audio):
36
+ """Gradio gives (sr, int16 array); resample with a polyphase filter (plain interpolation aliases and makes
37
+ speech sound harsher, which skews emotion and speaking-style answers)."""
38
+ from math import gcd
39
+ from scipy.signal import resample_poly
40
  sr, x = audio
41
  x = np.asarray(x)
42
  if x.dtype.kind == "i":
43
+ x = x.astype(np.float32) / float(np.iinfo(x.dtype).max + 1)
44
  x = x.astype(np.float32)
45
  if x.ndim == 2:
46
  x = x.mean(axis=1)
47
  if sr != SR:
48
+ g = gcd(int(sr), SR)
49
+ x = resample_poly(x, SR // g, int(sr) // g).astype(np.float32)
50
  return x[: SR * 20] # at most 20 s
51
 
52
 
 
75
 
76
 
77
  @spaces.GPU(duration=20, size=GPU_SIZE)
78
+ def _run(x, qs, n_perm):
79
  t = time.perf_counter()
80
+ res = DECIDER.decide(x, qs) if MOCK else DECIDER.decide(x, qs, n_perm=n_perm)
81
  return res, (time.perf_counter() - t) * 1000
82
 
83
 
84
+ def decide(audio, lang, text, n_perm=None):
85
  if audio is None:
86
  raise gr.Error("Record or upload a clip first (or pick an example).")
87
  x = _to16k(audio)
88
  if len(x) < SR * 0.2:
89
  raise gr.Error("The clip is too short.")
90
  qs = parse_table(text, lang)
91
+ res, ms = _run(x, qs, int(n_perm or N_PERM))
92
  rows = []
93
  for q in qs:
94
  r = res[q.id]
 
139
  with gr.Accordion("Questions (editable) / 判断题(可编辑)", open=False):
140
  table = gr.Textbox(value=table_text("en"), lines=11, show_label=False)
141
  btn = gr.Button("Decide ⚡", variant="primary")
142
+ nperm = gr.Number(value=N_PERM, visible=False)
143
  gr.Examples(EXAMPLES, inputs=[audio, lang], label="Examples (synthetic or public-licence clips)",
144
  example_labels=["EN · angry barge-in", "EN · stops mid-request", "EN · “mm-hmm” backchannel", "laughter", "中文 · 等一下我想想", "中文 · 后排闲聊(不是对助手说)", "中文 · 开心道谢", "中文 · 导航请求"])
145
  with gr.Column(scale=6):
 
148
  interactive=False, max_height=1000, column_widths=["18%", "34%", "13%", "35%"])
149
  gr.Markdown(FOOT)
150
  lang.change(set_lang, lang, table)
151
+ btn.click(decide, [audio, lang, table, nperm], [head, out], api_name="decide")
152
 
153
  if __name__ == "__main__":
154
  demo.queue(max_size=40).launch()