Setting espeak_SetSynthCallback to member function in C++ - c++

My application makes heavy use of text-to-speech (through libespeak). It is written in C++/Qt5 with a QML-based frontend.
I have no formal C++ training (I have a Java background though) and as such I'm not entirely sure how to properly implement some of the more esoteric features.
libespeak supports a callback feature, which is called every time speech is synthesized.
The callback function takes three arguments, which I would like to use to visualize the speech. The code below works in the sense that the callback function is called correctly, but not useful since I can't access other member functions or variables.
itemvoice.h
#include "espeak/speak_lib.h"
int callback(short *wav, int numsamples, espeak_EVENT *events);
class ItemVoice : public Item
{
public:
explicit ItemVoice(QQuickItem *parent = 0);
};
itemvoice.cpp
#include "itemvoice.h"
extern int callback(short *wav, int numsamples, espeak_EVENT *events)
{
// do stuff
}
ItemVoice::ItemVoice(QQuickItem *parent):Item(parent)
{
espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,500,NULL,0);
espeak_SetSynthCallback(callback);
}
I would like to make the callback function a member of the ItemVoice class. However if I try (and set the callback function with espeak_SetSynthCallback(ItemVoice::callback), the code won't compile anymore because of arguments which cannot be converted.
UPDATE: The suggestion below works. However, I have now run into another problem.
This is what the class looks like now:
itemvoice.h
#include "espeak/speak_lib.h"
int staticCallback(short *wav, int numsamples, espeak_EVENT *events);
class ItemVoice : public Item
{
Q_OBJECT
public:
explicit ItemVoice(QQuickItem *parent = 0);
void startSpeaking();
void stopSpeaking();
signals:
void updateGUI();
}
itemvoice.cpp
#include "itemvoice.h"
ItemVoice::ItemVoice(QQuickItem *parent):Item(parent)
{
espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,500,NULL,0);
espeak_SetSynthCallback(staticCallback);
}
int staticCallback(short *wav, int numsamples, espeak_EVENT *events)
{
espeak_EVENT_TYPE type=events->type;
if(type==2) // start sentence
(static_cast<ItemVoice*>(events[0].user_data))->startSpeaking();
else if(type==6) // stop sentence
(static_cast<ItemVoice*>(events[0].user_data))->stopSpeaking();
}
void ItemVoice::startSpeaking()
{
//do stuff
updateGUI();
}
void ItemVoice::stopSpeaking()
{
// do stuff
updateGUI();
}
This works correctly. startSpeaking() is called when synthesis begins, and stopSpeaking() when it stops. The problem is that I need to send a Qt signal to update the GUI (updateGUI), and about a second after it's sent, my application crashes with a segmentation fault, even if the signal is not connected anywhere. It works perfectly otherwise.
Any idea?
Thanks for reading!

There is no direct way to do what you want. In your case you are lucky because there is void* user_data field in espeak_EVENT. You can set it to this when you call espeak_Synth():
void ItemVoice::synthSpeech() {
espeak_Synth(...., this);
}
So in the callback (which is still a global function, or a static function in ItemVoice) you can do roughly this:
int staticCallback(short *wav, int numsamples, espeak_EVENT *events) {
if (numsamples > 0)
return (static_cast<ItemVoice*>(events[0].user_data))->nonStaticCallback(wav, numsamples, events);
}

Related

Anonymous inner class in C++ (Java-style listener)

