AnyWave:BuildReader
One important thing with AnyWave is to be able to read a data file.
Although that AnyWave is able to read some common EEG or MEG file formats, you might need to read a particular data file.
The only way to achieve that is to build a Reader plug-in for AnyWave.
This will require implementing a C++ plug-in using the SDK.
See the previous sections of the Developer's corner to see how to build the SDK and use it to build a new plug-in.
Let's start with the basic cmake project that we will modify to suit our needs.
ADES reader as example
AnyWave is able to read .ades file format which is a simple file format built upon a text header file and a binary data file.
This 'plug-in' is embedded within AnyWave but we are going to implement it as an external plug-in, for the sake of demonstration.
Define the C++ classes
A C++ plug-in is defined by two classes:
- A class that describes the plug-in to AnyWave.
- A class that describes the core mechanism of the plug-in.
That is true for all kind of plug-ins in AnyWave.
AwReaderPlugin and AwFileReader classes
As mentioned above, two C++ classes must be described and implemented to build a Reader plug-in.
Here are the two classes, described within one header file:
#ifndef DESREADER_H #define DESREADER_H #include <AwReaderInterface.h> #include <QtCore> #include <QDataStream> class ADesReader : public AwFileReader // our class must derived from AwFileReader { Q_OBJECT // Q_OBJECT and Q_INTERFACES macro are specific to the Qt Framework. Q_INTERFACES(AwFileReader) // They indicate that the object is also derived from QObject and implements the Qt signals and slots mechanism. public: ADesReader(const QString& filename); ~ADesReader() { cleanUpAndClose(); } // The three methods above need to be implemented. There are virtuals method defined in AwFileReader. long readDataFromChannels(float start, float duration, QList<AwChannel *> &channelList); // This method will get data from the file and fill channels with them. FileStatus openFile(const QString &path); // This method will open the file and return a status. FileStatus canRead(const QString &path); // This method will check if the file format is correct and return a status. // The method above is optional but it is a good practice to implement it. void cleanUpAndClose(); // A cleanup method to clean memory and close the file. private: // Here we define variables and methods required by our plug-in. QFile m_headerFile; // A QFile to handle the text header file. QFile m_binFile; // A QFile to handle the binary data file. QTextStream m_headerStream; // A stream object to read the content of the header file. QDataStream m_binStream; // A stream object to read the content of the data file. float m_samplingRate; // A variable to store the global sampling rate. int m_nSamples; // A variable to store the number of samples. QString m_binPath; // A variable to store the file path to the binary data file. }; class ADesReaderPlugin : public AwReaderPlugin // The plugin class must derived from AwReaderPlugin { Q_OBJECT // Define the object as a QObject. The interface for the plugin must be AwReaderPlugin Q_INTERFACES(AwReaderPlugin) public: ADesReaderPlugin(); // The constructor ADesReader *newInstance(const QString& filename) { return new ADesReader(filename); } // MANDATORY method that must instantiate the AwFileReader derived class for our plug-in. }; #endif // DESREADER_H