As I've received a number of questions concerning the С++ code, I'll try to answer them here....
The working (I hope) example of this code usage together with brief explanation can be found at
http://diz-vara.mail333.com/ActiveD.zip
Code: Select all
READ_MULTIPLE_SWEEPS(m_hAct2,m_pBuf,BUFSIZE*4);
// BUFSIZE is 8M , right ? I follow the step in the forum, and m_pBuf is a PCHAR, size 32M, and the third parameter is nbyteToRead, Is it the same as BUFSIZE ? I have no idea...
I use
Code: Select all
long *m_pBuf;
m_pBuf = new long[BUFSIZE];
So, the size of the buffer is 8 MegaSamples - but 32 MB
Code: Select all
for (i = 0; i < 10; i++) {
READ_POINTER(m_hAct2,&lPointer); //I initial the lPointer as 0 , is it right?
if (lPointer/4 != m_dwPointer) break; //each time it break here... because after READ_POINTER, lpointer is never 0 again, is it means I have synchronize or mean something else ?
Sleep(10);
}
lPointer /= 4;
if (m_dwPointer == lPointer)
throw("No cord or power");
Yes, lPointer is initialized with 0.
This portion is just a 'translation' of ActiView code into C++. It tests for the new data 10 times (with 10ms interval). If the device is switched off (or the cable is not connected), the pointer will not change - and the corresponding exception will be thrown. Otherwise you'll receive new value of the pointer.
Code: Select all
ULONG lNew;
if (lPointer >= m_dwPointer)
lNew = lPointer - m_dwPointer;
else {
lNew = lPointer + BUFSIZE - m_dwPointer;
}
Code: Select all
m_i64Buf += lNew; // so , m_i64Buf is how many data had been buffer ?
Yes, it's the total amount of data buffered. I've decided that one _int64 counter will be enough for my purposes... You can calculate the possibility to overflow this counter youself
Code: Select all
DWORD dwDispBufPos = (DWORD)(m_i64Disp%(BUFSIZE));
DWORD dwSynch = m_pBuf[dwDispBufPos];
if (dwSynch != 0xFFFFFF00) throw("Synch lost"); //Never get Sysch here... ,Because Never Change m_i64Disp ....it's just zero...
Yes, I change m_i64Disp at the end of timer function (after processing of new data). The real code for detecting synchonization problems will be like that:
Code: Select all
DWORD dwDispBufPos = (DWORD)(m_i64Disp%(BUFSIZE));
DWORD dwSynch(0);
int a,b;
_int64 One(2);
long lTmp;
b = (dwDispBufPos+1)&(BUFSIZE-1);
dwMode = (m_pBuf[b] & 0x2E000000) >> 25;
m_aMode= actMode(dwMode);
m_nActChans = m_aMode.GetBufChans();
if (m_nActChans)
nDisp = (int)(m_i64Buf-m_i64Disp)/m_nActChans;
else
nDisp = 0;
for (i = 0; i < nDisp; i++)
{
a = (dwDispBufPos+i*m_nActChans)&(BUFSIZE-1);
b = (dwDispBufPos+i*m_nActChans+1)&(BUFSIZE-1);
dwSynch = m_pBuf[a];
dwMode = (m_pBuf[b] & 0x7E000000) >> 25;
if (dwSynch != 0xFFFFFF00)
{
dwMode = -1;
throw("Synch lost");
}
if ( (dwMode & 0x17) != m_dwMode)
throw("Mode changed");
}
///////////////////////////////////////////////////////////////////
// !!!!!!!!!!!!!!!!!!!!!! ////////////////////
// Here follows long (more than 500 lines) and really complex
// critical section that remap channels, detects trigger events,
// performs filtering and decimation, calculates mean channel offsets
// and post messages to other threads (to display and store data)
////////////////////////////////////////////////////////////////////////////
//update display pointer
m_i64Disp += nDisp * m_nActChans;
Of course, the main problem is not the code itself (it does not differ from any other acquisition program) - but the design of the project: how to divide the flow between severla threads, how to organize inter-thread synchronization and communication - etc... But I hope this small will help you with the 'core' part of the program.