source: trunk/src/dsound/waveoutdaud.cpp

Last change on this file was 5643, checked in by sandervl, 24 years ago

DirectAudio interface updates

File size: 9.2 KB
Line 
1/* $Id: waveoutdaud.cpp,v 1.2 2001-04-30 21:06:37 sandervl Exp $ */
2
3/*
4 * Wave playback class (DirectAudio)
5 *
6 * Copyright 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 * Includes *
16 ****************************************************************************/
17
18
19
20#define INCL_BASE
21#define INCL_OS2MM
22#include <os2wrap.h> //Odin32 OS/2 api wrappers
23#include <os2mewrap.h> //Odin32 OS/2 MMPM/2 api wrappers
24#include <stdlib.h>
25#include <string.h>
26#define OS2_ONLY
27#include <win32api.h>
28#include <wprocess.h>
29#include <audio.h>
30#include <daudio.h>
31
32#include "misc.h"
33#include "waveoutdaud.h"
34#include <options.h>
35
36DWORD WIN32API DAudioThreadHandler(LPVOID pUserData);
37
38//TODO: mulaw, alaw & adpcm
39/******************************************************************************/
40/******************************************************************************/
41DAudioWaveOut::DAudioWaveOut(LPWAVEFORMATEX pwfx) :
42 ulError(0), hDAudioDrv(0), fUnderrun(FALSE), State(STATE_STOPPED)
43{
44 APIRET rc;
45 ULONG action;
46 HFILE hDriver;
47 MCI_AUDIO_INIT init = {0};
48 DAUDIO_CMD cmd;
49 ULONG ParmLength = 0, DataLength;
50
51 rc = DosOpen("DAUDIO1$", &hDAudioDrv, &action, 0,
52 FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE |
53 OPEN_SHARE_DENYNONE | OPEN_FLAGS_WRITE_THROUGH,
54 NULL );
55 if(rc) {
56 dprintf(("DosOpen failed with error %d\n", rc));
57 ulError = MMSYSERR_NODRIVER;
58 goto fail;
59 }
60
61 DataLength = sizeof(init);
62
63 init.lSRate = pwfx->nSamplesPerSec;
64 init.lBitsPerSRate = pwfx->wBitsPerSample;
65 init.sChannels = pwfx->nChannels;
66 init.sMode = PCM; //todo!!
67
68 rc = DosDevIOCtl(hDAudioDrv, DAUDIO_IOCTL_CAT, DAUDIO_OPEN, NULL, 0,
69 &ParmLength, &init, DataLength, &DataLength);
70 if(rc) {
71 dprintf(("DosDevIOCtl failed with error %d\n", rc));
72 ulError = MMSYSERR_NODRIVER;
73 goto fail;
74 }
75 if(init.sReturnCode != 0) {
76 dprintf(("init.sReturnCode = %d\n", init.sReturnCode));
77 ulError = MMSYSERR_NODRIVER;
78 goto fail;
79 }
80
81 setVolume(volume);
82
83fail:
84 return;
85}
86/******************************************************************************/
87/******************************************************************************/
88DAudioWaveOut::~DAudioWaveOut()
89{
90 DAUDIO_CMD cmd;
91
92 if(State != STATE_STOPPED) {
93 stop();
94 }
95 if(hDAudioDrv) {
96 sendIOCTL(DAUDIO_CLOSE, &cmd);
97 DosClose(hDAudioDrv);
98 hDAudioDrv = 0;
99 }
100}
101/******************************************************************************/
102/******************************************************************************/
103MMRESULT DAudioWaveOut::write(LPVOID lpBuffer, UINT ulSize)
104{
105 DAUDIO_CMD cmd;
106
107 cmd.Buffer.lpBuffer = (ULONG)lpBuffer;
108 cmd.Buffer.ulBufferLength = ulSize;
109 if(sendIOCTL(DAUDIO_ADDBUFFER, &cmd)) {
110 dprintf(("Unable to add buffer!!!!!"));
111 return MMSYSERR_ERROR;
112 }
113
114 return(MMSYSERR_NOERROR);
115}
116/******************************************************************************/
117/******************************************************************************/
118MMRESULT DAudioWaveOut::pause()
119{
120 DAUDIO_CMD cmd;
121
122 dprintf(("WINMM: DAudioWaveOut::pause"));
123
124 // Pause the playback.
125 sendIOCTL(DAUDIO_PAUSE, &cmd);
126
127 if(State != STATE_PLAYING) {
128 State = STATE_PAUSED;
129 return(MMSYSERR_NOERROR);
130 }
131 State = STATE_PAUSED;
132
133 return(MMSYSERR_NOERROR);
134}
135/******************************************************************************/
136/******************************************************************************/
137MMRESULT DAudioWaveOut::resume()
138{
139 DAUDIO_CMD cmd;
140
141 return sendIOCTL(DAUDIO_RESUME, &cmd);
142}
143/******************************************************************************/
144/******************************************************************************/
145MMRESULT DAudioWaveOut::stop()
146{
147 DAUDIO_CMD cmd;
148 MMRESULT rc;
149
150 dprintf(("DAudioWaveOut::stop %s", (State == STATE_PLAYING) ? "playing" : "stopped"));
151 if(State != STATE_PLAYING)
152 return(MMSYSERR_HANDLEBUSY);
153
154 // Stop the playback.
155 rc = sendIOCTL(DAUDIO_STOP, &cmd);
156
157 State = STATE_STOPPED;
158 fUnderrun = FALSE;
159
160 return rc;
161}
162/******************************************************************************/
163/******************************************************************************/
164MMRESULT DAudioWaveOut::restart()
165{
166 DAUDIO_CMD cmd;
167
168 dprintf(("DAudioWaveOut::restart"));
169 if(State == STATE_PLAYING)
170 return(MMSYSERR_NOERROR);
171
172 State = STATE_PLAYING;
173 fUnderrun = FALSE;
174
175 return sendIOCTL(DAUDIO_START, &cmd);
176}
177/******************************************************************************/
178/******************************************************************************/
179MMRESULT DAudioWaveOut::setProperty(int type, ULONG value)
180{
181 DAUDIO_CMD cmd;
182
183 dprintf(("DAudioWaveOut::setProperty %d %x", type, value));
184
185 cmd.SetProperty.type = type;
186 cmd.SetProperty.value = type;
187 return sendIOCTL(DAUDIO_SETPROPERTY, &cmd);
188}
189/******************************************************************************/
190/******************************************************************************/
191MMRESULT DAudioWaveOut::setVolume(ULONG ulVol)
192{
193 DAUDIO_CMD cmd;
194
195 //Scale down from 0-64k-1 -> 0-100
196 cmd.Vol.VolumeR = (((ulVol & 0xFFFF0000) >> 16)*100)/0xFFFF;
197 cmd.Vol.VolumeL = ((ulVol & 0x0000FFFF) *100)/0xFFFF;
198 return sendIOCTL(DAUDIO_SETVOLUME, &cmd);
199}
200/******************************************************************************/
201/******************************************************************************/
202ULONG DAudioWaveOut::getPosition(PULONG pulWritePos)
203{
204 DAUDIO_CMD cmd;
205 MMRESULT rc;
206
207 rc = sendIOCTL(DAUDIO_GETPOS, &cmd);
208 if(rc) {
209 return 0xFFFFFFFF;
210 }
211 *pulWritePos = cmd.Pos.ulWritePos;
212 return cmd.Pos.ulCurrentPos;
213}
214/******************************************************************************/
215/******************************************************************************/
216BOOL DAudioWaveOut::queryFormat(ULONG formatTag, ULONG nChannels, ULONG nSamplesPerSec, ULONG sampleSize)
217{
218 ULONG ParmLength = 0, DataLength;
219 MCI_AUDIO_INIT init = {0};
220 APIRET rc;
221 ULONG action;
222 HFILE hDriver;
223
224 rc = DosOpen("DAUDIO1$", &hDriver, &action, 0,
225 FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE |
226 OPEN_SHARE_DENYNONE | OPEN_FLAGS_WRITE_THROUGH,
227 NULL );
228 if(rc) {
229 dprintf(("DosOpen failed with error %d\n", rc));
230 return FALSE;
231 }
232
233 DataLength = sizeof(init);
234
235 init.lSRate = nSamplesPerSec;
236 init.lBitsPerSRate = sampleSize;
237 init.sChannels = nChannels;
238 init.sMode = PCM; //TODO: check formattag for ulaw/alaw/adpcm
239 rc = DosDevIOCtl(hDriver, DAUDIO_IOCTL_CAT, DAUDIO_QUERYFORMAT, NULL, 0,
240 &ParmLength, &init, DataLength, &DataLength);
241
242 if(rc) {
243 dprintf(("DosDevIOCtl failed with error %d\n", rc));
244 goto fail;
245 }
246 if(init.sReturnCode != 0) {
247 dprintf(("init.sReturnCode = %d\n", init.sReturnCode));
248 goto fail;
249 }
250
251 DosClose(hDriver);
252 return TRUE;
253
254fail:
255 DosClose(hDriver);
256 return FALSE;
257}
258/******************************************************************************/
259/******************************************************************************/
260BOOL DAudioWaveOut::isDirectAudioAvailable()
261{
262 static BOOL fAvailable = FALSE;
263 static BOOL fTested = FALSE;
264
265 APIRET rc;
266 ULONG action;
267 HFILE hDriver;
268
269
270 if(!fTested) {
271 if(PROFILE_GetOdinIniInt(SECTION_WINMM, KEY_DIRECTAUDIO, 1) == 0) {
272 fTested = TRUE;
273 return FALSE;
274 }
275 rc = DosOpen("DAUDIO1$", &hDriver, &action, 0,
276 FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE |
277 OPEN_SHARE_DENYNONE | OPEN_FLAGS_WRITE_THROUGH,
278 NULL );
279 fTested = TRUE;
280 if(rc) {
281 return FALSE;
282 }
283 DosClose(hDriver);
284 fAvailable = TRUE;
285 }
286 return fAvailable;
287
288}
289/******************************************************************************/
290/******************************************************************************/
291MMRESULT DAudioWaveOut::sendIOCTL(ULONG cmd, DAUDIO_CMD *pDataPacket)
292{
293 ULONG DataLength, ParmLength = 0;
294 APIRET rc;
295
296 DataLength = sizeof(DAUDIO_CMD);
297
298 rc = DosDevIOCtl(hDAudioDrv, DAUDIO_IOCTL_CAT, cmd, NULL, 0,
299 &ParmLength, pDataPacket, DataLength, &DataLength);
300 if(rc) {
301 dprintf(("DosDevIOCtl failed with error %d (command %d)", rc, cmd));
302 return MMSYSERR_ERROR;
303 }
304 return(MMSYSERR_NOERROR);
305
306}
307/******************************************************************************/
308/******************************************************************************/
309
Note: See TracBrowser for help on using the repository browser.