YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
FakePythonSpeechTranscription.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2023-2023 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
7
8#include <yarp/os/Log.h>
9#include <yarp/os/LogStream.h>
11
12#include <cstdio>
13#include <cstdlib>
14
15using namespace yarp::os;
16using namespace yarp::dev;
17
18namespace {
19YARP_LOG_COMPONENT(FAKE_SPEECHTR, "yarp.device.fakePythonSpeechTranscription")
20}
21
26
28{
29 // Clear references for each PyObject
30 if (m_classInstance!=NULL)
31 {
32 for (long int i = 0; i < m_classInstance->ob_refcnt; ++i)
33 {
34 Py_XDECREF(m_classInstance);
35 }
36 }
37
39}
40
42{
43 std::string func_name = "open";
44
45 m_moduleName = config.check("moduleName", yarp::os::Value("Module")).asString();
46 m_path = config.find("modulePath").asString();
47 m_className = config.check("className", yarp::os::Value("SpeechTranscriptor")).asString();
48
49 //Simple Function Calling without passing any parameters
50
51 PyObject *pArgs = NULL, //Interpreted name of the Arguments
52 *pValue; //Interpreted return value from function call
53
54 // Initialize the Python Interpreter
55 if (!Py_IsInitialized())
56 {
57 yInfo() << "Calling Py_Initialize from open()";
59 }
60
61 if(!functionWrapper(m_moduleName, func_name, pArgs, pValue))
62 {
63 yCError(FAKE_SPEECHTR) << "[open] Unable to call the " << func_name << " function from python \n";
64 return false;
65 }
66
67 if (pValue == NULL)
68 {
69 yCError(FAKE_SPEECHTR) << "[open] Returned null pointer from function call \n";
70 //Py_DECREF(pValue);
71 return false;
72 }
73
74 bool ret; //result from the function call on python side
75 if (!boolWrapper(pValue, ret))
76 {
77 yCError(FAKE_SPEECHTR) << "[open] Unable to convert returned PyObject to bool \n";
79 return false;
80 }
82
83 /*------------------CLASS CREATION*------------------*/
84 // This line instantiate the class in Module.py with two parameters: lang=auto and verbose=1
85 PyObject* pClassArgs = Py_BuildValue("(si)", m_language.c_str(), 1);
86
87 if (! classInstanceCreator(m_moduleName, m_className, pClassArgs, m_classInstance))
88 {
89 yCError(FAKE_SPEECHTR) << "Failed to instantiate py class \n";
91 return false;
92 }
93 // Clear not needed PyObjects
95
96 return ret;
97}
98
100{
101 std::string func_name = "close";
102
103 //Simple Function Calling without passing any parameters
104
105 PyObject *pArgs = NULL, //Interpreted name of the Arguments
106 *pValue; //Interpreted return value from function call
107
108 // Initialize the Python Interpreter
109 if (!Py_IsInitialized())
110 {
111 yInfo() << "Calling Close Py_Initialize";
113 }
114
115 if(!functionWrapper(m_moduleName, func_name, pArgs, pValue))
116 {
117 yCError(FAKE_SPEECHTR) << "[close] Unable to call the close() function from python \n";
118 return false;
119 }
120
121 if (pValue == NULL)
122 {
123 yCError(FAKE_SPEECHTR) << "[close] Returned null pointer from function call \n";
124 //Py_DECREF(pValue);
125 return false;
126 }
127
128 bool ret; //result from the function call on python side
129 if (!boolWrapper(pValue, ret))
130 {
131 yCError(FAKE_SPEECHTR) << "[close] Unable to convert returned PyObject to bool \n";
132 return false;
133 }
135
136 return ret;
137}
138
140{
141 if (!Py_IsInitialized())
142 {
143 yInfo()<<"Calling setLanguage Py_Initialize";
145 }
146
147 PyObject* pRetVal; // Return Value from the class method
148 std::string methodName = "set_language";
149 yCInfo(FAKE_SPEECHTR) << "[setLanguage] converting input: " << language.c_str();
150 PyObject* pInput = PyUnicode_FromString(language.c_str()); // string to pass to the method
151
152 yCInfo(FAKE_SPEECHTR) << "[setLanguage] calling class wrapper";
153 if(! classWrapper(m_classInstance, methodName, pInput, pRetVal))
154 {
155 yCError(FAKE_SPEECHTR) << "[setLanguage] Returned False at classWrapper \n";
156 return ReturnValue::return_code::return_value_error_generic;
157 }
158 bool result;
159
160 if (!boolWrapper(pRetVal, result))
161 {
162 yCError(FAKE_SPEECHTR) << "[setLanguage] Unable to convert returned PyObject to bool \n";
163 return ReturnValue::return_code::return_value_error_generic;
164 }
165
166 if (pInput!=NULL)
167 {
168 for (long int i = 0; i < pInput->ob_refcnt; ++i)
169 {
171 }
172 }
174 yInfo() << "Returning from setLanguage: " << result;
175
176 return ReturnValue_ok;
177}
178
180{
181 if (!Py_IsInitialized())
182 {
183 yInfo()<<"Calling getLanguage Py_Initialize";
185 }
186
187 PyObject* pRetVal; // Return Value from the class method
188 std::string methodName = "get_language";
189 PyObject* pClassMethodArgs = NULL; // no arguments passed
190
191 if(! classWrapper(m_classInstance, methodName, pClassMethodArgs, pRetVal))
192 {
193 yCError(FAKE_SPEECHTR) << "[getLanguage] Returned False at classWrapper \n";
194 return ReturnValue::return_code::return_value_error_generic;
195 }
196
197 std::string ret;
198 if (!stringWrapper(pRetVal, ret))
199 {
200 yCError(FAKE_SPEECHTR) << "[getLanguage] Unable to covert PyObject to string, Null value \n";
201 return ReturnValue::return_code::return_value_error_generic;
202 }
203
204 yInfo() << "Returning from getLanguage: " << ret;
205 language = ret;
207
208 return ReturnValue_ok;
209}
210
211yarp::dev::ReturnValue FakePythonSpeechTranscription::transcribe(const yarp::sig::Sound& sound, std::string& transcription, double& score)
212{
213 if (sound.getSamples() == 0 ||
214 sound.getChannels() == 0)
215 {
216 yCError(FAKE_SPEECHTR) << "Invalid Sound sample received";
217 transcription = "";
218 score = 0.0;
219 return ReturnValue::return_code::return_value_error_method_failed;
220 }
221
222 transcription = "hello world";
223 score = 1.0;
224 return ReturnValue_ok;
225}
226
227bool FakePythonSpeechTranscription::functionWrapper(std::string moduleName, std::string functionName, PyObject* &pArgs, PyObject* &pValue)
228{
229 if (!Py_IsInitialized())
230 {
231 yInfo()<<"Calling functionWrapper Py_Initialize";
233 }
234
235 PyObject *pName, //Interpreted name of the module
236 *pModule, //Imported py Module loaded in this object
237 *pFunc; //Interpreted name of the function
238
239 // Build the name object (of the module)
240 PyObject* sysPath = PySys_GetObject((char*)"path"); // BORROWED REFERENCE
241 PyList_Append(sysPath, (PyUnicode_FromString(m_path.c_str()))); // sets where to look for the module
242 pName = PyUnicode_DecodeFSDefault(m_moduleName.c_str()); //The string "Module" should be the name of the python file: i.e. Module.py
243
244 // Load the module object
246 // Destroy the pName object: not needed anymore
248
249 if (pModule != NULL) // Check if the Module has been found and loaded
250 {
251 // Get the function inside the module
253
254 if (pFunc && PyCallable_Check(pFunc)) // Check if the function has been found and is callable
255 {
256 // Call the function
258 // Check the return value
259 if (pValue != NULL)
260 {
261 yCInfo(FAKE_SPEECHTR) << "Returning object " << " \n";
262 // Clear memory
264 return true;
265 }
266 else
267 { // Call Failed
269 PyErr_Print();
270 yCError(FAKE_SPEECHTR) << "Call failed";
271
272 return false;
273 }
274 }
275 else
276 { // Function not found in the py module
277 if (PyErr_Occurred())
278 PyErr_Print();
279 yCError(FAKE_SPEECHTR) << "Cannot find function: " << functionName;
280 //Py_XDECREF(pFunc);
282
283 return false;
284 }
285 }
286 else
287 { // Module not found or loaded
288 PyErr_Print();
289 yCError(FAKE_SPEECHTR) << "Failed to load: " << m_moduleName;
290 return false;
291 }
292}
293
294bool FakePythonSpeechTranscription::classWrapper(PyObject* &pClassInstance, std::string methodName, PyObject* &pClassMethodArgs, PyObject* &pValue)
295{
296 if (!Py_IsInitialized())
297 {
298 yInfo()<<"Calling classWrapper Py_Initialize";
300 }
301 PyObject *pMethod; // Converted name of the class method to PyObject
302
303 yCInfo(FAKE_SPEECHTR) << "[classWrapper] converting method from str";
305
306 if (pMethod == NULL)
307 {
308 yCError(FAKE_SPEECHTR) << "[classWrapper] Unable to convert methodName to python";
309 if (PyErr_Occurred())
310 PyErr_Print();
312 return false;
313 }
314
315 yCInfo(FAKE_SPEECHTR) << "[classWrapper] class instance check";
316 if (pClassInstance==NULL)
317 {
318 yCError(FAKE_SPEECHTR) << "[classWrapper] Class instance NULL";
319 if (PyErr_Occurred())
320 PyErr_Print();
322 return false;
323 }
324
325 yCInfo(FAKE_SPEECHTR) << "[classWrapper] calling method class";
327
328 if (pValue==NULL)
329 {
330 yCError(FAKE_SPEECHTR) << "[classWrapper] Returned NULL Value from Class call";
331 if (PyErr_Occurred())
332 PyErr_Print();
334 return false;
335 }
337 return true;
338}
339
340bool FakePythonSpeechTranscription::classInstanceCreator(std::string moduleName, std::string className, PyObject* &pClassArgs, PyObject* &pReturn)
341{
342 if (!Py_IsInitialized())
343 {
344 yInfo()<<"Calling classWrapper Py_Initialize";
346 }
347 PyObject *pName, // Interpreted name of the module
348 *pModule, // Imported py Module loaded in this object
349 *pClass, // Interpreted name of the class
350 *pDict; // Dictionary of the interpreter
351
352 // Build the name object (of the module)
353 PyObject* sysPath = PySys_GetObject((char*)"path"); // BORROWED REFERENCE
354 PyList_Append(sysPath, (PyUnicode_FromString(m_path.c_str()))); // sets where to look for the module
355 pName = PyUnicode_DecodeFSDefault(m_moduleName.c_str()); //The string "Module" should be the name of the python file: i.e. Module.py
356
357 // Load the module object
359 // Destroy the pName object: not needed anymore
361
362 if (pModule==NULL)
363 {
364 if (PyErr_Occurred())
365 PyErr_Print();
366 yCError(FAKE_SPEECHTR) << "[classWrapper] Unable to create module instance \n";
367 return false;
368 }
370
371 // pDict is a borrowed reference
373 // Build the name of a callable class -> borrowed reference
374 pClass = PyDict_GetItemString(pDict, className.c_str());
375
377 {
378 //Create instance of the class
380
381 if (pReturn==NULL)
382 {
383 if (PyErr_Occurred())
384 PyErr_Print();
385 yCError(FAKE_SPEECHTR) << "[classWrapper] Unable to instantiate Class with given class arguments \n";
386
387 if (pReturn->ob_refcnt>0)
388 {
390 }
391 return false;
392 }
393
394 return true;
395 }
396 else
397 {
398 if (PyErr_Occurred())
399 PyErr_Print();
400 yCError(FAKE_SPEECHTR) << "[classWrapper] Unable to find class in py module \n";
401 return false;
402 }
403}
404
405bool FakePythonSpeechTranscription::stringWrapper(PyObject* &pValue, std::string &ret)
406{
407 if (pValue!=NULL)
408 {
409 ret = std::string(PyUnicode_AsUTF8(pValue));
410 return true;
411 }
412 else
413 {
414 yCError(FAKE_SPEECHTR) << "Null pValue passed to FakePythonSpeechTranscription::stringWrapper \n";
415 return false;
416 }
417}
418
419bool FakePythonSpeechTranscription::intWrapper(PyObject* &pValue, long &ret)
420{
421 if (pValue!=NULL)
422 {
424 return true;
425 }
426 else
427 {
428 yCError(FAKE_SPEECHTR) << "Null pValue passed to FakePythonSpeechTranscription::intWrapper \n";
429 return false;
430 }
431}
432
433bool FakePythonSpeechTranscription::doubleWrapper(PyObject* &pValue, double &ret)
434{
435 if (pValue!=NULL)
436 {
438 return true;
439 }
440 else
441 {
442 yCError(FAKE_SPEECHTR) << "Null pValue passed to FakePythonSpeechTranscription::doubleWrapper \n";
443 return false;
444 }
445}
446
447bool FakePythonSpeechTranscription::boolWrapper(PyObject* &pValue, bool &ret)
448{
449 if (pValue!=NULL)
450 {
452 return true;
453 }
454 else
455 {
456 yCError(FAKE_SPEECHTR) << "Null pValue passed to FakePythonSpeechTranscription::boolWrapper \n";
457 return false;
458 }
459}
bool ret
#define yInfo(...)
Definition Log.h:319
#define ReturnValue_ok
Definition ReturnValue.h:77
virtual yarp::dev::ReturnValue transcribe(const yarp::sig::Sound &sound, std::string &transcription, double &score) override
Performs the speech transcription.
bool close() override
Close the DeviceDriver.
virtual yarp::dev::ReturnValue getLanguage(std::string &language) override
Gets the current language set for speech transcription.
virtual yarp::dev::ReturnValue setLanguage(const std::string &language) override
Sets the language for speech transcription.
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
A mini-server for performing network communication in the background.
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.
A single value (typically within a Bottle).
Definition Value.h:43
Class for storing sounds See Audio in YARP for additional documentation on YARP audio.
Definition Sound.h:25
size_t getChannels() const
Get the number of channels of the sound.
Definition Sound.cpp:603
size_t getSamples() const
Get the number of samples contained in the sound.
Definition Sound.cpp:598
#define yCInfo(component,...)
#define yCError(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.