001/*
002 *   Copyright 2024 Vonage
003 *
004 *   Licensed under the Apache License, Version 2.0 (the "License");
005 *   you may not use this file except in compliance with the License.
006 *   You may obtain a copy of the License at
007 *
008 *        http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *   Unless required by applicable law or agreed to in writing, software
011 *   distributed under the License is distributed on an "AS IS" BASIS,
012 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *   See the License for the specific language governing permissions and
014 *   limitations under the License.
015 */
016package com.vonage.client.voice;
017
018import com.fasterxml.jackson.annotation.JsonIgnore;
019import com.fasterxml.jackson.annotation.JsonProperty;
020import com.vonage.client.JsonableBaseObject;
021
022/**
023 * Defines the text-to-speech properties.
024 */
025public final class TalkPayload extends JsonableBaseObject {
026    @JsonIgnore String uuid;
027    private final String text;
028    private final Integer loop, style;
029    private final Double level;
030    private final Boolean premium;
031    private final TextToSpeechLanguage language;
032
033    private TalkPayload(Builder builder) {
034        if ((text = builder.text) == null || text.trim().isEmpty()) {
035            throw new IllegalArgumentException("Text is required.");
036        }
037        if ((loop = builder.loop) != null && loop < 0) {
038            throw new IllegalArgumentException("Loop cannot be negative.");
039        }
040        if ((style = builder.style) != null && style < 0) {
041            throw new IllegalArgumentException("Style cannot be negative.");
042        }
043        if ((level = builder.level) != null && (level < -1 || level > 1)) {
044            throw new IllegalArgumentException("Volume level must be between -1 and 1 (inclusive).");
045        }
046        premium = builder.premium;
047        language = builder.language;
048    }
049
050    /**
051     * The number of times the audio file at stream_url is repeated before the stream ends (0 for infinite).
052     *
053     * @return The number of repetitions, or {@code null} if unset (the default).
054     */
055    @JsonProperty("loop")
056    public Integer getLoop() {
057        return loop;
058    }
059
060    /**
061     * A string of up to 1500 characters containing the message to be synthesized in the Call or Conversation.
062     * Each comma in text adds a short pause to the synthesized speech.
063     *
064     * @return The speech text, or {@code null} if unset (the default).
065     */
066    @JsonProperty("text")
067    public String getText() {
068        return text;
069    }
070
071    /**
072     * The Language that will be used to convert {@code text} into speech.
073     *
074     * @return The TTS language as an enum, or {@code null} if unset (the default).
075     */
076    @JsonProperty("language")
077    public TextToSpeechLanguage getLanguage() {
078        return language;
079    }
080
081    /**
082     * The Vocal Style to use (range, tessitura, timbre) to use in the speech.
083     *
084     * @return The voice style, or {@code null} if unset (the default).
085     */
086    @JsonProperty("style")
087    public Integer getStyle() {
088        return style;
089    }
090
091    /**
092     * The volume level that the speech is played at, between -1 and 1.
093     *
094     * @return The speech volume, or {@code null} if unset (the default).
095     */
096    @JsonProperty("level")
097    public Double getLevel() {
098        return level;
099    }
100
101    /**
102     * Whether the premium version of the specified voice style should be used if available.
103     *
104     * @return {@code true} for premium, {@code false} for standard or {@code null} if unset (the default).
105     */
106    @JsonProperty("premium")
107    public Boolean getPremium() {
108        return premium;
109    }
110
111    /**
112     * Entry point for constructing an instance of this class.
113     *
114     * @param text The text to convert to speech.
115     *
116     * @return A new Builder.
117     */
118    public static Builder builder(String text) {
119        return new Builder(text);
120    }
121
122    /**
123     * Builder for configuring properties of TalkPayload.
124     */
125    public static final class Builder {
126        private final String text;
127        private Integer loop, style;
128        private Double level;
129        private Boolean premium;
130        private TextToSpeechLanguage language;
131
132        Builder(String text) {
133            this.text = text;
134        }
135
136        /**
137         * The number of times to repeat the message. The default value is {@code 1}, or you can use {@code 0}
138         *  to indicate that the message should be repeated indefinitely.
139         *
140         * @param loop The number of repetitions.
141         *
142         * @return This builder.
143         */
144        public Builder loop(int loop) {
145            this.loop = loop;
146            return this;
147        }
148
149        /**
150         * The vocal style (vocal range, tessitura, and timbre) to use for text-to-speech.
151         * Each language has varying number of styles. Refer to
152         * <a href=https://developer.vonage.com/en/voice/voice-api/concepts/text-to-speech#supported-languages>
153         * the documentation</a> for available values.
154         *
155         * @param style The language style as an integer.
156         *
157         * @return This builder.
158         */
159        public Builder style(int style) {
160            this.style = style;
161            return this;
162        }
163
164        /**
165         * The volume level that the speech is played.
166         * This can be any value between -1 to 1 in 0.1 increments, with 0 being the default.
167         *
168         * @param level The volume of speech.
169         *
170         * @return This builder.
171         */
172        public Builder level(double level) {
173            this.level = level;
174            return this;
175        }
176
177        /**
178         * Specify whether to use the premium version of the specified style if available.
179         * Find out more information about Premium Voices in the
180         * <a href=https://developer.vonage.com/en/voice/voice-api/guides/text-to-speech#premium-voices>
181         * Text-To-Speech guide</a>.
182         *
183         * @param premium {@code true} to use premium voice or {@code false} for standard version (the default).
184         *
185         * @return This builder.
186         */
187        public Builder premium(boolean premium) {
188            this.premium = premium;
189            return this;
190        }
191
192        /**
193         * The speech language to use.
194         *
195         * @param language Language code as an enum.
196         *
197         * @return This builder.
198         */
199        public Builder language(TextToSpeechLanguage language) {
200            this.language = language;
201            return this;
202        }
203
204        /**
205         * Constructs the TalkPayload object.
206         *
207         * @return A new {@linkplain TalkPayload} instance with this builder's properties.
208         */
209        public TalkPayload build() {
210            return new TalkPayload(this);
211        }
212    }
213}