source: sbliveos2/trunk/drv16/dwavestrm.cpp@ 200

Last change on this file since 200 was 178, checked in by sandervl, 24 years ago

DirectAudio interface updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.9 KB
Line 
1/* $Id: dwavestrm.cpp 178 2001-04-30 21:08:00Z sandervl $ */
2
3/* SCCSID = %W% %E% */
4/****************************************************************************
5 * *
6 * Copyright (c) IBM Corporation 1994 - 1997. *
7 * *
8 * The following IBM OS/2 source code is provided to you solely for the *
9 * the purpose of assisting you in your development of OS/2 device drivers. *
10 * You may use this code in accordance with the IBM License Agreement *
11 * provided in the IBM Device Driver Source Kit for OS/2. *
12 * *
13 ****************************************************************************/
14/**@internal %W%
15 * @notes
16 * @version %I%
17 * @context Unless otherwise noted, all interfaces are Ring-0, 16-bit,
18 * <stack context>.
19 * @history
20 *
21 */
22#define INCL_NOPMAPI
23#include <os2.h>
24#include <os2me.h>
25#include <audio.h>
26
27#include <devhelp.h>
28#include <include.h>
29
30#include "dwavestrm.hpp"
31#include "memutil.h"
32#include <dbgos2.h>
33#include "ioctl.h"
34#include "malloc.h"
35#include <ossidc.h>
36
37void cdecl HookHandler(ULONG ulSysFileNum)
38{
39 PDWAVESTREAM pStream;
40 PSTREAMBUFFER temp;
41 int rc;
42
43 pStream = (PDWAVESTREAM)FindStream_fromFile(ulSysFileNum);
44 if(pStream == NULL) {
45 dprintf(("HookHandler stream %lx not found!", (ULONG) ulSysFileNum));
46 DebugInt3();
47 return;
48 }
49
50 temp = (PSTREAMBUFFER)pStream->qhReturn.PopHead();
51 while(temp) {
52 if(pStream->hSem) {
53 rc = DevHelp_PostEventSem(pStream->hSem);
54 if(rc != 0) {
55 dprintf(("DevHlp_PostEventSem returned %d", rc));
56 }
57 }
58 DevHelp_VMFree((LIN)temp->pBuffptr);
59 DevHelp_VMUnLock(temp->linLock);
60 delete temp;
61
62 temp = (PSTREAMBUFFER)pStream->qhReturn.PopHead();
63 }
64 return;
65}
66
67
68ULONG DWAVESTREAM::Write(PSTREAMBUF pbuf, ULONG uLength, BOOL fLooping)
69{
70 PSTREAMBUFFER pStreamBuf;
71 LIN linAddr;
72 PULONG pLock;
73 ULONG PageListCount;
74 LIN linLock;
75 int rc;
76
77 pStreamBuf = new STREAMBUFFER(uLength, (PSTREAMBUF)0, fLooping);
78 if(pStreamBuf == NULL) {
79 DebugInt3();
80 return 1;
81 }
82
83 pLock = &pStreamBuf->lock[0];
84
85 rc = DevHelp_VirtToLin(SELECTOROF(pLock), OFFSETOF(pLock), &linLock);
86 if(rc) {
87 DebugInt3();
88 delete pStreamBuf;
89 return rc;
90 }
91
92 rc = DevHelp_VMLock(VMDHL_LONG | VMDHL_WRITE, (LIN)pbuf, uLength, -1L, linLock, (PULONG)&PageListCount);
93 if(rc) {
94 DebugInt3();
95 delete pStreamBuf;
96 return rc;
97 }
98
99 rc = DevHelp_VMProcessToGlobal(VMDHGP_WRITE, (LIN)pbuf, uLength, (PLIN)&linAddr);
100 if(rc) {
101 DebugInt3();
102 DevHelp_VMUnLock(linLock);
103 delete pStreamBuf;
104 return rc;
105 }
106 pStreamBuf->pBuffptr = (PSTREAMBUF)linAddr;
107 pStreamBuf->linLock = linLock;
108
109 return WAVESTREAM::Write((PSTREAMBUFFER)pStreamBuf);
110}
111
112void DWAVESTREAM::ReturnBuffer(void)
113{
114 PSTREAMBUFFER temp = (PSTREAMBUFFER)qhDone.PopHead();
115
116 if(temp)
117 {
118 if(ulStreamState == STREAM_STREAMING) {//means we're called during an interrupt
119 qhReturn.PushOnTail((PQUEUEELEMENT)temp);
120 DevHelp_ArmCtxHook(ulSysFileNum, hCtxHook);
121 }
122 else {
123 DevHelp_VMFree((LIN)temp->pBuffptr);
124 DevHelp_VMUnLock(temp->linLock);
125 delete temp;
126 }
127 }
128}
129
130ULONG DWAVESTREAM::Register(PDDCMDREGISTER pReg)
131{
132 hSem = pReg->hStream;
133
134 if(DevHelp_OpenEventSem(hSem) != 0) {
135 dprintf(("DevHlp_OpenEventSem %lx failed!", hSem));
136 hSem = 0;
137 return 1;
138 }
139 return WAVESTREAM::Register(pReg);
140}
141
142void DWAVESTREAM::DeRegister(void)
143{
144 if(DevHelp_CloseEventSem(hSem) != 0) {
145 dprintf(("DevHlp_CloseEventSemaphore %lx failed!", hSem));
146 return;
147 }
148 hSem = 0;
149 WAVESTREAM::DeRegister();
150}
151
152//
153//
154ULONG DWAVESTREAM::StartStream(void)
155{
156 return WAVESTREAM::StartStream();
157}
158
159
160void DWAVESTREAM::AddBuffers(BOOL fFirst)
161{
162 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhDone.Tail();
163 ULONG space, Buff_left, byteswritten;
164
165 if(!pTemp) pTemp = (PSTREAMBUFFER)qhInProcess.Tail();
166
167 if(ulStreamType & STREAM_WRITE && pTemp && pTemp->looping)
168 {
169 Buff_left = pTemp->ulBuffsz - pTemp->ulBuffpos;
170
171 space = OSS16_StreamGetSpace(this);
172 if(fFirst) {
173 space = min(space, 4*fragsize);
174 }
175 else space = min(space, fragsize);
176
177 if(space) {
178 if(space >= Buff_left) {
179 byteswritten = AddBuffer(Buff_left);
180 if(byteswritten == Buff_left) {
181 pTemp->ulBuffpos = 0; //reset fill position
182 AddBuffer(space - Buff_left);
183 }
184 }
185 else AddBuffer(space);
186 }
187 pTemp->ulDonepos = 0; //make sure it ::Process never thinks it's done
188 }
189 else WAVESTREAM::AddBuffers(fFirst);
190}
191
192BOOL DWAVESTREAM::SetProperty(int type, ULONG value, ULONG reserved)
193{
194 switch(type) {
195 case PROPERTY_LOOPING:
196 {
197 cli();
198 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
199
200 if(!pTemp) pTemp = (PSTREAMBUFFER)qhDone.Head();
201
202 if(pTemp) {
203 pTemp->looping = (BOOL)value;
204 if(pTemp->looping == FALSE) {
205 //calculate current play position
206 pTemp->ulDonepos = (_ulBytesProcessed % pTemp->ulBuffsz);
207 }
208 }
209 sti();
210 }
211 case PROPERTY_FREQUENCY:
212 break;
213
214 default:
215 return WAVESTREAM::SetProperty(type, value, reserved);
216
217 }
218 return TRUE;
219}
220
221ULONG DWAVESTREAM::GetProperty(int type)
222{
223 switch(type) {
224 case PROPERTY_LOOPING:
225 {
226 cli();
227 PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
228 ULONG ret = FALSE;
229
230 if(!pTemp) pTemp = (PSTREAMBUFFER)qhDone.Head();
231
232 if(pTemp) {
233 ret = pTemp->looping;
234 }
235 sti();
236 return ret;
237 }
238
239 default:
240 return WAVESTREAM::GetProperty(type);
241 }
242}
243
244DWAVESTREAM::DWAVESTREAM(ULONG streamtype, LPMCI_AUDIO_INIT pinit, USHORT filesysnum):
245 WAVESTREAM(streamtype, pinit, filesysnum), fError(FALSE), hCtxHook(0), hSem(0)
246{
247 if(DevHelp_AllocateCtxHook((NPFN)HookHandlerAsm, &hCtxHook)) {
248 DebugInt3();
249 fError = TRUE;
250 }
251}
252
253DWAVESTREAM::~DWAVESTREAM()
254{
255 if (ulStreamState == STREAM_STREAMING) {
256 CONTROL_PARM cParm;
257 StopStream(&cParm);
258 }
259 else ReturnBuffers();
260
261 if(hSem) {
262 APIRET rc = DevHelp_PostEventSem(hSem);
263 if(rc != 0) {
264 dprintf(("DevHlp_PostEventSem returned %d", rc));
265 }
266 if(DevHelp_CloseEventSem(hSem) != 0) {
267 dprintf(("DevHlp_CloseEventSemaphore %lx failed!", hSem));
268 }
269 }
270 if(hCtxHook) {
271 DevHelp_FreeCtxHook(hCtxHook);
272 }
273}
274
Note: See TracBrowser for help on using the repository browser.