示例#1
0
文件: primary.c 项目: CepGamer/wine
static DWORD DSOUND_FindSpeakerConfig(IMMDevice *mmdevice, int channels)
{
    IPropertyStore *store;
    HRESULT hr;
    PROPVARIANT pv;
    ULONG phys_speakers;

    const DWORD def = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE);

    hr = IMMDevice_OpenPropertyStore(mmdevice, STGM_READ, &store);
    if (FAILED(hr)) {
        WARN("IMMDevice_OpenPropertyStore failed: %08x\n", hr);
        return def;
    }

    hr = IPropertyStore_GetValue(store, &PKEY_AudioEndpoint_PhysicalSpeakers, &pv);

    if (FAILED(hr)) {
        WARN("IPropertyStore_GetValue failed: %08x\n", hr);
        IPropertyStore_Release(store);
        return def;
    }

    if (pv.vt != VT_UI4) {
        WARN("PKEY_AudioEndpoint_PhysicalSpeakers is not a ULONG: 0x%x\n", pv.vt);
        PropVariantClear(&pv);
        IPropertyStore_Release(store);
        return def;
    }

    phys_speakers = pv.u.ulVal;

    PropVariantClear(&pv);
    IPropertyStore_Release(store);

    if ((channels >= 6 || channels == 0) && (phys_speakers & KSAUDIO_SPEAKER_5POINT1) == KSAUDIO_SPEAKER_5POINT1)
        return DSSPEAKER_5POINT1_BACK;
    else if ((channels >= 6 || channels == 0) && (phys_speakers & KSAUDIO_SPEAKER_5POINT1_SURROUND) == KSAUDIO_SPEAKER_5POINT1_SURROUND)
        return DSSPEAKER_5POINT1_SURROUND;
    else if ((channels >= 4 || channels == 0) && (phys_speakers & KSAUDIO_SPEAKER_QUAD) == KSAUDIO_SPEAKER_QUAD)
        return DSSPEAKER_QUAD;
    else if ((channels >= 2 || channels == 0) && (phys_speakers & KSAUDIO_SPEAKER_STEREO) == KSAUDIO_SPEAKER_STEREO)
        return DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE);
    else if ((phys_speakers & KSAUDIO_SPEAKER_MONO) == KSAUDIO_SPEAKER_MONO)
        return DSSPEAKER_MONO;

    return def;
}
示例#2
0
//////////////////////////////////////////////////////////////////////
// Descripcion:
// - Configura los altavoces del usuario segun el tipo y 
//   su geometria.
// Parametros:
// - dwType: Tipo de altavoces entre:
//     * DSSPEAKER_HEADPHONE <auriculares>
//     * DSSPEAKER_MONO <sistema mono>
//     * DSSPEAKER_QUAD <sistema cuadrafonico>
//     * DSSPEAKER_STEREO <sistema estereo>
//     * DSSPEAKER_SURROUND <sistema doble surround>
// - dwGeometry: Geometria de los altavoces con respecto al usuario:
//     * DSSPEAKER_GEOMETRY_MIN <5 grados>
//     * DSSPEAKER_GEOMETRY_NARROW <10 grados>
//     * DSSPEAKER_GEOMETRY_WIDE <20 grados>
//     * DSSPEAKER_GEOMETRY_MAX <180 grados>
// Devuelve:
// true: Si se han configurado altavoces con exito.
// false: Si no se ha podido realizar la configuracion.
// Notas:
// - La informacion de la geometria solo tiene sentido cuando se
//   habla de altavoces stereo en cuyo caso tiene valor por defecto
//   a DSSPEAKER_GEOMETRY_WIDE.
// - En el caso de que no se haya creado objeto DirectSound el 
//   metodo retorna sin hacer nada.
////////////////////////////////////////////////////////////////////// 
bool DXSound::SetSpeakers(const dword dwType, 
						  const dword dwGeometry)
{  
  // SOLO si hay objeto DirectSound
  DXASSERT(m_lpDSObj != NULL);
  
    // Efectua configuracion de altavoces
  if (dwType != DSSPEAKER_STEREO) {
    // Configuracion no estereo
    m_CodeResult = m_lpDSObj->SetSpeakerConfig(dwType);
  }
  else {
    // Configuracion estereo; hay que combinar flags
    m_CodeResult = m_lpDSObj->SetSpeakerConfig(DSSPEAKER_COMBINED(dwType, dwGeometry));
  }

  // Comprueba resultado operacion
  if (FAILED(m_CodeResult)) {
    // Hay problemas
    DXDSError::DXDSErrorToString(m_CodeResult, m_sLastCode);
    return false;
  }
  
  // Todo correcto
  return true;
}
示例#3
0
static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized,
                               LPCGUID lpGuid)
{
    HRESULT rc;
    DSCAPS dscaps;
    int ref;
    IUnknown * unknown;
    IDirectSound * ds;
    IDirectSound8 * ds8;
    DWORD speaker_config, new_speaker_config;
    DWORD certified;

    /* Try to Query for objects */
    rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
    ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",
       DXGetErrorString8(rc));
    if (rc==DS_OK)
        IDirectSound8_Release(unknown);

    rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
    ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",
       DXGetErrorString8(rc));
    if (rc==DS_OK)
        IDirectSound_Release(ds);

    rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
    ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) "
       "should have returned DSERR_INVALIDPARAM, returned: %s\n",
       DXGetErrorString8(rc));
    if (rc==DS_OK)
        IDirectSound8_Release(ds8);

    if (initialized == FALSE) {
        /* try unitialized object */
        rc=IDirectSound8_GetCaps(dso,0);
        ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) "
           "should have returned DSERR_UNINITIALIZED, returned: %s\n",
           DXGetErrorString8(rc));

        rc=IDirectSound8_GetCaps(dso,&dscaps);
        ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() "
           "should have returned DSERR_UNINITIALIZED, returned: %s\n",
           DXGetErrorString8(rc));

        rc=IDirectSound8_Compact(dso);
        ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() "
           "should have returned DSERR_UNINITIALIZED, returned: %s\n",
           DXGetErrorString8(rc));

        rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
        ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() "
           "should have returned DSERR_UNINITIALIZED, returned: %s\n",
           DXGetErrorString8(rc));

        rc=IDirectSound8_VerifyCertification(dso, &certified);
        ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() "
           "should have returned DSERR_UNINITIALIZED, returned: %s\n",
           DXGetErrorString8(rc));

        rc=IDirectSound8_Initialize(dso,lpGuid);
        ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
           "IDirectSound8_Initialize() failed: %s\n",DXGetErrorString8(rc));
        if (rc==DSERR_NODRIVER) {
            trace("  No Driver\n");
            goto EXIT;
        } else if (rc==E_FAIL) {
            trace("  No Device\n");
            goto EXIT;
        } else if (rc==DSERR_ALLOCATED) {
            trace("  Already In Use\n");
            goto EXIT;
        }
    }

    rc=IDirectSound8_Initialize(dso,lpGuid);
    ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound8_Initialize() "
       "should have returned DSERR_ALREADYINITIALIZED: %s\n",
       DXGetErrorString8(rc));

    /* DSOUND: Error: Invalid caps buffer */
    rc=IDirectSound8_GetCaps(dso,0);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
       "should have returned DSERR_INVALIDPARAM, returned: %s\n",
       DXGetErrorString8(rc));

    ZeroMemory(&dscaps, sizeof(dscaps));

    /* DSOUND: Error: Invalid caps buffer */
    rc=IDirectSound8_GetCaps(dso,&dscaps);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() "
       "should have returned DSERR_INVALIDPARAM, returned: %s\n",
       DXGetErrorString8(rc));

    dscaps.dwSize=sizeof(dscaps);

    /* DSOUND: Running on a certified driver */
    rc=IDirectSound8_GetCaps(dso,&dscaps);
    ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %s\n",DXGetErrorString8(rc));

    rc=IDirectSound8_Compact(dso);
    ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %s\n",
       DXGetErrorString8(rc));

    rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
    ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %s\n",
       DXGetErrorString8(rc));

    rc=IDirectSound8_Compact(dso);
    ok(rc==DS_OK,"IDirectSound8_Compact() failed: %s\n",DXGetErrorString8(rc));

    rc=IDirectSound8_GetSpeakerConfig(dso,0);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) "
       "should have returned DSERR_INVALIDPARAM, returned: %s\n",
       DXGetErrorString8(rc));

    rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config);
    ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
       DXGetErrorString8(rc));

    speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO,
                                        DSSPEAKER_GEOMETRY_WIDE);
    rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config);
    ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %s\n",
       DXGetErrorString8(rc));
    if (rc==DS_OK) {
        rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config);
        ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %s\n",
           DXGetErrorString8(rc));
        if (rc==DS_OK && speaker_config!=new_speaker_config)
               trace("IDirectSound8_GetSpeakerConfig() failed to set speaker "
               "config: expected 0x%08lx, got 0x%08lx\n",
               speaker_config,new_speaker_config);
    }

    rc=IDirectSound8_VerifyCertification(dso, &certified);
    ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %s\n",
       DXGetErrorString8(rc));

