1+ import type { VRM } from '@pixiv/three-vrm'
12import type { PositionalAudio } from 'three'
23
34import { useThree } from '@react-three/fiber'
45import { useEffect , useMemo , useRef } from 'react'
56import { AudioListener } from 'three'
67
78import { useAudioBuffer } from '~/context/audio-buffer'
9+ import { useAudioContext } from '~/context/audio-context'
10+ import { useLipSync } from '~/hooks/use-lip-sync'
811
9- export const GalateaTTS = ( ) => {
12+ export const GalateaTTS = ( { vrm } : { vrm : VRM } ) => {
1013 const { camera } = useThree ( )
1114 const sound = useRef < PositionalAudio > ( null )
1215 const listener = useMemo ( ( ) => new AudioListener ( ) , [ ] )
1316 const audioBuffer = useAudioBuffer ( )
17+ const audioContext = useAudioContext ( )
18+ const audioBufferSource = useMemo ( ( ) => {
19+ const audioBufferSource = audioContext . createBufferSource ( )
20+ audioBufferSource . buffer = audioBuffer ?? null
21+ return audioBufferSource
22+ } , [ audioContext , audioBuffer ] )
23+
24+ useLipSync ( audioBufferSource , vrm )
1425
1526 useEffect ( ( ) => {
1627 const _sound = sound . current
@@ -20,16 +31,21 @@ export const GalateaTTS = () => {
2031 // _sound.setRefDistance(1)
2132 _sound . setLoop ( false )
2233 _sound . play ( )
34+ audioBufferSource . start ( )
2335 }
2436
2537 return ( ) => {
26- if ( ! _sound )
27- return
28-
29- _sound . stop ( )
30- _sound . clear ( )
38+ try {
39+ audioBufferSource . stop ( )
40+ }
41+ catch { }
42+
43+ if ( _sound ) {
44+ _sound . stop ( )
45+ _sound . clear ( )
46+ }
3147 }
32- } , [ sound , audioBuffer ] )
48+ } , [ sound , audioBuffer , audioBufferSource ] )
3349
3450 useEffect ( ( ) => {
3551 camera . add ( listener )
0 commit comments