예제 #1
0
파일: ole2dup.c 프로젝트: mingpen/OpenNT
// translate string form of CLSID into binary form; tries Ole1Class too.
// errors: E_INVALIDARG, CO_E_CLASSSTRING, REGDB_E_WRITEREGDB
STDAPI SHCLSIDFromString(LPCTSTR lpsz, LPCLSID lpclsid)
{
    if (lpsz == NULL) {
        *lpclsid = CLSID_NULL;
        return NOERROR;
    }

    return GUIDFromString(lpsz,lpclsid) ? NOERROR : ResultFromScode(CO_E_CLASSSTRING);
}
예제 #2
0
파일: comdthk.c 프로젝트: shuowen/OpenNT
//+---------------------------------------------------------------------------
//
//  Function:   CLSIDFromString, Remote
//
//  History:    Straight from OLE2 sources
//
//----------------------------------------------------------------------------
STDAPI CLSIDFromString(LPSTR lpsz, LPCLSID pclsid)
{
    HRESULT hr;

    thkDebugOut((DEB_ITRACE, "CLSIDFromString\n"));

    //
    //	The 16-bit OLE2 application "Family Tree Maker" always passes a bad
    //	string to CLSIDFromString.  We need to make sure we fail in the exact
    //	same way with the interop layer.  This will also provide a speed
    //	improvement since we only need to remote to the 32bit version of
    //	CLSIDFromString when the string provided does not start with '{'.
    //
    if (lpsz[0] == '{')
        return GUIDFromString(lpsz, pclsid)
               ? NOERROR : ResultFromScode(CO_E_CLASSSTRING);

    // Note: Corel calls this function prior to calling
    //       CoInitialize so use CheckInit

    return (HRESULT)CallObjectInWOWCheckInit(THK_API_METHOD(THK_API_CLSIDFromString),
            PASCAL_STACK_PTR(lpsz));
}
예제 #3
0
BOOL CALLBACK DSound51::ConfigProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	int wmId,wmEvent;
	int tSel=0;

	switch(uMsg)
	{
		case WM_INITDIALOG:

			haveGuid = ! FAILED(GUIDFromString(Config_DSound51.Device,&DevGuid));
			SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_RESETCONTENT,0,0);

			ndevs=0;
			DirectSoundEnumerate(DSEnumCallback,NULL);

			tSel=-1;
			for(int i=0;i<ndevs;i++)
			{
				SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_ADDSTRING,0,(LPARAM)devices[i].name);
				if(haveGuid && IsEqualGUID(devices[i].guid,DevGuid))
				{
					tSel=i;
				}
			}

			if(tSel>=0)
			{
				SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_SETCURSEL,tSel,0);
			}

			INIT_SLIDER(IDC_LEFT_GAIN_SLIDER,0,512,64,16,8);
			INIT_SLIDER(IDC_RIGHT_GAIN_SLIDER,0,512,64,16,8);
			INIT_SLIDER(IDC_RLEFT_GAIN_SLIDER,0,512,64,16,8);
			INIT_SLIDER(IDC_RRIGHT_GAIN_SLIDER,0,512,64,16,8);
			INIT_SLIDER(IDC_CENTER_GAIN_SLIDER,0,512,64,16,8);
			INIT_SLIDER(IDC_LFE_SLIDER,0,512,64,16,8);
			INIT_SLIDER(IDC_LR_CENTER_SLIDER,0,512,64,16,8);

			AssignSliderValue( hWnd, IDC_LEFT_GAIN_SLIDER, IDC_LEFT_GAIN_EDIT, Config_DSound51.GainL );
			AssignSliderValue( hWnd, IDC_RIGHT_GAIN_SLIDER, IDC_RIGHT_GAIN_EDIT, Config_DSound51.GainR );
			AssignSliderValue( hWnd, IDC_RLEFT_GAIN_SLIDER, IDC_RLEFT_GAIN_EDIT, Config_DSound51.GainSL );
			AssignSliderValue( hWnd, IDC_RRIGHT_GAIN_SLIDER, IDC_RRIGHT_GAIN_EDIT, Config_DSound51.GainSR );
			AssignSliderValue( hWnd, IDC_CENTER_GAIN_SLIDER, IDC_CENTER_GAIN_EDIT, Config_DSound51.GainC);
			AssignSliderValue( hWnd, IDC_LFE_SLIDER, IDC_LFE_EDIT, Config_DSound51.GainLFE);
			AssignSliderValue( hWnd, IDC_LR_CENTER_SLIDER, IDC_LR_CENTER_EDIT, Config_DSound51.AddCLR );

			char temp[128];
			INIT_SLIDER( IDC_BUFFERS_SLIDER, 2, MAX_BUFFER_COUNT, 2, 1, 1 );
			SendMessage(GetDlgItem(hWnd,IDC_BUFFERS_SLIDER),TBM_SETPOS,TRUE,Config_DSound51.NumBuffers);
			sprintf_s(temp, 128, "%d (%d ms latency)",Config_DSound51.NumBuffers, 1000 / (96000 / (Config_DSound51.NumBuffers * BufferSize)));
			SetWindowText(GetDlgItem(hWnd,IDC_LATENCY_LABEL2),temp);
			break;

		case WM_COMMAND:
			wmId    = LOWORD(wParam);
			wmEvent = HIWORD(wParam);
			// Parse the menu selections:
			switch (wmId)
			{
				case IDOK:
					{
						int i = (int)SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_GETCURSEL,0,0);

						if(!devices[i].hasGuid)
						{
							Config_DSound51.Device[0]=0; // clear device name to ""
						}
						else
						{
							sprintf_s(Config_DSound51.Device,256,"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
								devices[i].guid.Data1,
								devices[i].guid.Data2,
								devices[i].guid.Data3,
								devices[i].guid.Data4[0],
								devices[i].guid.Data4[1],
								devices[i].guid.Data4[2],
								devices[i].guid.Data4[3],
								devices[i].guid.Data4[4],
								devices[i].guid.Data4[5],
								devices[i].guid.Data4[6],
								devices[i].guid.Data4[7]
								);

							Config_DSound51.NumBuffers = GetSliderValue( hWnd, IDC_BUFFERS_SLIDER );
							Config_DSound51.GainL = GetSliderValue( hWnd, IDC_LEFT_GAIN_SLIDER );
							Config_DSound51.GainR = GetSliderValue( hWnd, IDC_RIGHT_GAIN_SLIDER );
							Config_DSound51.GainSL = GetSliderValue( hWnd, IDC_RLEFT_GAIN_SLIDER );
							Config_DSound51.GainSR = GetSliderValue( hWnd, IDC_RRIGHT_GAIN_SLIDER );
							Config_DSound51.GainLFE = GetSliderValue( hWnd, IDC_LFE_SLIDER );
							Config_DSound51.GainC = GetSliderValue( hWnd, IDC_CENTER_GAIN_SLIDER );
							Config_DSound51.AddCLR = GetSliderValue( hWnd, IDC_LR_CENTER_SLIDER );

							if( Config_DSound51.NumBuffers < 2 ) Config_DSound51.NumBuffers = 2;
							if( Config_DSound51.NumBuffers > MAX_BUFFER_COUNT ) Config_DSound51.NumBuffers = MAX_BUFFER_COUNT;
						}
					}
					EndDialog(hWnd,0);
					break;
				case IDCANCEL:
					EndDialog(hWnd,0);
					break;
				default:
					return FALSE;
			}
			break;

		case WM_HSCROLL:
			wmId    = LOWORD(wParam);
			wmEvent = HIWORD(wParam);
			switch(wmId) {
				//case TB_ENDTRACK:
				//case TB_THUMBPOSITION:
				case TB_LINEUP:
				case TB_LINEDOWN:
				case TB_PAGEUP:
				case TB_PAGEDOWN:
					wmEvent=(int)SendMessage((HWND)lParam,TBM_GETPOS,0,0);
				case TB_THUMBTRACK:
					if( wmEvent < 2 ) wmEvent = 2;
					if( wmEvent > MAX_BUFFER_COUNT ) wmEvent = MAX_BUFFER_COUNT;
					SendMessage((HWND)lParam,TBM_SETPOS,TRUE,wmEvent);
					sprintf_s(temp,128,"%d (%d ms latency)",wmEvent, 1000 / (96000 / (wmEvent * BufferSize)));
					SetWindowText(GetDlgItem(hWnd,IDC_LATENCY_LABEL2),temp);
					break;
				default:
					return FALSE;
			}
			break;

		case WM_VSCROLL:
			HANDLE_SCROLL_MESSAGE(IDC_LEFT_GAIN_SLIDER,IDC_LEFT_GAIN_EDIT);
			HANDLE_SCROLL_MESSAGE(IDC_RIGHT_GAIN_SLIDER,IDC_RIGHT_GAIN_EDIT);
			HANDLE_SCROLL_MESSAGE(IDC_RLEFT_GAIN_SLIDER,IDC_RLEFT_GAIN_EDIT);
			HANDLE_SCROLL_MESSAGE(IDC_RRIGHT_GAIN_SLIDER,IDC_RRIGHT_GAIN_EDIT);
			HANDLE_SCROLL_MESSAGE(IDC_CENTER_GAIN_SLIDER,IDC_CENTER_GAIN_EDIT);
			HANDLE_SCROLL_MESSAGE(IDC_LFE_SLIDER,IDC_LFE_EDIT);
			HANDLE_SCROLL_MESSAGE(IDC_LR_CENTER_SLIDER,IDC_LR_CENTER_EDIT);

		default:
			return FALSE;
	}
	return TRUE;
}
예제 #4
0
DSound51_Driver::DSound51_Driver( SndBuffer *sb ) :
	buff( sb ),
	numBuffers( Config_DSound51.NumBuffers ),
	dpl2( Config_DSound51.LowpassLFE, SampleRate )
{
	//
	// Initialize DSound
	//
	GUID cGuid;
	bool success  = false;

	if( (strlen(Config_DSound51.Device)>0)&&(!FAILED(GUIDFromString(Config_DSound51.Device,&cGuid))))
	{
		if( !FAILED( DirectSoundCreate8(&cGuid,&dsound,NULL) ) )
			success = true;
	}

	// if the GUID failed, just open up the default dsound driver:
	if( !success )
	{
		verifyc(DirectSoundCreate8(NULL,&dsound,NULL));
	}

	verifyc(dsound->SetCooperativeLevel(GetDesktopWindow(),DSSCL_PRIORITY));
	IDirectSoundBuffer* buffer_;
	DSBUFFERDESC desc;

	// Set up WAV format structure.

	memset(&wfx, 0, sizeof(WAVEFORMATEX));
	wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
	wfx.Format.nSamplesPerSec = SampleRate;
	wfx.Format.nChannels=6;
	wfx.Format.wBitsPerSample = 16;
	wfx.Format.nBlockAlign = wfx.Format.nChannels*wfx.Format.wBitsPerSample/8;
	wfx.Format.nAvgBytesPerSec = SampleRate * wfx.Format.nBlockAlign;
	wfx.Format.cbSize=22;
	wfx.Samples.wValidBitsPerSample=0;
	wfx.dwChannelMask=SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT;
	wfx.SubFormat=KSDATAFORMAT_SUBTYPE_PCM;

	verifyc(dsound->SetSpeakerConfig(DSSPEAKER_5POINT1));

	// Set up DSBUFFERDESC structure.

	memset(&desc, 0, sizeof(DSBUFFERDESC));
	desc.dwSize = sizeof(DSBUFFERDESC);
	desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY;// _CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
	desc.dwBufferBytes = DSound51::BufferSizeBytes * numBuffers;
	desc.lpwfxFormat = &wfx.Format;

	desc.dwFlags |=DSBCAPS_LOCSOFTWARE;
	desc.dwFlags|=DSBCAPS_GLOBALFOCUS;

	verifyc(dsound->CreateSoundBuffer(&desc,&buffer_,0));
	verifyc(buffer_->QueryInterface(IID_IDirectSoundBuffer8,(void**)&buffer));
	buffer_->Release();

	verifyc(buffer->QueryInterface(IID_IDirectSoundNotify8,(void**)&buffer_notify));

	DSBPOSITIONNOTIFY not[DSound51::MAX_BUFFER_COUNT];

	for(u32 i=0;i<numBuffers;i++)
	{
		buffer_events[i]=CreateEvent(NULL,FALSE,FALSE,NULL);
		not[i].dwOffset=(wfx.Format.nBlockAlign*2 + DSound51::BufferSizeBytes*(i+1))%desc.dwBufferBytes;
		not[i].hEventNotify=buffer_events[i];
	}

	buffer_notify->SetNotificationPositions(numBuffers,not);

	LPVOID p1=0,p2=0;
	DWORD s1=0,s2=0;

	verifyc(buffer->Lock(0,desc.dwBufferBytes,&p1,&s1,&p2,&s2,0));
	assert(p2==0);
	memset(p1,0,s1);
	verifyc(buffer->Unlock(p1,s1,p2,s2));

	//Play the buffer !
	verifyc(buffer->Play(0,0,DSBPLAY_LOOPING));

	// Start Thread
	myLastWrite = 0;
	dsound_running=true;
	thread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RThread,this,0,&tid);
	SetThreadPriority(thread,THREAD_PRIORITY_TIME_CRITICAL);
}
예제 #5
0
	static BOOL CALLBACK ConfigProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
	{
		int wmId,wmEvent;
		int tSel=0;

		switch(uMsg)
		{
			case WM_INITDIALOG:
			{
				wchar_t temp[128];
				
				char temp2[192];
				sprintf_s( temp2, "%S", Config_DSoundOut.Device.c_str() );
				haveGuid = ! FAILED(GUIDFromString(temp2,&DevGuid));
				SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_RESETCONTENT,0,0); 

				ndevs=0;
				DirectSoundEnumerate( DSEnumCallback, NULL );

				tSel=-1;
				for(int i=0;i<ndevs;i++)
				{
					SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_ADDSTRING,0,(LPARAM)devices[i].name.c_str());
					if(haveGuid && IsEqualGUID(devices[i].guid,DevGuid))
					{
						tSel=i;
					}
				}

				if(tSel>=0)
				{
					SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_SETCURSEL,tSel,0);
				}

				INIT_SLIDER( IDC_BUFFERS_SLIDER, 2, MAX_BUFFER_COUNT, 2, 1, 1 );
				SendMessage(GetDlgItem(hWnd,IDC_BUFFERS_SLIDER),TBM_SETPOS,TRUE,Config_DSoundOut.NumBuffers); 
				swprintf_s(temp, _T("%d (%d ms latency)"),Config_DSoundOut.NumBuffers, 1000 / (96000 / (Config_DSoundOut.NumBuffers * BufferSize)));
				SetWindowText(GetDlgItem(hWnd,IDC_LATENCY_LABEL),temp);
			}
			break;

			case WM_COMMAND:
			{
				wchar_t temp[128];

				wmId    = LOWORD(wParam); 
				wmEvent = HIWORD(wParam); 
				// Parse the menu selections:
				switch (wmId)
				{
					case IDOK:
						{
							int i = (int)SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_GETCURSEL,0,0);
							
							if(!devices[i].hasGuid)
							{
								Config_DSoundOut.Device[0] = 0; // clear device name to ""
							}
							else
							{
								swprintf_s(temp, _T("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
									devices[i].guid.Data1,
									devices[i].guid.Data2,
									devices[i].guid.Data3,
									devices[i].guid.Data4[0],
									devices[i].guid.Data4[1],
									devices[i].guid.Data4[2],
									devices[i].guid.Data4[3],
									devices[i].guid.Data4[4],
									devices[i].guid.Data4[5],
									devices[i].guid.Data4[6],
									devices[i].guid.Data4[7]
								);
								Config_DSoundOut.Device = temp;
							}

							Config_DSoundOut.NumBuffers = (int)SendMessage( GetDlgItem( hWnd, IDC_BUFFERS_SLIDER ), TBM_GETPOS, 0, 0 );

							if( Config_DSoundOut.NumBuffers < 2 ) Config_DSoundOut.NumBuffers = 2;
							if( Config_DSoundOut.NumBuffers > MAX_BUFFER_COUNT ) Config_DSoundOut.NumBuffers = MAX_BUFFER_COUNT;
						}
						EndDialog(hWnd,0);
						break;
					case IDCANCEL:
						EndDialog(hWnd,0);
						break;
					default:
						return FALSE;
				}
			}
			break;

			case WM_HSCROLL:
			{
				wmId    = LOWORD(wParam); 
				wmEvent = HIWORD(wParam); 
				switch(wmId) {
					//case TB_ENDTRACK:
					//case TB_THUMBPOSITION:
					case TB_LINEUP:
					case TB_LINEDOWN:
					case TB_PAGEUP:
					case TB_PAGEDOWN:
						wmEvent=(int)SendMessage((HWND)lParam,TBM_GETPOS,0,0);
					case TB_THUMBTRACK:
					{
						wchar_t temp[128];
						if( wmEvent < 2 ) wmEvent = 2;
						if( wmEvent > MAX_BUFFER_COUNT ) wmEvent = MAX_BUFFER_COUNT;
						SendMessage((HWND)lParam,TBM_SETPOS,TRUE,wmEvent);
						swprintf_s(temp,_T("%d (%d ms latency)"),wmEvent, 1000 / (96000 / (wmEvent * BufferSize)));
						SetWindowText(GetDlgItem(hWnd,IDC_LATENCY_LABEL),temp);
						break;
					}
					default:
						return FALSE;
				}
			}
			break;

			default:
				return FALSE;
		}
		return TRUE;
	}
