commit 25/11/2025

This commit is contained in:
2025-11-25 11:52:05 +07:00
parent 080d75946b
commit 802cf940a9
8 changed files with 317 additions and 10 deletions

View File

@@ -0,0 +1,59 @@
<component name="libraryTable">
<library name="google.cloud.texttospeech" type="repository">
<properties maven-id="com.google.cloud:google-cloud-texttospeech:2.81.0" />
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/google/cloud/google-cloud-texttospeech/2.81.0/google-cloud-texttospeech-2.81.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-api/1.76.0/grpc-api-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.42.0/error_prone_annotations-2.42.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-stub/1.76.0/grpc-stub-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/codehaus/mojo/animal-sniffer-annotations/1.24/animal-sniffer-annotations-1.24.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-protobuf/1.76.0/grpc-protobuf-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-protobuf-lite/1.76.0/grpc-protobuf-lite-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/api/api-common/2.55.1/api-common-2.55.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/auto/value/auto-value-annotations/1.11.0/auto-value-annotations-1.11.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/j2objc/j2objc-annotations/3.1/j2objc-annotations-3.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/protobuf/protobuf-java/3.25.8/protobuf-java-3.25.8.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/api/grpc/proto-google-common-protos/2.63.1/proto-google-common-protos-2.63.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/api/grpc/proto-google-cloud-texttospeech-v1/2.81.0/proto-google-cloud-texttospeech-v1-2.81.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/api/grpc/proto-google-cloud-texttospeech-v1beta1/0.170.0/proto-google-cloud-texttospeech-v1beta1-0.170.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/guava/guava/33.5.0-jre/guava-33.5.0-jre.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/guava/failureaccess/1.0.3/failureaccess-1.0.3.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jspecify/jspecify/1.0.0/jspecify-1.0.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/api/gax/2.72.1/gax-2.72.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/auth/google-auth-library-credentials/1.40.0/google-auth-library-credentials-1.40.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/protobuf/protobuf-java-util/3.25.8/protobuf-java-util-3.25.8.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/opencensus/opencensus-api/0.31.1/opencensus-api-0.31.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-context/1.76.0/grpc-context-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/auth/google-auth-library-oauth2-http/1.40.0/google-auth-library-oauth2-http-1.40.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/api/gax-grpc/2.72.1/gax-grpc-2.72.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-inprocess/1.76.0/grpc-inprocess-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-core/1.76.0/grpc-core-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/android/annotations/4.1.1.4/annotations-4.1.1.4.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-alts/1.76.0/grpc-alts-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-grpclb/1.76.0/grpc-grpclb-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/conscrypt/conscrypt-openjdk-uber/2.5.2/conscrypt-openjdk-uber-2.5.2.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-auth/1.76.0/grpc-auth-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-netty-shaded/1.76.0/grpc-netty-shaded-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-util/1.76.0/grpc-util-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/perfmark/perfmark-api/0.27.0/perfmark-api-0.27.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-googleapis/1.76.0/grpc-googleapis-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-xds/1.76.0/grpc-xds-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/grpc/grpc-services/1.76.0/grpc-services-1.76.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/re2j/re2j/1.8/re2j-1.8.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/api/gax-httpjson/2.72.1/gax-httpjson-2.72.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.12.1/gson-2.12.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/http-client/google-http-client/2.0.2/google-http-client-2.0.2.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpclient/4.5.14/httpclient-4.5.14.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/commons-codec/commons-codec/1.18.0/commons-codec-1.18.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpcore/4.4.16/httpcore-4.4.16.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/io/opencensus/opencensus-contrib-http-util/0.31.1/opencensus-contrib-http-util-0.31.1.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/com/google/http-client/google-http-client-gson/2.0.2/google-http-client-gson-2.0.2.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/threeten/threetenbp/1.7.0/threetenbp-1.7.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -36,5 +36,6 @@
<jarDirectory url="file://C:/SLC/Apache POI" recursive="false" type="SOURCES" />
</library>
</orderEntry>
<orderEntry type="library" name="google.cloud.texttospeech" level="project" />
</component>
</module>

View File