My C/C++ skills are a bit rusty, and I've mostly been working in Java for the past few years. Now I just started playing around with Arduino, and made a simple button class. I want to add an event listener, so I did something like this:
class MyButton{
public:
MyButton(byte pin);
bool isPressed();
bool wasToggled();
bool wasPressed();
void eventLoop();
inline void setListener(MyButtonListener* listener) { _listener = listener; }
private:
byte _pin;
boolean _lastToggledState = false;
MyButtonListener* _listener;
};
class MyButtonListener{
public:
virtual void onPressed() = 0;
private:
};
The eventLoop() method (which is intended to be called from the Arduino loop() function ), invokes the onPressed() method in the listener class:
void MyButton::eventLoop(){
if( wasPressed() && _listener ){
_listener->onPressed();
}
}
So far, things are okay. But I can't figure out how to actually assign and use the listener in the main Arduino file. Coming from Java, I'm used to just doing something like
myBtn.setListener( new MyButtonListener(){
void onPressed(){
Serial.println("Pressed");
toggleLed(); // toggleLed() is a method in the main Arduino file
}
});
I got it to work in a very convoluted way, by declaring a new class which takes the toggleLed() method as an argument (because it can't be accessed from within the new class otherwise):
class BtnListener : public MyButtonListener{
public:
BtnListener(void* toggleFunction) : _toggleFunction(toggleFunction){ };
private:
void (*_toggleFunction)();
void onPressed(){
Serial.println("Pressed");
_toggleFunction();
};
};
myBtn.setListener( new BtnListener(toggleLed) );
Surely there must be a more convenient way of doing something like this in C++? It's doable (but ugly) with one listener - I can't even imagine the horror of having 10 buttons which all need different listener implementations...
In your case, one or the simplest methods would be to store the listener as a std::function<void()> and don't have an actual class to model the buttonlistener at all (you can still have that if you really want to encapsulate that, but it's not neccesary). Then use a lambda function to the setListener call, something like this:
myBtn.setListener( [this]{
Serial.println("Pressed");
toggleLed(); // toggleLed() is a method in the main Arduino file
});
Since the Arduino IDE by default doesn't seem to include <functional.h>, I wasn't able to use the answer using std::function<void()>. However, after some experimenting I realized there was an easier way, which also has the benefit of being able to model the listener.
The listener class simply contains function pointers to each listener callback function, and a constructor that takes an argument for each callback. Then it's very convenient to just create a new instance of the listener class and pass each callback as a lambda.
class MyButton{
public:
inline void setListener(MyButtonListener* listener) { _listener = listener; }
private:
MyButtonListener* _listener;
}
class MyButtonListener{
public:
MyButtonListener(void* onPressed, void* onToggled) : onPressed(onPressed), onToggled(onToggled) {};
void (*onPressed)();
void (*onToggled)();
};
void MyButton::eventLoop(){
if( _listener ){
if( wasPressed() ){
_listener->onPressed();
}
if( wasToggled() ){
_listener->onToggled();
}
}
}
myBtn.setListener(
new MyButtonListener(
// onPressed
[](){
Serial.println("Pressed");
toggleLed();
},
// onToggled
[](){
Serial.println("Toggled");
}
)
);
Not sure if there are any drawbacks with this solution, but it works, is readable and is fit for use on Arduino.

C++ Object Oriented Design frustration.

After working within a group project to build pretty much a copy of IRC, and manning the GUI battle station, I realise I have written code for much more than the GUI (user commands, font commands, chat filter, etc).
This being my first attempt at OOP at all, i am now stuck with a huge GUI class which i would love to split into smaller classes.
However, now I am faced with a situation like the following:
Class A {
public:
int printStuff();
int doThings();
}
A::printStuff() {
return doThings;
}
A::doThings() {
return 2;
}
A situation where the classes still need to interact.
Keep in mind, the class system is a lot more complex than this, and there are interactions between all 5 of my proposed subclasses.
but class A should only be printing things, not doing things; as such, i would love to have it like this:
Class A {
public:
int printStuff();
}
Class B {
public:
int doThings();
}
What are the best/most elegant ways to go about doing so?
Heres the actual chunk from the header, if it helps; I've commented in the functions/variables each method requires- and also outlined my proposed subclasses:
// ncurses (GUI, screens)
void setup(); // initScreen(); initWindows();
void initScreen(); // ncurses.h
void initWindows(); // screen vars, ncruses.h, dummy text
void resize(); // screen vars, ncruses.h, showScreen();
void Routine();
// message factory (GUI, controll, vars)
string mRequested(); // _messageQueue
void mRecieved(string message); // command(), printchat(), _chatlog, _user
bool command(string message, int out_in); // _user, _messageQueue, mRecieved -- quit(not made), removeUser
int checkVulgar(string *message); // _user
string upperCase(string message);
// GUI (windows, vars)
void printAscii(WINDOW *scr, char *gaphics[], int sizey, int sizex, int starty, int startx); // ncurses.h, windows
void printServers(WINDOW *scr, int a); // ncurses.h, windows
void printMessage(string message, int message_lines, int *h_index, int *attempt, int *message_len, int prev_len, int endline); // ncurses.h, windows
void printUsers(WINDOW *scr); // _users, ncurses.h, windows
void printTimeout();
void printChat(); // printMessage(), fontcommands, _chatlog, ncurses.h, windows //
void showScreen(int a, int b); // printAscii,servers,users,chat , ncurses.h, windows
// control (GUI, _users)
void updateUsers(vector<User> users); // _users, printUsers();
void removeUser(string user); // _users, printUsers();
// Boundary (ncurses, GUI, messageFactory, vars)
void userInput();
void userInputB(); // _user, resize(), printchat(), mRecieved(), checkvulgar(), quit(), command(), _messageQueue
int selectServer(); // showScreen()
What are the best/most elegant ways to go about doing so?
Sit down on a sofa for a few days and come up with a robust and elegant design.
Then implement that design.
The mistake you made was not designing before you began coding. Now it's already time to refactor.
Figure out what classes should do what, try and make some CRC cards. They are a great help to figure out what the class diagram should look like.
After reworking the class design and starting from scratch, I've managed to separate and reuse most of my earlier code.
For anyone wondering, the mainApp now talks directly to the MessageFactory; MF contains an object of both GUI and Windows (ncurses in previous image).
This is really how it should have been from the beginning, and poor planning (due to not knowing anything about command line GUI, and the excitement of adding new features) has caused me a great deal of grief.
Plan properly, or suffer.

