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 |
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.
|
06 May 2007, 10:01 |
farrier Joined: 26 Aug 2004 |
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 _________________
|
06 May 2007, 15:29 |
madmatt Joined: 07 Oct 2003 |
madmatt 07 May 2007, 09:58 Everything looks good, except for:
|
07 May 2007, 09:58 |
ManOfSteel Joined: 02 Feb 2005 |
ManOfSteel 07 May 2007, 11:52 Hello Farrier,
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.
I’m getting 0 on both of them, so I guess CreateSoundBuffer must be the faulty one.
2147942487 in decimal, which is … DSERR_INVALIDPARAM. 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? 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? madmatt,
|
07 May 2007, 11:52 |
vid Joined: 05 Sep 2003 |
vid 07 May 2007, 12:02
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.
|
07 May 2007, 12:02 |
ManOfSteel Joined: 02 Feb 2005 |
ManOfSteel 07 May 2007, 13:55 madmatt, vid,
Ok, I will.
|
07 May 2007, 13:55 |
vid Joined: 05 Sep 2003 |
vid 07 May 2007, 14:32 ManOfSteel: I’ll leave rest on you
|
07 May 2007, 14:32 |
farrier Joined: 26 Aug 2004 |
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 _________________
|
07 May 2007, 14:37 |
ManOfSteel Joined: 02 Feb 2005 |
ManOfSteel 08 May 2007, 05:54 vid, 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,
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.
|
08 May 2007, 05:54 |
farrier Joined: 26 Aug 2004 |
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 _________________
|
08 May 2007, 06:46 |
vid Joined: 05 Sep 2003 |
vid 08 May 2007, 09:27
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.
|
08 May 2007, 09:27 |
ManOfSteel Joined: 02 Feb 2005 |
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:
|
09 May 2007, 20:41 |
vid Joined: 05 Sep 2003 |
vid 09 May 2007, 21:42 sorry, you was right. I forgot that FASM’s «DSBUFFERDESC» is C’s «LPDSBUFFERDESC» etc…
|
09 May 2007, 21:42 |
Forum Rules:
You cannot post new topics in this forum |