Merge pull request #3371 from fearmear/release Decrease TTS generation delay by splitting a message on a new line
Signed| @@ -120,7 +120,7 @@ async function onNarrateOneMessage() { | |||
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | resetTtsPlayback(); | 122 | resetTtsPlayback(); |
| 123 | ttsJobQueue.push(message); | 123 | processAndQueueTtsMessage(message); |
| 124 | moduleWorker(); | 124 | moduleWorker(); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| @@ -147,7 +147,7 @@ async function onNarrateText(args, text) { | |||
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | resetTtsPlayback(); | 149 | resetTtsPlayback(); |
| 150 | ttsJobQueue.push({ mes: text, name: name }); | 150 | processAndQueueTtsMessage({ mes: text, name: name }); |
| 151 | await moduleWorker(); | 151 | await moduleWorker(); |
| 152 | 152 | ||
| 153 | // Return back to the chat voices | 153 | // Return back to the chat voices |
| @@ -220,6 +220,36 @@ function isTtsProcessing() { | |||
| 220 | return processing; | 220 | return processing; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | /** | ||
| 224 | * Splits a message into lines and adds each non-empty line to the TTS job queue. | ||
| 225 | * @param {Object} message - The message object to be processed. | ||
| 226 | * @param {string} message.mes - The text of the message to be split into lines. | ||
| 227 | * @param {string} message.name - The name associated with the message. | ||
| 228 | * @returns {void} | ||
| 229 | */ | ||
| 230 | function processAndQueueTtsMessage(message) { | ||
| 231 | if (!extension_settings.tts.narrate_by_paragraphs) { | ||
| 232 | ttsJobQueue.push(message); | ||
| 233 | return; | ||
| 234 | } | ||
| 235 | |||
| 236 | const lines = message.mes.split('\n'); | ||
| 237 | |||
| 238 | for (let i = 0; i < lines.length; i++) { | ||
| 239 | const line = lines[i]; | ||
| 240 | |||
| 241 | if (line.length === 0) { | ||
| 242 | continue; | ||
| 243 | } | ||
| 244 | |||
| 245 | ttsJobQueue.push( | ||
| 246 | Object.assign({}, message, { | ||
| 247 | mes: line, | ||
| 248 | }), | ||
| 249 | ); | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 223 | function debugTtsPlayback() { | 253 | function debugTtsPlayback() { |
| 224 | console.log(JSON.stringify( | 254 | console.log(JSON.stringify( |
| 225 | { | 255 | { |
| @@ -350,7 +380,7 @@ function onAudioControlClicked() { | |||
| 350 | talkingAnimation(false); | 380 | talkingAnimation(false); |
| 351 | } else { | 381 | } else { |
| 352 | // Default play behavior if not processing or playing is to play the last message. | 382 | // Default play behavior if not processing or playing is to play the last message. |
| 353 | ttsJobQueue.push(context.chat[context.chat.length - 1]); | 383 | processAndQueueTtsMessage(context.chat[context.chat.length - 1]); |
| 354 | } | 384 | } |
| 355 | updateUiAudioPlayState(); | 385 | updateUiAudioPlayState(); |
| 356 | } | 386 | } |
| @@ -569,6 +599,7 @@ function loadSettings() { | |||
| 569 | $('#tts_narrate_quoted').prop('checked', extension_settings.tts.narrate_quoted_only); | 599 | $('#tts_narrate_quoted').prop('checked', extension_settings.tts.narrate_quoted_only); |
| 570 | $('#tts_auto_generation').prop('checked', extension_settings.tts.auto_generation); | 600 | $('#tts_auto_generation').prop('checked', extension_settings.tts.auto_generation); |
| 571 | $('#tts_periodic_auto_generation').prop('checked', extension_settings.tts.periodic_auto_generation); | 601 | $('#tts_periodic_auto_generation').prop('checked', extension_settings.tts.periodic_auto_generation); |
| 602 | $('#tts_narrate_by_paragraphs').prop('checked', extension_settings.tts.narrate_by_paragraphs); | ||
| 572 | $('#tts_narrate_translated_only').prop('checked', extension_settings.tts.narrate_translated_only); | 603 | $('#tts_narrate_translated_only').prop('checked', extension_settings.tts.narrate_translated_only); |
| 573 | $('#tts_narrate_user').prop('checked', extension_settings.tts.narrate_user); | 604 | $('#tts_narrate_user').prop('checked', extension_settings.tts.narrate_user); |
| 574 | $('#tts_pass_asterisks').prop('checked', extension_settings.tts.pass_asterisks); | 605 | $('#tts_pass_asterisks').prop('checked', extension_settings.tts.pass_asterisks); |
| @@ -638,6 +669,11 @@ function onPeriodicAutoGenerationClick() { | |||
| 638 | saveSettingsDebounced(); | 669 | saveSettingsDebounced(); |
| 639 | } | 670 | } |
| 640 | 671 | ||
| 672 | function onNarrateByParagraphsClick() { | ||
| 673 | extension_settings.tts.narrate_by_paragraphs = !!$('#tts_narrate_by_paragraphs').prop('checked'); | ||
| 674 | saveSettingsDebounced(); | ||
| 675 | } | ||
| 676 | |||
| 641 | 677 | ||
| 642 | function onNarrateDialoguesClick() { | 678 | function onNarrateDialoguesClick() { |
| 643 | extension_settings.tts.narrate_dialogues_only = !!$('#tts_narrate_dialogues').prop('checked'); | 679 | extension_settings.tts.narrate_dialogues_only = !!$('#tts_narrate_dialogues').prop('checked'); |
| @@ -816,7 +852,12 @@ async function onMessageEvent(messageId, lastCharIndex) { | |||
| 816 | lastChatId = context.chatId; | 852 | lastChatId = context.chatId; |
| 817 | 853 | ||
| 818 | console.debug(`Adding message from ${message.name} for TTS processing: "${message.mes}"`); | 854 | console.debug(`Adding message from ${message.name} for TTS processing: "${message.mes}"`); |
| 819 | ttsJobQueue.push(message); | 855 | |
| 856 | if (extension_settings.tts.periodic_auto_generation) { | ||
| 857 | ttsJobQueue.push(message); | ||
| 858 | } else { | ||
| 859 | processAndQueueTtsMessage(message); | ||
| 860 | } | ||
| 820 | } | 861 | } |
| 821 | 862 | ||
| 822 | async function onMessageDeleted() { | 863 | async function onMessageDeleted() { |
| @@ -1156,6 +1197,7 @@ jQuery(async function () { | |||
| 1156 | $('#tts_pass_asterisks').on('click', onPassAsterisksClick); | 1197 | $('#tts_pass_asterisks').on('click', onPassAsterisksClick); |
| 1157 | $('#tts_auto_generation').on('click', onAutoGenerationClick); | 1198 | $('#tts_auto_generation').on('click', onAutoGenerationClick); |
| 1158 | $('#tts_periodic_auto_generation').on('click', onPeriodicAutoGenerationClick); | 1199 | $('#tts_periodic_auto_generation').on('click', onPeriodicAutoGenerationClick); |
| 1200 | $('#tts_narrate_by_paragraphs').on('click', onNarrateByParagraphsClick); | ||
| 1159 | $('#tts_narrate_user').on('click', onNarrateUserClick); | 1201 | $('#tts_narrate_user').on('click', onNarrateUserClick); |
| 1160 | 1202 | ||
| 1161 | $('#playback_rate').on('input', function () { | 1203 | $('#playback_rate').on('input', function () { |
| @@ -30,6 +30,10 @@ | |||
| 30 | <input type="checkbox" id="tts_periodic_auto_generation"> | 30 | <input type="checkbox" id="tts_periodic_auto_generation"> |
| 31 | <small data-i18n="Narrate by paragraphs (when streaming)">Narrate by paragraphs (when streaming)</small> | 31 | <small data-i18n="Narrate by paragraphs (when streaming)">Narrate by paragraphs (when streaming)</small> |
| 32 | </label> | 32 | </label> |
| 33 | <label class="checkbox_label" for="tts_narrate_by_paragraphs"> | ||
| 34 | <input type="checkbox" id="tts_narrate_by_paragraphs"> | ||
| 35 | <small data-i18n="Narrate by paragraphs (when not streaming)">Narrate by paragraphs (when not streaming)</small> | ||
| 36 | </label> | ||
| 33 | <label class="checkbox_label" for="tts_narrate_quoted"> | 37 | <label class="checkbox_label" for="tts_narrate_quoted"> |
| 34 | <input type="checkbox" id="tts_narrate_quoted"> | 38 | <input type="checkbox" id="tts_narrate_quoted"> |
| 35 | <small data-i18n="Only narrate quotes">Only narrate "quotes"</small> | 39 | <small data-i18n="Only narrate quotes">Only narrate "quotes"</small> |