Error ds createsoundbuffer

Well, just wondering is anyone has had any experience with the "DirectX in 24 hours" code. I used it and I am getting an error with the CreateSoundBuffer() call. I basically used the EXACT same code, is there an error there or something, maybe something I should know about dsound that they don''t

Well, just wondering is anyone has had any experience with the «DirectX in 24 hours» code. I used it and I am getting an error with the CreateSoundBuffer() call. I basically used the EXACT same code, is there an error there or something, maybe something I should know about dsound that they don»t tell me (which seems to happen quite often with this book). Any help will be much obliged (I think that»s the right word).

And finally, it this where dsound questions go, I couldn»t figure out where else to put them?

Retired Pokemon Master of Prgramming Problems

I already had them all.

This Space for rent.

Maybe it should go in the API specific section with Direct X I dunno though, and for your question I»m sorry I»m not familiar with that code (Direct X in 24 hours)

Maketty
(Matthew FitzGerald)
Knightvision Games

Maketty (Matthew FitzGerald) The meaning of Life part 5:Live organ transplants…

i»d be glad to try to help you; i»ve got the book right in front of me.. i never used the code directly, though, just looked at it and wrote my own..

what»s the error it»s giving you?
i think the most likely problem is with the DSBUFFERDESC parameter.. either you»re setting a field wrong (or not setting a vital one), or you»re not zeroing it out and setting the struct size. if it»s the last, that»s easily fixed, just do the same thing you did with DDSURFACEDESC struct for DirectDraw, i.e.

DSBUFFERDESC dsbd;
memset(&dsbd,0,sizeof(dsbd));
dsbd.dwSize = sizeof(dsbd);

if that»s not it, please post the error the compiler gives you, and i»ll try to help

————————
IUnknown *pUnkOuter

«Just do your best and
don’t worry»
—Morrissey

«Try the best you can
try the best you can
the best you can is good enough»
—Radiohead

«Are you looking for new ways
to do better than your worst»
—Nick Drake

————————IUnknown *pUnkOuter»Try the best you cantry the best you canthe best you can is good enough» —Radiohead

My bad, I was confused, I thought the dx/ogl/etc section was graphics or something, sorry for the mispost.

Retired Pokemon Master of Prgramming Problems

I already had them all.

This Space for rent.

No Problem!

Maketty
(Matthew FitzGerald)
Knightvision Games

Maketty (Matthew FitzGerald) The meaning of Life part 5:Live organ transplants…

ZeroMemory(&dsBD, sizeof(DSBUFFERDESC));
dsBD.dwSize = sizeof(DSBUFFERDESC);
dsBD.dwFlags = DSBCAPS_CTRLDEFAULT | DSBCAPS_STATIC;

//Set up the Sound(s)
dsBD.dwBufferBytes = dwDataLen;
dsBD.lpwfxFormat = &wfFormat;

if(lpDS->CreateSoundBuffer(&dsBD, &lpDSBSound, NULL) != DS_OK)
error(«lpDS->CreateSoundBuffer (Sound)»);

There’s the stuff I’m doin’ with the buffer descripter, the only difference between that and the book is the CTRL_DEFAULT, in the book it uses three things that DEFAULT adds anyway.

Is there a way to retrieve the error, ’cause I was looking through that book and Tricks of the Windows Game programming book and neither had any way to retrieve error codes.

/********
I should have specified the first time, it’s a runtime error. When it calls CreateSoundBuffer() it doen’t go through as DS_OK.
********/

Retired Pokemon Master of Prgramming Problems

I already had them all.

Edited by — Kudaba on October 7, 2000 2:18:59 AM

This Space for rent.

the function returns the error code, like with all parts of DirectX.. see the DirectX SDK Help for more details on the code, but here they are:
DSERR_ALLOCATED
DSERR_CONTROLUNAVAIL
DSERR_BADFORMAT
DSERR_INVALIDPARAM
DSERR_NOAGGREGATION
DSERR_OUTOFMEMORY
DSERR_UNINITIALIZED
DSERR_UNSUPPORTED

