Skip to content

Commit

Permalink
fix: bugs introduced by migration
Browse files Browse the repository at this point in the history
  • Loading branch information
nekomeowww committed Dec 13, 2024
1 parent 2d9cdd2 commit 8514573
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 50 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"i18n-ally.sourceLanguage": "en",
"i18n-ally.keystyle": "nested",
"i18n-ally.localesPaths": "locales",
"i18n-ally.localesPaths": [
"packages/stage/locales"
],
"i18n-ally.sortKeys": true,

// Disable the default formatter
Expand Down
4 changes: 2 additions & 2 deletions packages/stage/src/components/Widgets/ChatHistory.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<script setup lang="ts">
import type { Message } from '@xsai/shared-chat-completion'
import { storeToRefs } from 'pinia'
import { ref } from 'vue'
import Avatar from '../../assets/live2d/models/hiyori_free_zh/avatar.png'
import { useMarkdown } from '../../composables/markdown'
import { useSpeakingStore } from '../../stores/audio'
const messages = ref<Message[]>([])
const chatHistoryRef = ref<HTMLDivElement>()
const { messages } = storeToRefs(useChatStore())
const bounding = useElementBounding(chatHistoryRef, { immediate: true, windowScroll: true, windowResize: true })
const { y: chatHistoryContainerY } = useScroll(chatHistoryRef)
Expand Down
86 changes: 44 additions & 42 deletions packages/stage/src/components/Widgets/InputArea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,65 +6,28 @@ import { ref } from 'vue'
import WhisperWorker from '../../libs/workers/worker?worker&url'
import { encodeWAVToBase64 } from '../../utils/binary'
const messageInput = ref('')
const supportedModels = ref<{ id: string, name?: string }[]>([])
const listening = ref(false)
const { audioInputs } = useDevicesList({ constraints: { audio: true }, requestPermissions: true })
const { openAiModel, openAiApiBaseURL, openAiApiKey, selectedAudioDevice, isAudioInputOn, selectedAudioDeviceId } = storeToRefs(useSettings())
const { models } = useLLM()
const { send, onAfterSend } = useChatStore()
const { audioContext } = useAudioContext()
const { t } = useI18n()
const messageInput = ref('')
const supportedModels = ref<{ id: string, name?: string }[]>([])
const listening = ref(false)
function handleModelChange(event: Event) {
const target = event.target as HTMLSelectElement
const found = supportedModels.value.find(m => m.id === target.value)
if (!found) {
openAiModel.value = undefined
return
}
openAiModel.value = found
}
async function handleAudioInputChange(event: Event) {
const target = event.target as HTMLSelectElement
const found = audioInputs.value.find(d => d.deviceId === target.value)
if (!found) {
selectedAudioDevice.value = undefined
return
}
selectedAudioDevice.value = found
}
const { transcribe: generate, load: loadWhisper, status: whisperStatus, terminate } = useWhisper(WhisperWorker, {
onComplete: async (res) => {
await send(res)
},
})
function handleLoadWhisper() {
if (whisperStatus.value === 'loading')
return
loadWhisper()
}
async function handleTranscription(buffer: Float32Array) {
await audioContext.resume()
// Convert Float32Array to WAV format
const audioBase64 = await encodeWAVToBase64(buffer, audioContext.sampleRate)
generate({ type: 'generate', data: { audio: audioBase64, language: 'en' } })
}
async function handleSend() {
await send(messageInput.value)
}
const { destroy } = useMicVAD(selectedAudioDeviceId, {
const { destroy, start } = useMicVAD(selectedAudioDeviceId, {
onSpeechStart: () => {
// TODO: interrupt the playback
// TODO: interrupt any of the ongoing TTS
Expand All @@ -87,8 +50,47 @@ const { destroy } = useMicVAD(selectedAudioDeviceId, {
listening.value = false
handleTranscription(buffer)
},
auto: false,
})
function handleLoadWhisper() {
if (whisperStatus.value === 'loading')
return
loadWhisper()
start()
}
async function handleTranscription(buffer: Float32Array) {
await audioContext.resume()
// Convert Float32Array to WAV format
const audioBase64 = await encodeWAVToBase64(buffer, audioContext.sampleRate)
generate({ type: 'generate', data: { audio: audioBase64, language: 'en' } })
}
function handleModelChange(event: Event) {
const target = event.target as HTMLSelectElement
const found = supportedModels.value.find(m => m.id === target.value)
if (!found) {
openAiModel.value = undefined
return
}
openAiModel.value = found
}
async function handleAudioInputChange(event: Event) {
const target = event.target as HTMLSelectElement
const found = audioInputs.value.find(d => d.deviceId === target.value)
if (!found) {
selectedAudioDevice.value = undefined
return
}
selectedAudioDevice.value = found
}
watch(isAudioInputOn, async (value) => {
if (value === 'false') {
destroy()
Expand Down
2 changes: 0 additions & 2 deletions packages/stage/src/stores/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ export const useChatStore = defineStore('chat', () => {
for (const hook of onTokenSpecialHooks.value) {
await hook(special)
}

streamingMessage.value.content += special
},
})

Expand Down
2 changes: 1 addition & 1 deletion packages/stage/src/stores/llm.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { GenerateAudioStream } from '@airi-proj/elevenlabs/types'
import type { GenerateAudioStream } from '@proj-airi/elevenlabs/types'
import type { Message } from '@xsai/shared-chat-completion'
import { listModels } from '@xsai/model'
import { streamText } from '@xsai/stream-text'
Expand Down
17 changes: 15 additions & 2 deletions packages/stage/src/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { defineStore } from 'pinia'
import { i18n } from '~/modules/i18n'

export const useSettings = defineStore('settings', () => {
const selectedAudioDevice = ref<MediaDeviceInfo>()

const openAiApiKey = useLocalStorage('settings/credentials/openai-api-key', '')
const openAiApiBaseURL = useLocalStorage('settings/credentials/openai-api-base-url', '')
const elevenLabsApiKey = useLocalStorage('settings/credentials/elevenlabs-api-key', '')
Expand All @@ -11,11 +13,10 @@ export const useSettings = defineStore('settings', () => {
const stageView = useLocalStorage('settings/stage/view/model-renderer', '2d')
const openAiModel = useLocalStorage<{ id: string, name?: string }>('settings/llm/openai/model', { id: 'openai/gpt-3.5-turbo', name: 'OpenAI GPT3.5 Turbo' })
const isAudioInputOn = useLocalStorage('settings/audio/input', 'true')
const selectedAudioDevice = useLocalStorage<MediaDeviceInfo | undefined>('settings/audio/input/device', undefined)
const selectedAudioDeviceId = computed(() => selectedAudioDevice.value?.deviceId)
const { audioInputs } = useDevicesList({ constraints: { audio: true }, requestPermissions: true })

watch(isAudioInputOn, async (value) => {
watch(isAudioInputOn, (value) => {
if (value === 'false') {
selectedAudioDevice.value = undefined
}
Expand All @@ -24,6 +25,18 @@ export const useSettings = defineStore('settings', () => {
}
})

onMounted(() => {
if (isAudioInputOn.value === 'true' && !selectedAudioDevice.value) {
selectedAudioDevice.value = audioInputs.value[0]
}
})

watch(audioInputs, () => {
if (isAudioInputOn.value === 'true' && !selectedAudioDevice.value) {
selectedAudioDevice.value = audioInputs.value[0]
}
})

watch(language, value => i18n.global.locale.value = value)

return {
Expand Down

0 comments on commit 8514573

Please sign in to comment.