示例#1
0
HRESULT SetCapturenotification(LPDIRECTSOUNDCAPTUREBUFFER8 pDSCB){
#define cEvent 3
	LPDIRECTSOUNDNOTIFY8 pDSBNotify;
	WAVEFORMATEX wfx;
	HANDLE		rghEvent[cEvent];
	DSBPOSITIONNOTIFY rgdsbpn[cEvent];
	HRESULT hr;

	if (NULL == pDSCB) return E_INVALIDARG;
	if (FAILED(hr = pDSCB->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&pDSBNotify))){
		return hr;
	}
	if (FAILED(hr = pDSCB->GetFormat(&wfx, sizeof(WAVEFORMATEX), NULL)))
		return hr;
	for (int i = 0;  i< cEvent; ++i){
		rghEvent[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
		if (rghEvent[i] == NULL){
			hr = GetLastError();
			return hr;
		}
	}
	rgdsbpn[0].dwOffset = wfx.nAvgBytesPerSec/2 - 1;
	rgdsbpn[0].hEventNotify = rghEvent[0];

	rgdsbpn[1].dwOffset = wfx.nAvgBytesPerSec - 1;
	rgdsbpn[1].hEventNotify = rghEvent[1];

	rgdsbpn[2].dwOffset = DSBPN_OFFSETSTOP;
	rgdsbpn[2].hEventNotify = rghEvent[2];

	hr = pDSBNotify->SetNotificationPositions(cEvent, rgdsbpn);
	pDSBNotify->Release();
	return hr;
}
示例#2
0
//设置播放通知,一般用处有二:
//1. 通知程序写入下一段声音数据
//2. 通知做某一个操作
HRESULT SetStopNotification(HANDLE hEvent, LPDIRECTSOUNDBUFFER8 lpDsbSecondary){
	LPDIRECTSOUNDNOTIFY8 lpDsNotify;
	DSBPOSITIONNOTIFY PositionNotify;
	HRESULT hr;

	if (SUCCEEDED(hr = 
		lpDsbSecondary->QueryInterface(IID_IDirectSoundNotify8, (LPVOID*)lpDsNotify)
		)){
	        PositionNotify.dwOffset = DSBPN_OFFSETSTOP;
			PositionNotify.hEventNotify = hEvent;
			hr = lpDsNotify->SetNotificationPositions(1, &PositionNotify);
			lpDsNotify->Release();
	}
	return hr;
}
bool DirectSound::init(long sampleRate)
{
	HRESULT hr;
	DWORD freq;
	DSBUFFERDESC dsbdesc;
	int i;

	hr = CoCreateInstance( CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (LPVOID *)&pDirectSound );
	if( hr != S_OK ) {
		systemMessage( IDS_CANNOT_CREATE_DIRECTSOUND, NULL, hr );
		return false;
	}

	pDirectSound->Initialize( &DSDEVID_DefaultPlayback );
	if( hr != DS_OK ) {
		systemMessage( IDS_CANNOT_CREATE_DIRECTSOUND, NULL, hr );
		return false;
	}

	if( FAILED( hr = pDirectSound->SetCooperativeLevel( theApp.m_pMainWnd->GetSafeHwnd(), DSSCL_EXCLUSIVE ) ) ) {
		systemMessage( IDS_CANNOT_SETCOOPERATIVELEVEL, _T("Cannot SetCooperativeLevel %08x"), hr );
		return false;
	}


	// Create primary sound buffer
	ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
	dsbdesc.dwSize = sizeof(DSBUFFERDESC);
	dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
	if( dsoundDisableHardwareAcceleration ) {
		dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
	}

	if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbPrimary, NULL ) ) ) {
		systemMessage(IDS_CANNOT_CREATESOUNDBUFFER, _T("Cannot CreateSoundBuffer %08x"), hr);
		return false;
	}

	freq = sampleRate;
	// calculate the number of samples per frame first
	// then multiply it with the size of a sample frame (16 bit * stereo)
	soundBufferLen = ( freq / 60 ) * 4;
	soundBufferTotalLen = soundBufferLen * 10;
	soundNextPosition = 0;

	ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
	wfx.wFormatTag = WAVE_FORMAT_PCM;
	wfx.nChannels = 2;
	wfx.nSamplesPerSec = freq;
	wfx.wBitsPerSample = 16;
	wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
	wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

	if( FAILED( hr = dsbPrimary->SetFormat( &wfx ) ) ) {
		systemMessage( IDS_CANNOT_SETFORMAT_PRIMARY, _T("CreateSoundBuffer(primary) failed %08x"), hr );
		return false;
	}


	// Create secondary sound buffer
	ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
	dsbdesc.dwSize = sizeof(DSBUFFERDESC);
	dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS;
	if( dsoundDisableHardwareAcceleration ) {
		dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
	}
	dsbdesc.dwBufferBytes = soundBufferTotalLen;
	dsbdesc.lpwfxFormat = &wfx;

	if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbSecondary, NULL ) ) ) {
		systemMessage( IDS_CANNOT_CREATESOUNDBUFFER, _T("CreateSoundBuffer(secondary) failed %08x"), hr );
		return false;
	}

	if( FAILED( hr = dsbSecondary->SetCurrentPosition( 0 ) ) ) {
		systemMessage( 0, _T("dsbSecondary->SetCurrentPosition failed %08x"), hr );
		return false;
	}


	if( SUCCEEDED( hr = dsbSecondary->QueryInterface( IID_IDirectSoundNotify8, (LPVOID*)&dsbNotify ) ) ) {
		dsbEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
		DSBPOSITIONNOTIFY notify[10];
		for( i = 0; i < 10; i++ ) {
			notify[i].dwOffset = i * soundBufferLen;
			notify[i].hEventNotify = dsbEvent;
		}

		if( FAILED( dsbNotify->SetNotificationPositions( 10, notify ) ) ) {
			dsbNotify->Release();
			dsbNotify = NULL;
			CloseHandle(dsbEvent);
			dsbEvent = NULL;
		}
	}


	// Play primary buffer
	if( FAILED( hr = dsbPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ) ) {
		systemMessage( IDS_CANNOT_PLAY_PRIMARY, _T("Cannot Play primary %08x"), hr );
		return false;
	}

	return true;
}
示例#4
0
bool SoundRecoder::createBuffer(LPGUID guid)
{
	//デバイスの作成
	HMODULE library = LoadLibraryA("dsound.dll");
	if(!library)
		return false;

	HRESULT (WINAPI *DirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8*,LPUNKNOWN) =
		(HRESULT (WINAPI *)(LPCGUID,LPDIRECTSOUNDCAPTURE8*,LPUNKNOWN))
		GetProcAddress(library,"DirectSoundCaptureCreate8");

	DirectSoundCaptureCreate8(guid,&m_soundCapture,NULL);

	FreeLibrary(library);

	//デバイスが作成できなかったら終了
	if(!m_soundCapture)
		return false;

	if(m_soundCaptureBuffer)
	{
		m_soundCaptureBuffer->Release();
		m_soundCaptureBuffer = NULL;
	}
	DSCBUFFERDESC dscbd;
	WAVEFORMATEX wfx = 
	{
		WAVE_FORMAT_PCM,
		m_bufferChannel,
		m_bufferRate,
		m_bufferRate*m_bufferChannel*m_bufferBit/8,
		m_bufferChannel*m_bufferBit/8,
		m_bufferBit, 0
	};

	m_bufferSize =  wfx.nAvgBytesPerSec*m_bufferMSec/1000;

	dscbd.dwSize = sizeof(DSCBUFFERDESC);
	dscbd.dwFlags = 0;
	dscbd.dwBufferBytes = m_bufferSize;
	dscbd.dwReserved = 0;
	dscbd.lpwfxFormat = &wfx;
	dscbd.dwFXCount = 0;
	dscbd.lpDSCFXDesc = NULL;
	
	m_latency = m_bufferSize / m_notifyCount;


	LPDIRECTSOUNDCAPTUREBUFFER soundBuffer = NULL;
	m_soundCapture->CreateCaptureBuffer(&dscbd, &soundBuffer, NULL);
	if(!soundBuffer)
		return false;
	soundBuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8,(LPVOID*)&m_soundCaptureBuffer);
	soundBuffer->Release();

	if(!m_soundCaptureBuffer)
		return false;

	INT i;
	for(i=0;i<m_notifyCount;i++)
	{
		m_positionNotify[i].dwOffset = (dscbd.dwBufferBytes /m_notifyCount)*i ;
	}

	LPDIRECTSOUNDNOTIFY8 dsNotify;
	m_soundCaptureBuffer->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&dsNotify);
	dsNotify->SetNotificationPositions(m_notifyCount, m_positionNotify);
	dsNotify->Release();

	return true;
}
bool FVoiceCaptureWindows::CreateNotifications(uint32 BufferSize)
{
	bool bSuccess = true;

	LPDIRECTSOUNDNOTIFY8 NotifyInt = NULL;

	HRESULT hr = CV->VoiceCaptureBuffer8->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&NotifyInt);
	if (SUCCEEDED(hr))
	{
		DSBPOSITIONNOTIFY NotifyEvents[NUM_EVENTS];

		// Create events.
		for (int i = 0; i < NUM_EVENTS; i++)
		{
			CV->Events[i] = CreateEvent(NULL, true, false, NULL);
			if (CV->Events[i] == INVALID_HANDLE_VALUE)
			{
				UE_LOG(LogVoiceCapture, Warning, TEXT("Error creating sync event"));
				bSuccess = false;
			}
		}

		if (bSuccess)
		{
			// Evenly distribute notifications throughout the buffer
			uint32 NumSegments = NUM_EVENTS - 1; 
			uint32 BufferSegSize = BufferSize / NumSegments;
			for (uint32 i = 0; i < NumSegments; i++)
			{
				NotifyEvents[i].dwOffset = ((i + 1) * BufferSegSize) - 1;
				NotifyEvents[i].hEventNotify = CV->Events[i];
			}

			// when buffer stops
			NotifyEvents[STOP_EVENT].dwOffset = DSBPN_OFFSETSTOP;
			NotifyEvents[STOP_EVENT].hEventNotify = CV->Events[STOP_EVENT];

			hr = NotifyInt->SetNotificationPositions(NUM_EVENTS, NotifyEvents);
			if (FAILED(hr))
			{
				UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to set notifications 0x%08x"), hr);
				bSuccess = false;
			}

			float BufferSegMs = BufferSegSize / ((CV->WavFormat.nSamplesPerSec / 1000.0) * (CV->WavFormat.wBitsPerSample / 8.0));
			UE_LOG(LogVoiceCapture, Display, TEXT("%d notifications, every %d bytes [%f ms]"), NumSegments, BufferSegSize, BufferSegMs);
		}

		NotifyInt->Release();
	}
	else
	{
		UE_LOG(LogVoiceCapture, Warning, TEXT("Failed to create voice notification interface 0x%08x"), hr);
	}

	if (!bSuccess)
	{
		for (int i = 0; i < NUM_EVENTS; i++)
		{
			if (CV->Events[i] != INVALID_HANDLE_VALUE)
			{
				CloseHandle(CV->Events[i]);
				CV->Events[i] = INVALID_HANDLE_VALUE;
			}
		}
	}

	return bSuccess;
}