From dfcf50041d9efdda3c045623fa49176f8f6e077d Mon Sep 17 00:00:00 2001 From: Teuniz Date: Sun, 14 May 2017 18:16:49 +0200 Subject: [PATCH] Added Record & Playback function. --- dsremote.pro | 2 + global.h | 20 ++- interface.cpp | 93 ++++++++++ mainwindow.cpp | 42 +++++ mainwindow.h | 7 + notes.txt | 12 +- playback_dialog.cpp | 360 +++++++++++++++++++++++++++++++++++++++ playback_dialog.h | 115 +++++++++++++ read_settings_thread.cpp | 162 ++++++++++++++++++ screen_thread.cpp | 160 +++++++++++++++++ screen_thread.h | 7 + signalcurve.cpp | 42 +++++ signalcurve.h | 1 + tmc_dev.c | 7 +- tmc_lan.c | 7 +- 15 files changed, 1030 insertions(+), 7 deletions(-) create mode 100644 playback_dialog.cpp create mode 100644 playback_dialog.h diff --git a/dsremote.pro b/dsremote.pro index 7ff2ad3..263a801 100644 --- a/dsremote.pro +++ b/dsremote.pro @@ -60,6 +60,7 @@ HEADERS += decode_dialog.h HEADERS += tdial.h HEADERS += wave_dialog.h HEADERS += wave_view.h +HEADERS += playback_dialog.h HEADERS += third_party/kiss_fft/kiss_fft.h HEADERS += third_party/kiss_fft/_kiss_fft_guts.h @@ -89,6 +90,7 @@ SOURCES += decode_dialog.cpp SOURCES += tdial.cpp SOURCES += wave_dialog.cpp SOURCES += wave_view.cpp +SOURCES += playback_dialog.cpp SOURCES += third_party/kiss_fft/kiss_fft.c SOURCES += third_party/kiss_fft/kiss_fftr.c diff --git a/global.h b/global.h index 0ec02ee..60d48c0 100644 --- a/global.h +++ b/global.h @@ -35,7 +35,7 @@ #define PROGRAM_NAME "DSRemote" -#define PROGRAM_VERSION "0.34_1702162027" +#define PROGRAM_VERSION "0.35_1705141814" #define MAX_PATHLEN 4096 @@ -256,7 +256,7 @@ struct device_settings struct waveform_preamble preamble; char cmd_cue[TMC_CMD_CUE_SZ][128]; - + char *cmd_cue_resp[TMC_CMD_CUE_SZ]; int cmd_cue_idx_in; int cmd_cue_idx_out; @@ -283,6 +283,22 @@ struct device_settings int wave_mem_view_enabled; double viewer_center_position; + + int func_wrec_enable; + int func_wrec_fend; + int func_wrec_fmax; + double func_wrec_fintval; + int func_wrec_prompt; + int func_wrec_operate; + int func_wplay_fstart; + int func_wplay_fend; + int func_wplay_fmax; + double func_wplay_fintval; + int func_wplay_mode; + int func_wplay_dir; + int func_wplay_operate; + int func_wplay_fcur; + int func_has_record; }; diff --git a/interface.cpp b/interface.cpp index 2407dd7..1e6ddf7 100644 --- a/interface.cpp +++ b/interface.cpp @@ -568,6 +568,11 @@ void UI_Mainwindow::horScaleDialChanged(int new_pos) horScaleDial_timer->start(TMC_DIAL_TIMER_DELAY); old_pos = new_pos; + + if(devparms.timebasedelayscale > 0.1000001) + { + devparms.func_wrec_enable = 0; + } } else { @@ -644,6 +649,11 @@ void UI_Mainwindow::horScaleDialChanged(int new_pos) horScaleDial_timer->start(TMC_DIAL_TIMER_DELAY); old_pos = new_pos; + + if(devparms.timebasescale > 0.1000001) + { + devparms.func_wrec_enable = 0; + } } waveForm->update(); @@ -1832,6 +1842,89 @@ void UI_Mainwindow::set_grading_inf() void UI_Mainwindow::utilButtonClicked() { + QMenu menu; + + menu.addAction("Record", this, SLOT(show_playback_window())); + + menu.exec(utilButton->mapToGlobal(QPoint(0,0))); +} + + +void UI_Mainwindow::show_playback_window() +{ + UI_playback_window w(this); +} + + +void UI_Mainwindow::playpauseButtonClicked() +{ + if(devparms.func_wrec_enable == 0) return; + + if(devparms.func_wrec_operate) return; + + if(devparms.func_has_record == 0) return; + + if(devparms.func_wplay_operate == 1) + { + devparms.func_wplay_operate = 2; + + statusLabel->setText("Replay paused"); + + set_cue_cmd(":FUNC:WREP:OPER PAUS"); + } + else + { + devparms.func_wplay_operate = 1; + + devparms.func_wplay_fcur = 0; + + statusLabel->setText("Replay on"); + + set_cue_cmd(":FUNC:WREP:OPER PLAY"); + } +} + + +void UI_Mainwindow::stopButtonClicked() +{ + if(devparms.func_wrec_enable == 0) return; + + if(devparms.func_wrec_operate) + { + statusLabel->setText("Record off"); + + set_cue_cmd(":FUNC:WREC:OPER STOP"); + } + + if(devparms.func_wplay_operate) + { + statusLabel->setText("Replay off"); + + set_cue_cmd(":FUNC:WREP:OPER STOP"); + } +} + + +void UI_Mainwindow::recordButtonClicked() +{ + if(devparms.func_wrec_enable == 0) return; + + if(devparms.func_wplay_operate) return; + + if(devparms.func_wrec_operate) return; + + statusLabel->setText("Record on"); + + if(devparms.modelserie == 6) + { + set_cue_cmd(":FUNC:WREC:OPER REC"); + } + else + { + set_cue_cmd(":FUNC:WREC:OPER RUN"); + } + + devparms.func_has_record = 1; } diff --git a/mainwindow.cpp b/mainwindow.cpp index b0ee406..704cd2a 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -341,6 +341,8 @@ void UI_Mainwindow::open_connection() devparms.cmd_cue_idx_in = 0; devparms.cmd_cue_idx_out = 0; + devparms.func_has_record = 0; + devparms.fftbufsz = devparms.hordivisions * 50; if(devparms.k_cfg != NULL) @@ -397,6 +399,10 @@ void UI_Mainwindow::open_connection() connect(trigAdjustDial, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(trigAdjustDialClicked(QPoint))); connect(adjDial, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(adjustDialClicked(QPoint))); + connect(playpauseButton, SIGNAL(clicked()), this, SLOT(playpauseButtonClicked())); + connect(stopButton, SIGNAL(clicked()), this, SLOT(stopButtonClicked())); + connect(recordButton, SIGNAL(clicked()), this, SLOT(recordButtonClicked())); + sprintf(str, PROGRAM_NAME " " PROGRAM_VERSION " %s %s %s", devparms.serialnr, devparms.softwvers, dev_str); // sprintf(str, PROGRAM_NAME " " PROGRAM_VERSION " %s %s", @@ -517,6 +523,10 @@ void UI_Mainwindow::close_connection() disconnect(trigAdjustDial, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(trigAdjustDialClicked(QPoint))); disconnect(adjDial, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(adjustDialClicked(QPoint))); + disconnect(playpauseButton, SIGNAL(clicked()), this, SLOT(playpauseButtonClicked())); + disconnect(stopButton, SIGNAL(clicked()), this, SLOT(stopButtonClicked())); + disconnect(recordButton, SIGNAL(clicked()), this, SLOT(recordButtonClicked())); + scrn_thread->set_device(NULL); devparms.math_fft = 0; @@ -1838,6 +1848,11 @@ void UI_Mainwindow::zoom_out() sprintf(str, ":TIM:DEL:SCAL %e", devparms.timebasedelayscale); set_cue_cmd(str); + + if(devparms.timebasedelayscale > 0.1000001) + { + devparms.func_wrec_enable = 0; + } } else { @@ -1863,6 +1878,11 @@ void UI_Mainwindow::zoom_out() sprintf(str, ":TIM:SCAL %e", devparms.timebasescale); set_cue_cmd(str); + + if(devparms.timebasescale > 0.1000001) + { + devparms.func_wrec_enable = 0; + } } waveForm->update(); @@ -2440,6 +2460,8 @@ void UI_Mainwindow::set_to_factory() devparms.countersrc = 0; + devparms.func_wrec_enable = 0; + statusLabel->setText("Reset to factory settings"); waveForm->update(); @@ -2646,6 +2668,26 @@ void UI_Mainwindow::set_cue_cmd(const char *str) devparms.cmd_cue[devparms.cmd_cue_idx_in][127] = 0; + devparms.cmd_cue_resp[devparms.cmd_cue_idx_in] = NULL; + + devparms.cmd_cue_idx_in++; + + devparms.cmd_cue_idx_in %= TMC_CMD_CUE_SZ; + + scrn_timer_handler(); +} + + +void UI_Mainwindow::set_cue_cmd(const char *str, char *ptr) +{ + strncpy(devparms.cmd_cue[devparms.cmd_cue_idx_in], str, 128); + + devparms.cmd_cue[devparms.cmd_cue_idx_in][127] = 0; + + ptr[0] = 0; + + devparms.cmd_cue_resp[devparms.cmd_cue_idx_in] = ptr; + devparms.cmd_cue_idx_in++; devparms.cmd_cue_idx_in %= TMC_CMD_CUE_SZ; diff --git a/mainwindow.h b/mainwindow.h index 7eca52c..6a5993f 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -91,6 +91,7 @@ #include "decode_dialog.h" #include "tdial.h" #include "wave_dialog.h" +#include "playback_dialog.h" #include "third_party/kiss_fft/kiss_fftr.h" @@ -112,6 +113,7 @@ public: void read_settings(void); void write_settings(void); void set_cue_cmd(const char *); + void set_cue_cmd(const char *, char *); void serial_decoder(struct device_settings *); void save_wave_inspector_buffer_to_edf(struct device_settings *); @@ -464,6 +466,11 @@ private slots: void show_decode_window(); + void show_playback_window(); + void playpauseButtonClicked(); + void stopButtonClicked(); + void recordButtonClicked(); + void updateLabels(); protected: diff --git a/notes.txt b/notes.txt index 67f218e..eed69a4 100644 --- a/notes.txt +++ b/notes.txt @@ -1,5 +1,11 @@ +DSRemote 0.35 +------------- + +Added Record & Playback function + + DSRemote 0.34 ------------- @@ -131,7 +137,7 @@ What's implemented so far: - save screenshot - save display data -- save memory data +- save memory data (via the Wave Inspector) fileformat for waveform data is EDF, these files can be read by lots of viewers and analyzing software like EDFbrowser, Scilab, Octave, Matlab, Labview, etc. @@ -151,10 +157,10 @@ What's implemented so far: using the above described keyboard shortcuts or the slider at the bottom of the screen. - Serial Decoder - This is a work in progress. So far, only UART and SPI are imlemented. + This is a work in progress. So far, only UART and SPI are implemented. Stay tuned for updates. - +- Record & Replay (it's hidden under the "util" button) diff --git a/playback_dialog.cpp b/playback_dialog.cpp new file mode 100644 index 0000000..99d8e48 --- /dev/null +++ b/playback_dialog.cpp @@ -0,0 +1,360 @@ +/* +*************************************************************************** +* +* Author: Teunis van Beelen +* +* Copyright (C) 2017 Teunis van Beelen +* +* Email: teuniz@gmail.com +* +*************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*************************************************************************** +*/ + + +#include "playback_dialog.h" + + + +UI_playback_window::UI_playback_window(QWidget *w_parent) +{ + mainwindow = (UI_Mainwindow *)w_parent; + + devparms = &mainwindow->devparms; + + mainwindow->set_cue_cmd(":FUNC:WREC:FMAX?", rec_fmax_resp); + mainwindow->set_cue_cmd(":FUNC:WREC:FEND?", rec_fend_resp); + mainwindow->set_cue_cmd(":FUNC:WREC:FINT?", rec_fint_resp); + mainwindow->set_cue_cmd(":FUNC:WREP:FST?", rep_fstart_resp); + mainwindow->set_cue_cmd(":FUNC:WREP:FEND?", rep_fend_resp); + mainwindow->set_cue_cmd(":FUNC:WREP:FMAX?", rep_fmax_resp); + mainwindow->set_cue_cmd(":FUNC:WREP:FINT?", rep_fint_resp); + + setWindowTitle("Record/Playback"); + + setMinimumSize(420, 300); + setMaximumSize(420, 300); + + rec_fend_label = new QLabel(this); + rec_fend_label->setGeometry(20, 20, 150, 25); + rec_fend_label->setText("Recording Length"); + + rec_fend_spinbox = new QSpinBox(this); + rec_fend_spinbox->setGeometry(200, 20, 140, 25); + rec_fend_spinbox->setSuffix(" frames"); + if(!devparms->func_wrec_enable) + { + rec_fend_spinbox->setEnabled(false); + } + + rec_fint_label = new QLabel(this); + rec_fint_label->setGeometry(20, 65, 150, 25); + rec_fint_label->setText("Recording Interval"); + + rec_fint_spinbox = new QDoubleSpinBox(this); + rec_fint_spinbox->setGeometry(200, 65, 140, 25); + rec_fint_spinbox->setDecimals(7); + rec_fint_spinbox->setRange(1e-7, 10); + rec_fint_spinbox->setSuffix(" Sec."); + if(!devparms->func_wrec_enable) + { + rec_fint_spinbox->setEnabled(false); + } + + rep_fstart_label = new QLabel(this); + rep_fstart_label->setGeometry(20, 110, 150, 25); + rep_fstart_label->setText("Playback Start Frame"); + + rep_fstart_spinbox = new QSpinBox(this); + rep_fstart_spinbox->setGeometry(200, 110, 140, 25); + if(!devparms->func_has_record || !devparms->func_wrec_enable) + { + rep_fstart_spinbox->setEnabled(false); + } + + rep_fend_label = new QLabel(this); + rep_fend_label->setGeometry(20, 155, 150, 25); + rep_fend_label->setText("Playback End Frame"); + + rep_fend_spinbox = new QSpinBox(this); + rep_fend_spinbox->setGeometry(200, 155, 140, 25); + if(!devparms->func_has_record || !devparms->func_wrec_enable) + { + rep_fend_spinbox->setEnabled(false); + } + + rep_fint_label = new QLabel(this); + rep_fint_label->setGeometry(20, 200, 150, 25); + rep_fint_label->setText("Playback Interval"); + + rep_fint_spinbox = new QDoubleSpinBox(this); + rep_fint_spinbox->setGeometry(200, 200, 140, 25); + rep_fint_spinbox->setDecimals(7); + rep_fint_spinbox->setRange(1e-7, 10); + rep_fint_spinbox->setSuffix(" Sec."); + if(!devparms->func_has_record || !devparms->func_wrec_enable) + { + rep_fint_spinbox->setEnabled(false); + } + + toggle_playback_button = new QPushButton(this); + toggle_playback_button->setGeometry(20, 255, 100, 25); + if(devparms->func_wrec_enable == 1) + { + toggle_playback_button->setText("Disable"); + } + else + { + toggle_playback_button->setText("Enable"); + } + toggle_playback_button->setAutoDefault(false); + toggle_playback_button->setDefault(false); + toggle_playback_button->setEnabled(false); + + close_button = new QPushButton(this); + close_button->setGeometry(300, 255, 100, 25); + close_button->setText("Close"); + close_button->setAutoDefault(false); + close_button->setDefault(false); + + t1 = new QTimer(this); + + connect(close_button, SIGNAL(clicked()), this, SLOT(close())); + connect(toggle_playback_button, SIGNAL(clicked()), this, SLOT(toggle_playback())); + connect(t1, SIGNAL(timeout()), this, SLOT(t1_func())); + + t1->start(100); + + exec(); +} + + +void UI_playback_window::t1_func() +{ + if((rep_fint_resp[0] == 0) || + (rep_fmax_resp[0] == 0) || + (rep_fend_resp[0] == 0) || + (rep_fstart_resp[0] == 0) || + (rec_fend_resp[0] == 0) || + (rec_fmax_resp[0] == 0) || + (rec_fint_resp[0] == 0)) + { + return; + } + + t1->stop(); + + devparms->func_wrec_fmax = atoi(rec_fmax_resp); + + devparms->func_wrec_fend = atoi(rec_fend_resp); + + devparms->func_wrec_fintval = atof(rec_fint_resp); + + devparms->func_wplay_fstart = atoi(rep_fstart_resp); + + devparms->func_wplay_fend = atoi(rep_fend_resp); + + devparms->func_wplay_fmax = atoi(rep_fmax_resp); + + devparms->func_wplay_fintval = atof(rep_fint_resp); + + rec_fend_spinbox->setRange(1, devparms->func_wrec_fmax); + rec_fend_spinbox->setValue(devparms->func_wrec_fend); + rec_fint_spinbox->setValue(devparms->func_wrec_fintval); + rep_fstart_spinbox->setValue(devparms->func_wplay_fstart); + rep_fend_spinbox->setRange(1, devparms->func_wrec_fend); + rep_fend_spinbox->setValue(devparms->func_wplay_fend); + rep_fint_spinbox->setValue(devparms->func_wplay_fintval); + + connect(rec_fend_spinbox, SIGNAL(valueChanged(int)), this, SLOT(rec_fend_spinbox_changed(int))); + connect(rec_fint_spinbox, SIGNAL(valueChanged(double)), this, SLOT(rec_fint_spinbox_changed(double))); + connect(rep_fstart_spinbox, SIGNAL(valueChanged(int)), this, SLOT(rep_fstart_spinbox_changed(int))); + connect(rep_fend_spinbox, SIGNAL(valueChanged(int)), this, SLOT(rep_fend_spinbox_changed(int))); + connect(rep_fint_spinbox, SIGNAL(valueChanged(double)), this, SLOT(rep_fint_spinbox_changed(double))); + + toggle_playback_button->setEnabled(true); +} + + +void UI_playback_window::toggle_playback() +{ + QMessageBox msgBox; + msgBox.setText("Timebase scale must be <= 100mS."); + + if(devparms->func_wrec_enable == 0) + { + if(devparms->timebasedelayenable) + { + if(devparms->timebasedelayscale > 0.1000001) + { + msgBox.exec(); + return; + } + } + else + { + if(devparms->timebasescale > 0.1000001) + { + msgBox.exec(); + return; + } + } + + devparms->func_wrec_enable = 1; + + toggle_playback_button->setText("Disable"); + + rec_fend_spinbox->setEnabled(true); + + rec_fint_spinbox->setEnabled(true); + + mainwindow->statusLabel->setText("Recording enabled"); + + if(devparms->modelserie != 6) + { + mainwindow->set_cue_cmd(":FUNC:WREC:ENAB ON"); + } + } + else + { + devparms->func_wrec_enable = 0; + + devparms->func_has_record = 0; + + rec_fend_spinbox->setEnabled(false); + + rec_fint_spinbox->setEnabled(false); + + rep_fstart_spinbox->setEnabled(false); + + rep_fend_spinbox->setEnabled(false); + + rep_fint_spinbox->setEnabled(false); + + mainwindow->statusLabel->setText("Recording disabled"); + + toggle_playback_button->setText("Enable"); + + if(devparms->modelserie != 6) + { + mainwindow->set_cue_cmd(":FUNC:WREC:ENAB OFF"); + } + } +} + + +void UI_playback_window::rec_fend_spinbox_changed(int fend) +{ + char str[128]; + + sprintf(str, "Recording frame end: %i", fend); + + mainwindow->statusLabel->setText(str); + + sprintf(str, ":FUNC:WREC:FEND %i", fend); + + mainwindow->set_cue_cmd(str); +} + + +void UI_playback_window::rec_fint_spinbox_changed(double fint) +{ + char str[128]; + + strcpy(str, "Recording frame interval: "); + + convert_to_metric_suffix(str + strlen(str), 3, fint); + + strcat(str, "S"); + + sprintf(str, ":FUNC:WREC:FINT %e", fint); + + mainwindow->set_cue_cmd(str); +} + + +void UI_playback_window::rep_fstart_spinbox_changed(int fstart) +{ + char str[128]; + + sprintf(str, "Playback frame start: %i", fstart); + + mainwindow->statusLabel->setText(str); + + sprintf(str, ":FUNC:WREP:FST %i", fstart); + + mainwindow->set_cue_cmd(str); +} + + +void UI_playback_window::rep_fend_spinbox_changed(int fend) +{ + char str[128]; + + sprintf(str, "Playback frame end: %i", fend); + + mainwindow->statusLabel->setText(str); + + sprintf(str, ":FUNC:WREP:FEND %i", fend); + + mainwindow->set_cue_cmd(str); +} + + +void UI_playback_window::rep_fint_spinbox_changed(double fint) +{ + char str[128]; + + strcpy(str, "Playback frame interval: "); + + convert_to_metric_suffix(str + strlen(str), 3, fint); + + strcat(str, "S"); + + mainwindow->statusLabel->setText(str); + + sprintf(str, ":FUNC:WREP:FINT %e", fint); + + mainwindow->set_cue_cmd(str); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/playback_dialog.h b/playback_dialog.h new file mode 100644 index 0000000..5b4c5e3 --- /dev/null +++ b/playback_dialog.h @@ -0,0 +1,115 @@ +/* +*************************************************************************** +* +* Author: Teunis van Beelen +* +* Copyright (C) 2017 Teunis van Beelen +* +* Email: teuniz@gmail.com +* +*************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*************************************************************************** +*/ + + +#ifndef UI_PLAYBACK_DIALOG_H +#define UI_PLAYBACK_DIALOG_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "global.h" +#include "mainwindow.h" +#include "utils.h" + + + +class UI_Mainwindow; + + + +class UI_playback_window : public QDialog +{ + Q_OBJECT + +public: + UI_playback_window(QWidget *parent); + + UI_Mainwindow *mainwindow; + +private: + + QLabel *rec_fend_label, + *rec_fint_label, + *rep_fstart_label, + *rep_fend_label, + *rep_fint_label; + + QSpinBox *rec_fend_spinbox, + *rep_fstart_spinbox, + *rep_fend_spinbox; + + QDoubleSpinBox *rec_fint_spinbox, + *rep_fint_spinbox; + + QPushButton *close_button, + *toggle_playback_button; + + QTimer *t1; + + struct device_settings *devparms; + + char rec_fmax_resp[128], + rec_fend_resp[128], + rec_fint_resp[128], + rep_fstart_resp[128], + rep_fend_resp[128], + rep_fint_resp[128], + rep_fmax_resp[128]; + +private slots: + + void toggle_playback(); + void t1_func(); + void rec_fend_spinbox_changed(int); + void rec_fint_spinbox_changed(double); + void rep_fstart_spinbox_changed(int); + void rep_fend_spinbox_changed(int); + void rep_fint_spinbox_changed(double); +}; + + +#endif + + + + + + diff --git a/read_settings_thread.cpp b/read_settings_thread.cpp index 77d837c..6059691 100644 --- a/read_settings_thread.cpp +++ b/read_settings_thread.cpp @@ -2588,6 +2588,168 @@ void read_settings_thread::run() devparms->math_decode_spi_end = 1; } + usleep(TMC_GDS_DELAY); + + if(devparms->modelserie != 6) + { + if(tmc_write(":FUNC:WREC:ENAB?") != 16) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(!strcmp(device->buf, "1")) + { + devparms->func_wrec_enable = 1; + } + else if(!strcmp(device->buf, "0")) + { + devparms->func_wrec_enable = 0; + } + else + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + } + + if(devparms->func_wrec_enable) + { + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREC:FEND?") != 16) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + devparms->func_wrec_fend = atoi(device->buf); + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREC:FMAX?") != 16) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + devparms->func_wrec_fmax = atoi(device->buf); + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREC:FINT?") != 16) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + devparms->func_wrec_fintval = atof(device->buf); + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREP:FST?") != 15) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + devparms->func_wplay_fstart = atoi(device->buf); + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREP:FEND?") != 16) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + devparms->func_wplay_fend = atoi(device->buf); + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREP:FMAX?") != 16) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + devparms->func_wplay_fmax = atoi(device->buf); + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREP:FINT?") != 16) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + devparms->func_wplay_fintval = atof(device->buf); + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREP:FCUR?") != 16) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto GDS_OUT_ERROR; + } + + devparms->func_wplay_fcur = atoi(device->buf); + } + err_num = 0; return; diff --git a/screen_thread.cpp b/screen_thread.cpp index 62cfeed..bb2a933 100644 --- a/screen_thread.cpp +++ b/screen_thread.cpp @@ -98,6 +98,12 @@ void screen_thread::set_params(struct device_settings *dev_parms) params.kiss_fftbuf = deviceparms->kiss_fftbuf; params.current_screen_sf = deviceparms->current_screen_sf; params.debug_str[0] = 0; + params.func_wrec_enable = deviceparms->func_wrec_enable; + params.func_wrec_operate = deviceparms->func_wrec_operate; + params.func_wplay_operate = deviceparms->func_wplay_operate; + params.func_wplay_fcur = deviceparms->func_wplay_fcur; + params.func_wrec_fmax = deviceparms->func_wrec_fmax; + params.func_wrep_fmax = deviceparms->func_wplay_fmax; } @@ -138,6 +144,14 @@ void screen_thread::get_params(struct device_settings *dev_parms) dev_parms->math_fft_hscale = params.math_fft_hscale; dev_parms->math_fft_hcenter = params.math_fft_hcenter; } + if(dev_parms->func_wrec_enable) + { + dev_parms->func_wrec_operate = params.func_wrec_operate; + dev_parms->func_wplay_operate = params.func_wplay_operate; + deviceparms->func_wplay_fcur = params.func_wplay_fcur; + deviceparms->func_wrec_fmax = params.func_wrec_fmax; + deviceparms->func_wplay_fmax = params.func_wrep_fmax; + } if(params.debug_str[0]) { params.debug_str[1023] = 0; @@ -278,6 +292,136 @@ int screen_thread::get_devicestatus() params.counterfreq = atof(device->buf); } + if(params.func_wrec_enable) + { + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREC:OPER?") != 16) + { + line = __LINE__; + goto OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto OUT_ERROR; + } + + if(params.modelserie == 6) + { + if(!strcmp(device->buf, "REC")) + { + params.func_wrec_operate = 1; + } + else if(!strcmp(device->buf, "STOP")) + { + params.func_wrec_operate = 0; + } + else + { + line = __LINE__; + goto OUT_ERROR; + } + } + else + { + if(!strcmp(device->buf, "RUN")) + { + params.func_wrec_operate = 1; + } + else if(!strcmp(device->buf, "STOP")) + { + params.func_wrec_operate = 0; + } + else + { + line = __LINE__; + goto OUT_ERROR; + } + } + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREP:OPER?") != 16) + { + line = __LINE__; + goto OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto OUT_ERROR; + } + + if(!strcmp(device->buf, "PLAY")) + { + params.func_wplay_operate = 1; + } + else if(!strcmp(device->buf, "STOP")) + { + params.func_wplay_operate = 0; + } + else if(!strcmp(device->buf, "PAUS")) + { + params.func_wplay_operate = 2; + } + else + { + line = __LINE__; + goto OUT_ERROR; + } + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREP:FCUR?") != 16) + { + line = __LINE__; + goto OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto OUT_ERROR; + } + + params.func_wplay_fcur = atoi(device->buf); + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREC:FMAX?") != 16) + { + line = __LINE__; + goto OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto OUT_ERROR; + } + + params.func_wrec_fmax = atoi(device->buf); + + usleep(TMC_GDS_DELAY); + + if(tmc_write(":FUNC:WREP:FMAX?") != 16) + { + line = __LINE__; + goto OUT_ERROR; + } + + if(tmc_read() < 1) + { + line = __LINE__; + goto OUT_ERROR; + } + + params.func_wrep_fmax = atoi(device->buf); + } + params.debug_str[0] = 0; return 0; @@ -334,6 +478,22 @@ void screen_thread::run() tmc_write(deviceparms->cmd_cue[params.cmd_cue_idx_out]); + if(deviceparms->cmd_cue_resp[params.cmd_cue_idx_out] != NULL) + { + usleep(TMC_GDS_DELAY); + + if(tmc_read() < 1) + { + printf("Can not read from device.\n"); + line = __LINE__; + goto OUT_ERROR; + } + + strncpy(deviceparms->cmd_cue_resp[params.cmd_cue_idx_out], device->buf, 128); + + deviceparms->cmd_cue_resp[params.cmd_cue_idx_out][127] = 0; + } + if((!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":TLHA", 5)) || ((!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":CHAN", 5)) && (!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out] + 6, ":SCAL ", 6)))) diff --git a/screen_thread.h b/screen_thread.h index d025701..e6a0db1 100644 --- a/screen_thread.h +++ b/screen_thread.h @@ -103,6 +103,13 @@ private: int current_screen_sf; + int func_wrec_enable; + int func_wrec_fmax; + int func_wrec_operate; + int func_wrep_fmax; + int func_wplay_operate; + int func_wplay_fcur; + char debug_str[1024]; } params; diff --git a/signalcurve.cpp b/signalcurve.cpp index 3384be6..ef45b6c 100644 --- a/signalcurve.cpp +++ b/signalcurve.cpp @@ -544,6 +544,11 @@ void SignalCurve::drawWidget(QPainter *painter, int curve_w, int curve_h) paintCounterLabel(painter, curve_w - 180, 6); } + if(devparms->func_wrec_enable) + { + paintPlaybackLabel(painter, curve_w - 180, 40); + } + if((mainwindow->adjDialFunc == ADJ_DIAL_FUNC_HOLDOFF) || (mainwindow->navDialFunc == NAV_DIAL_FUNC_HOLDOFF)) { convert_to_metric_suffix(str, devparms->triggerholdoff, 2); @@ -2252,6 +2257,43 @@ void SignalCurve::paintCounterLabel(QPainter *painter, int xpos, int ypos) } +void SignalCurve::paintPlaybackLabel(QPainter *painter, int xpos, int ypos) +{ + char str[128]; + + QPainterPath path; + + path.addRoundedRect(xpos, ypos, 175, 20, 3, 3); + + painter->fillPath(path, Qt::black); + + painter->setPen(Qt::darkGray); + + painter->drawRoundedRect(xpos, ypos, 175, 20, 3, 3); + + if(devparms->func_wrec_operate || !devparms->func_has_record) + { + painter->fillRect(xpos + 5, ypos + 5, 10, 10, Qt::red); + + painter->setPen(Qt::red); + + sprintf(str, "%i/%i", 0, devparms->func_wrec_fend); + + painter->drawText(xpos + 30, ypos, 120, 20, Qt::AlignCenter, str); + } + else + { + painter->fillRect(xpos + 5, ypos + 5, 10, 10, Qt::green); + + painter->setPen(Qt::green); + + sprintf(str, "%i/%i", devparms->func_wplay_fcur, devparms->func_wrec_fend); + + painter->drawText(xpos + 30, ypos, 120, 20, Qt::AlignCenter, str); + } +} + + bool SignalCurve::hasMoveEvent(void) { if(use_move_events) diff --git a/signalcurve.h b/signalcurve.h index 4e68732..4d0c186 100644 --- a/signalcurve.h +++ b/signalcurve.h @@ -153,6 +153,7 @@ private: void drawTopLabels(QPainter *); void paintLabel(QPainter *, int, int, int, int, const char *, QColor); void paintCounterLabel(QPainter *, int, int); + void paintPlaybackLabel(QPainter *, int, int); void drawFFT(QPainter *, int, int); void drawfpsLabel(QPainter *, int, int); void draw_decoder(QPainter *, int, int); diff --git a/tmc_dev.c b/tmc_dev.c index de4486d..b11315d 100644 --- a/tmc_dev.c +++ b/tmc_dev.c @@ -142,7 +142,12 @@ int tmcdev_write(struct tmcdev *dev, const char *cmd) !strncmp(buf, ":TRIG:SWE?", 10) || !strncmp(buf, ":ACQ:SRAT?", 10) || !strncmp(buf, ":ACQ:MDEP?", 10) || - !strncmp(buf, ":MEAS:COUN:VAL?", 15))) + !strncmp(buf, ":MEAS:COUN:VAL?", 15) || + !strncmp(buf, ":FUNC:WREC:OPER?", 16) || + !strncmp(buf, ":FUNC:WREP:OPER?", 16) || + !strncmp(buf, ":FUNC:WREP:FMAX?", 16) || + !strncmp(buf, ":FUNC:WREC:FMAX?", 16) || + !strncmp(buf, ":FUNC:WREP:FCUR?", 16))) { printf("tmc_dev write: %s", buf); } diff --git a/tmc_lan.c b/tmc_lan.c index fc79d3f..155319b 100644 --- a/tmc_lan.c +++ b/tmc_lan.c @@ -232,7 +232,12 @@ int tmclan_write(struct tmcdev *tmc_device __attribute__ ((unused)), const char !strncmp(buf, ":TRIG:SWE?", 10) || !strncmp(buf, ":ACQ:SRAT?", 10) || !strncmp(buf, ":ACQ:MDEP?", 10) || - !strncmp(buf, ":MEAS:COUN:VAL?", 15))) + !strncmp(buf, ":MEAS:COUN:VAL?", 15) || + !strncmp(buf, ":FUNC:WREC:OPER?", 16) || + !strncmp(buf, ":FUNC:WREP:OPER?", 16) || + !strncmp(buf, ":FUNC:WREP:FMAX?", 16) || + !strncmp(buf, ":FUNC:WREC:FMAX?", 16) || + !strncmp(buf, ":FUNC:WREP:FCUR?", 16))) { printf("tmc_lan write: %s", buf); }