How to use RHVoice Text To Speech C/C++ library - c++

I'm using rhvoice library in a qt c++ project, and I'm struggling to make it work and speak.
So far i have managed to load voices and voice profiles to a tts_engine, but no sound plays even tho the speak function gives no error.
So I'm wondering if someone could give me an example on how to initialize a tts engine and use it to speak strings, or any help on how to use this library, because the documentation wasn't enough for me to figure it out.
One thing i noticed is that RHVoice_callbacks causes my application to crash even if i just initialize it without using it.
Code:
The function that will implement the library:
short samples[]={140,139,145};
//initialize callbacks
/*RHVoice_callbacks *callbacks;
callbacks->set_sample_rate(24000,NULL);
callbacks->play_speech(samples,3,NULL);
callbacks->process_mark=NULL;
callbacks->word_starts=NULL;
callbacks->word_ends=NULL;
callbacks->sentence_starts=NULL;
callbacks->sentence_ends=NULL;
callbacks->play_audio=NULL;
callbacks->done=NULL;*/
RHVoice_init_params init_params;
char config[]="RHVoice.conf";
char one[]="RHVoice/languages/English/";
char two[]="RHVoice/voices/alan";
//initialize init_params
const char *array[] = {config,two,one,NULL};
init_params.resource_paths=array;
init_params.options=RHVoice_preload_voices;
//assisgn callbacks to init_params
/*init_params.callbacks.set_sample_rate(24000,NULL);
init_params.callbacks.play_speech(samples,3,NULL);
init_params.callbacks.process_mark=NULL;
init_params.callbacks.word_starts=NULL;
init_params.callbacks.word_ends=NULL;
init_params.callbacks.sentence_starts=NULL;
init_params.callbacks.sentence_ends=NULL;
init_params.callbacks.play_audio=NULL;
init_params.callbacks.done=NULL;*/
//initialize a tts_engine
RHVoice_tts_engine ttsengine=RHVoice_new_tts_engine(&init_params);
//debug
QVariant voiceprofnum = RHVoice_get_number_of_voice_profiles(ttsengine);
QVariant voiceprof = RHVoice_get_voices(ttsengine)->name;
QVariant voice = RHVoice_get_number_of_voices(ttsengine);
entrance->debug->setText(voiceprofnum.toString()+","+voiceprof.toString()+","+voice.toString());
//
//initialize synth_params without the voice profile because it causes a crash
RHVoice_synth_params synth;
synth.flags=0;
synth.capitals_mode=RHVoice_capitals_default;
synth.punctuation_mode=RHVoice_punctuation_default;
synth.relative_pitch=1;
synth.relative_volume=1;
synth.relative_rate=1;
synth.absolute_pitch=0;
synth.absolute_volume=1;
synth.absolute_rate=0;
//synth.voice_profile="Alan+Aleksandr";
//
//initialize RHVoice_message which will hold the string i want spoken
RHVoice_message userinput=RHVoice_new_message(ttsengine,"test",4,RHVoice_message_text,&synth,NULL);
RHVoice_speak(userinput);
RHVoice.h
#ifndef RHVOICE_H
#define RHVOICE_H
#include "RHVoice_common.h"
#ifdef __cplusplus
extern "C" {
#else
#include <stddef.h>
#endif
struct RHVoice_tts_engine_struct;
typedef struct RHVoice_tts_engine_struct* RHVoice_tts_engine;
typedef struct
{
/* These are the functions the caller is *required* to provide. */
/* This function will be called first. It will be called again if the sampling rate changes. Return 0 to signal an error. */
int (*set_sample_rate)(int sample_rate,void* user_data);
/* Return 0 to stop synthesis. */
int (*play_speech)(const short* samples,unsigned int count,void* user_data);
/* These functions are optional, */
/* but please make sure to set unused function pointers to 0. */
int (*process_mark)(const char* name,void* user_data);
int (*word_starts)(unsigned int position,unsigned int length,void* user_data);
int (*word_ends)(unsigned int position,unsigned int length,void* user_data);
int (*sentence_starts)(unsigned int position,unsigned int length,void* user_data);
int (*sentence_ends)(unsigned int position,unsigned int length,void* user_data);
int(*play_audio)(const char* src,void *user_data);
void (*done)(void* user_data);
} RHVoice_callbacks;
typedef enum {
RHVoice_preload_voices=1
} RHVoice_init_option;
typedef unsigned int RHVoice_init_options;
typedef struct
{
/* The paths should be encoded as utf-8 strings. */
const char *data_path,*config_path;
/* A list of paths to language and voice data. */
/* It should be used when it is not possible to collect all the data in one place. */
/* The last item in the array should be NULL. */
const char** resource_paths;
RHVoice_callbacks callbacks;
RHVoice_init_options options;
} RHVoice_init_params;
typedef enum {
RHVoice_message_text,
RHVoice_message_ssml,
RHVoice_message_characters,
RHVoice_message_key
} RHVoice_message_type;
struct RHVoice_message_struct;
typedef struct RHVoice_message_struct* RHVoice_message;
typedef struct
{
/* Language code. */
const char* language;
const char* name;
RHVoice_voice_gender gender;
/* Country code. */
const char* country;
} RHVoice_voice_info;
typedef struct
{
/* One of the predefined voice profiles or a custom one, e.g. */
/* Aleksandr+Alan. Voice names should be ordered according to their */
/* priority, but they must not speak the same language. If the */
/* combination includes more than one voice, automatic language */
/* switching may be used. The voice which speaks the primary language */
/* should be placed first. RHVoice will use one of the other voices */
/* from the list, if it detects the corresponding language. The */
/* detection algorithm is not very smart at the moment. It will not */
/* handle languages with common letters. For example, if you set this */
/* field to "CLB+Spomenka", it will always choose CLB for latin */
/* letters. Spomenka might still be used, if Esperanto is requested */
/* through SSML. */
const char* voice_profile;
/* The values must be between -1 and 1. */
/* They are normalized this way, because users can set different */
/* parameters for different voices in the configuration file. */
double absolute_rate,absolute_pitch,absolute_volume;
/* Relative values, in case someone needs them. */
/* If you don't, just set each of them to 1. */
double relative_rate,relative_pitch,relative_volume;
/* Set to RHVoice_punctuation_default to allow the synthesizer to decide */
RHVoice_punctuation_mode punctuation_mode;
/* Optional */
const char* punctuation_list;
/* This mode only applies to reading by characters. */
/* If your program doesn't support this setting, set to RHVoice_capitals_default. */
RHVoice_capitals_mode capitals_mode;
/* Set to 0 for defaults. */
int flags;
} RHVoice_synth_params;
const char* RHVoice_get_version();
RHVoice_tts_engine RHVoice_new_tts_engine(const RHVoice_init_params* init_params);
void RHVoice_delete_tts_engine(RHVoice_tts_engine tts_engine);
unsigned int RHVoice_get_number_of_voices(RHVoice_tts_engine tts_engine);
const RHVoice_voice_info* RHVoice_get_voices(RHVoice_tts_engine tts_engine);
unsigned int RHVoice_get_number_of_voice_profiles(RHVoice_tts_engine tts_engine);
char const * const * RHVoice_get_voice_profiles(RHVoice_tts_engine tts_engine);
int RHVoice_are_languages_compatible(RHVoice_tts_engine tts_engine,const char* language1,const char* language2);
/* Text should be a valid utf-8 string */
RHVoice_message RHVoice_new_message(RHVoice_tts_engine tts_engine,const char* text,unsigned int length,RHVoice_message_type message_type,const RHVoice_synth_params* synth_params,void* user_data);
/* On Windows the library is now built with MSVC instead of Mingw, */
/* so wchar_t will always mean utf-16 there */
RHVoice_message RHVoice_new_message_w(RHVoice_tts_engine tts_engine,const wchar_t* text,unsigned int length,RHVoice_message_type message_type,const RHVoice_synth_params* synth_params,void* user_data);
void RHVoice_delete_message(RHVoice_message message);
int RHVoice_speak(RHVoice_message message);
#ifdef __cplusplus
}
#endif
#endif
I tried setting the synth parameter in new_rhvoice_message function to null but it had no effect.
the voice profile attribute in synth parameters causes the application to crash as well.
Update:
I was told to use rhvoice via speech-dispatcher, and avoid using it directly.
I couldn't figure out how to do that, I have this package installed (rhvoice-speech-dispatcher-plugin.x86_64) on fedora. As far as i know, it doesn't provide any library that I can work with in my project, i can only use it from command line in a terminal.
I'm mentioning this in case it might help someone get closer to figuring this out.
Thank you for your time and help!

