Skip to content

Commit cdb8aaf

Browse files
committed
Allow for specifying voices and admin default
Signed-off-by: Lukas Schaefer <[email protected]>
1 parent ffba2d7 commit cdb8aaf

File tree

4 files changed

+87
-4
lines changed

4 files changed

+87
-4
lines changed

lib/AppInfo/Application.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ class Application extends App implements IBootstrap {
4141
public const DEFAULT_TRANSCRIPTION_MODEL_ID = 'whisper-1';
4242
public const DEFAULT_SPEECH_MODEL_ID = 'tts-1-hd';
4343
public const DEFAULT_SPEECH_VOICE = 'alloy';
44+
public const DEFAULT_SPEECH_VOICES = [
45+
'alloy', 'ash', 'ballad', 'coral', 'echo', 'fable',
46+
'onyx', 'nova', 'sage', 'shimmer', 'verse'
47+
];
4448
public const DEFAULT_DEFAULT_IMAGE_SIZE = '1024x1024';
4549
public const MAX_GENERATION_IDLE_TIME = 60 * 60 * 24 * 10;
4650
public const DEFAULT_CHUNK_SIZE = 10000;

lib/Service/OpenAiSettingsService.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ class OpenAiSettingsService {
2424
'default_completion_model_id' => 'string',
2525
'default_stt_model_id' => 'string',
2626
'default_tts_model_id' => 'string',
27+
'tts_voices' => 'array',
28+
'default_tts_voice' => 'string',
2729
'default_image_model_id' => 'string',
2830
'default_image_size' => 'string',
2931
'image_request_auth' => 'boolean',
@@ -121,10 +123,37 @@ public function getAdminDefaultImageSize(): string {
121123
return $this->appConfig->getValueString(Application::APP_ID, 'default_image_size') ?: Application::DEFAULT_DEFAULT_IMAGE_SIZE;
122124
}
123125

126+
/**
127+
* @return string
128+
*/
124129
public function getAdminDefaultTtsModelId(): string {
125130
return $this->appConfig->getValueString(Application::APP_ID, 'default_speech_model_id') ?: Application::DEFAULT_MODEL_ID;
126131
}
127132

133+
/**
134+
* @return string
135+
*/
136+
public function getAdminDefaultTtsVoice(): string {
137+
return $this->appConfig->getValueString(Application::APP_ID, 'default_speech_voice') ?: Application::DEFAULT_SPEECH_VOICE;
138+
}
139+
140+
/**
141+
* @return array
142+
*/
143+
public function getAdminTtsVoices(): array {
144+
$voices = json_decode(
145+
$this->appConfig->getValueString(
146+
Application::APP_ID, 'tts_voices',
147+
json_encode(Application::DEFAULT_SPEECH_VOICES)
148+
) ?: json_encode(Application::DEFAULT_SPEECH_VOICES),
149+
true,
150+
);
151+
if (!is_array($voices)) {
152+
$voices = Application::DEFAULT_SPEECH_VOICES;
153+
}
154+
return $voices;
155+
}
156+
128157
/**
129158
* @return string
130159
*/
@@ -274,6 +303,8 @@ public function getAdminConfig(): array {
274303
'default_completion_model_id' => $this->getAdminDefaultCompletionModelId(),
275304
'default_stt_model_id' => $this->getAdminDefaultSttModelId(),
276305
'default_tts_model_id' => $this->getAdminDefaultTtsModelId(),
306+
'default_tts_voice' => $this->getAdminDefaultTtsVoice(),
307+
'tts_voices' => $this->getAdminTtsVoices(),
277308
'default_image_model_id' => $this->getAdminDefaultImageModelId(),
278309
'default_image_size' => $this->getAdminDefaultImageSize(),
279310
'image_request_auth' => $this->getIsImageRetrievalAuthenticated(),
@@ -467,6 +498,14 @@ public function setAdminDefaultImageModelId(string $defaultImageModelId): void {
467498
$this->appConfig->setValueString(Application::APP_ID, 'default_image_model_id', $defaultImageModelId);
468499
}
469500

501+
/**
502+
* @param string $voice
503+
* @return void
504+
*/
505+
public function setAdminDefaultTtsVoice(string $voice): void {
506+
$this->appConfig->setValueString(Application::APP_ID, 'default_speech_voice', $voice);
507+
}
508+
470509
/**
471510
* @param string $defaultImageSize
472511
* @return void
@@ -608,6 +647,15 @@ public function setUseBasicAuth(bool $useBasicAuth): void {
608647
$this->invalidateModelsCache();
609648
}
610649

650+
/**
651+
* @param array $voices
652+
* @return void
653+
*/
654+
public function setAdminTtsVoices(array $voices): void {
655+
$this->appConfig->setValueString(Application::APP_ID, 'tts_voices', json_encode($voices));
656+
$this->invalidateModelsCache();
657+
}
658+
611659
/**
612660
* Set the admin config for the settings page
613661
* @param mixed[] $config
@@ -692,6 +740,9 @@ public function setAdminConfig(array $adminConfig): void {
692740
if (isset($adminConfig['tts_provider_enabled'])) {
693741
$this->setTtsProviderEnabled($adminConfig['tts_provider_enabled']);
694742
}
743+
if (isset($adminConfig['default_tts_voice'])) {
744+
$this->setAdminDefaultTtsVoice($adminConfig['default_tts_voice']);
745+
}
695746
if (isset($adminConfig['chat_endpoint_enabled'])) {
696747
$this->setChatEndpointEnabled($adminConfig['chat_endpoint_enabled']);
697748
}
@@ -704,6 +755,9 @@ public function setAdminConfig(array $adminConfig): void {
704755
if (isset($adminConfig['use_basic_auth'])) {
705756
$this->setUseBasicAuth($adminConfig['use_basic_auth']);
706757
}
758+
if (isset($adminConfig['tts_voices'])) {
759+
$this->setAdminTtsVoices($adminConfig['tts_voices']);
760+
}
707761
}
708762

709763
/**

lib/TaskProcessing/TextToSpeechProvider.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,18 @@ public function getOptionalInputShape(): array {
8282
}
8383

8484
public function getOptionalInputShapeEnumValues(): array {
85+
$voices = json_decode($this->appConfig->getValueString(Application::APP_ID, 'tts_voices')) ?: Application::DEFAULT_SPEECH_VOICES;
8586
return [
86-
'voice' => [new ShapeEnumValue('alloy', 'alloy')],
87+
'voice' => array_map(function ($v) { return new ShapeEnumValue($v, $v); }, $voices),
8788
'model' => $this->openAiAPIService->getModelEnumValues($this->userId),
8889
];
8990
}
9091

9192
public function getOptionalInputShapeDefaults(): array {
92-
$adminModel = $this->appConfig->getValueString(Application::APP_ID, 'default_speech_model_id');
93+
$adminVoice = $this->appConfig->getValueString(Application::APP_ID, 'default_speech_voice') ?: Application::DEFAULT_SPEECH_VOICE;
94+
$adminModel = $this->appConfig->getValueString(Application::APP_ID, 'default_speech_model_id') ?: Application::DEFAULT_SPEECH_MODEL_ID;
9395
return [
94-
'voice' => 'alloy',
96+
'voice' => $adminVoice,
9597
'model' => $adminModel,
9698
'speed' => 1,
9799
];

src/components/AdminSettings.vue

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@
397397
<NcSelect
398398
v-model="selectedModel.tts"
399399
class="model-select"
400-
:clearable="state.default_image_model_id !== DEFAULT_MODEL_ITEM.id"
400+
:clearable="state.default_tts_model_id !== DEFAULT_MODEL_ITEM.id"
401401
:options="formattedModels"
402402
:input-label="t('integration_openai', 'Default transcription model to use')"
403403
:no-wrap="true"
@@ -427,6 +427,27 @@
427427
<NcNoteCard v-else type="info">
428428
{{ t('integration_openai', 'No models to list') }}
429429
</NcNoteCard>
430+
<NcSelect v-model="state.tts_voices"
431+
:input-label="t('integration_openai', 'TTS Voices')"
432+
multiple
433+
taggable
434+
@input="onInput()" />
435+
<NcButton
436+
:title="t('integration_openai', 'A list of voices supported by the endpoint you are using. Defaults to openai\'s list.')"
437+
type="tertiary"
438+
aria-label="voices-info">
439+
<template #icon>
440+
<HelpCircleIcon />
441+
</template>
442+
</NcButton>
443+
<NcSelect
444+
v-model="state.default_tts_voice"
445+
class="model-select"
446+
:options="state.tts_voices"
447+
:input-label="t('integration_openai', 'Default voice to use')"
448+
:no-wrap="true"
449+
input-id="openai-tts-voices-select"
450+
@input="onInput()" />
430451
</div>
431452
<div>
432453
<h2>
@@ -808,6 +829,8 @@ export default {
808829
default_image_size: this.state.default_image_size,
809830
quota_period: parseInt(this.state.quota_period),
810831
quotas: this.state.quotas,
832+
tts_voices: this.state.tts_voices,
833+
default_tts_voice: this.state.default_tts_voice,
811834
}
812835
await this.saveOptions(values, false)
813836
}, 2000),

0 commit comments

Comments
 (0)