you can check like this

        HRESULT result;if( (result = lpDS->CreateSoundBuffer(&dsbd,&lpdsb,NULL)) != DD_OK){    switch(result)    {        case DSERR_ALLOCATED:            // etc.....        

oh, and you’re getting an error at run time, or compile time?
(nevermind, answered the question while i was answering yours )

————————
IUnknown *pUnkOuter

«Just do your best and
don’t worry»
—Morrissey

«Try the best you can
try the best you can
the best you can is good enough»
—Radiohead

«Are you looking for new ways
to do better than your worst»
—Nick Drake

Edited by — pUnkOuter on October 7, 2000 2:26:34 AM

————————IUnknown *pUnkOuter»Try the best you cantry the best you canthe best you can is good enough» —Radiohead

DSBCAPS_DEFAULT is obsolete in dx7.

change it back.

a2k

——————General Equation, this is Private Function reporting for duty, sir!a2k

Well, getting closer, thanks a lot for the help so far, I took out DSBCAPS_DEFAULT, now the error that it»s giving me is DSERR_CONTROLUNAVAIL, I took out frequency volume, and pan and it still gives it to me. I wish DX i 24 would explain things a little better.

Retired Pokemon Master of Prgramming Problems

I already had them all.

This Space for rent.

The specific answer was given by Chris P. by referencing this document:

http://www.microsoft.com/whdc/archive/Non-PCM.mspx#EKAAC

Specifics for DirectSound Clients

The information in this section applies to Windows 98 Second Edition, Windows 2000, Windows Me, Windows XP and future operating systems that support WDM.

To determine if a WDM driver supports a given wave format, attempt to create a DSBCAPS_LOCHARDWARE buffer in the desired format on that driver. This is the only way within the DirectSound API to discover whether the non-PCM data format is supported.

Secondary DSBCAPS_LOCHARDWARE buffers in any valid format (both WAVEFORMATEX and EXTENSIBLE) are supported if the specific driver being used supports the format. This means having a non-PCM data range with the SPECIFIER_DSOUND designation.

To use non-PCM formats in DirectSound, simply create a WAVEFORMATEX or WAVEFORMATEXTENSIBLE structure describing the format and pass it to CreateSoundBuffer in the lpwfxFormat member of the DSBUFFERDESC structure. No other changes to existing DirectSound code are required to use these formats. However, note that certain formats are less likely to support controls that are taken for granted for PCM data. For example, a card supporting digital output of AC3-encoded data probably would not support the DSBCAPS_CTRLPAN or DSBCAPS_CTRLVOLUME controls on that data, so attempting to create the DirectSound buffer with those flags would fail.

DirectSound playback through VxD drivers or legacy waveOut drivers is still limited to PCM; this has not been addressed.

AC-3 Data Ranges

Wave format tag 0x0092 is defined as AC-3 over S/PDIF. Tags 0x0240 and 0x0241 are synonymous and treated in an identical manner by many DVD applications. To eliminate redundancy, Microsoft recommends that drivers and applications support wave format tag 0x0092. Microsoft does not recommend supporting 0x0240 or 0x0241 at this time.

If AC-3 data is intended to be passed digitally without decode, it can be treated the same as a 2-channel, 16-bit, 48 kHz PCM stream. In fact, when specifying an AC-3 over S/PDIF data range, the wave format tag is the only element that differs from a data range of PCM data being sent out of the S/PDIF port.

Note: AC-3 data is streamed in units called frames. Each frame can be independently decoded into 1536 samples of PCM audio (multiplied by the number of channels in the frame). This represents 32 milliseconds of audio at 48 kHz sample rate. A 5.1 channel AC-3 frame occupies fewer bytes than 1536 stereo PCM samples. There are exceptions to this, but those types of AC-3 frames are very uncommon, cannot be transmitted over S/PDIF, and will not be discussed in this article. Therefore, to prevent delivering the compressed audio bitstream over the S/PDIF interface faster than real time (that is, to prevent delivering 32 ms of audio in less than 32 ms), an AC-3 frame must be padded with zeros until it takes up the same number of bytes as 1536 stereo PCM samples.

If attempting to send unpadded AC-3 to a PortCls adapter driver that uses WaveCyclic, note that when the port driver senses data starvation, it will fill the cyclic buffer with silence. The port driver senses data starvation because the data stream contains fewer bytes than a two-channel uncompressed stream. When the cyclic buffer is filled with silence, it causes problems on the AC-3 decode because these periods of silence will not correspond to AC-3 frames.

Finally, take into account hardware specifics, such as indicating a non-PCM S/PDIF stream by setting the /AUDIO bit on the S/PDIF transceiver if you are doing AC-3 S/PDIF pass-through. This bit in the S/PDIF frame header will indicate to the receiver/decoder that the data stream must be decoded.

BOOL CDSBuffer::CreateSoundBuffer(LPDIRECTSOUND lpDS, DWORD dwFlags, DWORD dwBufSize, DWORD dwFreq, DWORD dwBitsPerSample, DWORD dwBlkAlign, BOOL bStereo)
{
	PCMWAVEFORMAT pcmwf;
	DSBUFFERDESC dsbdesc;
	
	// Set up wave format structure.
	memset( &pcmwf, 0, sizeof(PCMWAVEFORMAT) );
	pcmwf.wf.wFormatTag         = WAVE_FORMAT_PCM;      
	pcmwf.wf.nChannels          = bStereo ? 2 : 1;
	pcmwf.wf.nSamplesPerSec     = dwFreq;
	pcmwf.wf.nBlockAlign        = (WORD)dwBlkAlign;
	pcmwf.wf.nAvgBytesPerSec    = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
	pcmwf.wBitsPerSample        = (WORD)dwBitsPerSample;
	
	// Set up DSBUFFERDESC structure.
	memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));  // Zero it out. 
	dsbdesc.dwSize              = sizeof(DSBUFFERDESC);
	dsbdesc.dwFlags             = dwFlags;
	dsbdesc.dwBufferBytes       = dwBufSize; 
	dsbdesc.lpwfxFormat         = (LPWAVEFORMATEX)&pcmwf;
	
	if (DS_OK != lpDS->CreateSoundBuffer(&dsbdesc, &m_lpDSBuffer, NULL))
	{
		MessageBox(g_hWnd,"Error - DS - CreateSoundBuffer","Error",MB_OK);
		return FALSE;
	}
	
	return TRUE;
}
AUI_ERRCODE aui_DirectSound::CreateDSBuffer() 
{ 
	PCMWAVEFORMAT pcmwf; 
	DSBUFFERDESC dsbdesc; 
	LPDIRECTSOUND	dsHandle; 

	aui_DirectAudioManager *audioManager =
		(aui_DirectAudioManager *)(void *)g_ui->TheAudioManager();

  
  memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); 
  pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; 
  pcmwf.wf.nChannels = 1; 
  pcmwf.wf.nSamplesPerSec = 22050; 
  pcmwf.wf.nBlockAlign = 1; 
  pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; 
  pcmwf.wBitsPerSample = 8; 

  memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); 
  dsbdesc.dwSize = sizeof(DSBUFFERDESC); 
  dsbdesc.dwFlags =   DSBCAPS_STATIC;
  dsbdesc.dwBufferBytes = m_size; 
  dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf; 

	dsHandle = audioManager->GetdDSHandle();
	
	if (dsHandle->CreateSoundBuffer( &dsbdesc, &dsb, NULL) < DS_OK)
		return AUI_ERRCODE_MEMALLOCFAILED;

	return AUI_ERRCODE_OK;
}
//===========================================================================
// CreateDSBuffer
//===========================================================================
int CreateDSBuffer(DWORD flags, int samples, int freq, int bits, int channels, 
				   LPDIRECTSOUNDBUFFER *bufAddr)
{
	DSBUFFERDESC	bufd;
	WAVEFORMATEX	form;
	DWORD			dataBytes = samples * bits/8 * channels;
	
	// Prepare the buffer description.
	memset(&bufd, 0, sizeof(bufd));
	bufd.dwSize = sizeof(bufd);
	bufd.dwFlags = flags;
	bufd.dwBufferBytes = dataBytes;
	bufd.lpwfxFormat = &form;

	// Prepare the format description.
	memset(&form, 0, sizeof(form));
	form.wFormatTag = WAVE_FORMAT_PCM;
	form.nChannels = channels;
	form.nSamplesPerSec = freq;
	form.nBlockAlign = channels * bits/8;
	form.nAvgBytesPerSec = form.nSamplesPerSec * form.nBlockAlign;
	form.wBitsPerSample = bits;

	return dsound->CreateSoundBuffer(&bufd, bufAddr, NULL);
}
/*------------------------------------------------------------------------
*
* PROTOTYPE  :  uint16_t static DS_AllocBuffer(uint32_t size, uint32_t nSamplesPerSec, uint16_t nBitsPerSample, uint16_t nChannels, uint16_t channel, DWORD smode)
*
* DESCRIPTION :  Allocate a DirectSound secondary buffer.
*
*/
static uint16_t DS_AllocBuffer(uint32_t size, uint32_t nSamplesPerSec, uint16_t nBitsPerSample, uint16_t nChannels, short channel, DWORD smode)
{
	HRESULT  hr;
    PCMWAVEFORMAT   pwf;
    DS_handle      *hnd = channel>=0  ? g_pDSHandles + channel : &DS_SecBuffer;
    // Initialize
    sysMemZero(&pwf, sizeof(PCMWAVEFORMAT));
    pwf.wBitsPerSample =  nBitsPerSample;
    pwf.wf.nChannels =  nChannels;
    // Format Tag should be the same as the Primary (Compatiblity with some non certified drivers).
    pwf.wf.wFormatTag =  g_cDSPCMOutFormat.wFormatTag;
    pwf.wf.nSamplesPerSec  =  g_cDSPCMOutFormat.nSamplesPerSec ? g_cDSPCMOutFormat.nSamplesPerSec : nSamplesPerSec ;
    pwf.wf.nBlockAlign =  (uint16_t)(pwf.wf.nChannels *  (pwf.wBitsPerSample>>3));
    pwf.wf.nAvgBytesPerSec =  (uint32_t)pwf.wf.nSamplesPerSec * (uint32_t)pwf.wf.nBlockAlign;
    // Initialisation de la structure buffer
    sysMemZero(&DS_BufferDesc, sizeof(DSBUFFERDESC));
    DS_BufferDesc.dwSize =  sizeof(DSBUFFERDESC);
    DS_BufferDesc.dwFlags  =  smode;
    DS_BufferDesc.dwBufferBytes =  size;
    DS_BufferDesc.lpwfxFormat =  (LPWAVEFORMATEX) &pwf;
    // Creation du buffer son
    hr = g_lpDSDevice->CreateSoundBuffer( &DS_BufferDesc, &hnd->pbuffer, NULL);
    if (SYS_DXTRACE(hr))
    {
		return 0;
    }
    return (hr != DS_OK) ? (uint16_t)0 : channel<0 ? (uint16_t)0xff : (uint16_t)(channel+1);
}
//-----------------------------------------------------------------------------
// Name: DSUtil_LoadSoundBuffer()
// Desc:
//-----------------------------------------------------------------------------
LPDIRECTSOUNDBUFFER DSUtil_LoadSoundBuffer( LPDIRECTSOUND pDS, LPCTSTR strName )
{
    LPDIRECTSOUNDBUFFER pDSB = NULL;
    DSBUFFERDESC        dsbd;
    BYTE*               pbWaveData;

    ZeroMemory( &dsbd, sizeof(dsbd) );
    dsbd.dwSize  = sizeof(dsbd);
    dsbd.dwFlags = DSBCAPS_STATIC|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME|
                   DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPOSITIONNOTIFY;

    if( SUCCEEDED( DSUtil_GetWaveResource( NULL, strName, &dsbd.lpwfxFormat,
                                           &pbWaveData, &dsbd.dwBufferBytes ) ) )
    {

        if( SUCCEEDED( pDS->CreateSoundBuffer( &dsbd, &pDSB, NULL ) ) )
        {
            if( FAILED( DSUtil_FillSoundBuffer( pDSB, pbWaveData,
                                                dsbd.dwBufferBytes ) ) )
            {
                pDSB->Release();
                pDSB = NULL;
            }
        }
        else
        {
            pDSB = NULL;
        }
    }

    return pDSB;
}
//-----------------------------------------------------------------------------
//	Проверка возможности использования алгоритма трехмерного звука
// на входе    :  direct   - указатель интерфейс Direct Sound
//  			  alg      - тестируемый алгорим
// на выходе   :	успешность использования
//-----------------------------------------------------------------------------
int ds_TestAlgorithm(LPDIRECTSOUND direct, int alg)
{
	// объявление переменных
	int ret;
	DSBUFFERDESC dsbd;
	WAVEFORMATEX wfx;
	LPDIRECTSOUNDBUFFER buffer;

	// заполним структуру с форматом
	wfx.wFormatTag = 1;
	wfx.nChannels = 2;
	wfx.nSamplesPerSec = 44100;
	wfx.wBitsPerSample = 16;
	wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample) >> 3;
	wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
	wfx.cbSize = 0;

	// проверка наличия объекта воспроизведения
	if (direct) {
		// занесение данных вторичного буфера
		ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));
		dsbd.dwSize = sizeof(DSBUFFERDESC);
		dsbd.dwFlags = DSBCAPS_STATIC |
			DSBCAPS_CTRLFREQUENCY |
			DSBCAPS_CTRLVOLUME |
			DSBCAPS_GLOBALFOCUS |
			DSBCAPS_CTRL3D |
			DSBCAPS_MUTE3DATMAXDISTANCE;
		dsbd.dwBufferBytes = 128;
		dsbd.lpwfxFormat = &wfx;
		/* !!! убрать !!!
					// подбор способа общета трехмерного звука
					switch(alg)
				  {
						case 0x0:
						dsbd.guid3DAlgorithm = DS3DALG_DEFAULT;
						break;
						case 0x1:
						dsbd.guid3DAlgorithm = DS3DALG_NO_VIRTUALIZATION;
						break;
						case 0x2:
						dsbd.guid3DAlgorithm = DS3DALG_HRTF_FULL;
						break;
						case 0x3:
						dsbd.guid3DAlgorithm = DS3DALG_HRTF_LIGHT;
						break;
					}*/

		// Создание вторичного буфера
		ret = (direct->CreateSoundBuffer(&dsbd, & buffer, NULL) == DS_OK) ?
			true :
			false;
		if (ret)
			buffer->Release();
	}

	// вернем результат
	return ret;
}
int audioStreamer_ds::Open(int iswrite, int srate, int nch, int bps, int sleep, int nbufs, int bufsize, GUID *device)
{
  // todo: use device
  m_sleep = sleep >= 0 ? sleep : 0;

  GUID zero={0,};
  if (!memcmp(device,&zero,sizeof(zero))) device=NULL;

  m_nch = nch;
  m_srate=srate;
  m_bps=bps;

  int fmt_align=(bps>>3)*nch;
  int fmt_mul=fmt_align*srate;
  WAVEFORMATEX wfx={
		WAVE_FORMAT_PCM,
		nch,
		srate,
		fmt_mul,
		fmt_align,
		bps,
		0
	};
  m_totalbufsize=nbufs*bufsize;

  if (iswrite)
  {
      DirectSoundCreate(device,&m_lpds,NULL);

      if (m_lpds)
      {
        HWND hWnd = GetForegroundWindow();
        if (hWnd == NULL) hWnd = GetDesktopWindow();
        m_lpds->SetCooperativeLevel(hWnd,DSSCL_PRIORITY);

        // create a secondary buffer for now
        DSBUFFERDESC ds={sizeof(ds),DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_GLOBALFOCUS,m_totalbufsize,0,&wfx, };
        m_lpds->CreateSoundBuffer(&ds,&m_outbuf,NULL);
        
      }

  }
  else
  {
    DirectSoundCaptureCreate(device,&m_lpcap,NULL);
    if (m_lpcap)
    {
      DSCBUFFERDESC ds={sizeof(ds),0,m_totalbufsize,0,&wfx, };
      m_lpcap->CreateCaptureBuffer(&ds,&m_inbuf,NULL);
    }
  }

  m_bufsize=bufsize;


  return 0;
}
/*
===============
idAudioHardwareWIN32::Create
===============
*/
int idAudioHardwareWIN32::Create(idAudioBuffer **ppSound,
                                 const char *strWaveFileName,
                                 dword dwCreationFlags)
{
	int hr;
	LPDIRECTSOUNDBUFFER   apDSBuffer     = NULL;
	dword                 dwDSBufferSize = NULL;
	idWaveFile          *pWaveFile      = NULL;

	if (m_pDS == NULL)
		return -1;

	if (strWaveFileName == NULL || ppSound == NULL)
		return -1;

	pWaveFile = new idWaveFile();

	pWaveFile->Open(strWaveFileName, NULL);

	if (pWaveFile->GetOutputSize() == 0)     {
		// Wave is blank, so don't create it.
		hr = E_FAIL;
		goto LFail;
	}

	// Make the DirectSound buffer the same size as the wav file
	dwDSBufferSize = pWaveFile->GetOutputSize();

	// Create the direct sound buffer, and only request the flags needed
	// since each requires some overhead and limits if the buffer can
	// be hardware accelerated
	DSBUFFERDESC dsbd;
	memset(&dsbd, 0, sizeof(DSBUFFERDESC));
	dsbd.dwSize          = sizeof(DSBUFFERDESC);
	dsbd.dwFlags         = dwCreationFlags;
	dsbd.dwBufferBytes   = dwDSBufferSize;
	dsbd.guid3DAlgorithm = GUID_NULL;
	dsbd.lpwfxFormat     = (WAVEFORMATEX *)&pWaveFile->mpwfx;

	// DirectSound is only guarenteed to play PCM data.  Other
	// formats may or may not work depending the sound card driver.
	if (FAILED(hr = m_pDS->CreateSoundBuffer(&dsbd, &apDSBuffer, NULL)))
		return -1;

	// Create the sound
	*ppSound = new idAudioBufferWIN32(apDSBuffer, dwDSBufferSize, pWaveFile);

	pWaveFile->Close();

	return 0;

LFail:
	// Cleanup
	SAFE_DELETE(pWaveFile);
	return -1;
}
		HRESULT create(LPDIRECTSOUND dsound)
		{
			assert(!m_buffer);
			DSBUFFERDESC desc;
			memset(&desc, 0, sizeof(desc));
			desc.dwSize = sizeof(desc);
			desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2;
			desc.lpwfxFormat = nullptr;
			return dsound->CreateSoundBuffer(&desc, &m_buffer, nullptr);
		}
