Adrian is right. I want to make you aware of another patch set (see
attachment) which I recommend to add.
The patch is fixing an issue when importing an event file, and the
sample rate in the event file does not match the data file.
The patch set is currently maintained here
https://git.ist.ac.at/alois.schloegl/sigviewer
and corresponds to the last three patches (currently this 'git diff
7e26e4da 7303ba9d0' )
The changes have been sent to the maintainer (Clemens Brunner), but
there is no release yet.
I can contact the maintainer, or submit another bug report. The easiest
approach would be if you could just add the patch here.
Alois
On 11/14/20 11:08 PM, Adrian Bunk wrote:
On Sat, Nov 14, 2020 at 09:28:53PM +0100, Andreas Tille wrote:
Control: tags -1 pending
Control: tags 922571 pending
Hi,
I have moved sigviewer to Debian Med team[1], fixed the other bug and
tried to build the new upstream version 0.6.4 but failed:
...
g++ -c -pipe -g -O2 -fdebug-prefix-map=/build/sigviewer-0.6.4=.
-fstack-protector-strong -Wformat -Werror=format-security -Wdate-time
-D_FORTIFY_SOURCE=2 -std=gnu++11 -D_REENTRANT -Wall - Wextra -fPIC
-DVERSION_MAJOR=0 -DVERSION_MINOR=6 -DVERSION_BUILD=4 -DQT_NO_DEBUG_OUTPUT
-DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_XML_LIB -DQT_CORE_LIB -I.
-I/build/sigviewer-0.6.4/ external/include -Isrc
-I/usr/include/x86_64-linux-gnu/qt5
-I/usr/include/x86_64-linux-gnu/qt5/QtWidgets
-I/usr/include/x86_64-linux-gnu/qt5/QtGui -I/usr/include/x86_64-linux-gnu/qt5/
QtXml -I/usr/include/x86_64-linux-gnu/qt5/QtCore -Itmp/release
-Itmp/release -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o
tmp/release/undo_redo_gui_command.o src/gui_impl/commands/
undo_redo_gui_command.cpp
src/gui_impl/commands/open_file_gui_command.cpp: In member function 'void
sigviewer::OpenFileGuiCommand::importEvents()':
src/gui_impl/commands/open_file_gui_command.cpp:200:23: error: redeclaration of
'sigviewer::FileSignalReader* file_signal_reader'
200 | FileSignalReader* file_signal_reader =
FileSignalReaderFactory::getInstance()->getHandler (file_path);
| ^~~~~~~~~~~~~~~~~~
src/gui_impl/commands/open_file_gui_command.cpp:185:23: note:
'sigviewer::FileSignalReader* file_signal_reader' previously declared here
185 | FileSignalReader* file_signal_reader =
FileSignalReaderFactory::getInstance()->getHandler (file_path);
| ^~~~~~~~~~~~~~~~~~
make[1]: *** [Makefile:2576: tmp/release/open_file_gui_command.o] Error 1
Any help would be welcome
This is from 0002-add-support-for-reading-GDF-formated-event-file.patch,
which seems to be upstream now - and adding the same code twice is what
failed.
Andreas.
cu
Adrian
diff --git a/src/file_handling_impl/biosig_reader.cpp b/src/file_handling_impl/biosig_reader.cpp
index 41fce69..42c12ae 100644
--- a/src/file_handling_impl/biosig_reader.cpp
+++ b/src/file_handling_impl/biosig_reader.cpp
@@ -121,10 +121,6 @@ QString BioSigReader::open (QString const& file_name)
QString BioSigReader::loadFixedHeader(const QString& file_name)
{
QMutexLocker locker (&biosig_access_lock_);
- char *c_file_name = new char[file_name.length() + 1];
- strcpy (c_file_name, file_name.toLocal8Bit ().data());
- c_file_name[file_name.length()] = '\0';
-
tzset();
if(biosig_header_==NULL)
@@ -134,7 +130,7 @@ QString BioSigReader::loadFixedHeader(const QString& file_name)
biosig_header_->FLAG.OVERFLOWDETECTION = 1;
}
- biosig_header_ = sopen(c_file_name, "r", biosig_header_ );
+ biosig_header_ = sopen(file_name.toStdString().c_str(), "r", biosig_header_ );
basic_header_ = QSharedPointer<BasicHeader>
(new BiosigBasicHeader (biosig_header_, file_name));
@@ -145,8 +141,6 @@ QString BioSigReader::loadFixedHeader(const QString& file_name)
destructHDR(biosig_header_);
biosig_header_ = NULL;
- delete[] c_file_name;
-
qDebug() << "File doesn't exist.";
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Warning);
@@ -167,17 +161,11 @@ QString BioSigReader::loadFixedHeader(const QString& file_name)
destructHDR(biosig_header_);
biosig_header_ = NULL;
- delete[] c_file_name;
-
return "file not supported";
}
convert2to4_eventtable(biosig_header_);
- delete[] c_file_name;
-
- c_file_name = NULL;
-
basic_header_->setNumberEvents(biosig_header_->EVENT.N);
if (biosig_header_->EVENT.SampleRate)
diff --git a/src/gui_impl/commands/open_file_gui_command.cpp b/src/gui_impl/commands/open_file_gui_command.cpp
index 094e1d9..d7ed693 100644
--- a/src/gui_impl/commands/open_file_gui_command.cpp
+++ b/src/gui_impl/commands/open_file_gui_command.cpp
@@ -2,7 +2,7 @@
// Licensed under the GNU General Public License (GPL)
// https://www.gnu.org/licenses/gpl
-
+#include <biosig.h>
#include "open_file_gui_command.h"
#include "gui_impl/gui_helper_functions.h"
@@ -182,26 +182,85 @@ void OpenFileGuiCommand::importEvents ()
if (file_path.isEmpty())
return;
- FileSignalReader* file_signal_reader = FileSignalReaderFactory::getInstance()->getHandler (file_path);
- if (file_signal_reader != 0) {
- QList<QSharedPointer<SignalEvent const> > events = file_signal_reader->getEvents ();
- QSharedPointer<EventManager> event_manager = applicationContext()->getCurrentFileContext()->getEventManager();
- QList<QSharedPointer<QUndoCommand> > creation_commands;
- foreach (QSharedPointer<SignalEvent const> event, events) {
- QSharedPointer<QUndoCommand> creation_command (new NewEventUndoCommand (event_manager, event));
- creation_commands.append (creation_command);
- }
- MacroUndoCommand* macro_command = new MacroUndoCommand (creation_commands);
- applicationContext()->getCurrentCommandExecuter()->executeCommand (macro_command);
- delete file_signal_reader;
- return;
- }
+ QList<QSharedPointer<SignalEvent const> > events;
+ QSharedPointer<EventManager> event_manager = applicationContext()->getCurrentFileContext()->getEventManager();
+ double sampleRate = event_manager->getSampleRate();
+ std::set<EventType> types = event_manager->getEventTypes();
+ int numberChannels = applicationContext()->getCurrentFileContext()->getChannelManager().getNumberChannels();
+
+ // try reading event file through biosig
+ HDRTYPE* evtHDR = sopen(file_path.toStdString().c_str(), "r", NULL );
+ if (!serror2(evtHDR)) {
+ /* Note: evtSampleRate and transition rate can be NaN,
+ indicating sample rate is not specified in event file
+ */
+ double evtSampleRate = biosig_get_eventtable_samplerate(evtHDR);
+ double transition_rate = sampleRate / evtSampleRate;
+ size_t NumEvents = biosig_get_number_of_events(evtHDR);
+ for (size_t k = 0; k < NumEvents; k++) {
+ uint16_t typ; uint32_t pos; uint16_t chn; uint32_t dur;
+ gdf_time timestamp;
+ const char *desc;
+ biosig_get_nth_event(evtHDR, k, &typ, &pos, &chn, &dur, ×tamp, &desc);
+
+ if (transition_rate > 0) {
+ pos = lround(pos*transition_rate);
+ dur = lround(dur*transition_rate);
+ }
- std::fstream file;
- file.open(file_path.toStdString());
+ if (typ <= 254 && do_not_show_warning_message == false) {
+ QMessageBox msgBox;
+ msgBox.setText("Currently customized event text cannot be properly imported.");
+ msgBox.setIcon(QMessageBox::Warning);
+ msgBox.addButton(QMessageBox::Ok);
+ msgBox.addButton(QMessageBox::Cancel);
+ msgBox.setDefaultButton(QMessageBox::Cancel);
+ QCheckBox* dontShowCheckBox = new QCheckBox("Don't show this message again");
+ msgBox.setCheckBox(dontShowCheckBox);
+ int32_t userReply = msgBox.exec();
+ if (userReply == QMessageBox::Ok) {
+ if(dontShowCheckBox->checkState() == Qt::Checked) {
+ QSettings settings;
+ settings.setValue("DoNotShowWarningMessage", true);
+ do_not_show_warning_message = true;
+ }
+ }
+ else if (userReply == QMessageBox::Cancel) {
+ if(dontShowCheckBox->checkState() == Qt::Checked) {
+ QSettings settings;
+ settings.setValue("DoNotShowWarningMessage", true);
+ do_not_show_warning_message = true;
+ }
+ destructHDR(evtHDR);
+ return;
+ }
+ }
+
+ /* biosig uses a 1-based channel index, and 0 refers to all channels,
+ sigviewer uses a 0-based indexing, and -1 indicates all channels */
+ //boundary check & error handling
+ if (pos > event_manager->getMaxEventPosition()
+ || pos + dur > event_manager->getMaxEventPosition()
+ || chn > numberChannels
+ || !types.count(typ))
+ continue;
- if (file.is_open())
+ QSharedPointer<SignalEvent> event = QSharedPointer<SignalEvent>(new SignalEvent(pos,
+ typ, sampleRate, -1, chn-1, dur));
+
+ events << event;
+ }
+ sclose(evtHDR);
+ destructHDR(evtHDR);
+ } else
{
+ // if the file can not be read with biosig, try this approach
+ destructHDR(evtHDR);
+#if BIOSIG_VERSION<10903
+ std::fstream file;
+ file.open(file_path.toStdString());
+
+ if (file.is_open()) {
std::string line;
std::getline(file, line);
@@ -211,13 +270,6 @@ void OpenFileGuiCommand::importEvents ()
return;
}
- QList<QSharedPointer<SignalEvent const> > events;
- QSharedPointer<EventManager> event_manager
- = applicationContext()->getCurrentFileContext()->getEventManager();
- double sampleRate = event_manager->getSampleRate();
- std::set<EventType> types = event_manager->getEventTypes();
- int numberChannels = applicationContext()->getCurrentFileContext()->getChannelManager().getNumberChannels();
-
while (std::getline(file, line))
{
QStringList Qline = QString::fromStdString(line).split(',');
@@ -274,22 +326,25 @@ void OpenFileGuiCommand::importEvents ()
events << event;
}
-
-
- QList<QSharedPointer<QUndoCommand> > creation_commands;
- foreach (QSharedPointer<SignalEvent const> event, events)
- {
- QSharedPointer<QUndoCommand> creation_command (new NewEventUndoCommand (event_manager, event));
- creation_commands.append (creation_command);
- }
- MacroUndoCommand* macro_command = new MacroUndoCommand (creation_commands);
- applicationContext()->getCurrentCommandExecuter()->executeCommand (macro_command);
}
else
{
+#endif
QMessageBox::critical(0, file_path, tr("Cannot open file.\nIs the target file open in another application?"));
return;
+#if BIOSIG_VERSION<10903
+ }
+#endif
+ }
+
+ QList<QSharedPointer<QUndoCommand> > creation_commands;
+ foreach (QSharedPointer<SignalEvent const> event, events)
+ {
+ QSharedPointer<QUndoCommand> creation_command (new NewEventUndoCommand (event_manager, event));
+ creation_commands.append (creation_command);
}
+ MacroUndoCommand* macro_command = new MacroUndoCommand (creation_commands);
+ applicationContext()->getCurrentCommandExecuter()->executeCommand (macro_command);
}
//-------------------------------------------------------------------------