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

Last change on this file since 2013 was 1744, checked in by hugh, 26 years ago

Implemented fake soundcard
The Bufferpos will be advanced based on the elapsed time
since start playing

File size: 17.1 KB
Line 
1/* $Id: OS2SNDBUFFER.CPP,v 1.5 1999-11-14 22:12:15 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 lpBuffer = (LPSTR)VirtualAlloc( 0, bufferdesc.dwBufferBytes, MEM_COMMIT, PAGE_READWRITE);
103 if(lpBuffer == NULL)
104 {
105 dprintf(("VirtualAlloc failed"));
106 lpBuffer = NULL;
107 lastError = DSERR_OUTOFMEMORY;
108 return;
109 }
110}
111//******************************************************************************
112//******************************************************************************
113OS2IDirectSoundBuffer::~OS2IDirectSoundBuffer()
114{
115 if(lpBuffer)
116 VirtualFree(lpBuffer, 0, MEM_RELEASE);
117 if(lpfxFormat)
118 free(lpfxFormat);
119
120}
121//******************************************************************************
122//******************************************************************************
123HRESULT WIN32API SoundBufQueryInterface(THIS, REFIID riid, LPVOID * ppvObj)
124{
125 dprintf(("OS2IDirectSoundBuffer::QueryInterface\n"));
126 if(This == NULL)
127 {
128 return DSERR_INVALIDPARAM;
129 }
130 *ppvObj = NULL;
131
132 if(!IsEqualGUID(riid, IID_IDirectSoundBuffer))
133 return E_NOINTERFACE;
134
135 *ppvObj = This;
136
137 SoundBufAddRef(This);
138 return(DS_OK);
139}
140//******************************************************************************
141//******************************************************************************
142ULONG WIN32API SoundBufAddRef(THIS)
143{
144 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
145
146 dprintf(("OS2IDirectSoundBuffer::AddRef %d\n", me->Referenced+1));
147 if(me == NULL)
148 {
149 return 0;
150 }
151 return ++me->Referenced;
152}
153//******************************************************************************
154//******************************************************************************
155ULONG WIN32API SoundBufRelease(THIS)
156{
157 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
158
159 dprintf(("OS2IDirectSoundBuffer::Release %d\n", me->Referenced-1));
160 if(me == NULL)
161 {
162 return 0;
163 }
164 if(me->Referenced)
165 {
166 me->Referenced--;
167 if(me->Referenced == 0)
168 {
169 delete me;
170 return(0);
171 }
172 else
173 return me->Referenced;
174 }
175 else
176 return(0);
177}
178//******************************************************************************
179//******************************************************************************
180HRESULT __stdcall SoundBufGetCaps(THIS_ LPDSBCAPS lpDSCaps)
181{
182 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
183
184 dprintf(("OS2IDirectSoundBuffer::SoundBufGetCaps"));
185 if(me == NULL || lpDSCaps == NULL)
186 {
187 return DSERR_INVALIDPARAM;
188 }
189 return DS_OK;
190}
191//******************************************************************************
192//******************************************************************************
193HRESULT __stdcall SoundBufGetCurrentPosition(THIS_ LPDWORD lpdwCurrentPlayCursor,
194 LPDWORD lpdwCurrentWriteCursor)
195{
196 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
197
198 dprintf(("OS2IDirectSoundBuffer::SoundBufGetCurrentPosition"));
199 if( me == NULL || lpdwCurrentPlayCursor == NULL || lpdwCurrentWriteCursor == NULL)
200 {
201 dprintf((" Invalid parameters %d %d %d",me,lpdwCurrentPlayCursor,lpdwCurrentWriteCursor));
202 return DSERR_INVALIDPARAM;
203 }
204
205 // Simply advance the bufferpointer according to time;
206 if(me->fPlaying)
207 {
208 ULONG CurrentTicks, Ticks, NewPos;
209 CurrentTicks = GetTickCountOS2();
210 Ticks = CurrentTicks-me->LastTickCnt;
211 dprintf((" Is Playing, Ticks: Last %d Current %d Difference %d",me->LastTickCnt, CurrentTicks,Ticks));
212 me->LastTickCnt = CurrentTicks;
213
214 NewPos = ((me->frequency*Ticks)/1000)*(me->bufferdesc.lpwfxFormat->wBitsPerSample/8);
215 dprintf((" advance pos by %d bytes",NewPos));
216
217 if(me->playpos+NewPos >= me->bufferdesc.dwBufferBytes)
218 {
219 if(me->fLoop)
220 {
221 me->playpos = (me->playpos+NewPos) % me->bufferdesc.dwBufferBytes;
222 }
223 else
224 {
225 me->playpos = me->bufferdesc.dwBufferBytes;
226 me->fPlaying = FALSE;
227 }
228
229 }
230 else
231 {
232 me->playpos += NewPos;
233 }
234 me->writepos = me->playpos + 2048;
235 if(me->writepos >= me->bufferdesc.dwBufferBytes)
236 me->writepos = me->writepos % me->bufferdesc.dwBufferBytes;
237
238 }
239 else
240 {
241 dprintf((" Buffer Not playing"));
242 }
243 dprintf((" Buffer %d: PlayPos %d, WritePos %d\n",me, me->playpos,me->writepos));
244 *lpdwCurrentPlayCursor = me->playpos;
245 *lpdwCurrentWriteCursor = me->writepos;
246 return DS_OK;
247}
248//******************************************************************************
249//******************************************************************************
250HRESULT __stdcall SoundBufGetFormat(THIS_ LPWAVEFORMATEX lpwfxFormat,
251 DWORD ddwSizeAllocated, LPDWORD lpdwSizeWritten)
252{
253 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
254 int copysize;
255
256 dprintf(("OS2IDirectSoundBuffer::SoundBufGetFormat"));
257 if( me == NULL || lpwfxFormat == NULL || ddwSizeAllocated == 0)
258 {
259 return DSERR_INVALIDPARAM;
260 }
261 copysize = min(ddwSizeAllocated, (me->lpfxFormat->cbSize + sizeof(WAVEFORMATEX)));
262 memcpy(lpwfxFormat, me->lpfxFormat, copysize);
263
264 if(lpdwSizeWritten)
265 {
266 *lpdwSizeWritten = copysize;
267 }
268 return DS_OK;
269}
270//******************************************************************************
271//******************************************************************************
272HRESULT __stdcall SoundBufGetVolume(THIS_ LPLONG lplVolume)
273{
274 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
275
276 dprintf(("OS2IDirectSoundBuffer::SoundBufGetVolume"));
277 if(me == NULL || lplVolume == NULL)
278 {
279 return DSERR_INVALIDPARAM;
280 }
281 *lplVolume = me->volume;
282 return DS_OK;
283}
284//******************************************************************************
285//******************************************************************************
286HRESULT __stdcall SoundBufGetPan(THIS_ LPLONG lplPan)
287{
288 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
289
290 dprintf(("OS2IDirectSoundBuffer::SoundBufGetPan"));
291 if(me == NULL || lplPan == NULL)
292 {
293 return DSERR_INVALIDPARAM;
294 }
295 *lplPan = me->pan;
296 return DS_OK;
297}
298//******************************************************************************
299//******************************************************************************
300HRESULT __stdcall SoundBufGetFrequency(THIS_ LPDWORD lpdwFrequency)
301{
302 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
303
304 dprintf(("OS2IDirectSoundBuffer::SoundBufGetFrequency"));
305 if(me == NULL || lpdwFrequency == NULL)
306 {
307 return DSERR_INVALIDPARAM;
308 }
309 *lpdwFrequency = me->frequency;
310 return DS_OK;
311}
312//******************************************************************************
313//******************************************************************************
314HRESULT __stdcall SoundBufGetStatus(THIS_ LPDWORD lpdwStatus)
315{
316 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
317
318 dprintf(("OS2IDirectSoundBuffer::SoundBufGetStatus"));
319 if(me == NULL || lpdwStatus == NULL)
320 {
321 return DSERR_INVALIDPARAM;
322 }
323 *lpdwStatus = me->status;
324 return DS_OK;
325}
326//******************************************************************************
327//******************************************************************************
328HRESULT __stdcall SoundBufInitialize(THIS_ LPDIRECTSOUND, LPDSBUFFERDESC )
329{
330 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
331
332 dprintf(("SoundBufInitialize"));
333 if(me == NULL)
334 {
335 return DSERR_INVALIDPARAM;
336 }
337 return DSERR_ALREADYINITIALIZED; //todo: for future extensions (dx5/6 ??)
338}
339//******************************************************************************
340//******************************************************************************
341HRESULT __stdcall SoundBufLock(THIS_ DWORD dwWriteCursor, DWORD dwWriteBytes,
342 LPVOID lplpvAudioPtr1, LPDWORD lpdwAudioBytes1,
343 LPVOID lplpvAudioPtr2, LPDWORD lpdwAudioBytes2,
344 DWORD dwFlags)
345{
346 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
347
348 dprintf(("OS2IDirectSoundBuffer::SoundBufLock"));
349 if(me == NULL || !lplpvAudioPtr1 || !lpdwAudioBytes1)
350 {
351 return(DSERR_INVALIDPARAM);
352 }
353 //not sure if this is an error, but it's certainly a smart thing to do (cond. == true)
354 if(dwWriteBytes > me->bufferdesc.dwBufferBytes)
355 {
356 dprintf(("SoundBufLock: dwWriteBytes > me->bufferdesc.dwBufferBytes"));
357 return(DSERR_INVALIDPARAM);
358 }
359 if(dwFlags & DSBLOCK_FROMWRITECURSOR)
360 {
361 dwWriteCursor = me->writepos;
362 }
363 if(dwWriteCursor + dwWriteBytes > me->bufferdesc.dwBufferBytes )
364 {
365 *(DWORD *)lplpvAudioPtr1 = (DWORD)(me->lpBuffer + dwWriteCursor);
366 *lpdwAudioBytes1 = me->bufferdesc.dwBufferBytes - dwWriteCursor;
367 if(lplpvAudioPtr2 && lpdwAudioBytes2)
368 {
369 *(DWORD *)lplpvAudioPtr2 = (DWORD)me->lpBuffer;
370 *lpdwAudioBytes2 = dwWriteBytes - *lpdwAudioBytes1;
371 }
372 }
373 else
374 {
375 *(DWORD *)lplpvAudioPtr1 = (DWORD)(me->lpBuffer + dwWriteCursor);
376 *lpdwAudioBytes1 = dwWriteBytes;
377 if(lplpvAudioPtr2 && lpdwAudioBytes2)
378 {
379 *(DWORD *)lplpvAudioPtr2 = 0;
380 *lpdwAudioBytes2 = 0;
381 }
382 }
383 me->fLocked = TRUE;
384 return DS_OK;
385}
386//******************************************************************************
387//******************************************************************************
388HRESULT __stdcall SoundBufPlay(THIS_ DWORD dwRes1,DWORD dwRes2,DWORD dwFlags)
389{
390 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
391
392 dprintf(("OS2IDirectSoundBuffer::SoundBufPlay"));
393 if(me == NULL)
394 {
395 dprintf((" Invalid parms me is NULL\n"));
396 return DSERR_INVALIDPARAM;
397 }
398 me->fPlaying = TRUE;
399 me->fLoop = dwFlags == DSBPLAY_LOOPING;
400 me->LastTickCnt = GetTickCountOS2();
401 dprintf((" Buffer %d: Start at Tick %d Loop %s",me,me->LastTickCnt,me->fLoop?"YES":"NO"));
402 return DS_OK;
403}
404//******************************************************************************
405//******************************************************************************
406HRESULT __stdcall SoundBufSetCurrentPosition(THIS_ DWORD dwNewPosition)
407{
408 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
409
410 dprintf(("OS2IDirectSoundBuffer::SoundBufSetCurrentPosition"));
411 if(me == NULL)
412 {
413 return DSERR_INVALIDPARAM;
414 }
415 //todo: check for primary buffer (can't do it with those)
416 me->playpos = dwNewPosition;
417 me->writepos = dwNewPosition;
418 return DS_OK;
419}
420//******************************************************************************
421//******************************************************************************
422HRESULT __stdcall SoundBufSetFormat(THIS_ LPWAVEFORMATEX )
423{
424 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
425
426 dprintf(("OS2IDirectSoundBuffer::SoundBufSetFormat"));
427 if(me == NULL)
428 {
429 return DSERR_INVALIDPARAM;
430 }
431 return DS_OK;
432}
433//******************************************************************************
434//******************************************************************************
435HRESULT __stdcall SoundBufSetVolume(THIS_ LONG lVolume)
436{
437 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
438
439 dprintf(("OS2IDirectSoundBuffer::SoundBufSetVolume"));
440 if(me == NULL)
441 {
442 return DSERR_INVALIDPARAM;
443 }
444 me->volume = lVolume;
445 return DS_OK;
446}
447//******************************************************************************
448//******************************************************************************
449HRESULT __stdcall SoundBufSetPan(THIS_ LONG lPan)
450{
451 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
452
453 dprintf(("OS2IDirectSoundBuffer::SoundBufSetPan"));
454 if(me == NULL)
455 {
456 return DSERR_INVALIDPARAM;
457 }
458 me->pan = lPan;
459 return DS_OK;
460}
461//******************************************************************************
462//******************************************************************************
463HRESULT __stdcall SoundBufSetFrequency(THIS_ DWORD dwFrequency)
464{
465 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
466
467 dprintf(("OS2IDirectSoundBuffer::SoundBufSetFrequency"));
468 if(me == NULL)
469 {
470 return DSERR_INVALIDPARAM;
471 }
472 me->frequency = dwFrequency;
473 return DS_OK;
474}
475//******************************************************************************
476//******************************************************************************
477HRESULT __stdcall SoundBufStop(THIS )
478{
479 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
480
481 dprintf(("OS2IDirectSoundBuffer::SoundBufStop"));
482 if(me == NULL)
483 {
484 return DSERR_INVALIDPARAM;
485 }
486 // Simply advance the bufferpointer according to time;
487 if(me->fPlaying)
488 {
489 ULONG CurrentTicks, Ticks, NewPos;
490 CurrentTicks = GetTickCountOS2();
491
492 Ticks = CurrentTicks - me->LastTickCnt;
493 me->LastTickCnt = CurrentTicks;
494
495 NewPos = ((me->frequency*Ticks)/1000)*(me->bufferdesc.lpwfxFormat->wBitsPerSample>>8);
496 if(me->playpos+NewPos >= me->bufferdesc.dwBufferBytes)
497 {
498 if(me->fLoop)
499 {
500 me->playpos = (me->playpos+NewPos % me->bufferdesc.dwBufferBytes);
501 }
502 else
503 {
504 me->playpos = me->bufferdesc.dwBufferBytes;
505 me->fPlaying = FALSE;
506 }
507
508 }
509 else
510 {
511 me->playpos += NewPos;
512 }
513 me->writepos = me->playpos + 2048;
514 if(me->writepos >= me->bufferdesc.dwBufferBytes)
515 me->writepos = me->writepos % me->bufferdesc.dwBufferBytes;
516
517 me->fPlaying = FALSE;
518
519 }
520 return DS_OK;
521}
522//******************************************************************************
523//******************************************************************************
524HRESULT __stdcall SoundBufUnlock(THIS_ LPVOID,DWORD,LPVOID,DWORD )
525{
526 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
527
528 dprintf(("OS2IDirectSoundBuffer::SoundBufUnlock"));
529 if(me == NULL)
530 {
531 return DSERR_INVALIDPARAM;
532 }
533 return DS_OK;
534}
535//******************************************************************************
536//******************************************************************************
537HRESULT __stdcall SoundBufRestore(THIS )
538{
539 OS2IDirectSoundBuffer *me = (OS2IDirectSoundBuffer *)This;
540
541 dprintf(("OS2IDirectSoundBuffer::SoundBufRestore"));
542 if(me == NULL)
543 {
544 return DSERR_INVALIDPARAM;
545 }
546 return DS_OK;
547}
548//******************************************************************************
549//******************************************************************************
Note: See TracBrowser for help on using the repository browser.