// Secondary SoundBuffer erstellen und Wave-Daten aus der Datei fileName in den Buffer laden
int	MakeSoundBuffer(const char *fileName, LPDIRECTSOUNDBUFFER *lpDSB)
{
	DSBUFFERDESC         dsbd;          // SB Description
	BYTE                *pDSBuffData;   // SB Daten Adresse
	WAVEFORMATEX         waveFormat;    // Wave Format
	DWORD                dwDataLength;  // Länge der Wave Daten
	PBYTE                pbyWaveDaten;  // Eigentliche Wave Daten
	HRESULT              dsrval;        // Rückgabewert

	pbyWaveDaten = NULL;

	if(LoadWave(fileName, &waveFormat, &dwDataLength, &pbyWaveDaten))
	{
		MessageBox(NULL, "Error", "LoadWave()", NULL);
		return 1;
	}

	ZeroMemory(&dsbd,sizeof(DSBUFFERDESC));
	dsbd.dwSize = sizeof(DSBUFFERDESC);
	dsbd.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME |
				  DSBCAPS_CTRLFREQUENCY | DSBCAPS_STATIC;
	dsbd.dwBufferBytes = dwDataLength;	//Länge der Wave-Daten
	dsbd.lpwfxFormat = &waveFormat;		//Format der Wave-Daten

	dsrval = lpDS->CreateSoundBuffer(&dsbd, lpDSB, NULL);
	if (FAILED(dsrval))
	{
		MessageBox(NULL, "Error", "CreateSoundBuffer()", NULL);
		return 1;
	}

	// Sound Buffer verriegeln um Daten zu speichern
	dsrval = (*lpDSB)->Lock(0,dwDataLength,(LPVOID *)&pDSBuffData,
						   &dwDataLength,NULL,0,0);
	if (FAILED(dsrval))
	{
		MessageBox(NULL, "Error", "Lock()", NULL);
		return 1;
	}

	// Kopieren der Sounddaten in den Sound Buffer
	memcpy(pDSBuffData,pbyWaveDaten,dwDataLength);
	// Freigeben der Sounddaten (Werden jetzt nicht mehr gebraucht)
	free(pbyWaveDaten);

	// Sound Buffer entriegeln
	dsrval = (*lpDSB)->Unlock(pDSBuffData,dwDataLength,NULL,0);
	if (FAILED(dsrval))
	{
		MessageBox(NULL, "Error", "Unlock()", NULL);
		return 1;
	}

	return 0;
}
// initialize
bool sspDSDeviceGroup::initializeImpl(LPVOID hWnd)
{
	if (m_pDS.size() > 0) return TRUE;	// Already initialized

    if (hWnd == NULL)
    {
        // Error, invalid hwnd
        DOUT (_T("ERROR: Invalid parameters, unable to initialize servicesnr"));
        return FALSE;
    }
	m_hApp = (HWND) hWnd;
    setBufferFormat(2);
	m_pDS.reserve(m_nDevices.size());
	m_pDSBuf.reserve(m_nDevices.size());
	for (unsigned int i=0; i<m_nDevices.size(); i++) {
		// Create DirectSound object
		LPDIRECTSOUND ds;
		HRESULT nResult = DirectSoundCreate(m_dsInfo[m_nDevices[i]]->lpGuid, &ds, NULL);
		if (nResult == DS_OK) {
			nResult = ds->SetCooperativeLevel(m_hApp, DSSCL_PRIORITY);
			if (nResult == DS_OK) {
				LPDIRECTSOUNDBUFFER dsbuf;
				nResult = ds->CreateSoundBuffer(&m_dsBufDesc, &dsbuf, NULL);
				if (nResult == DS_OK) {
					nResult = dsbuf->SetFormat(&m_pcmWf);
					if (nResult == DS_OK) {
						DOUT (_T("SUCCESS: DirectSound created and formattednr"));
					}
					else {
						DOUT(_T("ERROR: Unable to set DirectSound formatnr"));
						return FALSE;
					}
				m_pDSBuf.push_back(dsbuf);
				}
				else {
					DOUT(_T("ERROR: Unable to create DirectSound buffernr"));
					return FALSE;
				}
			}
			else {
				DOUT(_T("ERROR: Unable to set DirectSound cooperative levelnr"));
				return FALSE;
			}
			m_pDS.push_back(ds);
		}
		else {
			// Error
			DOUT(_T("ERROR: Unable to create DirectSound objectnr"));
			return FALSE;
		}
	}
    return TRUE;
}
		HRESULT create(LPDIRECTSOUND dsound, DWORD size, WAVEFORMATEX &format)
		{
			assert(!m_buffer);
			DSBUFFERDESC desc;
			memset(&desc, 0, sizeof(desc));
			desc.dwSize = sizeof(desc);
			desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;
			desc.dwBufferBytes = size;
			desc.lpwfxFormat = &format;
			m_size = size;
			return dsound->CreateSoundBuffer(&desc, &m_buffer, nullptr);
		}
