ReactOS  0.4.14-dev-98-gb0d4763
midi.c File Reference
#include <stdio.h>
#include <stddef.h>
#include "windows.h"
#include "mmsystem.h"
#include "objbase.h"
#include "wine/test.h"
Include dependency graph for midi.c:

Go to the source code of this file.

Classes

struct  midishortevent_tag
 

Macros

#define _WINE
 
#define MYCBINST   0x4CAFE5A8 /* not used with window or thread callbacks */
 
#define WHATEVER   0xFEEDF00D
 
#define test_notification(hwnd, command, m1, p2)   test_notification_dbg(hwnd, command, m1, p2, __LINE__)
 

Typedefs

typedef struct midishortevent_tag MIDISHORTEVENT
 

Functions

const charmmsys_error (MMRESULT error)
 
static BOOL spurious_message (LPMSG msg)
 
static void CALLBACK callback_func (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
 
static void test_notification_dbg (HWND hwnd, const char *command, UINT m1, DWORD_PTR p2, int line)
 
static void test_midiIn_device (UINT udev, HWND hwnd)
 
static void test_midi_infns (HWND hwnd)
 
static void test_midi_mci (HWND hwnd)
 
static void test_midiOut_device (UINT udev, HWND hwnd)
 
static void test_position (HMIDISTRM hm, UINT typein, UINT typeout)
 
static MMRESULT playStream (HMIDISTRM hm, LPMIDIHDR lpMidiHdr)
 
static void test_midiStream (UINT udev, HWND hwnd)
 
static BOOL scan_subkeys (HKEY parent, const LPCSTR *sub_keys)
 
static BOOL on_vmware (void)
 
static void test_midi_outfns (HWND hwnd)
 
 START_TEST (midi)
 

Variables

static UINT cbmsg = 0
 
static DWORD_PTR cbval1 = WHATEVER
 
static DWORD_PTR cbval2 = 0
 
static DWORD_PTR cbinst = MYCBINST
 
static BYTE strmEvents []
 
static MIDISHORTEVENT strmNops []
 

Macro Definition Documentation

◆ _WINE

#define _WINE

Definition at line 21 of file midi.c.

◆ MYCBINST

#define MYCBINST   0x4CAFE5A8 /* not used with window or thread callbacks */

Definition at line 37 of file midi.c.

◆ test_notification

#define test_notification (   hwnd,
  command,
  m1,
  p2 
)    test_notification_dbg(hwnd, command, m1, p2, __LINE__)

Definition at line 67 of file midi.c.

◆ WHATEVER

#define WHATEVER   0xFEEDF00D

Definition at line 38 of file midi.c.

Typedef Documentation

◆ MIDISHORTEVENT

Function Documentation

◆ callback_func()

static void CALLBACK callback_func ( HWAVEOUT  hwo,
UINT  uMsg,
DWORD_PTR  dwInstance,
DWORD_PTR  dwParam1,
DWORD_PTR  dwParam2 
)
static

Definition at line 55 of file midi.c.

58 {
59  if (winetest_debug>1)
60  trace("Callback! msg=%x %lx %lx\n", uMsg, dwParam1, dwParam2);
61  cbmsg = uMsg;
62  cbval1 = dwParam1; /* mhdr or 0 */
63  cbval2 = dwParam2; /* always 0 */
64  cbinst = dwInstance; /* MYCBINST, see midiOut/StreamOpen */
65 }
static DWORD_PTR cbval2
Definition: midi.c:52
int winetest_debug
static DWORD_PTR cbinst
Definition: midi.c:53
#define trace
Definition: atltest.h:70
static UINT cbmsg
Definition: midi.c:50
static DWORD_PTR cbval1
Definition: midi.c:51

Referenced by test_midiIn_device(), test_midiOut_device(), and test_midiStream().

◆ mmsys_error()

const char* mmsys_error ( MMRESULT  error)

Definition at line 220 of file wave.c.

221 {
222 #define ERR_TO_STR(dev) case dev: return #dev
223  static char unknown[32];
224  switch (error) {
264  }
265  sprintf(unknown, "Unknown(0x%08x)", error);
266  return unknown;
267 #undef ERR_TO_STR
268 }
#define WAVERR_BADFORMAT
Definition: mmsystem.h:176
#define MMIOERR_CANNOTSEEK
Definition: mmsystem.h:515
#define JOYERR_PARMS
Definition: mmsystem.h:430
#define MMIOERR_CANNOTCLOSE
Definition: mmsystem.h:512
#define MMIOERR_CANNOTEXPAND
Definition: mmsystem.h:516
#define JOYERR_NOCANDO
Definition: mmsystem.h:431
#define error(str)
Definition: mkdosfs.c:1605
#define ERR_TO_STR(dev)
#define MMIOERR_CANNOTWRITE
Definition: mmsystem.h:514
#define MIDIERR_STILLPLAYING
Definition: mmsystem.h:232
#define JOYERR_UNPLUGGED
Definition: mmsystem.h:432
#define MIXERR_INVALCONTROL
Definition: mmsystem.h:296
#define MIXERR_INVALLINE
Definition: mmsystem.h:295
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
#define MMIOERR_FILENOTFOUND
Definition: mmsystem.h:509
#define TIMERR_NOCANDO
Definition: mmsystem.h:419
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
#define MIDIERR_UNPREPARED
Definition: mmsystem.h:231
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
#define MMIOERR_UNBUFFERED
Definition: mmsystem.h:518
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define MIXERR_INVALVALUE
Definition: mmsystem.h:297
#define MMSYSERR_ALLOCATED
Definition: mmsystem.h:100
#define MMIOERR_OUTOFMEMORY
Definition: mmsystem.h:510
#define MMSYSERR_INVALFLAG
Definition: mmsystem.h:106
#define WAVERR_SYNC
Definition: mmsystem.h:179
Definition: id3.c:18
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define MMSYSERR_NOTENABLED
Definition: mmsystem.h:99
#define MIDIERR_INVALIDSETUP
Definition: mmsystem.h:236
#define MMIOERR_CANNOTREAD
Definition: mmsystem.h:513
#define MMSYSERR_BADERRNUM
Definition: mmsystem.h:105
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define MMIOERR_CHUNKNOTFOUND
Definition: mmsystem.h:517
#define WAVERR_UNPREPARED
Definition: mmsystem.h:178
#define MMIOERR_CANNOTOPEN
Definition: mmsystem.h:511
#define MIDIERR_NOTREADY
Definition: mmsystem.h:234
#define MIDIERR_NODEVICE
Definition: mmsystem.h:235
#define TIMERR_STRUCT
Definition: mmsystem.h:420

Referenced by mixer_test_controlA(), mixer_test_controlW(), mixer_test_deviceA(), mixer_test_deviceW(), mixer_testsA(), mixer_testsW(), test_midi_infns(), test_midi_outfns(), test_midiIn_device(), test_midiOut_device(), test_midiStream(), test_mixerClose(), test_mixerOpen(), test_position(), test_timeGetDevCaps(), test_timer(), wave_in_error(), and wave_in_test_deviceIn().

◆ on_vmware()

static BOOL on_vmware ( void  )
static

Definition at line 769 of file midi.c.

770 {
771  static const LPCSTR sub_keys[] = { "Scsi Port ", "Scsi Bus ", "Target Id ", "Logical Unit Id ", NULL };
772  HKEY scsi;
773  BOOL found_vmware = FALSE;
774 
775  if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\Scsi", 0, KEY_ENUMERATE_SUB_KEYS, &scsi) != ERROR_SUCCESS)
776  return FALSE;
777 
778  found_vmware = scan_subkeys(scsi, sub_keys);
779 
780  RegCloseKey(scsi);
781 
782  return found_vmware;
783 }
static BOOL scan_subkeys(HKEY parent, const LPCSTR *sub_keys)
Definition: midi.c:719
#define ERROR_SUCCESS
Definition: deptool.c:10
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3331
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
const char * LPCSTR
Definition: xmlstorage.h:183
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019

Referenced by test_midi_outfns().

◆ playStream()

static MMRESULT playStream ( HMIDISTRM  hm,
LPMIDIHDR  lpMidiHdr 
)
static

Definition at line 464 of file midi.c.

465 {
466  MMRESULT rc = midiStreamOut(hm, lpMidiHdr, sizeof(MIDIHDR));
467  /* virtual machines may return MIDIERR_STILLPLAYING from the next request
468  * even after MHDR_DONE is set. It's still too early, so add MHDR_INQUEUE. */
469  if (!rc) while (!(lpMidiHdr->dwFlags & MHDR_DONE) || (lpMidiHdr->dwFlags & MHDR_INQUEUE)) { Sleep(100); }
470  return rc;
471 }
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
UINT MMRESULT
Definition: mmsystem.h:962
MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr, UINT cbMidiHdr)
Definition: winmm.c:1869
DWORD dwFlags
Definition: mmsystem.h:1155
#define MHDR_DONE
Definition: mmsystem.h:268
#define MHDR_INQUEUE
Definition: mmsystem.h:270

