ReactOS  0.4.15-dev-3287-gfec35dc
mcimidi.c File Reference
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wingdi.h"
#include "winuser.h"
#include "wownt32.h"
#include "mmddk.h"
#include "wine/debug.h"
Include dependency graph for mcimidi.c:

Go to the source code of this file.

Classes

struct  MCI_MIDITRACK
 
struct  tagWINE_MCIMIDI
 

Macros

#define MIDI_NOTEOFF   0x80
 
#define MIDI_NOTEON   0x90
 
#define TIME_MS_IN_ONE_HOUR   (60*60*1000)
 
#define TIME_MS_IN_ONE_MINUTE   (60*1000)
 
#define TIME_MS_IN_ONE_SECOND   (1000)
 

Typedefs

typedef struct tagWINE_MCIMIDI WINE_MCIMIDI
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (mcimidi)
 
static DWORD mmr2mci (DWORD ret)
 
static DWORD MIDI_mciResume (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD MIDI_drvOpen (LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
 
static DWORD MIDI_drvClose (DWORD dwDevID)
 
static WINE_MCIMIDIMIDI_mciGetOpenDev (MCIDEVICEID wDevID, UINT wMsg)
 
static void MIDI_mciNotify (DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
 
static DWORD MIDI_mciReadByte (WINE_MCIMIDI *wmm, BYTE *lpbyt)
 
static DWORD MIDI_mciReadWord (WINE_MCIMIDI *wmm, LPWORD lpw)
 
static DWORD MIDI_mciReadLong (WINE_MCIMIDI *wmm, LPDWORD lpdw)
 
static WORD MIDI_mciReadVaryLen (WINE_MCIMIDI *wmm, LPDWORD lpdw)
 
static DWORD MIDI_mciReadNextEvent (WINE_MCIMIDI *wmm, MCI_MIDITRACK *mmt)
 
static DWORD MIDI_mciReadMTrk (WINE_MCIMIDI *wmm, MCI_MIDITRACK *mmt)
 
static DWORD MIDI_mciReadMThd (WINE_MCIMIDI *wmm, DWORD dwOffset)
 
static DWORD MIDI_ConvertPulseToMS (WINE_MCIMIDI *wmm, DWORD pulse)
 
static DWORD MIDI_ConvertTimeFormatToMS (WINE_MCIMIDI *wmm, DWORD val)
 
static DWORD MIDI_ConvertMSToTimeFormat (WINE_MCIMIDI *wmm, DWORD _val)
 
static DWORD MIDI_GetMThdLengthMS (WINE_MCIMIDI *wmm)
 
static DWORD MIDI_mciOpen (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms)
 
static DWORD MIDI_mciStop (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD MIDI_mciClose (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static MCI_MIDITRACKMIDI_mciFindNextEvent (WINE_MCIMIDI *wmm, LPDWORD hiPulse)
 
static DWORD MIDI_player (WINE_MCIMIDI *wmm, DWORD dwFlags)
 
static DWORD CALLBACK MIDI_Starter (void *ptr)
 
static DWORD ensurePlayerThread (WINE_MCIMIDI *wmm)
 
static DWORD MIDI_mciPlay (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 
static DWORD MIDI_mciPause (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD MIDI_mciSet (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_SEQ_SET_PARMS lpParms)
 
static DWORD MIDI_mciStatus (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 
static DWORD MIDI_mciGetDevCaps (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
 
static DWORD MIDI_mciInfo (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
 
static DWORD MIDI_mciSeek (WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
 
LRESULT CALLBACK MCIMIDI_DriverProc (DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
 

Macro Definition Documentation

◆ MIDI_NOTEOFF

#define MIDI_NOTEOFF   0x80

Definition at line 44 of file mcimidi.c.

◆ MIDI_NOTEON

#define MIDI_NOTEON   0x90

Definition at line 45 of file mcimidi.c.

◆ TIME_MS_IN_ONE_HOUR

#define TIME_MS_IN_ONE_HOUR   (60*60*1000)

Definition at line 549 of file mcimidi.c.

◆ TIME_MS_IN_ONE_MINUTE

#define TIME_MS_IN_ONE_MINUTE   (60*1000)

Definition at line 550 of file mcimidi.c.

◆ TIME_MS_IN_ONE_SECOND

#define TIME_MS_IN_ONE_SECOND   (1000)

Definition at line 551 of file mcimidi.c.

Typedef Documentation

◆ WINE_MCIMIDI

Function Documentation

◆ ensurePlayerThread()

static DWORD ensurePlayerThread ( WINE_MCIMIDI wmm)
static

Definition at line 1099 of file mcimidi.c.

1100 {
1101  if (1) {
1102  DWORD dwRet;
1103 
1104  switch (wmm->dwStatus) {
1105  default:
1107  case MCI_MODE_PAUSE:
1108  return MIDI_mciResume(wmm, 0, NULL);
1109  case MCI_MODE_PLAY:
1110  /* the player was not stopped, use it */
1111  return 0;
1112  case MCI_MODE_STOP:
1113  break;
1114  }
1115  wmm->dwStatus = MCI_MODE_PLAY;
1116  if (wmm->hThread) {
1118  CloseHandle(wmm->hThread);
1119  wmm->hThread = 0;
1120  }
1121  wmm->hThread = CreateThread(NULL, 0, MIDI_Starter, wmm, 0, NULL);
1122  if (!wmm->hThread) {
1123  dwRet = MCIERR_OUT_OF_MEMORY;
1124  } else {
1126  dwRet = 0;
1127  }
1128  if (dwRet)
1129  wmm->dwStatus = MCI_MODE_STOP;
1130  return dwRet;
1131  }
1132 }
#define MCIERR_NONAPPLICABLE_FUNCTION
Definition: mmsystem.h:610
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define CloseHandle
Definition: compat.h:598
static DWORD CALLBACK MIDI_Starter(void *ptr)
Definition: mcimidi.c:1093
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:699
#define MCIERR_OUT_OF_MEMORY
Definition: mmsystem.h:574
unsigned long DWORD
Definition: ntddk_ex.h:95
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:278
static DWORD MIDI_mciResume(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcimidi.c:1215
#define NULL
Definition: types.h:112
WORD dwStatus
Definition: mcimidi.c:71
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define INFINITE
Definition: serial.h:102
HANDLE hThread
Definition: mcimidi.c:65

Referenced by MIDI_mciPlay().

◆ MCIMIDI_DriverProc()

LRESULT CALLBACK MCIMIDI_DriverProc ( DWORD_PTR  dwDevID,
HDRVR  hDriv,
UINT  wMsg,
LPARAM  dwParam1,
LPARAM  dwParam2 
)

Definition at line 1582 of file mcimidi.c.

1584 {
1585  WINE_MCIMIDI* wmm;
1586  switch (wMsg) {
1587  case DRV_LOAD: return 1;
1588  case DRV_FREE: return 1;
1589  case DRV_ENABLE: return 1;
1590  case DRV_DISABLE: return 1;
1591  case DRV_QUERYCONFIGURE: return 1;
1592  case DRV_CONFIGURE: MessageBoxA(0, "Sample Midi Driver !", "OSS Driver", MB_OK); return 1;
1593  case DRV_INSTALL: return DRVCNF_RESTART;
1594  case DRV_REMOVE: return DRVCNF_RESTART;
1595  case DRV_OPEN: return MIDI_drvOpen((LPCWSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSW)dwParam2);
1596  case DRV_CLOSE: return MIDI_drvClose(dwDevID);
1597  }
1598  if ((wMsg < DRV_MCI_FIRST) || (wMsg > DRV_MCI_LAST)) {
1599  TRACE("Sending msg %04x to default driver proc\n", wMsg);
1600  return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1601  }
1602 
1603  wmm = MIDI_mciGetOpenDev(dwDevID, wMsg);
1604  if (wmm == NULL) return MCIERR_INVALID_DEVICE_ID;
1605 
1606  switch (wMsg) {
1607  case MCI_OPEN_DRIVER: return MIDI_mciOpen (wmm, dwParam1, (LPMCI_OPEN_PARMSW) dwParam2);
1608  case MCI_CLOSE_DRIVER: return MIDI_mciClose (wmm, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1609  case MCI_PLAY: return MIDI_mciPlay (wmm, dwParam1, (LPMCI_PLAY_PARMS) dwParam2);
1610  case MCI_STOP: return MIDI_mciStop (wmm, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1611  case MCI_SET: return MIDI_mciSet (wmm, dwParam1, (LPMCI_SEQ_SET_PARMS) dwParam2);
1612  case MCI_PAUSE: return MIDI_mciPause (wmm, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1613  case MCI_RESUME: return MIDI_mciResume (wmm, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
1614  case MCI_STATUS: return MIDI_mciStatus (wmm, dwParam1, (LPMCI_STATUS_PARMS) dwParam2);
1615  case MCI_GETDEVCAPS: return MIDI_mciGetDevCaps(wmm, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
1616  case MCI_INFO: return MIDI_mciInfo (wmm, dwParam1, (LPMCI_INFO_PARMSW) dwParam2);
1617  case MCI_SEEK: return MIDI_mciSeek (wmm, dwParam1, (LPMCI_SEEK_PARMS) dwParam2);
1618  case MCI_OPEN:
1619  case MCI_CLOSE:
1620  FIXME("Shouldn't receive a MCI_OPEN or CLOSE message\n");
1621  /* fall through */
1622  default:
1623  TRACE("Unsupported command [0x%x]\n", wMsg);
1624  return MCIERR_UNSUPPORTED_FUNCTION; /* Win9x: MCIERR_UNRECOGNIZED_COMMAND */
1625  }
1626 }
#define DRV_DISABLE
Definition: mmsystem.h:123
static WINE_MCIMIDI * MIDI_mciGetOpenDev(MCIDEVICEID wDevID, UINT wMsg)
Definition: mcimidi.c:146
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static DWORD MIDI_drvClose(DWORD dwDevID)
Definition: mcimidi.c:131
static DWORD MIDI_mciOpen(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms)
Definition: mcimidi.c:658
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
static DWORD MIDI_mciStop(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcimidi.c:761
#define MCI_PLAY
Definition: mmsystem.h:649
#define DRV_CLOSE
Definition: mmsystem.h:122
#define MCI_RESUME
Definition: mmsystem.h:675
static DWORD MIDI_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
Definition: mcimidi.c:110
static DWORD MIDI_mciInfo(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
Definition: mcimidi.c:1507
#define DRV_MCI_LAST
Definition: mmsystem.h:140
static DWORD MIDI_mciPause(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcimidi.c:1196
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define DRV_OPEN
Definition: mmsystem.h:121
#define MCI_STOP
Definition: mmsystem.h:651
static DWORD MIDI_mciGetDevCaps(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
Definition: mcimidi.c:1435
int WINAPI MessageBoxA(_In_opt_ HWND, _In_opt_ LPCSTR, _In_opt_ LPCSTR, _In_ UINT)
#define MCI_SET
Definition: mmsystem.h:656
#define FIXME(fmt,...)
Definition: debug.h:111
static DWORD MIDI_mciClose(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcimidi.c:794
#define DRV_LOAD(x)
#define MCI_OPEN
Definition: mmsystem.h:646
static DWORD MIDI_mciPlay(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
Definition: mcimidi.c:1137
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define DRV_REMOVE
Definition: mmsystem.h:128
#define MCI_INFO
Definition: mmsystem.h:653
#define MCI_OPEN_DRIVER
Definition: mmddk.h:338
#define MCI_STATUS
Definition: mmsystem.h:662
#define TRACE(s)
Definition: solgame.cpp:4
static DWORD MIDI_mciSeek(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
Definition: mcimidi.c:1545
#define DRV_CONFIGURE
Definition: mmsystem.h:125
static DWORD MIDI_mciStatus(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
Definition: mcimidi.c:1316
#define DRV_FREE
Definition: mmsystem.h:124
static DWORD MIDI_mciResume(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcimidi.c:1215
#define MCI_CLOSE_DRIVER
Definition: mmddk.h:339
#define DRV_ENABLE
Definition: mmsystem.h:120
#define DRV_MCI_FIRST
Definition: mmsystem.h:139
#define NULL
Definition: types.h:112
#define MB_OK
Definition: winuser.h:784
#define MCI_CLOSE
Definition: mmsystem.h:647
#define MCI_GETDEVCAPS
Definition: mmsystem.h:654
#define MCI_PAUSE
Definition: mmsystem.h:652
#define DRV_INSTALL
Definition: mmsystem.h:127
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
static DWORD MIDI_mciSet(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_SEQ_SET_PARMS lpParms)
Definition: mcimidi.c:1231
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_SEEK
Definition: mmsystem.h:650

◆ MIDI_ConvertMSToTimeFormat()

static DWORD MIDI_ConvertMSToTimeFormat ( WINE_MCIMIDI wmm,
DWORD  _val 
)
static

Definition at line 591 of file mcimidi.c.

592 {
593  DWORD ret = 0, val = _val;
594  DWORD h, m, s, f;
595 
596  switch (wmm->dwMciTimeFormat) {
598  ret = val;
599  break;
600  case MCI_FORMAT_SMPTE_24:
601  case MCI_FORMAT_SMPTE_25:
602  case MCI_FORMAT_SMPTE_30:
606  switch (wmm->dwMciTimeFormat) {
607  case MCI_FORMAT_SMPTE_24:
608  /* one frame is 1000/24 val long, 1000/24 == 125/3 */
609  f = (val * 3) / 125; val -= (f * 125) / 3;
610  break;
611  case MCI_FORMAT_SMPTE_25:
612  /* one frame is 1000/25 ms long, 1000/25 == 40 */
613  f = val / 40; val -= f * 40;
614  break;
615  case MCI_FORMAT_SMPTE_30:
616  /* one frame is 1000/30 ms long, 1000/30 == 100/3 */
617  f = (val * 3) / 100; val -= (f * 100) / 3;
618  break;
619  default:
620  FIXME("There must be some bad bad programmer\n");
621  f = 0;
622  }
623  /* val contains the number of ms which cannot make a complete frame */
624  /* FIXME: is this correct ? programs seem to be happy with that */
625  ret = (f << 24) | (s << 16) | (m << 8) | (h << 0);
626  break;
627  default:
628  WARN("Bad time format %u!\n", wmm->dwMciTimeFormat);
629  }
630  /*
631  TRACE("val=%u [tf=%u] => ret=%u=0x%08x\n", _val, wmm->dwMciTimeFormat, ret, ret);
632  */
633  return ret;
634 }
#define TIME_MS_IN_ONE_MINUTE
Definition: mcimidi.c:550
#define MCI_FORMAT_SMPTE_25
Definition: mmsystem.h:706
#define TIME_MS_IN_ONE_HOUR
Definition: mcimidi.c:549
#define WARN(fmt,...)
Definition: debug.h:112
#define MCI_FORMAT_SMPTE_30
Definition: mmsystem.h:707
const GLfloat * m
Definition: glext.h:10848
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
#define FIXME(fmt,...)
Definition: debug.h:111
#define TIME_MS_IN_ONE_SECOND
Definition: mcimidi.c:551
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat f
Definition: glext.h:7540
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_FORMAT_SMPTE_24
Definition: mmsystem.h:705
int ret
GLdouble s
Definition: gl.h:2039
#define f
Definition: ke_i.h:83
DWORD dwMciTimeFormat
Definition: mcimidi.c:72

Referenced by MIDI_mciStatus().

◆ MIDI_ConvertPulseToMS()

static DWORD MIDI_ConvertPulseToMS ( WINE_MCIMIDI wmm,
DWORD  pulse 
)
static

Definition at line 523 of file mcimidi.c.

524 {
525  DWORD ret = 0;
526 
527  /* FIXME: this function may return false values since the tempo (wmm->dwTempo)
528  * may change during file playing
529  */
530  if (wmm->nDivision == 0) {
531  FIXME("Shouldn't happen. wmm->nDivision = 0\n");
532  } else if (wmm->nDivision > 0x8000) { /* SMPTE, unchecked FIXME? */
533  int nf = -(char)HIBYTE(wmm->nDivision); /* number of frames */
534  int nsf = LOBYTE(wmm->nDivision); /* number of sub-frames */
535  ret = (pulse * 1000) / (nf * nsf);
536  } else {
537  ret = (DWORD)((double)pulse * ((double)wmm->dwTempo / 1000) /
538  (double)wmm->nDivision);
539  }
540 
541  /*
542  TRACE("pulse=%u tempo=%u division=%u=0x%04x => ms=%u\n",
543  pulse, wmm->dwTempo, wmm->nDivision, wmm->nDivision, ret);
544  */
545 
546  return ret;
547 }
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define DWORD
Definition: nt_native.h:44
#define FIXME(fmt,...)
Definition: debug.h:111
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
unsigned char
Definition: typeof.h:29
unsigned long DWORD
Definition: ntddk_ex.h:95
WORD nDivision
Definition: mcimidi.c:75
int ret
DWORD dwTempo
Definition: mcimidi.c:77

Referenced by MIDI_GetMThdLengthMS(), MIDI_mciStatus(), and MIDI_player().

◆ MIDI_ConvertTimeFormatToMS()

static DWORD MIDI_ConvertTimeFormatToMS ( WINE_MCIMIDI wmm,
DWORD  val 
)
static

Definition at line 556 of file mcimidi.c.

557 {
558  DWORD ret = 0;
559 
560  switch (wmm->dwMciTimeFormat) {
562  ret = val;
563  break;
564  case MCI_FORMAT_SMPTE_24:
565  ret =
566  (HIBYTE(HIWORD(val)) * 125) / 3 + LOBYTE(HIWORD(val)) * TIME_MS_IN_ONE_SECOND +
568  break;
569  case MCI_FORMAT_SMPTE_25:
570  ret =
573  break;
574  case MCI_FORMAT_SMPTE_30:
575  ret =
576  (HIBYTE(HIWORD(val)) * 100) / 3 + LOBYTE(HIWORD(val)) * TIME_MS_IN_ONE_SECOND +
578  break;
579  default:
580  WARN("Bad time format %u!\n", wmm->dwMciTimeFormat);
581  }
582  /*
583  TRACE("val=%u=0x%08x [tf=%u] => ret=%u\n", val, val, wmm->dwMciTimeFormat, ret);
584  */
585  return ret;
586 }
#define TIME_MS_IN_ONE_MINUTE
Definition: mcimidi.c:550
#define MCI_FORMAT_SMPTE_25
Definition: mmsystem.h:706
#define LOBYTE(W)
Definition: jmemdos.c:487
#define TIME_MS_IN_ONE_HOUR
Definition: mcimidi.c:549
#define WARN(fmt,...)
Definition: debug.h:112
#define HIBYTE(W)
Definition: jmemdos.c:486
#define MCI_FORMAT_SMPTE_30
Definition: mmsystem.h:707
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
#define TIME_MS_IN_ONE_SECOND
Definition: mcimidi.c:551
GLuint GLfloat * val
Definition: glext.h:7180
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_FORMAT_SMPTE_24
Definition: mmsystem.h:705
int ret
#define HIWORD(l)
Definition: typedefs.h:247
DWORD dwMciTimeFormat
Definition: mcimidi.c:72
#define LOWORD(l)
Definition: pedump.c:82

Referenced by MIDI_mciPlay(), and MIDI_mciSeek().

◆ MIDI_drvClose()

static DWORD MIDI_drvClose ( DWORD  dwDevID)
static

Definition at line 131 of file mcimidi.c.

132 {
133  WINE_MCIMIDI* wmm = (WINE_MCIMIDI*)mciGetDriverData(dwDevID);
134 
135  if (wmm) {
136  HeapFree(GetProcessHeap(), 0, wmm);
137  mciSetDriverData(dwDevID, 0);
138  return 1;
139  }
140  return (dwDevID == 0xFFFFFFFF) ? 1 : 0;
141 }
BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD dwData)
DWORD WINAPI mciGetDriverData(UINT uDeviceID)
Definition: mci.c:2066
#define GetProcessHeap()
Definition: compat.h:595
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by MCIMIDI_DriverProc().

◆ MIDI_drvOpen()

static DWORD MIDI_drvOpen ( LPCWSTR  str,
LPMCI_OPEN_DRIVER_PARMSW  modp 
)
static

Definition at line 110 of file mcimidi.c.

111 {
112  WINE_MCIMIDI* wmm;
113 
114  if (!modp) return 0xFFFFFFFF;
115 
117 
118  if (!wmm)
119  return 0;
120 
121  wmm->wDevID = modp->wDeviceID;
122  mciSetDriverData(wmm->wDevID, (DWORD_PTR)wmm);
125  return modp->wDeviceID;
126 }
BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD dwData)
#define MCI_NO_COMMAND_TABLE
Definition: mmddk.h:375
UINT wCustomCommandTable
Definition: mmddk.h:438
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define MCI_DEVTYPE_SEQUENCER
Definition: mmsystem.h:690

Referenced by MCIMIDI_DriverProc().

◆ MIDI_GetMThdLengthMS()

static DWORD MIDI_GetMThdLengthMS ( WINE_MCIMIDI wmm)
static

Definition at line 639 of file mcimidi.c.

640 {
641  WORD nt;
642  DWORD ret = 0;
643 
644  for (nt = 0; nt < wmm->nTracks; nt++) {
645  if (wmm->wFormat == 2) {
646  ret += wmm->tracks[nt].dwLength;
647  } else if (wmm->tracks[nt].dwLength > ret) {
648  ret = wmm->tracks[nt].dwLength;
649  }
650  }
651  /* FIXME: this is wrong if there is a tempo change inside the file */
652  return MIDI_ConvertPulseToMS(wmm, ret);
653 }
static DWORD MIDI_ConvertPulseToMS(WINE_MCIMIDI *wmm, DWORD pulse)
Definition: mcimidi.c:523
DWORD dwLength
Definition: mcimidi.c:51
IMAGE_NT_HEADERS nt
Definition: module.c:50
MCI_MIDITRACK * tracks
Definition: mcimidi.c:78
WORD nTracks
Definition: mcimidi.c:74
WORD wFormat
Definition: mcimidi.c:73
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret

Referenced by MIDI_mciStatus().

◆ MIDI_mciClose()

static DWORD MIDI_mciClose ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 794 of file mcimidi.c.

795 {
796 
797  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
798 
799  if (wmm->dwStatus != MCI_MODE_STOP) {
800  /* mciStop handles MCI_NOTIFY_ABORTED */
801  MIDI_mciStop(wmm, MCI_WAIT, lpParms);
802  }
803 
804  wmm->nUseCount--;
805  if (wmm->nUseCount == 0) {
806  if (wmm->hFile != 0) {
807  mmioClose(wmm->hFile, 0);
808  wmm->hFile = 0;
809  TRACE("hFile closed !\n");
810  }
811  if (wmm->hThread) {
812  CloseHandle(wmm->hThread);
813  wmm->hThread = 0;
814  }
815  HeapFree(GetProcessHeap(), 0, wmm->tracks);
818  HeapFree(GetProcessHeap(), 0, wmm->lpstrName);
819  } else {
820  TRACE("Shouldn't happen... nUseCount=%d\n", wmm->nUseCount);
821  return MCIERR_INTERNAL;
822  }
823 
824  if ((dwFlags & MCI_NOTIFY) && lpParms) {
826  }
827  return 0;
828 }
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define CloseHandle
Definition: compat.h:598
#define MCI_WAIT
Definition: mmsystem.h:730
static DWORD MIDI_mciStop(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcimidi.c:761
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:701
MCI_MIDITRACK * tracks
Definition: mcimidi.c:78
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:595
LPWSTR lpstrCopyright
Definition: mcimidi.c:68
LPWSTR lpstrName
Definition: mcimidi.c:69
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCIERR_INTERNAL
Definition: mmsystem.h:587
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
HMMIO hFile
Definition: mcimidi.c:66
WORD dwStatus
Definition: mcimidi.c:71
LPWSTR lpstrElementName
Definition: mcimidi.c:67
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define HeapFree(x, y, z)
Definition: compat.h:594
HANDLE hThread
Definition: mcimidi.c:65

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciFindNextEvent()

static MCI_MIDITRACK* MIDI_mciFindNextEvent ( WINE_MCIMIDI wmm,
LPDWORD  hiPulse 
)
static

Definition at line 833 of file mcimidi.c.

834 {
835  WORD cnt, nt;
836  MCI_MIDITRACK* mmt;
837 
838  *hiPulse = 0xFFFFFFFFul;
839  cnt = 0xFFFFu;
840  for (nt = 0; nt < wmm->nTracks; nt++) {
841  mmt = &wmm->tracks[nt];
842 
843  if (mmt->wStatus == 0)
844  continue;
845  if (mmt->dwEventPulse < *hiPulse) {
846  *hiPulse = mmt->dwEventPulse;
847  cnt = nt;
848  }
849  }
850  return (cnt == 0xFFFFu) ? 0 /* no more event on all tracks */
851  : &wmm->tracks[cnt];
852 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
WORD wStatus
Definition: mcimidi.c:55
IMAGE_NT_HEADERS nt
Definition: module.c:50
MCI_MIDITRACK * tracks
Definition: mcimidi.c:78
WORD nTracks
Definition: mcimidi.c:74
DWORD dwEventPulse
Definition: mcimidi.c:52
unsigned short WORD
Definition: ntddk_ex.h:93

Referenced by MIDI_player().

◆ MIDI_mciGetDevCaps()

static DWORD MIDI_mciGetDevCaps ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_GETDEVCAPS_PARMS  lpParms 
)
static

Definition at line 1435 of file mcimidi.c.

1437 {
1438  DWORD ret;
1439 
1440  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
1441 
1442  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1443 
1444  if (dwFlags & MCI_GETDEVCAPS_ITEM) {
1445  switch (lpParms->dwItem) {
1447  TRACE("MCI_GETDEVCAPS_DEVICE_TYPE !\n");
1450  break;
1452  TRACE("MCI_GETDEVCAPS_HAS_AUDIO !\n");
1453  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1455  break;
1457  TRACE("MCI_GETDEVCAPS_HAS_VIDEO !\n");
1458  lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
1460  break;
1462  TRACE("MCI_GETDEVCAPS_USES_FILES !\n");
1463  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1465  break;
1467  TRACE("MCI_GETDEVCAPS_COMPOUND_DEVICE !\n");
1468  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1470  break;
1472  TRACE("MCI_GETDEVCAPS_CAN_EJECT !\n");
1473  lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
1475  break;
1477  TRACE("MCI_GETDEVCAPS_CAN_PLAY !\n");
1478  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1480  break;
1482  TRACE("MCI_GETDEVCAPS_CAN_RECORD !\n");
1483  lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
1485  break;
1487  TRACE("MCI_GETDEVCAPS_CAN_SAVE !\n");
1488  lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
1490  break;
1491  default:
1492  FIXME("Unknown capability (%08x) !\n", lpParms->dwItem);
1494  }
1495  } else {
1496  WARN("No GetDevCaps-Item !\n");
1498  }
1499  if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
1501  return ret;
1502 }
#define TRUE
Definition: types.h:120
#define MCI_GETDEVCAPS_CAN_SAVE
Definition: mmsystem.h:767
#define WARN(fmt,...)
Definition: debug.h:112
#define MCI_GETDEVCAPS_COMPOUND_DEVICE
Definition: mmsystem.h:764
#define MCI_RESOURCE_RETURNED
Definition: mmddk.h:369
#define MCI_GETDEVCAPS_CAN_RECORD
Definition: mmsystem.h:759
#define MAKEMCIRESOURCE(wRet, wRes)
Definition: mmddk.h:388
#define MCI_GETDEVCAPS_USES_FILES
Definition: mmsystem.h:763
#define FALSE
Definition: types.h:117
#define FIXME(fmt,...)
Definition: debug.h:111
#define MCI_GETDEVCAPS_DEVICE_TYPE
Definition: mmsystem.h:762
#define MCI_GETDEVCAPS_HAS_VIDEO
Definition: mmsystem.h:761
#define TRACE(s)
Definition: solgame.cpp:4
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
int ret
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCI_GETDEVCAPS_HAS_AUDIO
Definition: mmsystem.h:760
#define MCI_GETDEVCAPS_ITEM
Definition: mmsystem.h:758
#define MCI_FALSE
Definition: mmddk.h:340
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
#define NULL
Definition: types.h:112
#define MCI_TRUE
Definition: mmddk.h:341
#define MCIERR_UNRECOGNIZED_COMMAND
Definition: mmsystem.h:571
#define HRESULT_CODE(hr)
Definition: winerror.h:76
#define MCI_GETDEVCAPS_CAN_EJECT
Definition: mmsystem.h:765
#define MCI_DEVTYPE_SEQUENCER
Definition: mmsystem.h:690
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define MCI_GETDEVCAPS_CAN_PLAY
Definition: mmsystem.h:766

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciGetOpenDev()

static WINE_MCIMIDI* MIDI_mciGetOpenDev ( MCIDEVICEID  wDevID,
UINT  wMsg 
)
static

Definition at line 146 of file mcimidi.c.

147 {
148  WINE_MCIMIDI* wmm = (WINE_MCIMIDI*)mciGetDriverData(wDevID);
149 
150  if (wmm == NULL || ((wmm->nUseCount == 0) ^ (wMsg == MCI_OPEN_DRIVER))) {
151  WARN("Invalid wDevID=%u\n", wDevID);
152  return 0;
153  }
154  return wmm;
155 }
DWORD WINAPI mciGetDriverData(UINT uDeviceID)
Definition: mci.c:2066
#define WARN(fmt,...)
Definition: debug.h:112
#define MCI_OPEN_DRIVER
Definition: mmddk.h:338
#define NULL
Definition: types.h:112

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciInfo()

static DWORD MIDI_mciInfo ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_INFO_PARMSW  lpParms 
)
static

Definition at line 1507 of file mcimidi.c.

1508 {
1509  LPCWSTR str = 0;
1510  DWORD ret = 0;
1511  static const WCHAR wszMidiSeq[] = {'W','i','n','e','\'','s',' ','M','I','D','I',' ','s','e','q','u','e','n','c','e','r',0};
1512 
1513  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
1514 
1515  if (lpParms == NULL || lpParms->lpstrReturn == NULL)
1517 
1518  TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize);
1519 
1520  switch (dwFlags & ~(MCI_WAIT|MCI_NOTIFY)) {
1521  case MCI_INFO_PRODUCT: str = wszMidiSeq; break;
1522  case MCI_INFO_FILE: str = wmm->lpstrElementName; break;
1523  case MCI_INFO_COPYRIGHT: str = wmm->lpstrCopyright; break;
1524  case MCI_INFO_NAME: str = wmm->lpstrName; break;
1525  default:
1526  WARN("Don't know this info command (%u)\n", dwFlags);
1527  return MCIERR_MISSING_PARAMETER; /* not MCIERR_FLAGS_... */
1528  }
1529  if (!ret) {
1530  if (lpParms->dwRetSize) {
1531  WCHAR zero = 0;
1532  /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize
1533  * to the number of characters written, excluding \0. */
1534  lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize);
1535  } else ret = MCIERR_PARAM_OVERFLOW;
1536  }
1537  if (MMSYSERR_NOERROR==ret && (dwFlags & MCI_NOTIFY))
1539  return ret;
1540 }
#define MCI_INFO_PRODUCT
Definition: mmsystem.h:752
#define MCI_WAIT
Definition: mmsystem.h:730
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define WARN(fmt,...)
Definition: debug.h:112
#define lstrcpynW
Definition: compat.h:597
const WCHAR * str
#define MCI_INFO_FILE
Definition: mmsystem.h:753
int zero
Definition: sehframes.cpp:29
DWORD_PTR dwCallback
Definition: mmsystem.h:1579
#define MCIERR_MISSING_PARAMETER
Definition: mmsystem.h:583
#define MCIERR_PARAM_OVERFLOW
Definition: mmsystem.h:578
#define TRACE(s)
Definition: solgame.cpp:4
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
LPWSTR lpstrCopyright
Definition: mcimidi.c:68
LPWSTR lpstrName
Definition: mcimidi.c:69
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
int ret
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCI_INFO_NAME
Definition: mmsystem.h:756
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
#define NULL
Definition: types.h:112
#define MCI_INFO_COPYRIGHT
Definition: mmsystem.h:757
LPWSTR lpstrElementName
Definition: mcimidi.c:67
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciNotify()

static void MIDI_mciNotify ( DWORD_PTR  hWndCallBack,
WINE_MCIMIDI wmm,
UINT  wStatus 
)
static

Definition at line 164 of file mcimidi.c.

165 {
166  /* We simply save one parameter by not passing the wDevID local
167  * to the command. They are the same (via mciGetDriverData).
168  */
169  MCIDEVICEID wDevID = wmm->wDevID;
171  if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_SUPERSEDED);
172  mciDriverNotify(HWND_32(LOWORD(hWndCallBack)), wDevID, wStatus);
173 }
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2056
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define HWND_32(h16)
Definition: wownt32.h:29
#define MCI_NOTIFY_SUPERSEDED
Definition: mmsystem.h:726
#define NULL
Definition: types.h:112
UINT MCIDEVICEID
Definition: mmsystem.h:959
#define LOWORD(l)
Definition: pedump.c:82
HANDLE hCallback
Definition: mcimidi.c:64

Referenced by MIDI_mciClose(), MIDI_mciGetDevCaps(), MIDI_mciInfo(), MIDI_mciOpen(), MIDI_mciPause(), MIDI_mciResume(), MIDI_mciSeek(), MIDI_mciSet(), MIDI_mciStatus(), and MIDI_mciStop().

◆ MIDI_mciOpen()

static DWORD MIDI_mciOpen ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_OPEN_PARMSW  lpParms 
)
static

Definition at line 658 of file mcimidi.c.

659 {
660  DWORD dwRet = 0;
661 
662  TRACE("(%d, %08X, %p)\n", wmm->wDevID, dwFlags, lpParms);
663 
664  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
666  return MCIERR_HARDWARE;
667 
668  if (wmm->nUseCount > 0) {
669  /* The driver is already opened on this channel
670  * MIDI sequencer cannot be shared
671  */
672  return MCIERR_DEVICE_OPEN;
673  }
674  wmm->nUseCount++;
675 
676  wmm->hFile = 0;
677  wmm->hMidi = 0;
678  wmm->wPort = MIDI_MAPPER;
679  wmm->lpstrElementName = NULL;
680 
681  TRACE("wDevID=%d (lpParams->wDeviceID=%d)\n", wmm->wDevID, lpParms->wDeviceID);
682  /* lpParms->wDeviceID = wDevID;*/
683 
684  if (dwFlags & MCI_OPEN_ELEMENT) {
685  TRACE("MCI_OPEN_ELEMENT %s!\n", debugstr_w(lpParms->lpstrElementName));
686  if (lpParms->lpstrElementName && lpParms->lpstrElementName[0]) {
687  wmm->hFile = mmioOpenW((LPWSTR)lpParms->lpstrElementName, NULL,
689  if (wmm->hFile == 0) {
690  WARN("Can't find file %s!\n", debugstr_w(lpParms->lpstrElementName));
691  wmm->nUseCount--;
692  return MCIERR_FILE_NOT_FOUND;
693  }
695  (lstrlenW(lpParms->lpstrElementName) + 1) * sizeof(WCHAR));
697  }
698  }
699  TRACE("hFile=%p\n", wmm->hFile);
700 
701  wmm->lpstrCopyright = NULL;
702  wmm->lpstrName = NULL;
703 
704  wmm->dwStatus = MCI_MODE_NOT_READY; /* while loading file contents */
705  /* spec says it should be the default format from the MIDI file... */
707 
708  if (wmm->hFile != 0) {
709  MMCKINFO ckMainRIFF;
710  MMCKINFO mmckInfo;
711  DWORD dwOffset = 0;
712 
713  if (mmioDescend(wmm->hFile, &ckMainRIFF, NULL, 0) != 0) {
714  dwRet = MCIERR_INVALID_FILE;
715  } else {
716  TRACE("ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n",
717  (LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType, ckMainRIFF.cksize);
718 
719  if (ckMainRIFF.ckid == FOURCC_RIFF && ckMainRIFF.fccType == mmioFOURCC('R', 'M', 'I', 'D')) {
720  mmckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');
721  mmioSeek(wmm->hFile, ckMainRIFF.dwDataOffset + ((ckMainRIFF.cksize + 1) & ~1), SEEK_SET);
722  if (mmioDescend(wmm->hFile, &mmckInfo, &ckMainRIFF, MMIO_FINDCHUNK) == 0) {
723  TRACE("... is a 'RMID' file\n");
724  dwOffset = mmckInfo.dwDataOffset;
725  } else {
726  dwRet = MCIERR_INVALID_FILE;
727  }
728  }
729  if (dwRet == 0 && MIDI_mciReadMThd(wmm, dwOffset) != 0) {
730  WARN("Can't read 'MThd' header\n");
731  dwRet = MCIERR_INVALID_FILE;
732  }
733  }
734  } else {
735  TRACE("hFile==0, setting #tracks to 0; is this correct ?\n");
736  wmm->nTracks = 0;
737  wmm->wFormat = 0;
738  wmm->nDivision = 1;
739  }
740  if (dwRet != 0) {
741  wmm->nUseCount--;
742  if (wmm->hFile != 0)
743  mmioClose(wmm->hFile, 0);
744  wmm->hFile = 0;
745  HeapFree(GetProcessHeap(), 0, wmm->tracks);
748  HeapFree(GetProcessHeap(), 0, wmm->lpstrName);
749  } else {
750  wmm->dwPositionMS = 0;
751  wmm->dwStatus = MCI_MODE_STOP;
752  if (dwFlags & MCI_NOTIFY)
754  }
755  return dwRet;
756 }
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
#define MIDI_MAPPER
Definition: mmsystem.h:253
#define WARN(fmt,...)
Definition: debug.h:112
DWORD dwDataOffset
Definition: mmsystem.h:1510
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:701
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:669
#define MMIO_DENYWRITE
Definition: mmsystem.h:540
char * LPSTR
Definition: xmlstorage.h:182
#define lstrlenW
Definition: compat.h:609
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
MCI_MIDITRACK * tracks
Definition: mcimidi.c:78
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
LPCWSTR lpstrElementName
Definition: mmsystem.h:1532
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
#define debugstr_w
Definition: kernel32.h:32
static DWORD MIDI_mciReadMThd(WINE_MCIMIDI *wmm, DWORD dwOffset)
Definition: mcimidi.c:403
DWORD dwPositionMS
Definition: mcimidi.c:80
HMIDI hMidi
Definition: mcimidi.c:62
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
FOURCC fccType
Definition: mmsystem.h:1509
#define MMIO_READ
Definition: mmsystem.h:535
WORD nTracks
Definition: mcimidi.c:74
WORD wFormat
Definition: mcimidi.c:73
#define SEEK_SET
Definition: jmemansi.c:26
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MCI_OPEN_SHAREABLE
Definition: mmsystem.h:734
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD_PTR dwCallback
Definition: mmsystem.h:1529
LPWSTR lpstrCopyright
Definition: mcimidi.c:68
DWORD cksize
Definition: mmsystem.h:1508
LPWSTR lpstrName
Definition: mcimidi.c:69
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
WORD nDivision
Definition: mcimidi.c:75
#define FOURCC_RIFF
Definition: mmsystem.h:564
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define MCIERR_FILE_NOT_FOUND
Definition: mmsystem.h:585
#define lstrcpyW
Definition: compat.h:608
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
FOURCC ckid
Definition: mmsystem.h:1507
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1106
#define MCI_OPEN_ELEMENT
Definition: mmsystem.h:735
HMMIO hFile
Definition: mcimidi.c:66
#define NULL
Definition: types.h:112
#define MCIERR_HARDWARE
Definition: mmsystem.h:572
WORD dwStatus
Definition: mcimidi.c:71
LPWSTR lpstrElementName
Definition: mcimidi.c:67
#define MCIERR_DEVICE_OPEN
Definition: mmsystem.h:575
DWORD dwMciTimeFormat
Definition: mcimidi.c:72
MCIDEVICEID wDeviceID
Definition: mmsystem.h:1530
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define HeapFree(x, y, z)
Definition: compat.h:594

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciPause()

static DWORD MIDI_mciPause ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 1196 of file mcimidi.c.

1197 {
1198  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
1199 
1200  if (wmm->dwStatus == MCI_MODE_PLAY) {
1201  /* stop all notes */
1202  unsigned chn;
1203  for (chn = 0; chn < 16; chn++)
1204  midiOutShortMsg((HMIDIOUT)(wmm->hMidi), 0x78B0 | chn);
1205  wmm->dwStatus = MCI_MODE_PAUSE;
1206  }
1207  if ((dwFlags & MCI_NOTIFY) && lpParms)
1209  return 0;
1210 }
UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
Definition: winmm.c:1042
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
HMIDI hMidi
Definition: mcimidi.c:62
#define TRACE(s)
Definition: solgame.cpp:4
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
WORD dwStatus
Definition: mcimidi.c:71
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define MCI_NOTIFY
Definition: mmsystem.h:729

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciPlay()

static DWORD MIDI_mciPlay ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_PLAY_PARMS  lpParms 
)
static

Definition at line 1137 of file mcimidi.c.

1138 {
1139  DWORD dwStartMS, dwEndMS;
1140  DWORD dwRet;
1141  HANDLE oldcb;
1142 
1143  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
1144 
1145  if (wmm->hFile == 0) {
1146  WARN("Can't play: no file %s!\n", debugstr_w(wmm->lpstrElementName));
1147  return MCIERR_FILE_NOT_FOUND;
1148  }
1149 
1150  if (lpParms && (dwFlags & MCI_TO)) {
1151  dwEndMS = MIDI_ConvertTimeFormatToMS(wmm, lpParms->dwTo);
1152  /* FIXME: if (dwEndMS > length) return MCIERR_OUTOFRANGE; */
1153  } else {
1154  dwEndMS = 0xFFFFFFFFul; /* FIXME: dwEndMS = length; */
1155  }
1156  if (lpParms && (dwFlags & MCI_FROM)) {
1157  dwStartMS = MIDI_ConvertTimeFormatToMS(wmm, lpParms->dwFrom);
1158  } else {
1159  dwStartMS = wmm->dwPositionMS;
1160  }
1161  if (dwEndMS < dwStartMS)
1162  return MCIERR_OUTOFRANGE;
1163 
1164  if (dwFlags & MCI_FROM) {
1165  /* Stop with MCI_NOTIFY_ABORTED and set new position. */
1166  MIDI_mciStop(wmm, MCI_WAIT, NULL);
1167  wmm->dwPositionMS = dwStartMS;
1168  } /* else use existing player. */
1169  if (wmm->dwEndMS != dwEndMS) {
1170  oldcb = InterlockedExchangePointer(&wmm->hCallback, NULL);
1171  if (oldcb) mciDriverNotify(oldcb, wmm->wDevID, MCI_NOTIFY_ABORTED);
1172  wmm->dwEndMS = dwEndMS;
1173  }
1174 
1175  TRACE("Playing from %u to %u\n", dwStartMS, dwEndMS);
1176 
1177  if ((dwFlags & MCI_NOTIFY) && lpParms) {
1178  oldcb = InterlockedExchangePointer(&wmm->hCallback, HWND_32(LOWORD(lpParms->dwCallback)));
1179  if (oldcb) mciDriverNotify(oldcb, wmm->wDevID, MCI_NOTIFY_SUPERSEDED);
1180  }
1181 
1182  dwRet = ensurePlayerThread(wmm);
1183 
1184  if (!dwRet && (dwFlags & MCI_WAIT)) {
1186  GetExitCodeThread(wmm->hThread, &dwRet);
1187  /* STATUS_PENDING cannot happen. It folds onto MCIERR_UNRECOGNIZED_KEYWORD */
1188  }
1189  /* The player thread performs notification at exit. */
1190  return dwRet;
1191 }
#define MCI_WAIT
Definition: mmsystem.h:730
#define WARN(fmt,...)
Definition: debug.h:112
DWORD_PTR dwCallback
Definition: mmsystem.h:1537
static DWORD MIDI_mciStop(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcimidi.c:761
#define MCI_NOTIFY_ABORTED
Definition: mmsystem.h:727
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:540
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2056
#define debugstr_w
Definition: kernel32.h:32
DWORD dwEndMS
Definition: mcimidi.c:81
DWORD dwPositionMS
Definition: mcimidi.c:80
static DWORD ensurePlayerThread(WINE_MCIMIDI *wmm)
Definition: mcimidi.c:1099
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
#define HWND_32(h16)
Definition: wownt32.h:29
#define MCIERR_FILE_NOT_FOUND
Definition: mmsystem.h:585
#define MCI_NOTIFY_SUPERSEDED
Definition: mmsystem.h:726
HMMIO hFile
Definition: mcimidi.c:66
#define NULL
Definition: types.h:112
LPWSTR lpstrElementName
Definition: mcimidi.c:67
#define MCI_FROM
Definition: mmsystem.h:731
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define INFINITE
Definition: serial.h:102
#define LOWORD(l)
Definition: pedump.c:82
static DWORD MIDI_ConvertTimeFormatToMS(WINE_MCIMIDI *wmm, DWORD val)
Definition: mcimidi.c:556
HANDLE hCallback
Definition: mcimidi.c:64
#define MCI_TO
Definition: mmsystem.h:732
HANDLE hThread
Definition: mcimidi.c:65

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciReadByte()

static DWORD MIDI_mciReadByte ( WINE_MCIMIDI wmm,
BYTE lpbyt 
)
static

Definition at line 178 of file mcimidi.c.

179 {
180  DWORD ret = 0;
181 
182  if (mmioRead(wmm->hFile, (HPSTR)lpbyt, sizeof(BYTE)) != (long)sizeof(BYTE)) {
183  WARN("Error reading wmm=%p\n", wmm);
185  }
186 
187  return ret;
188 }
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
#define WARN(fmt,...)
Definition: debug.h:112
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
char * HPSTR
Definition: mmsystem.h:1477
unsigned char BYTE
Definition: xxhash.c:193
HMMIO hFile
Definition: mcimidi.c:66
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:732

Referenced by MIDI_mciReadNextEvent(), MIDI_mciReadVaryLen(), MIDI_mciReadWord(), and MIDI_player().

◆ MIDI_mciReadLong()

static DWORD MIDI_mciReadLong ( WINE_MCIMIDI wmm,
LPDWORD  lpdw 
)
static

Definition at line 209 of file mcimidi.c.

210 {
211  WORD hiword, loword;
213 
214  if (MIDI_mciReadWord(wmm, &hiword) == 0 &&
215  MIDI_mciReadWord(wmm, &loword) == 0) {
216  *lpdw = MAKELONG(loword, hiword);
217  ret = 0;
218  }
219  return ret;
220 }
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
static DWORD MIDI_mciReadWord(WINE_MCIMIDI *wmm, LPWORD lpw)
Definition: mcimidi.c:193
#define MAKELONG(a, b)
Definition: typedefs.h:249
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret

Referenced by MIDI_mciReadMThd(), and MIDI_mciReadMTrk().

◆ MIDI_mciReadMThd()

static DWORD MIDI_mciReadMThd ( WINE_MCIMIDI wmm,
DWORD  dwOffset 
)
static

Definition at line 403 of file mcimidi.c.

404 {
405  DWORD toberead;
406  FOURCC fourcc;
407  WORD nt;
408 
409  TRACE("(%p, %08X);\n", wmm, dwOffset);
410 
411  if (mmioSeek(wmm->hFile, dwOffset, SEEK_SET) != dwOffset) {
412  WARN("Can't seek at %08X begin of 'MThd'\n", dwOffset);
413  return MCIERR_INVALID_FILE;
414  }
415  if (mmioRead(wmm->hFile, (HPSTR)&fourcc,
416  (long) sizeof(FOURCC)) != (long) sizeof(FOURCC))
417  return MCIERR_INVALID_FILE;
418 
419  if (fourcc != mmioFOURCC('M', 'T', 'h', 'd')) {
420  WARN("Can't synchronize on 'MThd' !\n");
421  return MCIERR_INVALID_FILE;
422  }
423 
424  if (MIDI_mciReadLong(wmm, &toberead) != 0 || toberead < 3 * sizeof(WORD))
425  return MCIERR_INVALID_FILE;
426 
427  if (MIDI_mciReadWord(wmm, &wmm->wFormat) != 0 ||
428  MIDI_mciReadWord(wmm, &wmm->nTracks) != 0 ||
429  MIDI_mciReadWord(wmm, &wmm->nDivision) != 0) {
430  return MCIERR_INVALID_FILE;
431  }
432 
433  TRACE("toberead=0x%08X, wFormat=0x%04X nTracks=0x%04X nDivision=0x%04X\n",
434  toberead, wmm->wFormat, wmm->nTracks, wmm->nDivision);
435 
436  /* MS doc says that the MIDI MCI time format must be put by default to the format
437  * stored in the MIDI file...
438  */
439  if (wmm->nDivision > 0x8000) {
440  /* eric.pouech@lemel.fr 98/11
441  * I did not check this very code (pulses are expressed as SMPTE sub-frames).
442  * In about 40 MB of MIDI files I have, none was SMPTE based...
443  * I'm just wondering if this is widely used :-). So, if someone has one of
444  * these files, I'd like to know about it.
445  */
446  FIXME("Handling SMPTE time in MIDI files has not been tested\n"
447  "Please report to comp.emulators.ms-windows.wine with MIDI file !\n");
448 
449  switch (HIBYTE(wmm->nDivision)) {
450  case 0xE8: wmm->dwMciTimeFormat = MCI_FORMAT_SMPTE_24; break; /* -24 */
451  case 0xE7: wmm->dwMciTimeFormat = MCI_FORMAT_SMPTE_25; break; /* -25 */
452  case 0xE3: wmm->dwMciTimeFormat = MCI_FORMAT_SMPTE_30DROP; break; /* -29 */ /* is the MCI constant correct ? */
453  case 0xE2: wmm->dwMciTimeFormat = MCI_FORMAT_SMPTE_30; break; /* -30 */
454  default:
455  WARN("Unsupported number of frames %d\n", -(char)HIBYTE(wmm->nDivision));
456  return MCIERR_INVALID_FILE;
457  }
458  switch (LOBYTE(wmm->nDivision)) {
459  case 4: /* MIDI Time Code */
460  case 8:
461  case 10:
462  case 80: /* SMPTE bit resolution */
463  case 100:
464  default:
465  WARN("Unsupported number of sub-frames %d\n", LOBYTE(wmm->nDivision));
466  return MCIERR_INVALID_FILE;
467  }
468  } else if (wmm->nDivision == 0) {
469  WARN("Number of division is 0, can't support that !!\n");
470  return MCIERR_INVALID_FILE;
471  } else {
473  }
474 
475  switch (wmm->wFormat) {
476  case 0:
477  if (wmm->nTracks != 1) {
478  WARN("Got type 0 file whose number of track is not 1. Setting it to 1\n");
479  wmm->nTracks = 1;
480  }
481  break;
482  case 1:
483  case 2:
484  break;
485  default:
486  WARN("Handling MIDI files which format = %d is not (yet) supported\n"
487  "Please report with MIDI file !\n", wmm->wFormat);
488  return MCIERR_INVALID_FILE;
489  }
490 
491  if (wmm->nTracks > 0x80) {
492  /* wTrackNr is 7 bits only */
493  FIXME("Truncating MIDI file with %u tracks\n", wmm->nTracks);
494  wmm->nTracks = 0x80;
495  }
496 
497  if ((wmm->tracks = HeapAlloc(GetProcessHeap(), 0, sizeof(MCI_MIDITRACK) * wmm->nTracks)) == NULL) {
498  return MCIERR_OUT_OF_MEMORY;
499  }
500 
501  toberead -= 3 * sizeof(WORD);
502  if (toberead > 0) {
503  TRACE("Size of MThd > 6, skipping %d extra bytes\n", toberead);
504  mmioSeek(wmm->hFile, toberead, SEEK_CUR);
505  }
506 
507  for (nt = 0; nt < wmm->nTracks; nt++) {
508  wmm->tracks[nt].wTrackNr = nt;
509  if (MIDI_mciReadMTrk(wmm, &wmm->tracks[nt]) != 0) {
510  WARN("Can't read 'MTrk' header\n");
511  return MCIERR_INVALID_FILE;
512  }
513  }
514 
515  wmm->dwTempo = 500000;
516 
517  return 0;
518 }
#define SEEK_CUR
Definition: util.h:63
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
#define MCI_FORMAT_SMPTE_25
Definition: mmsystem.h:706
#define LOBYTE(W)
Definition: jmemdos.c:487
#define WARN(fmt,...)
Definition: debug.h:112
#define HIBYTE(W)
Definition: jmemdos.c:486
static DWORD MIDI_mciReadMTrk(WINE_MCIMIDI *wmm, MCI_MIDITRACK *mmt)
Definition: mcimidi.c:316
#define MCI_FORMAT_SMPTE_30
Definition: mmsystem.h:707
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
IMAGE_NT_HEADERS nt
Definition: module.c:50
MCI_MIDITRACK * tracks
Definition: mcimidi.c:78
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2032
static DWORD MIDI_mciReadWord(WINE_MCIMIDI *wmm, LPWORD lpw)
Definition: mcimidi.c:193
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
#define FIXME(fmt,...)
Definition: debug.h:111
WORD nTracks
Definition: mcimidi.c:74
#define MCIERR_OUT_OF_MEMORY
Definition: mmsystem.h:574
WORD wFormat
Definition: mcimidi.c:73
#define SEEK_SET
Definition: jmemansi.c:26
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_FORMAT_SMPTE_24
Definition: mmsystem.h:705
WORD nDivision
Definition: mcimidi.c:75
char * HPSTR
Definition: mmsystem.h:1477
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
DWORD FOURCC
Definition: dmdls.h:25
#define MCI_FORMAT_SMPTE_30DROP
Definition: mmsystem.h:708
HMMIO hFile
Definition: mcimidi.c:66
WORD wTrackNr
Definition: mcimidi.c:55
#define NULL
Definition: types.h:112
DWORD dwMciTimeFormat
Definition: mcimidi.c:72
static DWORD MIDI_mciReadLong(WINE_MCIMIDI *wmm, LPDWORD lpdw)
Definition: mcimidi.c:209
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:732
DWORD dwTempo
Definition: mcimidi.c:77

Referenced by MIDI_mciOpen().

◆ MIDI_mciReadMTrk()

static DWORD MIDI_mciReadMTrk ( WINE_MCIMIDI wmm,
MCI_MIDITRACK mmt 
)
static

Definition at line 316 of file mcimidi.c.

317 {
318  DWORD toberead;
319  FOURCC fourcc;
320 
321  if (mmioRead(wmm->hFile, (HPSTR)&fourcc, (long)sizeof(FOURCC)) !=
322  (long)sizeof(FOURCC)) {
323  return MCIERR_INVALID_FILE;
324  }
325 
326  if (fourcc != mmioFOURCC('M', 'T', 'r', 'k')) {
327  WARN("Can't synchronize on 'MTrk' !\n");
328  return MCIERR_INVALID_FILE;
329  }
330 
331  if (MIDI_mciReadLong(wmm, &toberead) != 0) {
332  return MCIERR_INVALID_FILE;
333  }
334  mmt->dwFirst = mmioSeek(wmm->hFile, 0, SEEK_CUR); /* >= 0 */
335  mmt->dwLast = mmt->dwFirst + toberead;
336 
337  /* compute # of pulses in this track */
338  mmt->dwIndex = mmt->dwFirst;
339  mmt->dwEventPulse = 0;
340 
341  while (MIDI_mciReadNextEvent(wmm, mmt) == 0 && LOWORD(mmt->dwEventData) != 0x2FFF) {
342  char buf[1024];
343  WORD len;
344 
345  mmt->dwIndex += mmt->wEventLength;
346 
347  switch (LOWORD(mmt->dwEventData)) {
348  case 0x02FF:
349  case 0x03FF:
350  len = mmt->wEventLength - HIWORD(mmt->dwEventData);
351  if (len >= sizeof(buf)) {
352  WARN("Buffer for text is too small (%u are needed)\n", len);
353  len = sizeof(buf) - 1;
354  }
355  if (mmioRead(wmm->hFile, buf, len) == len) {
356  buf[len] = 0; /* end string in case */
357  switch (HIBYTE(LOWORD(mmt->dwEventData))) {
358  case 0x02:
359  if (wmm->lpstrCopyright) {
360  WARN("Two copyright notices (%s|%s)\n", debugstr_w(wmm->lpstrCopyright), buf);
362  }
363  len = MultiByteToWideChar( CP_ACP, 0, buf, -1, NULL, 0 );
364  wmm->lpstrCopyright = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
365  MultiByteToWideChar( CP_ACP, 0, buf, -1, wmm->lpstrCopyright, len );
366  break;
367  case 0x03:
368  if (wmm->lpstrName) {
369  WARN("Two names (%s|%s)\n", debugstr_w(wmm->lpstrName), buf);
370  HeapFree(GetProcessHeap(), 0, wmm->lpstrName);
371  } /* last name or name from last track wins */
372  len = MultiByteToWideChar( CP_ACP, 0, buf, -1, NULL, 0 );
373  wmm->lpstrName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
374  MultiByteToWideChar( CP_ACP, 0, buf, -1, wmm->lpstrName, len );
375  break;
376  }
377  }
378  break;
379  }
380  }
381  mmt->dwLength = mmt->dwEventPulse;
382 
383  TRACE("Track %u has %u bytes and %u pulses\n", mmt->wTrackNr, toberead, mmt->dwLength);
384 
385  /* reset track data */
386  mmt->wStatus = 1; /* ok, playing */
387  mmt->dwIndex = mmt->dwFirst;
388  mmt->dwEventPulse = 0;
389 
390  if (mmioSeek(wmm->hFile, 0, SEEK_CUR) != mmt->dwLast) {
391  WARN("Ouch, out of sync seek=%u track=%u\n",
392  mmioSeek(wmm->hFile, 0, SEEK_CUR), mmt->dwLast);
393  /* position at end of this track, to be ready to read next track */
394  mmioSeek(wmm->hFile, mmt->dwLast, SEEK_SET);
395  }
396 
397  return 0;
398 }
WORD wEventLength
Definition: mcimidi.c:54
#define SEEK_CUR
Definition: util.h:63
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
DWORD dwLength
Definition: mcimidi.c:51
DWORD dwLast
Definition: mcimidi.c:49
WORD wStatus
Definition: mcimidi.c:55
#define CP_ACP
Definition: compat.h:109
#define WARN(fmt,...)
Definition: debug.h:112
#define HIBYTE(W)
Definition: jmemdos.c:486
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
DWORD dwFirst
Definition: mcimidi.c:48
#define debugstr_w
Definition: kernel32.h:32
static DWORD MIDI_mciReadNextEvent(WINE_MCIMIDI *wmm, MCI_MIDITRACK *mmt)
Definition: mcimidi.c:245
DWORD dwEventData
Definition: mcimidi.c:53
#define SEEK_SET
Definition: jmemansi.c:26
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
DWORD dwEventPulse
Definition: mcimidi.c:52
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
LPWSTR lpstrCopyright
Definition: mcimidi.c:68
LPWSTR lpstrName
Definition: mcimidi.c:69
char * HPSTR
Definition: mmsystem.h:1477
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
GLenum GLsizei len
Definition: glext.h:6722
DWORD FOURCC
Definition: dmdls.h:25
DWORD dwIndex
Definition: mcimidi.c:50
HMMIO hFile
Definition: mcimidi.c:66
WORD wTrackNr
Definition: mcimidi.c:55
#define NULL
Definition: types.h:112
#define MultiByteToWideChar
Definition: compat.h:110
#define HIWORD(l)
Definition: typedefs.h:247
#define LOWORD(l)
Definition: pedump.c:82
#define HeapFree(x, y, z)
Definition: compat.h:594
static DWORD MIDI_mciReadLong(WINE_MCIMIDI *wmm, LPDWORD lpdw)
Definition: mcimidi.c:209
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:732

Referenced by MIDI_mciReadMThd().

◆ MIDI_mciReadNextEvent()

static DWORD MIDI_mciReadNextEvent ( WINE_MCIMIDI wmm,
MCI_MIDITRACK mmt 
)
static

Definition at line 245 of file mcimidi.c.

246 {
247  BYTE b1, b2 = 0, b3;
248  WORD hw = 0;
249  DWORD evtPulse;
250  DWORD evtLength;
251  DWORD tmp;
252 
253  if (mmioSeek(wmm->hFile, mmt->dwIndex, SEEK_SET) != mmt->dwIndex) {
254  WARN("Can't seek at %08X\n", mmt->dwIndex);
255  return MCIERR_INVALID_FILE;
256  }
257  evtLength = MIDI_mciReadVaryLen(wmm, &evtPulse) + 1; /* > 0 */
258  MIDI_mciReadByte(wmm, &b1);
259  switch (b1) {
260  case 0xF0:
261  case 0xF7:
262  evtLength += MIDI_mciReadVaryLen(wmm, &tmp);
263  evtLength += tmp;
264  break;
265  case 0xFF:
266  MIDI_mciReadByte(wmm, &b2); evtLength++;
267 
268  evtLength += MIDI_mciReadVaryLen(wmm, &tmp);
269  if (evtLength >= 0x10000u) {
270  /* this limitation shouldn't be a problem */
271  WARN("Ouch !! Implementation limitation to 64k bytes for a MIDI event is overflowed\n");
272  hw = 0xFFFF;
273  } else {
274  hw = LOWORD(evtLength);
275  }
276  evtLength += tmp;
277  break;
278  default:
279  if (b1 & 0x80) { /* use running status ? */
280  mmt->wLastCommand = b1;
281  MIDI_mciReadByte(wmm, &b2); evtLength++;
282  } else {
283  b2 = b1;
284  b1 = mmt->wLastCommand;
285  }
286  switch ((b1 >> 4) & 0x07) {
287  case 0: case 1: case 2: case 3: case 6:
288  MIDI_mciReadByte(wmm, &b3); evtLength++;
289  hw = b3;
290  break;
291  case 4: case 5:
292  break;
293  case 7:
294  WARN("Strange indeed b1=0x%02x\n", b1);
295  }
296  break;
297  }
298  if (mmt->dwIndex + evtLength > mmt->dwLast)
299  return MCIERR_INTERNAL;
300 
301  mmt->dwEventPulse += evtPulse;
302  mmt->dwEventData = (hw << 16) + (b2 << 8) + b1;
303  mmt->wEventLength = evtLength;
304 
305  /*
306  TRACE("[%u] => pulse=%08x(%08x), data=%08x, length=%u\n",
307  mmt->wTrackNr, mmt->dwEventPulse, evtPulse,
308  mmt->dwEventData, mmt->wEventLength);
309  */
310  return 0;
311 }
WORD wEventLength
Definition: mcimidi.c:54
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
DWORD dwLast
Definition: mcimidi.c:49
#define WARN(fmt,...)
Definition: debug.h:112
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
static WORD MIDI_mciReadVaryLen(WINE_MCIMIDI *wmm, LPDWORD lpdw)
Definition: mcimidi.c:225
WORD wLastCommand
Definition: mcimidi.c:55
static CRYPT_DATA_BLOB b1[]
Definition: msg.c:573
DWORD dwEventData
Definition: mcimidi.c:53
#define SEEK_SET
Definition: jmemansi.c:26
DWORD dwEventPulse
Definition: mcimidi.c:52
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCIERR_INTERNAL
Definition: mmsystem.h:587
unsigned char BYTE
Definition: xxhash.c:193
static CRYPT_DATA_BLOB b3[]
Definition: msg.c:592
DWORD dwIndex
Definition: mcimidi.c:50
HMMIO hFile
Definition: mcimidi.c:66
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:582
static DWORD MIDI_mciReadByte(WINE_MCIMIDI *wmm, BYTE *lpbyt)
Definition: mcimidi.c:178
#define LOWORD(l)
Definition: pedump.c:82

Referenced by MIDI_mciReadMTrk(), and MIDI_player().

◆ MIDI_mciReadVaryLen()

static WORD MIDI_mciReadVaryLen ( WINE_MCIMIDI wmm,
LPDWORD  lpdw 
)
static

Definition at line 225 of file mcimidi.c.

226 {
227  BYTE byte;
228  DWORD value = 0;
229  WORD len = 0;
230 
231  do {
232  if (MIDI_mciReadByte(wmm, &byte) != 0) {
233  return 0;
234  }
235  value = (value << 7) + (byte & 0x7F);
236  len++;
237  } while (byte & 0x80);
238  *lpdw = value;
239  return len;
240 }
Definition: pdh_main.c:93
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLsizei len
Definition: glext.h:6722
GLsizei const GLfloat * value
Definition: glext.h:6069
unsigned char BYTE
Definition: xxhash.c:193
#define byte(x, n)
Definition: tomcrypt.h:118
static DWORD MIDI_mciReadByte(WINE_MCIMIDI *wmm, BYTE *lpbyt)
Definition: mcimidi.c:178

Referenced by MIDI_mciReadNextEvent().

◆ MIDI_mciReadWord()

static DWORD MIDI_mciReadWord ( WINE_MCIMIDI wmm,
LPWORD  lpw 
)
static

Definition at line 193 of file mcimidi.c.

194 {
195  BYTE hibyte, lobyte;
197 
198  if (MIDI_mciReadByte(wmm, &hibyte) == 0 &&
199  MIDI_mciReadByte(wmm, &lobyte) == 0) {
200  *lpw = ((WORD)hibyte << 8) + lobyte;
201  ret = 0;
202  }
203  return ret;
204 }
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
unsigned char BYTE
Definition: xxhash.c:193
static DWORD MIDI_mciReadByte(WINE_MCIMIDI *wmm, BYTE *lpbyt)
Definition: mcimidi.c:178

Referenced by MIDI_mciReadLong(), MIDI_mciReadMThd(), and MIDI_player().

◆ MIDI_mciResume()

static DWORD MIDI_mciResume ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 1215 of file mcimidi.c.

1216 {
1217  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
1218 
1219  if (wmm->dwStatus == MCI_MODE_PAUSE) {
1220  wmm->wStartedPlaying = FALSE;
1221  wmm->dwStatus = MCI_MODE_PLAY;
1222  }
1223  if ((dwFlags & MCI_NOTIFY) && lpParms)
1225  return 0;
1226 }
#define FALSE
Definition: types.h:117
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
#define TRACE(s)
Definition: solgame.cpp:4
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
WORD dwStatus
Definition: mcimidi.c:71
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
WORD wStartedPlaying
Definition: mcimidi.c:76
#define MCI_NOTIFY
Definition: mmsystem.h:729

Referenced by ensurePlayerThread(), and MCIMIDI_DriverProc().

◆ MIDI_mciSeek()

static DWORD MIDI_mciSeek ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_SEEK_PARMS  lpParms 
)
static

Definition at line 1545 of file mcimidi.c.

1546 {
1547  DWORD position;
1548 
1549  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
1550 
1551  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1552 
1554  if (!position) return MCIERR_MISSING_PARAMETER;
1555  if (position&(position-1)) return MCIERR_FLAGS_NOT_COMPATIBLE;
1556 
1557  MIDI_mciStop(wmm, MCI_WAIT, 0);
1558 
1559  if (dwFlags & MCI_TO) { /* FIXME: compare with length */
1560  wmm->dwPositionMS = MIDI_ConvertTimeFormatToMS(wmm, lpParms->dwTo);
1561  } else if (dwFlags & MCI_SEEK_TO_START) {
1562  wmm->dwPositionMS = 0;
1563  } else {
1564  wmm->dwPositionMS = 0xFFFFFFFF; /* FIXME */
1565  }
1566 
1567  TRACE("Seeking to position=%u ms\n", wmm->dwPositionMS);
1568 
1569  if (dwFlags & MCI_NOTIFY)
1571 
1572  return 0;
1573 }
#define MCI_WAIT
Definition: mmsystem.h:730
static DWORD MIDI_mciStop(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcimidi.c:761
#define MCIERR_FLAGS_NOT_COMPATIBLE
Definition: mmsystem.h:593
DWORD dwPositionMS
Definition: mcimidi.c:80
#define MCIERR_MISSING_PARAMETER
Definition: mmsystem.h:583
#define TRACE(s)
Definition: solgame.cpp:4
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD_PTR dwCallback
Definition: mmsystem.h:1543
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCI_SEEK_TO_END
Definition: mmsystem.h:741
#define MCI_SEEK_TO_START
Definition: mmsystem.h:740
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
#define NULL
Definition: types.h:112
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
static DWORD MIDI_ConvertTimeFormatToMS(WINE_MCIMIDI *wmm, DWORD val)
Definition: mcimidi.c:556
#define MCI_TO
Definition: mmsystem.h:732

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciSet()

static DWORD MIDI_mciSet ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_SEQ_SET_PARMS  lpParms 
)
static

Definition at line 1231 of file mcimidi.c.

1232 {
1233  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
1234 
1235  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1236 
1237  if (dwFlags & MCI_SET_TIME_FORMAT) {
1238  switch (lpParms->dwTimeFormat) {
1240  TRACE("MCI_FORMAT_MILLISECONDS !\n");
1242  break;
1243  case MCI_FORMAT_SMPTE_24:
1244  TRACE("MCI_FORMAT_SMPTE_24 !\n");
1246  break;
1247  case MCI_FORMAT_SMPTE_25:
1248  TRACE("MCI_FORMAT_SMPTE_25 !\n");
1250  break;
1251  case MCI_FORMAT_SMPTE_30:
1252  TRACE("MCI_FORMAT_SMPTE_30 !\n");
1254  break;
1255  default:
1256  WARN("Bad time format %u!\n", lpParms->dwTimeFormat);
1257  return MCIERR_BAD_TIME_FORMAT;
1258  }
1259  }
1260  if (dwFlags & MCI_SET_VIDEO) {
1261  TRACE("No support for video !\n");
1263  }
1264  if (dwFlags & MCI_SET_DOOR_OPEN) {
1265  TRACE("No support for door open !\n");
1267  }
1268  if (dwFlags & MCI_SET_DOOR_CLOSED) {
1269  TRACE("No support for door close !\n");
1271  }
1272  if (dwFlags & MCI_SET_AUDIO) {
1273  if (dwFlags & MCI_SET_ON) {
1274  TRACE("MCI_SET_ON audio !\n");
1275  } else if (dwFlags & MCI_SET_OFF) {
1276  TRACE("MCI_SET_OFF audio !\n");
1277  } else {
1278  WARN("MCI_SET_AUDIO without SET_ON or SET_OFF\n");
1279  return MCIERR_BAD_INTEGER;
1280  }
1281 
1282  switch (lpParms->dwAudio)
1283  {
1284  case MCI_SET_AUDIO_ALL: TRACE("MCI_SET_AUDIO_ALL !\n"); break;
1285  case MCI_SET_AUDIO_LEFT: TRACE("MCI_SET_AUDIO_LEFT !\n"); break;
1286  case MCI_SET_AUDIO_RIGHT: TRACE("MCI_SET_AUDIO_RIGHT !\n"); break;
1287  default: WARN("Unknown audio channel %u\n", lpParms->dwAudio); break;
1288  }
1289  }
1290 
1292  TRACE("MCI_SEQ_SET_MASTER !\n");
1293  if (dwFlags & MCI_SEQ_SET_SLAVE)
1294  TRACE("MCI_SEQ_SET_SLAVE !\n");
1296  TRACE("MCI_SEQ_SET_OFFSET !\n");
1297  if (dwFlags & MCI_SEQ_SET_PORT) {
1298  TRACE("MCI_SEQ_SET_PORT = %d\n", lpParms->dwPort);
1299  if ((UINT16)lpParms->dwPort != (UINT16)MIDI_MAPPER &&
1300  (UINT16)lpParms->dwPort >= midiOutGetNumDevs())
1301  /* FIXME: input/output port distinction? */
1303  /* FIXME: Native manages to swap the device while playing! */
1304  wmm->wPort = lpParms->dwPort;
1305  }
1306  if (dwFlags & MCI_SEQ_SET_TEMPO)
1307  TRACE("MCI_SEQ_SET_TEMPO !\n");
1308  if (dwFlags & MCI_NOTIFY)
1310  return 0;
1311 }
#define MCI_FORMAT_SMPTE_25
Definition: mmsystem.h:706
#define MIDI_MAPPER
Definition: mmsystem.h:253
DWORD_PTR dwCallback
Definition: mmsystem.h:2645
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
#define WARN(fmt,...)
Definition: debug.h:112
#define MCI_SET_OFF
Definition: mmsystem.h:778
#define MCI_SET_AUDIO
Definition: mmsystem.h:775
#define MCI_SET_DOOR_CLOSED
Definition: mmsystem.h:773
#define MCI_FORMAT_SMPTE_30
Definition: mmsystem.h:707
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
#define MCI_SEQ_SET_TEMPO
Definition: mmsystem.h:860
#define MCI_SEQ_SET_PORT
Definition: mmsystem.h:861
#define MCI_SEQ_SET_SLAVE
Definition: mmsystem.h:862
#define TRACE(s)
Definition: solgame.cpp:4
#define MCI_SET_ON
Definition: mmsystem.h:777
#define MCIERR_BAD_INTEGER
Definition: mmsystem.h:580
#define MCI_SET_TIME_FORMAT
Definition: mmsystem.h:774
#define MCI_SET_AUDIO_LEFT
Definition: mmsystem.h:780
#define MCIERR_BAD_TIME_FORMAT
Definition: mmsystem.h:601
#define MCI_FORMAT_SMPTE_24
Definition: mmsystem.h:705
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
#define MCI_SET_AUDIO_RIGHT
Definition: mmsystem.h:781
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCI_SEQ_SET_MASTER
Definition: mmsystem.h:863
#define MCI_SEQ_SET_OFFSET
Definition: mmsystem.h:864
#define MCI_SET_VIDEO
Definition: mmsystem.h:776
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
unsigned short UINT16
#define NULL
Definition: types.h:112
DWORD dwMciTimeFormat
Definition: mcimidi.c:72
#define MCI_SET_AUDIO_ALL
Definition: mmsystem.h:779
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_SEQ_PORT_NONEXISTENT
Definition: mmsystem.h:633
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
UINT WINAPI midiOutGetNumDevs(void)
Definition: winmm.c:809
#define MCI_SET_DOOR_OPEN
Definition: mmsystem.h:772

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciStatus()

static DWORD MIDI_mciStatus ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_STATUS_PARMS  lpParms 
)
static

Definition at line 1316 of file mcimidi.c.

1317 {
1318  DWORD ret = 0;
1319 
1320  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
1321 
1322  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1323 
1324  if (dwFlags & MCI_STATUS_ITEM) {
1325  switch (lpParms->dwItem) {
1327  /* FIXME in Format 2 */
1328  lpParms->dwReturn = 1;
1329  TRACE("MCI_STATUS_CURRENT_TRACK => %lu\n", lpParms->dwReturn);
1330  break;
1331  case MCI_STATUS_LENGTH:
1332  if ((dwFlags & MCI_TRACK) && wmm->wFormat == 2) {
1333  if (lpParms->dwTrack >= wmm->nTracks)
1334  return MCIERR_OUTOFRANGE;
1335  /* FIXME: this is wrong if there is a tempo change inside the file */
1336  lpParms->dwReturn = MIDI_ConvertPulseToMS(wmm, wmm->tracks[lpParms->dwTrack].dwLength);
1337  } else {
1338  lpParms->dwReturn = MIDI_GetMThdLengthMS(wmm);
1339  }
1340  lpParms->dwReturn = MIDI_ConvertMSToTimeFormat(wmm, lpParms->dwReturn);
1341  /* FIXME: ret = MCI_COLONIZED4_RETURN if SMPTE */
1342  TRACE("MCI_STATUS_LENGTH => %lu\n", lpParms->dwReturn);
1343  break;
1344  case MCI_STATUS_MODE:
1345  TRACE("MCI_STATUS_MODE => %u\n", wmm->dwStatus);
1346  lpParms->dwReturn = MAKEMCIRESOURCE(wmm->dwStatus, wmm->dwStatus);
1348  break;
1350  TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE\n");
1351  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
1353  break;
1355  lpParms->dwReturn = (wmm->wFormat == 2) ? wmm->nTracks : 1;
1356  TRACE("MCI_STATUS_NUMBER_OF_TRACKS => %lu\n", lpParms->dwReturn);
1357  break;
1358  case MCI_STATUS_POSITION:
1359  /* FIXME: check MCI_TRACK == 1 if set */
1360  lpParms->dwReturn = MIDI_ConvertMSToTimeFormat(wmm,
1361  (dwFlags & MCI_STATUS_START) ? 0 : wmm->dwPositionMS);
1362  /* FIXME: ret = MCI_COLONIZED4_RETURN if SMPTE */
1363  TRACE("MCI_STATUS_POSITION %s => %lu\n",
1364  (dwFlags & MCI_STATUS_START) ? "start" : "current", lpParms->dwReturn);
1365  break;
1366  case MCI_STATUS_READY:
1367  lpParms->dwReturn = (wmm->dwStatus == MCI_MODE_NOT_READY) ?
1370  TRACE("MCI_STATUS_READY = %u\n", LOWORD(lpParms->dwReturn));
1371  break;
1374  TRACE("MCI_STATUS_TIME_FORMAT => %u\n", LOWORD(lpParms->dwReturn));
1376  break;
1378  TRACE("MCI_SEQ_STATUS_DIVTYPE !\n");
1379  if (wmm->nDivision > 0x8000) {
1380  switch (HIBYTE(wmm->nDivision)) {
1381  case 0xE8: lpParms->dwReturn = MCI_SEQ_DIV_SMPTE_24; break; /* -24 */
1382  case 0xE7: lpParms->dwReturn = MCI_SEQ_DIV_SMPTE_25; break; /* -25 */
1383  case 0xE3: lpParms->dwReturn = MCI_SEQ_DIV_SMPTE_30DROP; break; /* -29 */ /* is the MCI constant correct ? */
1384  case 0xE2: lpParms->dwReturn = MCI_SEQ_DIV_SMPTE_30; break; /* -30 */
1385  default: FIXME("There is a bad bad programmer\n");
1386  }
1387  } else {
1388  lpParms->dwReturn = MCI_SEQ_DIV_PPQN;
1389  }
1390  lpParms->dwReturn = MAKEMCIRESOURCE(lpParms->dwReturn,lpParms->dwReturn);
1392  break;
1393  case MCI_SEQ_STATUS_MASTER:
1394  TRACE("MCI_SEQ_STATUS_MASTER !\n");
1397  break;
1398  case MCI_SEQ_STATUS_SLAVE:
1399  TRACE("MCI_SEQ_STATUS_SLAVE !\n");
1402  break;
1403  case MCI_SEQ_STATUS_OFFSET:
1404  TRACE("MCI_SEQ_STATUS_OFFSET !\n");
1405  lpParms->dwReturn = 0;
1406  break;
1407  case MCI_SEQ_STATUS_PORT:
1408  if (wmm->wPort != (UINT16)MIDI_MAPPER)
1409  lpParms->dwReturn = wmm->wPort;
1410  else {
1413  }
1414  TRACE("MCI_SEQ_STATUS_PORT (%u) => %d\n", wmm->wDevID, wmm->wPort);
1415  break;
1416  case MCI_SEQ_STATUS_TEMPO:
1417  TRACE("MCI_SEQ_STATUS_TEMPO !\n");
1418  lpParms->dwReturn = wmm->dwTempo;
1419  break;
1420  default:
1421  FIXME("Unknown command %08X !\n", lpParms->dwItem);
1423  }
1424  } else {
1425  return MCIERR_MISSING_PARAMETER;
1426  }
1427  if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
1429  return ret;
1430 }
#define MCI_SEQ_DIV_PPQN
Definition: mmsystem.h:841
static DWORD MIDI_ConvertPulseToMS(WINE_MCIMIDI *wmm, DWORD pulse)
Definition: mcimidi.c:523
#define MCI_SEQ_DIV_SMPTE_30DROP
Definition: mmsystem.h:844
#define MCI_STATUS_ITEM
Definition: mmsystem.h:742
DWORD dwLength
Definition: mcimidi.c:51
#define MIDI_MAPPER
Definition: mmsystem.h:253
#define TRUE
Definition: types.h:120
#define MCI_STATUS_NUMBER_OF_TRACKS
Definition: mmsystem.h:746
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
#define HIBYTE(W)
Definition: jmemdos.c:486
#define MCI_SEQ_DIV_SMPTE_24
Definition: mmsystem.h:842
#define MCI_RESOURCE_RETURNED
Definition: mmddk.h:369
#define MCI_SEQ_STATUS_TEMPO
Definition: mmsystem.h:852
#define MAKEMCIRESOURCE(wRet, wRes)
Definition: mmddk.h:388
#define MCI_STATUS_POSITION
Definition: mmsystem.h:745
MCI_MIDITRACK * tracks
Definition: mcimidi.c:78
DWORD_PTR dwReturn
Definition: mmsystem.h:1567
#define MCI_SEQ_NONE
Definition: mmsystem.h:850
#define MCI_SEQ_STATUS_MASTER
Definition: mmsystem.h:855
#define FALSE
Definition: types.h:117
static DWORD MIDI_GetMThdLengthMS(WINE_MCIMIDI *wmm)
Definition: mcimidi.c:639
#define FIXME(fmt,...)
Definition: debug.h:111
#define MCI_SEQ_NONE_S
Definition: mmddk.h:366
DWORD dwPositionMS
Definition: mcimidi.c:80
#define MCI_SEQ_STATUS_PORT
Definition: mmsystem.h:853
#define MCIERR_MISSING_PARAMETER
Definition: mmsystem.h:583
WORD nTracks
Definition: mcimidi.c:74
WORD wFormat
Definition: mcimidi.c:73
#define TRACE(s)
Definition: solgame.cpp:4
#define MCI_STATUS_LENGTH
Definition: mmsystem.h:744
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_STATUS_MODE
Definition: mmsystem.h:747
#define MCI_STATUS_START
Definition: mmsystem.h:743
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
WORD nDivision
Definition: mcimidi.c:75
int ret
#define MCI_SEQ_STATUS_DIVTYPE
Definition: mmsystem.h:857
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCI_STATUS_CURRENT_TRACK
Definition: mmsystem.h:751
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
#define MCI_FALSE
Definition: mmddk.h:340
DWORD_PTR dwCallback
Definition: mmsystem.h:1566
#define MCI_SEQ_MAPPER_S
Definition: mmddk.h:361
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
#define MCI_SEQ_STATUS_OFFSET
Definition: mmsystem.h:856
unsigned short UINT16
#define NULL
Definition: types.h:112
#define MCI_SEQ_FILE
Definition: mmsystem.h:847
#define MCI_SEQ_DIV_SMPTE_30
Definition: mmsystem.h:845
#define MCI_TRACK
Definition: mmsystem.h:733
#define MCI_TRUE
Definition: mmddk.h:341
#define MCI_SEQ_DIV_SMPTE_25
Definition: mmsystem.h:843
#define HRESULT_CODE(hr)
Definition: winerror.h:76
WORD dwStatus
Definition: mcimidi.c:71
#define MCI_SEQ_STATUS_SLAVE
Definition: mmsystem.h:854
#define MCI_SEQ_FILE_S
Definition: mmddk.h:362
DWORD dwMciTimeFormat
Definition: mcimidi.c:72
#define MCI_STATUS_TIME_FORMAT
Definition: mmsystem.h:749
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCI_STATUS_MEDIA_PRESENT
Definition: mmsystem.h:748
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define LOWORD(l)
Definition: pedump.c:82
static DWORD MIDI_ConvertMSToTimeFormat(WINE_MCIMIDI *wmm, DWORD _val)
Definition: mcimidi.c:591
#define MCI_FORMAT_RETURN_BASE
Definition: mmddk.h:343
DWORD dwTempo
Definition: mcimidi.c:77
#define MCI_STATUS_READY
Definition: mmsystem.h:750

Referenced by MCIMIDI_DriverProc().

◆ MIDI_mciStop()

static DWORD MIDI_mciStop ( WINE_MCIMIDI wmm,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 761 of file mcimidi.c.

762 {
763  DWORD dwRet = 0;
764 
765  TRACE("(%d, %08X, %p);\n", wmm->wDevID, dwFlags, lpParms);
766 
767  if (wmm->dwStatus != MCI_MODE_STOP) {
769  if (old) mciDriverNotify(old, wmm->wDevID, MCI_NOTIFY_ABORTED);
770  }
771 
772  if (wmm->dwStatus != MCI_MODE_STOP) {
773  int oldstat = wmm->dwStatus;
774 
776  if (oldstat == MCI_MODE_PAUSE)
777  dwRet = midiOutReset((HMIDIOUT)wmm->hMidi);
778 
779  if (wmm->hThread)
781  }
782 
783  /* sanity reset */
784  wmm->dwStatus = MCI_MODE_STOP;
785 
786  if ((dwFlags & MCI_NOTIFY) && lpParms && MMSYSERR_NOERROR==dwRet)
788  return dwRet;
789 }
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define MCI_NOTIFY_ABORTED
Definition: mmsystem.h:727
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2056
HMIDI hMidi
Definition: mcimidi.c:62
UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
Definition: winmm.c:1073
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
unsigned long DWORD
Definition: ntddk_ex.h:95
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
Definition: mcimidi.c:164
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
#define NULL
Definition: types.h:112
WORD dwStatus
Definition: mcimidi.c:71
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define INFINITE
Definition: serial.h:102
HANDLE hCallback
Definition: mcimidi.c:64
HANDLE hThread
Definition: mcimidi.c:65

Referenced by MCIMIDI_DriverProc(), MIDI_mciClose(), MIDI_mciPlay(), and MIDI_mciSeek().

◆ MIDI_player()

static DWORD MIDI_player ( WINE_MCIMIDI wmm,
DWORD  dwFlags 
)
static

Definition at line 857 of file mcimidi.c.

858 {
859  DWORD dwRet;
860  WORD doPlay, nt;
861  MCI_MIDITRACK* mmt;
862  DWORD hiPulse, dwStartMS = wmm->dwPositionMS;
863  HANDLE oldcb = NULL;
864 
865  /* init tracks */
866  for (nt = 0; nt < wmm->nTracks; nt++) {
867  mmt = &wmm->tracks[nt];
868 
869  mmt->wStatus = 1; /* ok, playing */
870  mmt->dwIndex = mmt->dwFirst;
871  if (wmm->wFormat == 2 && nt > 0) {
872  mmt->dwEventPulse = wmm->tracks[nt - 1].dwLength;
873  } else {
874  mmt->dwEventPulse = 0;
875  }
876  MIDI_mciReadNextEvent(wmm, mmt); /* FIXME == 0 */
877  }
878 
879  dwRet = midiOutOpen((LPHMIDIOUT)&wmm->hMidi, wmm->wPort, 0L, 0L, CALLBACK_NULL);
880  if (dwRet != MMSYSERR_NOERROR) {
881  return mmr2mci(dwRet);
882  }
883 
884  wmm->dwPulse = 0;
885  wmm->dwTempo = 500000;
886  wmm->dwPositionMS = 0;
887  wmm->wStartedPlaying = FALSE;
888 
889  while (wmm->dwStatus != MCI_MODE_STOP && wmm->dwStatus != MCI_MODE_NOT_READY) {
890  /* it seems that in case of multi-threading, gcc is optimizing just a little bit
891  * too much. Tell gcc not to optimize status value using volatile.
892  */
893  while (((volatile WINE_MCIMIDI*)wmm)->dwStatus == MCI_MODE_PAUSE);
894 
895  doPlay = (wmm->dwPositionMS >= dwStartMS && wmm->dwPositionMS <= wmm->dwEndMS);
896 
897  TRACE("wmm->dwStatus=%d, doPlay=%c\n", wmm->dwStatus, doPlay ? 'T' : 'F');
898 
899  if ((mmt = MIDI_mciFindNextEvent(wmm, &hiPulse)) == NULL)
900  break; /* no more event on tracks */
901 
902  /* if starting playing, then set StartTicks to the value it would have had
903  * if play had started at position 0
904  */
905  if (doPlay && !wmm->wStartedPlaying) {
907  wmm->wStartedPlaying = TRUE;
908  TRACE("Setting dwStartTicks to %u\n", wmm->dwStartTicks);
909  }
910 
911  if (hiPulse > wmm->dwPulse) {
912  wmm->dwPositionMS += MIDI_ConvertPulseToMS(wmm, hiPulse - wmm->dwPulse);
913  if (doPlay) {
914  DWORD togo = wmm->dwStartTicks + wmm->dwPositionMS;
915  DWORD tc = GetTickCount();
916 
917  TRACE("Pulses hi=0x%08x <> cur=0x%08x\n", hiPulse, wmm->dwPulse);
918  TRACE("Wait until %u => %u ms\n",
919  tc - wmm->dwStartTicks, togo - wmm->dwStartTicks);
920  if (tc < togo)
921  Sleep(togo - tc);
922  }
923  wmm->dwPulse = hiPulse;
924  }
925 
926  switch (LOBYTE(LOWORD(mmt->dwEventData))) {
927  case 0xF0:
928  case 0xF7: /* sysex events */
929  {
930  FIXME("Not handling SysEx events (yet)\n");
931  }
932  break;
933  case 0xFF:
934  /* position after meta data header */
935  mmioSeek(wmm->hFile, mmt->dwIndex + HIWORD(mmt->dwEventData), SEEK_SET);
936  switch (HIBYTE(LOWORD(mmt->dwEventData))) {
937  case 0x00: /* 16-bit sequence number */
938  if (TRACE_ON(mcimidi)) {
939  WORD twd;
940 
941  MIDI_mciReadWord(wmm, &twd); /* == 0 */
942  TRACE("Got sequence number %u\n", twd);
943  }
944  break;
945  case 0x01: /* any text */
946  case 0x02: /* Copyright Message text */
947  case 0x03: /* Sequence/Track Name text */
948  case 0x04: /* Instrument Name text */
949  case 0x05: /* Lyric text */
950  case 0x06: /* Marker text */
951  case 0x07: /* Cue-point text */
952  if (TRACE_ON(mcimidi)) {
953  char buf[1024];
954  WORD len = mmt->wEventLength - HIWORD(mmt->dwEventData);
955  static const char* const info[8] = {"", "Text", "Copyright", "Seq/Trk name",
956  "Instrument", "Lyric", "Marker", "Cue-point"};
957  WORD idx = HIBYTE(LOWORD(mmt->dwEventData));
958 
959  if (len >= sizeof(buf)) {
960  WARN("Buffer for text is too small (%u are needed)\n", len);
961  len = sizeof(buf) - 1;
962  }
963  if (mmioRead(wmm->hFile, buf, len) == len) {
964  buf[len] = 0; /* end string in case */
965  TRACE("%s => \"%s\"\n", (idx < 8 ) ? info[idx] : "", buf);
966  } else {
967  WARN("Couldn't read data for %s\n", (idx < 8) ? info[idx] : "");
968  }
969  }
970  break;
971  case 0x20:
972  /* MIDI channel (cc) */
973  if (FIXME_ON(mcimidi)) {
974  BYTE bt;
975 
976  MIDI_mciReadByte(wmm, &bt); /* == 0 */
977  FIXME("NIY: MIDI channel=%u, track=%u\n", bt, mmt->wTrackNr);
978  }
979  break;
980  case 0x21:
981  /* MIDI port (pp) */
982  if (FIXME_ON(mcimidi)) {
983  BYTE bt;
984 
985  MIDI_mciReadByte(wmm, &bt); /* == 0 */
986  FIXME("NIY: MIDI port=%u, track=%u\n", bt, mmt->wTrackNr);
987  }
988  break;
989  case 0x2F: /* end of track */
990  mmt->wStatus = 0;
991  break;
992  case 0x51:/* set tempo */
993  /* Tempo is expressed in -seconds per midi quarter note
994  * for format 1 MIDI files, this can only be present on track #0
995  */
996  if (mmt->wTrackNr != 0 && wmm->wFormat == 1) {
997  WARN("For format #1 MIDI files, tempo can only be changed on track #0 (%u)\n", mmt->wTrackNr);
998  } else {
999  BYTE tbt;
1000  DWORD value = 0;
1001 
1002  MIDI_mciReadByte(wmm, &tbt); value = ((DWORD)tbt) << 16;
1003  MIDI_mciReadByte(wmm, &tbt); value |= ((DWORD)tbt) << 8;
1004  MIDI_mciReadByte(wmm, &tbt); value |= ((DWORD)tbt) << 0;
1005  TRACE("Setting tempo to %d (BPM=%d)\n", wmm->dwTempo, (value) ? (60000000 / value) : 0);
1006  wmm->dwTempo = value;
1007  }
1008  break;
1009  case 0x54: /* (hour) (min) (second) (frame) (fractional-frame) - SMPTE track start */
1010  if (mmt->wTrackNr != 0 && wmm->wFormat == 1) {
1011  WARN("For format #1 MIDI files, SMPTE track start can only be expressed on track #0 (%u)\n", mmt->wTrackNr);
1012  } if (mmt->dwEventPulse != 0) {
1013  WARN("SMPTE track start can only be expressed at start of track (%u)\n", mmt->dwEventPulse);
1014  } else {
1015  BYTE h, m, s, f, ff;
1016 
1017  MIDI_mciReadByte(wmm, &h);
1018  MIDI_mciReadByte(wmm, &m);
1019  MIDI_mciReadByte(wmm, &s);
1020  MIDI_mciReadByte(wmm, &f);
1021  MIDI_mciReadByte(wmm, &ff);
1022  FIXME("NIY: SMPTE track start %u:%u:%u %u.%u\n", h, m, s, f, ff);
1023  }
1024  break;
1025  case 0x58: /* file rhythm */
1026  if (TRACE_ON(mcimidi)) {
1027  BYTE num, den, cpmc, _32npqn;
1028 
1029  MIDI_mciReadByte(wmm, &num);
1030  MIDI_mciReadByte(wmm, &den); /* to notate e.g. 6/8 */
1031  MIDI_mciReadByte(wmm, &cpmc); /* number of MIDI clocks per metronome click */
1032  MIDI_mciReadByte(wmm, &_32npqn); /* number of notated 32nd notes per MIDI quarter note */
1033 
1034  TRACE("%u/%u, clock per metronome click=%u, 32nd notes by 1/4 note=%u\n", num, 1 << den, cpmc, _32npqn);
1035  }
1036  break;
1037  case 0x59: /* key signature */
1038  if (TRACE_ON(mcimidi)) {
1039  BYTE sf, mm;
1040 
1041  MIDI_mciReadByte(wmm, &sf);
1042  MIDI_mciReadByte(wmm, &mm);
1043 
1044  if (sf >= 0x80) TRACE("%d flats\n", -(char)sf);
1045  else if (sf > 0) TRACE("%d sharps\n", (char)sf);
1046  else TRACE("Key of C\n");
1047  TRACE("Mode: %s\n", (mm == 0) ? "major" : "minor");
1048  }
1049  break;
1050  default:
1051  WARN("Unknown MIDI meta event %02x. Skipping...\n", HIBYTE(LOWORD(mmt->dwEventData)));
1052  break;
1053  }
1054  break;
1055  default:
1056  if (doPlay) {
1057  dwRet = midiOutShortMsg((HMIDIOUT)wmm->hMidi, mmt->dwEventData);
1058  } else {
1059  switch (LOBYTE(LOWORD(mmt->dwEventData)) & 0xF0) {
1060  case MIDI_NOTEON:
1061  case MIDI_NOTEOFF:
1062  dwRet = 0;
1063  break;
1064  default:
1065  dwRet = midiOutShortMsg((HMIDIOUT)wmm->hMidi, mmt->dwEventData);
1066  }
1067  }
1068  }
1069  mmt->dwIndex += mmt->wEventLength;
1070  if (mmt->dwIndex < mmt->dwFirst || mmt->dwIndex >= mmt->dwLast) {
1071  mmt->wStatus = 0;
1072  }
1073  if (mmt->wStatus) {
1074  MIDI_mciReadNextEvent(wmm, mmt);
1075  }
1076  }
1077 
1078  midiOutReset((HMIDIOUT)wmm->hMidi);
1079 
1080  dwRet = midiOutClose((HMIDIOUT)wmm->hMidi);
1081 
1082  if (dwFlags & MCI_NOTIFY)
1083  oldcb = InterlockedExchangePointer(&wmm->hCallback, NULL);
1084 
1085  wmm->dwStatus = MCI_MODE_STOP;
1086 
1087  /* Let the potentially asynchronous commands support FAILURE notification. */
1088  if (oldcb) mciDriverNotify(oldcb, wmm->wDevID,
1090  return mmr2mci(dwRet);
1091 }
WORD wEventLength
Definition: mcimidi.c:54
#define MCI_MODE_STOP
Definition: mmsystem.h:695
Definition: pdh_main.c:93
static DWORD MIDI_ConvertPulseToMS(WINE_MCIMIDI *wmm, DWORD pulse)
Definition: mcimidi.c:523
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define FIXME_ON(ch)
Definition: debug.h:406
#define MIDI_NOTEOFF
Definition: mcimidi.c:44
DWORD dwPulse
Definition: mcimidi.c:79
DWORD dwLength
Definition: mcimidi.c:51
#define LOBYTE(W)
Definition: jmemdos.c:487
DWORD dwLast
Definition: mcimidi.c:49
WORD wStatus
Definition: mcimidi.c:55
#define TRUE
Definition: types.h:120
#define WARN(fmt,...)
Definition: debug.h:112
MMRESULT WINAPI midiOutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
Definition: winmm.c:942
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define HIBYTE(W)
Definition: jmemdos.c:486
#define MIDI_NOTEON
Definition: mcimidi.c:45
#define DWORD
Definition: nt_native.h:44
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
IMAGE_NT_HEADERS nt
Definition: module.c:50
MCI_MIDITRACK * tracks
Definition: mcimidi.c:78
const GLfloat * m
Definition: glext.h:10848
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
Definition: winmm.c:1042
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2056
HMIDIOUT * LPHMIDIOUT
Definition: mmsystem.h:1101
DWORD dwFirst
Definition: mcimidi.c:48
static DWORD MIDI_mciReadWord(WINE_MCIMIDI *wmm, LPWORD lpw)
Definition: mcimidi.c:193
#define FALSE
Definition: types.h:117
static DWORD mmr2mci(DWORD ret)
Definition: mcimidi.c:89
#define FIXME(fmt,...)
Definition: debug.h:111
unsigned int idx
Definition: utils.c:41
static DWORD MIDI_mciReadNextEvent(WINE_MCIMIDI *wmm, MCI_MIDITRACK *mmt)
Definition: mcimidi.c:245
DWORD dwEndMS
Definition: mcimidi.c:81
const GLfloat * tc
Definition: glext.h:8925
DWORD dwPositionMS
Definition: mcimidi.c:80
DWORD dwEventData
Definition: mcimidi.c:53
HMIDI hMidi
Definition: mcimidi.c:62
#define MCI_NOTIFY_FAILURE
Definition: mmsystem.h:728
UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
Definition: winmm.c:1073
WORD nTracks
Definition: mcimidi.c:74
WORD wFormat
Definition: mcimidi.c:73
#define SEEK_SET
Definition: jmemansi.c:26
GLfloat f
Definition: glext.h:7540
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
Definition: winmm.c:981
DWORD dwEventPulse
Definition: mcimidi.c:52
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint num
Definition: glext.h:9618
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
GLsizei const GLfloat * value
Definition: glext.h:6069
unsigned char BYTE
Definition: xxhash.c:193
DWORD dwStatus
Definition: mediaobj.idl:95
#define CALLBACK_NULL
Definition: mmsystem.h:147
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
DWORD dwIndex
Definition: mcimidi.c:50
static MCI_MIDITRACK * MIDI_mciFindNextEvent(WINE_MCIMIDI *wmm, LPDWORD hiPulse)
Definition: mcimidi.c:833
#define f
Definition: ke_i.h:83
HMMIO hFile
Definition: mcimidi.c:66
WORD wTrackNr
Definition: mcimidi.c:55
#define NULL
Definition: types.h:112
WORD dwStatus
Definition: mcimidi.c:71
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define HIWORD(l)
Definition: typedefs.h:247
WORD wStartedPlaying
Definition: mcimidi.c:76
static DWORD MIDI_mciReadByte(WINE_MCIMIDI *wmm, BYTE *lpbyt)
Definition: mcimidi.c:178
#define MCI_NOTIFY
Definition: mmsystem.h:729
DWORD dwStartTicks
Definition: mcimidi.c:82
#define TRACE_ON(x)
Definition: compat.h:75
#define LOWORD(l)
Definition: pedump.c:82
HANDLE hCallback
Definition: mcimidi.c:64
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:732
DWORD dwTempo
Definition: mcimidi.c:77

Referenced by MIDI_Starter().

◆ MIDI_Starter()

static DWORD CALLBACK MIDI_Starter ( void ptr)
static

Definition at line 1093 of file mcimidi.c.

1094 {
1095  WINE_MCIMIDI* wmm = ptr;
1096  return MIDI_player(wmm, MCI_NOTIFY);
1097 }
static DWORD MIDI_player(WINE_MCIMIDI *wmm, DWORD dwFlags)
Definition: mcimidi.c:857
static PVOID ptr
Definition: dispmode.c:27
#define MCI_NOTIFY
Definition: mmsystem.h:729

Referenced by ensurePlayerThread().

◆ mmr2mci()

static DWORD mmr2mci ( DWORD  ret)
static

Definition at line 89 of file mcimidi.c.

90 {
91  switch (ret) {
92  case MMSYSERR_ALLOCATED:
93  return MCIERR_SEQ_PORT_INUSE;
94  case MMSYSERR_NOMEM:
95  return MCIERR_OUT_OF_MEMORY;
96  case MMSYSERR_BADDEVICEID: /* wine*.drv disabled */
98  case MIDIERR_INVALIDSETUP: /* from midimap.dll without snd-seq module */
100  default:
101  return ret;
102  }
103 }
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
#define MCIERR_SEQ_PORT_MAPNODEVICE
Definition: mmsystem.h:634
#define MCIERR_OUT_OF_MEMORY
Definition: mmsystem.h:574
#define MMSYSERR_ALLOCATED
Definition: mmsystem.h:100
#define MIDIERR_INVALIDSETUP
Definition: mmsystem.h:236
int ret
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
#define MCIERR_SEQ_PORT_NONEXISTENT
Definition: mmsystem.h:633
#define MCIERR_SEQ_PORT_INUSE
Definition: mmsystem.h:632

Referenced by MIDI_player().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( mcimidi  )