source: trunk/src/dsound/OS2SNDBUFFER.CPP@ 2912

Last change on this file since 2912 was 2637, checked in by hugh, 26 years ago

some minor dsound fixes

File size: 17.7 KB
Line 
1/* $Id: OS2SNDBUFFER.CPP,v 1.6 2000-02-04 19:29:16 hugh Exp $ */
2
3/*
4 * DirectSound SoundBuffer class
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11
12
13/*@Header***********************************************************************
14* Header Files *
15*******************************************************************************/
16#define INCL_DOSMISC
17#include <os2win.h>
18#include <stdlib.h>
19#include <string.h>
20
21#define INITGUID
22#include <dsound.h>
23
24#include "os2dsound.h"
25#include "os2sndbuffer.h"
26#include <misc.h>
27
28
29extern DWORD GetTickCountOS2();
30
31WAVEFORMATEX wfxDefaultPrimaryBuf = { WAVE_FORMAT_PCM,
32 2,
33 22050,
34 44100,
35 2,
36 8,
37 0};
38
39//******************************************************************************
40//******************************************************************************
41OS2IDirectSoundBuffer::OS2IDirectSoundBuffer(const DSBUFFERDESC *lpDSBufferDesc) //KSO Apr 13 1999: const, SDK changes
42 : Referenced(0), lastError(DS_OK)
43{
44 lpVtbl = &Vtbl;
45 Vtbl.AddRef = SoundBufAddRef;
46 Vtbl.Release = SoundBufRelease;
47 Vtbl.QueryInterface = SoundBufQueryInterface;
48 Vtbl.GetCaps = SoundBufGetCaps;
49 Vtbl.GetFormat = SoundBufGetFormat;
50 Vtbl.GetVolume = SoundBufGetVolume;
51 Vtbl.GetStatus = SoundBufGetStatus;
52 Vtbl.GetCurrentPosition = SoundBufGetCurrentPosition;
53 Vtbl.GetPan = SoundBufGetPan;
54 Vtbl.Initialize = SoundBufInitialize;
55 Vtbl.Restore = SoundBufRestore;
56 Vtbl.SetFormat = SoundBufSetFormat;
57 Vtbl.SetVolume = SoundBufSetVolume;
58 Vtbl.SetCurrentPosition = SoundBufSetCurrentPosition;
59 Vtbl.SetPan = SoundBufSetPan;
60 Vtbl.Lock = SoundBufLock;
61 Vtbl.Unlock = SoundBufUnlock;
62 Vtbl.Stop = SoundBufStop;
63 Vtbl.Play = SoundBufPlay;
64
65 pan = 0;
66 writepos = 0;
67 playpos = 0;
68 frequency = 22050;
69 status = 0;;
70 fLocked = FALSE;
71 volume = 0;
72 lpfxFormat= NULL;
73 lpBuffer = NULL;
74 fPlaying = FALSE;
75 fLoop = FALSE;
76 newWritePos = 0;
77 LastTickCnt = 0;
78 memcpy(&bufferdesc, lpDSBufferDesc, sizeof(DSBUFFERDESC));
79
80 if(bufferdesc.dwFlags & DSBCAPS_PRIMARYBUFFER)
81 {
82 // Primary Buffer
83 // Fake this for now and setup the default values for it
84 //todo: Do the primary buffer right
85 bufferdesc.dwBufferBytes = 4096;
86 bufferdesc.lpwfxFormat = &wfxDefaultPrimaryBuf;
87
88 }
89
90 if(bufferdesc.lpwfxFormat == NULL || bufferdesc.dwBufferBytes == 0)
91 {
92 dprintf(("bufferdesc not valid!"));
93 lastError = DSERR_INVALIDPARAM;
94 return;
95 }
96
97 lpfxFormat = (WAVEFORMATEX *)malloc(bufferdesc.lpwfxFormat->cbSize + sizeof(WAVEFORMATEX));
98 memcpy( lpfxFormat,
99 bufferdesc.lpwfxFormat,
100 bufferdesc.lpwfxFormat->cbSize + sizeof(WAVEFORMATEX));
101
102 bufferdesc.lpwfxFormat = lpfxFormat;
103
104 lpBuffer = (LPSTR)VirtualAlloc( 0, bufferdesc.dwBufferBytes, MEM_COMMIT, PAGE_READWRITE);
105 if(lpBuffer == NULL)
106 {
107 dprintf(("VirtualAlloc failed"));
108 lpBuffer = NULL;
109 lastError = DSERR_OUTOFMEMORY;
110 return;
111 }
112
113}
114//******************************************************************************
115//******************************************************************************
116OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer()
117{
118 if(lpBuffer)
119 VirtualFree(lpBuffer, 0, MEM_RELEASE);
120 if(lpfxFormat)
121 free(lpfxFormat);
122
123}
124//******************************************************************************
125//******************************************************************************
126HRESULT WIN32API SoundBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj)
127{
128 dprintf(("OS2IDirectSoundBuffer::QueryInterface\n"));
129 if(This == NULL)
130 {
131 return DSERR_INVALIDPARAM;
132 }
133 *ppvObj = NULL;
134
135 if(!IsEqualGUID(riid, IID_IDirectSoundBuffer))
136 return E_NOINTERFACE;
137
138 *ppvObj = This;
139
140 SoundBufAddRef(This);
141 return(DS_OK);
142}
143//******************************************************************************
144//******************************************************************************
145ULONG WIN32API SoundBufAddRef(THIS)
146{
147 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
148
149 dprintf(("OS2IDirectSoundBuffer::AddRef %d\n", me->Referenced+1));
150 if(me == NULL)
151 {
152 return 0;
153 }
154 return ++me->Referenced;
155}
156//******************************************************************************
157//******************************************************************************
158ULONG WIN32API SoundBufRelease(THIS)
159{
160 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
161
162 dprintf(("OS2IDirectSoundBuffer::Release %d\n", me->Referenced-1));
163 if(me == NULL)
164 {
165 return 0;
166 }
167 if(me->Referenced)
168 {
169 me->Referenced--;
170 if(me->Referenced == 0)
171 {
172 delete me;
173 return(0);
174 }
175 else
176 return me->Referenced;
177 }
178 else
179 return(0);
180}
181//******************************************************************************
182//******************************************************************************
183HRESULT __stdcall SoundBufGetCaps(THIS_ LPDSBCAPS lpDSCaps)
184{
185 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
186
187 dprintf(("OS2IDirectSoundBuffer::SoundBufGetCaps"));
188 if(me == NULL || lpDSCaps == NULL)
189 {
190 return DSERR_INVALIDPARAM;
191 }
192 return DS_OK;
193}
194//******************************************************************************
195//******************************************************************************
196HRESULT __stdcall SoundBufGetCurrentPosition(THIS_ LPDWORD lpdwCurrentPlayCursor,
197 LPDWORD lpdwCurrentWriteCursor)
198{
199 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
200
201 dprintf(("OS2IDirectSoundBuffer::SoundBufGetCurrentPosition"));
202 if( me == NULL || lpdwCurrentPlayCursor == NULL || lpdwCurrentWriteCursor == NULL)
203 {
204 dprintf((" Invalid parameters %d %d %d",me,lpdwCurrentPlayCursor,lpdwCurrentWriteCursor));
205 return DSERR_INVALIDPARAM;
206 }
207
208 // Simply advance the bufferpointer according to time;
209 if(me->fPlaying)
210 {
211 ULONG CurrentTicks, Ticks, NewPos;
212 CurrentTicks = GetTickCountOS2();
213 Ticks = CurrentTicks-me->LastTickCnt;
214 dprintf((" Is Playing, Ticks: Last %d Current %d Difference %d",me->LastTickCnt, CurrentTicks,Ticks));
215 dprintf((" Frequency: %d Bits per Sample %d",me->frequency,me->lpfxFormat->wBitsPerSample));
216
217 NewPos = ((me->frequency*Ticks)/1000)*(me->lpfxFormat->wBitsPerSample/8);
218 dprintf((" advance pos by %d bytes",NewPos));
219
220 if(NewPos)
221 me->LastTickCnt = CurrentTicks;
222
223 if(me->playpos+NewPos >= me->bufferdesc.dwBufferBytes)
224 {
225 if(me->fLoop)
226 {
227 me->playpos = (me->playpos+NewPos) % me->bufferdesc.dwBufferBytes;
228 }
229 else
230 {
231 me->playpos = me->bufferdesc.dwBufferBytes;
232 me->fPlaying = FALSE;
233 }
234
235 }
236 else
237 {
238 me->playpos += NewPos;
239 }
240 me->writepos = me->playpos + 2048;
241 if(me->writepos >= me->bufferdesc.dwBufferBytes)
242 me->writepos = me->writepos % me->bufferdesc.dwBufferBytes;
243 dprintf((" new Pos Write: %d Play: %d",me->writepos,me->playpos));
244 }
245 else
246 {
247 dprintf((" Buffer Not playing"));
248 }
249 dprintf((" Buffer %d: PlayPos %d, WritePos %d\n",me, me->playpos,me->writepos));
250 *lpdwCurrentPlayCursor = me->playpos;
251 *lpdwCurrentWriteCursor = me->writepos;
252 return DS_OK;
253}
254//******************************************************************************
255//******************************************************************************
256HRESULT __stdcall SoundBufGetFormat(THIS_ LPWAVEFORMATEX lpwfxFormat,
257 DWORD ddwSizeAllocated, LPDWORD lpdwSizeWritten)
258{
259 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
260 int copysize;
261
262 dprintf(("OS2IDirectSoundBuffer::SoundBufGetFormat"));
263 if( me == NULL || lpwfxFormat == NULL || ddwSizeAllocated == 0)
264 {
265 return DSERR_INVALIDPARAM;
266 }
267 copysize = min(ddwSizeAllocated, (me->lpfxFormat->cbSize + sizeof(WAVEFORMATEX)));
268 memcpy(lpwfxFormat, me->lpfxFormat, copysize);
269
270 if(lpdwSizeWritten)
271 {
272 *lpdwSizeWritten = copysize;
273 }
274 return DS_OK;
275}
276//******************************************************************************
277//******************************************************************************
278HRESULT __stdcall SoundBufGetVolume(THIS_ LPLONG lplVolume)
279{
280 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
281
282 dprintf(("OS2IDirectSoundBuffer::SoundBufGetVolume"));
283 if(me == NULL || lplVolume == NULL)
284 {
285 return DSERR_INVALIDPARAM;
286 }
287 *lplVolume = me->volume;
288 return DS_OK;
289}
290//******************************************************************************
291//******************************************************************************
292HRESULT __stdcall SoundBufGetPan(THIS_ LPLONG lplPan)
293{
294 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
295
296 dprintf(("OS2IDirectSoundBuffer::SoundBufGetPan"));
297 if(me == NULL || lplPan == NULL)
298 {
299 return DSERR_INVALIDPARAM;
300 }
301 *lplPan = me->pan;
302 return DS_OK;
303}
304//******************************************************************************
305//******************************************************************************
306HRESULT __stdcall SoundBufGetFrequency(THIS_ LPDWORD lpdwFrequency)
307{
308 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
309
310 dprintf(("OS2IDirectSoundBuffer::SoundBufGetFrequency"));
311 if(me == NULL || lpdwFrequency == NULL)
312 {
313 return DSERR_INVALIDPARAM;
314 }
315 *lpdwFrequency = me->frequency;
316 return DS_OK;
317}
318//******************************************************************************
319//******************************************************************************
320HRESULT __stdcall SoundBufGetStatus(THIS_ LPDWORD lpdwStatus)
321{
322 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
323
324 dprintf(("OS2IDirectSoundBuffer::SoundBufGetStatus"));
325 if(me == NULL || lpdwStatus == NULL)
326 {
327 return DSERR_INVALIDPARAM;
328 }
329 *lpdwStatus = me->status;
330 return DS_OK;
331}
332//******************************************************************************
333//******************************************************************************
334HRESULT __stdcall SoundBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC )
335{
336 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
337
338 dprintf(("SoundBufInitialize"));
339 if(me == NULL)
340 {
341 return DSERR_INVALIDPARAM;
342 }
343 return DSERR_ALREADYINITIALIZED; //todo: for future extensions (dx5/6 ??)
344}
345//******************************************************************************
346//******************************************************************************
347HRESULT __stdcall SoundBufLock(THIS_ DWORD dwWriteCursor, DWORD dwWriteBytes,
348 LPVOID lplpvAudioPtr1, LPDWORD lpdwAudioBytes1,
349 LPVOID lplpvAudioPtr2, LPDWORD lpdwAudioBytes2,
350 DWORD dwFlags)
351{
352 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
353
354 dprintf(("OS2IDirectSoundBuffer::SoundBufLock"));
355 if(me == NULL || !lplpvAudioPtr1 || !lpdwAudioBytes1)
356 {
357 return(DSERR_INVALIDPARAM);
358 }
359 //not sure if this is an error, but it's certainly a smart thing to do (cond. == true)
360 if(dwWriteBytes > me->bufferdesc.dwBufferBytes)
361 {
362 dprintf(("SoundBufLock: dwWriteBytes > me->bufferdesc.dwBufferBytes"));
363 return(DSERR_INVALIDPARAM);
364 }
365 if(dwFlags & DSBLOCK_FROMWRITECURSOR)
366 {
367 dwWriteCursor = me->writepos;
368 }
369 dprintf((" Buffer at 0x%08X Size %d",me->lpBuffer,me->bufferdesc.dwBufferBytes));
370 if(dwWriteCursor + dwWriteBytes > me->bufferdesc.dwBufferBytes )
371 {
372 *(DWORD *)lplpvAudioPtr1 = (DWORD)(me->lpBuffer + dwWriteCursor);
373 *lpdwAudioBytes1 = me->bufferdesc.dwBufferBytes - dwWriteCursor;
374 dprintf((" Lock1 at 0x%08X Size %d",*(DWORD *)lplpvAudioPtr1,*lpdwAudioBytes1));
375 if(lplpvAudioPtr2 && lpdwAudioBytes2)
376 {
377 *(DWORD *)lplpvAudioPtr2 = (DWORD)me->lpBuffer;
378 *lpdwAudioBytes2 = dwWriteBytes - *lpdwAudioBytes1;
379 dprintf((" Lock2 at 0x%08X Size %d",*(DWORD *)lplpvAudioPtr2,*lpdwAudioBytes2));
380 }
381 }
382 else
383 {
384 *(DWORD *)lplpvAudioPtr1 = (DWORD)(me->lpBuffer + dwWriteCursor);
385 *lpdwAudioBytes1 = dwWriteBytes;
386 dprintf((" Lock1 at 0x%08X Size %d",*(DWORD *)lplpvAudioPtr1,*lpdwAudioBytes1));
387 if(lplpvAudioPtr2 && lpdwAudioBytes2)
388 {
389 *(DWORD *)lplpvAudioPtr2 = 0;
390 *lpdwAudioBytes2 = 0;
391 dprintf((" Lock2 at 0x%08X Size %d",*(DWORD *)lplpvAudioPtr2,*lpdwAudioBytes2));
392 }
393 }
394 me->fLocked = TRUE;
395 return DS_OK;
396}
397//******************************************************************************
398//******************************************************************************
399HRESULT __stdcall SoundBufPlay(THIS_ DWORD dwRes1,DWORD dwRes2,DWORD dwFlags)
400{
401 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
402
403 dprintf(("OS2IDirectSoundBuffer::SoundBufPlay"));
404 if(me == NULL)
405 {
406 dprintf((" Invalid parms me is NULL\n"));
407 return DSERR_INVALIDPARAM;
408 }
409 me->fPlaying = TRUE;
410 me->fLoop = dwFlags == DSBPLAY_LOOPING;
411 me->LastTickCnt = GetTickCountOS2();
412 dprintf((" Buffer %d: Start at Tick %d Loop %s",me,me->LastTickCnt,me->fLoop?"YES":"NO"));
413 return DS_OK;
414}
415//******************************************************************************
416//******************************************************************************
417HRESULT __stdcall SoundBufSetCurrentPosition(THIS_ DWORD dwNewPosition)
418{
419 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
420
421 dprintf(("OS2IDirectSoundBuffer::SoundBufSetCurrentPosition"));
422 if(me == NULL)
423 {
424 return DSERR_INVALIDPARAM;
425 }
426 //todo: check for primary buffer (can't do it with those)
427 me->playpos = dwNewPosition;
428 me->writepos = dwNewPosition;
429 return DS_OK;
430}
431//******************************************************************************
432//******************************************************************************
433HRESULT __stdcall SoundBufSetFormat(THIS_ LPWAVEFORMATEX )
434{
435 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
436
437 dprintf(("OS2IDirectSoundBuffer::SoundBufSetFormat"));
438 if(me == NULL)
439 {
440 return DSERR_INVALIDPARAM;
441 }
442 return DS_OK;
443}
444//******************************************************************************
445//******************************************************************************
446HRESULT __stdcall SoundBufSetVolume(THIS_ LONG lVolume)
447{
448 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
449
450 dprintf(("OS2IDirectSoundBuffer::SoundBufSetVolume"));
451 if(me == NULL)
452 {
453 return DSERR_INVALIDPARAM;
454 }
455 me->volume = lVolume;
456 return DS_OK;
457}
458//******************************************************************************
459//******************************************************************************
460HRESULT __stdcall SoundBufSetPan(THIS_ LONG lPan)
461{
462 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
463
464 dprintf(("OS2IDirectSoundBuffer::SoundBufSetPan"));
465 if(me == NULL)
466 {
467 return DSERR_INVALIDPARAM;
468 }
469 me->pan = lPan;
470 return DS_OK;
471}
472//******************************************************************************
473//******************************************************************************
474HRESULT __stdcall SoundBufSetFrequency(THIS_ DWORD dwFrequency)
475{
476 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
477
478 dprintf(("OS2IDirectSoundBuffer::SoundBufSetFrequency"));
479 if(me == NULL)
480 {
481 return DSERR_INVALIDPARAM;
482 }
483 me->frequency = dwFrequency;
484 return DS_OK;
485}
486//******************************************************************************
487//******************************************************************************
488HRESULT __stdcall SoundBufStop(THIS )
489{
490 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
491
492 dprintf(("OS2IDirectSoundBuffer::SoundBufStop"));
493 if(me == NULL)
494 {
495 return DSERR_INVALIDPARAM;
496 }
497 // Simply advance the bufferpointer according to time;
498 if(me->fPlaying)
499 {
500 ULONG CurrentTicks, Ticks, NewPos;
501 CurrentTicks = GetTickCountOS2();
502
503 Ticks = CurrentTicks - me->LastTickCnt;
504 me->LastTickCnt = CurrentTicks;
505
506 NewPos = ((me->frequency*Ticks)/1000)*(me->lpfxFormat->wBitsPerSample>>8);
507 if(me->playpos+NewPos >= me->bufferdesc.dwBufferBytes)
508 {
509 if(me->fLoop)
510 {
511 me->playpos = (me->playpos+NewPos % me->bufferdesc.dwBufferBytes);
512 }
513 else
514 {
515 me->playpos = me->bufferdesc.dwBufferBytes;
516 me->fPlaying = FALSE;
517 }
518
519 }
520 else
521 {
522 me->playpos += NewPos;
523 }
524 me->writepos = me->playpos + 2048;
525 if(me->writepos >= me->bufferdesc.dwBufferBytes)
526 me->writepos = me->writepos % me->bufferdesc.dwBufferBytes;
527
528 me->fPlaying = FALSE;
529
530 }
531 return DS_OK;
532}
533//******************************************************************************
534//******************************************************************************
535HRESULT __stdcall SoundBufUnlock(THIS_ LPVOID,DWORD,LPVOID,DWORD )
536{
537 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
538
539 dprintf(("OS2IDirectSoundBuffer::SoundBufUnlock"));
540 if(me == NULL)
541 {
542 return DSERR_INVALIDPARAM;
543 }
544
545 return DS_OK;
546}
547//******************************************************************************
548//******************************************************************************
549HRESULT __stdcall SoundBufRestore(THIS )
550{
551 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
552
553 dprintf(("OS2IDirectSoundBuffer::SoundBufRestore"));
554 if(me == NULL)
555 {
556 return DSERR_INVALIDPARAM;
557 }
558 return DS_OK;
559}
560//******************************************************************************
561//******************************************************************************
Note: See TracBrowser for help on using the repository browser.