...
 
Commits (6)
......@@ -36,6 +36,7 @@ FUNCTION(OV_ADD_CONTRIB_DRIVER DRIVER_PATH)
ENDFUNCTION(OV_ADD_CONTRIB_DRIVER)
OV_ADD_CONTRIB_DRIVER("${CMAKE_SOURCE_DIR}/contrib/plugins/server-drivers/bitalino")
OV_ADD_CONTRIB_DRIVER("${CMAKE_SOURCE_DIR}/contrib/plugins/server-drivers/brainmaster-discovery")
OV_ADD_CONTRIB_DRIVER("${CMAKE_SOURCE_DIR}/contrib/plugins/server-drivers/brainproducts-brainvisionrecorder")
OV_ADD_CONTRIB_DRIVER("${CMAKE_SOURCE_DIR}/contrib/plugins/server-drivers/cognionics")
......
......@@ -12,6 +12,7 @@
#include "ovasCDriverCognionics.h"
#include "ovasCDriverCtfVsmMeg.h"
#include "ovasCDriverEncephalan.h"
#include "ovasCDriverBITalino.h"
#include "ovasCDriverGTecGUSBamp.h"
#include "ovasCDriverGTecGUSBampLegacy.h"
#include "ovasCDriverGTecGUSBampLinux.h"
......@@ -38,6 +39,7 @@ namespace OpenViBEContributions
drivers->push_back(new OpenViBEAcquisitionServer::CDriverMBTSmarting(pAS->getDriverContext()));
drivers->push_back(new OpenViBEAcquisitionServer::CDriverOpenEEGModularEEG(pAS->getDriverContext()));
drivers->push_back(new OpenViBEAcquisitionServer::CDriverOpenBCI(pAS->getDriverContext()));
drivers->push_back(new OpenViBEAcquisitionServer::CDriverBITalino(pAS->getDriverContext()));
//OS Limitations
#if defined WIN32
......
This diff is collapsed.
This diff is collapsed.
#include "ovasCConfigurationBITalino.h"
#include <iostream>
#include <gtk/gtk.h>
using namespace OpenViBE;
using namespace Kernel;
using namespace OpenViBEAcquisitionServer;
using namespace std;
/*_________________________________________________
Insert callback to specific widget here
Example with a button that launch a calibration of the device:
//Callback connected to a dedicated gtk button:
static void button_calibrate_pressed_cb(::GtkButton* pButton, void* pUserData)
{
CConfigurationBITalino* l_pConfig=static_cast<CConfigurationBITalino*>(pUserData);
l_pConfig->buttonCalibratePressedCB();
}
//Callback actually called:
void CConfigurationGTecGUSBamp::buttonCalibratePressedCB()
{
// Connect to the hardware, ask for calibration, verify the return code, etc.
}
_________________________________________________*/
// If you added more reference attribute, initialize them here
// Added macAdress as an input
CConfigurationBITalino::CConfigurationBITalino(IDriverContext& driverContext, const char* gtkBuilderFileName, std::string& macAddress, std::string& channelMask)
: CConfigurationBuilder(gtkBuilderFileName), m_driverContext(driverContext), m_macAddress(macAddress), m_channelMask(channelMask) {}
bool CConfigurationBITalino::preConfigure()
{
if (!CConfigurationBuilder::preConfigure()) { return false; }
// Connect here all callbacks
// Example:
// g_signal_connect(gtk_builder_get_object(m_pBuilderConfigureInterface, "button_calibrate"), "pressed", G_CALLBACK(button_calibrate_pressed_cb), this);
// Added method to populate input field with the passed mac address
GtkEntry* entryMac = GTK_ENTRY(gtk_builder_get_object(m_pBuilderConfigureInterface, "entry_mac"));
gtk_entry_set_text(entryMac, m_macAddress.c_str());
// Read channel mask and check the boxes
int active = 0;
for (int i = 0; i < 6; ++i)
{
const int value = m_channelMask[i] - 48;
std::string result = "checkbutton_chn" + std::to_string(i + 1);
GtkToggleButton* toggleChannel = GTK_TOGGLE_BUTTON(gtk_builder_get_object(m_pBuilderConfigureInterface, result.c_str()));
gtk_toggle_button_set_active(toggleChannel, value);
active += value;
}
// Update number of channels
GtkSpinButton* l_pNChannels = GTK_SPIN_BUTTON(gtk_builder_get_object(m_pBuilderConfigureInterface, "spinbutton_number_of_channels"));
gtk_spin_button_set_value(l_pNChannels, active);
return true;
}
bool CConfigurationBITalino::postConfigure()
{
if (m_bApplyConfiguration)
{
// Added method change the mac address and channel mask.
GtkEntry* entryMac = GTK_ENTRY(gtk_builder_get_object(m_pBuilderConfigureInterface, "entry_mac"));
m_channelMask = "";
for (int i = 0; i < 6; ++i)
{
std::string result = "checkbutton_chn" + std::to_string(i + 1);
GtkToggleButton* toggleChannel = GTK_TOGGLE_BUTTON(gtk_builder_get_object(m_pBuilderConfigureInterface, result.c_str()));
m_channelMask += std::to_string(gtk_toggle_button_get_active(toggleChannel));
}
m_macAddress = gtk_entry_get_text(entryMac);
}
// normal header is filled (Subject ID, Age, Gender, channels, sampling frequency), ressources are realesed
return CConfigurationBuilder::postConfigure();
}
///-------------------------------------------------------------------------------------------------
///
/// \file ovasCConfigurationBITalino.h
/// \brief The CConfigurationBITalino handles the configuration dialog specific to the BITalino device.
/// \author Daniel Osorio (PLUX)
/// \version 1.0.
/// \date 12/04/2019.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------
#pragma once
#include "../ovasCConfigurationBuilder.h"
#include "ovasIDriver.h"
namespace OpenViBEAcquisitionServer
{
/// <summary> The CConfigurationBITalino handles the configuration dialog specific to the BITalino device. </summary>
/// @todo Update number of channels using callbacks(see pre configuration comments);
/// <seealso cref="CDriverBITalino" />
class CConfigurationBITalino : public CConfigurationBuilder
{
public:
// Added macAdress and channel mask references as inputs
CConfigurationBITalino(IDriverContext& driverContext, const char* gtkBuilderFileName, std::string& macAddress, std::string& channelMask);
bool preConfigure() override;
bool postConfigure() override;
protected:
IDriverContext& m_driverContext;
// Added a reference for the mac address and for the channel mask;
std::string& m_macAddress;
std::string& m_channelMask;
};
} // namespace OpenViBEAcquisitionServer
#include "ovasCDriverBITalino.h"
#include "ovasCConfigurationBITalino.h"
#include "bitalino.h"
#include <vector>
using namespace OpenViBEAcquisitionServer;
using namespace OpenViBE;
using namespace Kernel;
using namespace std;
//___________________________________________________________________//
// //
CDriverBITalino::CDriverBITalino(IDriverContext& rDriverContext)
: IDriver(rDriverContext), m_settings("AcquisitionServer_Driver_BITalino", m_rDriverContext.getConfigurationManager())
{
m_header.setSamplingFrequency(100);
m_header.setChannelCount(6);
m_settings.add("Header", &m_header);
// Added field for Mac Address of the device and saved it to settings;
m_macAddress = "XX:XX:XX:XX:XX:XX";
m_settings.add("MacAddress", &m_macAddress);
// Added channel mask and saved it to settings;
m_channelMask = "111111";
m_settings.add("ChannelMask", &m_channelMask);
m_settings.load();
}
const char* CDriverBITalino::getName() { return "BITalino"; }
//___________________________________________________________________//
// //
bool CDriverBITalino::initialize(const uint32_t sampleCountPerSentBlock, IDriverCallback& rCallback)
{
if (m_rDriverContext.isConnected() || !m_header.isChannelCountSet() || !m_header.isSamplingFrequencySet()) { return false; }
m_sample.resize(m_header.getChannelCount() * sampleCountPerSentBlock);
m_callback = &rCallback;
m_sampleCountPerBlock = sampleCountPerSentBlock;
cout << "[ BIT ] CONNECT. BIT MAC address : " << m_macAddress.c_str() << " Channel Count: " << std::to_string(m_header.getChannelCount()) << " Sampling Freq: " << std::to_string(m_header.getSamplingFrequency()) << "\n" << std::flush;
try
{
// Point device to a new BITalino with the MAC address from the properties;
m_device = new BITalino(m_macAddress.c_str());
cout << "[ BIT ] Connected" << std::endl;
const std::string ver = m_device->version(); // Get device version string
cout << "[ BIT ] BITalino version: " << ver << std::endl;
}
catch (BITalino::Exception& e)
{
// If device cannot be reached, return false (re enable the connect button);
cout << "[ BIT ] BITalino exception: " << e.getDescription() << std::endl;
return false;
}
return true;
}
bool CDriverBITalino::start()
{
if (!m_rDriverContext.isConnected() || m_rDriverContext.isStarted()) { return false; }
// Get channel array using channel mask
vector<int> channels;
for (int i = 0; i < 6; ++i)
{
if (int(m_channelMask[i]) - 48 == 1) { channels.push_back(i); }
}
// Create BITalino frame container
m_frames = new BITalino::vframe(int(m_sampleCountPerBlock));
try
{
// Start data aquisition
m_device->start(int(m_header.getSamplingFrequency()), channels);
cout << "[ BIT ] PLAY. BIT MAC address : " << m_macAddress.c_str() << " Channel Count: " << std::to_string(m_header.getChannelCount()) << " Sampling Freq: " << std::to_string(m_header.getSamplingFrequency()) << "\n" << std::flush;
return true;
}
catch (BITalino::Exception& e)
{
// If device cannot be reached, return false (re enable the connect button);
cout << "[ BIT ] BITalino exception: " << e.getDescription() << std::endl;
return false;
}
}
bool CDriverBITalino::loop()
{
if (!m_rDriverContext.isConnected()) { return false; }
if (!m_rDriverContext.isStarted()) { return true; }
try
{
// Try to read data from device
m_device->read(*m_frames);
}
catch (BITalino::Exception& e)
{
// If device cannot be reached, return false (re enable the connect button);
cout << "[ BIT ] BITalino exception: " << e.getDescription() << std::endl;
return false;
}
// Access data and put it in the right place in the m_pSample array
BITalino::vframe frames = *m_frames;
for (int i = 0; i < int(m_sampleCountPerBlock); ++i)
{
const BITalino::SFrame& f = frames[i];
for (int j = 0; j < int(m_header.getChannelCount()); ++j)
{
m_sample[i + j * int(m_sampleCountPerBlock)] = float(f.analog[j]);
}
}
// Send data
m_callback->setSamples(m_sample.data(), m_sampleCountPerBlock);
return true;
}
bool CDriverBITalino::stop()
{
if (!m_rDriverContext.isConnected() || !m_rDriverContext.isStarted()) { return false; }
// Send a stop aquisition signal to device, if device cannot be reached, return false (re enable the connect button)
try { m_device->stop(); }
catch (BITalino::Exception& e) { cout << "[ BIT ] BITalino exception: " << e.getDescription() << std::endl; }
cout << "\n[ BIT ] STOP. BIT MAC address : " << m_macAddress.c_str() << "\n" << std::flush;
return true;
}
bool CDriverBITalino::uninitialize()
{
if (!m_rDriverContext.isConnected() || m_rDriverContext.isStarted()) { return false; }
m_sample.clear();
m_callback = nullptr;
// Destroy current BITalino device, if device cannot be reached, return false (re enable the connect button);
try { m_device->~BITalino(); }
catch (BITalino::Exception& e) { cout << "[ BIT ] BITalino exception: " << e.getDescription() << std::endl; }
cout << "[ BIT ] DISCONNECT. BIT MAC address : " << m_macAddress.c_str() << "\n" << std::flush;
return true;
}
//___________________________________________________________________//
// //
bool CDriverBITalino::isConfigurable() { return true; } // change to false if your device is not configurable
bool CDriverBITalino::configure()
{
// Added field for Mac Address of the device and channel mask;
CConfigurationBITalino configuration(m_rDriverContext, Directories::getDataDir() + "/applications/acquisition-server/interface-BITalino.ui", m_macAddress, m_channelMask);
if (!configuration.configure(m_header)) { return false; }
// Update channel count based on channel mask;
int active = 0;
for (int i = 0; i < 6; ++i) { active += m_channelMask[i] - 48; }
m_header.setChannelCount(active);
m_settings.save();
cout << "[ BIT ] CONFIG. BIT MAC address : " << m_macAddress.c_str() << " Channel Count: " << std::to_string(m_header.getChannelCount()) << " Sampling Freq: " << std::to_string(m_header.getSamplingFrequency()) << "\n" << std::flush;
return true;
}
///-------------------------------------------------------------------------------------------------
///
/// \file ovasCDriverBITalino.h
/// \brief The CDriverBITalino allows the acquisition server to acquire data from a BITalino device.
/// \author Daniel Osorio (PLUX)
/// \version 1.0.
/// \date 12/04/2019.
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
///
///-------------------------------------------------------------------------------------------------
#pragma once
#include "ovasIDriver.h"
#include "../ovasCHeader.h"
#include <openvibe/ov_all.h>
#include "../ovasCSettingsHelper.h"
#include "../ovasCSettingsHelperOperators.h"
#include "bitalino.h"
namespace OpenViBEAcquisitionServer
{
/// <summary> The CDriverBITalino allows the acquisition server to acquire data from a BITalino device. </summary>
/// \todo Update number of channels using callbacks(see pre configuration comments);
/// <seealso cref="CDriverBITalino" />
class CDriverBITalino : public IDriver
{
public:
explicit CDriverBITalino(IDriverContext& rDriverContext);
~CDriverBITalino() override = default;
const char* getName() override;
bool initialize(uint32_t sampleCountPerSentBlock, IDriverCallback& rCallback) override;
bool uninitialize() override;
bool start() override;
bool stop() override;
bool loop() override;
bool isConfigurable() override;
bool configure() override;
const IHeader* getHeader() override { return &m_header; }
bool isFlagSet(const EDriverFlag eFlag) const override { return eFlag == DriverFlag_IsUnstable; }
protected:
SettingsHelper m_settings;
IDriverCallback* m_callback = nullptr;
CHeader m_header;
uint32_t m_sampleCountPerBlock = 0;
std::vector<float> m_sample;
private:
// Added a variable for the mac address;
std::string m_macAddress;
std::string m_channelMask;
// Added a pointer to make devices and frames
BITalino* m_device = nullptr;
BITalino::vframe* m_frames = nullptr;
};
} // namespace OpenViBEAcquisitionServer