Ejemplo n.º 1
0
error_code filelib_write_show(char *buf, u_long size)
{
  if ((int)size > m_ringbuf.Size())
  {
    CLog::Log(LOGERROR, "Shoutcast chunk too big: %lu", size);
    return SR_ERROR_BUFFER_FULL;
  }
  while (m_ringbuf.GetMaxWriteSize() < (int)size) Sleep(10);
  m_ringbuf.WriteBinary(buf, size);
  m_ripFile.Write( buf, size ); //will only write, if it has to
  return SR_SUCCESS;
}
Ejemplo n.º 2
0
bool COrganyaCodec::Init(const std::string& strFile, unsigned int filecache, int& channels,
                         int& samplerate, int& bitspersample, int64_t& totaltime,
                         int& bitrate, AEDataFormat& format, std::vector<AEChannel>& channelinfo)
{
  sample_buffer.Create(4096);
  kodi::vfs::CFile file;
  file.OpenFile(strFile);
  if (!file.OpenFile(strFile, 0))
    return false;
  std::string temp = kodi::GetSettingString("__addonpath__") + "/resources/samples";
  tune = org_decoder_create(&file, temp.c_str(), 1);
  tune->state.sample_rate = 48000;
  totaltime = org_decoder_get_total_samples(tune)*1000/48000;
  length = totaltime/1000*48000*4;
  format = AE_FMT_S16NE;
  channelinfo = { AE_CH_FL, AE_CH_FR, AE_CH_NULL };
  channels = 2;
  bitspersample = 16;
  bitrate = 0.0;
  samplerate = 48000;

  file.Close();
  Seek(0);

  return true;
}
Ejemplo n.º 3
0
void allbuttests::samplednotlast()
{  
  RingItemHeader h  = {sizeof(RingItemHeader), 1234};
  pProd->put(&h, sizeof(h));
  pProd->put(&h, sizeof(h));
  
  CAllButPredicate p;
  p.addExceptionType(1234, true);

  ASSERT(p(*pCons));
  EQ(sizeof(h), pCons->availableData());
 
  ASSERT(!p(*pCons));
  

}
Ejemplo n.º 4
0
void allbuttests::notinlist() {
  RingItemHeader h  = {sizeof(RingItemHeader), 1234};
  pProd->put(&h, sizeof(h));

  CAllButPredicate p;

  ASSERT(!p(*pCons));
}
Ejemplo n.º 5
0
/* Write data to ring buffer from another ring buffer object specified by
 * 'rBuf'.
 */
bool CRingBuffer::WriteData(CRingBuffer &rBuf, unsigned int size)
{
  CSingleLock lock(m_critSection);
  if (m_buffer == NULL)
    Create(size);

  bool bOk = size <= rBuf.getMaxReadSize() && size <= getMaxWriteSize();
  if (bOk)
  {
    unsigned int readpos = rBuf.getReadPtr();
    unsigned int chunksize = std::min(size, rBuf.getSize() - readpos);
    bOk = WriteData(&rBuf.getBuffer()[readpos], chunksize);
    if (bOk && chunksize < size)
      bOk = WriteData(&rBuf.getBuffer()[0], size - chunksize);
  }

  return bOk;
}
Ejemplo n.º 6
0
void allbuttests::inlist()
{
  RingItemHeader h  = {sizeof(RingItemHeader), 1234};
  pProd->put(&h, sizeof(h));
  
  CAllButPredicate p;
  p.addExceptionType(1234);
  ASSERT(p(*pCons));
}
Ejemplo n.º 7
0
/* Read in data from the ring buffer to another ring buffer object specified by
 * 'rBuf'.
 */
