umaradnaan commited on
Commit
2a26c53
·
verified ·
1 Parent(s): b426119

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -103
app.py CHANGED
@@ -1,135 +1,84 @@
1
  import streamlit as st
2
- import numpy as np
3
  import speech_recognition as sr
4
- import base64
5
- import re
6
  import math
7
- import io
8
- import time
9
- import pandas as pd
10
 
11
  st.set_page_config(page_title="Voice Calculator", layout="wide")
12
 
13
- # ---------------- UI ----------------
14
- st.markdown("<h2>🎙️ Voice Scientific Calculator (HF Spaces Compatible)</h2>", unsafe_allow_html=True)
15
- st.markdown("Record voice auto convert → evaluate when you say **equal**")
16
-
17
- # ---------------- Recorder UI (JS) ----------------
18
- record_js = """
19
- <script>
20
- let chunks = [];
21
- let mediaRecorder;
22
-
23
- function startRecording() {
24
- navigator.mediaDevices.getUserMedia({ audio: true })
25
- .then(stream => {
26
- mediaRecorder = new MediaRecorder(stream);
27
- mediaRecorder.start();
28
- chunks = [];
29
- mediaRecorder.ondataavailable = e => { chunks.push(e.data); };
30
- });
31
- }
32
-
33
- function stopRecording() {
34
- mediaRecorder.stop();
35
- mediaRecorder.onstop = e => {
36
- let blob = new Blob(chunks, { type: 'audio/webm' });
37
- let reader = new FileReader();
38
- reader.readAsDataURL(blob);
39
- reader.onloadend = () => {
40
- let base64data = reader.result.split(',')[1];
41
- const streamlitEvent = new CustomEvent("streamlit:audio_recorded", {
42
- detail: { data: base64data }
43
- });
44
- window.parent.document.dispatchEvent(streamlitEvent);
45
- };
46
- };
47
- }
48
-
49
- </script>
50
- """
51
-
52
- st.markdown(record_js, unsafe_allow_html=True)
53
-
54
- st.button("🎙 Start Recording", on_click=lambda: st.session_state.update({"record": "start"}))
55
- st.button("⏹ Stop & Process", on_click=lambda: st.session_state.update({"record": "stop"}))
56
-
57
- # ---------------------------------------
58
- # LISTEN FOR JS → PYTHON AUDIO TRANSFER
59
- # ---------------------------------------
60
- audio_slot = st.empty()
61
-
62
- if "audio" not in st.session_state:
63
- st.session_state.audio = None
64
-
65
- def on_audio_received():
66
- pass
67
 
68
- # Inject listener
69
- audio_script = """
70
- <script>
71
- window.parent.document.addEventListener("streamlit:audio_recorded", (e) => {
72
- const data = e.detail.data;
73
- window.parent.postMessage({isStreamlitMessage: true, type: "streamlit:setComponentValue", value: data}, "*");
74
- });
75
- </script>
76
- """
77
- audio_slot.markdown(audio_script, unsafe_allow_html=True)
78
 
79
- audio_data = st.experimental_get_query_params().get("componentValue", [None])[0]
80
 
81
- if audio_data:
82
- st.session_state.audio = audio_data
 
 
83
 
84
- # ---------------- PROCESS AUDIO ----------------
85
  recognizer = sr.Recognizer()
86
 
87
- def decode_audio(b64):
88
- raw = base64.b64decode(b64)
89
- return raw
90
-
91
- if st.session_state.audio:
92
- st.info("Processing audio…")
93
-
94
- audio_bytes = decode_audio(st.session_state.audio)
95
-
96
- audio = sr.AudioData(audio_bytes, 48000, 2)
97
- try:
98
- text = recognizer.recognize_google(audio)
99
- except:
100
- text = ""
101
 
102
- st.success(f"Transcript: **{text}**")
103
 
104
- # EXPRESSION PARSER (simple version)
105
- text_lower = text.lower()
106
 