예제 #6
0
	s32 Init()
	{
		numBuffers = Config_DSoundOut.NumBuffers;

		//
		// Initialize DSound
		//
		GUID cGuid;

		try
		{
			if( Config_DSoundOut.Device.empty() )
				throw std::runtime_error( "screw it" );
			
			// Convert from unicode to ANSI:
			char guid[256];
			sprintf_s( guid, "%S", Config_DSoundOut.Device.c_str() );
			
			if( (FAILED(GUIDFromString( guid, &cGuid ))) ||
				FAILED( DirectSoundCreate8(&cGuid,&dsound,NULL) ) )
					throw std::runtime_error( "try again?" );
		}
		catch( std::runtime_error& )
		{
			// if the GUID failed, just open up the default dsound driver:
			if( FAILED(DirectSoundCreate8(NULL,&dsound,NULL) ) )
				throw std::runtime_error( "DirectSound failed to initialize!" );
		}

		if( FAILED(dsound->SetCooperativeLevel(GetDesktopWindow(),DSSCL_PRIORITY)) )
			throw std::runtime_error( "DirectSound Error: Cooperative level could not be set." );
		
		// Determine the user's speaker configuration, and select an expansion option as needed.
		// FAIL : Directsound doesn't appear to support audio expansion >_<
		
		DWORD speakerConfig = 2;
		//dsound->GetSpeakerConfig( &speakerConfig );

		IDirectSoundBuffer* buffer_;
 		DSBUFFERDESC desc; 
	 
		// Set up WAV format structure. 
	 
		memset(&wfx, 0, sizeof(WAVEFORMATEX)); 
		wfx.wFormatTag		= WAVE_FORMAT_PCM;
		wfx.nSamplesPerSec	= SampleRate;
		wfx.nChannels		= (WORD)speakerConfig;
		wfx.wBitsPerSample	= 16;
		wfx.nBlockAlign		= 2*(WORD)speakerConfig;
		wfx.nAvgBytesPerSec	= SampleRate * wfx.nBlockAlign;
		wfx.cbSize			= 0;

		uint BufferSizeBytes = BufferSize * wfx.nBlockAlign;
	 
		// Set up DSBUFFERDESC structure. 
	 
		memset(&desc, 0, sizeof(DSBUFFERDESC)); 
		desc.dwSize = sizeof(DSBUFFERDESC); 
		desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY;// _CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; 
		desc.dwBufferBytes = BufferSizeBytes * numBuffers;
		desc.lpwfxFormat = &wfx;
	 
		desc.dwFlags |= DSBCAPS_LOCSOFTWARE;
		desc.dwFlags |= DSBCAPS_GLOBALFOCUS;
	 
		if( FAILED(dsound->CreateSoundBuffer(&desc,&buffer_,0) ) )
			throw std::runtime_error( "DirectSound Error: Interface could not be queried." );
		
		if(	FAILED(buffer_->QueryInterface(IID_IDirectSoundBuffer8,(void**)&buffer)) )
			throw std::runtime_error( "DirectSound Error: Interface could not be queried." );

		buffer_->Release();
		verifyc( buffer->QueryInterface(IID_IDirectSoundNotify8,(void**)&buffer_notify) );

		DSBPOSITIONNOTIFY not[MAX_BUFFER_COUNT];
	 
		for(u32 i=0;i<numBuffers;i++)
		{
			// [Air] note: wfx.nBlockAlign modifier was *10 -- seems excessive to me but maybe
			// it was needed for some quirky driver?  Theoretically we want the notification as soon
			// as possible after the buffer has finished playing.

			buffer_events[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
			not[i].dwOffset = (wfx.nBlockAlign + BufferSizeBytes*(i+1)) % desc.dwBufferBytes;
			not[i].hEventNotify = buffer_events[i];
		}
	 
		buffer_notify->SetNotificationPositions(numBuffers,not);
	 
		LPVOID p1=0,p2=0;
		DWORD s1=0,s2=0;
	 
		verifyc(buffer->Lock(0,desc.dwBufferBytes,&p1,&s1,&p2,&s2,0));
		assert(p2==0);
		memset(p1,0,s1);
		verifyc(buffer->Unlock(p1,s1,p2,s2));
	 
		//Play the buffer !
		verifyc(buffer->Play(0,0,DSBPLAY_LOOPING));

		// Start Thread
		myLastWrite = 0;
		dsound_running = true;
		thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RThread<StereoOut16>,this,0,&tid);
		SetThreadPriority(thread,THREAD_PRIORITY_ABOVE_NORMAL);

		return 0;
	}