bool CRingBuffer::ReadData(CRingBuffer &rBuf, unsigned int size)
{
  CSingleLock lock(m_critSection);
  if (rBuf.getBuffer() == NULL)
    rBuf.Create(size);

  bool bOk = size <= rBuf.getMaxWriteSize() && size <= getMaxReadSize();
  if (bOk)
  {
    unsigned int chunksize = std::min(size, m_size - m_readPtr);
    bOk = rBuf.WriteData(&getBuffer()[m_readPtr], chunksize);
    if (bOk && chunksize < size)
      bOk = rBuf.WriteData(&getBuffer()[0], size - chunksize);
    if (bOk)
      SkipBytes(size);
  }

  return bOk;
}
Ejemplo n.º 8
0
void CFileShoutcast::Close()
{
  OutputDebugString("Shoutcast Stopping\n");
  if ( m_ripFile.IsRecording() )
    m_ripFile.StopRecording();
  m_ringbuf.Clear();
  rip_manager_stop();
  m_ripFile.Reset();
  OutputDebugString("Shoutcast Stopped\n");
}
Ejemplo n.º 9
0
int COrganyaCodec::ReadPCM(uint8_t* pBuffer, int size, int &actualsize)
{
  if (pos >= length*48000*4/1000)
    return 1;

  if (sample_buffer.getMaxReadSize() == 0) {
    int16_t temp[1024*2]; 
    int64_t written=1024;
    written = org_decode_samples(tune, temp, written);
    if (written == 0)
      return 1;
    sample_buffer.WriteData((const char*)temp, written*4);
  }

  int tocopy = std::min(size, (int)sample_buffer.getMaxReadSize());
  sample_buffer.ReadData((char*)pBuffer, tocopy);
  pos += tocopy;
  actualsize = tocopy;
  return 0;
}
Ejemplo n.º 10
0
unsigned int CFileShoutcast::Read(void* lpBuf, __int64 uiBufSize)
{
  if (m_fileState.bRipDone)
  {
    OutputDebugString("Read done\n");
    return 0;
  }
  while (m_ringbuf.GetMaxReadSize() <= 0) Sleep(10);
  int iRead = m_ringbuf.GetMaxReadSize();
  if (iRead > uiBufSize) iRead = (int)uiBufSize;
  m_ringbuf.ReadBinary((char*)lpBuf, iRead);

  if (timeGetTime() - m_dwLastTime > 500)
  {
    m_dwLastTime = timeGetTime();
    CMusicInfoTag tag;
    GetMusicInfoTag(tag);
    g_infoManager.SetCurrentSongTag(tag);
  }
  return iRead;
}
Ejemplo n.º 11
0
/*
 * 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;
}
Ejemplo n.º 12
0
CFileShoutcast::~CFileShoutcast()
{
  // FIXME: without this check
  // the playback stops when CFile::Stat()
  // or CFile::Exists() is called

  // Has this object initialized the ripper?
  if (m_pShoutCastRipper==this)
  {
    rip_manager_stop();
    m_pShoutCastRipper = NULL;
    m_ripFile.Reset();
    m_ringbuf.Destroy();
  }
}
Ejemplo n.º 13
0
TEST(TestRingBuffer, General)
{
  CRingBuffer a;
  char data[20];
  unsigned int i;

  EXPECT_TRUE(a.Create(20));
  EXPECT_EQ((unsigned int)20, a.getSize());
  memset(data, 0, sizeof(data));
  for (i = 0; i < a.getSize(); i++)
    EXPECT_TRUE(a.WriteData(data, 1));
  a.Clear();

  memcpy(data, "0123456789", sizeof("0123456789"));
  EXPECT_TRUE(a.WriteData(data, sizeof("0123456789")));
  EXPECT_STREQ("0123456789", a.getBuffer());

  memset(data, 0, sizeof(data));
  EXPECT_TRUE(a.ReadData(data, 5));
  EXPECT_STREQ("01234", data);
}
Ejemplo n.º 14
0
CFileShoutcast::CFileShoutcast()
{
  // FIXME: without this check
  // the playback stops when CFile::Stat()
  // or CFile::Exists() is called

  // Do we already have another file
  // using the ripper?
  if (!m_pShoutCastRipper)
  {
    m_fileState.bBuffering = true;
    m_fileState.bRipDone = false;
    m_fileState.bRipStarted = false;
    m_fileState.bRipError = false;
    m_ringbuf.Create(1024*1024); // must be big enough. some stations use 192kbps.
    m_pShoutCastRipper = this;
  }
}
Ejemplo n.º 15
0
//Starts the thread that does the data acquisition.
void StartAcquisition()
{
	int numChannels = NUMBER_OF_CHANNELS + (int) ENABLE_TRIGGER;

	_isRunning = true;
	_bufferOverrun = false;

	//give main process (the data processing thread) high priority
	HANDLE hProcess = GetCurrentProcess();
	SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS);

	//initialize application data buffer to the specified number of seconds
	_buffer.Initialize(BUFFER_SIZE_SECONDS * SAMPLE_RATE_HZ * numChannels);

	//reset event
	_dataAcquisitionStopped.ResetEvent();

	//create data acquisition thread with high priority
	_dataAcquisitionThread = AfxBeginThread(DoAcquisition, NULL, THREAD_PRIORITY_TIME_CRITICAL,0, CREATE_SUSPENDED);
	_dataAcquisitionThread->ResumeThread();
}
Ejemplo n.º 16
0
/**
 * Put data into the ring.
 * Each data item is assumed to be preceded by a two longword header of the form:
 * struct header {
 *    uint32_t size;
 *    uint32_t type
 *  };
 * 
 * Futhermore, from the point of view of byte ordering, the type field only has
 * nonzero bits in the lower order 16 bits.
 *
 * We're going to put each data item in the ring atomically.
 * If there are left over data in the buffer, that will be shifted down
 * to the beginning of the buffer and
 * the remaining size will be returned:
 * 
 * @param ring    - reference to the target ring buffer.
 * @param pBuffer - Pointer to the data buffer.
 * @param nBytes  - Number of bytes in the data buffer.
 *
 * It is assumed that the total buffer size will be larger than
 * needed to hold the largest item.   That's controld by the 
 * --mindata switch in any event.
 */