//-----------------------------------------------------------------------------
//	Создание звукового буфера
// на входе    :  direct   - указатель интерфейс Direct Sound
//  			  desc     - указатель на структуру описывающую параметры
//  						 создаваемого буфера
// на выходе   :	указатель на созданный звуковой буфер, если значение равно 0
//  			  значит создание не состоялось
//-----------------------------------------------------------------------------
LPDIRECTSOUNDBUFFER ds_CreateBuffer(LPDIRECTSOUND direct, LPDSBUFFERDESC desc)
{
	LPDIRECTSOUNDBUFFER buffer = 0;

	// проверка наличия Direct Sound объекта
	if (!direct)
		return 0;

	// Создание вторичного буфера
	if (direct->CreateSoundBuffer(desc, & buffer, NULL) == DS_OK)
		return buffer;

	// создание не состоялось
	return 0;
}
BOOL LC3Sound::LoadSamp(LPDIRECTSOUND lpDirectSound,
              LPDIRECTSOUNDBUFFER *lplpDsb,
              LPBYTE samp, UINT length, UINT flags)
{
    DSBUFFERDESC dsbdesc;
    HRESULT hr;
    WAVEFORMATEX pcmwf;

    // Set up wave format structure.
    memset(&pcmwf, 0, sizeof(WAVEFORMATEX));
    pcmwf.wFormatTag			= WAVE_FORMAT_PCM;
    pcmwf.nChannels = 1;
    pcmwf.nSamplesPerSec		= 22050;
    pcmwf.wBitsPerSample		= 8;
    pcmwf.nBlockAlign			= pcmwf.nChannels * (pcmwf.wBitsPerSample/8);
    pcmwf.nAvgBytesPerSec		= pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
    
    // Set up DSBUFFERDESC structure.
    memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out.
    dsbdesc.dwSize = sizeof(DSBUFFERDESC);
//    dsbdesc.dwFlags =	DSBCAPS_STATIC | DSBCAPS_CTRLDEFAULT | DSBCAPS_GETCURRENTPOSITION2;	//;	//;	// | flags;	//DSBCAPS_STATIC | DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLFREQUENCY| DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2|flags;
  
//  	dsbdesc.dwFlags =	DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLFREQUENCY|flags;
  	
  	dsbdesc.dwFlags =  DSBCAPS_GLOBALFOCUS;
    dsbdesc.dwBufferBytes = length;
    dsbdesc.dwReserved = 0;
    dsbdesc.lpwfxFormat = &pcmwf;
    hr = lpDirectSound->CreateSoundBuffer( &dsbdesc, lplpDsb, NULL);
    if(hr == DS_OK)
    {
//        lpDirectSound->lpVtbl->SetCooperativeLevel(
//                lpDirectSound,hwnd, DSSCL_EXCLUSIVE);
        // Succeeded! Valid interface is in *lplpDsb.
  //      WriteDataToBuffer(*lplpDsb, 0, samp,length);
//        lpDirectSound->lpVtbl->SetCooperativeLevel(
//                lpDirectSound,hwnd, DSSCL_NORMAL);
    }
    else
    {
    	//DEBUG debugger( TranslateDSError( hr));
    	
      *lplpDsb=NULL;
      return 0;
    }
    return 1;
}
HRESULT STDMETHODCALLTYPE DirectSound::CreateSoundBuffer(LPCDSBUFFERDESC pcDSBufferDesc, LPDIRECTSOUNDBUFFER *ppDSBuffer, LPUNKNOWN pUnkOuter)
{
	LPDIRECTSOUNDBUFFER localBuffer;
	HRESULT hr = m_ds->CreateSoundBuffer(pcDSBufferDesc, &localBuffer, pUnkOuter);
	if (FAILED(hr))
	{
		return hr;
	}

	(*ppDSBuffer) = createWrapper(localBuffer);
	if (!*ppDSBuffer)
	{
		localBuffer->Release();
		return DSERR_OUTOFMEMORY;
	}
	return hr;
}
BOOL LC3Sound::AppCreateWritePrimaryBuffer(
    LPDIRECTSOUND lpDirectSound,
    LPDIRECTSOUNDBUFFER *lplpDsb,
    HWND hwnd)
{
    DSBUFFERDESC dsbdesc;
    HRESULT hr;
    WAVEFORMATEX pcmwf;

    // Set up wave format structure.
    memset(&pcmwf, 0, sizeof(WAVEFORMATEX));
    pcmwf.wFormatTag 		= WAVE_FORMAT_PCM;
    
    pcmwf.nChannels = 1;
    pcmwf.nSamplesPerSec		= 22050;
    pcmwf.wBitsPerSample		= 8;
    pcmwf.nBlockAlign			= pcmwf.nChannels * (pcmwf.wBitsPerSample/8);
    pcmwf.nAvgBytesPerSec		= pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
    
    // Set up DSBUFFERDESC structure.
    memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out.
    dsbdesc.dwSize = sizeof(DSBUFFERDESC);
    dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;	//;	//DSBCAPS_GLOBALFOCUS;	//;
    dsbdesc.dwBufferBytes = 0; // Buffer size is determined
                               // by sound hardware.
    dsbdesc.lpwfxFormat = NULL; // Must be NULL for primary buffers.
    // Obtain write-primary cooperative level.
    hr = lpDirectSound->SetCooperativeLevel(hwnd, DSSCL_PRIORITY);
    if(DS_OK == hr)
    {
        // Succeeded! Try to create buffer.
        hr = lpDirectSound->CreateSoundBuffer(
            &dsbdesc, lplpDsb, NULL);
        if(DS_OK == hr) {
            // Succeeded! Set primary buffer to desired format.
            hr = (*lplpDsb)->SetFormat(&pcmwf);
            (*lplpDsb)->Play(0, 0, DSBPLAY_LOOPING);
            return TRUE;
        }
    }
    // If we got here, then we failed SetCooperativeLevel.
    // CreateSoundBuffer, or SetFormat.
    *lplpDsb = NULL;
    return FALSE;
}
//-----------------------------------------------------------------------------
// Name: idAudioHardwareWIN32::CreateFromMemory()
// Desc:
//-----------------------------------------------------------------------------
int idAudioHardwareWIN32::CreateFromMemory(idAudioBufferWIN32 **ppSound,
                byte *pbData,
                ulong  ulDataSize,
                waveformatextensible_t *pwfx,
                dword dwCreationFlags)
{
	int hr;
	LPDIRECTSOUNDBUFFER		apDSBuffer     = NULL;
	dword					dwDSBufferSize = NULL;
	idWaveFile			*pWaveFile      = NULL;

	if (m_pDS == NULL)
		return -1;

	if (pbData == NULL || ppSound == NULL)
		return -1;

	pWaveFile = new idWaveFile();

	pWaveFile->OpenFromMemory((short *)pbData, ulDataSize, (waveformatextensible_t *)pwfx);


	// Make the DirectSound buffer the same size as the wav file
	dwDSBufferSize = ulDataSize;

	// Create the direct sound buffer, and only request the flags needed
	// since each requires some overhead and limits if the buffer can
	// be hardware accelerated
	DSBUFFERDESC dsbd;
	memset(&dsbd, 0, sizeof(DSBUFFERDESC));
	dsbd.dwSize          = sizeof(DSBUFFERDESC);
	dsbd.dwFlags         = dwCreationFlags | DSBCAPS_GETCURRENTPOSITION2;
	dsbd.dwBufferBytes   = dwDSBufferSize;
	dsbd.guid3DAlgorithm = GUID_NULL;
	dsbd.lpwfxFormat     = (WAVEFORMATEX *)pwfx;

	if (FAILED(hr = m_pDS->CreateSoundBuffer(&dsbd, &apDSBuffer, NULL)))
		return -1;

	// Create the sound
	*ppSound = new idAudioBufferWIN32(apDSBuffer, dwDSBufferSize, pWaveFile);

	return S_OK;
}
LPDIRECTSOUNDBUFFER MkSoundBuffer::_CreateSoundBuffer(LPDIRECTSOUND directSound, const WAVEFORMATEX& waveFormatEx, const MkByteArray& dataBuffer)
{
	// 사운드 버퍼 생성
	DSBUFFERDESC desc;
	::ZeroMemory(&desc, sizeof(DSBUFFERDESC));
	desc.dwSize = sizeof(DSBUFFERDESC);
	desc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN;
	desc.dwBufferBytes = dataBuffer.GetSize();
	desc.lpwfxFormat = const_cast<LPWAVEFORMATEX>(&waveFormatEx);

	LPDIRECTSOUNDBUFFER soundBuffer = NULL;
	do
	{
		if (FAILED(directSound->CreateSoundBuffer(&desc, &soundBuffer, NULL)))
			break;

		// 사운드 버퍼에 데이터 복사
		LPVOID primarySoundBuffer = NULL;
		LPVOID secondarySoundBuffer = NULL;
		DWORD primaryLength, secondaryLength;

		if (FAILED(soundBuffer->Lock(0, desc.dwBufferBytes, &primarySoundBuffer, &primaryLength, &secondarySoundBuffer, &secondaryLength, 0)))
			break;

		memcpy_s(primarySoundBuffer, primaryLength, dataBuffer.GetPtr(), primaryLength); // 순환 버퍼의 앞부분 복사
		memcpy_s(secondarySoundBuffer, secondaryLength, dataBuffer.GetPtr() + primaryLength, secondaryLength); // 순환 버퍼의 뒷부분 복사

		if (FAILED(soundBuffer->Unlock(primarySoundBuffer, primaryLength, secondarySoundBuffer, secondaryLength)))
			break;

		return soundBuffer;
	}
	while (false);

	if (soundBuffer != NULL)
	{
		soundBuffer->Release();
	}
	return NULL;
}
static int Initialize(void *hwnd)
{
    DSBUFFERDESC primaryDesc;
    if (!g_lpDSDevice) return TRUE;
    sysMemZero(&primaryDesc, sizeof(DSBUFFERDESC));
    primaryDesc.dwSize = sizeof(DSBUFFERDESC);
    primaryDesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
    if (RLX.Audio.Config & RLXAUDIO_Use3D)
		primaryDesc.dwFlags|= DSBCAPS_CTRL3D;

	if (SYS_DXTRACE(g_lpDSDevice->SetCooperativeLevel((HWND)hwnd, DSSCL_EXCLUSIVE)) != DS_OK)
		return -1;

	if (SYS_DXTRACE(g_lpDSDevice->CreateSoundBuffer(&primaryDesc, &g_lpPrimaryBuffer, NULL))!=DS_OK )
		return 0;
    else
    {
		HRESULT hr;
		sysMemZero(&g_cDSPCMOutFormat, sizeof(WAVEFORMATEX));
		g_cDSPCMOutFormat.wFormatTag = WAVE_FORMAT_PCM;
		g_cDSPCMOutFormat.wBitsPerSample = 16;
		g_cDSPCMOutFormat.nChannels = 2;
		g_cDSPCMOutFormat.nSamplesPerSec = 44100;
		g_cDSPCMOutFormat.nBlockAlign = (uint16_t)(g_cDSPCMOutFormat.nChannels   *  (g_cDSPCMOutFormat.wBitsPerSample>>3));
		g_cDSPCMOutFormat.nAvgBytesPerSec = (uint32_t)g_cDSPCMOutFormat.nBlockAlign *  (uint32_t)g_cDSPCMOutFormat.nSamplesPerSec;
		hr = g_lpPrimaryBuffer->SetFormat(&g_cDSPCMOutFormat);
		if ( hr != DS_OK )
			FindAlternateSampleFormat();

        if (RLX.Audio.Config & RLXAUDIO_Use3D)
        {
			hr = SYS_DXTRACE(g_lpPrimaryBuffer->QueryInterface(IID_IDirectSound3DListener, (void**)&g_lpDS3DListener));
            if (hr== DS_OK)
				hr = g_lpDS3DListener->SetAllParameters(&Listener3dProps, DS3D_IMMEDIATE);
        }
    }
    return 0; // no problemo.
}
//-----------------------------------------------------------------------------
//	Создание первичного буфера
// на входе    :  direct   - указатель на Direct Sound объект
// на выходе   :	указатель на первичный буфер, в случае если значение равно 0
//  			  значит создание не состоялось
//-----------------------------------------------------------------------------
LPDIRECTSOUNDBUFFER ds_CreatePrimary(LPDIRECTSOUND direct)
{
	DSBUFFERDESC dsbd;
	LPDIRECTSOUNDBUFFER primary;

	// защита от дурака
	if (!direct)
		return 0;

	// создание данных для получения доступа к первичному буферу
	ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));
	dsbd.dwSize = sizeof(DSBUFFERDESC);
	dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER |
		DSBCAPS_CTRL3D |
		DSBCAPS_CTRLVOLUME;
	dsbd.dwBufferBytes = 0;
	dsbd.lpwfxFormat = NULL;

	// получение доступа к первичному буферу
	if (direct->CreateSoundBuffer(&dsbd, & primary, NULL) != DS_OK)
		return 0;

	return primary;
}
bool nuiAudioDevice_DirectSound::Open(std::vector<uint32>& rInputChannels, std::vector<uint32>& rOutputChannels, double SampleRate, uint32 BufferSize, nuiAudioProcessFn pProcessFunction)
{
  if (!mpDirectSound)
    return false;
  
  HRESULT hr = S_OK;
  mAudioProcessFn = pProcessFunction;

  mBufferSize = BufferSize;

  hr = mpDirectSound->SetCooperativeLevel(GetDesktopWindow(), DSSCL_EXCLUSIVE);

  mHasInput = (rInputChannels.size() > 0) && (mInputChannels.size() > 0);
  mHasOutput = (rOutputChannels.size() > 0) && (mOutputChannels.size() > 0);


  mpInputBuffer = NULL;
  mpOutputBuffer = NULL;

  if (!mHasInput && !mHasOutput)
    return false;

  // init ringbuffer
  mpRingBuffer = new nglRingBuffer(BufferSize*4, sizeof(float), rOutputChannels.size());
  mpRingBuffer->AdvanceWriteIndex(BufferSize);

  // init input buffers
  if (mHasInput)
  {
    {
      mActiveInputChannels = rInputChannels;
    }

    WAVEFORMATEX IFormat;
    IFormat.wFormatTag = WAVE_FORMAT_PCM;
    IFormat.nChannels = (WORD)mInputChannels.size();
    IFormat.nSamplesPerSec = ToNearest(SampleRate);
    IFormat.wBitsPerSample = 16;
    IFormat.nAvgBytesPerSec = IFormat.nChannels * IFormat.nSamplesPerSec * (IFormat.wBitsPerSample / 8);
    IFormat.nBlockAlign = IFormat.nChannels * (IFormat.wBitsPerSample / 8);
    IFormat.cbSize = 0;

    DSCBUFFERDESC IBufferDesc;
    memset(&IBufferDesc, 0, sizeof(IBufferDesc));
    IBufferDesc.dwSize = sizeof(DSCBUFFERDESC);
    IBufferDesc.dwFlags = DSCBCAPS_WAVEMAPPED;
    IBufferDesc.dwBufferBytes = (IFormat.wBitsPerSample / 8) * IFormat.nChannels * BufferSize * 2;
    IBufferDesc.dwReserved = 0;
    IBufferDesc.lpwfxFormat = &IFormat;
    IBufferDesc.dwFXCount = 0;
    IBufferDesc.lpDSCFXDesc = NULL;

    NGL_ASSERT(mpDirectSoundCapture);
    hr = mpDirectSoundCapture->CreateCaptureBuffer(&IBufferDesc, &mpInputBuffer, NULL);
  }


  // init output buffers
  if (mHasOutput)
  {
    {
      mActiveOutputChannels = rOutputChannels;
    }

    WAVEFORMATEX OFormat;
    OFormat.wFormatTag = WAVE_FORMAT_PCM;
    OFormat.nChannels = (WORD)mOutputChannels.size();
    OFormat.nSamplesPerSec = ToNearest(SampleRate);
    OFormat.wBitsPerSample = 16;
    OFormat.nAvgBytesPerSec = OFormat.nChannels * OFormat.nSamplesPerSec * (OFormat.wBitsPerSample / 8);
    OFormat.nBlockAlign = OFormat.nChannels * OFormat.wBitsPerSample / 8;
    OFormat.cbSize = 0;

    DSBUFFERDESC  OBufferDesc;
    memset(&OBufferDesc, 0, sizeof(OBufferDesc));
    OBufferDesc.dwSize = sizeof(OBufferDesc);
    OBufferDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY;
    OBufferDesc.dwBufferBytes = (OFormat.wBitsPerSample / 8) * OFormat.nChannels * BufferSize * 2;
    OBufferDesc.dwReserved = 0;
    OBufferDesc.lpwfxFormat = &OFormat;

    hr = mpDirectSound->CreateSoundBuffer(&OBufferDesc, &mpOutputBuffer, NULL);
  }


  // create event for notifications
  mNotifInputEvent[0] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundInputEvent0"));
  mNotifInputEvent[1] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundInputEvent1"));
  mNotifOutputEvent[0] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundOutputEvent0"));
  mNotifOutputEvent[1] = CreateEvent(NULL, FALSE, FALSE, _T("NUI_DSoundOutputEvent1"));




  // set the notification for the input buffer
  if (mHasInput)
  {
    // Setup the notification positions
    ZeroMemory( &mInputPosNotify, sizeof(DSBPOSITIONNOTIFY) * 2);
    mInputPosNotify[0].dwOffset = BufferSize * sizeof(int16) * mInputChannels.size() - 1;
    mInputPosNotify[0].hEventNotify = mNotifInputEvent[0];             
    mInputPosNotify[1].dwOffset = BufferSize * sizeof(int16) * mInputChannels.size() * 2 - 1;
    mInputPosNotify[1].hEventNotify = mNotifInputEvent[1];           

    LPDIRECTSOUNDNOTIFY pInputNotify = NULL;
    if( FAILED( hr = mpInputBuffer->QueryInterface( IID_IDirectSoundNotify, (VOID**)&pInputNotify ) ) )
    {
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in querying interface for input notifications.n"));
      return false;
    }


    // Tell DirectSound when to notify us. the notification will come in the from 
    // of signaled events that are handled in WinMain()
    if( FAILED( hr = pInputNotify->SetNotificationPositions( 2, mInputPosNotify ) ) )
    {
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in setting notifications for inputn"));
      return false;
    }

    pInputNotify->Release();
  }



  // set the notification events for the output buffer
  if (mHasOutput)
  {
    // Setup the notification positions
    ZeroMemory( &mOutputPosNotify, sizeof(DSBPOSITIONNOTIFY) * 2);
    mOutputPosNotify[0].dwOffset = BufferSize * sizeof(int16) * mOutputChannels.size() - 1;
    mOutputPosNotify[0].hEventNotify = mNotifOutputEvent[0];             
    mOutputPosNotify[1].dwOffset = BufferSize * sizeof(int16) * mOutputChannels.size() * 2 - 1;
    mOutputPosNotify[1].hEventNotify = mNotifOutputEvent[1];    

    LPDIRECTSOUNDNOTIFY pOutputNotify = NULL;
    if( FAILED( hr = mpOutputBuffer->QueryInterface( IID_IDirectSoundNotify, (VOID**)&pOutputNotify ) ) )
    {
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in querying interface for output notifications.n"));
      return false;
    }

    // Tell DirectSound when to notify us. the notification will come in the from 
    // of signaled events that are handled in WinMain()
    if( FAILED( hr = pOutputNotify->SetNotificationPositions( 2, mOutputPosNotify ) ) )
    {
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("Open ERROR : failed in setting notifications for outputn"));
      return false;
    }

    pOutputNotify->Release();
  }


  // start input processing thread
  mpProcessingTh = new nuiAudioDevice_DS_ProcessingTh(this, mNotifInputEvent[0], mNotifInputEvent[1], mAudioProcessFn);
  mpProcessingTh->Start();



  // start output thread
  if (mHasOutput)
  {
    mpOutputTh = new nuiAudioDevice_DS_OutputTh(this, mNotifInputEvent[0], mNotifInputEvent[1], mNotifOutputEvent[0], mNotifOutputEvent[1]);
    mpOutputTh->Start();
    hr = mpOutputBuffer->Play(0,0,DSCBSTART_LOOPING);
    if (FAILED(hr))
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("OutputBuffer->Play ERROR!n"));
  }

  // start input capture
  if (mHasInput)
  {
    hr = mpInputBuffer->Start(DSCBSTART_LOOPING);
    if (FAILED(hr))
      NGL_LOG(_T("nuiAudioDevice_DirectSound"), NGL_LOG_ERROR, _T("InputBuffer->Start ERROR!n"));    
  }





  return true;
}
internal void Win32InitDSound(HWND _Window, int32 _SamplerPerSecond, int32 _SecondaryBufferSize)
{
    // NOTE: Load the Library
    HMODULE dSoundLibrary = LoadLibraryA("dsound.dll");
    if (dSoundLibrary)
    {
        // NOTE: Get a DirectSound  object!
        direct_sound_create* directSoundCreate = (direct_sound_create*)
            GetProcAddress(dSoundLibrary, "DirectSoundCreate");

        LPDIRECTSOUND directSound;
        if (directSoundCreate && SUCCEEDED(directSoundCreate(0, &directSound, 0)))
        {
            WAVEFORMATEX waveFormat = {};
            waveFormat.wFormatTag = WAVE_FORMAT_PCM;
            waveFormat.nChannels = 2;
            waveFormat.nSamplesPerSec = _SamplerPerSecond;
            waveFormat.wBitsPerSample = 16;
            waveFormat.nBlockAlign = (waveFormat.nChannels * waveFormat.wBitsPerSample) / 8;
            waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign;
            waveFormat.cbSize = 0;

            if (SUCCEEDED(directSound->SetCooperativeLevel(_Window, DSSCL_PRIORITY)))
            {
                DSBUFFERDESC bufferDescription = {};
                bufferDescription.dwSize = sizeof(bufferDescription);
                bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER;

                LPDIRECTSOUNDBUFFER primaryBuffer;
                if (SUCCEEDED(directSound->CreateSoundBuffer(&bufferDescription, &primaryBuffer, 0)))
                {
                    HRESULT error = primaryBuffer->SetFormat(&waveFormat);
                    if (SUCCEEDED(error))
                    {
                        OutputDebugStringA("primary buffer format was set.n");
                    }
                    else
                    {

                    }
                }
                else
                {

                }
            }
            else
            {

            }

            DSBUFFERDESC bufferDescription = {};
            bufferDescription.dwSize = sizeof(bufferDescription);
            bufferDescription.dwFlags = 0;
            bufferDescription.dwBufferBytes = _SecondaryBufferSize;
            bufferDescription.lpwfxFormat = &waveFormat;
            HRESULT error = directSound->CreateSoundBuffer(&bufferDescription, &GlobalSecondaryBuffer, 0); 
            if (SUCCEEDED(error))
            {
                OutputDebugStringA("Secondary buffer created successfully.n");
            }
        }
        else
        {

        }
    }
    else
    {

    }
}
internal void initDirectSound(HWND windowHandle, int32 samplePerSecond, int32 bufferSize) {
	// Load the library
	HMODULE directSoundLibrary = LoadLibraryA("dsound.dll");
	if ( ! directSoundLibrary ) {
		OutputDebugStringA("Direct sound dll not found ");
		return;
	}

	// Get a direct sound object
	direct_sound_create *directSoundCreate = (direct_sound_create*)GetProcAddress(directSoundLibrary, "DirectSoundCreate");

	HRESULT error;

	LPDIRECTSOUND directSound;
	error = directSoundCreate(0, &directSound, 0);
	if ( directSoundCreate && SUCCEEDED(error) ) {

		DSBUFFERDESC bufferDescription = {};
		bufferDescription.dwSize = sizeof(bufferDescription);
		bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER;

		WAVEFORMATEX waveFormat = {};
		waveFormat.wFormatTag = WAVE_FORMAT_PCM;
		waveFormat.nChannels = 2;
		waveFormat.nSamplesPerSec = samplePerSecond;
		waveFormat.wBitsPerSample = 16;
		waveFormat.nBlockAlign = (waveFormat.nChannels*waveFormat.wBitsPerSample) / 8;
		waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; 
		waveFormat.cbSize = 0;

		

		LPDIRECTSOUNDBUFFER primaryBuffer;
		// create a primary buffer
		
		if ( SUCCEEDED(directSound->SetCooperativeLevel(windowHandle, DSSCL_PRIORITY)) ) {

			if ( SUCCEEDED(error = directSound->CreateSoundBuffer(&bufferDescription, &primaryBuffer, 0)) ) {
				
				if ( !(SUCCEEDED(error = primaryBuffer->SetFormat(&waveFormat))) ) {
					OutputDebugStringA("Primary buffer failed " + error );
				}

			} else {
				OutputDebugStringA("Primary buffer failed " + error);
			}

			DSBUFFERDESC bufferDescription = {};
			bufferDescription.dwSize = sizeof(bufferDescription);
			bufferDescription.dwFlags = 0;
			bufferDescription.dwBufferBytes = bufferSize;
			bufferDescription.lpwfxFormat = &waveFormat;

			
			// create a secondary buffer
			if ( SUCCEEDED(directSound->CreateSoundBuffer(&bufferDescription, &globalSecondaryBuffer, 0)) ) {

			}
		}

		

		// start playing it
	}
	else {
		OutputDebugStringA("Create DSound error " + error);
	}

	

}
internal void Win32InitDSound(HWND Window, int32 SamplesPerSecond, int32 BufferSize)
{
	HMODULE DSoundLibrary = LoadLibraryA("dsound.dll");
	if (DSoundLibrary)
	{
		direct_sound_create *DirectSoundCreate = (direct_sound_create *)GetProcAddress(DSoundLibrary, "DirectSoundCreate");

		// TODO: Double-check that this works on XP - DirectSound8 or 7??
		LPDIRECTSOUND DirectSound;
		if (DirectSoundCreate && SUCCEEDED(DirectSoundCreate(0, &DirectSound, 0)))
		{
			WAVEFORMATEX WaveFormat    = {};
			WaveFormat.wFormatTag      = WAVE_FORMAT_PCM;
			WaveFormat.nChannels       = 2;
			WaveFormat.nSamplesPerSec  = SamplesPerSecond;
			WaveFormat.wBitsPerSample  = 16;
			WaveFormat.nBlockAlign     = (WaveFormat.nChannels*WaveFormat.wBitsPerSample) / 8;
			WaveFormat.nAvgBytesPerSec = WaveFormat.nSamplesPerSec*WaveFormat.nBlockAlign;
			WaveFormat.cbSize          = 0;

			if (SUCCEEDED(DirectSound->SetCooperativeLevel(Window, DSSCL_PRIORITY)))
			{
				DSBUFFERDESC BufferDescription = {};
				BufferDescription.dwSize       = sizeof(BufferDescription);
				BufferDescription.dwFlags      = DSBCAPS_PRIMARYBUFFER;

				// NOTE: "Create" a primary buffer
				// TODO: DSBCAPS_GLOBALFOCUS?
				LPDIRECTSOUNDBUFFER PrimaryBuffer;
				if (SUCCEEDED(DirectSound->CreateSoundBuffer(&BufferDescription, &PrimaryBuffer, 0)))
				{
					HRESULT Error = PrimaryBuffer->SetFormat(&WaveFormat);
					if (SUCCEEDED(Error))
					{
						// NOTE: We have finally set the format!
						OutputDebugStringA("Primary buffer format was set.n");
					}
					else
					{
						// TODO: Diagnostic
					}
				}
				else
				{
					// TODO: Diagnostic
				}
			}
			else
			{
				// TODO: Diagnostic
			}

			// TODO: DSBCAPS_GETCURRENTPOSITION2
			DSBUFFERDESC BufferDescription  = {};
			BufferDescription.dwSize        = sizeof(BufferDescription);
			BufferDescription.dwFlags       = 0;
			BufferDescription.dwBufferBytes = BufferSize;
			BufferDescription.lpwfxFormat   = &WaveFormat;
			HRESULT Error = DirectSound->CreateSoundBuffer(&BufferDescription, &GlobalSecondaryBuffer, 0);
			if (SUCCEEDED(Error))
			{
				OutputDebugStringA("Secondary buffer created successfully.n");
			}
		}
		else
		{
			// TODO: Diagnostic
		}
	}
	else
	{
		// TODO: Diagnostic
	}
}
int DSoundInit(HWND wnd_coop, int rate, int stereo, int seg_samples)
{
  DSBUFFERDESC dsbd;
  WAVEFORMATEX wfx;
  DSBPOSITIONNOTIFY notifies[NSEGS];
  int i;

  memset(&dsbd,0,sizeof(dsbd));
  memset(&wfx,0,sizeof(wfx));

  // Make wave format:
  wfx.wFormatTag=WAVE_FORMAT_PCM;
  wfx.nChannels=stereo ? 2 : 1;
  wfx.nSamplesPerSec=rate;
  wfx.wBitsPerSample=16;

  wfx.nBlockAlign=(WORD)((wfx.nChannels*wfx.wBitsPerSample)>>3);
  wfx.nAvgBytesPerSec=wfx.nBlockAlign*wfx.nSamplesPerSec;

  // Create the DirectSound interface:
  DirectSoundCreate(NULL,&DSound,NULL);
  if (DSound==NULL) return 1;

  LoopSeg = seg_samples * 2;
  if (stereo)
    LoopSeg *= 2;

  LoopLen = LoopSeg * NSEGS;

  DSound->SetCooperativeLevel(wnd_coop, DSSCL_PRIORITY);
  dsbd.dwFlags=DSBCAPS_GLOBALFOCUS;  // Play in background
  dsbd.dwFlags|=DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLPOSITIONNOTIFY;

  // Create the looping buffer:
  dsbd.dwSize=sizeof(dsbd);
  dsbd.dwBufferBytes=LoopLen;
  dsbd.lpwfxFormat=&wfx;

  DSound->CreateSoundBuffer(&dsbd,&LoopBuffer,NULL);
  if (LoopBuffer==NULL) return 1;

  LoopBuffer->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&DSoundNotify);
  if (DSoundNotify == NULL) {
    lprintf("QueryInterface(IID_IDirectSoundNotify) failedn");
    goto out;
  }

  seg_played_event = CreateEvent(NULL, 0, 0, NULL);
  if (seg_played_event == NULL)
    goto out;

  for (i = 0; i < NSEGS; i++) {
    notifies[i].dwOffset = i * LoopSeg;
    notifies[i].hEventNotify = seg_played_event;
  }
  i = DSoundNotify->SetNotificationPositions(NSEGS, notifies);
  if (i != DS_OK) {
    lprintf("SetNotificationPositions failedn");
    goto out;
  }