예제 #7
0
	s32 Init()
	{
		CoInitializeEx( NULL, COINIT_MULTITHREADED );

		//
		// Initialize DSound
		//
		GUID cGuid;

		try
		{
			if( m_Device.empty() )
				throw std::runtime_error( "screw it" );

			// Convert from unicode to ANSI:
			char guid[256];
			sprintf_s( guid, "%S", m_Device.c_str() );

			if( (FAILED(GUIDFromString( guid, &cGuid ))) ||
				FAILED( DirectSoundCreate8(&cGuid,&dsound,NULL) ) )
					throw std::runtime_error( "try again?" );
		}
		catch( std::runtime_error& )
		{
			// if the GUID failed, just open up the default dsound driver:
			if( FAILED(DirectSoundCreate8(NULL,&dsound,NULL) ) )
				throw std::runtime_error( "DirectSound failed to initialize!" );
		}

		if( FAILED(dsound->SetCooperativeLevel(GetDesktopWindow(),DSSCL_PRIORITY)) )
			throw std::runtime_error( "DirectSound Error: Cooperative level could not be set." );

		// Determine the user's speaker configuration, and select an expansion option as needed.
		// FAIL : Directsound doesn't appear to support audio expansion >_<

		DWORD speakerConfig = 2;
		//dsound->GetSpeakerConfig( &speakerConfig );

		IDirectSoundBuffer* buffer_;
 		DSBUFFERDESC desc;

		// Set up WAV format structure.

		memset(&wfx, 0, sizeof(WAVEFORMATEX));
		wfx.wFormatTag		= WAVE_FORMAT_PCM;
		wfx.nSamplesPerSec	= SampleRate;
		wfx.nChannels		= (WORD)speakerConfig;
		wfx.wBitsPerSample	= 16;
		wfx.nBlockAlign		= 2*(WORD)speakerConfig;
		wfx.nAvgBytesPerSec	= SampleRate * wfx.nBlockAlign;
		wfx.cbSize			= 0;

		uint BufferSizeBytes = BufferSize * wfx.nBlockAlign;

		// Set up DSBUFFERDESC structure.

		memset(&desc, 0, sizeof(DSBUFFERDESC));
		desc.dwSize = sizeof(DSBUFFERDESC);
		desc.dwFlags =  DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY;
		desc.dwBufferBytes = BufferSizeBytes * m_NumBuffers;
		desc.lpwfxFormat = &wfx;

		// Try a hardware buffer first, and then fall back on a software buffer if
		// that one fails.

		desc.dwFlags |= m_UseHardware ? DSBCAPS_LOCHARDWARE : DSBCAPS_LOCSOFTWARE;
		desc.dwFlags |= m_DisableGlobalFocus ? DSBCAPS_STICKYFOCUS : DSBCAPS_GLOBALFOCUS;

		if( FAILED(dsound->CreateSoundBuffer(&desc, &buffer_, 0) ) )
		{
			if( m_UseHardware )
			{
				desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE;
				desc.dwFlags |= m_DisableGlobalFocus ? DSBCAPS_STICKYFOCUS : DSBCAPS_GLOBALFOCUS;

				if( FAILED(dsound->CreateSoundBuffer(&desc, &buffer_, 0) ) )
					throw std::runtime_error( "DirectSound Error: Buffer could not be created." );
			}

			throw std::runtime_error( "DirectSound Error: Buffer could not be created." );
		}
		if(	FAILED(buffer_->QueryInterface(IID_IDirectSoundBuffer8,(void**)&buffer)) || buffer == NULL )
			throw std::runtime_error( "DirectSound Error: Interface could not be queried." );

		buffer_->Release();
		verifyc( buffer->QueryInterface(IID_IDirectSoundNotify8,(void**)&buffer_notify) );

		DSBPOSITIONNOTIFY not[MAX_BUFFER_COUNT];

		for(uint i=0;i<m_NumBuffers;i++)
		{
			buffer_events[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
			not[i].dwOffset = (wfx.nBlockAlign + BufferSizeBytes*(i+1)) % desc.dwBufferBytes;
			not[i].hEventNotify = buffer_events[i];
		}

		buffer_notify->SetNotificationPositions(m_NumBuffers,not);

		LPVOID p1=0,p2=0;
		DWORD s1=0,s2=0;

		verifyc(buffer->Lock(0,desc.dwBufferBytes,&p1,&s1,&p2,&s2,0));
		assert(p2==0);
		memset(p1,0,s1);
		verifyc(buffer->Unlock(p1,s1,p2,s2));

		//Play the buffer !
		verifyc(buffer->Play(0,0,DSBPLAY_LOOPING));

		// Start Thread
		myLastWrite = 0;
		dsound_running = true;
		thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RThread<StereoOut16>,this,0,&tid);
		SetThreadPriority(thread,THREAD_PRIORITY_ABOVE_NORMAL);

		return 0;
	}