EXIT:
    ref=IDirectSound8_Release(dso);
    ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
}
示例#4
0
文件: dsound.c 项目: 3dseals/furseal
static ALCboolean DSoundResetPlayback(ALCdevice *device)
{
    DSoundData *pData = (DSoundData*)device->ExtraData;
    DSBUFFERDESC DSBDescription;
    WAVEFORMATEXTENSIBLE OutputType;
    DWORD frameSize = 0;
    ALenum format = 0;
    DWORD speakers;
    HRESULT hr;

    memset(&OutputType, 0, sizeof(OutputType));

    hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
    if(SUCCEEDED(hr) && ConfigValueExists(NULL, "format"))
    {
        if(aluChannelsFromFormat(device->Format) == 1)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
        else if(aluChannelsFromFormat(device->Format) == 2)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
        else if(aluChannelsFromFormat(device->Format) == 4)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
        else if(aluChannelsFromFormat(device->Format) == 6)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
        else if(aluChannelsFromFormat(device->Format) == 8)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
        else
        {
            AL_PRINT("Unknown format: 0x%x\n", device->Format);
            return ALC_FALSE;
        }
    }
    if(SUCCEEDED(hr))
    {
        speakers = DSSPEAKER_CONFIG(speakers);
        if(speakers == DSSPEAKER_MONO)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_MONO8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_MONO16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_MONO_FLOAT32;
            OutputType.dwChannelMask = SPEAKER_FRONT_CENTER;
        }
        else if(speakers == DSSPEAKER_STEREO)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_STEREO8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_STEREO16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_STEREO_FLOAT32;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT;
        }
        else if(speakers == DSSPEAKER_QUAD)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_QUAD8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_QUAD16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_QUAD32;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_5POINT1)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_51CHN8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_51CHN16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_51CHN32;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_FRONT_CENTER |
                                       SPEAKER_LOW_FREQUENCY |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_7POINT1)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_71CHN8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_71CHN16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_71CHN32;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_FRONT_CENTER |
                                       SPEAKER_LOW_FREQUENCY |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT |
                                       SPEAKER_SIDE_LEFT |
                                       SPEAKER_SIDE_RIGHT;
        }
        else
            format = device->Format;
        frameSize = aluFrameSizeFromFormat(format);

        OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
        OutputType.Format.nChannels = aluChannelsFromFormat(format);
        OutputType.Format.wBitsPerSample = aluBytesFromFormat(format) * 8;
        OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
        OutputType.Format.nSamplesPerSec = device->Frequency;
        OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
        OutputType.Format.cbSize = 0;
    }

    if(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16)
    {
        OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
        OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
        OutputType.Format.cbSize = 22;
        if(OutputType.Format.wBitsPerSample == 32)
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
        else
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
    }
    else
    {
        if(SUCCEEDED(hr))
        {
            memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
            DSBDescription.dwSize=sizeof(DSBUFFERDESC);
            DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
            hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
        }
        if(SUCCEEDED(hr))
            hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format);
    }

    if(SUCCEEDED(hr))
    {
        memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
        DSBDescription.dwSize=sizeof(DSBUFFERDESC);
        DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
        DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * frameSize;
        DSBDescription.lpwfxFormat=&OutputType.Format;
        hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
    }

    if(SUCCEEDED(hr))
        hr = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING);

    if(SUCCEEDED(hr))
    {
        device->Format = format;
        SetDefaultWFXChannelOrder(device);
        pData->thread = StartThread(DSoundProc, device);
        if(!pData->thread)
            hr = E_FAIL;
    }

    if(FAILED(hr))
    {
        if (pData->DSsbuffer)
            IDirectSoundBuffer_Release(pData->DSsbuffer);
        pData->DSsbuffer = NULL;
        if (pData->DSpbuffer)
            IDirectSoundBuffer_Release(pData->DSpbuffer);
        pData->DSpbuffer = NULL;
        return ALC_FALSE;
    }

    return ALC_TRUE;
}
示例#5
0
static ALCboolean DSoundResetPlayback(ALCdevice *device)
{
    DSoundData *pData = (DSoundData*)device->ExtraData;
    DSBUFFERDESC DSBDescription;
    WAVEFORMATEXTENSIBLE OutputType;
    DWORD speakers;
    HRESULT hr;

    memset(&OutputType, 0, sizeof(OutputType));

    switch(device->FmtType)
    {
    case DevFmtByte:
        device->FmtType = DevFmtUByte;
        break;
    case DevFmtUShort:
        device->FmtType = DevFmtShort;
        break;
    case DevFmtUByte:
    case DevFmtShort:
    case DevFmtFloat:
        break;
    }

    hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
    if(SUCCEEDED(hr) && ConfigValueExists(NULL, "format"))
    {
        switch(device->FmtChans)
        {
        case DevFmtMono:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
            break;
        case DevFmtStereo:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
            break;
        case DevFmtQuad:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
            break;
        case DevFmtX51:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
            break;
        case DevFmtX61:
            /* ??? */
            ;
            break;
        case DevFmtX71:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
            break;
        }
    }
    if(SUCCEEDED(hr))
    {
        speakers = DSSPEAKER_CONFIG(speakers);
        if(speakers == DSSPEAKER_MONO)
        {
            device->FmtChans = DevFmtMono;
            OutputType.dwChannelMask = SPEAKER_FRONT_CENTER;
        }
        else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE)
        {
            device->FmtChans = DevFmtStereo;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT;
        }
        else if(speakers == DSSPEAKER_QUAD)
        {
            device->FmtChans = DevFmtQuad;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_5POINT1)
        {
            device->FmtChans = DevFmtX51;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_FRONT_CENTER |
                                       SPEAKER_LOW_FREQUENCY |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_7POINT1)
        {
            device->FmtChans = DevFmtX71;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_FRONT_CENTER |
                                       SPEAKER_LOW_FREQUENCY |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT |
                                       SPEAKER_SIDE_LEFT |
                                       SPEAKER_SIDE_RIGHT;
        }

        OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
        OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans);
        OutputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8;
        OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
        OutputType.Format.nSamplesPerSec = device->Frequency;
        OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
        OutputType.Format.cbSize = 0;
    }

    if(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16)
    {
        OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
        OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
        OutputType.Format.cbSize = 22;
        if(OutputType.Format.wBitsPerSample == 32)
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
        else
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
    }
    else
    {
        if(SUCCEEDED(hr))
        {
            memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
            DSBDescription.dwSize=sizeof(DSBUFFERDESC);
            DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
            hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
        }
        if(SUCCEEDED(hr))
            hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format);
    }

    if(SUCCEEDED(hr))
    {
        memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
        DSBDescription.dwSize=sizeof(DSBUFFERDESC);
        DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
        DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates *
                                     OutputType.Format.nBlockAlign;
        DSBDescription.lpwfxFormat=&OutputType.Format;
        hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
    }

    if(SUCCEEDED(hr))
    {
        SetDefaultWFXChannelOrder(device);
        pData->thread = StartThread(DSoundProc, device);
        if(!pData->thread)
            hr = E_FAIL;
    }

    if(FAILED(hr))
    {
        if (pData->DSsbuffer)
            IDirectSoundBuffer_Release(pData->DSsbuffer);
        pData->DSsbuffer = NULL;
        if (pData->DSpbuffer)
            IDirectSoundBuffer_Release(pData->DSpbuffer);
        pData->DSpbuffer = NULL;
        return ALC_FALSE;
    }

    return ALC_TRUE;
}