Documentation Index Fetch the complete documentation index at: https://docs.supertoneapi.com/llms.txt
Use this file to discover all available pages before exploring further.
このドキュメントは英語の原文から自動翻訳されています。表現に不自然な箇所がある場合があります。正確な内容は英語の原文 もあわせてご確認ください。
生成音声にキャラクターをリップシンクさせるには、次の3つの情報を同期して扱う必要があります。
オーディオファイル
実際に発話された音素(phoneme)シンボル
各音素の開始時刻と継続時間
TTSリクエストでinclude_phonemes: trueを指定すると、Supertoneはこの3つすべてを返します。
Python — オーディオと音素をリクエストする
import base64
import os
from supertone import Supertone
VOICE_ID = "20160a4c5ba38967330c84" # replace with your voice ID
with Supertone( api_key =os.environ[ "SUPERTONE_API_KEY" ]) as client:
response = client.text_to_speech.create_speech(
voice_id =VOICE_ID,
text = "Welcome to the workshop." ,
language = "en" ,
model = "sona_speech_2" ,
include_phonemes = True ,
)
audio_bytes = base64.b64decode(response.result.audio_base64)
with open ( "speech.wav" , "wb" ) as f:
f.write(audio_bytes)
phonemes = response.result.phonemes
for symbol, start, duration in zip (
phonemes.symbols,
phonemes.start_times_seconds,
phonemes.durations_seconds,
):
print ( f " { start :7.3f} s { duration :5.3f} s { symbol !r} " )
TypeScript — オーディオと音素をリクエストする
import { Supertone } from "@supertone/supertone" ;
import * as fs from "node:fs" ;
const VOICE_ID = "20160a4c5ba38967330c84" ; // replace with your voice ID
const client = new Supertone ({ apiKey: process . env . SUPERTONE_API_KEY });
const response = await client . textToSpeech . createSpeech ({
voiceId: VOICE_ID ,
apiConvertTextToSpeechUsingCharacterRequest: {
text: "Welcome to the workshop." ,
language: "en" ,
model: "sona_speech_2" ,
includePhonemes: true ,
},
});
const result = response . result as {
audioBase64 : string ;
phonemes ?: { symbols ?: string []; startTimesSeconds ?: number []; durationsSeconds ?: number [] };
};
fs . writeFileSync ( "speech.wav" , Buffer . from ( result . audioBase64 , "base64" ));
const { symbols = [], startTimesSeconds = [], durationsSeconds = [] } = result . phonemes ?? {};
for ( let i = 0 ; i < symbols . length ; i ++) {
console . log (
` ${ startTimesSeconds [ i ]. toFixed ( 3 ) } s ${ durationsSeconds [ i ]. toFixed ( 3 ) } s ${ symbols [ i ] } ` ,
);
}
音素をビゼーム(viseme)にマッピングする
よく使われる描画パイプラインでは、各IPA形式のシンボルを少数の口形(ビゼーム)にマッピングし、それらを補間しながら3Dリグや2Dスプライトを駆動します。
// Minimal English IPA → viseme mapping (extend for your rig)
const PHONEME_TO_VISEME : Record < string , string > = {
// Closed lip
"p" : "BMP" ,
"b" : "BMP" ,
"m" : "BMP" ,
// Open vowel
"ɑ" : "Aa" ,
"ʌ" : "Aa" ,
"ɐ" : "Aa" ,
// Wide smile
"iː" : "Ee" ,
"i" : "Ee" ,
// Rounded
"uː" : "Oo" ,
"u" : "Oo" ,
"o" : "Oo" ,
// Fricative
"f" : "FV" ,
"v" : "FV" ,
"θ" : "Th" ,
// Silence
"" : "Rest" ,
};
interface VisemeKeyframe {
time : number ;
duration : number ;
viseme : string ;
}
function buildVisemeTrack (
symbols : string [],
starts : number [],
durations : number [],
): VisemeKeyframe [] {
return symbols . map (( symbol , i ) => ({
time: starts [ i ],
duration: durations [ i ],
viseme: PHONEME_TO_VISEME [ symbol ] ?? "Rest" ,
}));
}
レンダーループでは、現在のオーディオ時刻を進めながら、そのタイムスタンプに該当するビゼームを参照します。ビゼームのウェイトをトゥイーンさせることで、口形がカクッと切り替わらないようにしましょう。
音素をリアルタイムでストリーミングする
stream_speechをinclude_phonemes: true付きで呼び出すと、レスポンスはNDJSONになります。受信した各行をパースしながら、リアルタイムでリップシンクを駆動できます。
import json
response = client.text_to_speech.stream_speech(
voice_id =VOICE_ID,
text = "Streaming lip sync in real time." ,
language = "en" ,
model = "sona_speech_1" ,
include_phonemes = True ,
)
for line in response.result.iter_lines():
if not line:
continue
payload = json.loads(line)
audio_chunk = base64.b64decode(payload[ "audio_base64" ])
schedule_audio(audio_chunk)
schedule_phonemes(payload[ "phonemes" ])
ヒント
音素をサポートするモデルを使ってください。 sona_speech_2、sona_speech_2_flash、sona_speech_1はいずれも音素をサポートします。supertonic_api_3とsupertonic_api_1はサポートしません。
滑らかな遷移。 実際の口は形を瞬時に切り替えません。多くのエンジンでは50〜80ms程度かけてビゼームのウェイトを補間します。APIから返る音素の継続時間は、こうしたトゥイーンの良い出発点になります。
強勢と間。 symbolの値が空のものは無音や間を表します — その間は口を休止ポーズに戻してください。
マッピングをローカライズしましょう。 音素からビゼームへの対応表は言語ごとに異なります。多言語コンテンツを提供する場合は、韓国語と日本語に合わせてマッピングを調整してください。
関連情報
発音と音素 include_phonemesとレスポンス形式のリファレンスです。
ストリーミング音声合成 リアルタイムリップシンク向けのNDJSONストリーミングです。