@@ -1,14 +1,43 @@
package google
class GoogleTTS {
import com.google.cloud.texttospeech.v1.AudioConfig
import com.google.cloud.texttospeech.v1.AudioEncoding
import com.google.cloud.texttospeech.v1.SynthesisInput
import com.google.cloud.texttospeech.v1.TextToSpeechClient
import com.google.cloud.texttospeech.v1.VoiceSelectionParams
import org.tinylog.Logger
import java.nio.file.Files
import kotlin.io.path.Path
// project : Gtc-Cloud-AAS
// project ID : gtc-cloud-aas
// project number : 247742838587
// location : indonesia-southeast1
// name : API key 1
// creation date : 21 Nov 2025
// read : https://docs.cloud.google.com/vertex-ai/generative-ai/docs/reference/libraries#client-libraries-usage-java
private val BoundAccount = "vertex-express@gtc-cloud-aas.iam.gserviceaccount.com"
private val API_KEYS = "AQ.Ab8RN6K2ZF6wykKVJcuHsfm0po9IXn3alBpO5cfZzPb4lq35Yw"
@Suppress("unused")
class GoogleTTS(credentialJson: String = "c:/googlettsapi/gtc-cloud-aas-ae23c9552e1f.json") {
init{
System.setProperty("GOOGLE_APPLICATION_CREDENTIALS", credentialJson)
}
fun Speak(text: String, language : GoogleTTSLanguage, voicetype: GoogleTTSVoiceType, targetfilename: String){
TextToSpeechClient.create().use { client ->
try{
val input = SynthesisInput.newBuilder().setText(text).build()
val voice = VoiceSelectionParams.newBuilder()
.setLanguageCode(language.name)
.setName(String.format("%s-%s", language.name, voicetype.name))
.build()
val audioconfig = AudioConfig.newBuilder()
.setAudioEncoding(AudioEncoding.LINEAR16)
.setSampleRateHertz(44100)
.build()
val response = client.synthesizeSpeech(input, voice, audioconfig)
val bytes = response.audioContent.toByteArray()
val target = Path(targetfilename)
Files.write(target, bytes)
Logger.info { "Speak success, file saved to : $targetfilename" }
} catch (e : Exception){
Logger.error { "Speak failed, message : ${e.message}" }
}
}
}
}

View File

@@ -0,0 +1,10 @@
package google
@Suppress("unused")
enum class GoogleTTSLanguage(code: String) {
Indonesia("id-ID"),
English("en-US"),
Japanese("ja-JP"),
Chinese("zh-CN"),
Arabic("ar-SA")
}

View File

@@ -0,0 +1,11 @@
package google
@Suppress("unused")
enum class GoogleTTSSSMLBreakStrength(code: String) {
None("none"),
ExtraWeak("x-weak"),
Weak("weak"),
Medium("medium"),
Strong("strong"),
ExtraStrong("x-strong")
}

View File

@@ -0,0 +1,9 @@
package google
@Suppress("unused")
enum class GoogleTTSSSMLStrength(code: String) {
Strong("strong"),
Moderate("moderate"),
None("none"),
Reduced("reduced")
}

View File

@@ -0,0 +1,9 @@
package google
@Suppress("unused")
enum class GoogleTTSVoiceType(name: String) {
FemaleA("Wavenet-A"),
MaleA("Wavenet-B"),
MaleB("Wavenet-C"),
FemaleB("Wavenet-D")
}

179
src/google/SSML.kt Normal file
View File

@@ -0,0 +1,179 @@
package google
class SSML private constructor(
private val result : List<String>
) {
override fun toString(): String = result.joinToString("\n")
@Suppress("unused")
class SSMLBuilder {
private val result = mutableListOf<String>()
/**
* Create a new SSMLBuilder
* Source : https://cloud.google.com/text-to-speech/docs/ssml
*/
constructor()
/**
* Add a text to the SSML
* @param text The text to add
* @return The SSMLBuilder
*/
fun addText(text: String): SSMLBuilder = apply {
result.add(text)
}
/**
* Add a break to the SSML
* @param ms The duration of the break in milliseconds
* @return The SSMLBuilder
*/
fun addBreak(ms: Int): SSMLBuilder = apply {
result.add("<break time=\"${ms}ms\"/>")
}
/**
* Add a break to the SSML
* @param strength The strength of the break, relative to the surrounding text
* @return the SSMLBuilder
*/
fun addBreak(strength: GoogleTTSSSMLBreakStrength): SSMLBuilder = apply {
result.add("<break strength=\"${strength.name}\"/>")
}
/**
* For spelling currency / money
* @param amount The amount to spell
* @param lang The language to use
* @return The SSMLBuilder
*/
fun addSayAsCurrency(amount: String, lang: GoogleTTSLanguage): SSMLBuilder = apply {
result.add(
"<say-as interpret-as=\"currency\" language=\"${lang.name}\">$amount</say-as>"
)
}
/**
* For spelling numbers
* Number will be spelled individually
* @param number The number to spell
* @return The SSMLBuilder
*/
fun addSayAsTelephone(number: String): SSMLBuilder = apply {
result.add("<say-as interpret-as=\"telephone\">$number</say-as>")
}
/**
* For spelling letter by letter
* @param text The text to spell
* @return The SSMLBuilder
*/
fun addSayAsVerbatim(text: String): SSMLBuilder = apply {
result.add("<say-as interpret-as=\"verbatim\">$text</say-as>")
}
/**
* For spelling date
* @param date The date to spell, example 10-9-2021, or 2021-09-10, or 9-10
* @param format The format of the date, example dmy, ymd, mdy
* @return The SSMLBuilder
*/
fun addSayAsDate(date: String, format: String): SSMLBuilder = apply {
result.add(
"<say-as interpret-as=\"date\" format=\"$format\">$date</say-as>"
)
}
/**
* Spelling letter by letter
* @param text The text to spell
* @return the SSMLBuilder
*/
fun addSayAsCharacters(text: String): SSMLBuilder = apply {
result.add("<say-as interpret-as=\"characters\">$text</say-as>")
}
/**
* Saying number as cardinal
* for example 12345 will be spelled as twelve thousand three hundred forty five
* @param number The number to say
* @return The SSMLBuilder
*/
fun addSayAsCardinal(number: String): SSMLBuilder = apply {
result.add("<say-as interpret-as=\"cardinal\">$number</say-as>")
}
/**
* Saying number as ordinal
* for example 1 will be spelled as 'first'
* @param number number to say
* @return The SSMLBuilder
*/
fun addSayAsOrdinal(number: String): SSMLBuilder = apply {
result.add("<say-as interpret-as=\"ordinal\">$number</say-as>")
}
/**
* Saying number as fraction
* for example 5+1/2 will be spelled as 'five and a half'
* @param fraction number to say
* @return the SSMLBuilder
*/
fun addSayAsFraction(fraction: String): SSMLBuilder = apply {
result.add("<say-as interpret-as=\"fraction\">$fraction</say-as>")
}
/**
* Saying a word like it was censored 'beep'
* @param text The text to censor
* @return the SSMLBuilder
*/
fun addSayAsExpletive(text: String): SSMLBuilder = apply {
result.add("<say-as interpret-as=\"expletive\">$text</say-as>")
}
/**
* Say unit in singular or plural form
* For example 10 foot will be spelled as 'ten feet'
* @param unit The unit to spell
* @return the SSMLBuilder
*/
fun addSayAsUnit(unit: String): SSMLBuilder = apply {
result.add("<say-as interpret-as=\"unit\">$unit</say-as>")
}
/**
* Say a time
* for example 12:30 will be spelled as 'twelve thirty'
* @param time The time to spell
* @return the SSMLBuilder
*/
fun addSayAsTime(time: String): SSMLBuilder = apply {
result.add("<say-as interpret-as=\"time\" format=\"24\">$time</say-as>")
}
/**
* add a full sentence with specific emphasis
* @param text full sentence, not word
* @param strength the strength of the emphasis
* @return the SSMLBuilder
*/
fun addEmphasis(text: String, strength: GoogleTTSSSMLStrength): SSMLBuilder = apply {
result.add("<emphasis level=\"${strength.name}\">$text</emphasis>")
}
/**
* Build the SSML
* @return SSML object
*/
fun build(): SSML {
val xx = mutableListOf<String>()
xx.add("<speak>")
xx.addAll(result)
xx.add("</speak>")
return SSML(xx)
}
}
}