示例#1
0
//-----------------------------------------------------------------------------
// Name: CSoundManager::Initialize()
// Desc: Initializes the IDirectSound object and also sets the primary buffer
//       format.  This function must be called before any others.
//-----------------------------------------------------------------------------
HRESULT CSoundManager::Initialize( HWND  hWnd, 
                                   DWORD dwCoopLevel, 
                                   DWORD dwPrimaryChannels, 
                                   DWORD dwPrimaryFreq, 
                                   DWORD dwPrimaryBitRate )
{
    HRESULT             hr;

    SAFE_RELEASE( m_pDS );

    // Create IDirectSound using the primary sound device
    if( FAILED( hr = DirectSoundCreate8( NULL, &m_pDS, NULL ) ) )
        return DXTRACE_ERR( TEXT("DirectSoundCreate8"), hr );

    // Set DirectSound coop level 
    if( FAILED( hr = m_pDS->SetCooperativeLevel( hWnd, dwCoopLevel ) ) )
        return DXTRACE_ERR( TEXT("SetCooperativeLevel"), hr );
    
    // Set primary buffer format
    if( FAILED( hr = SetPrimaryBufferFormat( dwPrimaryChannels, dwPrimaryFreq, dwPrimaryBitRate ) ) )
        return DXTRACE_ERR( TEXT("SetPrimaryBufferFormat"), hr );

	m_dwPrimaryChannels = dwPrimaryChannels;
	m_dwPrimaryFreq = dwPrimaryFreq;
	m_dwPrimaryBitRate = dwPrimaryBitRate;

    return S_OK;
}
    // ////////////////////////////////////////////////////////////////////
    //
    // ////////////////////////////////////////////////////////////////////
    bool DirectSound8Audio::VInitialize()
    {
        if(Audio::IsInitialized()) {
            return (true);
        }

        Audio::SetInitialized(false);
        Release(m_pDS);
        HRESULT hr;

        // Create IDirectSound using the primary sound device
        if(FAILED(hr = DirectSoundCreate8(NULL, &m_pDS, NULL))) {
            GF_LOG_TRACE_ERR("DirectSound8Audio::VInitialize()", "Failed to initialized the DirectSound interface");
            return (false);
        }

        if(FAILED(hr = m_pDS->SetCooperativeLevel(m_hWnd, DSSCL_PRIORITY))) {
            GF_LOG_TRACE_ERR("DirectSound8Audio::VInitialize()", "Failed to set the coop level of the DirectSound interface");
            return (false);
        }

        if(FAILED(hr = SetPrimaryBufferFormat(8, 44100, 16))) {
            GF_LOG_TRACE_ERR("DirectSound8Audio::VInitialize()", "Failed to set the primary buffer format of the DirectSound interface");
            return (false);
        }

        Audio::SetInitialized(true);
        m_AllSamples.clear();

        return (true);
    }