How to make a constant or variable accessible in entire program

I would like to have access to constant/variable of desktop width and height in entire program.
This is how I do it - add this code to every .h file of my program and then use it normally.
#include <QDesktopWidget>
QDesktopWidget desktop;
int desktopHeight = desktop.geometry().height();
int desktopWidth = desktop.geometry().width();
I know it is not a good way how to do it. I tried to make one special desktopSize.h and then include to required parts of my program. But I was not successful.
What should be in header file like this one which I need?
You really do not want to use that particular approach and include that code in all translation units. If you did each one would include two variables named desktopWidth and desktopHeight causing duplicate symbol errors during link time. It will also make it difficult to manage updating them if the size of the desktop changes after the application starts. If you really want to provide global variables holding the size of the desktop you should place them in a single .cpp file and place extern declarations in a single header file that is included when needed.
Header file (GlobalDesktopInfo.h)
#ifndef GLOBALDESKTOPINFO_H
#define GLOBALDESKTOPINFO_H
extern int desktopHeight;
extern int desktopWidth;
#endif GLOBALDESKTOPINFO_H
Source file (GlobalDesktopInfo.cpp)
#include "GlobalDesktopInfo.h"
int desktopHeight = 0;
int desktopWidth = 0;
You will also need to initialize it at the earlier point reasonably possible. I suggest doing this in your main() function.
#include "GlobalDesktopInfo.h"
// other includes
int main()
{
QApplication app;
QDesktopWidget desktop;
desktopHeight = desktop.geometry().height();
desktopWidth = desktop.geometry().width();
// other code and initialization
}
I think it's better to have some slots in a class which return the desired values and use Qt's Signal/slot mechanism to access them from other classes.
Just make a signal in the target class, connect it to a slot in the class containing the slots and make a connection between two objects of the classes. This way you can access them in every class you like by connecting a signal to a slot returning that value and just emitting the signal and getting the returned value.
For example you can have a class like :
class DesktopInformation
{
Q_OBJECT
public:
DesktopInformation(QObject *parent = 0);
~DesktopInformation();
QDesktopWidget desktop;
public slots:
int getWidth()
{
return desktop.geometry().width();
}
int getHeight()
{
return desktop.geometry().height();
}
};
And access the desktop information from any other class like :
class SomeClass: public QObject
{
Q_OBJECT
public:
SomeClass(QObject *parent = 0);
~SomeClass();
signals:
int getWidth();
int getHeight();
private:
void someFunction()
{
int width = getWidth();
int heigth = getHeight();
...
}
};
And connect the signal from an object of SomeClass to the slot in an object of DesktopInformation :
connect(someClass, SIGNAL(getWidth()), desktopInformation, SLOT(getWidth()));
In class someClass you can access the value returned from getWidth slot in desktopInformation by just calling the signal and using the returned value.
Note that the two objects should be in the same thread for this to work. If they are in different threads then the connection type should be of type Qt::BlockingQueuedConnection :
connect(someClass, SIGNAL(getWidth()), desktopInformation, SLOT(getWidth()), Qt::BlockingQueuedConnection);
Another way is two use static member functions but it is not recommended unless you have a good reason to do it :
class desktopInformation {
public:
static QDesktopWidget desktop;
static int getWidth()
{
return desktop.geometry().width();
}
static int getHeight()
{
return desktop.geometry().height();
}
};
class someClass {
public:
void do_something();
};
You can access desktopInformation's static member function from someClass like this:
void someClass::do_something()
{
int width = A::getWidth();
...
};

C delegate to C++