Referenced by test_midiStream().

◆ scan_subkeys()

static BOOL scan_subkeys ( HKEY  parent,
const LPCSTR sub_keys 
)
static

Definition at line 719 of file midi.c.

720 {
721  char name[64];
722  DWORD index = 0;
723  DWORD name_len = sizeof(name);
724  BOOL found_vmware = FALSE;
725 
726  if (sub_keys[0] == NULL)
727  {
728  /* We're at the deepest level, check "Identifier" value now */
729  char *test;
730  if (RegQueryValueExA(parent, "Identifier", NULL, NULL, (LPBYTE) name, &name_len) != ERROR_SUCCESS)
731  return FALSE;
732  for (test = name; test < name + lstrlenA(name) - 6 && ! found_vmware; test++)
733  {
734  char c = test[6];
735  test[6] = '\0';
736  found_vmware = (lstrcmpiA(test, "VMware") == 0);
737  test[6] = c;
738  }
739  return found_vmware;
740  }
741 
742  while (RegEnumKeyExA(parent, index, name, &name_len, NULL, NULL, NULL, NULL) == ERROR_SUCCESS &&
743  ! found_vmware) {
744  char c = name[lstrlenA(sub_keys[0])];
745  name[lstrlenA(sub_keys[0])] = '\0';
746  if (lstrcmpiA(name, sub_keys[0]) == 0) {
747  HKEY sub_key;
748  name[lstrlenA(sub_keys[0])] = c;
750  found_vmware = scan_subkeys(sub_key, sub_keys + 1);
751  RegCloseKey(sub_key);
752  }
753  }
754 
755  name_len = sizeof(name);
756  index++;
757  }
758 
759  return found_vmware;
760 }
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4023
static BOOL scan_subkeys(HKEY parent, const LPCSTR *sub_keys)
Definition: midi.c:719
#define ERROR_SUCCESS
Definition: deptool.c:10
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3331
#define test
Definition: rosglue.h:37
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
GLuint index
Definition: glext.h:6031
r parent
Definition: btrfs.c:2897
const GLubyte * c
Definition: glext.h:8905
unsigned long DWORD
Definition: ntddk_ex.h:95
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
Definition: name.c:36
#define c
Definition: ke_i.h:80
LONG WINAPI RegEnumKeyExA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2442
#define KEY_ENUMERATE_SUB_KEYS
Definition: nt_native.h:1019
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by on_vmware().

◆ spurious_message()

static BOOL spurious_message ( LPMSG  msg)
static

Definition at line 40 of file midi.c.

41 {
42  /* WM_DEVICECHANGE 0x0219 appears randomly */
43  if(msg->message == WM_DEVICECHANGE) {
44  trace("skipping spurious message %04x\n", msg->message);
45  return TRUE;
46  }
47  return FALSE;
48 }
#define TRUE
Definition: types.h:120
#define trace
Definition: atltest.h:70
#define WM_DEVICECHANGE
Definition: winuser.h:1793
#define msg(x)
Definition: auth_time.c:54

Referenced by test_notification_dbg().

◆ START_TEST()

START_TEST ( midi  )

Definition at line 838 of file midi.c.

