Skip to content

Commit

Permalink
Merge pull request #85 from flukexp/support-piper
Browse files Browse the repository at this point in the history
added support for piper tts server
  • Loading branch information
slowsynapse authored Apr 1, 2024
2 parents 99e22f0 + faaf83b commit b5df2e5
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 2 deletions.
14 changes: 13 additions & 1 deletion src/components/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ import { SpeechT5SettingsPage } from './settings/SpeechT5SettingsPage';
import { CoquiSettingsPage } from './settings/CoquiSettingsPage';
import { OpenAITTSSettingsPage } from './settings/OpenAITTSSettingsPage';

import { PiperSettingsPage } from './settings/PiperSettingsPage';

import { STTBackendPage } from './settings/STTBackendPage';
import { WhisperOpenAISettingsPage } from './settings/WhisperOpenAISettingsPage';
import { WhisperCppSettingsPage } from './settings/WhisperCppSettingsPage';
Expand Down Expand Up @@ -96,6 +98,8 @@ export const Settings = ({
const [openAITTSModel, setOpenAITTSModel] = useState(config("openai_tts_model"));
const [openAITTSVoice, setOpenAITTSVoice] = useState(config("openai_tts_voice"));

const [piperUrl, setPiperUrl] = useState(config("piper_url"));

const [visionBackend, setVisionBackend] = useState(config("vision_backend"));
const [visionLlamaCppUrl, setVisionLlamaCppUrl] = useState(config("vision_llamacpp_url"));
const [visionOllamaUrl, setVisionOllamaUrl] = useState(config("vision_ollama_url"));
Expand Down Expand Up @@ -204,6 +208,7 @@ export const Settings = ({
speechT5SpeakerEmbeddingsUrl,
coquiApiKey, coquiVoiceId,
openAITTSApiKey, openAITTSUrl, openAITTSModel, openAITTSVoice,
piperUrl,
visionBackend,
visionLlamaCppUrl,
visionOllamaUrl, visionOllamaModel,
Expand Down Expand Up @@ -242,7 +247,7 @@ export const Settings = ({

case 'tts':
return <MenuPage
keys={["tts_backend", "elevenlabs_settings", "speecht5_settings", "coqui_settings", "openai_tts_settings"]}
keys={["tts_backend", "elevenlabs_settings", "speecht5_settings", "coqui_settings", "openai_tts_settings", "piper_settings"]}
menuClick={handleMenuClick} />;

case 'stt':
Expand Down Expand Up @@ -394,6 +399,13 @@ export const Settings = ({
setSettingsUpdated={setSettingsUpdated}
/>

case 'piper_settings':
return <PiperSettingsPage
piperUrl={piperUrl}
setPiperUrl={setPiperUrl}
setSettingsUpdated={setSettingsUpdated}
/>

case'stt_backend':
return <STTBackendPage
sttBackend={sttBackend}
Expand Down
44 changes: 44 additions & 0 deletions src/components/settings/PiperSettingsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useTranslation } from 'react-i18next';

import { BasicPage, FormRow, NotUsingAlert } from './common';
import { TextInput } from "@/components/textInput";
import { config, updateConfig } from "@/utils/config";

export function PiperSettingsPage({
piperUrl,
setPiperUrl,
setSettingsUpdated,
}: {
piperUrl: string;
setPiperUrl: (key: string) => void;
setSettingsUpdated: (updated: boolean) => void;
}) {
const { t } = useTranslation();

return (
<BasicPage
title={t("Piper") + " " + t("Settings")}
description={t("piper_desc", "Configure Piper")}
>
{config("tts_backend") !== "piper" && (
<NotUsingAlert>
{t("not_using_alert", "You are not currently using {{name}} as your {{what}} backend. These settings will not be used.", { name: t("Piper"), what: t("TTS") })}
</NotUsingAlert>
)}
<ul role="list" className="divide-y divide-gray-100 max-w-xs">
<li className="py-4">
<FormRow label={t("URL")}>
<TextInput
value={piperUrl}
onChange={(event: React.ChangeEvent<any>) => {
setPiperUrl(event.target.value);
updateConfig("piper_url", event.target.value);
setSettingsUpdated(true);
}}
/>
</FormRow>
</li>
</ul>
</BasicPage>
);
}
3 changes: 2 additions & 1 deletion src/components/settings/TTSBackendPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const ttsEngines = [
{key: "coqui", label: "Coqui TTS"},
{key: "openai_tts", label: "OpenAI TTS"},
{key: "localXTTS", label: "Local XTTS"}, // Our local TTS endpoint (XTTS based)
{key: "piper", label: "Piper"},
];

function idToTitle(id: string): string {
Expand Down Expand Up @@ -56,7 +57,7 @@ export function TTSBackendPage({
</select>
</FormRow>
</li>
{ ["elevenlabs", "speecht5", "coqui", "openai_tts"].includes(ttsBackend) && (
{ ["elevenlabs", "speecht5", "coqui", "openai_tts", "piper"].includes(ttsBackend) && (
<li className="py-4">
<FormRow label={`${t("Configure")} ${t(idToTitle(ttsBackend))}`}>
<button
Expand Down
2 changes: 2 additions & 0 deletions src/components/settings/common.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ export function getIconFromPage(page: string): JSX.Element {
case 'speecht5_settings': return <AdjustmentsHorizontalIcon className="h-5 w-5 flex-none text-gray-800" aria-hidden="true" />;
case 'coqui_settings': return <AdjustmentsHorizontalIcon className="h-5 w-5 flex-none text-gray-800" aria-hidden="true" />;
case 'openai_tts_settings': return <AdjustmentsHorizontalIcon className="h-5 w-5 flex-none text-gray-800" aria-hidden="true" />;
case 'piper_settings': return <AdjustmentsHorizontalIcon className="h-5 w-5 flex-none text-gray-800" aria-hidden="true" />;

case 'stt_backend': return <PencilSquareIcon className="h-5 w-5 flex-none text-gray-800" aria-hidden="true" />;
case 'whisper_openai_settings': return <AdjustmentsHorizontalIcon className="h-5 w-5 flex-none text-gray-800" aria-hidden="true" />;
Expand Down Expand Up @@ -193,6 +194,7 @@ function getLabelFromPage(page: string): string {
case 'speecht5_settings': return t('SpeechT5');
case 'coqui_settings': return t('Coqui');
case 'openai_tts_settings': return t('OpenAI');
case 'piper_settings': return t('Piper');

case 'vision_backend': return t('Vision Backend');
case 'vision_llamacpp_settings': return t('LLama.cpp');
Expand Down
5 changes: 5 additions & 0 deletions src/features/chat/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getWindowAiChatResponseStream } from './windowAiChat';
import { getOllamaChatResponseStream, getOllamaVisionChatResponse } from './ollamaChat';
import { getKoboldAiChatResponseStream } from './koboldAiChat';

import { piper} from "@/features/piper/piper";
import { elevenlabs } from "@/features/elevenlabs/elevenlabs";
import { coqui } from "@/features/coqui/coqui";
import { speecht5 } from "@/features/speecht5/speecht5";
Expand Down Expand Up @@ -423,6 +424,10 @@ export class Chat {
case 'localXTTS': {
const voice = await localXTTSTTS(talk.message);
}
case 'piper': {
const voice = await piper(talk.message);
return voice.audio;
}
}
} catch (e: any) {
console.error(e.toString());
Expand Down
20 changes: 20 additions & 0 deletions src/features/piper/piper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { config } from '@/utils/config';

export async function piper(
message: string,
) {
try {

const url = new URL(config("piper_url"));
url.searchParams.append('text', message);

const res = await fetch(url.toString());

const data = (await res.arrayBuffer()) as any;
return { audio: data };
} catch (error) {

console.error('Error in piper:', error);
throw error;
}
}
1 change: 1 addition & 0 deletions src/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const defaults = {
openai_tts_url: process.env.NEXT_PUBLIC_OPENAI_TTS_URL ?? 'https://api.openai.com',
openai_tts_model: process.env.NEXT_PUBLIC_OPENAI_TTS_MODEL ?? 'tts-1',
openai_tts_voice: process.env.NEXT_PUBLIC_OPENAI_TTS_VOICE ?? 'nova',
piper_url: process.env.NEXT_PUBLIC_PIPER_URL ?? 'http://localhost:5000',
elevenlabs_apikey: process.env.NEXT_PUBLIC_ELEVENLABS_APIKEY ??'',
elevenlabs_voiceid: process.env.NEXT_PUBLIC_ELEVENLABS_VOICEID ?? '21m00Tcm4TlvDq8ikWAM',
elevenlabs_model: process.env.NEXT_PUBLIC_ELEVENLABS_MODEL ?? 'eleven_monolingual_v1',
Expand Down

0 comments on commit b5df2e5

Please sign in to comment.