예제 #8
0
// This routine is called during IOCTL_POWER_CAPABILITIES processing.  It 
// returns TRUE if successful and FALSE if not.  The caller is expected to
// destroy the CDiskPower object if this routine fails.
BOOL CDiskPower::Init(CDisk *pDiskParent)
{
    DWORD dwStatus;
    GUID gPMClass;
    int nPriority = 250;    // THREAD_PRIORITY_ABOVE_NORMAL
    HANDLE hActive = NULL;
    BOOL fOk = TRUE;

    PREFAST_DEBUGCHK(pDiskParent != NULL);
    DEBUGMSG(ZONE_INIT, (_T("+CDiskPower::Init(): parent is 0x%08x\r\n"), pDiskParent));

    // record the parent device
    m_pDisk = pDiskParent;

    // get a pointer to the PM APIs we need
    if(fOk) {
        HMODULE hmCoreDll = LoadLibrary(L"coredll.dll");
        if(hmCoreDll == NULL) {
            DEBUGMSG(ZONE_INIT || ZONE_ERROR, (_T("CDevicePower::Init: LoadLibrary('coredll.dll') failed %d\r\n"), GetLastError()));
            fOk = FALSE;
        } else {
            m_pfnDevicePowerNotify = (DWORD ((*)(PVOID, CEDEVICE_POWER_STATE, DWORD))) GetProcAddress(hmCoreDll, L"DevicePowerNotify");
            if(m_pfnDevicePowerNotify == NULL) {
                DEBUGMSG(ZONE_INIT || ZONE_ERROR, (_T("CDevicePower::Init: GetProcAddress('DevicePowerNotify') failed %d\r\n"), GetLastError()));
                fOk = FALSE;
            }
            // we're explicitly linked with coredll so we don't need the handle
            FreeLibrary(hmCoreDll);
        }
    }

    // read registry configuration
    if(fOk) {
        HKEY hk;
        BOOL fGotClass = FALSE;
        WCHAR szClass[64] = {0}; // big enough for a GUID

        // determine the power class we are advertising
        dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_pDisk->m_szDeviceKey, 0, 0, &hk);
        if(dwStatus == ERROR_SUCCESS) {
            // read the PM class
            DWORD dwSize = sizeof(szClass);
            dwStatus = RegQueryValueEx(hk, L"PowerClass", NULL, NULL, (LPBYTE) szClass, &dwSize);
            if(dwStatus == ERROR_SUCCESS) {
                fGotClass = TRUE;
            }

            // get the inactivity timeout
            DWORD dwValue;
            dwSize = sizeof(dwValue);
            dwStatus = RegQueryValueEx(hk, L"InactivityTimeout", NULL, NULL, (LPBYTE) &dwValue, &dwSize);
            if(dwStatus == ERROR_SUCCESS) {
                m_dwPowerTimeout = dwValue;
            }
            DEBUGMSG(ZONE_INIT, (_T("CDiskPower::Init: inactivity timeout is %u ms\r\n"), m_dwPowerTimeout));
            
            // get the inactivity timeout
            dwSize = sizeof(dwValue);
            dwStatus = RegQueryValueEx(hk, L"TimeoutDx", NULL, NULL, (LPBYTE) &dwValue, &dwSize);
            if(dwStatus == ERROR_SUCCESS) {
                if(VALID_DX((CEDEVICE_POWER_STATE)dwValue) && dwValue != D3) {
                    m_timeoutDx = (CEDEVICE_POWER_STATE) dwValue;
                } else {
                    DEBUGMSG(ZONE_WARNING, (_T("CDiskPower::Init: invalid or unsupported timeout device power state %d (0x%x)\r\n"), dwValue, dwValue));
                }
            }
            DEBUGMSG(ZONE_INIT, (_T("CDiskPower::Init: timeout state is D%d\r\n"), m_timeoutDx));
            
            // get the inactivity timeout
            dwSize = sizeof(dwValue);
            dwStatus = RegQueryValueEx(hk, L"InactivityPriority256", NULL, NULL, (LPBYTE) &dwValue, &dwSize);
            if(dwStatus == ERROR_SUCCESS) {
                nPriority = (int) dwValue;
            }
            DEBUGMSG(ZONE_INIT, (_T("CDiskPower::Init: inactivity timeout thread priority is %d\r\n"), nPriority));
            
            RegCloseKey(hk);
        }   

        // did we get a class string?
        if(!fGotClass) {
            // no, use the default disk class
            wcsncpy(szClass, PMCLASS_BLOCK_DEVICE, dim(szClass));
            szClass[dim(szClass) - 1] = 0;
        }

        // convert to a GUID
        fOk = GUIDFromString(szClass, &gPMClass);
        if(!fOk) {
            DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: invalid power management class '%s'\r\n"),
                szClass));
        }
    }

    // get our active key from the registry
    if(fOk) {
        HKEY hk;
        dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_pDisk->m_szActiveKey, 0, 0, &hk);
        if(dwStatus == ERROR_SUCCESS) {
            DWORD dwValue;
            DWORD dwSize = sizeof(dwValue);
            dwStatus = RegQueryValueEx(hk, DEVLOAD_HANDLE_VALNAME, NULL, NULL, (LPBYTE) &dwValue, &dwSize);
            if(dwStatus != ERROR_SUCCESS) {
                DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: can't read '%s' from '%s'\r\n"),
                    DEVLOAD_HANDLE_VALNAME, m_pDisk->m_szActiveKey));
                fOk = FALSE;
            } else {
                DEBUGCHK(dwValue != 0);
                hActive = (HANDLE) dwValue;
            }
        }
    }

    // figure out the name we are using
    if(fOk) {
        WCHAR szName[MAX_PATH];
        DWORD dwIndex = 0;
        do {
            DWORD dwSize = sizeof(szName);
            GUID gClass;
            fOk = EnumDeviceInterfaces(hActive, dwIndex, &gClass, szName, &dwSize);
            if(fOk && gPMClass == gClass) {
                // we found the interface
                break;
            }
            dwIndex++;
        } while(fOk);
        DEBUGMSG(!fOk && (ZONE_WARNING || ZONE_INIT), (_T("CDiskPower::Init: can't find PM interface\r\n")));

        // did we find the name?
        if(fOk) {
            // yes, allocate a name buffer to use to talk to the power manager
            DWORD dwChars = wcslen(PMCLASS_BLOCK_DEVICE) + wcslen(szName) + 2;  // class + separator + name + null
            LPWSTR pszPMName = (LPWSTR) LocalAlloc(LPTR, dwChars * sizeof(WCHAR));
            fOk = FALSE;        // assume failure
            if(pszPMName) {
                HRESULT hr = StringCchPrintfW(pszPMName, dwChars, L"{%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x}\\%s",
                    gPMClass.Data1, gPMClass.Data2, gPMClass.Data3,
                    (gPMClass.Data4[0] << 8) + gPMClass.Data4[1], gPMClass.Data4[2], gPMClass.Data4[3], 
                    gPMClass.Data4[4], gPMClass.Data4[5], gPMClass.Data4[6], gPMClass.Data4[7],
                    szName);
                if(SUCCEEDED(hr)) {
                    m_pszPMName = (LPCWSTR) pszPMName;
                    fOk = TRUE;
                }
            }
            DEBUGMSG(!fOk && (ZONE_WARNING || ZONE_INIT), (_T("CDiskPower::Init: can't find PM interface\r\n")));
        }
    }

    // create an event to tell the timeout thread about activity
    if(fOk) {
        m_hevPowerSignal = CreateEvent(NULL, FALSE, FALSE, NULL);
        m_hevDummy = CreateEvent(NULL, FALSE, FALSE, NULL);
        if(!m_hevPowerSignal || !m_hevDummy) {
            DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: couldn't create status events\r\n")));
            fOk = FALSE;
        }
    }

    // create the timeout thread
    if(fOk) {
        m_htPower = CreateThread(NULL, 0, DiskPowerThreadStub, this, 0, NULL);
        if(!m_htPower) {
            DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: CreateThread() failed %d\r\n"), GetLastError()));
            fOk = FALSE;
        } else {
            BOOL fSuccess = CeSetThreadPriority(m_htPower, nPriority);
            DEBUGMSG(!fSuccess && (ZONE_WARNING || ZONE_INIT), (_T("CDiskPower::Init: CeSetThreadPriority(%d) failed %d\r\n"), nPriority, GetLastError()));
        }
    }

    // disable the standby timer, since the PM is going to be controlling
    // the disk power state
    if(fOk) {
        if(!m_pDisk->SendDiskPowerCommand(ATA_NEW_CMD_IDLE, 0)) {
            DEBUGMSG(ZONE_WARNING || ZONE_INIT, (_T("CDiskPower::Init: disable standby timer failed\r\n")));
        }
    }

    // on error, cleanup will happen in the destructor
    DEBUGMSG(ZONE_INIT, (_T("-CDiskPower::Init(): returning %d\r\n"), fOk));
    return fOk;
}
예제 #9
0
	bool _ConfigProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
	{
		int wmId,wmEvent;
		int tSel = 0;

		switch(uMsg)
		{
			case WM_INITDIALOG:
			{
				wchar_t temp[128];

				haveGuid = !FAILED(GUIDFromString(m_Device, &DevGuid));
				SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_RESETCONTENT,0,0);

				ndevs=0;
				DirectSoundEnumerate( DSEnumCallback, NULL );

				tSel=-1;
				for(int i=0;i<ndevs;i++)
				{
					SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_ADDSTRING,0,(LPARAM)m_devices[i].name.wc_str());
					if(haveGuid && IsEqualGUID(m_devices[i].guid,DevGuid) || tSel < 0 && !m_devices[i].hasGuid)
						tSel = i;
				}

				if(tSel>=0)
					SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_SETCURSEL,tSel,0);

				INIT_SLIDER( IDC_BUFFERS_SLIDER, 2, MAX_BUFFER_COUNT, 2, 1, 1 );
				SendMessage(GetDlgItem(hWnd,IDC_BUFFERS_SLIDER),TBM_SETPOS,TRUE,m_NumBuffers);
				swprintf_s(temp, L"%d (%d ms latency)",m_NumBuffers, 1000 / (96000 / (m_NumBuffers * BufferSize)));
				SetWindowText(GetDlgItem(hWnd,IDC_LATENCY_LABEL),temp);

				SET_CHECK( IDC_GLOBALFOCUS_DISABLE, m_DisableGlobalFocus );
				SET_CHECK( IDC_USE_HARDWARE, m_UseHardware );
			}
			break;

			case WM_COMMAND:
			{
				wchar_t temp[128];

				wmId    = LOWORD(wParam);
				wmEvent = HIWORD(wParam);
				// Parse the menu selections:
				switch (wmId)
				{
					case IDOK:
					{
						int i = (int)SendMessage(GetDlgItem(hWnd,IDC_DS_DEVICE),CB_GETCURSEL,0,0);

						if(!m_devices[i].hasGuid)
						{
							m_Device[0] = 0; // clear device name to ""
						}
						else
						{
							swprintf_s(temp, L"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
								m_devices[i].guid.Data1,
								m_devices[i].guid.Data2,
								m_devices[i].guid.Data3,
								m_devices[i].guid.Data4[0],
								m_devices[i].guid.Data4[1],
								m_devices[i].guid.Data4[2],
								m_devices[i].guid.Data4[3],
								m_devices[i].guid.Data4[4],
								m_devices[i].guid.Data4[5],
								m_devices[i].guid.Data4[6],
								m_devices[i].guid.Data4[7]
							);
							m_Device = temp;
						}

						m_NumBuffers = (int)SendMessage( GetDlgItem( hWnd, IDC_BUFFERS_SLIDER ), TBM_GETPOS, 0, 0 );

						if( m_NumBuffers < 2 ) m_NumBuffers = 2;
						if( m_NumBuffers > MAX_BUFFER_COUNT ) m_NumBuffers = MAX_BUFFER_COUNT;

						EndDialog(hWnd,0);
					}
					break;

					case IDCANCEL:
						EndDialog(hWnd,0);
					break;

					HANDLE_CHECK( IDC_GLOBALFOCUS_DISABLE, m_DisableGlobalFocus );
					HANDLE_CHECK( IDC_USE_HARDWARE, m_UseHardware );

					default:
						return FALSE;
				}
			}
			break;

			case WM_HSCROLL:
			{
				wmId    = LOWORD(wParam);
				wmEvent = HIWORD(wParam);
				switch(wmId)
				{
					//case TB_ENDTRACK:
					//case TB_THUMBPOSITION:
					case TB_LINEUP:
					case TB_LINEDOWN:
					case TB_PAGEUP:
					case TB_PAGEDOWN:
						wmEvent = (int)SendMessage((HWND)lParam,TBM_GETPOS,0,0);
					case TB_THUMBTRACK:
					{
						wchar_t temp[128];
						if( wmEvent < 2 ) wmEvent = 2;
						if( wmEvent > MAX_BUFFER_COUNT ) wmEvent = MAX_BUFFER_COUNT;
						SendMessage((HWND)lParam,TBM_SETPOS,TRUE,wmEvent);
						swprintf_s(temp,L"%d (%d ms latency)",wmEvent, 1000 / (96000 / (wmEvent * BufferSize)));
						SetWindowText(GetDlgItem(hWnd,IDC_LATENCY_LABEL),temp);
						break;
					}
					default:
						return FALSE;
				}
			}
			break;

			default:
				return FALSE;
		}
		return TRUE;
	}