source: trunk/src/dsound/waveoutdaud.cpp@ 5608

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

preliminary code for directaudio interface

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