Beispiel #1
0
  void System::onRawArrival( HANDLE handle )
  {
    UINT pathLength = 0;

    if ( GetRawInputDeviceInfoW( handle, RIDI_DEVICENAME, NULL, &pathLength ) )
      NIL_EXCEPT_WINAPI( "GetRawInputDeviceInfoW failed" );

    wideString rawPath( pathLength, '\0' );

    GetRawInputDeviceInfoW( handle, RIDI_DEVICENAME, &rawPath[0], &pathLength );
    rawPath.resize( rawPath.length() - 1 );

    for ( auto device : mDevices )
    {
      if ( device->getHandler() != Device::Handler_RawInput )
        continue;

      auto rawDevice = static_cast<RawInputDevice*>( device );

      if ( !_wcsicmp( rawDevice->getRawPath().c_str(), rawPath.c_str() ) )
      {
        deviceConnect( rawDevice );
        return;
      }
    }

    auto device = new RawInputDevice( this, getNextID(), handle, rawPath );

    if ( isInitializing() )
      device->setStatus( Device::Status_Connected );
    else
      deviceConnect( device );

    mDevices.push_back( device );
  }
Beispiel #2
0
  BOOL CALLBACK System::diDeviceEnumCallback( LPCDIDEVICEINSTANCEW instance,
  LPVOID referer )
  {
    auto system = reinterpret_cast<System*>( referer );

    for ( auto identifier : system->mXInputDeviceIDs )
      if ( instance->guidProduct.Data1 == identifier )
        return DIENUM_CONTINUE;

    for ( auto device : system->mDevices )
    {
      if ( device->getHandler() != Device::Handler_DirectInput )
        continue;

      auto diDevice = static_cast<DirectInputDevice*>( device );

      if ( diDevice->getInstanceID() == instance->guidInstance )
      {
        if ( device->getSavedStatus() == Device::Status_Disconnected )
          system->deviceConnect( device );
        else
          device->setStatus( Device::Status_Connected );

        return DIENUM_CONTINUE;
      }
    }

    Device* device = new DirectInputDevice( system, system->getNextID(), instance );

    if ( system->isInitializing() )
      device->setStatus( Device::Status_Connected );
    else
      system->deviceConnect( device );

    system->mDevices.push_back( device );

    return DIENUM_CONTINUE;
  }
Beispiel #3
0
bool Stream::doInit(const char *url)
{
	if(isInitializing()) {
		// this is not completely clean (should be within the lock) but otherwise the 
		// caller would have to wait for the thread lock

		post("Still initializing %s/%s:%i",hostname.c_str(),mountpt.c_str(),port);
		return false;
	}

	bool ok = true;

	pthread_mutex_lock(&mutex);

	// close open file
	Reset();

	// try to set host name, mount point, port number
	if(ok) {
		char *err = "Invalid URL";
		try { ok = SetURL(url); }
		catch(char *tx) { err = tx;	ok = false;	}
		catch(...) { ok = false; }

		if(!ok) { post(err); ResetHost(); }
	}

	if(ok) {
		state = ST_INIT;
		pthread_cond_signal(&cond);
	}

	pthread_mutex_unlock(&mutex);

	// let the thread worker do the rest

	return ok;
}
Beispiel #4
0
/*! Get sample frames
	\param buf		pointer array to channel buffers
	\param frames	number of maximum frames to get
	\return			frames put into buffers
*/
int Stream::doGet(int ch,float *const *buf,int frames,float sr)
{
	ASSERT(ch > 0 && frames >= 0 && sr > 0);

	if(isOk() && !isInitializing()) {
		// signal thread worker
		pthread_cond_signal(&cond);

		// check/(re)allocate buffers

		int strch = getChannels();
		if(bufs && bufch < strch) { 
			delete[] decoded;
			for(int i = 0; i < bufch; ++i) src_delete(src_state[i]);
			delete[] src_state;
			delete[] bufs;	bufs = NULL; 
		}

		if(!bufs) {
			if(bufch < strch) bufch = strch;
			bufs = new float *[bufch];
			decoded = new Fifo<float>[bufch];

			src_state = new SRC_STATE *[bufch];
			for(int i = 0; i < bufch; ++i) {
				int error;
				src_state[i] = src_new(SRC_ZERO_ORDER_HOLD,1,&error);
				if(!src_state[i]) post("src init error %i",error);
			}
		}

		// get frames

		float ratio = sr/getSamplerate();
		int frneed = (int)(frames/ratio)+DECMORE;  // number of frames to read from decoder fifo

		if(decoded[0].Size() < frneed) {
			// fifos are too small -> resize them (while keeping their contents)
			for(int i = 0; i < bufch; ++i) decoded[i].Resize(frneed,true);
		}

		// how many frames do we need to get from decoder?
		int frread = frneed-decoded[0].Have();

		int ret = state == ST_WAIT?0:DataRead(frread);

		if(ret < 0) {
			if(debug) post("read error");
			// clear output
			for(int c = 0; c < ch; ++c)
				memset(buf[c],0,frames*sizeof *buf[c]);
			return 0;
		}
		else {
			// how many channels do we really need for output?
			// this should be set elsewhere, because we can't change anyway!!! 
			// (SRC_STATE for dangling channels would be incorrect)
			int cmin = strch;
			if(ch < cmin) cmin = ch;

			// write data to fifo
			for(int i = 0; i < cmin; ++i) {
				int wr = decoded[i].Write(ret,bufs[i]);
				if(wr < ret) post("fifo overflow");
			}

//			state = ST_PROCESS;

			if(ratio == 1) {
				// no resampling necessary

				// hopefully all channel fifos advance uniformly.....
				for(int i = 0; i < cmin; ++i) {

					for(int got = 0; got < frames; ) {
						int cnt = frames-got;

						if(decoded[i].Have()) {
							got += decoded[i].Read(cnt,buf[i]+got);
						}
						else {
							state = ST_WAIT;
							if(debug) post("fifo underrun");

							// Buffer underrun!! -> zero output buffer
							memset(buf[i]+got,0,cnt*sizeof(*buf[i]));
							got += cnt;
						}
					}
				}
			}
			else 
			{
				SRC_DATA src_data;
				src_data.src_ratio = ratio;
				src_data.end_of_input = 0;

				// hopefully all channel fifos advance uniformly.....
				for(int i = 0; i < cmin; ++i) {
					src_set_ratio(src_state[i],ratio);

					for(int got = 0; got < frames; ) {
						src_data.data_out = buf[i]+got;
						src_data.output_frames = frames-got;

						if(decoded[i].Have()) {
							src_data.data_in = decoded[i].ReadPtr();
							src_data.input_frames = decoded[i].ReadSamples();

							int err = src_process(src_state[i],&src_data);
							if(err) post("src_process error %i",err);

							// advance buffer
							decoded[i].Read(src_data.input_frames_used,NULL);
						}
						else {
							state = ST_WAIT;
							if(debug) post("fifo underrun");

							// Buffer underrun!! -> zero output buffer
							memset(src_data.data_out,0,src_data.output_frames*sizeof(*src_data.data_out));
							src_data.output_frames_gen = src_data.output_frames;
						}
						got += src_data.output_frames_gen;
					}
				}
			}

			// zero remaining channels
			for(int c = cmin; c < ch; ++c)
				memset(buf[c],0,frames*sizeof *buf[c]);

			return ret;
		}
	}
	else {
		for(int c = 0; c < ch; ++c)
			memset(buf[c],0,frames*sizeof *buf[c]);
		return 0;
	}
}