From 49bcb76a8433b18da299078caa11c9760cebc284 Mon Sep 17 00:00:00 2001 From: twitchard Date: Fri, 19 Sep 2025 16:30:05 -0500 Subject: [PATCH 1/7] wip --- evi/evi-react-native/App.tsx | 18 ++++++ .../VoiceIsolationModePrompt.tsx | 64 +++++++++++++++++++ .../modules/audio/ios/AudioModule.swift | 28 ++++++++ .../modules/audio/src/AudioModule.ts | 2 + evi/evi-react-native/package-lock.json | 27 +++++++- evi/evi-react-native/package.json | 5 +- 6 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 evi/evi-react-native/VoiceIsolationModePrompt.tsx diff --git a/evi/evi-react-native/App.tsx b/evi/evi-react-native/App.tsx index 2ea92d0a..b5e31838 100644 --- a/evi/evi-react-native/App.tsx +++ b/evi/evi-react-native/App.tsx @@ -22,6 +22,7 @@ import { HumeClient, type Hume } from "hume"; // The provided native module is a good starting place, but you should // modify it to fit the audio recording needs of your specific app. import NativeAudio, { AudioEventPayload } from "./modules/audio"; +import VoiceIsolationModePrompt from "./VoiceIsolationModePrompt"; // Represents a chat message in the chat display. interface ChatEntry { @@ -55,6 +56,8 @@ const App = () => { const [isConnected, setIsConnected] = useState(false); const [isMuted, setIsMuted] = useState(false); const [chatEntries, setChatEntries] = useState([]); + const [showVoiceIsolationPrompt, setShowVoiceIsolationPrompt] = useState(false); + const [currentMicMode, setCurrentMicMode] = useState("Standard"); const humeRef = useRef(null); const addChatEntry = (entry: ChatEntry) => { setChatEntries((prev) => [...prev, entry]); @@ -90,6 +93,15 @@ const App = () => { console.error("Microphone permission denied"); return; } + + // Check microphone mode + const micMode = await NativeAudio.getMicrophoneMode(); + setCurrentMicMode(micMode); + + // Show prompt if not in Voice Isolation mode + if (micMode !== "Voice Isolation") { + setShowVoiceIsolationPrompt(true); + } } catch (error) { console.error("Failed to get permissions:", error); return; @@ -290,6 +302,12 @@ const App = () => { /> + + setShowVoiceIsolationPrompt(false)} + /> ); }; diff --git a/evi/evi-react-native/VoiceIsolationModePrompt.tsx b/evi/evi-react-native/VoiceIsolationModePrompt.tsx new file mode 100644 index 00000000..f8983861 --- /dev/null +++ b/evi/evi-react-native/VoiceIsolationModePrompt.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { + View, + Text, + Button, + Linking, + Platform, +} from 'react-native'; +import Modal from 'react-native-modal'; +import NativeAudio from './modules/audio'; + +interface VoiceIsolationModePromptProps { + isVisible: boolean; + currentMode: string; + onDismiss: () => void; +} + +const VoiceIsolationModePrompt: React.FC = ({ + isVisible, + currentMode, + onDismiss, +}) => { + const handleOpenSettings = async () => { + if (Platform.OS === 'ios') { + try { + await NativeAudio.showMicrophoneModes(); + } catch (error) { + // Fallback to general settings if the API is not available + Linking.openSettings(); + } + } else { + Linking.openSettings(); + } + onDismiss(); + }; + + const handleShowMeHow = () => { + const supportUrl = 'https://support.apple.com/guide/iphone/aside/iph45075b5b2/ios'; + Linking.openURL(supportUrl); + }; + + return ( + + + Enable voice isolation for the best experience + + + Your device is currently using a {currentMode} microphone mode. + Enabling voice isolation will provide the best audio experience + in a noisy setting. + + +