@@ -30,7 +30,10 @@ import {
3030 AudioRadialVisualizer ,
3131 audioRadialVisualizerVariants ,
3232} from '@/components/livekit/audio-visualizer/audio-radial-visualizer/audio-radial-visualizer' ;
33- import { AudioShaderVisualizer } from '@/components/livekit/audio-visualizer/audio-shader-visualizer/audio-shader-visualizer' ;
33+ import {
34+ AudioShaderVisualizer ,
35+ audioShaderVisualizerVariants ,
36+ } from '@/components/livekit/audio-visualizer/audio-shader-visualizer/audio-shader-visualizer' ;
3437import { Button , buttonVariants } from '@/components/livekit/button' ;
3538import { ChatEntry } from '@/components/livekit/chat-entry' ;
3639import {
@@ -52,6 +55,9 @@ type audioBarVisualizerVariantsSizeType = VariantProps<typeof audioBarVisualizer
5255type audioRadialVisualizerVariantsSizeType = VariantProps <
5356 typeof audioRadialVisualizerVariants
5457> [ 'size' ] ;
58+ type audioShaderVisualizerVariantsSizeType = VariantProps <
59+ typeof audioShaderVisualizerVariants
60+ > [ 'size' ] ;
5561
5662export function useMicrophone ( ) {
5763 const { startSession } = useSession ( ) ;
@@ -563,93 +569,147 @@ export const COMPONENTS = {
563569 } ,
564570
565571 AudioShaderVisualizer : ( ) => {
566- const [ presetIndex , setPresetIndex ] = useState ( 3 ) ;
567-
568- // speed
569- const [ a , setA ] = useState ( 50 ) ;
570- // // color scale
571- const [ h , setH ] = useState ( 0.1 ) ;
572- // // color position
573- const [ i , setI ] = useState ( 0.15 ) ;
574- // blur
575- const [ f , setF ] = useState ( 0.1 ) ;
572+ const { startSession, endSession } = useSession ( ) ;
573+ const { localParticipant } = useLocalParticipant ( ) ;
574+
576575 // shape
577- const [ g , setG ] = useState ( 1.0 ) ;
576+ const [ shape , setShape ] = useState ( 1.0 ) ;
577+ // color scale
578+ const [ colorScale , setColorScale ] = useState ( 0.1 ) ;
579+ // color position
580+ const [ colorPosition , setColorPosition ] = useState ( 0.15 ) ;
581+
582+ const sizes = [ 'icon' , 'sm' , 'md' , 'lg' , 'xl' ] ;
583+ const states = [
584+ 'disconnected' ,
585+ 'connecting' ,
586+ 'initializing' ,
587+ 'listening' ,
588+ 'thinking' ,
589+ 'speaking' ,
590+ ] as AgentState [ ] ;
591+
592+ const [ size , setSize ] = useState < audioShaderVisualizerVariantsSizeType > ( 'lg' ) ;
593+ const [ state , setState ] = useState < AgentState > ( states [ 0 ] ) ;
578594
579595 const {
580596 // state,
581597 audioTrack,
582598 } = useVoiceAssistant ( ) ;
583599
584- useMicrophone ( ) ;
600+ useEffect ( ( ) => {
601+ if ( state === 'speaking' ) {
602+ startSession ( ) ;
603+ localParticipant . setMicrophoneEnabled ( true , undefined ) ;
604+ } else {
605+ endSession ( ) ;
606+ localParticipant . setMicrophoneEnabled ( false , undefined ) ;
607+ }
608+ } , [ startSession , endSession , state , localParticipant ] ) ;
585609
586610 const fields = [
587- [ 'speed' , a , setA , 0 , 250 , 10 ] ,
588- [ 'color position' , i , setI , 0 , 1 , 0.01 ] ,
589- [ 'color scale' , h , setH , 0 , 1 , 0.01 ] ,
590- [ 'blur' , f , setF , 0 , 2 , 0.01 ] ,
591- [ 'shape' , g , setG , 1 , 5 , 1 ] ,
611+ [ 'color position' , colorPosition , setColorPosition , 0 , 1 , 0.01 ] ,
612+ [ 'color scale' , colorScale , setColorScale , 0 , 1 , 0.01 ] ,
592613 ] as const ;
593614
594615 return (
595616 < Container componentName = "AudioShaderVisualizer" >
596617 < StartAudio label = "Start Audio" />
597618 < RoomAudioRenderer />
598- < div className = "grid grid-cols-2 gap-4" >
619+
620+ < div className = "flex gap-4" >
621+ < div className = "flex-1" >
622+ < label className = "font-mono text-xs uppercase" htmlFor = "state" >
623+ State
624+ </ label >
625+ < Select value = { state } onValueChange = { ( value ) => setState ( value as AgentState ) } >
626+ < SelectTrigger id = "state" className = "w-full" >
627+ < SelectValue placeholder = "Select a state" />
628+ </ SelectTrigger >
629+ < SelectContent >
630+ { states . map ( ( state ) => (
631+ < SelectItem key = { state } value = { state } >
632+ { state }
633+ </ SelectItem >
634+ ) ) }
635+ </ SelectContent >
636+ </ Select >
637+ </ div >
638+
639+ < div className = "flex-1" >
640+ < label className = "font-mono text-xs uppercase" htmlFor = "size" >
641+ Size
642+ </ label >
643+ < Select
644+ value = { size as string }
645+ onValueChange = { ( value ) => setSize ( value as audioShaderVisualizerVariantsSizeType ) }
646+ >
647+ < SelectTrigger id = "size" className = "w-full" >
648+ < SelectValue placeholder = "Select a size" />
649+ </ SelectTrigger >
650+ < SelectContent >
651+ { sizes . map ( ( size ) => (
652+ < SelectItem key = { size } value = { size as string } >
653+ { size . toUpperCase ( ) }
654+ </ SelectItem >
655+ ) ) }
656+ </ SelectContent >
657+ </ Select >
658+ </ div >
659+
660+ < div className = "flex-1" >
661+ < label className = "font-mono text-xs uppercase" htmlFor = "shape" >
662+ Shape
663+ </ label >
664+ < Select value = { shape . toString ( ) } onValueChange = { ( value ) => setShape ( parseInt ( value ) ) } >
665+ < SelectTrigger id = "shape" className = "w-full" >
666+ < SelectValue placeholder = "Select a shape" />
667+ </ SelectTrigger >
668+ < SelectContent >
669+ < SelectItem value = "1" > Circle</ SelectItem >
670+ < SelectItem value = "2" > Line</ SelectItem >
671+ </ SelectContent >
672+ </ Select >
673+ </ div >
674+ </ div >
675+
676+ < div className = "py-12" >
599677 < AudioShaderVisualizer
600- speed = { a }
601- blur = { f }
602- shape = { g }
603- colorScale = { h }
604- colorPosition = { i }
605- audioTrack = { audioTrack }
606- presetIndex = { presetIndex }
607- // className="bg-amber-100"
678+ size = { size }
679+ state = { state }
680+ shape = { shape }
681+ colorScale = { colorScale }
682+ colorPosition = { colorPosition }
683+ audioTrack = { audioTrack as TrackReferenceOrPlaceholder }
684+ className = "mx-auto bg-black"
608685 />
609- < div >
610- < div className = "mb-4" >
611- < StoryTitle > Preset</ StoryTitle >
612- < Select
613- value = { String ( presetIndex ) }
614- onValueChange = { ( value ) => setPresetIndex ( parseInt ( value ) ) }
615- >
616- < SelectTrigger id = "presetIndex" className = "w-full" >
617- < SelectValue placeholder = "Select a preset" />
618- </ SelectTrigger >
619- < SelectContent >
620- < SelectItem value = "0" > Preset 1</ SelectItem >
621- < SelectItem value = "1" > Preset 2</ SelectItem >
622- < SelectItem value = "2" > Preset 3</ SelectItem >
623- < SelectItem value = "3" > Preset 4</ SelectItem >
624- </ SelectContent >
625- </ Select >
626- </ div >
686+ </ div >
627687
628- { fields . map ( ( [ name , value , setValue , min = 0.1 , max = 10 , step = 0.1 ] ) => {
629- // Use 0-1 range for color phase channels
630- const isColorPhase = name . toString ( ) . startsWith ( 'colorPhase' ) ;
631-
632- return (
633- < div key = { name } >
634- < div className = "flex items-center justify-between" >
635- < StoryTitle > { name } </ StoryTitle >
636- < div className = "text-muted-foreground mb-2 text-xs" >
637- { isColorPhase ? Number ( value ) . toFixed ( 2 ) : String ( value ) }
638- </ div >
688+ < div className = "grid grid-cols-2 gap-4" >
689+ { fields . map ( ( [ name , value , setValue , min = 0.1 , max = 10 , step = 0.1 ] ) => {
690+ // Use 0-1 range for color phase channels
691+ const isColorPhase = name . toString ( ) . startsWith ( 'colorPhase' ) ;
692+
693+ return (
694+ < div key = { name } >
695+ < div className = "flex items-center justify-between" >
696+ < StoryTitle > { name } </ StoryTitle >
697+ < div className = "text-muted-foreground mb-2 text-xs" >
698+ { isColorPhase ? Number ( value ) . toFixed ( 2 ) : String ( value ) }
639699 </ div >
640- < input
641- type = "range"
642- value = { String ( value ) }
643- min = { min }
644- max = { max }
645- step = { step }
646- onChange = { ( e ) => setValue ( parseFloat ( e . target . value ) ) }
647- className = "w-full"
648- />
649700 </ div >
650- ) ;
651- } ) }
652- </ div >
701+ < input
702+ type = "range"
703+ value = { String ( value ) }
704+ min = { min }
705+ max = { max }
706+ step = { step }
707+ onChange = { ( e ) => setValue ( parseFloat ( e . target . value ) ) }
708+ className = "w-full"
709+ />
710+ </ div >
711+ ) ;
712+ } ) }
653713 </ div >
654714 </ Container >
655715 ) ;
0 commit comments