Fix MiniMax (TTS) pitch on API calls being the wrong range (#4578) * fix: change MiniMax TTS pitch from float range 0.5-2.0 to integer range -12 to 12 Fixes #4570 * refactor: replace hardcoded defaults with defaultSettings in MiniMaxTtsProvider config * refactor: restructure TTS settings with min/max ranges and add value clamping, adjust volume range * fix: flatten MiniMaxTtsProvider settings to use default values from complex field definitions * Adjust block spacing --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>

d2f3a85742fd48547593076cd2f336402ee06b6b

Wolfsblvt <wolfsblvt@gmail.com>

Signed
2 files changed, +49 -16Showing whitespace changes
public/scripts/extensions/tts/css/minimax-tts.css+5 -0
@@ -1,3 +1,8 @@
1+.minimax_tts_settings>.tts_block {
2+ gap: 5px;
3+ margin: 5px 0;
4+}
5+
16.minimax-custom-item {
27 display: flex;
38 justify-content: space-between;
public/scripts/extensions/tts/minimax.js+44 -16
@@ -19,9 +19,9 @@ class MiniMaxTtsProvider {
1919 apiHost: 'https://api.minimax.io',
2020 model: 'speech-02-hd',
2121 voiceMap: {},
22- speed: 1.0,
22+ speed: { default: 1.0, min: 0.5, max: 2.0, step: 0.1 },
23- volume: 1.0,
23+ volume: { default: 1.0, min: 0.0, max: 10.0, step: 0.1 },
24- pitch: 1.0,
24+ pitch: { default: 0, min: -12, max: 12, step: 1 },
2525 audioSampleRate: 32000,
2626 bitrate: 128000,
2727 format: 'mp3',
@@ -84,15 +84,15 @@ class MiniMaxTtsProvider {
8484
8585 <div class="tts_block">
8686 <label for="minimax_tts_speed">Speed: <span id="minimax_tts_speed_output"></span></label>
8787 <input id="minimax_tts_speed" type="range" value="${this.defaultSettings.speed.default}" min="0${this.5defaultSettings.speed.min}" max="2${this.0defaultSettings.speed.max}" step="0${this.1defaultSettings.speed.step}" />
8888 </div>
8989 <div class="tts_block">
9090 <label for="minimax_tts_volume">Volume: <span id="minimax_tts_volume_output"></span></label>
9191 <input id="minimax_tts_volume" type="range" value="${this.defaultSettings.volume.default}" min="0${this.1defaultSettings.volume.min}" max="2${this.0defaultSettings.volume.max}" step="0${this.1defaultSettings.volume.step}" />
9292 </div>
9393 <div class="tts_block">
9494 <label for="minimax_tts_pitch">Pitch: <span id="minimax_tts_pitch_output"></span></label>
9595 <input id="minimax_tts_pitch" type="range" value="${this.defaultSettings.pitch.default}" min="0${this.5defaultSettings.pitch.min}" max="2${this.0defaultSettings.pitch.max}" step="0${this.1defaultSettings.pitch.step}" />
9696 </div>
9797 <div class="tts_block">
9898 <label for="minimax_tts_format">Audio Format</label>
@@ -190,14 +190,14 @@ class MiniMaxTtsProvider {
190190 this.settings.apiHost = $('#minimax_tts_api_host').val();
191191 this.settings.speed = parseFloat($('#minimax_tts_speed').val().toString());
192192 this.settings.volume = parseFloat($('#minimax_tts_volume').val().toString());
193193 this.settings.pitch = parseFloatparseInt($('#minimax_tts_pitch').val().toString());
194194 this.settings.model = $('#minimax_tts_model').find(':selected').val();
195195 this.settings.format = $('#minimax_tts_format').find(':selected').val();
196196 this.settings.customVoiceId = $('#minimax_tts_custom_voice_id').val();
197197
198198 $('#minimax_tts_speed_output').text(this.settings.speed.toFixed(1));
199199 $('#minimax_tts_volume_output').text(this.settings.volume.toFixed(1));
200200 $('#minimax_tts_pitch_output').text(this.settings.pitch.toFixed(1));
201201
202202 saveTtsProviderSettings();
203203 }
@@ -458,6 +458,16 @@ class MiniMaxTtsProvider {
458458 // Only accept keys defined in defaultSettings
459459 this.settings = { ...this.defaultSettings };
460460
461+ // Flatten the settings fields with default/min/max definitions so the actual values are used
462+ this.settings = Object.fromEntries(
463+ Object.entries(this.defaultSettings).map(([key, value]) => {
464+ if (value && typeof value === 'object' && 'default' in value) {
465+ return [key, value.default];
466+ }
467+ return [key, value];
468+ }),
469+ );
470+
461471 for (const key in settings) {
462472 if (key in this.settings) {
463473 this.settings[key] = settings[key];
@@ -470,6 +480,21 @@ class MiniMaxTtsProvider {
470480 if (!this.settings.customModels) this.settings.customModels = [];
471481 if (!this.settings.customVoices) this.settings.customVoices = [];
472482
483+ // # Migrate settings
484+ // Pitch value changed from float to int. If it's a float, let's try to extrapolate it to the new range
485+ if (!Number.isInteger(this.settings.pitch)) {
486+ const oldPitch = parseFloat(this.settings.pitch);
487+ if (!isNaN(oldPitch)) {
488+ // map old [0.5..1.0] to [-12..0], and [1.0..2.0] to [0..12] (old default was 1.0, new default is 0)
489+ const newPitch = (oldPitch < 1.0) ? (oldPitch - 1.0) * 24 : (oldPitch - 1.0) * 12;
490+ this.settings.pitch = Math.max(-12, Math.min(12, Math.round(newPitch)));
491+ console.info(`MiniMax TTS: Migrated pitch from ${oldPitch} to ${this.settings.pitch}`);
492+ } else {
493+ this.settings.pitch = 0;
494+ console.info(`MiniMax TTS: Migration reset pitch to default ${this.settings.pitch}`);
495+ }
496+ }
497+
473498 $('#minimax_tts_api_host').val(this.settings.apiHost || 'https://api.minimax.io');
474499 $('#minimax_tts_model').val(this.settings.model);
475500 $('#minimax_tts_speed').val(this.settings.speed);
@@ -546,7 +571,7 @@ class MiniMaxTtsProvider {
546571
547572 $('#minimax_tts_speed_output').text(this.settings.speed.toFixed(1));
548573 $('#minimax_tts_volume_output').text(this.settings.volume.toFixed(1));
549574 $('#minimax_tts_pitch_output').text(this.settings.pitch.toFixed(1));
550575
551576 // Initialize custom configuration display
552577 this.updateCustomModelsDisplay();
@@ -756,17 +781,20 @@ class MiniMaxTtsProvider {
756781 throw error;
757782 }
758783
784+ /** @param {number} number @param {number} lower @param {number} upper @returns {number} */
785+ const clamp = (number, lower, upper) => Math.min(Math.max(number, lower), upper);
786+
759787 const requestBody = {
760788 text: inputText,
761789 voiceId: voiceId,
762790 apiHost: this.settings.apiHost,
763791 model: this.settings.model || 'speech-02-hd'this.defaultSettings.model,
764792 speed: clamp(Number(this.settings.speed) || 1this.0defaultSettings.speed.default, this.defaultSettings.speed.min, this.defaultSettings.speed.max),
765793 volume: clamp(Number(this.settings.volume) || 1this.0defaultSettings.volume.default, this.defaultSettings.volume.min, this.defaultSettings.volume.max),
766794 pitch: clamp(Math.round(Number(this.settings.pitch)) || 1this.0defaultSettings.pitch.default, this.defaultSettings.pitch.min, this.defaultSettings.pitch.max),
767795 audioSampleRate: Number(this.settings.audioSampleRate) || 32000this.defaultSettings.audioSampleRate,
768796 bitrate: Number(this.settings.bitrate) || 128000this.defaultSettings.bitrate,
769797 format: this.settings.format || 'mp3'this.defaultSettings.format,
770798 language: language,
771799 };
772800