Related

How to register callback with variadic arguments and pass a value

could you please help in following.
I have callback function definition in the 3rd lib header:
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*SOCK_CLBK)(int, short, unsigned char*, int, ...);
#ifdef __cplusplus
}
#endif
And I define my callback in the following way:
header file:
template<typename T>
int ReadTCP(int socket, short code, unsigned char* msg, int received, T a);
cpp file:
template<>
int ReadTCP(int socket, short code, unsigned char* msg, int received, int a)
{
return 0;
}
and register my callback in the code:
server->registerCallback(port, (SOCK_CLBK)(ReadTCP<int>),maxTCPsize);
This works fine, and the callback is triggered when needed.
The problem is, the "int a" contains random values every time.
how to register a callback and pass my own specific value for example 100000, that will occur in the callback in "a"?
Something like
server->registerCallback(port, (SOCK_CLBK)(&std::bind(ReadTCP<int>,_1,_2,_3,_4, 100000),maxTCPsize);
but this does not work (triggers runtime exception).
What I am doing wrong?
lib header:
#include "CSocket.h"
#ifndef WIN32
#include <pthread.h>
#else
#include <windows.h>
#include <WinSock.h>
#endif
#define CPP_TCP_MAX_CLIENTS 17
#define CPP_TCP_MAX_SIZE 1500 //In accordance with MTU definitoins
class DLLCPP_API CSERVER {
public:
/**
* default constructor
*/
CSERVER ();
/**
* default destructor
*/
virtual ~CSERVER ();
/**! \fn int Create(unsigned int uiPort, bool bClbk);
* \brief creates singleton socket listener
* creates singleton socket listener, which is invoked within dedicated thread
* if bClbk is true, otherwise within the main thread.
* \param uiPort socket listener port
* \param fnClbk call-back function address. if not NULL then callback mode of operation. otherwise normal.
* \return 0 on success, error id otherwise.
*/
int registerCallback(unsigned int uiPort, SOCK_CLBK fnClbk=NULL, int iMsgMaxSize=512)throw (CMException);
….
…
Send()…
….
...
protected:
#ifndef WIN32
friend void* _fnTCPClbkThread(void *); //call-back argument for pthread_create within RunClbkThread.
#else
friend DWORD WINAPI _fnTCPClbkThread( LPVOID lpParam );
#endif
/**! \fn int IsPending(int iSock, bool& bFail)
* \brief check pending connection on a non blocking socket
* actuall checks for errors and whether or not connection is ready for write operation.
* \param iSock client socket connection to check.
* \return: OK (0) if iSock ready for write operation or ERROR otherwise (still pending for instance)
*/
int IsPending(int iSock)throw (CMException);
int RunClbkThread();
int CreateClbk()throw (CMException);
void ClbkThread();
private:
typedef void (CSERVER::*PCLBKTHREAD)(void *);
PCLBKTHREAD _pThreadClbk;
int _iServerSock;
int _iSock;
SOCK_CLBK _fnClbk;
unsigned int _uiPort;
int _iAddrLen;
bool _bClbkThreadAlive;
int _iClientConnectionsArr[CPP_TCP_MAX_CLIENTS];
int _iMsgMaxSize;
struct sockaddr_in _saddConnect ;
#ifdef WIN32
WSADATA m_wsaData;
HANDLE _thread;
#else
pthread_t _thread;
#endif
};
Look at function registerCallback
From which I can deduct that the class does not store any user data to be passed later as a callback parameter... Why do they have variadic template then - no idea.
First, your code with ReadTCP function template is incorrect. SOCK_CLBK is a type of a function pointer that has an ellipsis at the end of its argument list, which is different from int (or any other type) that ReadTCP<int> has. The compiler does not fail to compile because you explicitly convert the pointer to ReadTCP<int> to SOCK_CLBK, but the call fails at runtime (you either receive a random value in the int a argument or crash).
Your second piece of code with std::bind is also wrong because std::bind returns a function object, not a pointer to function. The function object has operator(), so it can be called like a function, but it cannot be converted to a function pointer (for one, because the object also contains data, like the arguments you bound).
You must define a function that accepts a variable number of arguments (i.e. has an ellipsis at the end of its argument list) and pass that function as the callback. In that function, you can process the passed arguments and possibly invoke other specialized functions in your code, like ReadTCP.
int ReadTCPCallback(int socket, short code, unsigned char* msg, int received, ...)
{
std::va_list args;
va_start(args, received);
// Use variable arguments here, using va_arg. Consult with the API
// documentation to know what arguments are expected here. For the sake
// of this example, let's assume an int argument is passed.
int n = va_arg(args, int);
int res = ReadTCP(socket, code, msg, received, n);
// Always call va_end before returning once you're done with va_list
va_end(args);
return res;
}
If you want to use function objects with this API then you will have to find a way to pass a pointer to data through the third party library to the callback. That data will contain the bound parameters and other state pertinent to the call. Refer to the documentation of that third party library as to how to pass user's data to the callback.
If the API does not support passing user's data (which would make it a rather poorly designed API), you could associate the data with some handle returned by the API that corresponds to your state. For example, you could maintain a global std::map to map the socket file descriptor (int) to a pointer to your data related to that socket or connection.

Access to ptr to array of node handle c++

I have this structure:
typedef struct edagroup
{
UINT16 nodes; /* # slots - may not all be in use */
EHANDLE *eh; /* ptr to array of node handles */
} *GNUM;
And this:
typedef struct ehandle
{
UINT32 is_tag256; /* Is the remote node 256 character? */
UINT32 is_tag30 ; /* Is the remote node 30 character? */
}*EHANDLE;
And this method:
GNUM sample_call(UINT16 n_nodes, INT16 detect_changes);
We call to this method that returns a GNUM struture and I want to access to is_tag256 property.
Sample:
GNUM FixGroupInit = sample_call(1, 0);
EHANDLE *eh = FixGroupInit->eh;
...
Somebody can help me?
There is not enough information to tell us where the array comes in (and there is an ambiguity in the code comments -- the author of that API ought to be beaten with a stick) but you can try this:
(**(FixGroupInit->eh)).is_tag256

Can we create a C++ string object from char pointer where the operations on the string object reflects to the source char pointer?

I've been trying to use C++ string class rich methods (find_first_of, replace) for some string processing for a task.
And i created a wrapper file around the above mentioned code, where it can be included in 'C' source files and get the functionality.
strUtils.h
#ifdef __cplusplus
extern "C" {
#endif
void doTheStringWork(char *inStr, unsigned beginLoc);
#ifdef __cplusplus
}
#endif
strUtils.cpp
#include "strUtils.h"
/*some standard includes here*/
void doTheStringWork(char *inStr, unsigned beginLoc) {
std::string inStr_s(inStr);
/* Doing some processing with the string object inStr_s*/
/* .......*/
/* Done */
return;
}
And now i'm stuck with one problem which cannot be solved without making copies as far as i know. So, i seek your help in this.
The problem is i need to get the changes done by doTheStringWork function back at the caller's place. You may say take .c_str() value as return from func or get a copy somehow. That approaches works well but for my tasks it becomes very slow approach since the string can be too long and i might require it to process recursively.
In plain words: can we create a string object around a char pointer where i can use all string functions and the char pointer reflects all these changes. If such thing cannot be achieved using standard library could someone provide an approach how can i achieve my goal here.
Best solution is to dump C, use C++ and get away from whole mess. But since you probably can't do that, next best solution is to create your own C visible struct and some C visible functions (essentially PIMPL), define those in C++ source (so you get benefits of std::string) and use them from C. Something like this.
In strUtils.h header:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct cpp_string cpp_string;
cpp_string *cpp_string_create(const char *txt, int size);
void cpp_string_free(cpp_string *);
cpp_string *cpp_string_add(cpp_string *, cpp_string *);
... // all operations you need
#ifdef __cplusplus
}
#endif
In C++ source (strUtils.cpp):
#include <string>
struct cpp_string {
std::string str;
cpp_string(std::string str): str(std::move(str)) { }
};
extern "C" cpp_string *cpp_string_create(const char *txt, int size)
{
return new cpp_string{ std::string{ txt, (size_t)size } };
}
// fill operations here
// since this is C++ file, just use std::string without copying
Now, when you want to use it, you do something like this:
int main()
{
cpp_string *s = cpp_string_create("qwerty", 6);
// do something with s
// dont forget to free s
cpp_string_free(s);
return 0;
}
This sidesteps whole can-i-overwrite-someone-elses-memory (no, you can't, unless you want to have weird, wierd problems) by creating your own data.

C++ compilation error: request for member ‘c_cflag' in something not a structure or union

I am trying to compile cp210x USB-UART driver on Debian 7 and getting the following error (when make command):
/var/distr/sillabs/Linux_3.x.x_VCP_Driver_Source/cp210x.c:589:17: error: request for member ‘c_cflag’ in something not a structure or union
Here is a fragment of code, line 589 (starts with &tty->), cp210x.c:
static void cp210x_get_termios(struct tty_struct *tty,
struct usb_serial_port *port)
{
unsigned int baud;
if (tty) {
cp210x_get_termios_port(tty->driver_data,
&tty->termios.c_cflag, &baud);
tty_encode_baud_rate(tty, baud, baud);
} else {
unsigned int cflag;
cflag = 0;
cp210x_get_termios_port(port, &cflag, &baud);
}
}
I think something is wrong with the &tty->termios.c_cflag construction. Please help how to fix it?
Thank you!
It means that in your definition of tty_struct, termios is a structure pointer, not a structure. You need to change the expression
&tty->termios.c_cflag
to
&tty->termios->c_cflag
The definition of tty_struct changed between versions 2.x and 3.x of the Linux kernel.
The driver you're building expects it to contain:
struct ktermios termios, termios_locked;
from 3.x, but you are using the includes from 2.x:
struct ktermios *termios, *termios_locked;
You can either reconsider the kernel you're using to better meet the driver's requirements, or you can hack the driver's code yourself:
- &tty->termios.c_cflag
+ &tty->termios->c_cflag
I would also suggest talking to the driver developer about this, if the requirements are unclear.
a tty_struct contain, among other thing:
// from tty.h
struct tty_struct {
int magic;
// some cut
struct ktermios termios, termios_locked;
// more cut
};
a ktermios in turn, is defined like:
// from termbits.h
struct ktermios {
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
speed_t c_ispeed; /* input speed */
speed_t c_ospeed; /* output speed */
};
and finally, a tcflag_t is:
// also from termbits.h
typedef unsigned int tcflag_t;
so, in conclusion, it should work.
What could muck up that? My first guess would be a macro.
Prime suspect would be that you have a termios macro.
If not that, don't look for the error at line where its reported, it's probably a side-effect of something else.
For example, do you have old headers that the compiler might find instead of those you want? If you are trying to compile a driver for v3 with headers from v2 it wont work.

Multiple definition errors in Arduino library

I am trying to compile the lightRobot.ino Arduino sketch from https://github.com/janisHD/LightRobot in Arduino 1.0.5, but I'm getting multiple definition errors for the functions in the lightRobot library.
I'm using OS X 10.8.5 but had the same problem in Windows 8.
Here are example .h and .cpp files:
BlueToothEvent.h
/*! \file BlueToothEvent.h checks periodically if new data over BT has been received.
*/
#include <Arduino.h>
#include <OrangutanLCD.h>
#include "TimeEvent.h"
#ifndef BLUETOOTH_EVENT_H
#define BLUETOOTH_EVENT_H
#define DATA_WORD_LENGTH 4
/*! \class BlueToothEvent
retrieves and stores the received BT data. The data should come over the serialport, it must be started in "setup".
The struct DataPacket publishes the parsed data for the Statemanager.
*/
class BlueToothEvent : public TimeEvent
{
public:
struct DataPacket {
char speed;
char direction;
int color[4]; // [3]==blue [2]==green [1]==red [0]==brightness
int mode[2]; // [1]==color mode (0000->remote, 0001->blink, 0010->random, 0011->random&blink) [0]==drive mode (0000->remote, 0001->random)
};
BlueToothEvent();
~BlueToothEvent(){};
/*! Callback which is executed periodically*/
virtual void onTimeEvent();
/*! Returns an internal state.*/
virtual unsigned char getInternalState();
/*! Sets an internal state.*/
virtual void setInternalState(unsigned char state, bool update=false);
/*! Executes a more complex (and time consuming) action.*/
virtual void executeAction();
/*! To get the received data in the DataPacket struct
\return The most recent data received via Serial connection
*/
DataPacket getDataPacket();
bool m_new_data_present;
private:
/*! Processes the array with a 4 byte data word and saves the information in the DataPacket field.
\param data the array (must have the length of 4 bytes)
*/
void processData(unsigned char* data);
private:
enum Data{
velocity=0,//desired velocity
direction,//direction to drive
color,//desired color of the LEDs
mode,//the different modes: remote, random, blink
};
unsigned char m_data[DATA_WORD_LENGTH];
struct DataPacket m_data_packet;
};
#endif
BlueToothEvent.cpp
#include "BlueToothEvent.h"
BlueToothEvent::BlueToothEvent():
TimeEvent(),
m_new_data_present(false)
{
//init data array
m_data[velocity] = 0;
m_data[direction] = 0;
m_data[color] = 0;
m_data[mode] = 0;
processData(m_data);
//Serial connection
}
void BlueToothEvent::onTimeEvent()
{
//Code to receive a single data word and store it in m_data field
//Word consists of 4 chars (see the docu for further explanations):
//[0] -> direction to drive [0-254]
//[1] -> velocity to drive [0-254]
//[2] -> desired color for the Light [0-254] in 2 bit packets -> b0[0,3]->Brightnes | [0,3]->Red| [0,3]->Green | [0,3]->Blue
//[3] -> internal mode (see responsible class)[0-254]
if(Serial.available() >= DATA_WORD_LENGTH)
{//minimum number of bytes must be available in the buffer
while(Serial.available() > DATA_WORD_LENGTH)
Serial.read();//clear buffer except the last 4 bits
m_data[velocity] = (char)Serial.read();
m_data[direction] = (char)Serial.read();
m_data[color] = (char)Serial.read();
m_data[mode] = (char)Serial.read();
processData(m_data);
m_new_data_present = true;
}
}
void BlueToothEvent::processData(unsigned char* data)
{
m_data_packet.speed = data[velocity];
m_data_packet.direction = data[direction];
m_data_packet.color[0] = data[color] & 0b00000011;
m_data_packet.color[1] = (data[color] & 0b00001100)>>2;
m_data_packet.color[2] = (data[color] & 0b00110000)>>4;
m_data_packet.color[3] = (data[color] & 0b11000000)>>6;
m_data_packet.mode[0] = data[mode] & B00001111;
m_data_packet.mode[1] = (data[mode] & B11110000)>>4;
}
BlueToothEvent::DataPacket BlueToothEvent::getDataPacket()
{
m_new_data_present = false;
return m_data_packet;
}
//unsigned char BlueToothEvent::getData(unsigned char field)
//{
// if(field <= mode)
// return m_data[field];
// else
// return 0;
//}
unsigned char BlueToothEvent::getInternalState()
{
return m_data[mode];
}
void BlueToothEvent::setInternalState(unsigned char state, bool update)
{
//nothing to do here!
}
void BlueToothEvent::executeAction()
{
//nothing to do here!
}
I get the following errors on compilation - I've only shown the errors for the listed pair of .h/.cpp files - there are similar ones for every file in the lightRobot library:
lightRobot/BlueToothEvent.cpp.o: In function `BlueToothEvent::processData(unsigned char*)':
/Users/lemmy/Documents/Arduino/libraries/lightRobot/BlueToothEvent.cpp:43: multiple definition of `BlueToothEvent::processData(unsigned char*)'
BlueToothEvent.cpp.o:BlueToothEvent.cpp:43: first defined here
lightRobot/BlueToothEvent.cpp.o: In function `BlueToothEvent':
/Users/lemmy/Documents/Arduino/libraries/lightRobot/BlueToothEvent.cpp:4: multiple definition of `BlueToothEvent::BlueToothEvent()'
BlueToothEvent.cpp.o:BlueToothEvent.cpp:4: first defined here
lightRobot/BlueToothEvent.cpp.o: In function `BlueToothEvent':
/Users/lemmy/Documents/Arduino/libraries/lightRobot/BlueToothEvent.cpp:4: multiple definition of `BlueToothEvent::BlueToothEvent()'
BlueToothEvent.cpp.o:BlueToothEvent.cpp:4: first defined here
lightRobot/BlueToothEvent.cpp.o: In function `BlueToothEvent::getDataPacket()':
/Users/lemmy/Documents/Arduino/libraries/lightRobot/BlueToothEvent.cpp:56: multiple definition of `BlueToothEvent::getDataPacket()'
BlueToothEvent.cpp.o:BlueToothEvent.cpp:56: first defined here
lightRobot/BlueToothEvent.cpp.o: In function `BlueToothEvent::getInternalState()':
/Users/lemmy/Documents/Arduino/libraries/lightRobot/BlueToothEvent.cpp:73: multiple definition of `BlueToothEvent::getInternalState()'
BlueToothEvent.cpp.o:BlueToothEvent.cpp:73: first defined here
lightRobot/BlueToothEvent.cpp.o: In function `BlueToothEvent::setInternalState(unsigned char, bool)':
/Users/lemmy/Documents/Arduino/libraries/lightRobot/BlueToothEvent.cpp:78: multiple definition of `BlueToothEvent::setInternalState(unsigned char, bool)'
BlueToothEvent.cpp.o:BlueToothEvent.cpp:78: first defined here
lightRobot/BlueToothEvent.cpp.o: In function `BlueToothEvent::executeAction()':
/Users/lemmy/Documents/Arduino/libraries/lightRobot/BlueToothEvent.cpp:83: multiple definition of `BlueToothEvent::executeAction()'
BlueToothEvent.cpp.o:BlueToothEvent.cpp:83: first defined here
lightRobot/BlueToothEvent.cpp.o: In function `BlueToothEvent::onTimeEvent()':
/Users/lemmy/Documents/Arduino/libraries/lightRobot/BlueToothEvent.cpp:18: multiple definition of `BlueToothEvent::onTimeEvent()'
BlueToothEvent.cpp.o:BlueToothEvent.cpp:18: first defined here
It seems that the errors are occurring in the object file, but I'm not sure why, as the header files have guards on them to prevent multiple definitions.
In case anyone else comes across this question later I was having the same problem and it was fixed by deleting the tabs on the library files in my sketch. It seems to include those files there and again when you have #include "lib.h"
The compilation succeeded when I moved the .ino file out of the lightRobot folder.
I know you already found the answer but, for future searchers, I had this same problem. I fixed it by renaming the main folder, for the .ino, and removing any .h or .cpp files from the folder.
Note: I don't know how this happened to me but it may be an issue for someone else.