839 {
840  HWND hwnd = 0;
841 
842  CoInitialize(NULL); /* Needed for Win 10 */
843 
844  if (1) /* select 1 for CALLBACK_WINDOW or 0 for CALLBACK_FUNCTION */
845  hwnd = CreateWindowExA(0, "static", "winmm midi test", WS_POPUP, 0,0,100,100,
846  0, 0, 0, NULL);
849  if (hwnd) DestroyWindow(hwnd);
850 
851  CoUninitialize();
852 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
static void test_midi_infns(HWND hwnd)
Definition: midi.c:211
BOOL WINAPI DestroyWindow(_In_ HWND)
smooth NULL
Definition: ftsmooth.c:416
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1991
#define WS_POPUP
Definition: pedump.c:616
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1897
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
static void test_midi_outfns(HWND hwnd)
Definition: midi.c:785

◆ test_midi_infns()

static void test_midi_infns ( HWND  hwnd)
static

Definition at line 211 of file midi.c.

212 {
213  HMIDIIN hm;
214  MMRESULT rc;
215  UINT udev, ndevs = midiInGetNumDevs();
216 
217  rc = midiInOpen(&hm, ndevs, 0, 0, CALLBACK_NULL);
218  ok(rc==MMSYSERR_BADDEVICEID, "midiInOpen udev>max rc=%s\n", mmsys_error(rc));
219  if (!rc) {
220  rc = midiInClose(hm);
221  ok(!rc, "midiInClose rc=%s\n", mmsys_error(rc));
222  }
223  if (!ndevs) {
224  trace("Found no MIDI IN device\n"); /* no skip for this common situation */
225  rc = midiInOpen(&hm, MIDIMAPPER, 0, 0, CALLBACK_NULL);
226  ok(rc==MMSYSERR_BADDEVICEID || broken(rc==MMSYSERR_NODRIVER /*nt,w2k*/), "midiInOpen MAPPER with no MIDI rc=%s\n", mmsys_error(rc));
227  if (!rc) {
228  rc = midiInClose(hm);
229  ok(!rc, "midiInClose rc=%s\n", mmsys_error(rc));
230  }
231  return;
232  }
233  trace("Found %d MIDI IN devices\n", ndevs);
234  for (udev=0; udev < ndevs; udev++) {
235  trace("** Testing device %d\n", udev);
236  test_midiIn_device(udev, hwnd);
237  Sleep(50);
238  }
239  trace("** Testing MIDI mapper\n");
241 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
MMRESULT WINAPI midiInOpen(HMIDIIN *lphMidiIn, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:1237
UINT MMRESULT
Definition: mmsystem.h:962
UINT WINAPI midiInClose(HMIDIIN hMidiIn)
Definition: winmm.c:1279
#define MIDIMAPPER
Definition: mmsystem.h:252
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
#define trace
Definition: atltest.h:70
static void test_midiIn_device(UINT udev, HWND hwnd)
Definition: midi.c:108
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
const char * mmsys_error(MMRESULT error)
Definition: wave.c:220
#define broken(x)
Definition: _sntprintf.h:21
#define CALLBACK_NULL
Definition: mmsystem.h:147
#define ok(value,...)
Definition: atltest.h:57
unsigned int UINT
Definition: ndis.h:50
UINT WINAPI midiInGetNumDevs(void)
Definition: winmm.c:1187

Referenced by START_TEST().

◆ test_midi_mci()

static void test_midi_mci ( HWND  hwnd)
static

Definition at line 244 of file midi.c.

245 {
246  MCIERROR err;
247  char buf[1024];
248  memset(buf, 0, sizeof(buf));
249 
250  err = mciSendStringA("sysinfo sequencer quantity", buf, sizeof(buf), hwnd);
251  ok(!err, "mci sysinfo sequencer quantity returned %d\n", err);
252  if (!err) trace("Found %s MCI sequencer devices\n", buf);
253 
254  if (!strcmp(buf, "0")) return;
255 
256  err = mciSendStringA("capability sequencer can record", buf, sizeof(buf), hwnd);
257  ok(!err, "mci sysinfo sequencer quantity returned %d\n", err);
258  if(!err) ok(!strcmp(buf, "false"), "capability can record is %s\n", buf);
259 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
DWORD WINAPI mciSendStringA(LPCSTR lpstrCommand, LPSTR lpstrRet, UINT uRetLen, HWND hwndCallback)
Definition: mci.c:1405
#define trace
Definition: atltest.h:70
DWORD MCIERROR
Definition: mmsystem.h:958
#define err(...)
#define ok(value,...)
Definition: atltest.h:57
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define memset(x, y, z)
Definition: compat.h:39

Referenced by test_midi_outfns().

◆ test_midi_outfns()

static void test_midi_outfns ( HWND  hwnd)
static

Definition at line 785 of file midi.c.

786 {
787  HMIDIOUT hm;
788  MMRESULT rc;
789  UINT udev, ndevs = midiOutGetNumDevs();
790 
791  rc = midiOutOpen(&hm, ndevs, 0, 0, CALLBACK_NULL);
792  ok(rc==MMSYSERR_BADDEVICEID, "midiOutOpen udev>max rc=%s\n", mmsys_error(rc));
793  if (!rc) {
794  rc = midiOutClose(hm);
795  ok(!rc, "midiOutClose rc=%s\n", mmsys_error(rc));
796  }
797  if (!ndevs) {
798  MIDIOUTCAPSA capsA;
799  skip("Found no MIDI out device\n");
800 
801  rc = midiOutGetDevCapsA(MIDIMAPPER, &capsA, sizeof(capsA));
802  /* GetDevCaps and Open must return compatible results */
803  ok(rc==MMSYSERR_BADDEVICEID || broken(rc==MMSYSERR_NODRIVER /*nt,w2k*/), "midiOutGetDevCaps MAPPER with no MIDI rc=%s\n", mmsys_error(rc));
804 
805  rc = midiOutOpen(&hm, MIDIMAPPER, 0, 0, CALLBACK_NULL);
806  todo_wine_if (rc == MIDIERR_INVALIDSETUP) /* Wine without snd-seq */
807  ok(rc == MMSYSERR_BADDEVICEID || broken(rc == MMSYSERR_NODRIVER /*w2k sound disabled*/),
808  "midiOutOpen MAPPER with no MIDI rc=%s\n", mmsys_error(rc));
809  if (!rc) {
810  rc = midiOutClose(hm);
811  ok(!rc, "midiOutClose rc=%s\n", mmsys_error(rc));
812  }
813  return;
814  }
815  trace("Found %d MIDI OUT devices\n", ndevs);
816 
818 
819  for (udev=0; udev < ndevs; udev++) {
820  MIDIOUTCAPSA capsA;
821  rc = midiOutGetDevCapsA(udev, &capsA, sizeof(capsA));
822  if (rc || strcmp(capsA.szPname, "Creative Sound Blaster MPU-401") != 0 || ! on_vmware()) {
823  trace("** Testing device %d\n", udev);
824  test_midiOut_device(udev, hwnd);
825  Sleep(800); /* Let the synth rest */
826  test_midiStream(udev, hwnd);
827  Sleep(800);
828  }
829  else
830  win_skip("Skipping this device on VMware, driver problem\n");
831  }
832  trace("** Testing MIDI mapper\n");
834  Sleep(800);
836 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
MMRESULT WINAPI midiOutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:942
UINT MMRESULT
Definition: mmsystem.h:962
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1114
#define MIDIMAPPER
Definition: mmsystem.h:252
static void test_midiStream(UINT udev, HWND hwnd)
Definition: midi.c:473
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
UINT WINAPI midiOutGetDevCapsA(UINT_PTR uDeviceID, LPMIDIOUTCAPSA lpCaps, UINT uSize)
Definition: winmm.c:835
#define todo_wine_if(is_todo)
Definition: test.h:155
#define trace
Definition: atltest.h:70
UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
Definition: winmm.c:981
static void test_midiOut_device(UINT udev, HWND hwnd)
Definition: midi.c:262
#define MIDIERR_INVALIDSETUP
Definition: mmsystem.h:236
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
const char * mmsys_error(MMRESULT error)
Definition: wave.c:220
#define broken(x)
Definition: _sntprintf.h:21
static void test_midi_mci(HWND hwnd)
Definition: midi.c:244
#define CALLBACK_NULL
Definition: mmsystem.h:147
#define ok(value,...)
Definition: atltest.h:57
unsigned int UINT
Definition: ndis.h:50
static BOOL on_vmware(void)
Definition: midi.c:769
#define skip(...)
Definition: atltest.h:64
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define win_skip
Definition: test.h:141
UINT WINAPI midiOutGetNumDevs(void)
Definition: winmm.c:809

Referenced by START_TEST().

◆ test_midiIn_device()

static void test_midiIn_device ( UINT  udev,
HWND  hwnd 
)
static

Definition at line 108 of file midi.c.

109 {
110  HMIDIIN hm;
111  MMRESULT rc;
112  MIDIINCAPSA capsA;
113  MIDIHDR mhdr;
114 
115  rc = midiInGetDevCapsA(udev, &capsA, sizeof(capsA));
116  ok((MIDIMAPPER==udev) ? (rc==MMSYSERR_BADDEVICEID || broken(rc==MMSYSERR_NODRIVER /*nt,w2k*/)) : rc==0,
117  "midiInGetDevCaps(dev=%d) rc=%s\n", udev, mmsys_error(rc));
118  if (!rc) {
119  /* MIDI IN capsA.dwSupport may contain garbage, absent in old MS-Windows */
120  trace("* %s: manufacturer=%d, product=%d, support=%X\n", capsA.szPname, capsA.wMid, capsA.wPid, capsA.dwSupport);
121  }
122 
123  if (hwnd)
125  else
127  ok((MIDIMAPPER!=udev) ? rc==0 : (rc==MMSYSERR_BADDEVICEID || broken(rc==MMSYSERR_NODRIVER /*nt,w2k*/)),
128  "midiInOpen(dev=%d) rc=%s\n", udev, mmsys_error(rc));
129  if (rc) return;
130 
131  test_notification(hwnd, "midiInOpen", MIM_OPEN, 0);
132 
133  memset(&mhdr, 0, sizeof(mhdr));
134  mhdr.dwFlags = MHDR_DONE;
135  mhdr.dwUser = 0x56FA552C;
136  mhdr.dwBufferLength = 70000; /* > 64KB! */
137  mhdr.dwBytesRecorded = 5;
138  mhdr.lpData = HeapAlloc(GetProcessHeap(), 0 , mhdr.dwBufferLength);
139  ok(mhdr.lpData!=NULL, "No %d bytes of memory!\n", mhdr.dwBufferLength);
140  if (mhdr.lpData) {
141  rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1);
142  ok(rc==MMSYSERR_INVALPARAM, "midiInPrepare tiny rc=%s\n", mmsys_error(rc));
143  ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags);
144 
145  mhdr.dwFlags |= MHDR_INQUEUE;
146  rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset));
147  ok(!rc, "midiInPrepare old size rc=%s\n", mmsys_error(rc));
148  ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_INQUEUE|MHDR_DONE)/*w9x*/ ||
149  mhdr.dwFlags == MHDR_PREPARED, "dwFlags=%x\n", mhdr.dwFlags);
150  trace("MIDIHDR flags=%x when unsent\n", mhdr.dwFlags);
151 
153  rc = midiInPrepareHeader(hm, &mhdr, sizeof(mhdr));
154  ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc));
155  ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_INQUEUE|MHDR_DONE), "dwFlags=%x\n", mhdr.dwFlags);
156 
157  mhdr.dwFlags &= ~MHDR_INQUEUE;
158  rc = midiInUnprepareHeader(hm, &mhdr, sizeof(mhdr));
159  ok(!rc, "midiInUnprepare rc=%s\n", mmsys_error(rc));
160  ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags);
161 
162  mhdr.dwFlags &= ~MHDR_DONE;
163  rc = midiInUnprepareHeader(hm, &mhdr, sizeof(mhdr));
164  ok(!rc, "midiInUnprepare rc=%s\n", mmsys_error(rc));
165  ok(mhdr.dwFlags == 0, "dwFlags=%x\n", mhdr.dwFlags);
166 
167  rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset));
168  ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc));
169  ok(mhdr.dwFlags == MHDR_PREPARED, "dwFlags=%x\n", mhdr.dwFlags);
170 
171  mhdr.dwFlags |= MHDR_DONE;
172  rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset));
173  ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc));
174  ok(mhdr.dwBytesRecorded == 5, "BytesRec=%u\n", mhdr.dwBytesRecorded);
175 
176  mhdr.dwFlags |= MHDR_DONE;
177  rc = midiInAddBuffer(hm, &mhdr, sizeof(mhdr));
178  ok(!rc, "midiAddBuffer rc=%s\n", mmsys_error(rc));
179  ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_INQUEUE), "dwFlags=%x\n", mhdr.dwFlags);
180 
181  /* w95 does not set dwBytesRecorded=0 within midiInAddBuffer. Wine does. */
182  if (mhdr.dwBytesRecorded != 0)
183  trace("dwBytesRecorded %u\n", mhdr.dwBytesRecorded);
184 
185  rc = midiInAddBuffer(hm, &mhdr, sizeof(mhdr));
186  ok(rc==MIDIERR_STILLPLAYING, "midiAddBuffer rc=%s\n", mmsys_error(rc));
187 
188  rc = midiInPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset));
189  ok(!rc, "midiInPrepare rc=%s\n", mmsys_error(rc));
190  ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_INQUEUE), "dwFlags=%x\n", mhdr.dwFlags);
191  }
192  rc = midiInReset(hm); /* Return any pending buffer */
193  ok(!rc, "midiInReset rc=%s\n", mmsys_error(rc));
194  test_notification(hwnd, "midiInReset", MIM_LONGDATA, (DWORD_PTR)&mhdr);
195 
196  ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_DONE), "dwFlags=%x\n", mhdr.dwFlags);
197  rc = midiInUnprepareHeader(hm, &mhdr, sizeof(mhdr));
198  ok(!rc, "midiInUnprepare rc=%s\n", mmsys_error(rc));
199 
200  ok(mhdr.dwBytesRecorded == 0, "Did some MIDI HW send %u bytes?\n", mhdr.dwBytesRecorded);
201 
202  rc = midiInClose(hm);
203  ok(!rc, "midiInClose rc=%s\n", mmsys_error(rc));
204 
205  ok(mhdr.dwUser==0x56FA552C, "MIDIHDR.dwUser changed to %lx\n", mhdr.dwUser);
206  HeapFree(GetProcessHeap(), 0, mhdr.lpData);
207  test_notification(hwnd, "midiInClose", MIM_CLOSE, 0);
208  test_notification(hwnd, "midiIn over", 0, WHATEVER);
209 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define CALLBACK_WINDOW
Definition: mmsystem.h:148
DWORD dwUser
Definition: mmsystem.h:1154
LPSTR lpData
Definition: mmsystem.h:1151
#define MIDIERR_STILLPLAYING
Definition: mmsystem.h:232
DWORD dwBufferLength
Definition: mmsystem.h:1152
UINT WINAPI midiInUnprepareHeader(HMIDIIN hMidiIn, MIDIHDR *lpMidiInHdr, UINT uSize)
Definition: winmm.c:1316
#define MIM_CLOSE
Definition: mmsystem.h:242
MMRESULT WINAPI midiInOpen(HMIDIIN *lphMidiIn, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:1237
UINT MMRESULT
Definition: mmsystem.h:962
UINT WINAPI midiInClose(HMIDIIN hMidiIn)
Definition: winmm.c:1279
#define MIDIMAPPER
Definition: mmsystem.h:252
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
#define MIM_LONGDATA
Definition: mmsystem.h:244
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
UINT WINAPI midiInAddBuffer(HMIDIIN hMidiIn, MIDIHDR *lpMidiInHdr, UINT uSize)
Definition: winmm.c:1339
#define MIM_OPEN
Definition: mmsystem.h:241
UINT WINAPI midiInPrepareHeader(HMIDIIN hMidiIn, MIDIHDR *lpMidiInHdr, UINT uSize)
Definition: winmm.c:1297
#define GetProcessHeap()
Definition: compat.h:395
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define MYCBINST
Definition: midi.c:37
DWORD dwFlags
Definition: mmsystem.h:1155
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
const char * mmsys_error(MMRESULT error)
Definition: wave.c:220
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define MHDR_DONE
Definition: mmsystem.h:268
#define broken(x)
Definition: _sntprintf.h:21
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1138
static void CALLBACK callback_func(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: midi.c:55
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define ok(value,...)
Definition: atltest.h:57
UINT WINAPI midiInGetDevCapsA(UINT_PTR uDeviceID, LPMIDIINCAPSA lpCaps, UINT uSize)
Definition: winmm.c:1212
#define MHDR_INQUEUE
Definition: mmsystem.h:270
#define test_notification(hwnd, command, m1, p2)
Definition: midi.c:67
#define WHATEVER
Definition: midi.c:38
#define MHDR_PREPARED
Definition: mmsystem.h:269
DWORD dwSupport
Definition: mmsystem.h:1139
UINT WINAPI midiInReset(HMIDIIN hMidiIn)
Definition: winmm.c:1385
#define memset(x, y, z)
Definition: compat.h:39
#define HeapFree(x, y, z)
Definition: compat.h:394
DWORD dwBytesRecorded
Definition: mmsystem.h:1153

Referenced by test_midi_infns().

◆ test_midiOut_device()

static void test_midiOut_device ( UINT  udev,
HWND  hwnd 
)
static

Definition at line 262 of file midi.c.

263 {
264  HMIDIOUT hm;
265  MMRESULT rc;
266  MIDIOUTCAPSA capsA;
267  DWORD ovolume;
268  UINT udevid;
269  MIDIHDR mhdr;
270 
271  rc = midiOutGetDevCapsA(udev, &capsA, sizeof(capsA));
272  ok(!rc, "midiOutGetDevCaps(dev=%d) rc=%s\n", udev, mmsys_error(rc));
273  if (!rc) {
274  trace("* %s: manufacturer=%d, product=%d, tech=%d, support=%X: %d voices, %d notes\n",
275  capsA.szPname, capsA.wMid, capsA.wPid, capsA.wTechnology, capsA.dwSupport, capsA.wVoices, capsA.wNotes);
276  ok(!((MIDIMAPPER==udev) ^ (MOD_MAPPER==capsA.wTechnology)), "technology %d on device %d\n", capsA.wTechnology, udev);
277  if (MOD_MIDIPORT == capsA.wTechnology) {
278  ok(capsA.wVoices == 0 && capsA.wNotes == 0, "external device with notes or voices\n");
279  ok(capsA.wChannelMask == 0xFFFF, "external device channel mask %x\n", capsA.wChannelMask);
280  ok(!(capsA.dwSupport & (MIDICAPS_VOLUME|MIDICAPS_LRVOLUME|MIDICAPS_CACHE)), "external device support=%X\n", capsA.dwSupport);
281  }
282  }
283 
284  if (hwnd)
286  else
288  if (rc == MMSYSERR_NOTSUPPORTED || rc == MMSYSERR_NODRIVER)
289  {
290  skip( "MIDI out not supported\n" );
291  return;
292  }
293  ok(!rc, "midiOutOpen(dev=%d) rc=%s\n", udev, mmsys_error(rc));
294  if (rc) return;
295 
296  test_notification(hwnd, "midiOutOpen", MOM_OPEN, 0);
297 
298  rc = midiOutGetVolume(hm, &ovolume);
299  ok((capsA.dwSupport & MIDICAPS_VOLUME) ? rc==MMSYSERR_NOERROR : rc==MMSYSERR_NOTSUPPORTED, "midiOutGetVolume rc=%s\n", mmsys_error(rc));
300  /* The native mapper responds with FFFFFFFF initially,
301  * real devices with the volume GUI SW-synth settings. */
302  if (!rc) trace("Current volume %x on device %d\n", ovolume, udev);
303 
304  /* The W95 ESFM Synthesis device reports NOTENABLED although
305  * GetVolume by handle works and music plays. */
306  rc = midiOutGetVolume(UlongToHandle(udev), &ovolume);
307  ok((capsA.dwSupport & MIDICAPS_VOLUME) ? rc==MMSYSERR_NOERROR || broken(rc==MMSYSERR_NOTENABLED) : rc==MMSYSERR_NOTSUPPORTED, "midiOutGetVolume(dev=%d) rc=%s\n", udev, mmsys_error(rc));
308 
309  rc = midiOutGetVolume(hm, NULL);
310  ok(rc==MMSYSERR_INVALPARAM, "midiOutGetVolume NULL rc=%s\n", mmsys_error(rc));
311 
312  /* Tests with midiOutSetvolume show that the midi mapper forwards
313  * the value to the real device, but Get initially always reports
314  * FFFFFFFF. Therefore, a Get+SetVolume pair with the mapper is
315  * not adequate to restore the value prior to tests.
316  */
318  DWORD volume2 = (ovolume < 0x80000000) ? 0xC000C000 : 0x40004000;
319  rc = midiOutSetVolume(hm, volume2);
320  ok(!rc, "midiOutSetVolume rc=%s\n", mmsys_error(rc));
321  if (!rc) {
322  DWORD volume3;
323  rc = midiOutGetVolume(hm, &volume3);
324  ok(!rc, "midiOutGetVolume new rc=%s\n", mmsys_error(rc));
325  if (!rc) trace("New volume %x on device %d\n", volume3, udev);
326  todo_wine ok(volume2==volume3, "volume Set %x = Get %x\n", volume2, volume3);
327 
328  rc = midiOutSetVolume(hm, ovolume);
329  ok(!rc, "midiOutSetVolume restore rc=%s\n", mmsys_error(rc));
330  }
331  }
332  rc = midiOutGetDevCapsA((UINT_PTR)hm, &capsA, sizeof(capsA));
333  ok(!rc, "midiOutGetDevCaps(dev=%d) by handle rc=%s\n", udev, mmsys_error(rc));
334  rc = midiInGetDevCapsA((UINT_PTR)hm, (LPMIDIINCAPSA)&capsA, sizeof(DWORD));
335  ok(rc==MMSYSERR_BADDEVICEID, "midiInGetDevCaps(dev=%d) by out handle rc=%s\n", udev, mmsys_error(rc));
336 
337  { DWORD e = 0x006F4893; /* velocity, note (#69 would be 440Hz) channel */
338  trace("ShortMsg type %x\n", LOBYTE(LOWORD(e)));
339  rc = midiOutShortMsg(hm, e);
340  ok(!rc, "midiOutShortMsg rc=%s\n", mmsys_error(rc));
341  if (!rc) Sleep(400); /* Hear note */
342  }
343 
344  memset(&mhdr, 0, sizeof(mhdr));
345  mhdr.dwFlags = MHDR_DONE;
346  mhdr.dwUser = 0x56FA552C;
347  mhdr.dwOffset = 0xDEADBEEF;
348  mhdr.dwBufferLength = 70000; /* > 64KB! */
349  mhdr.lpData = HeapAlloc(GetProcessHeap(), 0 , mhdr.dwBufferLength);
350  ok(mhdr.lpData!=NULL, "No %d bytes of memory!\n", mhdr.dwBufferLength);
351  if (mhdr.lpData) {
352  rc = midiOutLongMsg(hm, &mhdr, sizeof(mhdr));
353  ok(rc==MIDIERR_UNPREPARED, "midiOutLongMsg unprepared rc=%s\n", mmsys_error(rc));
354  ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags);
355  test_notification(hwnd, "midiOutLong unprepared", 0, WHATEVER);
356 
357  rc = midiOutPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1);
358  ok(rc==MMSYSERR_INVALPARAM, "midiOutPrepare tiny rc=%s\n", mmsys_error(rc));
359  ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags);
360 
361  /* Since at least w2k, midiOutPrepare clears the DONE and INQUEUE flags. w95 didn't. */
362  /* mhdr.dwFlags |= MHDR_INQUEUE; would cause w95 to return STILLPLAYING from Unprepare */
363  rc = midiOutPrepareHeader(hm, &mhdr, offsetof(MIDIHDR,dwOffset));
364  ok(!rc, "midiOutPrepare old size rc=%s\n", mmsys_error(rc));
365  ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_DONE)/*w9x*/ ||
366  mhdr.dwFlags == MHDR_PREPARED, "dwFlags=%x\n", mhdr.dwFlags);
367  trace("MIDIHDR flags=%x when unsent\n", mhdr.dwFlags);
368 
369  /* No flag is cleared when already prepared. */
371  rc = midiOutPrepareHeader(hm, &mhdr, sizeof(mhdr));
372  ok(!rc, "midiOutPrepare rc=%s\n", mmsys_error(rc));
373  ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_DONE|MHDR_INQUEUE), "dwFlags=%x\n", mhdr.dwFlags);
374 
375  mhdr.dwFlags |= MHDR_INQUEUE;
376  rc = midiOutUnprepareHeader(hm, &mhdr, sizeof(mhdr));
377  ok(rc==MIDIERR_STILLPLAYING, "midiOutUnprepare rc=%s\n", mmsys_error(rc));
378  ok(mhdr.dwFlags == (MHDR_PREPARED|MHDR_DONE|MHDR_INQUEUE), "dwFlags=%x\n", mhdr.dwFlags);
379 
380  mhdr.dwFlags &= ~MHDR_INQUEUE;
381  rc = midiOutUnprepareHeader(hm, &mhdr, sizeof(mhdr));
382  ok(!rc, "midiOutUnprepare rc=%s\n", mmsys_error(rc));
383  ok(mhdr.dwFlags == MHDR_DONE, "dwFlags=%x\n", mhdr.dwFlags);
384 
385  mhdr.dwFlags |= MHDR_INQUEUE;
386  rc = midiOutUnprepareHeader(hm, &mhdr, sizeof(mhdr));
387  ok(!rc, "midiOutUnprepare rc=%s\n", mmsys_error(rc));
388  ok(mhdr.dwFlags == (MHDR_INQUEUE|MHDR_DONE), "dwFlags=%x\n", mhdr.dwFlags);
389 
390  HeapFree(GetProcessHeap(), 0, mhdr.lpData);
391  }
392  ok(mhdr.dwUser==0x56FA552C, "MIDIHDR.dwUser changed to %lx\n", mhdr.dwUser);
393  ok(mhdr.dwOffset==0xDEADBEEF, "MIDIHDR.dwOffset changed to %x\n", mhdr.dwOffset);
394 
395  rc = midiOutGetID(hm, &udevid);
396  ok(!rc, "midiOutGetID rc=%s\n", mmsys_error(rc));
397  if(!rc) ok(udevid==udev, "midiOutGetID gives %d, expect %d\n", udevid, udev);
398 
399  rc = midiOutReset(hm); /* Quiet everything */
400  ok(!rc, "midiOutReset rc=%s\n", mmsys_error(rc));
401 
402  rc = midiOutClose(hm);
403  ok(!rc, "midiOutClose rc=%s\n", mmsys_error(rc));
404  test_notification(hwnd, "midiOutClose", MOM_CLOSE, 0);
405 
406  rc = midiOutOpen(&hm, udev, 0, (DWORD_PTR)MYCBINST, CALLBACK_WINDOW);
407  /* w95 broken(rc==MMSYSERR_INVALPARAM) see WINMM_CheckCallback */
408  ok(!rc, "midiOutOpen(dev=%d) 0 CALLBACK_WINDOW rc=%s\n", udev, mmsys_error(rc));
409  /* PostMessage(hwnd=0) redirects to PostThreadMessage(GetCurrentThreadId())
410  * which PeekMessage((HWND)-1) queries. */
411  test_notification((HWND)-1, "midiOutOpen WINDOW->THREAD", 0, WHATEVER);
412  test_notification(hwnd, "midiOutOpen WINDOW", 0, WHATEVER);
413  if (!rc) {
414  rc = midiOutClose(hm);
415  ok(!rc, "midiOutClose rc=%s\n", mmsys_error(rc));
416  test_notification((HWND)-1, "midiOutClose WINDOW->THREAD", 0, WHATEVER);
417  test_notification(hwnd, "midiOutClose", 0, WHATEVER);
418  }
419  test_notification(hwnd, "midiOut over", 0, WHATEVER);
420 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define CALLBACK_WINDOW
Definition: mmsystem.h:148
#define LOBYTE(W)
Definition: jmemdos.c:487
DWORD dwUser
Definition: mmsystem.h:1154
UINT WINAPI midiOutGetVolume(HMIDIOUT hMidiOut, DWORD *lpdwVolume)
Definition: winmm.c:1088
LPSTR lpData
Definition: mmsystem.h:1151
#define MIDIERR_STILLPLAYING
Definition: mmsystem.h:232
DWORD dwBufferLength
Definition: mmsystem.h:1152
#define MIDICAPS_VOLUME
Definition: mmsystem.h:264
#define MIDICAPS_LRVOLUME
Definition: mmsystem.h:265
MMRESULT WINAPI midiOutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:942
UINT WINAPI midiOutSetVolume(HMIDIOUT hMidiOut, DWORD dwVolume)
Definition: winmm.c:1103
UINT MMRESULT
Definition: mmsystem.h:962
int winetest_interactive
UINT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT *lpuDeviceID)
Definition: winmm.c:1139
CHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1114
#define MIDIMAPPER
Definition: mmsystem.h:252
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
Definition: winmm.c:1042
#define MIDIERR_UNPREPARED
Definition: mmsystem.h:231
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
UINT WINAPI midiOutGetDevCapsA(UINT_PTR uDeviceID, LPMIDIOUTCAPSA lpCaps, UINT uSize)
Definition: winmm.c:835
#define e
Definition: ke_i.h:82
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1000
UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
Definition: winmm.c:1073
#define MOM_OPEN
Definition: mmsystem.h:247
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:395
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define MIDICAPS_CACHE
Definition: mmsystem.h:266
UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
Definition: winmm.c:981
#define UlongToHandle(ul)
Definition: basetsd.h:97
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define MYCBINST
Definition: midi.c:37
#define MMSYSERR_NOTENABLED
Definition: mmsystem.h:99
DWORD dwFlags
Definition: mmsystem.h:1155
#define MOM_CLOSE
Definition: mmsystem.h:248
#define todo_wine
Definition: test.h:154
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1019
const char * mmsys_error(MMRESULT error)
Definition: wave.c:220
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define MHDR_DONE
Definition: mmsystem.h:268
#define broken(x)
Definition: _sntprintf.h:21
static void CALLBACK callback_func(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: midi.c:55
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define ok(value,...)
Definition: atltest.h:57
UINT WINAPI midiInGetDevCapsA(UINT_PTR uDeviceID, LPMIDIINCAPSA lpCaps, UINT uSize)
Definition: winmm.c:1212
#define MHDR_INQUEUE
Definition: mmsystem.h:270
unsigned int UINT
Definition: ndis.h:50
#define test_notification(hwnd, command, m1, p2)
Definition: midi.c:67
#define WHATEVER
Definition: midi.c:38
#define skip(...)
Definition: atltest.h:64
UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1057
#define MOD_MAPPER
Definition: mmsystem.h:263
#define MOD_MIDIPORT
Definition: mmsystem.h:259
DWORD dwOffset
Definition: mmsystem.h:1158
#define MHDR_PREPARED
Definition: mmsystem.h:269
#define memset(x, y, z)
Definition: compat.h:39
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by test_midi_outfns().

◆ test_midiStream()

static void test_midiStream ( UINT  udev,
HWND  hwnd 
)
static

Definition at line 473 of file midi.c.

474 {
475  HMIDISTRM hm;
476  MMRESULT rc, rc2;
477  MIDIHDR mhdr;
478  union {
479  MIDIPROPTEMPO tempo;
480  MIDIPROPTIMEDIV tdiv;
481  } midiprop;
482 
483  if (hwnd)
485  else
487  if (rc == MMSYSERR_NOTSUPPORTED || rc == MMSYSERR_NODRIVER)
488  {
489  skip( "MIDI stream not supported\n" );
490  return;
491  }
492  ok(!rc, "midiStreamOpen(dev=%d) rc=%s\n", udev, mmsys_error(rc));
493  if (rc) return;
494 
495  test_notification(hwnd, "midiStreamOpen", MOM_OPEN, 0);
496 
497  midiprop.tempo.cbStruct = sizeof(midiprop.tempo);
498  rc = midiStreamProperty(hm, (void*)&midiprop, MIDIPROP_GET|MIDIPROP_TEMPO);
499  ok(!rc, "midiStreamProperty TEMPO rc=%s\n", mmsys_error(rc));
500  ok(midiprop.tempo.dwTempo==500000, "default stream tempo %u microsec per quarter note\n", midiprop.tempo.dwTempo);
501 
502  midiprop.tdiv.cbStruct = sizeof(midiprop.tdiv);
503  rc = midiStreamProperty(hm, (void*)&midiprop, MIDIPROP_GET|MIDIPROP_TIMEDIV);
504  ok(!rc, "midiStreamProperty TIMEDIV rc=%s\n", mmsys_error(rc));
505  todo_wine ok(24==LOWORD(midiprop.tdiv.dwTimeDiv), "default stream time division %u\n", midiprop.tdiv.dwTimeDiv);
506 
507  memset(&mhdr, 0, sizeof(mhdr));
508  mhdr.dwUser = 0x56FA552C;
509  mhdr.dwOffset = 1234567890;
510  mhdr.dwBufferLength = sizeof(strmEvents);
511  mhdr.dwBytesRecorded = mhdr.dwBufferLength;
512  mhdr.lpData = (LPSTR)&strmEvents[0];
513  if (mhdr.lpData) {
514  rc = midiOutLongMsg((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
515  ok(rc==MIDIERR_UNPREPARED, "midiOutLongMsg unprepared rc=%s\n", mmsys_error(rc));
516  test_notification(hwnd, "midiOutLong unprepared", 0, WHATEVER);
517 
518  rc = midiOutPrepareHeader((HMIDIOUT)hm, &mhdr, offsetof(MIDIHDR,dwOffset)-1);
519  ok(rc==MMSYSERR_INVALPARAM, "midiOutPrepare tiny rc=%s\n", mmsys_error(rc));
520  rc = midiOutPrepareHeader((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
521  ok(!rc, "midiOutPrepare size rc=%s\n", mmsys_error(rc));
522  ok(mhdr.dwFlags & MHDR_PREPARED, "MHDR.dwFlags when prepared %x\n", mhdr.dwFlags);
523 
524  /* The device is still in paused mode and should queue the message. */
525  rc = midiStreamOut(hm, &mhdr, offsetof(MIDIHDR,dwOffset));
526  ok(!rc, "midiStreamOut old size rc=%s\n", mmsys_error(rc));
527  rc2 = rc;
528  trace("MIDIHDR flags=%x when submitted\n", mhdr.dwFlags);
529  /* w9X/me does not set MHDR_ISSTRM when StreamOut exits,
530  * but it will be set on all systems after the job is finished. */
531 
532  Sleep(90);
533  /* Wine <1.1.39 started playing immediately */
534  test_notification(hwnd, "midiStream still paused", 0, WHATEVER);
535 
536  /* MSDN asks to use midiStreamRestart prior to midiStreamOut()
537  * because the starting state is 'pause', but some apps seem to
538  * work with the inverse order: queue everything, then play.
539  */
540 
541  rc = midiStreamRestart(hm);
542  ok(!rc, "midiStreamRestart rc=%s\n", mmsys_error(rc));
543 
544  if (!rc2) while(mhdr.dwFlags & MHDR_INQUEUE) {
545  trace("async MIDI still queued\n");
546  Sleep(100);
547  } /* Checking INQUEUE is not the recommended way to wait for the end of a job, but we're testing. */
548  /* MHDR_ISSTRM is not necessarily set when midiStreamOut returns
549  * rather than when the queue is eventually processed. */
550  ok(mhdr.dwFlags & MHDR_ISSTRM, "MHDR.dwFlags %x no ISSTRM when out of queue\n", mhdr.dwFlags);
551  if (!rc2) while(!(mhdr.dwFlags & MHDR_DONE)) {
552  /* Never to be seen except perhaps on multicore */
553  trace("async MIDI still not done\n");
554  Sleep(100);
555  }
556  ok(mhdr.dwFlags & MHDR_DONE, "MHDR.dwFlags %x not DONE when out of queue\n", mhdr.dwFlags);
557  test_notification(hwnd, "midiStream callback", MOM_POSITIONCB, (DWORD_PTR)&mhdr);
558  test_notification(hwnd, "midiStreamOut", MOM_DONE, (DWORD_PTR)&mhdr);
559 
560  /* Native fills dwOffset regardless of the cbMidiHdr size argument to midiStreamOut */
561  ok(1234567890!=mhdr.dwOffset, "play left MIDIHDR.dwOffset at %u\n", mhdr.dwOffset);
562 
563  rc = midiOutUnprepareHeader((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
564  ok(!rc, "midiOutUnprepare rc=%s\n", mmsys_error(rc));
565  rc = midiOutUnprepareHeader((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
566  ok(!rc, "midiOutUnprepare #2 rc=%s\n", mmsys_error(rc));
567 
568  trace("MIDIHDR stream flags=%x when finished\n", mhdr.dwFlags);
569  ok(mhdr.dwFlags & MHDR_DONE, "MHDR.dwFlags when done %x\n", mhdr.dwFlags);
570 
577 
578  Sleep(400); /* Hear note */
579 
580  midiprop.tempo.cbStruct = sizeof(midiprop.tempo);
581  rc = midiStreamProperty(hm, (void*)&midiprop, MIDIPROP_GET|MIDIPROP_TEMPO);
582  ok(!rc, "midiStreamProperty TEMPO rc=%s\n", mmsys_error(rc));
583  ok(0x0493E0==midiprop.tempo.dwTempo, "stream set tempo %u\n", midiprop.tdiv.dwTimeDiv);
584 
585  rc = midiStreamRestart(hm);
586  ok(!rc, "midiStreamRestart #2 rc=%s\n", mmsys_error(rc));
587 
588  mhdr.dwFlags |= MHDR_ISSTRM;
589  /* Preset flags (e.g. MHDR_ISSTRM) do not disturb. */
590  rc = midiOutPrepareHeader((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
591  ok(!rc, "midiOutPrepare used flags %x rc=%s\n", mhdr.dwFlags, mmsys_error(rc));
592  rc = midiOutUnprepareHeader((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
593  ok(!rc, "midiOutUnprepare used flags %x rc=%s\n", mhdr.dwFlags, mmsys_error(rc));
594 
595  rc = midiStreamRestart(hm);
596  ok(!rc, "midiStreamRestart #3 rc=%s\n", mmsys_error(rc));
597  }
598  ok(mhdr.dwUser==0x56FA552C, "MIDIHDR.dwUser changed to %lx\n", mhdr.dwUser);
599  ok(0==((MIDISHORTEVENT*)&strmEvents)[0].dwStreamID, "dwStreamID set to %x\n", ((LPMIDIEVENT)&strmEvents[0])->dwStreamID);
600 
601  /* dwBytesRecorded controls how much is played, not dwBufferLength
602  * allowing to immediately forward packets from midiIn to midiOut */
603  mhdr.dwOffset = 1234123123;
604  mhdr.dwBufferLength = sizeof(strmNops);
605  trace("buffer: %u\n", mhdr.dwBufferLength);
606  mhdr.dwBytesRecorded = 0;
607  mhdr.lpData = (LPSTR)&strmNops[0];
610 
611  rc = midiOutPrepareHeader((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
612  ok(!rc, "midiOutPrepare rc=%s\n", mmsys_error(rc));
613 
614  rc = playStream(hm, &mhdr);
615  ok(!rc, "midiStreamOut 0 bytes recorded rc=%s\n", mmsys_error(rc));
616 
617  test_notification(hwnd, "midiStreamOut", MOM_DONE, (DWORD_PTR)&mhdr);
618  test_notification(hwnd, "0 bytes recorded", 0, WHATEVER);
619 
620  /* FIXME: check dwOffset within callback
621  * instead of the unspecified value afterwards */
622  ok(1234123123==mhdr.dwOffset || broken(0==mhdr.dwOffset), "play 0 set MIDIHDR.dwOffset to %u\n", mhdr.dwOffset);
623  /* w2k and later only set dwOffset when processing MEVT_T_CALLBACK,
624  * while w9X/me/nt always sets it. Have Wine behave like w2k because the
625  * dwOffset slot does not exist in the small size MIDIHDR. */
626 
627  mhdr.dwOffset = 1234123123;
628  mhdr.dwBytesRecorded = 1*sizeof(MIDISHORTEVENT);
629 
630  rc = playStream(hm, &mhdr);
631  ok(!rc, "midiStreamOut 1 event out of 2 rc=%s\n", mmsys_error(rc));
632 
633  test_notification(hwnd, "1 of 2 events", MOM_POSITIONCB, (DWORD_PTR)&mhdr);
634  test_notification(hwnd, "1 of 2 events", MOM_DONE, (DWORD_PTR)&mhdr);
635  test_notification(hwnd, "1 of 2 events", 0, WHATEVER);
636  ok(0==mhdr.dwOffset, "MIDIHDR.dwOffset 1/2 changed to %u\n", mhdr.dwOffset);
637 
638  mhdr.dwOffset = 1234123123;
639  mhdr.dwBytesRecorded = 2*sizeof(MIDISHORTEVENT);
640 
641  rc = playStream(hm, &mhdr);
642  ok(!rc, "midiStreamOut 1 event out of 2 rc=%s\n", mmsys_error(rc));
643 
644  test_notification(hwnd, "2 of 2 events", MOM_POSITIONCB, (DWORD_PTR)&mhdr);
645  test_notification(hwnd, "2 of 2 events", MOM_POSITIONCB, (DWORD_PTR)&mhdr);
646  test_notification(hwnd, "2 of 2 events", MOM_DONE, (DWORD_PTR)&mhdr);
647  test_notification(hwnd, "2 of 2 events", 0, WHATEVER);
648  ok(sizeof(MIDISHORTEVENT)==mhdr.dwOffset, "MIDIHDR.dwOffset 2/2 changed to %u\n", mhdr.dwOffset);
649  ok(mhdr.dwBytesRecorded == 2*sizeof(MIDISHORTEVENT), "dwBytesRecorded changed to %u\n", mhdr.dwBytesRecorded);
650 
653  mhdr.dwOffset = 1234123123;
654  rc = playStream(hm, &mhdr);
655  ok(!rc, "midiStreamOut 1 event out of 2 rc=%s\n", mmsys_error(rc));
656 
657  test_notification(hwnd, "0 CB in 2 events", MOM_DONE, (DWORD_PTR)&mhdr);
658  test_notification(hwnd, "0 CB in 2 events", 0, WHATEVER);
659  /* w9X/me/nt set dwOffset to the position played last */
660  ok(1234123123==mhdr.dwOffset || broken(sizeof(MIDISHORTEVENT)==mhdr.dwOffset), "MIDIHDR.dwOffset nocb changed to %u\n", mhdr.dwOffset);
661 
662  mhdr.dwBytesRecorded = mhdr.dwBufferLength-1;
663  rc = playStream(hm, &mhdr);
664  ok(rc==MMSYSERR_INVALPARAM,"midiStreamOut dwBytesRecorded modulo MIDIEVENT rc=%s\n", mmsys_error(rc));
665  if (!rc) {
666  test_notification(hwnd, "2 of 2 events", MOM_DONE, (DWORD_PTR)&mhdr);
667  }
668 
669  mhdr.dwBytesRecorded = mhdr.dwBufferLength+1;
670  rc = playStream(hm, &mhdr);
671  ok(rc==MMSYSERR_INVALPARAM,"midiStreamOut dwBufferLength<dwBytesRecorded rc=%s\n", mmsys_error(rc));
672  test_notification(hwnd, "past MIDIHDR tests", 0, WHATEVER);
673 
674  rc = midiStreamStop(hm);
675  ok(!rc, "midiStreamStop rc=%s\n", mmsys_error(rc));
676  ok(mhdr.dwUser==0x56FA552C, "MIDIHDR.dwUser changed to %lx\n", mhdr.dwUser);
677 
678  rc = midiOutUnprepareHeader((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
679  ok(!rc, "midiOutUnprepare rc=%s\n", mmsys_error(rc));
680  ok(0==strmNops[0].dwStreamID, "dwStreamID[0] set to %x\n", strmNops[0].dwStreamID);
681  ok(0==strmNops[1].dwStreamID, "dwStreamID[1] set to %x\n", strmNops[1].dwStreamID);
682 
683  mhdr.dwBufferLength = 70000; /* > 64KB! */
684  mhdr.lpData = HeapAlloc(GetProcessHeap(), 0 , mhdr.dwBufferLength);
685  ok(mhdr.lpData!=NULL, "No %d bytes of memory!\n", mhdr.dwBufferLength);
686  if (mhdr.lpData) {
687  mhdr.dwFlags = 0;
688  /* PrepareHeader detects the too large buffer is for a stream. */
689  rc = midiOutPrepareHeader((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
690  todo_wine ok(rc==MMSYSERR_INVALPARAM, "midiOutPrepare stream too large rc=%s\n", mmsys_error(rc));
691 
692  rc = midiOutUnprepareHeader((HMIDIOUT)hm, &mhdr, sizeof(mhdr));
693  ok(!rc, "midiOutUnprepare rc=%s\n", mmsys_error(rc));
694 
695  HeapFree(GetProcessHeap(), 0, mhdr.lpData);
696  }
697 
698  rc = midiStreamClose(hm);
699  ok(!rc, "midiStreamClose rc=%s\n", mmsys_error(rc));
700  test_notification(hwnd, "midiStreamClose", MOM_CLOSE, 0);
701  test_notification(hwnd, "midiStream over", 0, WHATEVER);
702 
703  rc = midiStreamOpen(&hm, &udev, 1, 0, (DWORD_PTR)MYCBINST, CALLBACK_FUNCTION);
704  ok(!rc /*w2k*/|| rc==MMSYSERR_INVALPARAM/*w98*/, "midiStreamOpen NULL function rc=%s\n", mmsys_error(rc));
705  if (!rc) {
706  trace("Device %d accepts NULL CALLBACK_FUNCTION\n", udev);
707  rc = midiStreamClose(hm);
708  ok(!rc, "midiStreamClose rc=%s\n", mmsys_error(rc));
709  }
710 
711  rc = midiStreamOpen(&hm, &udev, 1, (DWORD_PTR)0xDEADBEEF, (DWORD_PTR)MYCBINST, CALLBACK_WINDOW);
712  ok(rc==MMSYSERR_INVALPARAM, "midiStreamOpen bad window rc=%s\n", mmsys_error(rc));
713  if (!rc) {
714  rc = midiStreamClose(hm);
715  ok(!rc, "midiStreamClose rc=%s\n", mmsys_error(rc));
716  }
717 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
DWORD dwEvent
Definition: midi.c:446
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define CALLBACK_WINDOW
Definition: mmsystem.h:148
DWORD dwUser
Definition: mmsystem.h:1154
LPSTR lpData
Definition: mmsystem.h:1151
static BYTE strmEvents[]
Definition: midi.c:450
DWORD dwBufferLength
Definition: mmsystem.h:1152
UINT MMRESULT
Definition: mmsystem.h:962
#define MEVT_F_CALLBACK
Definition: mmsystem.h:274
#define MOM_POSITIONCB
Definition: mmsystem.h:251
char * LPSTR
Definition: xmlstorage.h:182
#define TIME_SAMPLES
Definition: mmsystem.h:29
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
MMRESULT WINAPI midiStreamOut(HMIDISTRM hMidiStrm, LPMIDIHDR lpMidiHdr, UINT cbMidiHdr)
Definition: winmm.c:1869
#define MIDIERR_UNPREPARED
Definition: mmsystem.h:231
#define MMSYSERR_NODRIVER
Definition: mmsystem.h:102
MMRESULT WINAPI midiStreamStop(HMIDISTRM hMidiStrm)
Definition: winmm.c:2038
#define MIDIPROP_GET
Definition: mmsystem.h:285
#define CALLBACK_FUNCTION
Definition: mmsystem.h:150
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
#define MHDR_ISSTRM
Definition: mmsystem.h:271
UINT WINAPI midiOutPrepareHeader(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1000
#define MOM_DONE
Definition: mmsystem.h:249
MMRESULT WINAPI midiStreamClose(HMIDISTRM hMidiStrm)
Definition: winmm.c:1778
MMRESULT WINAPI midiStreamRestart(HMIDISTRM hMidiStrm)
Definition: winmm.c:2007
#define MOM_OPEN
Definition: mmsystem.h:247
#define GetProcessHeap()
Definition: compat.h:395
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define TIME_MS
Definition: mmsystem.h:28
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define MYCBINST
Definition: midi.c:37
DWORD dwFlags
Definition: mmsystem.h:1155
#define MOM_CLOSE
Definition: mmsystem.h:248
MMRESULT WINAPI midiStreamOpen(HMIDISTRM *lphMidiStrm, LPUINT lpuDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)
Definition: winmm.c:1798
#define todo_wine
Definition: test.h:154
#define TIME_SMPTE
Definition: mmsystem.h:31
#define MIDIPROP_TEMPO
Definition: mmsystem.h:287
UINT WINAPI midiOutUnprepareHeader(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1019
const char * mmsys_error(MMRESULT error)
Definition: wave.c:220
static MMRESULT playStream(HMIDISTRM hm, LPMIDIHDR lpMidiHdr)
Definition: midi.c:464
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define MIDIPROP_TIMEDIV
Definition: mmsystem.h:286
#define MHDR_DONE
Definition: mmsystem.h:268
#define broken(x)
Definition: _sntprintf.h:21
struct midishortevent_tag MIDISHORTEVENT
static void CALLBACK callback_func(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
Definition: midi.c:55
#define TIME_TICKS
Definition: mmsystem.h:33
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define ok(value,...)
Definition: atltest.h:57
#define MHDR_INQUEUE
Definition: mmsystem.h:270
#define TIME_BYTES
Definition: mmsystem.h:30
#define test_notification(hwnd, command, m1, p2)
Definition: midi.c:67
#define WHATEVER
Definition: midi.c:38
#define skip(...)
Definition: atltest.h:64
UINT WINAPI midiOutLongMsg(HMIDIOUT hMidiOut, MIDIHDR *lpMidiOutHdr, UINT uSize)
Definition: winmm.c:1057
DWORD dwOffset
Definition: mmsystem.h:1158
static MIDISHORTEVENT strmNops[]
Definition: midi.c:459
#define MHDR_PREPARED
Definition: mmsystem.h:269
static void test_position(HMIDISTRM hm, UINT typein, UINT typeout)
Definition: midi.c:422
static const WCHAR rc2[]
Definition: oid.c:1216
#define TIME_MIDI
Definition: mmsystem.h:32
#define memset(x, y, z)
Definition: compat.h:39
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:394
MMRESULT WINAPI midiStreamProperty(HMIDISTRM hMidiStrm, LPBYTE lpPropData, DWORD dwProperty)
Definition: winmm.c:1962
DWORD dwBytesRecorded
Definition: mmsystem.h:1153

Referenced by test_midi_outfns().

◆ test_notification_dbg()

static void test_notification_dbg ( HWND  hwnd,
const char command,
UINT  m1,
DWORD_PTR  p2,
int  line 
)
static

Definition at line 68 of file midi.c.

69 { /* Use message type 0 as meaning no message */
70  MSG msg;
71  if (hwnd) {
72  /* msg.wParam is hmidiout, msg.lParam is the mhdr (or 0) */
73  BOOL seen;
74  do { seen = PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE); }
75  while(seen && spurious_message(&msg));
76  if (m1 && !seen) {
77  /* We observe transient delayed notification, mostly on native.
78  * Perhaps the OS preempts the player thread after setting MHDR_DONE
79  * or clearing MHDR_INQUEUE, before calling DriverCallback. */
80  DWORD rc;
81  trace_(__FILE__,line)("Waiting for delayed message %x from %s\n", m1, command);
82  SetLastError(0xDEADBEEF);
84  ok_(__FILE__,line)(rc==WAIT_OBJECT_0, "Wait failed: %04x %d\n", rc, GetLastError());
85  seen = PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE);
86  }
87  if (seen) {
88  trace_(__FILE__,line)("Message %x, wParam=%lx, lParam=%lx from %s\n",
89  msg.message, msg.wParam, msg.lParam, command);
90  ok_(__FILE__,line)(msg.hwnd==hwnd, "Didn't get the handle to our test window\n");
91  ok_(__FILE__,line)(msg.message==m1 && msg.lParam==p2, "bad message %x/%lx from %s, expect %x/%lx\n", msg.message, msg.lParam, command, m1, p2);
92  }
93  else ok_(__FILE__,line)(m1==0, "Expect message %x from %s\n", m1, command);
94  }
95  else {
96  /* FIXME: MOM_POSITIONCB and MOM_DONE are so close that a queue is needed. */
97  if (cbmsg) {
98  ok_(__FILE__,line)(cbmsg==m1 && cbval1==p2 && cbval2==0, "bad callback %x/%lx/%lx from %s, expect %x/%lx\n", cbmsg, cbval1, cbval2, command, m1, p2);
99  cbmsg = 0; /* Mark as read */
100  cbval1 = cbval2 = WHATEVER;
101  ok_(__FILE__,line)(cbinst==MYCBINST, "callback dwInstance changed to %lx\n", cbinst);
102  }
103  else ok_(__FILE__,line)(m1==0, "Expect callback %x from %s\n", m1, command);
104  }
105 }
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define trace_(file, line,...)
Definition: kmt_test.h:221
static DWORD_PTR cbval2
Definition: midi.c:52
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
Definition: parser.c:48
static BOOL spurious_message(LPMSG msg)
Definition: midi.c:40
static DWORD_PTR cbinst
Definition: midi.c:53
#define WAIT_OBJECT_0
Definition: winbase.h:387
unsigned long DWORD
Definition: ntddk_ex.h:95
static UINT cbmsg
Definition: midi.c:50
#define SetLastError(x)
Definition: compat.h:409
#define MYCBINST
Definition: midi.c:37
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
static DWORD_PTR cbval1
Definition: midi.c:51
#define QS_POSTMESSAGE
Definition: winuser.h:888
#define WHATEVER
Definition: midi.c:38
int command(const char *fmt,...)
Definition: ftp.c:266
#define msg(x)
Definition: auth_time.c:54
#define PM_REMOVE
Definition: winuser.h:1182
#define ok_(x1, x2)
Definition: atltest.h:61

◆ test_position()

static void test_position ( HMIDISTRM  hm,
UINT  typein,
UINT  typeout 
)
static

Definition at line 422 of file midi.c.

423 {
424  MMRESULT rc;
425  MMTIME mmtime;
426  mmtime.wType = typein;
427  rc = midiStreamPosition(hm, &mmtime, sizeof(MMTIME));
428  /* Ugly, but a single ok() herein enables using the todo_wine prefix */
429  ok(!rc && (mmtime.wType == typeout), "midiStreamPosition type %x converted to %x rc=%s\n", typein, mmtime.wType, mmsys_error(rc));
430  if (!rc) switch(mmtime.wType) {
431  case TIME_MS:
432  trace("Stream position %ums\n", mmtime.u.ms);
433  break;
434  case TIME_TICKS:
435  trace("Stream position %u ticks\n", mmtime.u.ticks);
436  break;
437  case TIME_MIDI:
438  trace("Stream position song pointer %u\n", mmtime.u.midi.songptrpos);
439  break;
440  }
441 }
UINT wType
Definition: mmsystem.h:965
UINT MMRESULT
Definition: mmsystem.h:962
MMRESULT WINAPI midiStreamPosition(HMIDISTRM hMidiStrm, LPMMTIME lpMMT, UINT cbmmt)
Definition: winmm.c:1928
DWORD ticks
Definition: mmsystem.h:970
struct mmtime_tag::@2914::@2916 midi
#define trace
Definition: atltest.h:70
#define TIME_MS
Definition: mmsystem.h:28
const char * mmsys_error(MMRESULT error)
Definition: wave.c:220
union mmtime_tag::@2914 u
#define TIME_TICKS
Definition: mmsystem.h:33
#define ok(value,...)
Definition: atltest.h:57
#define TIME_MIDI
Definition: mmsystem.h:32
DWORD ms
Definition: mmsystem.h:967

Referenced by test_midiStream().

Variable Documentation

◆ cbinst

DWORD_PTR cbinst = MYCBINST
static

Definition at line 53 of file midi.c.

Referenced by callback_func(), and test_notification_dbg().

◆ cbmsg

UINT cbmsg = 0
static

Definition at line 50 of file midi.c.

Referenced by callback_func(), and test_notification_dbg().

◆ cbval1

DWORD_PTR cbval1 = WHATEVER
static

Definition at line 51 of file midi.c.

Referenced by callback_func(), and test_notification_dbg().

◆ cbval2

DWORD_PTR cbval2 = 0
static

Definition at line 52 of file midi.c.

Referenced by callback_func(), and test_notification_dbg().

◆ strmEvents

BYTE strmEvents[]
static
Initial value:
= {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, MEVT_NOP | 0x40,
0, 0, 0, 0, 0, 0, 0, 0,
0xE0, 0x93, 0x04, MEVT_TEMPO,
0, 0, 0, 0, 0, 0, 0, 0,
0x93, 0x48, 0x6F, MEVT_SHORTMSG,
}
#define MEVT_NOP
Definition: mmsystem.h:279
#define MEVT_SHORTMSG
Definition: mmsystem.h:277
#define MEVT_TEMPO
Definition: mmsystem.h:278

Definition at line 450 of file midi.c.

Referenced by test_midiStream().

◆ strmNops

MIDISHORTEVENT strmNops[]
static
Initial value:
= {
{ 0, 0, (MEVT_NOP <<24)| MEVT_F_CALLBACK },
{ 0, 0, (MEVT_NOP <<24)| MEVT_F_CALLBACK },
}
#define MEVT_F_CALLBACK
Definition: mmsystem.h:274
#define MEVT_NOP
Definition: mmsystem.h:279

Definition at line 459 of file midi.c.

Referenced by test_midiStream().