File size: 2,126 Bytes
25647ae
 
 
79eafc9
 
25647ae
 
 
 
 
 
79eafc9
25647ae
 
 
 
 
 
 
 
 
e081e36
 
 
 
 
25647ae
 
 
 
 
 
 
 
 
 
79eafc9
 
25647ae
 
 
 
 
79eafc9
 
 
 
 
 
25647ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { createContext, useContext, useState, ReactNode } from 'react'

export interface TextToSpeechConfigState {
  speakerEmbeddings?: string
  voice?: string
}

export interface AudioResult {
  audio: Float32Array
  sampling_rate: number
  text: string
  voice?: string
}

interface TextToSpeechContextType {
  config: TextToSpeechConfigState
  setConfig: React.Dispatch<React.SetStateAction<TextToSpeechConfigState>>
  audioResults: AudioResult[]
  setAudioResults: React.Dispatch<React.SetStateAction<AudioResult[]>>
  currentText: string
  setCurrentText: React.Dispatch<React.SetStateAction<string>>
  addAudioResult: (
    text: string,
    audio: Omit<AudioResult, 'text'>,
    voice?: string
  ) => void
  clearAudioResults: () => void
}

const TextToSpeechContext = createContext<TextToSpeechContextType | undefined>(
  undefined
)

export function TextToSpeechProvider({ children }: { children: ReactNode }) {
  const [config, setConfig] = useState<TextToSpeechConfigState>({
    speakerEmbeddings:
      'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/speaker_embeddings.bin',
    voice: undefined
  })

  const [audioResults, setAudioResults] = useState<AudioResult[]>([])
  const [currentText, setCurrentText] = useState<string>('')

  const addAudioResult = (
    text: string,
    audio: Omit<AudioResult, 'text'>,
    voice?: string
  ) => {
    const fullAudioResult: AudioResult = { ...audio, text, voice }
    setAudioResults((prev) => [...prev, fullAudioResult])
  }

  const clearAudioResults = () => {
    setAudioResults([])
    setCurrentText('')
  }

  const value = {
    config,
    setConfig,
    audioResults,
    setAudioResults,
    currentText,
    setCurrentText,
    addAudioResult,
    clearAudioResults
  }

  return (
    <TextToSpeechContext.Provider value={value}>
      {children}
    </TextToSpeechContext.Provider>
  )
}

export function useTextToSpeech() {
  const context = useContext(TextToSpeechContext)
  if (context === undefined) {
    throw new Error(
      'useTextToSpeech must be used within a TextToSpeechProvider'
    )
  }
  return context
}