void SFXXAudioProvider::init()
{
   // Create a temp XAudio object for device enumeration.
   IXAudio2 *xAudio = NULL;
   if ( !_createXAudio( &xAudio ) )
   {
      Con::errorf( "SFXXAudioProvider::init() - XAudio2 failed to load!" );
      return;
   }

   // Add the devices to the info list.
   UINT32 count = 0;
   xAudio->GetDeviceCount( &count );
   for ( UINT32 i = 0; i < count; i++ )
   {
      XAUDIO2_DEVICE_DETAILS details;
      HRESULT hr = xAudio->GetDeviceDetails( i, &details );
      if ( FAILED( hr ) )
         continue;

      // Add a device to the info list.
      XADeviceInfo* info = new XADeviceInfo;
      info->deviceIndex = i;
      info->driver = String( "XAudio" );
      info->name = String( details.DisplayName );
      info->hasHardware = false;
      info->maxBuffers = 64;
      info->role = details.Role;
      info->format = details.OutputFormat;
      mDeviceInfo.push_back( info );
   }

   // We're done with XAudio for now.
   SAFE_RELEASE( xAudio );

   // If we have no devices... we're done.
   if ( mDeviceInfo.empty() )
   {
      Con::errorf( "SFXXAudioProvider::init() - No valid XAudio2 devices found!" );
      return;
   }

   // If we got this far then we should be able to
   // safely create a device for XAudio.
   regProvider( this );
}
Beispiel #2
0
bool XAudio2_Output::init(long sampleRate)
{
	if( failed || initialized ) return false;

	HRESULT hr;

	// Initialize XAudio2
	UINT32 flags = 0;
//#ifdef _DEBUG
//	flags = XAUDIO2_DEBUG_ENGINE;
//#endif

	hr = XAudio2Create( &xaud, flags );
	if( hr != S_OK ) {
		systemMessage( IDS_XAUDIO2_FAILURE, NULL );
		failed = true;
		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;

	// create own buffers to store sound data because it must not be
	// manipulated while the voice plays from it
	buffers = (BYTE *)malloc( ( bufferCount + 1 ) * soundBufferLen );
	// + 1 because we need one temporary buffer when all others are in use

	WAVEFORMATEX wfx;
	ZeroMemory( &wfx, sizeof( wfx ) );
	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;


	// create sound receiver
	hr = xaud->CreateMasteringVoice(
		&mVoice,
		XAUDIO2_DEFAULT_CHANNELS,
		XAUDIO2_DEFAULT_SAMPLERATE,
		0,
		theApp.xa2Device,
		NULL );
	if( hr != S_OK ) {
		systemMessage( IDS_XAUDIO2_CANNOT_CREATE_MASTERINGVOICE, NULL );
		failed = true;
		return false;
	}


	// create sound emitter
	hr = xaud->CreateSourceVoice( &sVoice, &wfx, 0, 4.0f, &notify );
	if( hr != S_OK ) {
		systemMessage( IDS_XAUDIO2_CANNOT_CREATE_SOURCEVOICE, NULL );
		failed = true;
		return false;
	}


	if( theApp.xa2Upmixing ) {
		// set up stereo upmixing
		XAUDIO2_DEVICE_DETAILS dd;
		ZeroMemory( &dd, sizeof( dd ) );
		hr = xaud->GetDeviceDetails( 0, &dd );
		ASSERT( hr == S_OK );
		float *matrix = NULL;
		matrix = (float*)malloc( sizeof( float ) * 2 * dd.OutputFormat.Format.nChannels );
        if( matrix == NULL ) return false;
		bool matrixAvailable = true;
		switch( dd.OutputFormat.Format.nChannels ) {
			case 4: // 4.0
	//Speaker \ Left Source           Right Source
	/*Front L*/	matrix[0] = 1.0000f;  matrix[1] = 0.0000f;
	/*Front R*/	matrix[2] = 0.0000f;  matrix[3] = 1.0000f;
	/*Back  L*/	matrix[4] = 1.0000f;  matrix[5] = 0.0000f;
	/*Back  R*/	matrix[6] = 0.0000f;  matrix[7] = 1.0000f;
				break;
			case 5: // 5.0
	//Speaker \ Left Source           Right Source
	/*Front L*/	matrix[0] = 1.0000f;  matrix[1] = 0.0000f;
	/*Front R*/	matrix[2] = 0.0000f;  matrix[3] = 1.0000f;
	/*Front C*/	matrix[4] = 0.7071f;  matrix[5] = 0.7071f;
	/*Side  L*/	matrix[6] = 1.0000f;  matrix[7] = 0.0000f;
	/*Side  R*/	matrix[8] = 0.0000f;  matrix[9] = 1.0000f;
				break;
			case 6: // 5.1
	//Speaker \ Left Source           Right Source
	/*Front L*/	matrix[0] = 1.0000f;  matrix[1] = 0.0000f;
	/*Front R*/	matrix[2] = 0.0000f;  matrix[3] = 1.0000f;
	/*Front C*/	matrix[4] = 0.7071f;  matrix[5] = 0.7071f;
	/*LFE    */	matrix[6] = 0.0000f;  matrix[7] = 0.0000f;
	/*Side  L*/	matrix[8] = 1.0000f;  matrix[9] = 0.0000f;
	/*Side  R*/	matrix[10] = 0.0000f;  matrix[11] = 1.0000f;
				break;
			case 7: // 6.1
	//Speaker \ Left Source           Right Source
	/*Front L*/	matrix[0] = 1.0000f;  matrix[1] = 0.0000f;
	/*Front R*/	matrix[2] = 0.0000f;  matrix[3] = 1.0000f;
	/*Front C*/	matrix[4] = 0.7071f;  matrix[5] = 0.7071f;
	/*LFE    */	matrix[6] = 0.0000f;  matrix[7] = 0.0000f;
	/*Side  L*/	matrix[8] = 1.0000f;  matrix[9] = 0.0000f;
	/*Side  R*/	matrix[10] = 0.0000f;  matrix[11] = 1.0000f;
	/*Back  C*/	matrix[12] = 0.7071f;  matrix[13] = 0.7071f;
				break;
			case 8: // 7.1
	//Speaker \ Left Source           Right Source
	/*Front L*/	matrix[0] = 1.0000f;  matrix[1] = 0.0000f;
	/*Front R*/	matrix[2] = 0.0000f;  matrix[3] = 1.0000f;
	/*Front C*/	matrix[4] = 0.7071f;  matrix[5] = 0.7071f;
	/*LFE    */	matrix[6] = 0.0000f;  matrix[7] = 0.0000f;
	/*Back  L*/	matrix[8] = 1.0000f;  matrix[9] = 0.0000f;
	/*Back  R*/	matrix[10] = 0.0000f;  matrix[11] = 1.0000f;
	/*Side  L*/	matrix[12] = 1.0000f;  matrix[13] = 0.0000f;
	/*Side  R*/	matrix[14] = 0.0000f;  matrix[15] = 1.0000f;
				break;
			default:
				matrixAvailable = false;
				break;
		}
		if( matrixAvailable ) {
			hr = sVoice->SetOutputMatrix( NULL, 2, dd.OutputFormat.Format.nChannels, matrix );
			ASSERT( hr == S_OK );
		}
		free( matrix );
		matrix = NULL;
	}


	hr = sVoice->Start( 0 );
	ASSERT( hr == S_OK );
	playing = true;

	currentBuffer = 0;
	device_changed = false;

	initialized = true;
	return true;
}
Beispiel #3
0
BOOL XAudio2_Config::OnInitDialog()
{
	CDialog::OnInitDialog();

	m_combo_dev.ResetContent();

	m_slider_buffer.SetRange( 2, 10, FALSE );
	m_slider_buffer.SetTicFreq( 1 );
	m_slider_buffer.SetPos( (int)m_buffer_count );

	CString info;
	int pos = m_slider_buffer.GetPos();
	info.Format( _T("%i frames = %.2f ms"), pos, (float)pos / 60.0f * 1000.0f );
	m_info_buffer.SetWindowText( info );

	HRESULT hr;
	IXAudio2 *xa = NULL;
	UINT32 flags = 0;
#ifdef _DEBUG
	flags = XAUDIO2_DEBUG_ENGINE;
#endif

	hr = XAudio2Create( &xa, flags );
	if( hr != S_OK ) {
		systemMessage( IDS_XAUDIO2_FAILURE, NULL );
	} else {
		UINT32 dev_count = 0;
		hr = xa->GetDeviceCount( &dev_count );
		if( hr != S_OK ) {
			systemMessage( IDS_XAUDIO2_CANNOT_ENUMERATE_DEVICES, NULL );
		} else {
			XAUDIO2_DEVICE_DETAILS dd;
			for( UINT32 i = 0; i < dev_count; i++ ) {
				hr = xa->GetDeviceDetails( i, &dd );
				if( hr != S_OK ) {
					continue;
				} else {
#ifdef _UNICODE
					int id = m_combo_dev.AddString( dd.DisplayName );
#else
					CHAR temp[256];
					ZeroMemory( temp, sizeof( temp ) );
					WideCharToMultiByte(
						CP_ACP,
						WC_NO_BEST_FIT_CHARS,
						dd.DisplayName,
						-1,
						temp,
						sizeof( temp ) - 1,
						NULL,
						NULL );
					
					int id = m_combo_dev.AddString( temp );
#endif
					if( id < 0 ) {
						systemMessage( IDS_XAUDIO2_CANNOT_ENUMERATE_DEVICES, NULL );
						break;
					} else {
						m_combo_dev.SetItemData( id, i );
					}
				}
			}

			// select the currently configured device {
			int count = m_combo_dev.GetCount();
			if( count > 0 ) {
				for( int i = 0; i < count; i++ ) {
					if( m_combo_dev.GetItemData( i ) == m_selected_device_index ) {
						m_combo_dev.SetCurSel( i );
						break;
					}
				}
			}
			// }

		}
		xa->Release();
		xa = NULL;
	}

	return TRUE;  // return TRUE unless you set the focus to a control
	// EXCEPTION: OCX Property Pages should return FALSE
}