示例#3
0
/*
===============
idAudioHardwareWIN32::Initialize
===============
*/
bool idAudioHardwareWIN32::Initialize( void ) {
    int             hr;

	bufferSize = 0;
	numSpeakers = 0;
	blockAlign = 0;

    SAFE_RELEASE( m_pDS );

    // Create IDirectSound using the primary sound device
    if( FAILED( hr = DirectSoundCreate( NULL, &m_pDS, NULL ) )) {
        return false;
	}

    // Set primary buffer format
	SetPrimaryBufferFormat( PRIMARYFREQ, 16, idSoundSystemLocal::s_numberOfSpeakers.GetInteger() );
	return true;
}
bool CSoundManager::init(HWND hWnd)
{
	// Set coop level to DSSCL_PRIORITY, 
	if( FAILED( Initialize( hWnd, DSSCL_PRIORITY) ) )
	{
		MessageBox( hWnd, L"Error initializing DirectSound.  Sample will now exit.", 
			                L"DirectSound Sample", MB_OK | MB_ICONERROR );
		return false;
	}
		
	// set primary buffer format to stereo, 22kHz and 16-bit output.
	if( FAILED( SetPrimaryBufferFormat( 2, 22050, 16 ) ) )
	{
		MessageBox( hWnd, L"Error initializing DirectSound.  Sample will now exit.", 
			              L"DirectSound Sample", MB_OK | MB_ICONERROR );
		return false;
	}

	return true;
}
示例#5
0
HX_RESULT CHXAudioDeviceDS::_DoOpen(const HXAudioFormat* pFormat)
{
    HX_RESULT theErr = HXR_FAIL;

    if(!m_hwnd || !m_hSoundDll)
	return theErr;

    // close open resources
    InternalClose() ;

    /* Get the IDirectSound interface */
    HXBOOL bUsingDS8 = TRUE;
    FPDIRECTSOUNDCREATE fpCreateDS = (FPDIRECTSOUNDCREATE) ::GetProcAddress(m_hSoundDll, TEXT("DirectSoundCreate8") );
    if(!fpCreateDS)
    {
	bUsingDS8 = FALSE;
	fpCreateDS = (FPDIRECTSOUNDCREATE) ::GetProcAddress(m_hSoundDll, TEXT("DirectSoundCreate"));
	if(!fpCreateDS)
	    return theErr;
    }

    theErr = fpCreateDS(NULL, &m_pDSDev, NULL);
    if (FAILED(theErr))
	return theErr;

    /* set the cooperative level. Because we want control over the format of the
       primary buffer (16 bit, multichannel!), we need DSSCL_PRIORITY. */
    m_pDSDev->SetCooperativeLevel(m_hwnd, DSSCL_PRIORITY );

    /* set the format of the primary buffer. This will fail on WDM systems (because
       the kernel mixer termines the primary buffer format), but is important on
       non-WDM systems.
    
       This might change the m_WaveFormat structure from a WAVE_FORMAT_EXTENSIBLE
       to a WAVEFORMATEX.

       Ignore the result.
    */
    SetPrimaryBufferFormat() ;

    /* Now open a secondary buffer. */

    DSBUFFERDESC bufferDesc;
    ::memset(&bufferDesc, 0, sizeof(DSBUFFERDESC));

    bufferDesc.dwSize	   = sizeof(DSBUFFERDESC);
    bufferDesc.lpwfxFormat = m_pWaveFormat;

    // Manipulate the buffer size so that is is an exact multiple of the block size.
    // This will ensure that our write positions on the buffer are the same in every loop.
    // We need to do this so that we have fixed playback notification positions marking the end each write block.
    m_nBlocksPerBuffer = (m_pWaveFormat->nAvgBytesPerSec*BUFFER_TIME)/pFormat->uMaxBlockSize;
    m_ulTotalBuffer = pFormat->uMaxBlockSize*m_nBlocksPerBuffer;
    m_ulLoopTime = (double)m_ulTotalBuffer / (double)m_pWaveFormat->nAvgBytesPerSec;

    bufferDesc.dwBufferBytes = m_ulTotalBuffer ;
    bufferDesc.dwFlags	=
		      DSBCAPS_CTRLVOLUME | // so we can control the volume
		      DSBCAPS_GETCURRENTPOSITION2 | // finer position reports
		      DSBCAPS_CTRLPOSITIONNOTIFY | // have them reported here
		      DSBCAPS_GLOBALFOCUS | // take control!
		      DSBCAPS_STICKYFOCUS |
#ifdef HELIX_FEATURE_AUDIO_DEVICE_HOOKS
		      (bUsingDS8 && m_pWaveFormat->nChannels <= 2 && !m_bOpaqueFormat ? DSBCAPS_CTRLFX : 0);
#else
		      0;
#endif

    /* Again, try with WAVE_FORMAT_EXTENSIBLE first, but only if multichannel. */

    theErr = !DS_OK ;
    if (m_pWaveFormat->nChannels > 2 || m_bOpaqueFormat)
    {
	if(!m_bOpaqueFormat)
	    m_pWaveFormat->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
        theErr = m_pDSDev->CreateSoundBuffer(&bufferDesc, &m_pSecondaryBuffer, NULL);
    }

    if (theErr != DS_OK && !m_bOpaqueFormat)
    {
	/* and if that fails, try WAVEFORMATEX */
	m_pWaveFormat->wFormatTag = WAVE_FORMAT_PCM;
	theErr = m_pDSDev->CreateSoundBuffer(&bufferDesc, &m_pSecondaryBuffer, NULL);
    }

    /* call it a day and count our blessings. */
    switch (theErr)
    {
	case DS_OK: 
	    theErr = HXR_OK;
	    break;
	case DSERR_OUTOFMEMORY:
	    theErr = HXR_OUTOFMEMORY;
	    break;
	default:
	    theErr = HXR_FAIL;
	    break;
    }

    if (SUCCEEDED(theErr) && m_pSecondaryBuffer)
    {
	m_eState = E_DEV_OPENED;

	KillThreadAndEvent();

	SetWindowLong(m_hwnd, GWL_USERDATA, (LONG)this);

	// Create the event to be signalled on playback position notifications and the thread to wait for those events to be signalled.
	m_hDSNotifyEvent = CreateEvent(NULL, TRUE, FALSE, kDSWaitEvent);

	// now set the notification positions for direct sound playback.
	IDirectSoundNotify* pNotify = NULL;
	m_pSecondaryBuffer->QueryInterface(IID_IDirectSoundNotify, (void**)&pNotify);
	if(pNotify && m_hDSNotifyEvent)
	{
	    DSBPOSITIONNOTIFY* aPositionNotify = new DSBPOSITIONNOTIFY[m_nBlocksPerBuffer];
	    if(aPositionNotify)
	    {
		for(int i = 0; i < m_nBlocksPerBuffer; i++)
		{
		    aPositionNotify[i].dwOffset = i * pFormat->uMaxBlockSize;
		    aPositionNotify[i].hEventNotify = m_hDSNotifyEvent;
		}
	    }
	    pNotify->SetNotificationPositions(m_nBlocksPerBuffer, aPositionNotify);
	    delete[] aPositionNotify;
	    DWORD dwWaitThreadID(0);
	    m_hWaitThread = CreateThread(NULL, 0, EventThreadProc, (LPVOID)this, 0, &dwWaitThreadID);
            SetDebuggerThreadName(dwWaitThreadID, "DirectSound Audio Device Thread");
	    SetThreadPriority( m_hWaitThread, THREAD_PRIORITY_HIGHEST );
	}
	HX_RELEASE(pNotify);

	m_pSecondaryBuffer->SetVolume(DSBVOLUME_MAX);
	m_pSecondaryBuffer->SetCurrentPosition(0);

        // detect whether we are playing remotely(via Remote Desktop)
        // disable audio device hook if it is to avoid poor audio quality
        int bRemoteSession = GetSystemMetrics(SM_REMOTESESSION);
	if(!bRemoteSession && bUsingDS8 && m_pWaveFormat->nChannels <= 2 && !m_bOpaqueFormat)
	{
	    LoadDirectSoundFilter();
	}
    }

    m_ulCurrPlayTime = 0;
	m_ulCurrLoopTime = 0;
    m_ulLoops = 0;

    // Setup converter to convert from samples/sec to milliseconds
    m_TSConverter.SetBase(m_pWaveFormat->nSamplesPerSec, 1000);

    return theErr;
}
// Sets a general quality of playback (CPU time vs. fidelity)
HRESULT DS3DSoundEngine::SetQuality(Quality quality)
{
    HRESULT hr;

    // stop all playing sound buffers
    VirtualSoundList::iterator iterSound;
    for (iterSound = m_listActiveSounds.begin();
        iterSound != m_listActiveSounds.end(); ++iterSound)
    {
        if ((*iterSound)->HasPlayingBuffer())
        {
            hr = (*iterSound)->StopBuffer();
            if (ZFailed(hr)) return hr;
        }
    }
    
    switch (quality)
    {
    case minQuality:
        hr = SetPrimaryBufferFormat(22050, 8, 1);
        if ((hr != DSERR_PRIOLEVELNEEDED) && ZFailed(hr)) return hr;
        m_nNumBuffersDesired = 8;
        m_nNumBuffersMax = 8;
        break;

    case midQuality:
    default:
        hr = SetPrimaryBufferFormat(22050, 16, 2);
        if ((hr != DSERR_PRIOLEVELNEEDED) && ZFailed(hr)) return hr;
        if (m_bAllowHardware)
        {
            m_nNumBuffersDesired = max(16, (int)m_dscaps.dwMaxHwMixingStreamingBuffers * 2 / 3);
            m_nNumBuffersMax = max(24, (int)m_dscaps.dwMaxHwMixingStreamingBuffers);
        }
        else
        {
            m_nNumBuffersDesired = 16;
            m_nNumBuffersMax = 24;
        }
        break;

    case maxQuality:
        hr = SetPrimaryBufferFormat(44100, 16, 2);
        if ((hr != DSERR_PRIOLEVELNEEDED) && ZFailed(hr)) return hr;
        if (m_bAllowHardware)
        {
            m_nNumBuffersDesired = max(24, (int)m_dscaps.dwMaxHwMixingStreamingBuffers - 8);
            m_nNumBuffersMax = max(32, (int)m_dscaps.dwMaxHwMixingStreamingBuffers);
        }
        else
        {
            m_nNumBuffersDesired = 24;
            m_nNumBuffersMax = 32;
        }
        break;
    }

    m_quality = quality;

    return S_OK;
};