YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
GoogleSpeechSynthesizer.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2023 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#ifndef _USE_MATH_DEFINES
7#define _USE_MATH_DEFINES
8#endif
9
11
12#include <yarp/sig/SoundFile.h>
13
15#include <yarp/os/LogStream.h>
16#include <fstream>
17
18#include <cmath>
19
20using namespace yarp::os;
21using namespace yarp::dev;
22namespace texttospeech = ::google::cloud::texttospeech_v1;
23
24
26
27
32
34{
35 if(m_offline)
36 {
37 return true;
38 }
39 if(m_synthVoices.size() == 0)
40 {
41 yCError(GOOGLESPEECHSYNTH) << "You haven't set the language code yet. Voice name cannot be set without a language code";
42 }
43
44 google::protobuf::RepeatedPtrField<google::cloud::texttospeech::v1::Voice>::iterator it;
45 for(it = m_synthVoices.begin(); it != m_synthVoices.end(); it++)
46 {
47 if(it->name() == voice_name)
48 {
49 return true;
50 }
51 }
52
53 yCError(GOOGLESPEECHSYNTH) << "Unsupported voice name";
54 return false;
55}
56
58{
59 if(config.check("__offline"))
60 {
61 m_offline = config.find("__offline").asInt32() == 1;
62 }
63
64 parseParams(config);
65
66 m_synthClient = std::make_shared<texttospeech::TextToSpeechClient>(texttospeech::MakeTextToSpeechConnection());
67 m_synthVoiceSelParams = std::make_shared<google::cloud::texttospeech::v1::VoiceSelectionParams>();
68 m_synthInput = std::make_shared<google::cloud::texttospeech::v1::SynthesisInput>();
69 m_synthAudioConfig = std::make_shared<google::cloud::texttospeech::v1::AudioConfig>();
70
71 if(!setLanguage(m_language_code) && !m_offline)
72 {
73 return false;
74 }
75
76 if(config.check("voice_name"))
77 {
78 if(!setVoice(config.find("voice_name").asString()))
79 {
80 return false;
81 }
82 };
83
85 {
86 return false;
87 }
89 {
90 return false;
91 }
92
93 m_synthAudioConfig->set_audio_encoding(google::cloud::texttospeech::v1::MP3);
94
95 return true;
96}
97
99{
100 return true;
101}
102
104{
105 if(m_offline)
106 {
107 m_synthVoiceSelParams->set_language_code(language);
109 }
110 if(language == "auto")
111 {
112 yCError(GOOGLESPEECHSYNTH) << "The \"auto\" option is not supported by this device";
113
115 }
116 if(language == m_synthVoiceSelParams->language_code() && m_synthVoices.size() != 0)
117 {
118 yCWarning(GOOGLESPEECHSYNTH) << "The language code is already set to:" << language;
120 }
121 google::cloud::StatusOr<google::cloud::texttospeech::v1::ListVoicesResponse> response = m_synthClient->ListVoices(language);
122 if (!response) {
123 yCError(GOOGLESPEECHSYNTH) << "Error in getting the list of available voices. Google status:\n\t" << response.status().message() << "\n";
125 }
126 m_synthVoices = response->voices();
127 m_synthVoiceSelParams->set_language_code(language);
128
129 setVoice(m_synthVoices[0].name());
130
132}
133
135{
136 language = m_synthVoiceSelParams->language_code();
137
139}
140
142{
143 if(voice_name == "auto")
144 {
145 m_synthVoiceSelParams->set_name(m_synthVoices[0].name());
146 yCInfo(GOOGLESPEECHSYNTH) << "auto option selected. Setting the voice name to:" << m_synthVoiceSelParams->name();
147
149 }
150
151 if(m_offline)
152 {
153 m_synthVoiceSelParams->set_name(voice_name);
155 }
156
158 {
160 }
161
162 m_synthVoiceSelParams->set_name(voice_name);
163
165}
166
173
175{
176 m_synthAudioConfig->set_speaking_rate(speed);
178 {
179 yCError(GOOGLESPEECHSYNTH) << "Error while setting the speach rate (speed). The value is outside the allowed range [" << SPEED_RANGE.first << SPEED_RANGE.second << "]";
181 }
182
184}
185
187{
188 speed = m_synthAudioConfig->speaking_rate();
189
191}
192
194{
195 m_synthAudioConfig->set_pitch(pitch);
197 {
198 yCError(GOOGLESPEECHSYNTH) << "Error while setting the speach pitch. The value is outside the allowed range [" << PITCH_RANGE.first << PITCH_RANGE.second << "]";
200 }
201
203}
204
206{
207 pitch = m_synthAudioConfig->pitch();
208
210}
211
213{
214 m_synthInput->set_text(text);
215 google::cloud::StatusOr<google::cloud::texttospeech::v1::SynthesizeSpeechResponse> response = m_synthClient->SynthesizeSpeech(*m_synthInput,*m_synthVoiceSelParams,*m_synthAudioConfig);
216 if (!response) {
217 yCError(GOOGLESPEECHSYNTH) << "Error synthesizing speech. Google status:\n\t" << response.status().message() << "\n";
219 }
220
221 sound.clear();
222 if(!yarp::sig::file::read_bytestream(sound, response->audio_content().data(), response->audio_content().size(), ".mp3"))
223 {
224 yCError(GOOGLESPEECHSYNTH) << "Error while transfering data from google response to yarp::sigSound sound object";
226 }
227
229}
const yarp::os::LogComponent & GOOGLESPEECHSYNTH()
const std::pair PITCH_RANGE
const std::pair SPEED_RANGE
bool parseParams(const yarp::os::Searchable &config) override
Parse the DeviceDriver parameters.
bool _voiceSupported(const std::string &voice_name)
Checks whether or not a particular voice name is supported by the currently selected language code.
yarp::dev::ReturnValue getPitch(double &pitch) override
Gets the current pitch set for speech synthesis.
yarp::dev::ReturnValue getLanguage(std::string &language) override
Gets the current language set for speech synthesis.
yarp::dev::ReturnValue setSpeed(const double speed=0) override
Sets the voice speed for speech synthesis.
yarp::dev::ReturnValue getSpeed(double &speed) override
Gets the current voice speed.
yarp::dev::ReturnValue setPitch(const double pitch) override
Sets the pitch for speech synthesis.
yarp::dev::ReturnValue setVoice(const std::string &voice_name="auto") override
Sets the voice set for speech synthesis.
bool close() override
Close the DeviceDriver.
yarp::dev::ReturnValue setLanguage(const std::string &language="auto") override
Sets the language for speech synthesis.
yarp::dev::ReturnValue synthesize(const std::string &text, yarp::sig::Sound &sound) override
Performs the speech synthesis.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
yarp::dev::ReturnValue getVoice(std::string &voice_name) override
Gets the current voice set for speech synthesis.
@ return_value_error_generic
Method was successfully executed.
A mini-server for performing network communication in the background.
@ TraceType
Definition Log.h:92
A base class for nested structures that can be searched.
Definition Searchable.h:31
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
Class for storing sounds See Audio in YARP for additional documentation on YARP audio.
Definition Sound.h:25
void clear()
set all the samples to zero (silence)
Definition Sound.cpp:315
#define yCInfo(component,...)
#define yCError(component,...)
#define yCWarning(component,...)
#define YARP_LOG_COMPONENT(name,...)
For streams capable of holding different kinds of content, check what they actually have.
An interface to the operating system, including Port based communication.
bool read_bytestream(Sound &data, const char *filename, size_t streamsize, std::string format)
Read a sound from a byte array.
Definition SoundFile.cpp:56