General TTS SSML 가이드
SSML(Speech Synthesis Markup Language, 음성 합성 마크업 언어)은 TTS에 입력된 텍스트를 합성 음성으로 변환하는 방법을 지정할 수 있는 XML 기반의 마크업(Markup) 언어입니다. SSML을 사용해 목소리, 발음, 말하는 속도, 음량 등을 변경할 수 있으며 상황마다 특수하게 읽어야 할 단어의 발음을 설정할 수 있습니다. 또한 합성 음성 중간에 효과음 등의 소리를 삽입할 수 있습니다.
안내
카카오 i 클라우드 General TTS에서 제공하는 SSML은 W3C의 Speech Synthesis Markup Language (SSML) Version 1.1을 기반으로 제작되었으며, 카카오 커스텀 태그와 속성을 제공합니다.
예약 문자
SSML 태그 내의 텍스트에서 SSML 예약 문자를 사용하려면 특수문자가 코드로 읽히지 않도록 이스케이프(Escape) 처리가 필요합니다. 아래 표에서 SSML 예약 문자와 이스케이프 코드를 확인할 수 있습니다. 보다 자세한 설명은 D Expansion of Entity and Character References (Non-Normative)를 참고하시기 바랍니다.
예약 문자 | 이스케이프 코드 |
---|---|
” | " |
& | & |
’ | ' |
< | < |
> | > |
지원하는 SSML 태그
<speak>
음성으로 변환할 텍스트를 나타내는 필수 태그입니다. 모든 텍스트는 반드시 <speak>
</speak>
태그 안에 작성되어야 합니다. SSML의 루트 요소이며, <speak>
태그를 제외한 모든 태그는 <speak>
태그의 하위 요소로 존재할 수 있습니다.
<speak>
태그는 문장, 문단 단위로 적용하는 것을 원칙으로 합니다. 만일 단어의 연속적인 나열을 합성하고자 할 경우, 음성 합성 품질을 위해 쉼표 등의 구두점으로 요소를 구분할 것을 권장합니다.
코드 예제 <speak>
태그
<speak> 안녕하세요. 반가워요. </speak>
<voice>
음성의 목소리를 설정할 수 있는 태그입니다. <speak>
, <voice>
태그를 제외한 모든 태그 (<kakao:effect>
, <prosody>
, <break>
, <audio>
, <say-as>
, <sub>
)를 하위 태그로 작성할 수 있습니다. 문장, 문단 단위로 적용하는 것을 원칙으로 하며, 역시 단어 별로 <voice>
태그 적용을 권장하지 않습니다.
<voice>
태그의 name
속성으로 원하는 목소리를 설정합니다.
<voice>
태그를 지정하지 않은 경우에는 기본값인Summer
목소리가 적용됩니다.name
속성값으로 합성 엔진이 지원하지 않거나 혹은 존재하지 않는 값을 입력한 경우 에러 메시지를 반환합니다.
속성 | 속성값 | 지원 엔진 | 설명 |
---|---|---|---|
name | Anna | Deep Voice | 일반, 여성 목소리 (카카오엔터프라이즈 커넥트 센터) |
Anna_Call | Deep Voice | 콜센터용, 여성 목소리 (카카오엔터프라이즈 커넥트 센터) | |
Bentley | Deep Voice | 일반, 남성 목소리 (카카오엔터프라이즈 커넥트 센터) | |
Bentley_Call | Deep Voice | 콜센터용, 남성 목소리 (카카오엔터프라이즈 커넥트 센터) | |
Cameron | Deep Voice | 일반, 여성 목소리 (카카오엔터프라이즈 커넥트 센터) | |
Cameron_Call | Deep Voice | 콜센터용, 여성 목소리 (카카오엔터프라이즈 커넥트 센터) | |
Carter | Deep Voice | 일반, 남성 목소리 | |
Carter_Call | Deep Voice | 콜센터용, 남성 목소리 | |
Casey | Deep Voice | 일반, 여성 목소리 | |
Casey_Call | Deep Voice | 콜센터용, 여성 목소리 | |
Chase | Deep Voice | 일반, 남성 목소리 | |
Chase_Call | Deep Voice | 콜센터용, 남성 목소리 | |
Claire | Deep Voice | 일반, 여성 목소리 | |
Claire_Call | Deep Voice | 콜센터용, 여성 목소리 | |
Clara | Deep Voice | 일반, 여성 목소리 | |
Clara_Call | Deep Voice | 콜센터용, 여성 목소리 | |
Cooper | Deep Voice | 일반, 남성 목소리 (카카오엔터프라이즈 커넥트 센터) | |
Cooper_Call | Deep Voice | 콜센터용, 남성 목소리 (카카오엔터프라이즈 커넥트 센터) | |
Cora | Deep Voice | 일반, 여성 목소리 | |
Cora_Call | Deep Voice | 콜센터용, 여성 목소리 | |
Daisy | Deep Voice | 일반, 여성 목소리 | |
Dakota | Deep Voice | 일반, 여성 목소리 | |
David | Deep Voice | 일반, 남성 목소리 | |
Dax | Deep Voice | 일반, 남성 목소리 | |
Dean | Deep Voice | 일반, 남성 목소리 | |
Della | Deep Voice | 일반, 여성 목소리 | |
Demi | Deep Voice | 일반, 여성 목소리 | |
Diana | Deep Voice | 일반, 여성 목소리 | |
Dorothy | Deep Voice | 일반, 여성 목소리 | |
Dream | Deep Voice | 일반, 여성 목소리 | |
Elias | Deep Voice | 일반, 남성 목소리 | |
Emily | Deep Voice | 일반, 여성 목소리 | |
Emma | Deep Voice | 일반, 여성 목소리 | |
Kai | Plain Voice, Deep Voice | 키즈 캐릭터 목소리 (카카오 i) | |
Kane | Deep Voice | 남자아이 목소리 | |
Kayla | Deep Voice | 여자아이 목소리 | |
Kevin | Deep Voice | 남자아이 목소리 | |
Kyle | Deep Voice | 남자아이 목소리 | |
Nathan | Deep Voice | 정보 전달용, 남성 목소리 | |
Nolan | Deep Voice | 정보 전달용, 남성 목소리 | |
Nora | Deep Voice | 정보 전달용, 여성 목소리 | |
Roman | Plain Voice, Deep Voice | 일반, 남성 목소리 (카카오 i) | |
Summer (기본값) | Plain Voice, Deep Voice | 일반, 여성 목소리 (카카오 i) |
안내
음성 샘플은 General TTS > Overview를 참고하시기 바랍니다.
코드 예제 <voice>
태그
<speak>
<voice name="Summer"> 안녕하세요. 서머 목소리입니다.</voice>
<voice name="Roman"> 로만 목소리입니다. </voice>
<voice name="Anna"> 안나 목소리입니다. </voice>
<voice name="Carter"> 카터 목소리입니다. </voice>
</speak>
<prosody>
음성의 속도와 크기를 조정하는 태그입니다. <speak>
, <prosody>
태그를 제외한 모든 태그(<kakao:effect>
, <break>
, <audio>
, <say-as>
, <sub>
)를 하위 태그로 작성할 수 있습니다. 문장, 문단 단위로 적용하는 것을 원칙으로 하며, 단어 별로 <prosody>
태그를 적용하지 않습니다.
속성 | 속성값 |
---|---|
rate | 음성 속도 지정 - slow : 0.9- medium (기본값): 1.0- fast : 1.1* SSML 표준에 따르면 최대 속도는 기본 대비 50% 증가(1.5), 최소 속도는 33.3% 감소(0.7)이므로 표준에 부합 * 기본 속도는 언어와 목소리 등에 따라 다름 |
volume | 음량 크기 지정 - soft : 0.7- medium (기본값): 1.0- loud : 1.4* SSML 표준에 따르면 최대 음량은 기본 대비 +4.08dB 증가(1.6배에 해당), 최소 음량은 정의 없음이므로 표준에 부합 |
코드 예제 <prosody>
태그
<speak>
<prosody rate="fast" volume="loud">안녕하세요. 반가워요.</prosody>
<prosody rate="slow" volume="soft">안녕하세요. 반가워요.</prosody>
</speak>
<break>
문장과 문장 사이에 휴지(pause)를 주어 끊어 읽을 수 있는 태그입니다. <speak>
, <prosody>
태그의 하위로 작성하며, <break>
의 하위 태그는 없습니다.
단어 사이에 <break>
태그를 적용할 경우 억양이 어색해질 수 있으므로 문장과 문장 사이에만 작성합니다. 또한 <break>
태그 앞에 선행 문장이 없거나, 특수 문자가 있어 텍스트의 합성이 실패하면 <break>
가 적용되지 않습니다. 속성을 입력하지 않을 시 150ms
로 기본 적용됩니다.
속성 | 속성값 |
---|---|
time | 150ms (0.15초)~1500ms (1.5초)까지 지원- 기본값: 150ms - 단위: ms (필수 입력) |
코드 예제 <break>
태그
<speak>
첫 번째 문장입니다.
<break/> 두 번째 문장입니다. 옵션을 안 준 경우 기본 세팅 150입니다.
세 번째 문장입니다.
<break time="150ms"/> 네 번째 문장입니다. 앞이랑 똑같죠?
<break time="1500ms"/> 다섯 번째 문장입니다. 길게 쉬지요?
</speak>
<kakao:effect>
카카오에서 제공하는 커스텀 태그입니다.
<speak>
태그를 제외한 모든 태그(<kakao:effect>
, <prosody>
, <break>
, <audio>
, <say-as>
, <sub>
)를 하위 태그로 작성할 수 있습니다. <kakao:effect>
를 하위 태그로 여러 번 작성할 수 있으며, tone
속성을 사용해 존댓말을 반말로 변경할 수 있습니다. 반말을 존댓말로 변경하는 기능은 지원하지 않습니다.
속성 | 속성값 |
---|---|
tone | - default (기본값): 사용자 입력 텍스트 그대로 음성 반환- friendly : 친구 같은 반말 |
코드 예제 <kakao:effect>
태그
<speak>
<kakao:effect tone="friendly"> 안녕하세요. 반가워요.
<kakao:effect tone="default"> 잘 지내요? 여긴 존댓말 구역이에요.</kakao:effect>
<prosody> 저도 잘 지내요. </prosody>
</kakao:effect>
</speak>
<say-as>
날짜, 시간과 같은 축약형 표현이나 전화번호, 스펠링 등 발음을 상황에 맞게 적용하는 태그입니다. 입력한 속성값에 따라 모델이 특수 표현을 해석하여 음성을 합성합니다. <say-as>
하위에 적용할 수 있는 태그는 없습니다.
format
속성은 interpret-as
속성의 속성값으로 date
, time
, kakao:number
를 입력했을 때에만 함께 쓰입니다.
속성 | 속성값 |
---|---|
interpret-as | 단일 속성으로 사용 가능 - spell-out : 영어 단어를 개별 알파벳으로 발음- digits : 숫자를 하나씩 발음 (ex. 일, 이, 삼)- kakao:serial : 숫자를 하나씩 읽되, -를 ‘다시’로 발음- telephone : 전화번호 읽기처럼 0을 ‘공’으로, -를 ‘에’로 발음- kakao:none : 원문을 적절한 조사로 적용하여 발음 - kakao:score : 스코어로 발음 (ex. 3:1 → 삼 대 일)- kakao:vocative : 호격 조사를 적절하게 반영해 발음 (ex. 영숙야 → 영숙아)format 속성 필수 지정 - date : 날짜 형식으로 발음- time : 시간으로 발음- kakao:number : 숫자의 고유어 또는 한자어 발음 선택 |
format date | 날짜 형식을 다양하게 조합 가능 (ex. dmy, my, ymd, d, m 등) - y : 년, m : 월, d : 일- 조합된 순서대로 숫자를 대입해 발음 - |
format time | 시간 형식을 다양하게 조합 가능 (ex. hms12, hm24, ms, hm, s 등) - h : 시, m : 분, s : 초, 12 : 12시간제, 24 : 24시간제 - 조합된 순서대로 숫자를 대입해 발음 - 시간제 미입력 시, 오전/오후 없이 12시간제로 발음 - <say-as> 태그를 적용할 시간 표기법은 : 만 사용 |
format kakao:number | 숫자 읽기 방식 지정 - korean : 숫자 고유어 발음 (ex. 한/하나, 두/둘, 세/셋)- chinese : 숫자 한자어 발음 (ex. 일, 이, 삼)- 수량 단위 명사를 <say-as> 태그 내에 작성 |
코드 예제 <say-as>
태그: interpret-as
단일 속성 사용
<speak>
<say-as interpret-as="spell-out">kakao</say-as>를 스펠링으로 읽어줍니다.
<say-as interpret-as="digits">1987</say-as>, 숫자를 낱개로 읽어줍니다.
<say-as interpret-as="telephone">82-010-1234-5678</say-as>, 휴대폰 번호를 잘 읽어줍니다.
<say-as interpret-as="kakao:none">부처님 오신 날</say-as>가, 조사 처리도 잘해줍니다.
<say-as interpret-as="kakao:score">3:1</say-as>로 이겼습니다. 스코어로 인식하고 읽어줍니다.
<say-as interpret-as="kakao:vocative">영숙</say-as>야.
<say-as interpret-as="kakao:vocative">톤</say-as>야.
</speak>
코드 예제 <say-as>
태그: format
필수 속성 사용
<speak>
<say-as interpret-as="date" format="dmy">10.6.85</say-as> 입니다.
<say-as interpret-as="date" format="my">10.1985</say-as> 입니다.
<say-as interpret-as="date" format="md">10-6</say-as> 입니다.
<say-as interpret-as="date" format="d">10</say-as> 입니다.
<say-as interpret-as="time" format="hms12">13:16:45</say-as> 입니다.
<say-as interpret-as="time" format="hm24">13:50</say-as> 입니다.
<say-as interpret-as="time" format="ms">10:59</say-as> 입니다.
<say-as interpret-as="time" format="h">13</say-as> 입니다.
<say-as interpret-as="kakao:number" format="chinese">13장</say-as> 입니다.
<say-as interpret-as="kakao:number" format="korean">13장</say-as> 입니다.
</speak>
<sub>
단어의 발음을 직접 지정할 수 있는 태그입니다. <sub>
하위에 적용할 수 있는 태그는 없습니다.
속성값은 모델의 해석이 용이하도록 한글로 작성합니다.
속성 | 속성값 |
---|---|
alias | 합성 요청 텍스트 대신 발음할 단어를 직접 입력 - 가능한 한글로 입력 |
코드 예제 <sub>
태그
<speak><sub alias="알루미늄">Al</sub>은 단단하다.</speak>
<audio>
외부 음원을 재생할 수 있는 태그입니다. <speak>
, <prosody>
태그 하위에 작성할 수 있습니다.
음성과 함께 효과음 등을 제공하기에 용이하며, 음원의 시작과 종료 지점, 반복 횟수 등을 지정할 수 있습니다.
속성 | 속성값 |
---|---|
src | 재생할 음원의 원본 위치(URL) - 카카오 i 클라우드 오브젝트 스토리지 경로만 입력 가능 - 재생 지원 오디오 스펙 ㄴ 형식: mp3(스펙 무관) / wav(16kHz, 16bit, mono) ㄴ 파일 길이: 180초 이하 권장 |
clipBegin | 음원의 시작 지점 설정 - 단위: s (필수 입력)- 소수점 첫 번째 자리까지 입력 가능 - 음원의 전체 길이보다 큰 값을 입력할 경우 무시하고 음원 재생하지 않음 - clipBegin 속성값이 clipEnd 속성값보다 큰 경우 음원 재생하지 않음- clipEnd 와 반드시 함께 입력할 필요 없음- ex. 음원을 3분부터 시작하고 싶은 경우 180s 입력 |
clipEnd | 음원이 끝나는 지점 설정 - 단위: s (필수 입력)- 소수점 첫 번째 자리까지 입력 가능 - 음원의 전체 길이보다 큰 값을 입력할 경우 무시하고 음원 끝까지 재생 - clipBegin 과 반드시 함께 입력할 필요 없음 |
repeatCount | 음원 반복 횟수 - 자연수를 단위 없이 입력 (소수 입력 시 내림 처리) - clipBegin 과 clipEnd 로 설정한 음원 시작부터 끝나는 지점까지 반복 |
repeatDur | 음원 반복 시간 - 단위: s (필수 입력)- 소수점 첫 번째 자리까지 입력 가능 - 음원의 시작과 끝을 기준으로 반복 - clipBegin 과 clipEnd 를 설정한 경우 해당 구간 반복- 설정한 반복 시간보다 clipBegin , clipEnd , repeatCount 으로 정한 재생 시간이 더 큰 경우 반복 시간까지만 재생- repeatDur 와 repeatCount 를 함께 설정할 경우 repeatDur 기준으로 작동 |
soundLevel | 음원 볼륨 조절 - 기본값: 0 - 단위: (±n) dB (필수 입력)- 소수점 첫째 자리까지 입력 권장 - 권장값: -40 ~ +40 - 너무 높거나 낮은 값 입력 시 클리핑 발생 |
speed | 음원 속도 조절 - 기본값: 0 - 단위: % (필수 입력)- 자연수만 입력 가능 - 권장값: 70 ~ 130 |
코드 예제 <audio>
태그
<speak>
<audio src="https://objectstorage.kr-central-1.kakaoi.io/v1/797c9fa126ea4678b2137074647faa18/general-tts-guide/ssml%2Fdog-barking.mp3" clipBegin="1.1s" clipEnd="3s" repeatDur="10s" soundLevel="3dB" speed="70%"/>
</speak>
SSML 사용 시 주의 사항
공백 처리
문장 내에 SSML 태그를 삽입하는 경우 공백(space)을 올바른 위치에 삽입하여야 합니다. 이를 통해 의도하지 않은 끊어 읽기 오류를 방지할 수 있습니다.
두 SSML 태그 사이에 공백만 입력한 경우에는 공백을 무시합니다. 공백을 인식시키려면, 태그 안에 공백을 포함시키거나 태그 사이에 공백과 글자를 함께 입력합니다.
코드 예제 태그 사이에 공백만 입력한 경우 - 공백 무시
<speak>
<say-as interpret-as="kakao:none">내일</say-as> <say-as interpret-as="kakao:none">제주특별자치도</say-as>에 첫눈 예보가 있어요.
</speak>
코드 예제 태그 안에 공백이 포함된 경우 - 공백 인식
<speak>
<say-as interpret-as="kakao:none">내일 </say-as><say-as interpret-as="kakao:none">제주특별자치도</say-as>에 첫눈 예보가 있어요.
</speak>
코드 예제 태그 사이에 공백과 글자를 함께 입력한 경우 - 공백 인식
<speak>
<say-as interpret-as="kakao:none">내일</say-as>은 <say-as interpret-as="kakao:none">제주특별자치도</say-as>에 첫눈 예보가 있어요.
</speak>
줄바꿈 처리
태그로 구분되지만 붙여 읽어야 하는 구절을 줄바꿈으로 분리하는 경우, 끊어 읽기 오류가 발생할 수 있습니다. 한 문장 안에서는 되도록 줄바꿈을 적용하지 않는 것이 좋습니다.
코드 예제 부적절한 줄바꿈 처리
<speak>
<say-as interpret-as="kakao:none">내일</say-as>
은
<say-as interpret-as="kakao:none">제주특별자치도</say-as>
에 첫눈 예보가 있어요.
</speak>
부록. SSML 사용 예시
Case 1: 조사 처리하기
단어에 적합한 조사나 어미의 직접 수정 없이 자동 반영되도록 할 경우 <say-as interpret-as="kakao:none">
태그를 활용합니다.
코드 예제 조사 처리를 위한 <say-as>
태그
<speak>
오늘은 <say-as interpret-as="kakao:none">부처님</say-as>가 태어난 날로, <say-as interpret-as="kakao:none">부처님 오신 날</say-as>예요.
</speak>
Case 2: 효과음과 함께 음성 재생하기
음성에 효과음을 함께 적용하고자 할 경우 <audio>
태그를 활용합니다.
코드 예제 효과음 재생을 위한 <audio>
태그
<speak>
<audio src="https://objectstorage.kr-central-1.kakaoi.io/v1/797c9fa126ea4678b2137074647faa18/general-tts-guide/dog-barking.mp3" clipBegin="1.1s" clipEnd="3s"/> 안녕하세요?
</speak>
Case 3: 개봉한 영화의 발음 지정하기
영화 1987은 “천구백팔십칠”이 아니라 “일구팔칠”로 한 글자씩 읽어야 합니다. 기존의 발음과 다르게 읽고자 할 때, <say-as>
또는 <sub>
태그를 활용합니다. <say-as>
의 속성값으로 설정이 어려운 경우에는 <sub>
태그로 발음을 직접 입력합니다.
코드 예제 상황에 맞는 발음을 위한 <say-as>
태그
<speak>
영화 <say-as interpret-as="digits">1987</say-as>은, 흥행 1위입니다.
</speak>
코드 예제 상황에 맞는 발음을 위한 <sub>
태그
<speak>
영화 <sub alias="일구팔칠">1987</sub>은, 흥행 1위입니다.
</speak>
Case 4: 도서 목차 읽기
10장을 “열 장”으로 발음하는 기본 규칙과 달리, 책의 장(chapter)은 “십장”으로 읽는 것이 자연스럽습니다. 이러한 경우 <say-as>
태그로 숫자 읽기 규칙을 설정합니다.
코드 예제 목차 읽기를 위한 <say-as>
태그
<speak>
오늘은 부가 의문문에 대해서 공부해 볼게요. 다들 영어 문제집 <say-as interpret-as="kakao:number" format="chinese">10</say-as>장 펴 주세요.
</speak>