107
- # Replace words
108
- ops = {
109
  "plus": "+",
110
  "minus": "-",
111
  "times": "*",
112
  "into": "*",
113
  "x": "*",
114
- "divide": "/",
115
  "divided by": "/",
116
- "power": "**",
117
  "to the power of": "**",
 
118
  "square root of": "math.sqrt",
 
 
 
 
 
 
119
  }
120
 
121
- expr = text_lower
122
- for k, v in ops.items():
123
- expr = expr.replace(k, v)
124
 
125
- expr = re.sub(r"[^0-9\+\-\*\/\.\(\)a-z ]", "", expr)
 
 
 
 
 
126
 
127
- if "equal" in expr:
128
- expr = expr.replace("equal", "")
129
- st.write(f"Expression: `{expr}`")
130
 
 
 
 
131
  try:
132
  result = eval(expr, {"math": math, "__builtins__": {}})
133
- st.success(f"Result = **{result}**")
134
  except Exception as e:
135
  st.error(f"Error: {e}")
 
1
  import streamlit as st
2
+ from audiorecorder import audiorecorder
3
  import speech_recognition as sr
 
 
4
  import math
5
+ import re
 
 
6
 
7
  st.set_page_config(page_title="Voice Calculator", layout="wide")
8
 
9
+ st.markdown("""
10
+ # 🎙️ Voice Scientific Calculator (HF Spaces Compatible)
11
+ Speak natural math expressions
12
+ Say **equal / equals / equal to** to calculate
13
+ ---
14
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ # ---------------- RECORD AUDIO ----------------
17
+ st.subheader("🎧 Record Voice")
 
 
 
 
 
 
 
 
18
 
19
+ audio = audiorecorder("🎙️ Start Recording", "⏹ Stop Recording")
20
 
21
+ if len(audio) == 0:
22
+ st.info("Press **Start Recording**, speak, then Stop.")
23
+ else:
24
+ st.audio(audio.tobytes())
25
 
26
+ # ------------ SPEECH RECOGNITION -----------
27
  recognizer = sr.Recognizer()
28
 
29
+ if len(audio) > 0:
30
+ with st.spinner("Transcribing..."):
31
+ try:
32
+ audio_data = sr.AudioData(audio.tobytes(), sample_rate=44100, sample_width=2)
33
+ text = recognizer.recognize_google(audio_data)
34
+ except:
35
+ text = ""
 
 
 
 
 
 
 
36
 
37
+ st.success(f"🗣 Transcript: **{text}**")
38
 
39
+ # ---------------- PARSER ----------------
40
+ expr = text.lower()
41
 
42
+ replacements = {
 
43
  "plus": "+",
44
  "minus": "-",
45
  "times": "*",
46
  "into": "*",
47
  "x": "*",
48
+ "divide by": "/",
49
  "divided by": "/",
50
+ "divide": "/",
51
  "to the power of": "**",
52
+ "power": "**",
53
  "square root of": "math.sqrt",
54
+ "sin": "math.sin(math.radians",
55
+ "cos": "math.cos(math.radians",
56
+ "tan": "math.tan(math.radians",
57
+ "log": "math.log10(",
58
+ "ln": "math.log(",
59
+ "point": "."
60
  }
61
 
62
+ # word-by-word replace
63
+ for word, symbol in replacements.items():
64
+ expr = expr.replace(word, symbol)
65
 
66
+ # close parentheses automatically
67
+ if "math.sin(math.radians" in expr: expr += ")"
68
+ if "math.cos(math.radians" in expr: expr += ")"
69
+ if "math.tan(math.radians" in expr: expr += ")"
70
+ if "math.log10(" in expr: expr += ")"
71
+ if "math.log(" in expr: expr += ")"
72
 
73
+ # cleanup
74
+ expr = re.sub(r"[^0-9+\-*/.()a-z* ]", "", expr)
75
+ st.code(expr, language="python")
76
 
77
+ # ---------------- CALCULATE ----------------
78
+ if "equal" in expr:
79
+ expr = expr.replace("equal","")
80
  try:
81
  result = eval(expr, {"math": math, "__builtins__": {}})
82
+ st.success(f"📊 Result: **{result}**")
83
  except Exception as e:
84
  st.error(f"Error: {e}")