diff --git a/src/api/class/include/class/class_core.hpp b/src/api/class/include/class/class_core.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..75d6b0f458fcda477b9baaa289c66681e051078d
--- /dev/null
+++ b/src/api/class/include/class/class_core.hpp
@@ -0,0 +1,772 @@
+/**
+ * @file   class_core.hpp
+ * @author Alfonso Dominguez <alfonso.dominguez@tecnalia.com> and Leire Querejeta Lomas <leire.querejeta@tecnalia.com>
+ * @date   2020
+ *
+ * Copyright 2020 Tecnalia Research & Innovation.
+ * Distributed under the GNU GPL v3.
+ * For full terms see https://www.gnu.org/licenses/gpl.txt
+ *
+ * @brief Interface to the funccionalities of Class
+ */
+
+#ifndef CLASS_CORE_HPP
+#define CLASS_CORE_HPP
+
+#include <vector>
+#include <string>
+#include <memory>
+#include <thread>
+#include <mutex>
+#include <cmath>
+#include <iostream>
+#include <fstream>
+
+#include <boost/circular_buffer.hpp>
+
+#include <communication/udp_server.hpp>
+#include <communication/udp_client.hpp>
+#include <logger/logger.hpp>
+#include <class/class_structures.hpp>
+#include <class/class_error.hpp>
+#include <class/class_cb.hpp>
+#include <filter/butterworth.hpp>
+
+#include <Python.h>
+
+/**
+ * @brief Core class
+ */
+class ClassCore:public UdpServerListener
+{
+public:
+  //! Allowed values
+
+  int BUZZER_MAX_VALUE = 500;
+  int BUZZER_MIN_VALUE = 25;
+  int FREQ_MAX_VALUE = 2000;
+  int FREQ_MIN_VALUE = 0;
+  int HV_MAX_VALUE = 200;
+  int HV_MIN_VALUE = 120;
+  int INTERVAL_MAX_VALUE = 1000;
+  int INTERVAL_MIN_VALUE = 250;
+
+  //! Structure for electrode
+  struct Elec
+  {
+    int id;
+    int pads_number;
+  };
+
+  //! Structure for virtual electrode
+  struct Velec
+  {
+    int id;
+    std::string name;
+    bool selected;
+  };
+
+  //! basic constructor
+  ClassCore();
+  //! basic destructor
+  ~ClassCore();
+
+  /*!
+    \brief Stops acquisition
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error acqOff();
+
+  /*!
+    \brief Starts acquisition
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error acqOn();
+
+  /*!
+    \brief Stops impedance acquisition
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error acqImpedanceOff();
+
+  /*!
+    \brief Starts impedance acquisition
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error acqImpedanceOn();
+
+  /*!
+    \brief Stops acquisition stream
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error acqStreamOff();
+
+  /*!
+    \brief Starts acquisition stream
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error acqStreamOn();
+ 
+  /*!
+    \brief Sets the config for impedance acquisition
+    \param positive Indicates whther is positive (true) or negative (false)
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error acqImpedanceConfig(const bool& positive);
+
+  /*!
+    \brief Sets the polarity for impedance acquisition
+    \param unipolar Indicates whther is unipolar (true) or bipolar (false).
+    \return Integer indicating the success of the setting process (0-success, <0 error)
+  */
+  ClassError::Error acqImpedancePolarity(const bool& unipolar);
+
+  /*!
+    \brief Sets class acq input to normal (bio signal captured from channels)
+    \return Integer indicating the success of the setting process (0-success, <0 error)
+  */
+  ClassError::Error acqInputNormal();
+
+  /*!
+    \brief Sets class acq input to test. The class will provide a quadratic signal. It is useful for testing and not getting saturated signal all the time.
+    \return Integer indicating the success of the setting process (0-success, <0 error)
+  */
+  ClassError::Error acqInputTest();
+
+  /*!
+    \brief Sends the request for battery level
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error batteryLevel();
+
+  /*!
+    \brief Sets the duration of the buffer (ms*frequency//1000.0)
+    \param ms Time in ms
+    \return Integer indicating the success of the setting process (0-success, <0 error)
+  */
+  ClassError::Error bufferDuration(const double& ms);
+
+  /*!
+  \brief Sets buzzer on
+  \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error buzzerPlay();
+
+  /*!
+    \brief Sends the request for buzzer
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error buzzerStatus();
+
+  /*!
+  \brief Sets ms of buzzer song
+  \param tempo time in ms
+  \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error buzzerTempo(const std::string& tempo);
+
+  /*!
+    \brief Connect to the CLASS server
+    \param server_ip IP of the CLASS server
+    \param server_port of the CLASS server
+    \param local_ip IP in which the instance is listening for messages coming from CLASS server
+    \param local_port Port in which the instance is listening for messages coming from CLASS server
+    \return Integer indicating the success of the connection (0-success, <0 error)
+  */
+  ClassError::Error connect(const std::string & server_ip, const int & server_port, const std::string & local_ip, const int & local_port);
+
+  /*!
+    \brief Sends the request for device name
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error deviceName();
+
+  /*!
+    \brief Sets name of device
+    \param devicename Name of the device
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error devName(const std::string& devicename);
+
+  /*!
+    \brief Disconnect from the CLASS server
+    \return Integer indicating the success of the disconnection (0-success, <0 error)
+  */
+  ClassError::Error disconnect();
+
+  /*!
+    \brief Sets electrode pads number
+    \param id Electrode number/ID
+    \param pads_number Number of pads of the electrode
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error elecPads(const int& id, const int& pads_number);
+
+  /*!
+    \brief Sends the request for firmware version
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error firmwareVersion();
+
+  /*!
+    \brief Sends the request for frequency
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error frequencyStatus();
+
+  /*!
+    \brief Sets the config for impedance acquisition
+    \param acq_frames Vector to fill with acqusition frames
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error getAcqFrames(std::vector<AcqFrame>& acq_frames);
+
+  /*!
+    \brief Sends the request for hardware version
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error hardwareVersion();
+
+  /*!
+    \brief Sets high voltage to off
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error hvOff();
+
+  /*!
+    \brief Sets high voltage to on
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error hvOn();
+
+  /*!
+    \brief Sends the request for high voltage status
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error hvStatus();
+
+  /*!
+    \brief Sets high voltage value
+    \param hvvalue value of high voltage
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error hvValue(const std::string& hvvalue);
+
+  /*!
+    \brief Sets the order of the filter used for impedance calculation
+    \param order Filter order (>0)
+    \return Integer indicating the success of the setting process (0-success, <0 error)
+  */
+  ClassError::Error impedanceFilterOrder(const int& order);
+
+  /*!
+    \brief Init communication
+    \param init_mode Initialization mode
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error initCommunication(const std::string& init_mode);
+
+  /*!
+    \brief Sends the request for interval status
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error intervalStatus();
+
+  /*!
+    \brief Sets stimulation inter pulses interval
+    \param interval value of stimulation inter pulses
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error intervalValue(const std::string& interval);
+
+  /*!
+    \brief Sets logevents to off
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error logeventsOff();
+
+  /*!
+    \brief Sets logevents to on
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error logeventsOn();
+
+  /*!
+    \brief Sends the request for logevents
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error logeventsStatus();
+
+  /*!
+    \brief Sets pattern
+    \param number pattern number
+    \param pat vector of patterns
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error pattern(const int& number, const std::vector<Pattern>& pat);
+
+  /*!
+    \brief Clear pattern
+    \param id pattern to delete
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error patternClear(const int& id);
+
+  /*!
+    \brief Sends the request for pattern
+    \param number pattern
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error patternStatus(const int& number);
+
+  /*!
+    \brief Sends the request for pattern
+    \param number pattern
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error velecStatus(const int& number);
+
+  /*!
+    \brief Sets rtc date
+    \param rtcdate mm/dd/yyyy format
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error rtcDate(const std::string& rtcdate);
+
+  /*!
+    \brief Sends the request for rtc
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error rtcStatus();
+
+  /*!
+    \brief Sets rtc time
+    \param rtctime hh:mm:ss format
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error rtcTime(const std::string& rtctime);
+
+  /*!
+    \brief Sends the request for sd function
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error sdfunctionStatus();
+
+  /*!
+  \brief Sets name of sdcard folder where the pattern are saved
+  \param sdfunctionname name of the folder
+  \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error sdFunctionName(const std::string& sdfunctionname);
+ 
+  /*!
+  \brief Sets name of sdcard folder where the folder containing the patterns is saved
+  \param sduname name of the folder
+  \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error sdUName(const std::string& sduname);
+
+  /*!
+    \brief Sends the request for sd user name
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error sdunameStatus();
+
+  /*!
+    \brief Sends custom command to CLASS device
+    \param cmd Command
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error sendCustomCmd(const std::string& cmd);
+
+  /*!
+    \brief Sets class acq configuration
+    \param frequency Frequency of acquisition
+    \param channel_numbers Channel numbers
+    \param gain Gain of the acquisition
+    \param input Acq input type, normal or test
+    \return Integer indicating the success of the setting process (0-success, <0 error)
+  */
+  ClassError::Error setAcqConfig(const double& frequency, const std::vector<int>& channel_numbers, const double& gain, const std::string& input);
+  
+  /*!
+    \brief Sets the callback
+    \param callback Callback
+    \param language Language which has defined the callback
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error setCallback(ClassCallback* callback, std::string language);
+
+  /*!
+    \brief Turn off
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error shutdown();
+
+  /*!
+    \brief Sets frequency of the stimulation
+    \param frequency Frequency of the stimulation
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error stimFreq(const double& frequency);
+
+  /*!
+    \brief Stops stimulation
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error stimOff();
+
+  /*!
+    \brief Starts stimulation
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error stimOn();
+
+  /*!
+    \brief Starts stimulation of the virtual electrode which name is passed as parameter
+    \param name Name of the virtual electrode
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error stimVelec(const std::string& name);
+
+  /*!
+    \brief Sends the request for tic
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error tic();
+
+  /*!
+    \brief Handles the reception of an UDP msg from the CLASS server
+    \param msg Msg
+    \param ip IP the message comes from
+  */
+  void udpMsgReceived(std::string msg, std::string client_ip);
+
+  /*!
+    \brief Sets virtual electrode
+    \param number Virtual electrode number/ID
+    \param name Name of the virtual electrode
+    \param electrode_id Electrode ID/number
+    \param cathodes List of integers with the IDs of the pads acting as cathodes
+    \param anodes List of integers with the IDs of the pads acting as cathodes
+    \param amp List of doubles with the amplitude (in mA) associated to each of the cathodes. Must have the same length as cathodes
+    \param width List of integers with the pulse width (in uS) associated to each of the cathodes. Must have the same length as cathodes
+    \param selected Defines if the velec is selected (‘true’ value) or deselected (‘false’ value). Only selected velecs will be executed with a “stim on” command
+    \param sync Defines if the velec is synchronous (‘rtue’ value) or asynchronous (‘false’ value).
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error velec(const int& id, const std::string& name, const int& electrode_id, const std::vector<int>& cathodes, const std::vector<int>& anodes, const std::vector<double>& amp, const std::vector<int>& width, const bool& selected, const bool& sync);
+
+  /*!
+    \brief Sets whether the virtual electrode is selected or not
+    \param id Virtual electrode number/ID
+    \param selected Defines if the velec is selected (‘true’ value) or deselected (‘false’ value). Only selected velecs will be executed with a “stim on” command.
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error velecSelected(const int& id, const bool& selected);
+
+  /*!
+    \brief Sets whether the virtual electrodes are selected or not
+    \param id Vector with virtual electrode number/ID.
+    \param selected Vector of bool values indicating whether the virtual electrode is selected
+    \return Integer indicating the success of the process (0-success, <0 error)
+  */
+  ClassError::Error velecsSelected(const std::vector<int>& id, const std::vector<bool>& selected);
+  
+private:
+  /*!
+    \brief Sends msg through serial
+    \param msg Msg to send.
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error sendMsg(std::string msg);
+
+  /*!
+    \brief Sends msgs through serial
+    \param msgs Vector with msgs to send.
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error sendMsgs(std::vector<std::string> msgs);
+
+  /*!
+    \brief Updates buffer capacity based on acq rate and seconds
+    \param seconds Buffer duration.
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error setBufferCapacity(const double& seconds);
+
+  /*!
+    \brief Configures the filter for impedance
+    \param order Order of the filter
+    \param low_freq Lower frequency of the band
+    \param up_freq Upper freqeuncy of the band 
+    \param acq_freq Sampling rate
+    \return Integer indicating the success of the starting process (0-success, <0 error)
+  */
+  ClassError::Error configureFilter(int order, double low_freq, double up_freq, double acq_freq);
+
+  /*!
+    \brief Sets the number of digits after decimal
+    \param value Value
+    \param digits_after_decimal Number of desired digits after decimal
+    \return Pair with the new_value and a bool indicating whether the operation has enough precision
+  */
+  std::pair< double, bool > trunc_n( double value, std::size_t digits_after_decimal);
+
+  /*!
+    \brief Increases lock error number
+  */
+  void increaseLockError();
+
+  //! UDP server where it listens for command coming form the CLASS server
+  UDPServer *udp_server_;
+  //! UDP client which sends messages to CLASS server
+  UDPClient *udp_client_;
+
+  //! indicates the IP where the CLASS server is listening
+  std::string server_ip_;
+  //! indicates the port where the CLASS server is listening
+  int server_port_;
+  //! indicates the local IP where the instance is listening for messages coming from CLASS server
+  std::string local_ip_;
+  //! indicates the local port where the instance is listening for messages coming from CLASS server 
+  int local_port_;
+
+  //! defined electrodes
+  std::vector<Elec> electrodes_;
+
+  //! defined virual electrodes
+  std::vector<Velec> virtual_electrodes_;
+
+  //! indicates whether it is acquiring frames
+  bool is_acquiring_frames_;
+  //! is_acquiring_frames mutex
+  std::mutex is_acquiring_frames_mutex_;
+  //! number of channels
+  int channels_number_;
+  //! frequency of the acquisition
+  double acq_frequency_;
+  //! acquisition time (determinates buffer maximum size)
+  double acq_seconds_;
+  //! acquisition time
+  int acq_buffer_capacity_;
+  //! acquisition buffer
+  boost::circular_buffer<AcqFrame> acq_buffer_;
+  //! acquisition buffer mutex
+  std::mutex acq_buffer_mutex_;
+
+  //! indicates whether it is acquiring impedances
+  bool is_acquiring_impedances_;
+  //! is_acquiring_frames mutex
+  std::mutex is_acquiring_impedances_mutex_;
+  //! acquisition time
+  int acq_impedances_buffer_capacity_;
+  //! acquisition buffer
+  boost::circular_buffer<AcqFrame> acq_impedances_buffer_;
+  //! acquisition buffer mutex
+  std::mutex acq_impedances_buffer_mutex_;
+
+  //! butterworth filters, one per channel
+  Butterworth **butterworth_;
+  //! order of the filter
+  int filter_order_;
+
+  //! thread for waiting messages
+  std::thread *waiting_thread_;
+  //! function for waiting messages
+  void waitingThreadFunction_();
+  //! Indicates whether to wait for special messages
+  bool waiting_;
+  //! Mutex for waiting
+  std::mutex waiting_mutex_;
+
+  //! indicates whether it is waiting for tic
+  bool tic_received_;
+  //! indicates whether tic has been received
+  bool is_waiting_tic_;
+  //! mutex for tic
+  std::mutex tic_mutex_;
+
+  //! indicates whether it is waiting for firmware
+  bool firmware_received_;
+  //! indicates whether firmware has been received
+  bool is_waiting_firmware_;
+  //! mutex for firmware
+  std::mutex firmware_mutex_;
+
+  //! indicates whether it is waiting for device name
+  bool device_received_;
+  //! indicates whether device name has been received
+  bool is_waiting_device_;
+  //! mutex for firmware
+  std::mutex device_mutex_;
+
+  //! indicates whether it is waiting for hardware
+  bool hardware_received_;
+  //! indicates whether hardware has been received
+  bool is_waiting_hardware_;
+  //! mutex for hardware
+  std::mutex hardware_mutex_;
+
+  //! indicates whether it is waiting for battery
+  bool battery_received_;
+  //! indicates whether battery has been received
+  bool is_waiting_battery_;
+  //! mutex for battery
+  std::mutex battery_mutex_;
+
+  //! indicates whether it is waiting for logevents
+  bool logevents_received_;
+  //! indicates whether logevents has been received
+  bool is_waiting_logevents_;
+  //! mutex for logevents
+  std::mutex logevents_mutex_;
+
+  //! indicates whether it is waiting for high voltage status
+  bool hvstatus_received_;
+  //! indicates whether high voltage status has been received
+  bool is_waiting_hvstatus_;
+  //! mutex for high voltage status
+  std::mutex hvstatus_mutex_;
+
+  //! indicates whether it is waiting for interval status
+  bool intervalstatus_received_;
+  //! indicates whether interval status has been received
+  bool is_waiting_intervalstatus_;
+  //! mutex for interval status
+  std::mutex intervalstatus_mutex_;
+
+  //! indicates whether it is waiting for rtc status
+  bool rtcstatus_received_;
+  //! indicates whether rtc status has been received
+  bool is_waiting_rtcstatus_;
+  //! mutex for rtc status
+  std::mutex rtcstatus_mutex_;
+
+  //! indicates whether it is waiting for buzzer status
+  bool buzzerstatus_received_;
+  //! indicates whether buzzer status has been received
+  bool is_waiting_buzzerstatus_;
+  //! mutex for buzzer status
+  std::mutex buzzerstatus_mutex_;
+
+  //! indicates whether it is waiting for frequency status
+  bool frequencystatus_received_;
+  //! indicates whether frequency status has been received
+  bool is_waiting_frequencystatus_;
+  //! mutex for frequency status
+  std::mutex frequencystatus_mutex_;
+
+  //! indicates whether it is waiting for sdfunction
+  bool sdfunction_received_;
+  //! indicates whether sdfunction has been received
+  bool is_waiting_sdfunction_;
+  //! mutex for sdfunction
+  std::mutex sdfunction_mutex_;
+
+  //! indicates whether it is waiting for sduname
+  bool sduname_received_;
+  //! indicates whether sduname has been received
+  bool is_waiting_sduname_;
+  //! mutex for sduname
+  std::mutex sduname_mutex_;
+
+  //! indicates whether it is waiting for pattern
+  bool patternstatus_received_;
+  //! indicates whether pattern has been received
+  bool is_waiting_patternstatus_;
+  //! mutex for logevents
+  std::mutex patternstatus_mutex_;
+
+  //! indicates whether it is waiting for velecstatus
+  bool velecstatus_received_;
+  //! indicates whether velecstatus has been received
+  bool is_waiting_velecstatus_;
+  //! mutex for velecstatus
+  std::mutex velecstatus_mutex_;
+
+  //! battery level
+  double battery_;
+  // tic text
+  std::string tic_;
+  // firmware text
+  std::string firmware_;
+  // hardware text
+  std::string hardware_;
+  // device text
+  std::string device_;
+  // logevents text
+  std::string logevents_;
+  // high voltage status text
+  std::string hvstatus_;
+  // interval status text
+  std::string intervalstatus_;
+  // rtc status text
+  std::string rtcstatus_;
+  // buzzer status text
+  std::string buzzerstatus_;
+  // frequency status text
+  std::string frequencystatus_;
+  // sdfunction status text
+  std::string sdfunctionstatus_;
+  // sduname status text
+  std::string sdunamestatus_;
+  // pattern status text
+  std::string patternstatus_;
+  // velecstatus text
+  std::string velecstatus_;
+
+  //! mutex for lock errors
+  std::mutex lock_error_mutex_;
+  //! number of lock errors
+  int lock_error_number_;
+  //! max number of lock errors before launching error
+  int lock_error_number_max_;
+  //! thread for lock errors
+  std::thread *lock_error_thread_;
+  //! function for lock error
+  void lockErrorThreadFunction_();
+  //! Indicates whether to wait for special messages
+  bool error_waiting_;
+
+  //! callback for battery, turn_off, etc.
+  ClassCallback* class_cb_;
+  //! Language which has defined the callback
+  std::string language_;
+
+  //! acq gainb
+  double gain_;
+
+  //! log function
+  #define log_stream_(x) log_(std::stringstream() << x);
+  #define log_warn_stream_(x) log_warn_(std::stringstream() << x);
+  #define log_error_stream_(x) log_err_(std::stringstream() << x);
+  void log_(const std::string &text);
+  void log_(const std::stringstream &text);
+  void log_(std::ostream & text);
+  void log_err_(const std::string &text);
+  void log_err_(std::ostream & text);
+  void log_warn_(const std::string &text);
+  void log_warn_(std::ostream & text);
+};
+
+/**
+ * @brief Class for locking when accesing callback in Python
+ */
+class PyThreadStateLock
+{
+public:
+  PyThreadStateLock(void)
+  {
+    state = PyGILState_Ensure( );
+  }
+  
+  ~PyThreadStateLock(void)
+  {
+    PyGILState_Release( state );
+  }
+private:
+  PyGILState_STATE state;
+};
+
+#endif  // CLASS_CORE_HPP