Use round() instead of ceil() in wodGetPosition(TIME_SMPTE).
[wine] / dlls / winmm / wineoss / mmaux.c
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
2 /*
3  * Sample AUXILARY Wine Driver
4  *
5  * Copyright 1994 Martin Ayotte
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #define EMULATE_SB16
23
24 #include "config.h"
25
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32 #include <fcntl.h>
33 #ifdef HAVE_SYS_IOCTL_H
34 # include <sys/ioctl.h>
35 #endif
36
37 #include "windef.h"
38 #include "winbase.h"
39 #include "mmddk.h"
40 #include "oss.h"
41 #include "wine/debug.h"
42
43 WINE_DEFAULT_DEBUG_CHANNEL(mmaux);
44
45 #ifdef HAVE_OSS
46
47 #define MIXER_DEV "/dev/mixer"
48
49 static int      NumDev = 6;
50
51 /*-----------------------------------------------------------------------*/
52
53 static  int     AUXDRV_Init(void)
54 {
55     int mixer;
56
57     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
58         WARN("mixer device not available !\n");
59         NumDev = 0;
60     } else {
61         close(mixer);
62         NumDev = 6;
63     }
64     return NumDev;
65 }
66
67 /**************************************************************************
68  *                              AUX_GetDevCaps                  [internal]
69  */
70 static DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPSA lpCaps, DWORD dwSize)
71 {
72     int         mixer,volume;
73
74     TRACE("(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
75     if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
76     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
77         WARN("mixer device not available !\n");
78         return MMSYSERR_NOTENABLED;
79     }
80     if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
81         close(mixer);
82         WARN("unable to read mixer !\n");
83         return MMSYSERR_NOTENABLED;
84     }
85     close(mixer);
86 #ifdef EMULATE_SB16
87     lpCaps->wMid = 0x0002;
88     lpCaps->vDriverVersion = 0x0200;
89     lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
90     switch (wDevID) {
91     case 0:
92         lpCaps->wPid = 0x0196;
93         strcpy(lpCaps->szPname, "SB16 Aux: Wave");
94         lpCaps->wTechnology = AUXCAPS_AUXIN;
95         break;
96     case 1:
97         lpCaps->wPid = 0x0197;
98         strcpy(lpCaps->szPname, "SB16 Aux: Midi Synth");
99         lpCaps->wTechnology = AUXCAPS_AUXIN;
100         break;
101     case 2:
102         lpCaps->wPid = 0x0191;
103         strcpy(lpCaps->szPname, "SB16 Aux: CD");
104         lpCaps->wTechnology = AUXCAPS_CDAUDIO;
105         break;
106     case 3:
107         lpCaps->wPid = 0x0192;
108         strcpy(lpCaps->szPname, "SB16 Aux: Line-In");
109         lpCaps->wTechnology = AUXCAPS_AUXIN;
110         break;
111     case 4:
112         lpCaps->wPid = 0x0193;
113         strcpy(lpCaps->szPname, "SB16 Aux: Mic");
114         lpCaps->wTechnology = AUXCAPS_AUXIN;
115         break;
116     case 5:
117         lpCaps->wPid = 0x0194;
118         strcpy(lpCaps->szPname, "SB16 Aux: Master");
119         lpCaps->wTechnology = AUXCAPS_AUXIN;
120         break;
121     }
122 #else
123     lpCaps->wMid = 0xAA;
124     lpCaps->wPid = 0x55;
125     lpCaps->vDriverVersion = 0x0100;
126     strcpy(lpCaps->szPname, "Generic Linux Auxiliary Driver");
127     lpCaps->wTechnology = AUXCAPS_CDAUDIO;
128     lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
129 #endif
130     return MMSYSERR_NOERROR;
131 }
132
133
134 /**************************************************************************
135  *                              AUX_GetVolume                   [internal]
136  */
137 static DWORD AUX_GetVolume(WORD wDevID, LPDWORD lpdwVol)
138 {
139     int         mixer, volume, left, right, cmd;
140
141     TRACE("(%04X, %p);\n", wDevID, lpdwVol);
142     if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
143     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
144         WARN("mixer device not available !\n");
145         return MMSYSERR_NOTENABLED;
146     }
147     switch(wDevID) {
148     case 0:
149         TRACE("SOUND_MIXER_READ_PCM !\n");
150         cmd = SOUND_MIXER_READ_PCM;
151         break;
152     case 1:
153         TRACE("SOUND_MIXER_READ_SYNTH !\n");
154         cmd = SOUND_MIXER_READ_SYNTH;
155         break;
156     case 2:
157         TRACE("SOUND_MIXER_READ_CD !\n");
158         cmd = SOUND_MIXER_READ_CD;
159         break;
160     case 3:
161         TRACE("SOUND_MIXER_READ_LINE !\n");
162         cmd = SOUND_MIXER_READ_LINE;
163         break;
164     case 4:
165         TRACE("SOUND_MIXER_READ_MIC !\n");
166         cmd = SOUND_MIXER_READ_MIC;
167         break;
168     case 5:
169         TRACE("SOUND_MIXER_READ_VOLUME !\n");
170         cmd = SOUND_MIXER_READ_VOLUME;
171         break;
172     default:
173         WARN("invalid device id=%04X !\n", wDevID);
174         return MMSYSERR_NOTENABLED;
175     }
176     if (ioctl(mixer, cmd, &volume) == -1) {
177         WARN("unable to read mixer !\n");
178         return MMSYSERR_NOTENABLED;
179     }
180     close(mixer);
181     left  = LOBYTE(LOWORD(volume));
182     right = HIBYTE(LOWORD(volume));
183     TRACE("left=%d right=%d !\n", left, right);
184     *lpdwVol = MAKELONG((left * 0xFFFFL) / 100, (right * 0xFFFFL) / 100);
185     return MMSYSERR_NOERROR;
186 }
187
188 /**************************************************************************
189  *                              AUX_SetVolume                   [internal]
190  */
191 static DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
192 {
193     int         mixer;
194     int         volume, left, right;
195     int         cmd;
196
197     TRACE("(%04X, %08lX);\n", wDevID, dwParam);
198
199     left   = (LOWORD(dwParam) * 100) >> 16;
200     right  = (HIWORD(dwParam) * 100) >> 16;
201     volume = (right << 8) | left;
202
203     if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
204         WARN("mixer device not available !\n");
205         return MMSYSERR_NOTENABLED;
206     }
207
208     switch(wDevID) {
209     case 0:
210         TRACE("SOUND_MIXER_WRITE_PCM !\n");
211         cmd = SOUND_MIXER_WRITE_PCM;
212         break;
213     case 1:
214         TRACE("SOUND_MIXER_WRITE_SYNTH !\n");
215         cmd = SOUND_MIXER_WRITE_SYNTH;
216         break;
217     case 2:
218         TRACE("SOUND_MIXER_WRITE_CD !\n");
219         cmd = SOUND_MIXER_WRITE_CD;
220         break;
221     case 3:
222         TRACE("SOUND_MIXER_WRITE_LINE !\n");
223         cmd = SOUND_MIXER_WRITE_LINE;
224         break;
225     case 4:
226         TRACE("SOUND_MIXER_WRITE_MIC !\n");
227         cmd = SOUND_MIXER_WRITE_MIC;
228         break;
229     case 5:
230         TRACE("SOUND_MIXER_WRITE_VOLUME !\n");
231         cmd = SOUND_MIXER_WRITE_VOLUME;
232         break;
233     default:
234         WARN("invalid device id=%04X !\n", wDevID);
235         return MMSYSERR_NOTENABLED;
236     }
237     if (ioctl(mixer, cmd, &volume) == -1) {
238         WARN("unable to set mixer !\n");
239         return MMSYSERR_NOTENABLED;
240     }
241     close(mixer);
242     return MMSYSERR_NOERROR;
243 }
244
245 #endif
246
247 /**************************************************************************
248  *              auxMessage (WINEOSS.2)
249  */
250 DWORD WINAPI OSS_auxMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
251                             DWORD dwParam1, DWORD dwParam2)
252 {
253     TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n",
254           wDevID, wMsg, dwUser, dwParam1, dwParam2);
255
256 #ifdef HAVE_OSS
257     switch (wMsg) {
258     case DRVM_INIT:
259         AUXDRV_Init();
260         /* fall through */
261     case DRVM_EXIT:
262     case DRVM_ENABLE:
263     case DRVM_DISABLE:
264         /* FIXME: Pretend this is supported */
265         return 0;
266     case AUXDM_GETDEVCAPS:
267         return AUX_GetDevCaps(wDevID, (LPAUXCAPSA)dwParam1,dwParam2);
268     case AUXDM_GETNUMDEVS:
269         TRACE("return %d;\n", NumDev);
270         return NumDev;
271     case AUXDM_GETVOLUME:
272         return AUX_GetVolume(wDevID, (LPDWORD)dwParam1);
273     case AUXDM_SETVOLUME:
274         return AUX_SetVolume(wDevID, dwParam1);
275     default:
276         WARN("unknown message !\n");
277     }
278     return MMSYSERR_NOTSUPPORTED;
279 #else
280     return MMSYSERR_NOTENABLED;
281 #endif
282 }