33import { useEffect , useMemo , useState } from 'react' ;
44import { type VariantProps } from 'class-variance-authority' ;
55import { Track } from 'livekit-client' ;
6+ import { RoomAudioRenderer , StartAudio } from '@livekit/components-react' ;
67import {
78 type AgentState ,
89 type TrackReference ,
910 type TrackReferenceOrPlaceholder ,
1011 useLocalParticipant ,
12+ useVoiceAssistant ,
1113} from '@livekit/components-react' ;
1214import { MicrophoneIcon } from '@phosphor-icons/react/dist/ssr' ;
1315import { useSession } from '@/components/app/session-provider' ;
@@ -22,15 +24,13 @@ import {
2224 AudioBarVisualizer ,
2325 audioBarVisualizerVariants ,
2426} from '@/components/livekit/audio-visualizer/audio-bar-visualizer/audio-bar-visualizer' ;
25- import {
26- AudioGridVisualizer ,
27- type GridOptions ,
28- } from '@/components/livekit/audio-visualizer/audio-grid-visualizer/audio-grid-visualizer' ;
27+ import { AudioGridVisualizer } from '@/components/livekit/audio-visualizer/audio-grid-visualizer/audio-grid-visualizer' ;
2928import { gridVariants } from '@/components/livekit/audio-visualizer/audio-grid-visualizer/demos' ;
3029import {
3130 AudioRadialVisualizer ,
3231 audioRadialVisualizerVariants ,
3332} 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' ;
3434import { Button , buttonVariants } from '@/components/livekit/button' ;
3535import { ChatEntry } from '@/components/livekit/chat-entry' ;
3636import {
@@ -442,11 +442,11 @@ export const COMPONENTS = {
442442 'speaking' ,
443443 ] as AgentState [ ] ;
444444
445- const { microphoneTrack, localParticipant } = useLocalParticipant ( ) ;
446445 const [ rowCount , setRowCount ] = useState ( rowCounts [ 0 ] ) ;
447446 const [ columnCount , setColumnCount ] = useState ( columnCounts [ 0 ] ) ;
448447 const [ state , setState ] = useState < AgentState > ( states [ 0 ] ) ;
449448 const [ demoIndex , setDemoIndex ] = useState ( 0 ) ;
449+ const { microphoneTrack, localParticipant } = useLocalParticipant ( ) ;
450450
451451 const micTrackRef = useMemo < TrackReferenceOrPlaceholder | undefined > ( ( ) => {
452452 return state === 'speaking'
@@ -562,6 +562,127 @@ export const COMPONENTS = {
562562 ) ;
563563 } ,
564564
565+ AudioShaderVisualizer : ( ) => {
566+ const [ presetIndex , setPresetIndex ] = useState ( 0 ) ;
567+
568+ // speed
569+ const [ a , setA ] = useState ( 50 ) ;
570+ // // amplitude
571+ // const [c, setC] = useState(0.5);
572+ // // frequency
573+ // const [d, setD] = useState(0.3);
574+ // // scale
575+ // const [e, setE] = useState(0.3);
576+ // blur
577+ const [ f , setF ] = useState ( 0.4 ) ;
578+ // shape
579+ const [ g , setG ] = useState ( 1.0 ) ;
580+ // const [rawColor2, setRawColor2] = useState('#0000ff');
581+
582+ const [ rawColor1 , setRawColor1 ] = useState ( '#00ffff' ) ;
583+ const [ r1 , g1 , b1 ] = rawColor1 . match ( / \w \w / g) ! . map ( ( c ) => parseInt ( c , 16 ) ) ;
584+ // const [r2, g2, b2] = rawColor2.match(/\w\w/g)!.map((c) => parseInt(c, 16));
585+
586+ // const { microphoneTrack, localParticipant } = useLocalParticipant();
587+ // const micTrackRef = useMemo<TrackReferenceOrPlaceholder | undefined>(() => {
588+ // return {
589+ // participant: localParticipant,
590+ // source: Track.Source.Microphone,
591+ // publication: microphoneTrack,
592+ // } as TrackReference;
593+ // }, [localParticipant, microphoneTrack]);
594+
595+ const {
596+ // state,
597+ audioTrack,
598+ } = useVoiceAssistant ( ) ;
599+
600+ useMicrophone ( ) ;
601+
602+ const fields = [
603+ [ 'speed' , a , setA , 0 , 250 , 10 ] ,
604+ // ['amplitude', c, setC, 0, 3, 0.01],
605+ // ['frequency', d, setD],
606+ // ['scale', e, setE, 0.1, 1, 0.01],
607+ [ 'blur' , f , setF , 0 , 2 , 0.1 ] ,
608+ [ 'shape' , g , setG , 1 , 5 , 1 ] ,
609+ ] as const ;
610+
611+ return (
612+ < Container componentName = "AudioShaderVisualizer" >
613+ < StartAudio label = "Start Audio" />
614+ < RoomAudioRenderer />
615+ < div className = "grid grid-cols-2 gap-4" >
616+ < AudioShaderVisualizer
617+ speed = { a }
618+ // intensity={0}
619+ // amplitude={c}
620+ // frequency={d}
621+ // scale={e}
622+ blur = { f }
623+ shape = { g }
624+ colorPhase = { [ r1 , g1 , b1 ] }
625+ audioTrack = { audioTrack }
626+ presetIndex = { presetIndex }
627+ // className="bg-amber-100"
628+ />
629+ < div >
630+ < div className = "mb-4" >
631+ < StoryTitle > Preset</ StoryTitle >
632+ < Select
633+ value = { String ( presetIndex ) }
634+ onValueChange = { ( value ) => setPresetIndex ( parseInt ( value ) ) }
635+ >
636+ < SelectTrigger id = "presetIndex" className = "w-full" >
637+ < SelectValue placeholder = "Select a preset" />
638+ </ SelectTrigger >
639+ < SelectContent >
640+ < SelectItem value = "0" > Preset 1</ SelectItem >
641+ < SelectItem value = "1" > Preset 2</ SelectItem >
642+ < SelectItem value = "2" > Preset 3</ SelectItem >
643+ < SelectItem value = "3" > Preset 4</ SelectItem >
644+ </ SelectContent >
645+ </ Select >
646+ </ div >
647+
648+ { fields . map ( ( [ name , value , setValue , min = 0.1 , max = 10 , step = 0.1 ] ) => {
649+ // Use 0-1 range for color phase channels
650+ const isColorPhase = name . toString ( ) . startsWith ( 'colorPhase' ) ;
651+
652+ return (
653+ < div key = { name } >
654+ < div className = "flex items-center justify-between" >
655+ < StoryTitle > { name } </ StoryTitle >
656+ < div className = "text-muted-foreground mb-2 text-xs" >
657+ { isColorPhase ? Number ( value ) . toFixed ( 2 ) : String ( value ) }
658+ </ div >
659+ </ div >
660+ < input
661+ type = "range"
662+ value = { String ( value ) }
663+ min = { min }
664+ max = { max }
665+ step = { step }
666+ onChange = { ( e ) => setValue ( parseFloat ( e . target . value ) ) }
667+ className = "w-full"
668+ />
669+ </ div >
670+ ) ;
671+ } ) }
672+ < div >
673+ < StoryTitle > Colors</ StoryTitle >
674+ < input
675+ type = "color"
676+ value = { rawColor1 }
677+ onChange = { ( e ) => setRawColor1 ( e . target . value ) }
678+ />
679+ </ div >
680+ </ div >
681+ </ div >
682+ </ Container >
683+ ) ;
684+ } ,
685+
565686 // Agent control bar
566687 AgentControlBar : ( ) => {
567688 useMicrophone ( ) ;
0 commit comments