static size_t 
putData(CRingBuffer& ring, void* pBuffer, size_t nBytes)
{

  struct header *pHeader;

  uint8_t* p = reinterpret_cast<uint8_t*>(pBuffer); // makes addr arithmetic easier.
  struct header *pLastItem;
  int           lastSize = 0;



  while(nBytes > sizeof(struct header)) {
    pHeader = reinterpret_cast<struct header*>(p);
    uint32_t size = computeSize(pHeader);


    if (size <= nBytes) {
      // we can put a complete item
      pLastItem = pHeader;

      ring.put(p, size);
      p += size;
      nBytes -= size;
      lastSize = size;
    } 
    else {
      // We don't have a complete packet.
      // Move the remainder of the buffer down to the start
      // must use memmove because this could be an overlapping
      // move
      break;
    }

  }								
  if (nBytes > 0) {
    memmove(pBuffer, p, nBytes);
  }
  return nBytes;		// Residual data.
}
Ejemplo n.º 17
0
/*
 * Starts data acquisition and acquires data until StopAcquisition is called (i.e., the _isRunning flag is set to false)
 * Then the data acquisition will be stopped.
 */
unsigned int DoAcquisition(LPVOID pArgs)
{
	int queueIndex = 0;
	int numChannels = NUMBER_OF_CHANNELS + (int) ENABLE_TRIGGER;
	int nPoints = NUMBER_OF_SCANS * numChannels;
	DWORD numValidBytes = nPoints * sizeof(float);
	DWORD bufferSizeBytes = (DWORD) ceil(numValidBytes / (double) MAX_USB_PACKET_SIZE) * MAX_USB_PACKET_SIZE;
	int timeOutMilliseconds = (int) ceil(2000 * (NUMBER_OF_SCANS / (double) SAMPLE_RATE_HZ));
	DWORD numBytesReceived = 0;

	//create the temporary data buffers (the device will write data into those)
	BYTE** buffers = new BYTE*[QUEUE_SIZE];
	OVERLAPPED* overlapped = new OVERLAPPED[QUEUE_SIZE];

	__try
	{
		//for each data buffer allocate a number of numValidBytes bytes
		for (queueIndex = 0; queueIndex < QUEUE_SIZE; queueIndex++)
		{
			buffers[queueIndex] = new BYTE[bufferSizeBytes];
			SecureZeroMemory(&(overlapped[queueIndex]), sizeof(OVERLAPPED));

			//create a windows event handle that will be signaled when new data from the device has been received for each data buffer
			overlapped[queueIndex].hEvent = CreateEvent(NULL, false, false, NULL);
		}

		queueIndex = 0;

		//start device
		if (!GT_Start(_hDevice))
		{
			cout << "\tError on GT_Start: Couldn't start data acquisition of device.\n";
			PrintDeviceErrorMessage();
			return 0;
		}

		//queue up the first batch of transfer requests to prevent overflow on the device
		for (queueIndex = 0; queueIndex < QUEUE_SIZE; queueIndex++)
		{
			if (!GT_GetData(_hDevice, buffers[queueIndex], bufferSizeBytes, &overlapped[queueIndex]))
			{
				cout << "\tError on GT_GetData.\n";
				PrintDeviceErrorMessage();
				return 0;
			}
		}

		queueIndex = 0;

		//continouos data acquisition
		while (_isRunning)
		{
			//wait for notification from the system telling that new data is available
			if (WaitForSingleObject(overlapped[queueIndex].hEvent, 5000) == WAIT_TIMEOUT)
			{
				cout << "\tError on data transfer: timeout occured.\n";
				PrintDeviceErrorMessage();
				return 0;
			}

			//get number of actually received bytes...
			if (!GT_GetOverlappedResult(_hDevice, &overlapped[queueIndex], &numBytesReceived, false))
			{
				cout << "\tError on data transfer: couldn't receive number of transferred bytes (GT_GetOverlappedResult() returned FALSE; Windows error code: " << GetLastError() << ")\n";
				return 0;
			}

			//...and check if we lost something (number of received bytes must be equal to the previously allocated buffer size)
			if (numBytesReceived != numValidBytes)
			{
				cout << "\tError on data transfer: samples lost.\n";
				return 0;
			}

			//to store the received data into the application data buffer at once, lock it
			_bufferLock.Lock();

			__try
			{
				//if we are going to overrun on writing the received data into the buffer, set the appropriate flag; the reading thread will handle the overrun
				_bufferOverrun = (_buffer.GetFreeSize() < nPoints);

				//store received data in the correct order (that is scan-wise, where one scan includes all channels)
				_buffer.Write((float*) buffers[queueIndex], nPoints);
			}
			__finally
			{
				//release the previously acquired lock
				_bufferLock.Unlock();
			}

			//add new GetData call to the queue replacing the currently received one
			if (!GT_GetData(_hDevice, buffers[queueIndex], bufferSizeBytes, &overlapped[queueIndex]))
			{
				cout << "\tError on GT_GetData.\n";
				PrintDeviceErrorMessage();
				return 0;
			}

			//signal processing (main) thread that new data is available
			_newDataAvailable.SetEvent();
			
			//increment circular queueIndex to process the next queue at the next loop repitition (on overrun start at index 0 again)
			queueIndex = (queueIndex + 1) % QUEUE_SIZE;
		}
	}
	__finally
	{
		cout << "Stopping device and cleaning up..." << "\n";

		//stop device
		if (!GT_Stop(_hDevice))
		{
			cout << "\tError on GT_Stop: couldn't stop device.\n";
			PrintDeviceErrorMessage();
		}

		//clean up allocated resources
		for (int i = 0; i < QUEUE_SIZE; i++)
		{
			if (WaitForSingleObject(overlapped[queueIndex].hEvent, timeOutMilliseconds) == WAIT_TIMEOUT)
				GT_ResetTransfer(_hDevice);

			CloseHandle(overlapped[queueIndex].hEvent);

			delete [] buffers[queueIndex];

			//increment queue index
			queueIndex = (queueIndex + 1) % QUEUE_SIZE;
		}

		delete [] buffers;
		delete [] overlapped;

		//reset _isRunning flag
		_isRunning = false;

		//signal event
		_dataAcquisitionStopped.SetEvent();

		//end thread
		AfxEndThread(0xdead);
	}

	return 0xdead;
}
Ejemplo n.º 18
0
bool CFileShoutcast::Open(const CURL& url, bool bBinary)
{
  m_dwLastTime = timeGetTime();
  int ret;

  CGUIDialogProgress* dlgProgress = (CGUIDialogProgress*)m_gWindowManager.GetWindow(WINDOW_DIALOG_PROGRESS);

  set_rip_manager_options_defaults(&m_opt);

  strcpy(m_opt.output_directory, "./");
  m_opt.proxyurl[0] = '\0';

  // Use a proxy, if the GUI was configured as such
  bool bProxyEnabled = g_guiSettings.GetBool("network.usehttpproxy");
  if (bProxyEnabled)
  {
    const CStdString &strProxyServer = g_guiSettings.GetString("network.httpproxyserver");
    const CStdString &strProxyPort = g_guiSettings.GetString("network.httpproxyport");
	  // Should we check for valid strings here
#ifndef _LINUX
	  _snprintf( m_opt.proxyurl, MAX_URL_LEN, "http://%s:%s", strProxyServer.c_str(), strProxyPort.c_str() );
#else
	  snprintf( m_opt.proxyurl, MAX_URL_LEN, "http://%s:%s", strProxyServer.c_str(), strProxyPort.c_str() );
#endif
  }

  CStdString strUrl;
  url.GetURL(strUrl);
  strUrl.Replace("shout://", "http://");
  printf("Opening url: %s\n", strUrl.c_str());
  strncpy(m_opt.url, strUrl.c_str(), MAX_URL_LEN);
  sprintf(m_opt.useragent, "x%s", url.GetFileName().c_str());
  if (dlgProgress)
  {
    dlgProgress->SetHeading(260);
    dlgProgress->SetLine(0, 259);
    dlgProgress->SetLine(1, strUrl);
    dlgProgress->SetLine(2, "");
    if (!dlgProgress->IsDialogRunning())
      dlgProgress->StartModal();
    dlgProgress->Progress();
  }

  if ((ret = rip_manager_start(rip_callback, &m_opt)) != SR_SUCCESS)
  {
    if (dlgProgress) dlgProgress->Close();
    return false;
  }
  int iShoutcastTimeout = 10 * SHOUTCASTTIMEOUT; //i.e: 10 * 10 = 100 * 100ms = 10s
  int iCount = 0;
  while (!m_fileState.bRipDone && !m_fileState.bRipStarted && !m_fileState.bRipError && (!dlgProgress || !dlgProgress->IsCanceled()))
  {
    if (iCount <= iShoutcastTimeout) //Normally, this isn't the problem,
      //because if RIP_MANAGER fails, this would be here
      //with m_fileState.bRipError
    {
      Sleep(100);
    }
    else
    {
      if (dlgProgress)
      {
        dlgProgress->SetLine(1, 257);
        dlgProgress->SetLine(2, "Connection timed out...");
        Sleep(1500);
        dlgProgress->Close();
      }
      return false;
    }
    iCount++;
  }
  
  if (dlgProgress && dlgProgress->IsCanceled())
  {
     Close();
     dlgProgress->Close();
     return false;
  }

  /* store content type of stream */
  m_contenttype = rip_manager_get_content_type();

  //CHANGED CODE: Don't reset timer anymore.

  while (!m_fileState.bRipDone && !m_fileState.bRipError && m_fileState.bBuffering && (!dlgProgress || !dlgProgress->IsCanceled()))
  {
    if (iCount <= iShoutcastTimeout) //Here is the real problem: Sometimes the buffer fills just to
      //slowly, thus the quality of the stream will be bad, and should be
      //aborted...
    {
      Sleep(100);
      char szTmp[1024];
      //g_dialog.SetCaption(0, "Shoutcast" );
      sprintf(szTmp, "Buffering %i bytes", m_ringbuf.GetMaxReadSize());
      if (dlgProgress)
      {
        dlgProgress->SetLine(2, szTmp );
        dlgProgress->Progress();
      }

      sprintf(szTmp, "%s", m_ripInfo.filename);
      for (int i = 0; i < (int)strlen(szTmp); i++)
        szTmp[i] = tolower((unsigned char)szTmp[i]);
      szTmp[50] = 0;
      if (dlgProgress)
      {
        dlgProgress->SetLine(1, szTmp );
        dlgProgress->Progress();
      }
    }
    else //it's not really a connection timeout, but it's here,
      //where things get boring, if connection is slow.
      //trust me, i did a lot of testing... Doesn't happen often,
      //but if it does it sucks to wait here forever.
      //CHANGED: Other message here
    {
      if (dlgProgress)
      {
        dlgProgress->SetLine(1, 257);
        dlgProgress->SetLine(2, "Connection to server too slow...");
        dlgProgress->Close();
      }
      return false;
    }
    iCount++;
  }
  if (dlgProgress && dlgProgress->IsCanceled())
  {
     Close();
     dlgProgress->Close();
     return false;
  }
  if ( m_fileState.bRipError )
  {
    if (dlgProgress)
    {
      dlgProgress->SetLine(1, 257);
      dlgProgress->SetLine(2, m_errorInfo.error_str);
      dlgProgress->Progress();

      Sleep(1500);
      dlgProgress->Close();
    }
    return false;
  }
  if (dlgProgress)
  {
    dlgProgress->SetLine(2, 261);
    dlgProgress->Progress();
    dlgProgress->Close();
  }
  return true;
}
Ejemplo n.º 19
0
//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();
}
Ejemplo n.º 20
0
/* Append all content from ring buffer 'rBuf' to this ring buffer */
bool CRingBuffer::Append(CRingBuffer &rBuf)
{
  return WriteData(rBuf, rBuf.getMaxReadSize());
}