|
|
|
@ -58,6 +58,7 @@ export function FreeFlow(){ |
|
|
|
|
|
|
|
|
|
|
|
const refPauseTimer=useRef(); |
|
|
|
const refPauseTimer=useRef(); |
|
|
|
const refSpeechPaused=useRef(false); |
|
|
|
const refSpeechPaused=useRef(false); |
|
|
|
|
|
|
|
const refChatCueEnd=useRef(false); |
|
|
|
|
|
|
|
|
|
|
|
const refContainer=useRef(); |
|
|
|
const refContainer=useRef(); |
|
|
|
|
|
|
|
|
|
|
|
@ -78,12 +79,26 @@ export function FreeFlow(){ |
|
|
|
|
|
|
|
|
|
|
|
function resetData() { |
|
|
|
function resetData() { |
|
|
|
setSummary(null); |
|
|
|
setSummary(null); |
|
|
|
|
|
|
|
|
|
|
|
reset(); |
|
|
|
reset(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function playAudio(url){ |
|
|
|
function playAudio(url){ |
|
|
|
if(!url) return; |
|
|
|
if(!url) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//TODO: if cue end, don't play audio |
|
|
|
|
|
|
|
if(refCurrentCue.current?.type=='chat'){ |
|
|
|
|
|
|
|
if(refChatCueEnd.current) { |
|
|
|
|
|
|
|
console.log('Chat cue has ended, not playing audio:', url); |
|
|
|
|
|
|
|
setChatStatus(ChatStatus.Clear); // Reset chat status to Clear |
|
|
|
|
|
|
|
onCueEnd(); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// if audio time larger than cue remaining time, don't play audio |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log('Playing audio:', url); |
|
|
|
console.log('Playing audio:', url); |
|
|
|
|
|
|
|
|
|
|
|
if(refAudio.current) { |
|
|
|
if(refAudio.current) { |
|
|
|
@ -101,6 +116,15 @@ export function FreeFlow(){ |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
audio.addEventListener("loadedmetadata", () => { |
|
|
|
|
|
|
|
if(refCurrentCue.current?.type!='chat' && refCurrentCue.current?.type!='user_input') { |
|
|
|
|
|
|
|
refTimer.current?.restart(audio.duration*1000 || 0); |
|
|
|
|
|
|
|
}else{ |
|
|
|
|
|
|
|
if(refCurrentCue.current?.type=='chat') setChatStatus(()=>ChatStatus.System); |
|
|
|
|
|
|
|
else setChatStatus(()=>ChatStatus.Clear); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
audio.onended = () => { |
|
|
|
audio.onended = () => { |
|
|
|
if(refCurrentCue.current?.type!='chat') onCueEnd(); |
|
|
|
if(refCurrentCue.current?.type!='chat') onCueEnd(); |
|
|
|
else{ |
|
|
|
else{ |
|
|
|
@ -123,27 +147,29 @@ export function FreeFlow(){ |
|
|
|
updatePrompt(prompt); |
|
|
|
updatePrompt(prompt); |
|
|
|
sendOsc(OSC_ADDRESS.PROMPT, prompt); |
|
|
|
sendOsc(OSC_ADDRESS.PROMPT, prompt); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(refChatCueEnd.current){ |
|
|
|
|
|
|
|
console.log('Talking ended, ending current cue'); |
|
|
|
|
|
|
|
onCueEnd(); // End the current cue if chat cue has ended |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
refAudio.current = audio; // Store the new audio reference |
|
|
|
refAudio.current = audio; // Store the new audio reference |
|
|
|
audio.addEventListener("loadedmetadata", () => { |
|
|
|
|
|
|
|
if(refCurrentCue.current?.type!='chat' && refCurrentCue.current?.type!='user_input') { |
|
|
|
|
|
|
|
refTimer.current?.restart(audio.duration*1000 || 0); |
|
|
|
|
|
|
|
}else{ |
|
|
|
|
|
|
|
if(refCurrentCue.current?.type=='chat') setChatStatus(()=>ChatStatus.System); |
|
|
|
|
|
|
|
else setChatStatus(()=>ChatStatus.Clear); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
function playCue(cue) { |
|
|
|
function playCue(cue) { |
|
|
|
|
|
|
|
|
|
|
|
if(!cue) return; |
|
|
|
if(!cue) return; |
|
|
|
console.log('Playing cue:', cue); |
|
|
|
console.log('Playing cue:', cue); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
setCurrentCue(cue); |
|
|
|
setCurrentCue(cue); |
|
|
|
refCurrentCue.current = cue; // Store the current cue in ref |
|
|
|
refCurrentCue.current = cue; // Store the current cue in ref |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(parseFloat(cue.id)<=4.2){ |
|
|
|
if(parseFloat(cue.id)<=4.2){ |
|
|
|
// Special case for starting a conversation |
|
|
|
// Special case for starting a conversation |
|
|
|
console.log('clear conversation...'); |
|
|
|
console.log('clear conversation...'); |
|
|
|
@ -158,6 +184,7 @@ export function FreeFlow(){ |
|
|
|
switch(cue.type){ |
|
|
|
switch(cue.type){ |
|
|
|
case 'chat': |
|
|
|
case 'chat': |
|
|
|
// Special case for starting a conversation |
|
|
|
// Special case for starting a conversation |
|
|
|
|
|
|
|
refChatCueEnd.current=false; |
|
|
|
resetTranscript(); |
|
|
|
resetTranscript(); |
|
|
|
console.log('Starting conversation...'); |
|
|
|
console.log('Starting conversation...'); |
|
|
|
sendMessage(null, false, false, voice); // Send initial message with voice |
|
|
|
sendMessage(null, false, false, voice); // Send initial message with voice |
|
|
|
@ -233,11 +260,20 @@ export function FreeFlow(){ |
|
|
|
function onCueEnd() { |
|
|
|
function onCueEnd() { |
|
|
|
|
|
|
|
|
|
|
|
refTimer.current?.stop(); // Stop the timer when cue ends |
|
|
|
refTimer.current?.stop(); // Stop the timer when cue ends |
|
|
|
refAudio.current?.pause(); // Pause any playing audio |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!refCurrentCue.current) return; |
|
|
|
if(!refCurrentCue.current) return; |
|
|
|
const cue= refCurrentCue.current; // Get the current cue from ref |
|
|
|
const cue= refCurrentCue.current; // Get the current cue from ref |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(cue.type=='chat'){ |
|
|
|
|
|
|
|
if(chatStatus==ChatStatus.System) { |
|
|
|
|
|
|
|
console.log('Still talking...'); |
|
|
|
|
|
|
|
refChatCueEnd.current=true; |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
refAudio.current?.pause(); // Pause any playing audio |
|
|
|
console.log('onCueEnd:', cue.id); |
|
|
|
console.log('onCueEnd:', cue.id); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|