Acoustic Touch Recognition
libacoustic_touch.h
Go to the documentation of this file.
1 #ifndef INCLUDED_ACOUSTIC_TOUCH_LIBACOUSTICTOUCH_H
2 #define INCLUDED_ACOUSTIC_TOUCH_LIBACOUSTICTOUCH_H
3 
4 // C libraries
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <signal.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 
11 // C++ libraries
12 #include <sstream>
13 #include <string>
14 #include <cstring>
15 #include <iostream>
16 #include <fstream>
17 #include <cstdlib>
18 #include <vector>
19 #include <map>
20 #include <iterator>
21 #include <thread>
22 #include <mutex>
23 #include <chrono>
24 
25 // Boost libraries
26 #include <boost/enable_shared_from_this.hpp>
27 #include <boost/algorithm/string.hpp>
28 
29 // ALSA includes
30 #include <alsa/asoundlib.h>
31 #include <alsa/mixer.h>
32 
33 // ROS libraries
34 #include "ros/rate.h"
35 #include "ros/ros.h"
36 #include "ros/console.h"
37 #include "ros/package.h"
38 
39 // ROS parameters
40 #include "ros/subscriber.h"
41 #include "xmlrpcpp/XmlRpcValue.h"
42 
43 //ROS msgs
44 #include "std_msgs/Empty.h"
45 #include "std_msgs/Float64.h"
46 #include "std_msgs/Int8.h"
47 #include "std_msgs/String.h"
48 #include "common_msgs/KeyValuePair.h"
49 #include "common_msgs/KeyValuePairArray.h"
50 #include "arduino_msgs/sensorStates.h"
51 #include "touch_gesture_msgs/SoundGesture.h"
52 
53 //ROS services
54 #include "acoustic_touch_recognition/MenuOptions.h"
55 
56 // linuxaudio library
57 #include "linuxaudio/utils.h"
58 
59 // pstreams library
60 #include "pstreams/pstream.h"
61 
62 // OSC-related includes and defines
63 #include "oscpack/ip/UdpSocket.h"
67 
68 #define HOST "127.0.0.1" // localhost
69 #define PORT 1230
70 #define IN_PORT 7000
71 #define OUTPUT_BUFFER_SIZE 1024
72 
73 //colors to use in the outputs
74 #define RESET_COLOR "\e[m"
75 #define MAKE_ITALIC "\e[3m"
76 #define MAKE_WHITE "\e[1;97m"
77 #define MAKE_GREEN "\e[1;32m"
78 #define MAKE_BLACK "\e[0;30m"
79 #define MAKE_RED "\e[1;31m"
80 #define MAKE_BLUE "\e[1;34m"
81 #define MAKE_CYAN "\e[1;36m"
82 #define MAKE_BROWN "\e[0;33m"
83 #define MAKE_PURPLE "\e[1;35m"
84 #define MAKE_YELLOW "\e[1;33m"
85 #define MAKE_BLUE_UNDERLINE "\e[4;34m"
86 #define MAKE_YELLOW_UNDERLINE "\e[4;33m"
87 
88 // ChucK macros
89 #define CK_DEBUG false
90 #define CK_LOG_PATH "/log/chuck/"
91 #define CK_FILE_PATH "/scripts/chuck/"
92 #define CK_FILE_NAME "audio_analyzer.ck"
93 #define CK_PULSE_LATENCY 60 // pulseaudio latency in msecs
94 
95 using namespace std;
96 //using namespace boost::posix_time;
97 
98 // ros::Duration timeSleep(1);
99 // volatile sig_atomic_t g_shutdown_flag;
100 //int numFingerPrints;
101 
106 {
107 public:
115  SoundGesture(int m_num = 0, string m_id = ""):
116  mic_num_(m_num),
117  mic_id_(m_id),
118  num_attrib_(vector<double>(33,0)),
119  empty_(true),
120  waiting_(false)
121  {}
122 
130  SoundGesture(int m_num, string m_id, vector<double> atts):
131  mic_num_(m_num),
132  mic_id_(m_id),
133  num_attrib_(atts),
134  empty_(false),
135  waiting_(false)
136  {}
137 
139  {}
140 
141  void setAttributes(vector<double>);
142  void clearAttributes();
143  void setId(string);
144  void setEmpty(bool);
145  void setWaiting(bool);
146 
147  vector<double> getAttributes()const;
148  int getMicNum()const;
149  string getMicId()const;
150  bool isEmpty()const;
151  bool isWaiting()const;
152 
153  SoundGesture &operator = (const SoundGesture &SG);
154 
155 private:
156  vector<double> num_attrib_;
157  int mic_num_;
158  string mic_id_;
159  bool empty_;
160  bool waiting_;
161 };
162 
167 {
168 public:
169  // Constructor and Destructor
170  InstanceBuilder(string mode);
171  ~InstanceBuilder();
172 
173  // ROS callbacks
174 
175  void startGestureCallback(const std_msgs::Int8::ConstPtr& msg);
176  void endGestureCallback(const touch_gesture_msgs::SoundGesture::ConstPtr& msg);
177  bool optionsCallback(acoustic_touch_recognition::MenuOptions::Request &req,
178  acoustic_touch_recognition::MenuOptions::Response &res);
179  void timerCallback(const ros::TimerEvent&);
180  void shutdownCallback(const ros::TimerEvent&);
181 
182  // setters
183  void setSoundGestures(vector<SoundGesture> s_gests); // is useful?
184  void setSoundGestures(SoundGesture s_gest, int index); // atomic, should check mic amount
185  void clearSoundGestures();
186  void clearSoundGestures(int index);
187  void setClassAttributes(string index, string c_att); // can be more complex and check the key
188  void setFile(string path);
189  void closeFile();
190 
191  // getters
192  vector<SoundGesture> getSoundGestures()const;
193  SoundGesture getSoundGestures(int index)const;
194 
195  // methods
196  void init();
197  bool fileExists(string path);
198  void createArffFile();
199  void writeGestures();
200 
201 private:
202  // ROS-related elements
203  ros::NodeHandle nh_;
204  ros::Publisher gesture_pub_;
205  ros::Subscriber gest_start_sub_;
207  ros::Subscriber gest_end_sub_;
208  ros::ServiceServer settings_srv_;
209  ros::Timer timer_;
210  ros::Timer shutdown_timer_;
211 
212  // Gesture elements
213  string robot_;
214  const string mode_;
216  vector<SoundGesture> sound_gestures_; // one gesture per microphone // variable element
217 
218  XmlRpc::XmlRpcValue class_labels_; // map containing the whole pack of labels and its values
219  XmlRpc::XmlRpcValue train_labels_; // map containing the label name and only the selected value in the training
220  vector<string> label_names_; // for accessing quickly to map values
221 
222  // File elements
223  string path_; // Fixed element again in construtor
224  fstream sound_file_;
225 };
226 
233 {
234  typedef struct ck_soundCardAttributes
235  {
236  uint32_t index; // The index assigned to the soundcard. To be supplied to the ChucK command
237  uint32_t number; // Unlike the index, this number is fixed and is set in the package's configuration file
238  uint32_t volume; // the input volume, set in the configuration file
239  bool capacitive; // if there is a capacitive sensor attached to the microphone
241 
242 public:
243  // Constructors & Destructors
244  ChucKHandler(const vector<string> &);
245  ChucKHandler(
246  const vector<string> &, const vector<int> &, const vector<int> &, const string & = "default");
247  ChucKHandler(
248  const vector<string> &, const vector<int> &, const vector<int> &, const vector<bool> &, const string & = "default");
249  ~ChucKHandler() {killChucK();}
250 
251  // Static Methods
252  static void getShellOutput(const string &, string *, string *);
253  static string fetchAlsaModel(const string &);
254  static vector<string> fetchAlsaModels(const vector<string> &);
255  static vector<string> fetchAlsaIDs(const string &);
256  static vector<int> fetchChucKIndexes(const string &);
257 
258  // 'Getters'
259  string getRobot() const;
260  string getChucKMode() const;
261  map<string, ck_cardAttribs_t> getSoundCards() const;
262  vector<string> getSoundCardIDs() const;
263  string getSoundCardID(const int &) const;
264  int getSoundCardIndex(const string &) const;
265  int getSoundCardNumber(const string &) const;
266  int getSoundCardVolume(const string &) const;
267  bool getSoundCardCapacitive(const string &) const;
268  bool getKillChucK() const;
269 
270  // 'Setters'
271  void setRobot(const string &);
272  void setChucKMode();
273  void setSoundCards(const vector<string> &);
274  void setSoundCards(const vector<string> &, const vector<int> &);
275  void setSoundCards(const vector<string> &, const vector<int> &, const vector<int> &);
276  void setSoundCards(const vector<string> &, const vector<int> &, const vector<int> &, const vector<bool> &);
277  void setSoundCardIDs(const vector<string> &);
278  void setSoundCardIndex(const int &, const string &);
279  void setSoundCardNumber(const int &, const string &);
280  void setSoundCardVolume(const int &, const string &);
281  void setSoundCardCapacitive(const bool &, const string &);
282  void setKillChucK(const bool &);
283 
284  // Main functionalities
285  void printSoundCards() const;
286  void setAttributesAlsa(); //TBC
287  void setAttributesPulse();
288  void setSoundCardInputVol(const int &, const string &);
289  void chucKThread(const string &);
290  void launchChucK(const bool & = CK_DEBUG); // "init" function
291  void killChucK();
292 
293 private:
294  string robot_;
295  string chuck_mode_;
296  vector<string> sndcard_ids_;
297  map<string, ck_cardAttribs_t> sound_cards_;
298  vector<thread> ck_threads_;
300 };
301 
305 class AcousticTouchInterface: public boost::enable_shared_from_this<AcousticTouchInterface>
306 {
307 public:
308  AcousticTouchInterface(string, bool);
310 
317  public:
319  protected:
320  virtual void ProcessMessage(const osc::ReceivedMessage &m,
321  const IpEndpointName& remoteEndpoint);
322  private:
324  };
325 
326  void oscCallback(int);
327  void capacitiveCallback(const arduino_msgs::sensorStates::ConstPtr &);
328  void classifReadyCallback(const std_msgs::Empty::ConstPtr &);
329  void sendOscMsg(string, int);
330  void loadSettings();
331  // void createSettings()
332  void showMenu();
333  void setTrainLabels(string);
334  void sendSrv();
335  void shutDown();
336  vector<std::string> getShellOutput(const std::string);
337 
338 private:
339  // ROS-related elements
340  ros::NodeHandle nh_;
341  ros::AsyncSpinner aspin_;
342  ros::Rate loop_rate_;
343  ros::Subscriber capacitive_sub_;
344  ros::Subscriber classif_ready_sub_;
345  ros::Publisher gesture_end_pub_;
346  ros::Publisher gesture_start_pub_;
347  ros::Publisher loud_noise_pub_;
348  ros::ServiceClient client_;
349  acoustic_touch_recognition::MenuOptions srv_;
350 
351  // Audio service elements
352  string robot_;
353  const string mode_;
354  bool with_GUI_;
355  int cap_state_; // the capacitive sensor array state
357 
359  XmlRpc::XmlRpcValue mics_;
360  XmlRpc::XmlRpcValue class_labels_;
361  vector<string> label_names_; // for accessing quickly to map values
362 
364 
365  //osc listening attributes
366  mutex osc_mutex_;
367  vector<thread> osc_threads_;
368  vector<IpEndpointName> ip_endpoints_;
369  vector<ChucKPacketListener> chuck_listeners_;
370  vector<UdpListeningReceiveSocket*> udp_sockets_;
371 };
372 
373 #endif /* INCLUDED_ACOUSTIC_TOUCH_LIBACOUSTICTOUCH_H */
int mic_num_
Definition: libacoustic_touch.h:157
string path_
Definition: libacoustic_touch.h:223
ros::AsyncSpinner aspin_
Definition: libacoustic_touch.h:341
Definition: IpEndpointName.h:41
acoustic_touch_recognition::MenuOptions srv_
Definition: libacoustic_touch.h:349
Definition: OscReceivedElements.h:474
ros::NodeHandle nh_
Definition: libacoustic_touch.h:340
string robot_
Definition: libacoustic_touch.h:294
vector< string > label_names_
Definition: libacoustic_touch.h:220
XmlRpc::XmlRpcValue train_labels_
Definition: libacoustic_touch.h:219
#define CK_DEBUG
Definition: libacoustic_touch.h:89
bool waiting_
Definition: libacoustic_touch.h:160
vector< ChucKPacketListener > chuck_listeners_
Definition: libacoustic_touch.h:369
int mic_amount_
Definition: libacoustic_touch.h:358
ros::ServiceServer settings_srv_
Definition: libacoustic_touch.h:208
const string mode_
Definition: libacoustic_touch.h:214
Front-end to create instance objects step by step.
Definition: libacoustic_touch.h:166
ros::Subscriber classif_ready_sub_
Definition: libacoustic_touch.h:344
Declares all PStreams classes.
uint32_t index
Definition: libacoustic_touch.h:236
uint32_t number
Definition: libacoustic_touch.h:237
AcousticTouchInterface & at_iface_
Definition: libacoustic_touch.h:323
vector< string > label_names_
Definition: libacoustic_touch.h:361
XmlRpc::XmlRpcValue class_labels_
Definition: libacoustic_touch.h:218
ChucKHandler * chuck_handler_
Definition: libacoustic_touch.h:363
bool capacitive
Definition: libacoustic_touch.h:239
ros::Timer timer_
Definition: libacoustic_touch.h:209
string mic_id_
Definition: libacoustic_touch.h:158
vector< thread > ck_threads_
Definition: libacoustic_touch.h:298
ros::NodeHandle nh_
Definition: libacoustic_touch.h:203
bool classif_state_
Definition: libacoustic_touch.h:356
This class is in charge of handling multiple instances of chuck, as much instances as the user wants...
Definition: libacoustic_touch.h:232
vector< string > sndcard_ids_
Definition: libacoustic_touch.h:296
const string mode_
Definition: libacoustic_touch.h:353
This class describes an audio client.
Definition: libacoustic_touch.h:305
vector< IpEndpointName > ip_endpoints_
Definition: libacoustic_touch.h:368
ros::Timer shutdown_timer_
Definition: libacoustic_touch.h:210
ChucKPacketListener(AcousticTouchInterface &ati)
Definition: libacoustic_touch.h:318
string robot_
Definition: libacoustic_touch.h:352
ros::ServiceClient client_
Definition: libacoustic_touch.h:348
SoundGesture(int m_num, string m_id, vector< double > atts)
Parametrized constructor. In this case sets the empty flag to false.
Definition: libacoustic_touch.h:130
ros::Subscriber gest_start_sub_
Definition: libacoustic_touch.h:205
vector< thread > osc_threads_
Definition: libacoustic_touch.h:367
XmlRpc::XmlRpcValue mics_
Definition: libacoustic_touch.h:359
int mic_amount_
Definition: libacoustic_touch.h:215
mutex osc_mutex_
Definition: libacoustic_touch.h:366
map< string, ck_cardAttribs_t > sound_cards_
Definition: libacoustic_touch.h:297
bool empty_
Definition: libacoustic_touch.h:159
fstream sound_file_
Definition: libacoustic_touch.h:224
ros::Rate loop_rate_
Definition: libacoustic_touch.h:342
vector< SoundGesture > sound_gestures_
Definition: libacoustic_touch.h:216
ros::Publisher gesture_pub_
Definition: libacoustic_touch.h:204
ros::Subscriber gest_end_sub_
Definition: libacoustic_touch.h:207
vector< double > num_attrib_
Definition: libacoustic_touch.h:156
ros::Subscriber capacitive_sub_
Definition: libacoustic_touch.h:343
ros::Publisher gesture_end_pub_
Definition: libacoustic_touch.h:345
bool with_GUI_
Definition: libacoustic_touch.h:354
bool kill_chuck_
Definition: libacoustic_touch.h:299
SoundGesture(int m_num=0, string m_id="")
Empty constructor. Admits number and id. Sets also the empty flag to true.
Definition: libacoustic_touch.h:115
int cap_state_
Definition: libacoustic_touch.h:355
uint32_t volume
Definition: libacoustic_touch.h:238
string chuck_mode_
Definition: libacoustic_touch.h:295
~ChucKHandler()
Definition: libacoustic_touch.h:249
Definition: libacoustic_touch.h:234
Definition: OscPacketListener.h:46
ros::Publisher gesture_start_pub_
Definition: libacoustic_touch.h:346
vector< UdpListeningReceiveSocket * > udp_sockets_
Definition: libacoustic_touch.h:370
This nested class describes a chuck packet listener. A nested class is also a member variable of the ...
Definition: libacoustic_touch.h:316
ros::Publisher loud_noise_pub_
Definition: libacoustic_touch.h:347
~SoundGesture()
Definition: libacoustic_touch.h:138
string robot_
Definition: libacoustic_touch.h:213
bool flag_start_sub_
Definition: libacoustic_touch.h:206
XmlRpc::XmlRpcValue class_labels_
Definition: libacoustic_touch.h:360