1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Configuration of network devices 4 * FILE: dll/directx/dsound_new/secondary.c 5 * PURPOSE: Secondary IDirectSoundBuffer8 implementation 6 * 7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) 8 */ 9 10 11 #include "precomp.h" 12 13 typedef struct 14 { 15 const IDirectSoundBuffer8Vtbl *lpVtbl; 16 LONG ref; 17 18 LPFILTERINFO Filter; 19 DWORD dwLevel; 20 DWORD dwFlags; 21 DWORD dwFrequency; 22 DWORD BufferPosition; 23 LONG Volume; 24 LONG VolumePan; 25 LPWAVEFORMATEX Format; 26 PUCHAR Buffer; 27 DWORD BufferSize; 28 KSSTATE State; 29 DWORD Flags; 30 DWORD Position; 31 DWORD PlayPosition; 32 33 LPDIRECTSOUNDBUFFER8 PrimaryBuffer; 34 35 36 }CDirectSoundBuffer, *LPCDirectSoundBuffer; 37 38 HRESULT 39 WINAPI 40 SecondaryDirectSoundBuffer8Impl_fnQueryInterface( 41 LPDIRECTSOUNDBUFFER8 iface, 42 IN REFIID riid, 43 LPVOID* ppobj) 44 { 45 LPOLESTR pStr; 46 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 47 48 if (IsEqualIID(riid, &IID_IUnknown) || 49 IsEqualIID(riid, &IID_IDirectSoundBuffer) || 50 IsEqualIID(riid, &IID_IDirectSoundBuffer8)) 51 { 52 *ppobj = (LPVOID)&This->lpVtbl; 53 InterlockedIncrement(&This->ref); 54 return S_OK; 55 } 56 57 if (SUCCEEDED(StringFromIID(riid, &pStr))) 58 { 59 DPRINT("No Interface for class %s\n", pStr); 60 CoTaskMemFree(pStr); 61 } 62 return E_NOINTERFACE; 63 } 64 65 ULONG 66 WINAPI 67 SecondaryDirectSoundBuffer8Impl_fnAddRef( 68 LPDIRECTSOUNDBUFFER8 iface) 69 { 70 ULONG ref; 71 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 72 73 ref = InterlockedIncrement(&This->ref); 74 75 return ref; 76 77 } 78 79 ULONG 80 WINAPI 81 SecondaryDirectSoundBuffer8Impl_fnRelease( 82 LPDIRECTSOUNDBUFFER8 iface) 83 { 84 ULONG ref; 85 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 86 87 ref = InterlockedDecrement(&(This->ref)); 88 89 if (!ref) 90 { 91 HeapFree(GetProcessHeap(), 0, This->Buffer); 92 HeapFree(GetProcessHeap(), 0, This->Format); 93 HeapFree(GetProcessHeap(), 0, This); 94 } 95 96 return ref; 97 } 98 99 HRESULT 100 WINAPI 101 SecondaryDirectSoundBuffer8Impl_fnGetCaps( 102 LPDIRECTSOUNDBUFFER8 iface, 103 LPDSBCAPS pDSBufferCaps) 104 { 105 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 106 107 if (!pDSBufferCaps) 108 { 109 /* invalid parameter */ 110 return DSERR_INVALIDPARAM; 111 } 112 113 if (pDSBufferCaps->dwSize < sizeof(DSBCAPS)) 114 { 115 /* invalid buffer size */ 116 return DSERR_INVALIDPARAM; 117 } 118 119 /* get buffer details */ 120 pDSBufferCaps->dwUnlockTransferRate = 0; 121 pDSBufferCaps->dwPlayCpuOverhead = 0; 122 pDSBufferCaps->dwSize = This->BufferSize; 123 pDSBufferCaps->dwFlags = This->dwFlags; 124 125 return DS_OK; 126 } 127 128 HRESULT 129 WINAPI 130 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition( 131 LPDIRECTSOUNDBUFFER8 iface, 132 LPDWORD pdwCurrentPlayCursor, 133 LPDWORD pdwCurrentWriteCursor) 134 { 135 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 136 137 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition This %p Play %p Write %p\n", This, pdwCurrentPlayCursor, pdwCurrentWriteCursor); 138 139 if (pdwCurrentWriteCursor) 140 { 141 *pdwCurrentWriteCursor = This->BufferPosition; 142 } 143 144 return PrimaryDirectSoundBuffer_GetPosition(This->PrimaryBuffer, pdwCurrentPlayCursor, NULL); 145 } 146 147 HRESULT 148 WINAPI 149 SecondaryDirectSoundBuffer8Impl_fnGetFormat( 150 LPDIRECTSOUNDBUFFER8 iface, 151 LPWAVEFORMATEX pwfxFormat, 152 DWORD dwSizeAllocated, 153 LPDWORD pdwSizeWritten) 154 { 155 DWORD FormatSize; 156 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 157 158 FormatSize = sizeof(WAVEFORMATEX) + This->Format->cbSize; 159 160 if (!pwfxFormat && !pdwSizeWritten) 161 { 162 /* invalid parameter */ 163 return DSERR_INVALIDPARAM; 164 } 165 166 if (!pwfxFormat) 167 { 168 /* return required format size */ 169 *pdwSizeWritten = FormatSize; 170 return DS_OK; 171 } 172 else 173 { 174 if (dwSizeAllocated >= FormatSize) 175 { 176 /* copy format */ 177 CopyMemory(pwfxFormat, This->Format, FormatSize); 178 179 if (pdwSizeWritten) 180 *pdwSizeWritten = FormatSize; 181 182 return DS_OK; 183 } 184 /* buffer too small */ 185 if (pdwSizeWritten) 186 *pdwSizeWritten = 0; 187 188 return DSERR_INVALIDPARAM; 189 } 190 } 191 192 HRESULT 193 WINAPI 194 SecondaryDirectSoundBuffer8Impl_fnGetVolume( 195 LPDIRECTSOUNDBUFFER8 iface, 196 LPLONG plVolume) 197 { 198 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 199 200 if (!plVolume) 201 { 202 /* invalid parameter */ 203 return DSERR_INVALIDPARAM; 204 } 205 206 /* get volume */ 207 *plVolume = This->Volume; 208 209 return DS_OK; 210 } 211 212 HRESULT 213 WINAPI 214 SecondaryDirectSoundBuffer8Impl_fnGetPan( 215 LPDIRECTSOUNDBUFFER8 iface, 216 LPLONG plPan) 217 { 218 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 219 220 if (!plPan) 221 { 222 /* invalid parameter */ 223 return DSERR_INVALIDPARAM; 224 } 225 226 /* get frequency */ 227 *plPan = This->VolumePan; 228 229 return DS_OK; 230 } 231 232 HRESULT 233 WINAPI 234 SecondaryDirectSoundBuffer8Impl_fnGetFrequency( 235 LPDIRECTSOUNDBUFFER8 iface, 236 LPDWORD pdwFrequency) 237 { 238 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 239 240 if (!pdwFrequency) 241 { 242 /* invalid parameter */ 243 return DSERR_INVALIDPARAM; 244 } 245 246 /* get frequency */ 247 *pdwFrequency = This->dwFrequency; 248 249 return DS_OK; 250 } 251 252 HRESULT 253 WINAPI 254 SecondaryDirectSoundBuffer8Impl_fnGetStatus( 255 LPDIRECTSOUNDBUFFER8 iface, 256 LPDWORD pdwStatus) 257 { 258 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 259 260 if (!pdwStatus) 261 { 262 /* invalid parameter */ 263 return DSERR_INVALIDPARAM; 264 } 265 266 *pdwStatus = 0; 267 if (This->State == KSSTATE_RUN || This->State == KSSTATE_ACQUIRE) 268 { 269 /* buffer is playing */ 270 *pdwStatus |= DSBSTATUS_PLAYING; 271 if (This->Flags & DSBPLAY_LOOPING) 272 *pdwStatus |= DSBSTATUS_LOOPING; 273 } 274 275 return DS_OK; 276 } 277 278 HRESULT 279 WINAPI 280 SecondaryDirectSoundBuffer8Impl_fnInitialize( 281 LPDIRECTSOUNDBUFFER8 iface, 282 LPDIRECTSOUND pDirectSound, 283 LPCDSBUFFERDESC pcDSBufferDesc) 284 { 285 /* RTFM */ 286 return DSERR_ALREADYINITIALIZED; 287 } 288 289 HRESULT 290 WINAPI 291 SecondaryDirectSoundBuffer8Impl_fnLock( 292 LPDIRECTSOUNDBUFFER8 iface, 293 DWORD dwOffset, 294 DWORD dwBytes, 295 LPVOID *ppvAudioPtr1, 296 LPDWORD pdwAudioBytes1, 297 LPVOID *ppvAudioPtr2, 298 LPDWORD pdwAudioBytes2, 299 DWORD dwFlags) 300 { 301 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 302 303 DPRINT("This %p dwOffset %u dwBytes %u ppvAudioPtr1 %p pdwAudioBytes1 %p ppvAudioPtr2 %p pdwAudioBytes2 %p dwFlags %x This->BufferSize %u\n", 304 This, dwOffset, dwBytes, ppvAudioPtr1, pdwAudioBytes1, ppvAudioPtr2, pdwAudioBytes2, dwFlags, This->BufferSize); 305 306 if (dwFlags == DSBLOCK_ENTIREBUFFER) 307 { 308 *ppvAudioPtr1 = (LPVOID)This->Buffer; 309 *pdwAudioBytes1 = This->BufferSize; 310 if (ppvAudioPtr2) 311 *ppvAudioPtr2 = NULL; 312 if (pdwAudioBytes2) 313 *pdwAudioBytes2 = 0; 314 315 return DS_OK; 316 } 317 else if (dwFlags == DSBLOCK_FROMWRITECURSOR) 318 { 319 UNIMPLEMENTED; 320 return DSERR_UNSUPPORTED; 321 } 322 else 323 { 324 ASSERT(dwOffset < This->BufferSize); 325 ASSERT(dwBytes <= This->BufferSize); 326 327 dwBytes = min(This->BufferSize - dwOffset, dwBytes); 328 329 *ppvAudioPtr1 = This->Buffer + dwOffset; 330 *pdwAudioBytes1 = dwBytes; 331 332 This->BufferPosition = dwOffset + dwBytes; 333 334 if (This->BufferPosition == This->BufferSize) 335 This->BufferPosition = 0; 336 337 if (ppvAudioPtr2) 338 *ppvAudioPtr2 = NULL; 339 if (pdwAudioBytes2) 340 *pdwAudioBytes2 = 0; 341 342 return DS_OK; 343 } 344 } 345 346 HRESULT 347 WINAPI 348 SecondaryDirectSoundBuffer8Impl_fnPlay( 349 LPDIRECTSOUNDBUFFER8 iface, 350 DWORD dwReserved1, 351 DWORD dwPriority, 352 DWORD dwFlags) 353 { 354 HRESULT hResult; 355 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 356 357 if (dwReserved1 != 0) 358 { 359 /* must be zero */ 360 return DSERR_INVALIDPARAM; 361 } 362 363 /* sanity check */ 364 ASSERT(dwFlags & DSBPLAY_LOOPING); 365 366 367 if (This->State == KSSTATE_RUN) 368 { 369 /* sound buffer is already playing */ 370 return DS_OK; 371 } 372 373 /* set dataformat */ 374 hResult = PrimaryDirectSoundBuffer_SetFormat(This->PrimaryBuffer, This->Format, TRUE); 375 376 if (!SUCCEEDED(hResult)) 377 { 378 /* failed */ 379 DPRINT1("Failed to set format Tag %u Samples %u Bytes %u nChannels %u\n", This->Format->wFormatTag, This->Format->nSamplesPerSec, This->Format->wBitsPerSample, This->Format->nChannels); 380 return hResult; 381 } 382 383 /* start primary buffer */ 384 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_RUN); 385 /* acquire primary buffer */ 386 PrimaryDirectSoundBuffer_AcquireLock(This->PrimaryBuffer); 387 /* HACK write buffer */ 388 PrimaryDirectSoundBuffer_Write(This->PrimaryBuffer, This->Buffer, This->BufferSize); 389 /* release primary buffer */ 390 PrimaryDirectSoundBuffer_ReleaseLock(This->PrimaryBuffer); 391 392 DPRINT("SetFormatSuccess PrimaryBuffer %p\n", This->PrimaryBuffer); 393 This->State = KSSTATE_RUN; 394 395 return DS_OK; 396 } 397 398 HRESULT 399 WINAPI 400 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition( 401 LPDIRECTSOUNDBUFFER8 iface, 402 DWORD dwNewPosition) 403 { 404 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 405 406 DPRINT("Setting position %u\n", dwNewPosition); 407 This->Position = dwNewPosition; 408 409 return DS_OK; 410 } 411 412 HRESULT 413 WINAPI 414 SecondaryDirectSoundBuffer8Impl_fnSetFormat( 415 LPDIRECTSOUNDBUFFER8 iface, 416 LPCWAVEFORMATEX pcfxFormat) 417 { 418 /* RTFM */ 419 return DSERR_INVALIDCALL; 420 } 421 422 HRESULT 423 WINAPI 424 SecondaryDirectSoundBuffer8Impl_fnSetVolume( 425 LPDIRECTSOUNDBUFFER8 iface, 426 LONG lVolume) 427 { 428 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 429 430 if (lVolume < DSBVOLUME_MIN || lVolume > DSBVOLUME_MAX) 431 { 432 /* invalid parameter */ 433 return DSERR_INVALIDPARAM; 434 } 435 436 437 /* Store volume */ 438 This->Volume = lVolume; 439 440 return DS_OK; 441 } 442 443 HRESULT 444 WINAPI 445 SecondaryDirectSoundBuffer8Impl_fnSetPan( 446 LPDIRECTSOUNDBUFFER8 iface, 447 LONG lPan) 448 { 449 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 450 451 if (lPan < DSBPAN_LEFT || lPan > DSBPAN_RIGHT) 452 { 453 /* invalid parameter */ 454 return DSERR_INVALIDPARAM; 455 } 456 457 /* Store volume pan */ 458 This->VolumePan = lPan; 459 460 return DS_OK; 461 } 462 463 HRESULT 464 WINAPI 465 SecondaryDirectSoundBuffer8Impl_fnSetFrequency( 466 LPDIRECTSOUNDBUFFER8 iface, 467 DWORD dwFrequency) 468 { 469 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 470 471 if (dwFrequency == DSBFREQUENCY_ORIGINAL) 472 { 473 /* restore original frequency */ 474 dwFrequency = This->Format->nSamplesPerSec; 475 } 476 477 if (dwFrequency < DSBFREQUENCY_MIN || dwFrequency > DSBFREQUENCY_MAX) 478 { 479 /* invalid frequency */ 480 return DSERR_INVALIDPARAM; 481 } 482 483 if (dwFrequency != This->dwFrequency) 484 { 485 /* FIXME handle frequency change */ 486 } 487 488 /* store frequency */ 489 This->dwFrequency = dwFrequency; 490 491 return DS_OK; 492 } 493 494 HRESULT 495 WINAPI 496 SecondaryDirectSoundBuffer8Impl_fnStop( 497 LPDIRECTSOUNDBUFFER8 iface) 498 { 499 LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl); 500 501 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_PAUSE); 502 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_ACQUIRE); 503 PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_STOP); 504 505 DPRINT("SecondaryDirectSoundBuffer8Impl_fnStop\n"); 506 507 508 /* set state to stop */ 509 This->State = KSSTATE_STOP; 510 This->BufferPosition = 0; 511 512 return DS_OK; 513 } 514 515 516 HRESULT 517 WINAPI 518 SecondaryDirectSoundBuffer8Impl_fnUnlock( 519 LPDIRECTSOUNDBUFFER8 iface, 520 LPVOID pvAudioPtr1, 521 DWORD dwAudioBytes1, 522 LPVOID pvAudioPtr2, 523 DWORD dwAudioBytes2) 524 { 525 //DPRINT("SecondaryDirectSoundBuffer8Impl_fnUnlock pvAudioPtr1 %p dwAudioBytes1 %u pvAudioPtr2 %p dwAudioBytes2 %u Unimplemented\n"); 526 return DS_OK; 527 } 528 529 530 531 532 HRESULT 533 WINAPI 534 SecondaryDirectSoundBuffer8Impl_fnRestore( 535 LPDIRECTSOUNDBUFFER8 iface) 536 { 537 UNIMPLEMENTED; 538 return DSERR_INVALIDPARAM; 539 } 540 541 542 HRESULT 543 WINAPI 544 SecondaryDirectSoundBuffer8Impl_fnSetFX( 545 LPDIRECTSOUNDBUFFER8 iface, 546 DWORD dwEffectsCount, 547 LPDSEFFECTDESC pDSFXDesc, 548 LPDWORD pdwResultCodes) 549 { 550 UNIMPLEMENTED; 551 return DSERR_INVALIDPARAM; 552 } 553 554 HRESULT 555 WINAPI 556 SecondaryDirectSoundBuffer8Impl_fnAcquireResources( 557 LPDIRECTSOUNDBUFFER8 iface, 558 DWORD dwFlags, 559 DWORD dwEffectsCount, 560 LPDWORD pdwResultCodes) 561 { 562 UNIMPLEMENTED; 563 return DSERR_INVALIDPARAM; 564 } 565 566 HRESULT 567 WINAPI 568 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath( 569 LPDIRECTSOUNDBUFFER8 iface, 570 REFGUID rguidObject, 571 DWORD dwIndex, 572 REFGUID rguidInterface, 573 LPVOID *ppObject) 574 { 575 UNIMPLEMENTED; 576 return DSERR_INVALIDPARAM; 577 } 578 579 static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8 = 580 { 581 /* IUnknown methods */ 582 SecondaryDirectSoundBuffer8Impl_fnQueryInterface, 583 SecondaryDirectSoundBuffer8Impl_fnAddRef, 584 SecondaryDirectSoundBuffer8Impl_fnRelease, 585 /* IDirectSoundBuffer methods */ 586 SecondaryDirectSoundBuffer8Impl_fnGetCaps, 587 SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition, 588 SecondaryDirectSoundBuffer8Impl_fnGetFormat, 589 SecondaryDirectSoundBuffer8Impl_fnGetVolume, 590 SecondaryDirectSoundBuffer8Impl_fnGetPan, 591 SecondaryDirectSoundBuffer8Impl_fnGetFrequency, 592 SecondaryDirectSoundBuffer8Impl_fnGetStatus, 593 SecondaryDirectSoundBuffer8Impl_fnInitialize, 594 SecondaryDirectSoundBuffer8Impl_fnLock, 595 SecondaryDirectSoundBuffer8Impl_fnPlay, 596 SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition, 597 SecondaryDirectSoundBuffer8Impl_fnSetFormat, 598 SecondaryDirectSoundBuffer8Impl_fnSetVolume, 599 SecondaryDirectSoundBuffer8Impl_fnSetPan, 600 SecondaryDirectSoundBuffer8Impl_fnSetFrequency, 601 SecondaryDirectSoundBuffer8Impl_fnStop, 602 SecondaryDirectSoundBuffer8Impl_fnUnlock, 603 SecondaryDirectSoundBuffer8Impl_fnRestore, 604 /* IDirectSoundBuffer8 methods */ 605 SecondaryDirectSoundBuffer8Impl_fnSetFX, 606 SecondaryDirectSoundBuffer8Impl_fnAcquireResources, 607 SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath 608 }; 609 610 HRESULT 611 NewSecondarySoundBuffer( 612 LPDIRECTSOUNDBUFFER8 *OutBuffer, 613 LPFILTERINFO Filter, 614 DWORD dwLevel, 615 LPCDSBUFFERDESC lpcDSBufferDesc, 616 LPDIRECTSOUNDBUFFER8 PrimaryBuffer) 617 { 618 ULONG FormatSize; 619 LPCDirectSoundBuffer This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundBuffer)); 620 621 if (!This) 622 { 623 /* not enough memory */ 624 return DSERR_OUTOFMEMORY; 625 } 626 627 FormatSize = sizeof(WAVEFORMATEX) + lpcDSBufferDesc->lpwfxFormat->cbSize; 628 629 This->Format = HeapAlloc(GetProcessHeap(), 0, FormatSize); 630 if (!This->Format) 631 { 632 /* not enough memory */ 633 HeapFree(GetProcessHeap(), 0, This); 634 return DSERR_OUTOFMEMORY; 635 } 636 637 /* sanity check */ 638 ASSERT(lpcDSBufferDesc->dwBufferBytes); 639 640 /* allocate sound buffer */ 641 This->Buffer = HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc->dwBufferBytes); 642 if (!This->Buffer) 643 { 644 /* not enough memory */ 645 HeapFree(GetProcessHeap(), 0, This->Format); 646 HeapFree(GetProcessHeap(), 0, This); 647 return DSERR_OUTOFMEMORY; 648 } 649 650 /* fill buffer with silence */ 651 FillMemory(This->Buffer, lpcDSBufferDesc->dwBufferBytes, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample == 8 ? 0x80 : 0); 652 653 This->ref = 1; 654 This->lpVtbl = &vt_DirectSoundBuffer8; 655 This->Filter = Filter; 656 This->dwLevel = dwLevel; 657 This->dwFlags = lpcDSBufferDesc->dwFlags; 658 This->dwFrequency = lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec; 659 This->State = KSSTATE_STOP; 660 This->Volume = DSBVOLUME_MAX; 661 This->VolumePan = DSBPAN_CENTER; 662 This->Flags = 0; 663 This->Position = 0; 664 This->BufferSize = lpcDSBufferDesc->dwBufferBytes; 665 This->PrimaryBuffer = PrimaryBuffer; 666 667 CopyMemory(This->Format, lpcDSBufferDesc->lpwfxFormat, FormatSize); 668 669 *OutBuffer = (LPDIRECTSOUNDBUFFER8)&This->lpVtbl; 670 return DS_OK; 671 } 672 673