Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: TTS output controls #1456

Draft
wants to merge 4 commits into
base: dev
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
168 changes: 168 additions & 0 deletions src/lib/components/chat/Settings/Audio.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@

let voices = [];
let speaker = '';
let volume = '';
let speechRate = '';
let pitch = '';
let notificationsPlayback = false;

const getOpenAIVoices = () => {
voices = [
Expand Down Expand Up @@ -69,12 +73,18 @@
saveSettings({ speechAutoSend: speechAutoSend });
};

const toggleNotificationsPlayback = async () => {
notificationsPlayback = !notificationsPlayback;
saveSettings({ notificationsPlayback: notificationsPlayback });
};

onMount(async () => {
let settings = JSON.parse(localStorage.getItem('settings') ?? '{}');

conversationMode = settings.conversationMode ?? false;
speechAutoSend = settings.speechAutoSend ?? false;
responseAutoPlayback = settings.responseAutoPlayback ?? false;
notificationsPlayback = settings.notificationsPlayback ?? false;

STTEngine = settings?.audio?.STTEngine ?? '';
TTSEngine = settings?.audio?.TTSEngine ?? '';
Expand Down Expand Up @@ -213,6 +223,164 @@
{/if}
</button>
</div>

<div class=" py-0.5 w-full justify-between">
<div class="flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Volume')}</div>

<button
class="p-1 px-3 text-xs flex rounded transition"
type="button"
on:click={() => {
volume = volume === '' ? 0.8 : '';
}}
>
{#if volume === ''}
<span class="ml-2 self-center"> {$i18n.t('Default')} </span>
{:else}
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
{/if}
</button>
</div>

{#if volume !== ''}
<div class="flex mt-0.5 space-x-2">
<div class=" flex-1">
<input
id="steps-range"
type="range"
min="0.1"
max="1"
step="0.01"
bind:value={volume}
class="w-full h-2 rounded-lg appearance-none cursor-pointer dark:bg-gray-700"
/>
</div>
<div>
<input
bind:value={volume}
type="number"
class=" bg-transparent text-center w-14"
min="0.1"
max="1"
step="0.01"
/>
</div>
</div>
{/if}
</div>

<div class=" py-0.5 w-full justify-between">
<div class="flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Speech Rate')}</div>

<button
class="p-1 px-3 text-xs flex rounded transition"
type="button"
on:click={() => {
speechRate = speechRate === '' ? 100 : '';
}}
>
{#if speechRate === ''}
<span class="ml-2 self-center"> {$i18n.t('Default')} </span>
{:else}
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
{/if}
</button>
</div>

{#if speechRate !== ''}
<div class="flex mt-0.5 space-x-2">
<div class=" flex-1">
<input
id="steps-range"
type="range"
min="1"
max="100"
step="0.01"
bind:value={speechRate}
class="w-full h-2 rounded-lg appearance-none cursor-pointer dark:bg-gray-700"
/>
</div>
<div>
<input
bind:value={speechRate}
type="number"
class=" bg-transparent text-center w-14"
min="1"
max="100"
step="0.01"
/>
</div>
</div>
{/if}
</div>

<div class=" py-0.5 w-full justify-between">
<div class="flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Pitch')}</div>

<button
class="p-1 px-3 text-xs flex rounded transition"
type="button"
on:click={() => {
pitch = pitch === '' ? 100 : '';
}}
>
{#if pitch === ''}
<span class="ml-2 self-center"> {$i18n.t('Default')} </span>
{:else}
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
{/if}
</button>
</div>

{#if pitch !== ''}
<div class="flex mt-0.5 space-x-2">
<div class=" flex-1">
<input
id="steps-range"
type="range"
min="0"
max="100"
step="0.01"
bind:value={pitch}
class="w-full h-2 rounded-lg appearance-none cursor-pointer dark:bg-gray-700"
/>
</div>
<div>
<input
bind:value={pitch}
type="number"
class=" bg-transparent text-center w-14"
min="0"
max="100"
step="0.01"
/>
</div>
</div>
{/if}
</div>

<div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Enable Notifications Playback')}
</div>

<button
class="p-1 px-3 text-xs flex rounded transition"
on:click={() => {
toggleNotificationsPlayback();
}}
type="button"
>
{#if notificationsPlayback === true}
<span class="ml-2 self-center">{$i18n.t('On')}</span>
{:else}
<span class="ml-2 self-center">{$i18n.t('Off')}</span>
{/if}
</button>
</div>
</div>

<hr class=" dark:border-gray-700" />
Expand Down