I have a small problem using a library that gets images from a CMOS camera.
The library permits to use a stream functionality and I have three access point to set (three delegates) for when I get an image, when an image is dropped and when there is an error.
typedef void(* StreamCallbackPtr)( IMAGE *image );
typedef void(* StreamErrorCallbackPtr)();
typedef void(* StreamFrameDroppedCallbackPtr)();
int Stream_Start( DEVICE device, IMAGEFORMAT format, StreamCallbackPtr stream_callback, StreamFrameDroppedCallbackPtr f_dropped_callback, StreamErrorCallbackPtr error_callback );
I enter a StreamCallbackPtr as soon as an image is ready on the camera, but keep in mind that I do not have any ways of changing the library code.
And here is the question: How do I plug my own delegate in C++ ?
Lets say I use this stream functionality inside a class, I know that I have at least two options; the wrapper, and global variables. The first one seems compromised since I cannot pass anything else than an IMAGE, and I want to avoid using global variables (it would be static members in this case).
Any ideas ?
You could use a static member function as the StreamCallbackPtr which then can access a private static reference or list of references to the C++ delegates which wish to receive the message.
That way you have hidden most of the details as private to the class.
The code below is pseudo-C++ (I haven't checked it properly) but it should give you the idea of what I am suggesting.
class Delegate
{
protected:
void Callback( IMAGE *image ) = 0;
void Error() = 0;
void FrameDropped() = 0;
public:
static void SetDelegate(Delegate* d) { delegateInstance = d; }
static void StaticCallback( IMAGE *image)
{
// Invoke the delegate instance
if (delegateInstance != nullptr) delegateInstance->Callback();
}
// Same for the others...
private:
static Delegate* delegateInstance = nullptr;
};
class MyClass : public Delegate
{
protected:
void Callback( IMAGE *image )
{
// Now the callback is in a delegate instance
}
};
int main(void)
{
MyClass mc;
Delegate::SetDelegate(&mc);
StreamCallbackPtr scp = &Delegate::StaticCallback;
// Register the other static callbacks...
return 0;
}

OpenCV 2.3 with VS 2008 - Mouse Events

Obligatory - I'm a newbie. Have a job that involves programming and I'm teaching myself as I go. Needless to say as a teacher I get things wrong frequently and thoroughly.
Where I'm at right now: I've created the class "Graph", it (surprisingly enough) makes graphs. But now I want to make it so that on a mouse click I modify the graph. But I can't seem to get a mouse handler to be a member function of the class.
cv::setMouseCallback(windowName, onMouse, 0); // Set mouse handler to be onMouse
Doesn't work with
cv::setMouseCallback(windowName, Graph::onMouse, 0);
It gives me lack of parameter errors. According to this I can't make it a member function. After following the answer given, it compiles but my this pointer is nulled. Ugh.
OnMouse looks like this:
void onMouse(int event, int x, int y,int, void*)
{
if (event == CV_EVENT_LBUTTONDOWN)
{
cvMoveWindow("Window", 500, 500); //Just to see if stuff happened
}
return;
}
I don't care about moving the window, I want to modify the graph itself - which is stored as a cv::Mat variable in a Graph object. And I can't figure out how to do it.
Any help would be appreciated, and I really hope this wasn't just gibberish.
Yes callback functions in C++ are a joy, aren't they? You actually have to give OpenCV a function (not a class method) as you've already found out. However, you can hack around this awfulness using the following technique:
class MyClass
{
public:
void realOnMouse(int event, int x, int y, int flags)
{
// Do your real processing here, "this" works fine.
}
};
// This is a function, not a class method
void wrappedOnMouse(int event, int x, int y, int flags, void* ptr)
{
MyClass* mcPtr = (MyClass*)ptr;
if(mcPtr != NULL)
mcPtr->realOnMouse(event, x, y, flags);
}
int main(int argv, char** argc)
{
// OpenCV setup stuff...
MyClass processor;
cv::setMouseCallback(windowName, wrappedOnMouse, (void*)&processor);
// Main program logic
return 0;
}
That last parameter on setMouseCallback is quite useful for overcoming some of the problems you usually encounter like this.
You can also use the onMouse method as a static method.
class Graph
{
public:
static void onMouse(int event, int x, int y, void* param)
{
//Your code here
}
//Everything else you may need
}
Now you should be able to call the onMouse method with:
cv::setMouseCallback(windowName, onMouse, (void*) param);
The param can be NULL or whatever you want to pass as parameter to the method, but you'll need to make a type-cast to the desired type.
Hope this was useful.
Bye.