-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathemgdatasource.cpp
More file actions
186 lines (148 loc) · 5.22 KB
/
emgdatasource.cpp
File metadata and controls
186 lines (148 loc) · 5.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "emgdatasource.h"
EMGDataSource::EMGDataSource(size_t refresh_ms,
QObject *parent) :
QObject(parent),
m_pSshSession(nullptr),
m_pSocket(nullptr),
m_iRefreshTime(refresh_ms)
{
}
EMGDataSource::~EMGDataSource() {
delete m_pSshSession;
delete m_pBuffer;
delete m_pFileBuffer;
delete[] m_pSendData;
delete[] m_pResidualData;
delete m_pSocket;
}
void EMGDataSource::init(TempFile* pTempFile) {
m_pTempFile = pTempFile;
connect(m_pTempFile, SIGNAL(sig_nSamplesRecorded(qulonglong)), this, SLOT(nSamplesRecorded(qulonglong)));
m_pBuffer = new RingBuffer<uint16_t>(10*iBlockLength, iTotalChannels, m_iRefreshTime);
m_pFileBuffer = new RingBuffer<uint16_t>(10*iBlockLength, iTotalChannels, iBlockLength);
m_pSendData = new uint16_t[m_iRefreshTime*iTotalChannels]; // Since frequency is 1KHz, time (ms) is the same as num samples
m_pResidualData = new uint16_t[iTotalChannels];
m_pTempFile->setFileBuffer(m_pFileBuffer);
}
Error_t EMGDataSource::initSocket(const QString& host, uint16_t port) {
m_host = host;
m_iPort = port;
if (m_pSocket) {
m_pSocket->doDisconnect();
delete m_pSocket;
m_pSocket = nullptr;
}
m_pSocket = new TCPSocket();
connect(m_pSocket, SIGNAL(updateUI(QString)), this, SLOT(slot_updateUI(QString)));
connect(m_pSocket, SIGNAL(dataAvailable(QByteArray)), this, SLOT(dataAvailable(QByteArray)));
m_pSocket->doConnect(m_host, m_iPort);
return kNoError;
}
void EMGDataSource::dataAvailable(QByteArray data) {
QMutexLocker locker(&m_mtx);
static size_t r_headSize = 0; static size_t r_headIdx = 0;
static size_t r_tailSize = 0; static size_t r_tailIdx = 0;
static size_t tcpDataSize = 0; static size_t tcpDataLength = 0;
static size_t writeSize = 0;
auto err = kNoError;
// get tail residuals from prev data chunk
memcpy(m_pResidualData, &m_pTcpData[tcpDataLength - r_tailIdx], r_tailSize);
// get current headsize from prev tail size
r_headSize = (iTotalChannelSize - r_tailSize) % iTotalChannelSize;
r_headIdx = r_headSize / ui16_size;
// Init current data chunk info
m_pTcpData = (const uint16_t*) data.constData();
tcpDataSize = data.size();
tcpDataLength = tcpDataSize / ui16_size;
// get the head residual from current chunk
memcpy(&m_pResidualData[r_tailIdx], m_pTcpData, r_headSize);
r_tailSize = (tcpDataSize - r_headSize) % iTotalChannelSize;
r_tailIdx = r_tailSize / ui16_size;
writeSize = tcpDataSize - r_headSize - r_tailSize;
// Push any residual data to buffers
if (r_headSize) {
err = m_pBuffer->push(m_pResidualData);
if (err != kNoError) {
qDebug() << "graph Buf residual write Error: " << err;
return;
}
if (m_bRecording) {
err = m_pFileBuffer->push(m_pResidualData);
if (err != kNoError) {
qDebug() << "graph Buf residual write Error: " << err;
return;
}
}
}
// Push current data chunk to buffers
err = m_pBuffer->push(&m_pTcpData[r_headIdx], writeSize/iTotalChannelSize);
if (err != kNoError) {
qDebug() << "graph Buf write Error: " << err;
return;
}
if (m_bRecording) {
err = m_pFileBuffer->push(&m_pTcpData[r_headIdx], writeSize/iTotalChannelSize);
if (err != kNoError) {
qDebug() << "graph Buf write Error: " << err;
return;
}
}
}
void EMGDataSource::startRecording() {
m_pTempFile->startWriting();
}
void EMGDataSource::stopRecording() {
m_pTempFile->stopWriting();
}
void EMGDataSource::nSamplesRecorded(qulonglong nSamples) {
// qDebug() << nSamples;
sig_nSamplesRecorded(nSamples);
}
RingBuffer<uint16_t>* EMGDataSource::getDataBufferPtr() {
return m_pBuffer;
}
Error_t EMGDataSource::sshStartServer(const std::string& host, uint16_t port) {
auto err = kNoError;
m_pSshSession = new SshSession();
err = m_pSshSession->doConnect(host);
if (err != kNoError) {
delete m_pSshSession;
m_pSshSession = nullptr;
return err;
}
err = m_pSshSession->startServer();
if (err != kNoError) {
m_pSshSession->disconnect();
delete m_pSshSession;
m_pSshSession = nullptr;
return err;
}
m_pSshSession->disconnect();
delete m_pSshSession;
m_pSshSession = nullptr;
return initSocket(QString(host.c_str()), port);
}
void EMGDataSource::slot_updateUI(QString message) {
sig_updateUI(message);
}
Error_t EMGDataSource::stop() {
return m_pSocket->send(TCPSocket::Exit);
}
void EMGDataSource::setRecording(bool bRec) {
if (m_bRecording != bRec) {
m_bRecording = bRec;
if (m_bRecording) {
startRecording();
} else {
stopRecording();
}
}
}
Error_t EMGDataSource::setSensorGain(uint16_t iGain) {
m_iSensorGain = iGain;
return m_pSocket->send(iGain);
}
void EMGDataSource::setCurrentSessionGesture(int iGesture) {
if (m_pTempFile)
m_pTempFile->setCurrentSessionGesture(iGesture);
}