/* * Reads the received numberOfScans scans from the device. If not enough data is available (errorCode == 2) or the application buffer overruns (errorCode == 1), this method returns false. * float* destBuffer: the array that returns the received data from the application data buffer. Data is aligned as follows: element at position destBuffer[scanIndex * numChannels + channelIndex] is sample of channel channelIndex (zero-based) of the scan with zero-based scanIndex. channelIndex ranges from 0..numChannelsPerDevices where numChannelsPerDevice the total number of channels of the device including the trigger line. * int numberOfScans: the number of scans to retrieve from the application buffer. */ bool ReadData(float* destBuffer, int numberOfScans, int *errorCode, string *errorMessage) { int numChannels = NUMBER_OF_CHANNELS + (int) ENABLE_TRIGGER; int validPoints = numChannels * numberOfScans; //wait until requested amount of data is ready if (_buffer.GetSize() < validPoints) { *errorCode = 2; *errorMessage = "Not enough data available"; return false; } //acquire lock on the application buffer for reading _bufferLock.Lock(); __try { //if buffer run over report error and reset buffer if (_bufferOverrun) { _buffer.Reset(); *errorCode = 1; *errorMessage = "Error on reading data from the application data buffer: buffer overrun."; _bufferOverrun = false; return false; } //copy the data from the application buffer into the destination buffer _buffer.Read(destBuffer, validPoints); } __finally { _bufferLock.Unlock(); } *errorCode = 0; *errorMessage = "No error occured."; return true; }
//this is the main entry point of the application void main(int argc, _TCHAR* argv[]) { zmq::context_t context(1); zmq::socket_t publisher(context, ZMQ_PUB); publisher.bind("tcp://192.168.56.101:5556"); CStopWatch timer; try { cout << "Opening device '" << _deviceSerial << "'...\n"; //open device _hDevice = GT_OpenDevice(0); //_hDevice = GT_OpenDeviceEx(_deviceSerial); if (_hDevice == NULL) throw string("Error on GT_OpenDeviceEx: couldn't open device ").append(_deviceSerial); cout << "Configuring device...\n"; int nossr = 0; int nof; GT_GetNumberOfFilter(&nof); cout<<"nof: "<<nof<<endl; FILT* flt = new FILT[nof]; GT_GetFilterSpec(flt); for (int i=0; i< nof; i++) { cout<<i<<":"<<flt[i].fu<<":"<<flt[i].fo<<":"<<flt[i].fs<<":"<<flt[i].type<<endl; } //GT_GetNumberOfSupportedSampleRates(_hDevice, &nossr); //cout<<"nossr: "<<nossr<<endl; /*GT_GetNumberOfSupportedSampleRates(_hDevice, &nossr); float* ssr = new float[nossr]; GT_GetSupportedSampleRates(_hDevice, ssr); for (int i=0; i<nossr; i++) cout<<ssr[i]<<endl; */ GT_Stop(_hDevice); GT_ResetTransfer(_hDevice); //configure device ConfigureDevice(_hDevice); /*GT_HIAMP_CHANNEL_IMPEDANCES imp; for (int i = 0; i<256; i++) { imp.IsActiveElectrode[i]=FALSE; imp.Impedance[i]=0.0; } BOOL status = GT_GetImpedance(_hDevice, &imp); cout<<"imp: "<<status<<" : "; for (int i = 0; i<10; i++) { cout<<imp.Impedance[i]<<" "; } cout<<endl; Sleep(200);*/ //Sleep(2000); //determine how many scans should be read and processed at once by the processing thread (not the acquisition thread!) int numScans = NUMBER_OF_SCANS; int numChannels = NUMBER_OF_CHANNELS + (int) ENABLE_TRIGGER; //initialize temporary data buffer where data from the application buffer will be copied out float *receivedData = new float[numScans * numChannels]; try { //for receiving error messages from ReadData int errorCode; string errorMessage; //initialize file stream where received data should be written to //CFile outputFile; //if (!outputFile.Open(_T("receivedData.bin"), CFile::modeCreate | CFile::modeWrite | CFile::typeBinary)) // throw string("Error on creating/opening output file: file 'receivedData.bin' couldn't be opened."); try { cout<<sizeof(float)<<" "<<sizeof(double)<<endl; cout << "Starting acquisition...\n"; //start data acquisition StartAcquisition(); //cout << "Receiving data for " << NUM_SECONDS_RUNNING << " seconds...\n"; cout << "Receiving data ...\n"; //to stop the application after a specified time, get start time long startTime = clock(); long endTime = startTime + NUM_SECONDS_RUNNING * CLOCKS_PER_SEC; //this is the data processing thread; data received from the devices will be written out to a file here //while (clock() < endTime) timer.startTimer(); while (!_kbhit()) { //to release CPU resources wait until the acquisition thread tells that new data has been received and is available in the buffer. WaitForSingleObject(_newDataAvailable.m_hObject, 1000); while (_buffer.GetSize() >= numScans * numChannels) { //read data from the application buffer and stop application if buffer overrun if (!ReadData(receivedData, numScans, &errorCode, &errorMessage)) { if (errorCode == 2) break; else throw errorMessage; } timer.stopTimer(); //cout<<"t: "<<setprecision(12)<<timer.getElapsedTime()<<endl; //stringstream ss; //ss<<setprecision(9)<<timer.getElapsedTime()<<" "; //for (size_t i=0; i<numScans * numChannels; i++) { // ss<<receivedData[i]<<" "; //} //zmq::message_t message(ss.str().size()+1); zmq::message_t message(sizeof(double) + sizeof(float)* numScans * numChannels); //memcpy(message.data(), ss.str().c_str(), ss.str().size()+1); double ct = timer.getElapsedTime(); memcpy(message.data(), &ct, sizeof(double)); memcpy((char *) (message.data())+sizeof(double), receivedData, sizeof(float)* numScans * numChannels); publisher.send(message); //timer.startTimer(); //cout<<"m:"<<ss.str().c_str()<<endl; //write data to file //outputFile.Write(receivedData, numScans * numChannels * sizeof(float)); //cout<<"d1: "<<receivedData[64]<<endl; //cout<<sizeof(float)<<endl; } } } catch (string& exception) { //an exception occured during data acquisition cout << "\t" << exception << "\n"; //continue execution in every case to clean up allocated resources (since no finally-block exists) } // //in every case, stop data acquisition and clean up allocated resources //since no finally statement exists in c++ and we can't mix it with the C __finally statement, the clean-up code follows the try-catch block. // //stop data acquisition StopAcquisition(); //close output file //outputFile.Close(); } catch (string& exception) { //an exception occured cout << "\t" << exception << "\n"; //continue execution in every case to clean up allocated resources (since no finally-block exists) } cout << "Closing device...\n"; //close device if (!GT_CloseDevice(&_hDevice)) cout << "Error on GT_CloseDevice: couldn't close device" << GetDeviceErrorMessage() << "\n"; //free allocated resources delete [] receivedData; cout << "Clean up complete. Bye bye!" << "\n\n"; } catch (string& exception) { //in case an error occured during opening and initialization, report it and stop execution cout << "\t" << exception << "\n\n"; } publisher.close(); cout << "Press ENTER to exit..."; getchar(); }