0c299e33971e9bb0fbb7ae5ccadf334cdd0d8b63
[reactos.git] / reactos / lib / drivers / sound / mmebuddy / mmewrap.c
1 /*
2 * PROJECT: ReactOS Sound System "MME Buddy" Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/drivers/sound/mmebuddy/mmewrap.c
5 *
6 * PURPOSE: Interface between MME functions and MME Buddy's own.
7 *
8 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
9 */
10
11 #include <windows.h>
12 #include <mmsystem.h>
13 #include <mmddk.h>
14 #include <ntddsnd.h>
15 #include <mmebuddy.h>
16
17 /*
18 Call the client application when something interesting happens (MME API
19 defines "interesting things" as device open, close, and buffer
20 completion.)
21 */
22 VOID
23 NotifyMmeClient(
24 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
25 IN DWORD Message,
26 IN DWORD Parameter)
27 {
28 SND_ASSERT( SoundDeviceInstance );
29
30 SND_TRACE(L"MME client callback - message %d, parameter %d\n",
31 (int) Message,
32 (int) Parameter);
33
34 if ( SoundDeviceInstance->WinMM.ClientCallback )
35 {
36 DriverCallback(SoundDeviceInstance->WinMM.ClientCallback,
37 HIWORD(SoundDeviceInstance->WinMM.Flags),
38 SoundDeviceInstance->WinMM.Handle,
39 Message,
40 SoundDeviceInstance->WinMM.ClientCallbackInstanceData,
41 Parameter,
42 0);
43 }
44 }
45
46 /*
47 This is a helper function to alleviate some of the repetition involved with
48 implementing the various MME message functions.
49 */
50 MMRESULT
51 MmeGetSoundDeviceCapabilities(
52 IN MMDEVICE_TYPE DeviceType,
53 IN DWORD DeviceId,
54 IN PVOID Capabilities,
55 IN DWORD CapabilitiesSize)
56 {
57 PSOUND_DEVICE SoundDevice;
58 MMRESULT Result;
59
60 SND_TRACE(L"MME *_GETCAPS for device %d of type %d\n", DeviceId, DeviceType);
61
62 /* FIXME: Validate device type and ID */
63 VALIDATE_MMSYS_PARAMETER( Capabilities );
64 VALIDATE_MMSYS_PARAMETER( CapabilitiesSize > 0 );
65
66 /* Our parameter checks are done elsewhere */
67 Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice);
68
69 if ( ! MMSUCCESS(Result) )
70 return Result;
71
72 return GetSoundDeviceCapabilities(SoundDevice,
73 Capabilities,
74 CapabilitiesSize);
75 }
76
77 MMRESULT
78 MmeOpenWaveDevice(
79 IN MMDEVICE_TYPE DeviceType,
80 IN DWORD DeviceId,
81 IN LPWAVEOPENDESC OpenParameters,
82 IN DWORD Flags,
83 OUT DWORD* PrivateHandle)
84 {
85 MMRESULT Result;
86
87 PSOUND_DEVICE SoundDevice;
88 PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
89 LPWAVEFORMATEX Format;
90
91 SND_TRACE(L"Opening wave device (WIDM_OPEN / WODM_OPEN)");
92
93 VALIDATE_MMSYS_PARAMETER( IS_WAVE_DEVICE_TYPE(DeviceType) ); /* FIXME? wave in too? */
94 VALIDATE_MMSYS_PARAMETER( OpenParameters );
95
96 Format = OpenParameters->lpFormat;
97
98 Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice);
99 if ( ! MMSUCCESS(Result) )
100 return TranslateInternalMmResult(Result);
101
102 /* Does this device support the format? */
103 Result = QueryWaveDeviceFormatSupport(SoundDevice, Format, sizeof(WAVEFORMATEX));
104 if ( ! MMSUCCESS(Result) )
105 {
106 SND_ERR(L"Format not supported\n");
107 return TranslateInternalMmResult(Result);
108 }
109
110 /* If the caller just wanted to know if a format is supported, end here */
111 if ( Flags & WAVE_FORMAT_QUERY )
112 return MMSYSERR_NOERROR;
113
114 /* Check that winmm gave us a private handle to fill */
115 VALIDATE_MMSYS_PARAMETER( PrivateHandle );
116
117 /* Create a sound device instance and open the sound device */
118 Result = CreateSoundDeviceInstance(SoundDevice, &SoundDeviceInstance);
119 if ( ! MMSUCCESS(Result) )
120 return TranslateInternalMmResult(Result);
121
122 Result = SetWaveDeviceFormat(SoundDeviceInstance, Format, sizeof(WAVEFORMATEX));
123 if ( ! MMSUCCESS(Result) )
124 {
125 /* TODO: Destroy sound instance */
126 return TranslateInternalMmResult(Result);
127 }
128
129 /* Store the device instance pointer in the private handle - is DWORD safe here? */
130 *PrivateHandle = (DWORD) SoundDeviceInstance;
131
132 /* Store the additional information we were given - FIXME: Need flags! */
133 SetSoundDeviceInstanceMmeData(SoundDeviceInstance,
134 (HDRVR)OpenParameters->hWave,
135 OpenParameters->dwCallback,
136 OpenParameters->dwInstance,
137 Flags);
138
139 /* Let the application know the device is open */
140 ReleaseEntrypointMutex(DeviceType);
141 NotifyMmeClient(SoundDeviceInstance,
142 DeviceType == WAVE_OUT_DEVICE_TYPE ? WOM_OPEN : WIM_OPEN,
143 0);
144
145 AcquireEntrypointMutex(DeviceType);
146
147 SND_TRACE(L"Wave device now open\n");
148
149 return MMSYSERR_NOERROR;
150 }
151
152 MMRESULT
153 MmeCloseDevice(
154 IN DWORD PrivateHandle)
155 {
156 MMRESULT Result;
157 PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
158 PSOUND_DEVICE SoundDevice;
159 MMDEVICE_TYPE DeviceType;
160
161 SND_TRACE(L"Closing wave device (WIDM_CLOSE / WODM_CLOSE)\n");
162
163 VALIDATE_MMSYS_PARAMETER( PrivateHandle );
164 SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle;
165
166 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
167 if ( ! MMSUCCESS(Result) )
168 return TranslateInternalMmResult(Result);
169
170 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
171 if ( ! MMSUCCESS(Result) )
172 return TranslateInternalMmResult(Result);
173
174 ReleaseEntrypointMutex(DeviceType);
175 NotifyMmeClient(SoundDeviceInstance,
176 DeviceType == WAVE_OUT_DEVICE_TYPE ? WOM_CLOSE : WIM_CLOSE,
177 0);
178 AcquireEntrypointMutex(DeviceType);
179
180 Result = DestroySoundDeviceInstance(SoundDeviceInstance);
181
182 return Result;
183 }