44 #define MIDI_NOTEOFF 0x80 45 #define MIDI_NOTEON 0x90 114 if (!modp)
return 0xFFFFFFFF;
140 return (dwDevID == 0xFFFFFFFF) ? 1 : 0;
151 WARN(
"Invalid wDevID=%u\n", wDevID);
183 WARN(
"Error reading wmm=%p\n", wmm);
200 *lpw = ((
WORD)hibyte << 8) + lobyte;
237 }
while (
byte & 0x80);
269 if (evtLength >= 0x10000u) {
271 WARN(
"Ouch !! Implementation limitation to 64k bytes for a MIDI event is overflowed\n");
286 switch ((
b1 >> 4) & 0x07) {
287 case 0:
case 1:
case 2:
case 3:
case 6:
294 WARN(
"Strange indeed b1=0x%02x\n",
b1);
326 if (fourcc !=
mmioFOURCC(
'M',
'T',
'r',
'k')) {
327 WARN(
"Can't synchronize on 'MTrk' !\n");
352 WARN(
"Buffer for text is too small (%u are needed)\n",
len);
391 WARN(
"Ouch, out of sync seek=%u track=%u\n",
419 if (fourcc !=
mmioFOURCC(
'M',
'T',
'h',
'd')) {
420 WARN(
"Can't synchronize on 'MThd' !\n");
433 TRACE(
"toberead=0x%08X, wFormat=0x%04X nTracks=0x%04X nDivision=0x%04X\n",
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");
469 WARN(
"Number of division is 0, can't support that !!\n");
478 WARN(
"Got type 0 file whose number of track is not 1. Setting it to 1\n");
486 WARN(
"Handling MIDI files which format = %d is not (yet) supported\n" 487 "Please report with MIDI file !\n", wmm->
wFormat);
493 FIXME(
"Truncating MIDI file with %u tracks\n", wmm->
nTracks);
501 toberead -= 3 *
sizeof(
WORD);
503 TRACE(
"Size of MThd > 6, skipping %d extra bytes\n", toberead);
510 WARN(
"Can't read 'MTrk' header\n");
531 FIXME(
"Shouldn't happen. wmm->nDivision = 0\n");
535 ret = (pulse * 1000) / (nf * nsf);
549 #define TIME_MS_IN_ONE_HOUR (60*60*1000) 550 #define TIME_MS_IN_ONE_MINUTE (60*1000) 551 #define TIME_MS_IN_ONE_SECOND (1000) 609 f = (
val * 3) / 125;
val -= (
f * 125) / 3;
617 f = (
val * 3) / 100;
val -= (
f * 100) / 3;
620 FIXME(
"There must be some bad bad programmer\n");
625 ret = (
f << 24) | (
s << 16) | (
m << 8) | (
h << 0);
689 if (wmm->
hFile == 0) {
708 if (wmm->
hFile != 0) {
716 TRACE(
"ParentChunk ckid=%.4s fccType=%.4s cksize=%08X\n",
723 TRACE(
"... is a 'RMID' file\n");
730 WARN(
"Can't read 'MThd' header\n");
735 TRACE(
"hFile==0, setting #tracks to 0; is this correct ?\n");
806 if (wmm->
hFile != 0) {
809 TRACE(
"hFile closed !\n");
838 *hiPulse = 0xFFFFFFFFul;
850 return (cnt == 0xFFFFu) ? 0
897 TRACE(
"wmm->dwStatus=%d, doPlay=%c\n", wmm->
dwStatus, doPlay ?
'T' :
'F');
917 TRACE(
"Pulses hi=0x%08x <> cur=0x%08x\n", hiPulse, wmm->
dwPulse);
918 TRACE(
"Wait until %u => %u ms\n",
930 FIXME(
"Not handling SysEx events (yet)\n");
942 TRACE(
"Got sequence number %u\n", twd);
955 static const char*
const info[8] = {
"",
"Text",
"Copyright",
"Seq/Trk name",
956 "Instrument",
"Lyric",
"Marker",
"Cue-point"};
960 WARN(
"Buffer for text is too small (%u are needed)\n",
len);
977 FIXME(
"NIY: MIDI channel=%u, track=%u\n", bt, mmt->
wTrackNr);
997 WARN(
"For format #1 MIDI files, tempo can only be changed on track #0 (%u)\n", mmt->
wTrackNr);
1011 WARN(
"For format #1 MIDI files, SMPTE track start can only be expressed on track #0 (%u)\n", mmt->
wTrackNr);
1013 WARN(
"SMPTE track start can only be expressed at start of track (%u)\n", mmt->
dwEventPulse);
1022 FIXME(
"NIY: SMPTE track start %u:%u:%u %u.%u\n",
h,
m,
s,
f, ff);
1034 TRACE(
"%u/%u, clock per metronome click=%u, 32nd notes by 1/4 note=%u\n",
num, 1 << den, cpmc, _32npqn);
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");
1139 DWORD dwStartMS, dwEndMS;
1145 if (wmm->
hFile == 0) {
1154 dwEndMS = 0xFFFFFFFFul;
1161 if (dwEndMS < dwStartMS)
1169 if (wmm->
dwEndMS != dwEndMS) {
1175 TRACE(
"Playing from %u to %u\n", dwStartMS, dwEndMS);
1203 for (chn = 0; chn < 16; chn++)
1240 TRACE(
"MCI_FORMAT_MILLISECONDS !\n");
1244 TRACE(
"MCI_FORMAT_SMPTE_24 !\n");
1248 TRACE(
"MCI_FORMAT_SMPTE_25 !\n");
1252 TRACE(
"MCI_FORMAT_SMPTE_30 !\n");
1261 TRACE(
"No support for video !\n");
1265 TRACE(
"No support for door open !\n");
1269 TRACE(
"No support for door close !\n");
1274 TRACE(
"MCI_SET_ON audio !\n");
1276 TRACE(
"MCI_SET_OFF audio !\n");
1278 WARN(
"MCI_SET_AUDIO without SET_ON or SET_OFF\n");
1287 default:
WARN(
"Unknown audio channel %u\n", lpParms->
dwAudio);
break;
1292 TRACE(
"MCI_SEQ_SET_MASTER !\n");
1294 TRACE(
"MCI_SEQ_SET_SLAVE !\n");
1296 TRACE(
"MCI_SEQ_SET_OFFSET !\n");
1298 TRACE(
"MCI_SEQ_SET_PORT = %d\n", lpParms->
dwPort);
1307 TRACE(
"MCI_SEQ_SET_TEMPO !\n");
1325 switch (lpParms->
dwItem) {
1329 TRACE(
"MCI_STATUS_CURRENT_TRACK => %lu\n", lpParms->
dwReturn);
1350 TRACE(
"MCI_STATUS_MEDIA_PRESENT => TRUE\n");
1356 TRACE(
"MCI_STATUS_NUMBER_OF_TRACKS => %lu\n", lpParms->
dwReturn);
1363 TRACE(
"MCI_STATUS_POSITION %s => %lu\n",
1378 TRACE(
"MCI_SEQ_STATUS_DIVTYPE !\n");
1385 default:
FIXME(
"There is a bad bad programmer\n");
1394 TRACE(
"MCI_SEQ_STATUS_MASTER !\n");
1399 TRACE(
"MCI_SEQ_STATUS_SLAVE !\n");
1404 TRACE(
"MCI_SEQ_STATUS_OFFSET !\n");
1417 TRACE(
"MCI_SEQ_STATUS_TEMPO !\n");
1421 FIXME(
"Unknown command %08X !\n", lpParms->
dwItem);
1445 switch (lpParms->
dwItem) {
1447 TRACE(
"MCI_GETDEVCAPS_DEVICE_TYPE !\n");
1452 TRACE(
"MCI_GETDEVCAPS_HAS_AUDIO !\n");
1457 TRACE(
"MCI_GETDEVCAPS_HAS_VIDEO !\n");
1462 TRACE(
"MCI_GETDEVCAPS_USES_FILES !\n");
1467 TRACE(
"MCI_GETDEVCAPS_COMPOUND_DEVICE !\n");
1472 TRACE(
"MCI_GETDEVCAPS_CAN_EJECT !\n");
1477 TRACE(
"MCI_GETDEVCAPS_CAN_PLAY !\n");
1482 TRACE(
"MCI_GETDEVCAPS_CAN_RECORD !\n");
1487 TRACE(
"MCI_GETDEVCAPS_CAN_SAVE !\n");
1492 FIXME(
"Unknown capability (%08x) !\n", lpParms->
dwItem);
1496 WARN(
"No GetDevCaps-Item !\n");
1511 static const WCHAR wszMidiSeq[] = {
'W',
'i',
'n',
'e',
'\'',
's',
' ',
'M',
'I',
'D',
'I',
' ',
's',
'e',
'q',
'u',
'e',
'n',
'c',
'e',
'r',0};
1526 WARN(
"Don't know this info command (%u)\n",
dwFlags);
1599 TRACE(
"Sending msg %04x to default driver proc\n", wMsg);
1600 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1620 FIXME(
"Shouldn't receive a MCI_OPEN or CLOSE message\n");
1623 TRACE(
"Unsupported command [0x%x]\n", wMsg);
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
BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD dwData)
#define MCI_NO_COMMAND_TABLE
#define MCIERR_NONAPPLICABLE_FUNCTION
static WINE_MCIMIDI * MIDI_mciGetOpenDev(MCIDEVICEID wDevID, UINT wMsg)
#define MCIERR_INVALID_FILE
#define TIME_MS_IN_ONE_MINUTE
DWORD WINAPI mciGetDriverData(UINT uDeviceID)
static DWORD MIDI_ConvertPulseToMS(WINE_MCIMIDI *wmm, DWORD pulse)
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
#define MCI_SEQ_DIV_SMPTE_30DROP
#define MCI_FORMAT_SMPTE_25
LRESULT CALLBACK MCIMIDI_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
#define MCI_STATUS_NUMBER_OF_TRACKS
#define MCI_GETDEVCAPS_CAN_SAVE
#define TIME_MS_IN_ONE_HOUR
static DWORD MIDI_drvClose(DWORD dwDevID)
static DWORD MIDI_mciOpen(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_OPEN_PARMSW lpParms)
#define MCIERR_UNSUPPORTED_FUNCTION
MMRESULT WINAPI midiOutOpen(LPHMIDIOUT lphMidiOut, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD dwFlags)
DWORD WINAPI GetTickCount(VOID)
static DWORD MIDI_mciReadMTrk(WINE_MCIMIDI *wmm, MCI_MIDITRACK *mmt)
static DWORD MIDI_mciStop(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
#define MCI_GETDEVCAPS_COMPOUND_DEVICE
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
static DWORD MIDI_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
static DWORD MIDI_mciInfo(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
#define MCI_SEQ_DIV_SMPTE_24
static DWORD CALLBACK MIDI_Starter(void *ptr)
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
#define MCI_RESOURCE_RETURNED
#define MCI_SEQ_STATUS_TEMPO
#define MCI_GETDEVCAPS_CAN_RECORD
#define MAKEMCIRESOURCE(wRet, wRes)
#define MCI_SET_DOOR_CLOSED
#define MCI_STATUS_POSITION
#define MCI_FORMAT_SMPTE_30
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
#define MCI_NOTIFY_ABORTED
static DWORD MIDI_mciPause(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
GLfloat GLfloat GLfloat GLfloat h
_In_ DWORD _In_ DWORD dwOffset
#define DRV_QUERYCONFIGURE
UINT WINAPI midiOutShortMsg(HMIDIOUT hMidiOut, DWORD dwMsg)
static DWORD MIDI_mciGetDevCaps(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
int WINAPI MessageBoxA(_In_opt_ HWND, _In_opt_ LPCSTR, _In_opt_ LPCSTR, _In_ UINT)
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
GLenum GLuint GLenum GLsizei const GLchar * buf
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
#define MCI_GETDEVCAPS_USES_FILES
#define MCI_SEQ_STATUS_MASTER
static DWORD MIDI_mciReadWord(WINE_MCIMIDI *wmm, LPWORD lpw)
#define MCIERR_FLAGS_NOT_COMPATIBLE
static WORD MIDI_mciReadVaryLen(WINE_MCIMIDI *wmm, LPDWORD lpdw)
#define MCI_FORMAT_MILLISECONDS
static DWORD MIDI_GetMThdLengthMS(WINE_MCIMIDI *wmm)
static DWORD mmr2mci(DWORD ret)
static DWORD MIDI_player(WINE_MCIMIDI *wmm, DWORD dwFlags)
#define MCIERR_SEQ_PORT_MAPNODEVICE
static CRYPT_DATA_BLOB b1[]
static DWORD MIDI_mciClose(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
#define MCI_GETDEVCAPS_DEVICE_TYPE
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
static DWORD MIDI_mciReadNextEvent(WINE_MCIMIDI *wmm, MCI_MIDITRACK *mmt)
#define MCI_SEQ_SET_TEMPO
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)
static DWORD MIDI_mciReadMThd(WINE_MCIMIDI *wmm, DWORD dwOffset)
#define MCI_SEQ_STATUS_PORT
#define TIME_MS_IN_ONE_SECOND
static DWORD MIDI_mciPlay(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
#define MCIERR_MISSING_PARAMETER
#define MCI_NOTIFY_FAILURE
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
#define MCI_GETDEVCAPS_HAS_VIDEO
UINT WINAPI midiOutReset(HMIDIOUT hMidiOut)
#define MCIERR_PARAM_OVERFLOW
static DWORD ensurePlayerThread(WINE_MCIMIDI *wmm)
#define MCIERR_OUT_OF_MEMORY
#define MCI_SEQ_SET_SLAVE
#define InterlockedExchangePointer(Target, Value)
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static DWORD MIDI_mciSeek(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
#define MCI_STATUS_LENGTH
#define MCIERR_BAD_INTEGER
static DWORD MIDI_mciStatus(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
#define MCI_OPEN_SHAREABLE
#define MCI_SET_TIME_FORMAT
#define MMSYSERR_ALLOCATED
UINT WINAPI midiOutClose(HMIDIOUT hMidiOut)
#define MCI_SET_AUDIO_LEFT
#define MCIERR_BAD_TIME_FORMAT
#define MCI_FORMAT_SMPTE_24
#define MIDIERR_INVALIDSETUP
#define MCI_NOTIFY_SUCCESSFUL
#define THREAD_PRIORITY_TIME_CRITICAL
#define MCI_SET_AUDIO_RIGHT
#define MCI_SEQ_STATUS_DIVTYPE
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
#define mmioFOURCC(c0, c1, c2, c3)
#define MCI_GETDEVCAPS_HAS_AUDIO
#define MCI_STATUS_CURRENT_TRACK
#define MCI_SEQ_SET_MASTER
static DWORD MIDI_mciResume(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
#define MMSYSERR_BADDEVICEID
#define MCIERR_OUTOFRANGE
#define MCI_GETDEVCAPS_ITEM
GLsizei const GLfloat * value
#define MCI_SEQ_SET_OFFSET
#define MCI_SEEK_TO_START
#define MCIERR_FILE_NOT_FOUND
#define MCI_FORMAT_SMPTE_30DROP
#define MCI_MODE_NOT_READY
static CRYPT_DATA_BLOB b3[]
#define MCI_NOTIFY_SUPERSEDED
static void MIDI_mciNotify(DWORD_PTR hWndCallBack, WINE_MCIMIDI *wmm, UINT wStatus)
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
static MCI_MIDITRACK * MIDI_mciFindNextEvent(WINE_MCIMIDI *wmm, LPDWORD hiPulse)
#define MCI_SEQ_STATUS_OFFSET
#define MCI_SEQ_DIV_SMPTE_30
#define MultiByteToWideChar
#define MCI_SEQ_DIV_SMPTE_25
#define MCIERR_UNRECOGNIZED_COMMAND
#define MCI_INFO_COPYRIGHT
#define MCI_GETDEVCAPS_CAN_EJECT
#define MCIERR_DEVICE_OPEN
struct tagWINE_MCIMIDI WINE_MCIMIDI
#define MCI_DEVTYPE_SEQUENCER
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
static CRYPT_DATA_BLOB b2[]
WINE_DEFAULT_DEBUG_CHANNEL(mcimidi)
#define MCI_SEQ_STATUS_SLAVE
static DWORD MIDI_mciSet(WINE_MCIMIDI *wmm, DWORD dwFlags, LPMCI_SEQ_SET_PARMS lpParms)
static DWORD MIDI_mciReadByte(WINE_MCIMIDI *wmm, BYTE *lpbyt)
#define MCIERR_INVALID_DEVICE_ID
#define MCI_SET_AUDIO_ALL
#define MCI_STATUS_TIME_FORMAT
#define MCI_STATUS_MEDIA_PRESENT
#define MCIERR_SEQ_PORT_NONEXISTENT
#define MCIERR_NULL_PARAMETER_BLOCK
UINT WINAPI midiOutGetNumDevs(void)
static DWORD MIDI_ConvertTimeFormatToMS(WINE_MCIMIDI *wmm, DWORD val)
#define HeapFree(x, y, z)
static DWORD MIDI_mciReadLong(WINE_MCIMIDI *wmm, LPDWORD lpdw)
static DWORD MIDI_ConvertMSToTimeFormat(WINE_MCIMIDI *wmm, DWORD _val)
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
#define MCI_SET_DOOR_OPEN
#define MCIERR_SEQ_PORT_INUSE
#define MCI_FORMAT_RETURN_BASE
#define MCI_GETDEVCAPS_CAN_PLAY