Skip to content

Commit edd1537

Browse files
committed
fix to unresponsive code bug
1 parent b46639c commit edd1537

4 files changed

Lines changed: 95 additions & 9 deletions

File tree

‎apps/llm/app/multimodal_llm/index.tsx‎

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import Spinner from '../../components/Spinner';
2828
import { GeneratingContext } from '../../context';
2929
import SuggestedPrompts from '../../components/SuggestedPrompts';
3030
import ErrorBanner from '../../components/ErrorBanner';
31+
import AudioWaveform from '../../components/AudioWaveform';
3132

3233
const SUGGESTED_PROMPTS = [
3334
"What's in this image?",
@@ -291,10 +292,16 @@ function MultimodalLLMScreen() {
291292
{/* Audio attachment strip */}
292293
{audioLabel && (
293294
<View style={styles.audioAttachmentContainer}>
294-
<Text style={styles.audioAttachmentText}>🎵 {audioLabel}</Text>
295-
<TouchableOpacity onPress={clearAudio}>
296-
<Text style={styles.audioAttachmentClear}>✕</Text>
297-
</TouchableOpacity>
295+
<View style={styles.audioAttachmentRow}>
296+
<Text style={styles.audioAttachmentText}>🎵 {audioLabel}</Text>
297+
<TouchableOpacity onPress={clearAudio}>
298+
<Text style={styles.audioAttachmentClear}>✕</Text>
299+
</TouchableOpacity>
300+
</View>
301+
<AudioWaveform
302+
buffer={audioBuffer}
303+
style={styles.audioWaveform}
304+
/>
298305
</View>
299306
)}
300307

@@ -471,9 +478,7 @@ const styles = StyleSheet.create({
471478
color: ColorPalette.blueDark,
472479
},
473480
audioAttachmentContainer: {
474-
flexDirection: 'row',
475-
alignItems: 'center',
476-
justifyContent: 'space-between',
481+
flexDirection: 'column',
477482
paddingHorizontal: 16,
478483
paddingVertical: 8,
479484
marginHorizontal: 16,
@@ -483,6 +488,11 @@ const styles = StyleSheet.create({
483488
borderColor: ColorPalette.blueLight,
484489
backgroundColor: '#fafbff',
485490
},
491+
audioAttachmentRow: {
492+
flexDirection: 'row',
493+
alignItems: 'center',
494+
justifyContent: 'space-between',
495+
},
486496
audioAttachmentText: {
487497
fontSize: 13,
488498
fontFamily: 'regular',
@@ -493,6 +503,10 @@ const styles = StyleSheet.create({
493503
color: ColorPalette.blueDark,
494504
paddingHorizontal: 8,
495505
},
506+
audioWaveform: {
507+
marginTop: 6,
508+
minWidth: 0,
509+
},
496510
audioUrlRow: {
497511
flexDirection: 'row',
498512
alignItems: 'center',
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { useMemo } from 'react';
2+
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
3+
import ColorPalette from '../colors';
4+
5+
interface AudioWaveformProps {
6+
buffer: Float32Array | null | undefined;
7+
style?: StyleProp<ViewStyle>;
8+
}
9+
10+
const NUM_BARS = 32;
11+
12+
export default function AudioWaveform({ buffer, style }: AudioWaveformProps) {
13+
const bars = useMemo(() => {
14+
if (!buffer || buffer.length === 0) return null;
15+
const chunkSize = Math.max(1, Math.floor(buffer.length / NUM_BARS));
16+
const peaks: number[] = [];
17+
let max = 0;
18+
for (let i = 0; i < NUM_BARS; i++) {
19+
const start = i * chunkSize;
20+
const end = Math.min(start + chunkSize, buffer.length);
21+
let peak = 0;
22+
for (let j = start; j < end; j++) {
23+
const v = Math.abs(buffer[j] ?? 0);
24+
if (v > peak) peak = v;
25+
}
26+
peaks.push(peak);
27+
if (peak > max) max = peak;
28+
}
29+
return max > 0 ? peaks.map((p) => p / max) : peaks;
30+
}, [buffer]);
31+
32+
if (!bars) return null;
33+
34+
return (
35+
<View style={[styles.container, style]}>
36+
{bars.map((amp, i) => (
37+
<View key={i} style={[styles.bar, { height: 2 + amp * 14 }]} />
38+
))}
39+
</View>
40+
);
41+
}
42+
43+
const styles = StyleSheet.create({
44+
container: {
45+
flexDirection: 'row',
46+
alignItems: 'center',
47+
height: 16,
48+
minWidth: 160,
49+
gap: 2,
50+
},
51+
bar: {
52+
flex: 1,
53+
borderRadius: 1,
54+
backgroundColor: ColorPalette.blueDark,
55+
opacity: 0.35,
56+
},
57+
});

‎apps/llm/components/MessageItem.tsx‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import MarkdownComponent from './MarkdownComponent';
1111
import LlamaIcon from '../assets/icons/llama_icon.svg';
1212
import ColorPalette from '../colors';
1313
import { Message } from 'react-native-executorch';
14+
import AudioWaveform from './AudioWaveform';
1415

1516
interface MessageItemProps {
1617
message: Message;
@@ -43,6 +44,12 @@ const MessageItem = memo(({ message, deleteMessage }: MessageItemProps) => {
4344
resizeMode="contain"
4445
/>
4546
)}
47+
{message.audioWaveform && (
48+
<AudioWaveform
49+
buffer={message.audioWaveform}
50+
style={styles.userMessageWaveform}
51+
/>
52+
)}
4653
<MarkdownComponent text={message.content} />
4754
</View>
4855
</View>
@@ -103,6 +110,9 @@ const styles = StyleSheet.create({
103110
borderRadius: 6,
104111
marginBottom: 6,
105112
},
113+
userMessageWaveform: {
114+
marginBottom: 6,
115+
},
106116
aiMessageIconContainer: {
107117
backgroundColor: ColorPalette.seaBlueLight,
108118
height: 32,

‎packages/react-native-executorch/src/controllers/LLMController.ts‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ export class LLMController {
297297
const hasImages = !!imagePaths && imagePaths.length > 0;
298298
const hasAudio = !!audioWaveforms && audioWaveforms.length > 0;
299299
try {
300+
console.log('kappa');
300301
this.isGeneratingCallback(true);
301302
this.nativeModule.reset();
302303
let response: string;
@@ -360,6 +361,8 @@ export class LLMController {
360361
messages: Message[],
361362
tools?: LLMTool[]
362363
): Promise<string> {
364+
let s = performance.now();
365+
console.log('kappa', performance.now() - s);
363366
if (!this._isReady) {
364367
throw new RnExecutorchError(
365368
RnExecutorchErrorCode.ModuleNotLoaded,
@@ -384,13 +387,13 @@ export class LLMController {
384387
const audioWaveforms = messages
385388
.filter((m) => m.audioWaveform)
386389
.map((m) => m.audioWaveform!);
387-
388390
const renderedChat: string = this.applyChatTemplate(
389391
messages,
390392
this.tokenizerConfig,
391393
tools,
392394
{ tools_in_user_message: false, add_generation_prompt: true }
393395
);
396+
console.log('kappa', performance.now() - s);
394397

395398
return await this.forward(
396399
renderedChat,
@@ -553,6 +556,8 @@ function messagesForChatTemplate(messages: Message[]): any[] {
553556
if (hasImage) parts.push({ type: 'image' });
554557
if (hasAudio) parts.push({ type: 'audio' });
555558
parts.push({ type: 'text', text: m.content });
556-
return { ...m, content: parts };
559+
// Drop the Float32Array on the clone only — passing it into the Jinja
560+
// template engine slows render past 3s. Don't mutate m;
561+
return { ...m, content: parts, audioWaveform: undefined };
557562
});
558563
}

0 commit comments

Comments
 (0)