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.