source: trunk/src/winmm/waveinoutbase.cpp@ 10367

Last change on this file since 10367 was 10269, checked in by sandervl, 22 years ago

Make sure the timer object is not deleted inside the timer callback handler

File size: 5.6 KB
Line 
1/* $Id: waveinoutbase.cpp,v 1.7 2003-10-13 09:18:38 sandervl Exp $ */
2
3/*
4 * Wave playback class (DART)
5 *
6 * Copyright 1998-2001 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 *
12 */
13
14
15/****************************************************************************
16 * Includes *
17 ****************************************************************************/
18
19
20
21#define INCL_BASE
22#define INCL_OS2MM
23#include <os2wrap.h> //Odin32 OS/2 api wrappers
24#include <os2mewrap.h> //Odin32 OS/2 MMPM/2 api wrappers
25#include <stdlib.h>
26#include <string.h>
27#define OS2_ONLY
28#include <win32api.h>
29#include <wprocess.h>
30
31#include "misc.h"
32#include "waveinoutbase.h"
33
34#define DBG_LOCALLOG DBG_waveinoutbase
35#include "dbglocal.h"
36
37VMutex wavemutex;
38
39/******************************************************************************/
40/******************************************************************************/
41WaveInOut::WaveInOut(LPWAVEFORMATEX pwfx, ULONG fdwOpen, ULONG nCallback, ULONG dwInstance)
42{
43 next = NULL;
44 wavehdr = NULL;
45 curhdr = NULL;
46 ulError = 0;
47 State = STATE_STOPPED;
48 queuedbuffers = 0;
49
50 BitsPerSample = pwfx->wBitsPerSample;
51 SampleRate = pwfx->nSamplesPerSec;
52 this->nChannels = pwfx->nChannels;
53
54 dprintf(("WaveInOutOpen: samplerate %d, numChan %d bps %d (%d), format %x", SampleRate, nChannels, BitsPerSample, pwfx->nBlockAlign, pwfx->wFormatTag));
55
56 State = STATE_STOPPED;
57
58 wavemutex.enter();
59
60 if(head == NULL) {
61 head = this;
62 }
63 else {
64 WaveInOut *dwave = head;
65
66 while(dwave->next) {
67 dwave = dwave->next;
68 }
69 dwave->next = this;
70 }
71 wavemutex.leave();
72
73 this->fdwOpen = fdwOpen;
74 dwCallback = nCallback;
75 this->dwInstance = dwInstance;
76}
77/******************************************************************************/
78/******************************************************************************/
79WaveInOut::~WaveInOut()
80{
81 wavemutex.enter();
82
83 State = STATE_STOPPED;
84
85 if(head == this) {
86 head = this->next;
87 }
88 else {
89 WaveInOut *dwave = head;
90
91 while(dwave->next != this) {
92 dwave = dwave->next;
93 }
94 dwave->next = this->next;
95 }
96 wavemutex.leave();
97}
98/******************************************************************************/
99/******************************************************************************/
100void WaveInOut::callback(UINT uMessage, DWORD dw1, DWORD dw2)
101{
102 dprintf(("WINMM:WaveInOut::callback type %x, callback 0x%x (HDRVR h=%08xh, UINT uMessage=%08xh, DWORD dwUser=%08xh, DWORD dw1=%08xh, DWORD dw2=%08xh)",
103 fdwOpen, dwCallback, this, uMessage, dwInstance, dw1, dw2));
104
105 switch(fdwOpen & CALLBACK_TYPEMASK) {
106 case CALLBACK_WINDOW:
107 PostMessageA((HWND)dwCallback, uMessage, (WPARAM)this, dw1);
108 break;
109
110 case CALLBACK_TASK: // == CALLBACK_THREAD
111 PostThreadMessageA(dwCallback, uMessage, (WPARAM)this, dw1);
112 break;
113
114 case CALLBACK_FUNCTION:
115 {
116 USHORT selTIB = GetFS(); // save current FS selector
117 USHORT selCallback;
118 LPDRVCALLBACK mthdCallback = (LPDRVCALLBACK)dwCallback;
119
120 if(selTIB == SELECTOR_OS2_FS) {
121 selCallback = GetProcessTIBSel();
122 }
123 else selCallback = selTIB;
124
125 //TODO: may not be very safe. perhaps we should allocate a new TIB for the DART thread or let another thread do the actual callback
126 if(selCallback)
127 {
128 SetFS(selCallback); // switch to callback win32 tib selector (stored in WaveInOutOpen)
129
130 //@@@PH 1999/12/28 Shockwave Flash seem to make assumptions on a
131 // specific stack layout. Do we have the correct calling convention here?
132 mthdCallback((HDRVR)this, uMessage, dwInstance, dw1, dw2);
133 SetFS(selTIB); // switch back to the saved FS selector
134 }
135 else {
136 dprintf(("WARNING: no valid selector of main thread available (process exiting); skipping WaveInOut notify"));
137 }
138 break;
139 }
140
141 case CALLBACK_EVENT:
142 SetEvent((HANDLE)dwCallback);
143 break;
144
145 case CALLBACK_NULL:
146 break; //no callback
147
148 default:
149 dprintf(("WARNING: Unknown callback type %x %x", fdwOpen, dwCallback));
150 break;
151 } //switch
152 dprintf2(("WINMM:WaveInOut::callback returned"));
153}
154/******************************************************************************/
155//Delete all active wave objects
156/******************************************************************************/
157void WaveInOut::shutdown()
158{
159 dprintf(("WaveInOut::shutdown"));
160 wavemutex.enter();
161 while(head) {
162 delete head;
163 }
164 wavemutex.leave();
165 dprintf(("WaveInOut::shutdown end"));
166}
167/******************************************************************************/
168/******************************************************************************/
169BOOL WaveInOut::find(WaveInOut *dwave)
170{
171 wavemutex.enter();
172
173 WaveInOut *curwave = head;
174
175 while(curwave) {
176 if(dwave == curwave) {
177 wavemutex.leave();
178 return(TRUE);
179 }
180 curwave = curwave->next;
181 }
182 wavemutex.leave();
183
184 dprintf2(("WINMM:WaveInOut not found!\n"));
185 return(FALSE);
186}
187/******************************************************************************/
188/******************************************************************************/
189WaveInOut *WaveInOut::head = NULL;
190
Note: See TracBrowser for help on using the repository browser.