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 ); }
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, ¬ify ); 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; }
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 }