mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
Speex: debug instrumentation
This commit is contained in:
@@ -17,6 +17,7 @@ import { AudioPlayer } from '~/common/util/audio/AudioPlayer';
|
||||
|
||||
import type { DSpeexEngine, SpeexSpeakResult } from '../../speex.types';
|
||||
import type { SpeexWire_Access, SpeexWire_ListVoices_Output, SpeexWire_Voice } from './rpc.wiretypes';
|
||||
import { SPEEX_DEBUG } from '../../speex.config';
|
||||
|
||||
|
||||
type _DSpeexEngineRPC = DSpeexEngine<'elevenlabs'> | DSpeexEngine<'localai'> | DSpeexEngine<'openai'>;
|
||||
@@ -44,6 +45,7 @@ export async function speexSynthesize_RPC(
|
||||
): Promise<SpeexSpeakResult> {
|
||||
|
||||
// engine credentials (DCredentials..) -> wire Access
|
||||
if (SPEEX_DEBUG) console.log(`[Speex RPC] Synthesize request (engine: ${engine.engineId}, ${text.length} chars) - options:`, options);
|
||||
const access = _buildRPCWireAccess(engine);
|
||||
if (!access) {
|
||||
const error = new Error(`Failed to resolve credentials for engine ${engine.engineId}`);
|
||||
@@ -72,6 +74,7 @@ export async function speexSynthesize_RPC(
|
||||
|
||||
// process streaming particles
|
||||
for await (const particle of particleStream) {
|
||||
if (SPEEX_DEBUG) console.log('[Speex RPC] <-', particle);
|
||||
switch (particle.t) {
|
||||
case 'start':
|
||||
callbacks?.onStart?.();
|
||||
@@ -134,7 +137,9 @@ export async function speexSynthesize_RPC(
|
||||
return result;
|
||||
|
||||
} catch (error: any) {
|
||||
// Cleanup
|
||||
if (SPEEX_DEBUG) console.error('[Speex RPC] Synthesis error:', { error });
|
||||
|
||||
// cleanup
|
||||
if (audioPlayer)
|
||||
void audioPlayer.stop();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { fetchJsonOrTRPCThrow, fetchResponseOrTRPCThrow } from '~/server/trpc/tr
|
||||
|
||||
import type { SpeexSpeechParticle, SpeexWire_Access_ElevenLabs, SpeexWire_ListVoices_Output } from './rpc.wiretypes';
|
||||
import type { SynthesizeBackendFn } from './rpc.router';
|
||||
import { SPEEX_DEBUG } from '../../speex.config';
|
||||
import { returnAudioWholeOrThrow, streamAudioChunksOrThrow } from './rpc.streaming';
|
||||
|
||||
|
||||
@@ -53,6 +54,7 @@ export const synthesizeElevenLabs: SynthesizeBackendFn<SpeexWire_Access_ElevenLa
|
||||
// Fetch
|
||||
let response: Response;
|
||||
try {
|
||||
if (SPEEX_DEBUG) console.log(`[Speex][ElevenLabs] POST (stream=${streaming})`, { url, headers, body });
|
||||
response = await fetchResponseOrTRPCThrow({
|
||||
url,
|
||||
method: 'POST',
|
||||
|
||||
@@ -6,6 +6,7 @@ import { fetchJsonOrTRPCThrow, fetchResponseOrTRPCThrow } from '~/server/trpc/tr
|
||||
|
||||
import type { SpeexWire_Access_OpenAI, SpeexWire_ListVoices_Output } from './rpc.wiretypes';
|
||||
import type { SynthesizeBackendFn } from './rpc.router';
|
||||
import { SPEEX_DEBUG } from '../../speex.config';
|
||||
import { returnAudioWholeOrThrow, streamAudioChunksOrThrow } from './rpc.streaming';
|
||||
|
||||
|
||||
@@ -56,6 +57,7 @@ export const synthesizeOpenAIProtocol: SynthesizeBackendFn<SpeexWire_Access_Open
|
||||
|
||||
// request.headers
|
||||
const { host, apiKey } = _resolveAccess(access);
|
||||
const url = `${host}/v1/audio/speech`;
|
||||
const headers: HeadersInit = {
|
||||
'Content-Type': 'application/json',
|
||||
...(!apiKey ? {} : { 'Authorization': `Bearer ${apiKey}` }),
|
||||
@@ -95,8 +97,9 @@ export const synthesizeOpenAIProtocol: SynthesizeBackendFn<SpeexWire_Access_Open
|
||||
const dialectName = access.dialect === 'localai' ? 'LocalAI' : 'OpenAI';
|
||||
let response: Response;
|
||||
try {
|
||||
if (SPEEX_DEBUG) console.log(`[Speex][OpenAI] POST (stream=${streaming})`, { url, headers, body });
|
||||
response = await fetchResponseOrTRPCThrow({
|
||||
url: `${host}/v1/audio/speech`,
|
||||
url,
|
||||
method: 'POST',
|
||||
headers,
|
||||
body,
|
||||
|
||||
@@ -9,6 +9,8 @@ import * as React from 'react';
|
||||
|
||||
import type { DVoiceWebSpeech, SpeexListVoiceOption, SpeexSpeakResult } from '../../speex.types';
|
||||
|
||||
import { SPEEX_DEBUG } from '~/modules/speex/speex.config';
|
||||
|
||||
|
||||
function _webspeechVoicesToVoiceOptions(browserVoices: ReadonlyArray<SpeechSynthesisVoice>): SpeexListVoiceOption[] {
|
||||
return browserVoices.map(v => ({
|
||||
@@ -128,6 +130,7 @@ export function speexSynthesize_WebSpeech(
|
||||
speechSynthesis.cancel(); // safe
|
||||
|
||||
// create utterance
|
||||
if (SPEEX_DEBUG) console.debug(`[Speex][WebSpeech] New utterance (${text.length} chars, voice: ${voice.ttsVoiceURI}, s=${voice.ttsSpeed}, p=${voice.ttsPitch})`);
|
||||
const utterance = new SpeechSynthesisUtterance(text);
|
||||
|
||||
// find and set voice by URI
|
||||
@@ -144,15 +147,18 @@ export function speexSynthesize_WebSpeech(
|
||||
|
||||
// set up event handlers
|
||||
utterance.onstart = () => {
|
||||
if (SPEEX_DEBUG) console.debug(`[Speex][WebSpeech] Utterance started`);
|
||||
callbacks?.onStart?.();
|
||||
};
|
||||
|
||||
utterance.onend = () => {
|
||||
if (SPEEX_DEBUG) console.debug(`[Speex][WebSpeech] Utterance completed`);
|
||||
callbacks?.onComplete?.();
|
||||
resolve({ success: true });
|
||||
};
|
||||
|
||||
utterance.onerror = (event) => {
|
||||
if (SPEEX_DEBUG) console.error(`[Speex][WebSpeech] Utterance error`, event.error);
|
||||
const errorMessage = event.error || 'Speech synthesis failed';
|
||||
const error = new Error(errorMessage);
|
||||
callbacks?.onError?.(error);
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// configuration
|
||||
export const SPEEX_DEBUG = false;
|
||||
Reference in New Issue
Block a user