out:
  LoopBlank();
  LoopBuffer->Play(0, 0, DSBPLAY_LOOPING);
  return 0;
}
int Game_Init(void *parms)
{
// this function is where you do all the initialization 
// for your game

// this example does everything: it sets up directsound
// creates a secondary buffer, loads it with a synthesizer
// sine wave and plays it

void 	*audio_ptr_1 = NULL,   // used to lock memory
		*audio_ptr_2 = NULL;

DWORD	dsbstatus;              // status of sound buffer

DWORD	audio_length_1    = 0,  // length of locked memory
		audio_length_2    = 0,
		snd_buffer_length = 64000; // working buffer

// allocate memory for buffer
UCHAR *snd_buffer_ptr = (UCHAR *)malloc(snd_buffer_length);

// we need some data for the buffer, you could load a .VOC or .WAV
// but as an example, lets synthesize the data

// fill buffer with a synthesized 100hz sine wave
for (int index=0; index < (int)snd_buffer_length; index++)
	snd_buffer_ptr[index] = 127*sin(6.28*((float)(index%110))/(float)110);

// note the math, 127 is the scale or amplitude
// 6.28 is to convert to radians
// (index % 110) read below
// we are playing at 11025 hz or 11025 cycles/sec therefore, in 1 sec
// we want 100 cycles of our synthesized sound, thus 11025/100 is approx.
// 110, thus we want the waveform to repeat each 110 clicks of index, so
// normalize to 110


// create a directsound object
if (DirectSoundCreate(NULL, &lpds, NULL)!=DS_OK )
	return(0);

// set cooperation level
if (lpds->SetCooperativeLevel(main_window_handle,DSSCL_NORMAL)!=DS_OK)
	return(0);

// set up the format data structure
memset(&pcmwf, 0, sizeof(WAVEFORMATEX));

pcmwf.wFormatTag	  = WAVE_FORMAT_PCM;
pcmwf.nChannels		  = 1;
pcmwf.nSamplesPerSec  = 11025;
pcmwf.nBlockAlign	  = 1;
pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign;
pcmwf.wBitsPerSample  = 8;
pcmwf.cbSize		  = 0;

// create the secondary buffer (no need for a primary)
memset(&dsbd,0,sizeof(DSBUFFERDESC));
dsbd.dwSize			= sizeof(DSBUFFERDESC);
dsbd.dwFlags		= DSBCAPS_CTRLDEFAULT | DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE;
dsbd.dwBufferBytes	= snd_buffer_length+1;
dsbd.lpwfxFormat	= &pcmwf;

if (lpds->CreateSoundBuffer(&dsbd,&lpdsbsecondary,NULL)!=DS_OK)
	return(0);

// copy data into sound buffer
if (lpdsbsecondary->Lock(0,					 
					  snd_buffer_length,			
    				  &audio_ptr_1, 
					  &audio_length_1,
					  &audio_ptr_2, 
					  &audio_length_2,
					  DSBLOCK_FROMWRITECURSOR)!=DS_OK)
  return(0);

// copy first section of circular buffer
CopyMemory(audio_ptr_1, snd_buffer_ptr, audio_length_1);

// copy last section of circular buffer
CopyMemory(audio_ptr_2, (snd_buffer_ptr+audio_length_1),audio_length_2);

// unlock the buffer
if (lpdsbsecondary->Unlock(audio_ptr_1, 
						   audio_length_1, 
						   audio_ptr_2, 
						   audio_length_2)!=DS_OK)
	return(0);

// play the sound in looping mode
if (lpdsbsecondary->Play(0,0,DSBPLAY_LOOPING )!=DS_OK)
	return(0);

// release the memory since DirectSound has made a copy of it
free(snd_buffer_ptr);

// return success
return(1);

} // end Game_Init
int SNDDMA_InitDS ()
{
	HRESULT			hresult;
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	WAVEFORMATEX	format;
	int				use8;

	Com_Printf( "Initializing DirectSoundn");

	use8 = 1;
    // Create IDirectSound using the primary sound device
    if( FAILED( hresult = CoCreateInstance(CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (void **)&pDS))) {
		use8 = 0;
	    if( FAILED( hresult = CoCreateInstance(CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound, (void **)&pDS))) {
			Com_Printf ("failedn");
			SNDDMA_Shutdown ();
			return qfalse;
		}
	}

	hresult = pDS->Initialize( NULL);

	Com_DPrintf( "okn" );

	Com_DPrintf("...setting DSSCL_PRIORITY coop level: " );

	if ( DS_OK != pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_PRIORITY ) )	{
		Com_Printf ("failedn");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	Com_DPrintf("okn" );


	// create the secondary buffer we'll actually work with
	dma.channels = 2;
	dma.samplebits = 16;

	if (s_khz->integer == 44)
		dma.speed = 44100;
	else if (s_khz->integer == 22)
		dma.speed = 22050;
	else
		dma.speed = 11025;

	memset (&format, 0, sizeof(format));
	format.wFormatTag = WAVE_FORMAT_PCM;
    format.nChannels = dma.channels;
    format.wBitsPerSample = dma.samplebits;
    format.nSamplesPerSec = dma.speed;
    format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
    format.cbSize = 0;
    format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; 

	memset (&dsbuf, 0, sizeof(dsbuf));
	dsbuf.dwSize = sizeof(DSBUFFERDESC);

	// Micah: take advantage of 2D hardware.if available.
	dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCHARDWARE;
	if (use8) {
		dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
	}
//#define idDSBCAPS_GETCURRENTPOSITION2 0x00010000
	dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
	dsbuf.lpwfxFormat = &format;
	
	memset(&dsbcaps, 0, sizeof(dsbcaps));
	dsbcaps.dwSize = sizeof(dsbcaps);
	
	Com_DPrintf( "...creating secondary buffer: " );
	if (DS_OK == pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) {
		Com_Printf( "locked hardware.  okn" );
	}
	else {
		// Couldn't get hardware, fallback to software.
		dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE;
		if (use8) {
			dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
		}
		if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) {
			Com_Printf( "failedn" );
			SNDDMA_Shutdown ();
			return qfalse;
		}
		Com_DPrintf( "forced to software.  okn" );
	}
		
	// Make sure mixer is active
	if ( DS_OK != pDSBuf->Play(0, 0, DSBPLAY_LOOPING) ) {
		Com_Printf ("*** Looped sound play failed ***n");
		SNDDMA_Shutdown ();
		return qfalse;
	}

	// get the returned buffer size
	if ( DS_OK != pDSBuf->GetCaps (&dsbcaps) ) {
		Com_Printf ("*** GetCaps failed ***n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	
	gSndBufSize = dsbcaps.dwBufferBytes;

	dma.channels = format.nChannels;
	dma.samplebits = format.wBitsPerSample;
	dma.speed = format.nSamplesPerSec;
	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.submission_chunk = 1;
	dma.buffer = NULL;			// must be locked first

	sample16 = (dma.samplebits/8) - 1;

	SNDDMA_BeginPainting ();
	if (dma.buffer)
		memset(dma.buffer, 0, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();
	return 1;
}
internal void
Win32InitDSound(HWND Window, int32 BufferSize, int32 SamplesPerSecond) {
   //Load library, get directsound object, create primary buffer, create secondary buffer
   // start playing!

   HMODULE DSoundLibrary = LoadLibraryA("dsound.dll");

   if (DSoundLibrary) {
      direct_sound_create *DirectSoundCreate = (direct_sound_create *)
         GetProcAddress(DSoundLibrary, "DirectSoundCreate");

      LPDIRECTSOUND DirectSound;
      if (DirectSoundCreate && SUCCEEDED(DirectSoundCreate(0, &DirectSound, 0))) {

         WAVEFORMATEX WaveFormat = {};
         WaveFormat.wFormatTag = WAVE_FORMAT_PCM;
         WaveFormat.nChannels = 2;
         WaveFormat.wBitsPerSample = 16;
         WaveFormat.nBlockAlign = (WaveFormat.nChannels * WaveFormat.wBitsPerSample) / 8;
         WaveFormat.nSamplesPerSec = SamplesPerSecond;
         WaveFormat.nAvgBytesPerSec = WaveFormat.nSamplesPerSec * WaveFormat.nBlockAlign;
         WaveFormat.cbSize = 0;

         if (SUCCEEDED(DirectSound->SetCooperativeLevel(Window, DSSCL_PRIORITY))) {

            DSBUFFERDESC BufferDescription = {};
            BufferDescription.dwBufferBytes = sizeof(BufferDescription);
            BufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER;

            LPDIRECTSOUNDBUFFER PrimaryBuffer;
            if (SUCCEEDED(DirectSound->CreateSoundBuffer(&BufferDescription, &PrimaryBuffer, 0))) {

               if (SUCCEEDED(PrimaryBuffer->SetFormat(&WaveFormat))) {

               }
               else {
                  //Log!
               }
            }
            else {
               //Log!
            }
         }
         else {
            //Log this!
         }

         DSBUFFERDESC BufferDescription = {};
         BufferDescription.dwSize = sizeof(BufferDescription);
         BufferDescription.dwFlags = 0;
         BufferDescription.dwBufferBytes = BufferSize;
         BufferDescription.lpwfxFormat = &WaveFormat;

         if (SUCCEEDED(DirectSound->CreateSoundBuffer(&BufferDescription, &GlobalSecondaryBuffer, 0))) {
         
         }
         else {
            //Log!
         }
      }
      else {
         //log error
      }
   }
   else {

   }
}
internal void InitializeSound(HWND window, int32 bufferSize, int32 samplesPerSecond)
{
	// First load the library
	HMODULE library = LoadLibraryA("dsound.dll");

	if(library)
	{
		// Get a directSound object.
		direct_sound_create *directSoundCreate = (direct_sound_create *)GetProcAddress(library, "DirectSoundCreate");
		LPDIRECTSOUND directSound;
		if(directSoundCreate && SUCCEEDED(directSoundCreate(0, &directSound, 0)))
		{
			WAVEFORMATEX waveformat;
			waveformat.wFormatTag = WAVE_FORMAT_PCM;
			waveformat.nChannels = 2;
			waveformat.nSamplesPerSec = samplesPerSecond;
			waveformat.wBitsPerSample = 16;
			waveformat.nBlockAlign = waveformat.nChannels * waveformat.wBitsPerSample / 8;
			waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign;
			waveformat.cbSize = 0;

			if(SUCCEEDED(directSound->SetCooperativeLevel(window, DSSCL_PRIORITY)))
			{

				DSBUFFERDESC bufferDescription = {};
				bufferDescription.dwSize = sizeof(bufferDescription);
				bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER;
				bufferDescription.dwBufferBytes = 0;
				// Responsible for creating a handle to the sound card and configures the sound card using the wave format we defined above.
				// TODO: Is this even necessary now?
				LPDIRECTSOUNDBUFFER primaryBuffer;
				if(SUCCEEDED(directSound->CreateSoundBuffer(&bufferDescription, &primaryBuffer, 0)))
				{
					if(SUCCEEDED(primaryBuffer->SetFormat(&waveformat)))
					{
						OutputDebugStringA("Primary buffer set/n");
					};
				}
			}
			else{
				// TODO: log diagnostic
			}

			DSBUFFERDESC bufferDescription = {};
			bufferDescription.dwSize = sizeof(bufferDescription);
			bufferDescription.dwFlags = 0;
			bufferDescription.dwBufferBytes = bufferSize;
			bufferDescription.lpwfxFormat = &waveformat;


			if(SUCCEEDED(directSound->CreateSoundBuffer(&bufferDescription, &audioBuffer, 0)))
			{
				OutputDebugStringA("Secondary buffer created/n");
			}
		}
		else{
			// TODO: Log direct sound not loaded.
		}
		// Create a primary buffer

		// Create a secondary buffer which is what we will actually write to

		// Start playing
	}
}
/*
===============
idAudioHardwareWIN32::SetPrimaryBufferFormat
Set primary buffer to a specified format
For example, to set the primary buffer format to 22kHz stereo, 16-bit
then:   dwPrimaryChannels = 2
        dwPrimaryFreq     = 22050,
        dwPrimaryBitRate  = 16
===============
*/
void idAudioHardwareWIN32::SetPrimaryBufferFormat(dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers)
{
	HRESULT             hr;

	if (m_pDS == NULL) {
		return;
	}

	ulong cfgSpeakers;
	m_pDS->GetSpeakerConfig(&cfgSpeakers);

	DSCAPS dscaps;
	dscaps.dwSize = sizeof(DSCAPS);
	m_pDS->GetCaps(&dscaps);

	if (dscaps.dwFlags & DSCAPS_EMULDRIVER) {
		return;
	}

	// Get the primary buffer
	DSBUFFERDESC dsbd;
	ZeroMemory(&dsbd, sizeof(DSBUFFERDESC));
	dsbd.dwSize        = sizeof(DSBUFFERDESC);
	dsbd.dwFlags       = DSBCAPS_PRIMARYBUFFER;
	dsbd.dwBufferBytes = 0;
	dsbd.lpwfxFormat   = NULL;

	// Obtain write-primary cooperative level.
	if (FAILED(hr = m_pDS->SetCooperativeLevel(win32.hWnd, DSSCL_PRIORITY))) {
		DXTRACE_ERR(TEXT("SetPrimaryBufferFormat"), hr);
		return;
	}

	if (FAILED(hr = m_pDS->CreateSoundBuffer(&dsbd, &pDSBPrimary, NULL))) {
		return;
	}

	if (dwSpeakers == 6 && (cfgSpeakers == DSSPEAKER_5POINT1 || cfgSpeakers == DSSPEAKER_SURROUND)) {
		WAVEFORMATEXTENSIBLE 	waveFormatPCMEx;
		ZeroMemory(&waveFormatPCMEx, sizeof(WAVEFORMATEXTENSIBLE));

		waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
		waveFormatPCMEx.Format.nChannels = 6;
		waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq;
		waveFormatPCMEx.Format.wBitsPerSample  = (WORD) dwPrimaryBitRate;
		waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels;
		waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign;
		waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
		// SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT |
		// SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY |
		// SPEAKER_BACK_LEFT  | SPEAKER_BACK_RIGHT
		waveFormatPCMEx.SubFormat =  KSDATAFORMAT_SUBTYPE_PCM;  // Specify PCM
		waveFormatPCMEx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE);
		waveFormatPCMEx.Samples.wValidBitsPerSample = 16;

		if (FAILED(hr = pDSBPrimary->SetFormat((WAVEFORMATEX *)&waveFormatPCMEx))) {
			DXTRACE_ERR(TEXT("SetPrimaryBufferFormat"), hr);
			return;
		}

		numSpeakers = 6;		// force it to think 5.1
		blockAlign = waveFormatPCMEx.Format.nBlockAlign;
	} else {
		if (dwSpeakers == 6) {
			common->Printf("sound: hardware reported unable to use multisound, defaulted to stereon");
		}

		WAVEFORMATEX wfx;
		ZeroMemory(&wfx, sizeof(WAVEFORMATEX));
		wfx.wFormatTag      = WAVE_FORMAT_PCM;
		wfx.nChannels       = 2;
		wfx.nSamplesPerSec  = dwPrimaryFreq;
		wfx.wBitsPerSample  = (WORD) dwPrimaryBitRate;
		wfx.nBlockAlign     = wfx.wBitsPerSample / 8 * wfx.nChannels;
		wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
		wfx.cbSize = sizeof(WAVEFORMATEX);

		if (FAILED(hr = pDSBPrimary->SetFormat(&wfx))) {
			return;
		}

		numSpeakers = 2;		// force it to think stereo
		blockAlign = wfx.nBlockAlign;
	}

	byte *speakerData;
	bufferSize = MIXBUFFER_SAMPLES * sizeof(word) * numSpeakers * ROOM_SLICES_IN_BUFFER;
	speakerData = (byte *)Mem_Alloc(bufferSize);
	memset(speakerData, 0, bufferSize);

	InitializeSpeakers(speakerData, bufferSize, dwPrimaryFreq, dwPrimaryBitRate, numSpeakers);
}

flat assembler
Message board for the users of flat assembler.

ManOfSteel

Joined: 02 Feb 2005
Posts: 1154

ManOfSteel 06 May 2007, 10:01

Hello,

After reading Farrier’s DirectSound recording utility, I tried to make a program that will play a small wave file.

ds                DirectSound
dsb              DirectSoundBuffer
dsbd               DSBUFFERDESC
WaveFormatEx    WAVEFORMATEX

...

         invoke  DirectSoundCreate,
                        0,
                        ds,
                       0

               cominvk ds,
                       SetCooperativeLevel,
                      [hwnd],
                   DSSCL_NORMAL

            mov     [WaveFormatEx.wFormatTag],WAVE_FORMAT_PCM
           mov     [WaveFormatEx.nChannels],2
          mov     [WaveFormatEx.nSamplesPerSec],44100
         mov     [WaveFormatEx.nAvgBytesPerSec],176400
               mov     [WaveFormatEx.nBlockAlign],4
                mov     [WaveFormatEx.wBitsPerSample],16
            mov     [WaveFormatEx.cbSize],0

         mov     [dsbd.dwSize],sizeof.DSBUFFERDESC
           mov     [dsbd.dwFlags],DSBCAPS_GLOBALFOCUS or DSBCAPS_CTRLPOSITIONNOTIFY
            mov     [dsbd.dwBufferBytes],176400
         mov     [dsbd.lpwfxFormat],WaveFormatEx
             cominvk ds,
                       CreateSoundBuffer,
                        dsbd,
                     dsb,
                      0
           cmp     eax,DS_OK
           jne     Error
    

CreateSoundBuffer doesn’t seem to be working: the code jumps to «Error» right after the call.

What am I doing wrong?

Thanks in advance.

Post
06 May 2007, 10:01

farrier

Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi

farrier 06 May 2007, 15:29

ManOfSteel,

As vid would say: «Always check the return value of any Windows function»!

What were the return values for the DirectSoundCreate and SetCooperativeLevel calls? That may give you your answer.

Also, what is the return value from the CreateSoundBuffer call?

hth,

farrier

_________________
Some Assembly Required

It’s a good day to code!

U.S.Constitution; Bill of Rights; Amendment 1:

… the right of the people peaceably to assemble, …

The code is dark, and full of errors!

Post
06 May 2007, 15:29

madmatt

Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA

madmatt 07 May 2007, 09:58

Everything looks good, except for:

1. should zero out ‘dsbd’ and ‘WaveFormatEx’ structures before using.

2. I use these flags for the buffer desc: DSBCAPS_STATIC or DSBCAPS_LOCSOFTWARE or DSBCAPS_CTRLFREQUENCY or DSBCAPS_CTRLPAN or DSBCAPS_CTRLVOLUME.

3. And as farrier quoted, Check ALL return values for errors. This helps in debugging also.

Post
07 May 2007, 09:58

ManOfSteel

Joined: 02 Feb 2005
Posts: 1154

ManOfSteel 07 May 2007, 11:52

Hello Farrier,

As vid would say: «Always check the return value of any Windows function»!

Actually, that’s what I’m doing. I only removed the checks because those two functions are working fine. I always compare the returning eax with 0 (which is DS_OK) after each API.

What were the return values for the DirectSoundCreate and SetCooperativeLevel calls? That may give you your answer.

I’m getting 0 on both of them, so I guess CreateSoundBuffer must be the faulty one.

Also, what is the return value from the CreateSoundBuffer call?

2147942487 in decimal, which is … DSERR_INVALIDPARAM.

Is it necessary to do a QueryInterface before CreateSoundBuffer? Could it be that?

By the way, I read somewhere DirectSound can’t play other than 22KHZ, 8-Bit, Mono at the NORMAL priority (SetCooperativeLevel,[hwnd],DSSCL_NORMAL). Is it true?

I changed the code to:

mov [WaveFormatEx.nChannels],1            ;mono
mov [WaveFormatEx.nSamplesPerSec],22050   ;22050 sample/s
mov [WaveFormatEx.nAvgBytesPerSec],44100  ;nSamplesPerSec * nBlockAlign
mov [WaveFormatEx.nBlockAlign],2          ;(nChannels * wBitsPerSample) / 8
mov [WaveFormatEx.wBitsPerSample],8       ;8 bits/sample
    

Are these values above (1 for mono, etc) correct?

Anyway, the result is still the same.

madmatt,

Thanks, I’ll check all this later. I must go now. I’ll be back soon.

Post
07 May 2007, 11:52

vid
Verbosity in development

Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia

vid 07 May 2007, 12:02

As vid would say: «Always check the return value of any Windows function»!

Actually, that’s what I’m doing. I only removed the checks because those two functions are working fine. I always compare the returning eax with 0 (which is DS_OK) after each API.

If function worked fine one time on your computer, it doesn’t mean they always will in future and on everyone’s machine.

You really should leave those checks there.

Post
07 May 2007, 12:02

ManOfSteel

Joined: 02 Feb 2005
Posts: 1154

ManOfSteel 07 May 2007, 13:55

madmatt,

I clean both structures with RtlZeroMemory and I also tried the flags you told me about, but it’s still the same.

vid,


If function worked fine one time on your computer, it doesn’t mean they always will in future and on everyone’s machine.

You really should leave those checks there.

Ok, I will.

Post
07 May 2007, 13:55

vid
Verbosity in development

Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia

vid 07 May 2007, 14:32

ManOfSteel:

look at MSDN reference of IDirectSound8::CreateSoundBuffer, and check description of «ppDSBuffer», there is the bug.

I’ll leave rest on you Wink

Post
07 May 2007, 14:32

farrier

Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi

farrier 07 May 2007, 14:37

ManOfSteel,

You can use GetCaps to find out exactly what your sound card is capable of. This will make sure you can use the parameters you have coded.

hth,

farrier

_________________
Some Assembly Required

It’s a good day to code!

U.S.Constitution; Bill of Rights; Amendment 1:

… the right of the people peaceably to assemble, …

The code is dark, and full of errors!

Post
07 May 2007, 14:37

ManOfSteel

Joined: 02 Feb 2005
Posts: 1154

ManOfSteel 08 May 2007, 05:54

vid,

I already read the MSDN. Are you suggesting that I write ppDSBuffer as a dword value in the .data section? Like that:

ppDSBuff dd ?
...
cominvk ds,CreateSoundBuffer,dsbd,ppDSBuff,0
    

Well, I’ve seen some code doing that and I already thought about it, but it doesn’t work any better. It still gives me the same invalid parameter error.

In the DirectSound recording utility I talked about earlier, Farrier did it like me (dsb DirectSoundBuffer) and it worked fine. I’m really confused.

farrier,

You can use GetCaps to find out exactly what your sound card is capable of. This will make sure you can use the parameters you have coded.

I’m using the same flags and settings as you did in your recording/playback utility (from the ‘com_invoke’ macro thread) and this utility is working fine.

Post
08 May 2007, 05:54

farrier

Joined: 26 Aug 2004
Posts: 274
Location: North Central Mississippi

farrier 08 May 2007, 06:46

ManOfSteel,

Just a wild guess:

Try removing the flags: DSBCAPS_GLOBALFOCUS or DSBCAPS_CTRLPOSITIONNOTIFY and try again.

The only other difference I can see is that I have been using the ‘8’ functions, only because they are the ones recommended in the latest SDK. I use DirectSoundCreate8, you use DirectSoundCreate. Other than that, I can’t see why yours is not working.

hth,

farrier

_________________
Some Assembly Required

It’s a good day to code!

U.S.Constitution; Bill of Rights; Amendment 1:

… the right of the people peaceably to assemble, …

The code is dark, and full of errors!

Post
08 May 2007, 06:46

vid
Verbosity in development

Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia

vid 08 May 2007, 09:27

I already read the MSDN. Are you suggesting that I write ppDSBuffer as a dword value in the .data section? Like that:

Yes, that’s how the function must be called.

You don’t pass pointer to structure (LPDIRECTSOUNDBUFFER = DIRECTSOUNDBUFFER *, LP = long pointer). You pass pointer to pointer to structure (LPDIRECTSOUNDBUFFER* = DIRECTSOUNDBUFFER**). In assembly terms, where every pointer is dword, you pass address of dword, which will on return hold address of filled structure.

But naybe you also have some other errors there.

Post
08 May 2007, 09:27

ManOfSteel

Joined: 02 Feb 2005
Posts: 1154

ManOfSteel 09 May 2007, 20:41

If what you say is correct, then I should do the same with DirectSoundCreate. Its second parameter is the «address of a variable to receive an IDirectSound8 interface pointer».

So when I call IDirectSound::SetCooperativeLevel, I will use the pointer that I just got from the first function.

For that I can’t use cominvk anymore. I will have to use comcall, right?

ds       DirectSound
dsbd     DSBUFFERDESC

ppDS     dd ?
ppDSBuff dd ?

invoke   DirectSoundCreate,0,ppDS,0
comcall  [ppDS],ds,SetCooperativeLevel,[hwnd],DSSCL_NORMAL
...
comcall         [ppDS],ds,CreateSoundBuffer,dsbd,ppDSBuff,0
    

The problem is still there: the first two functions still work well, while CreateSoundBuffer doesn’t.

Anyway, the output of both codes is quite the same: the disassembly is almost identical. I think there’s an explanation about the dword pointer in the manual:


You can also use the name of COM interface in the same way as the name of data structure, to define the variable that will hold the handle to object of given type:

ShellTaskBar ITaskBarList

The above line defines the double word variable, in which the handle to COM object can be stored. After storing there the handle to an object, its methods can be called with the cominvk.

Post
09 May 2007, 20:41

vid
Verbosity in development

Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia

vid 09 May 2007, 21:42

sorry, you was right. I forgot that FASM’s «DSBUFFERDESC» is C’s «LPDSBUFFERDESC» etc…

Embarassed

Post
09 May 2007, 21:42
Forum Rules:

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum

Понравилась статья? Поделить с друзьями:
  • Error drm not supported error ivi tcl
  • Error drivers need to be installed for connected device что делать
  • Error drivers need to be installed flashtool
  • Error driver uwp install process failed with error code 740
  • Error driver uwp install process failed with error code 183